diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e3be6fb..f8683b2e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/letta-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -46,7 +46,7 @@ jobs: id-token: write runs-on: ${{ github.repository == 'stainless-sdks/letta-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | @@ -67,7 +67,7 @@ jobs: github.repository == 'stainless-sdks/letta-sdk-python' && !startsWith(github.ref, 'refs/heads/stl/') id: github-oidc - uses: actions/github-script@v8 + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 with: script: core.setOutput('github_token', await core.getIDToken()); @@ -87,7 +87,7 @@ jobs: runs-on: ${{ github.repository == 'stainless-sdks/letta-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 93a42fc5..5636ed4a 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Install Rye run: | diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 90cade32..ec179ddd 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -12,7 +12,7 @@ jobs: if: github.repository == 'letta-ai/letta-python' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next') steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - name: Check release environment run: | diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 083df00e..caf14871 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "1.10.3" + ".": "1.11.0" } \ No newline at end of file diff --git a/.stats.yml b/.stats.yml index 1ba06022..ecb01875 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ configured_endpoints: 126 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/letta-ai%2Fletta-sdk-873f657578988b58f8920addcacee62440377571f56a48c44b3505342a4cdc96.yml -openapi_spec_hash: 6c5174fa1eddd3c0b8b072320d1d32b0 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/letta-ai/letta-sdk-3bf3ab3365d6881961c545ff1cde437e4060d17a0d46d02116f3be0b79158f5d.yml +openapi_spec_hash: 6c229aac939ec0b917ed2dcd5547deeb config_hash: f2ff70633d052a11601ad82a5afcfaec diff --git a/CHANGELOG.md b/CHANGELOG.md index 487ec43e..5d6fe844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,39 @@ # Changelog +## 1.11.0 (2026-05-14) + +Full Changelog: [v1.10.3...v1.11.0](https://github.com/letta-ai/letta-python/compare/v1.10.3...v1.11.0) + +### Features + +* cap v1 limit query params ([b5edad1](https://github.com/letta-ai/letta-python/commit/b5edad120811911e5f095dd280ba98c0da956acb)) +* **core:** add moonshot and kimi code BYOK providers ([0b0940b](https://github.com/letta-ai/letta-python/commit/0b0940b2ae070319c6a0f2cc4114a4d2b09d2b5a)) +* **internal/types:** support eagerly validating pydantic iterators ([8d289a9](https://github.com/letta-ai/letta-python/commit/8d289a9daa714a4f54d4d0483df35c5236b46797)) +* support setting headers via env ([f0c2ba8](https://github.com/letta-ai/letta-python/commit/f0c2ba89ef56ee33ff8137eee8c3a78c3b3ec689)) + + +### Bug Fixes + +* **client:** add missing f-string prefix in file type error message ([cbf36eb](https://github.com/letta-ai/letta-python/commit/cbf36ebe5738e46ecdd278db55d8dba1fd8fa373)) +* use correct field name format for multipart file arrays ([1039e5a](https://github.com/letta-ai/letta-python/commit/1039e5a7bb425f445ec815d15fcead06e2801a36)) + + +### Performance Improvements + +* **core:** reduce conversation send hot-path reads ([8a7b06e](https://github.com/letta-ai/letta-python/commit/8a7b06eee9b4d0ad28fe1016de5237797dfb01eb)) + + +### Chores + +* **internal:** more robust bootstrap script ([074fe85](https://github.com/letta-ai/letta-python/commit/074fe8585483c25a8c2cee48e3324db034901b47)) +* **internal:** reformat pyproject.toml ([d9a6109](https://github.com/letta-ai/letta-python/commit/d9a6109c3a68c5ad4bb2980ea5b53e3fc7a0e96b)) + + +### Refactors + +* hard-deprecate isolated conversation blocks ([ed0a3d4](https://github.com/letta-ai/letta-python/commit/ed0a3d42fcbc0b9b4af4a3fe63e2dff5bb0161f0)) +* stop creating new isolated conversation blocks ([aa75f2a](https://github.com/letta-ai/letta-python/commit/aa75f2af909e91d5a30e81ec2ac6cde27193a074)) + ## 1.10.3 (2026-04-17) Full Changelog: [v1.10.2...v1.10.3](https://github.com/letta-ai/letta-python/compare/v1.10.2...v1.10.3) diff --git a/pyproject.toml b/pyproject.toml index bb2d416f..22cccea2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "letta-client" -version = "1.10.3" +version = "1.11.0" description = "The official Python library for the letta API" dynamic = ["readme"] license = "Apache-2.0" @@ -168,7 +168,7 @@ show_error_codes = true # # We also exclude our `tests` as mypy doesn't always infer # types correctly and Pyright will still catch any type errors. -exclude = ['src/letta_client/_files.py', '_dev/.*.py', 'tests/.*'] +exclude = ["src/letta_client/_files.py", "_dev/.*.py", "tests/.*"] strict_equality = true implicit_reexport = true diff --git a/scripts/bootstrap b/scripts/bootstrap index b430fee3..fe8451e4 100755 --- a/scripts/bootstrap +++ b/scripts/bootstrap @@ -4,7 +4,7 @@ set -e cd "$(dirname "$0")/.." -if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ] && [ -t 0 ]; then +if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "${SKIP_BREW:-}" != "1" ] && [ -t 0 ]; then brew bundle check >/dev/null 2>&1 || { echo -n "==> Install Homebrew dependencies? (y/N): " read -r response diff --git a/src/letta_client/_client.py b/src/letta_client/_client.py index 07aeb3c6..d078bb30 100644 --- a/src/letta_client/_client.py +++ b/src/letta_client/_client.py @@ -22,7 +22,11 @@ RequestOptions, not_given, ) -from ._utils import is_given, get_async_library +from ._utils import ( + is_given, + is_mapping_t, + get_async_library, +) from ._compat import cached_property from ._version import __version__ from ._response import ( @@ -165,6 +169,15 @@ def __init__( except KeyError as exc: raise ValueError(f"Unknown environment: {environment}") from exc + custom_headers_env = os.environ.get("LETTA_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, @@ -482,6 +495,15 @@ def __init__( except KeyError as exc: raise ValueError(f"Unknown environment: {environment}") from exc + custom_headers_env = os.environ.get("LETTA_CUSTOM_HEADERS") + if custom_headers_env is not None: + parsed: dict[str, str] = {} + for line in custom_headers_env.split("\n"): + colon = line.find(":") + if colon >= 0: + parsed[line[:colon].strip()] = line[colon + 1 :].strip() + default_headers = {**parsed, **(default_headers if is_mapping_t(default_headers) else {})} + super().__init__( version=__version__, base_url=base_url, diff --git a/src/letta_client/_files.py b/src/letta_client/_files.py index 3ce00473..96fbe164 100644 --- a/src/letta_client/_files.py +++ b/src/letta_client/_files.py @@ -99,7 +99,7 @@ async def async_to_httpx_files(files: RequestFiles | None) -> HttpxRequestFiles elif is_sequence_t(files): files = [(key, await _async_transform_file(file)) for key, file in files] else: - raise TypeError("Unexpected file type input {type(files)}, expected mapping or sequence") + raise TypeError(f"Unexpected file type input {type(files)}, expected mapping or sequence") return files diff --git a/src/letta_client/_models.py b/src/letta_client/_models.py index 29070e05..8c5ab260 100644 --- a/src/letta_client/_models.py +++ b/src/letta_client/_models.py @@ -25,7 +25,9 @@ ClassVar, Protocol, Required, + Annotated, ParamSpec, + TypeAlias, TypedDict, TypeGuard, final, @@ -79,7 +81,15 @@ from ._constants import RAW_RESPONSE_HEADER if TYPE_CHECKING: + from pydantic import GetCoreSchemaHandler, ValidatorFunctionWrapHandler + from pydantic_core import CoreSchema, core_schema from pydantic_core.core_schema import ModelField, ModelSchema, LiteralSchema, ModelFieldsSchema +else: + try: + from pydantic_core import CoreSchema, core_schema + except ImportError: + CoreSchema = None + core_schema = None __all__ = ["BaseModel", "GenericModel"] @@ -396,6 +406,76 @@ def model_dump_json( ) +class _EagerIterable(list[_T], Generic[_T]): + """ + Accepts any Iterable[T] input (including generators), consumes it + eagerly, and validates all items upfront. + + Validation preserves the original container type where possible + (e.g. a set[T] stays a set[T]). Serialization (model_dump / JSON) + always emits a list — round-tripping through model_dump() will not + restore the original container type. + """ + + @classmethod + def __get_pydantic_core_schema__( + cls, + source_type: Any, + handler: GetCoreSchemaHandler, + ) -> CoreSchema: + (item_type,) = get_args(source_type) or (Any,) + item_schema: CoreSchema = handler.generate_schema(item_type) + list_of_items_schema: CoreSchema = core_schema.list_schema(item_schema) + + return core_schema.no_info_wrap_validator_function( + cls._validate, + list_of_items_schema, + serialization=core_schema.plain_serializer_function_ser_schema( + cls._serialize, + info_arg=False, + ), + ) + + @staticmethod + def _validate(v: Iterable[_T], handler: "ValidatorFunctionWrapHandler") -> Any: + original_type: type[Any] = type(v) + + # Normalize to list so list_schema can validate each item + if isinstance(v, list): + items: list[_T] = v + else: + try: + items = list(v) + except TypeError as e: + raise TypeError("Value is not iterable") from e + + # Validate items against the inner schema + validated: list[_T] = handler(items) + + # Reconstruct original container type + if original_type is list: + return validated + # str(list) produces the list's repr, not a string built from items, + # so skip reconstruction for str and its subclasses. + if issubclass(original_type, str): + return validated + try: + return original_type(validated) + except (TypeError, ValueError): + # If the type cannot be reconstructed, just return the validated list + return validated + + @staticmethod + def _serialize(v: Iterable[_T]) -> list[_T]: + """Always serialize as a list so Pydantic's JSON encoder is happy.""" + if isinstance(v, list): + return v + return list(v) + + +EagerIterable: TypeAlias = Annotated[Iterable[_T], _EagerIterable] + + def _construct_field(value: object, field: FieldInfo, key: str) -> object: if value is None: return field_get_default(field) diff --git a/src/letta_client/_qs.py b/src/letta_client/_qs.py index de8c99bc..4127c19c 100644 --- a/src/letta_client/_qs.py +++ b/src/letta_client/_qs.py @@ -2,17 +2,13 @@ from typing import Any, List, Tuple, Union, Mapping, TypeVar from urllib.parse import parse_qs, urlencode -from typing_extensions import Literal, get_args +from typing_extensions import get_args -from ._types import NotGiven, not_given +from ._types import NotGiven, ArrayFormat, NestedFormat, not_given from ._utils import flatten _T = TypeVar("_T") - -ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] -NestedFormat = Literal["dots", "brackets"] - PrimitiveData = Union[str, int, float, bool, None] # this should be Data = Union[PrimitiveData, "List[Data]", "Tuple[Data]", "Mapping[str, Data]"] # https://github.com/microsoft/pyright/issues/3555 diff --git a/src/letta_client/_types.py b/src/letta_client/_types.py index 39fa447f..8fa5c2a0 100644 --- a/src/letta_client/_types.py +++ b/src/letta_client/_types.py @@ -47,6 +47,9 @@ ModelT = TypeVar("ModelT", bound=pydantic.BaseModel) _T = TypeVar("_T") +ArrayFormat = Literal["comma", "repeat", "indices", "brackets"] +NestedFormat = Literal["dots", "brackets"] + # Approximates httpx internal ProxiesTypes and RequestFiles types # while adding support for `PathLike` instances diff --git a/src/letta_client/_utils/_utils.py b/src/letta_client/_utils/_utils.py index 771859f5..199cd231 100644 --- a/src/letta_client/_utils/_utils.py +++ b/src/letta_client/_utils/_utils.py @@ -17,11 +17,11 @@ ) from pathlib import Path from datetime import date, datetime -from typing_extensions import TypeGuard +from typing_extensions import TypeGuard, get_args import sniffio -from .._types import Omit, NotGiven, FileTypes, HeadersLike +from .._types import Omit, NotGiven, FileTypes, ArrayFormat, HeadersLike _T = TypeVar("_T") _TupleT = TypeVar("_TupleT", bound=Tuple[object, ...]) @@ -40,25 +40,45 @@ def extract_files( query: Mapping[str, object], *, paths: Sequence[Sequence[str]], + array_format: ArrayFormat = "brackets", ) -> list[tuple[str, FileTypes]]: """Recursively extract files from the given dictionary based on specified paths. A path may look like this ['foo', 'files', '', 'data']. + ``array_format`` controls how ```` segments contribute to the emitted + field name. Supported values: ``"brackets"`` (``foo[]``), ``"repeat"`` and + ``"comma"`` (``foo``), ``"indices"`` (``foo[0]``, ``foo[1]``). + Note: this mutates the given dictionary. """ files: list[tuple[str, FileTypes]] = [] for path in paths: - files.extend(_extract_items(query, path, index=0, flattened_key=None)) + files.extend(_extract_items(query, path, index=0, flattened_key=None, array_format=array_format)) return files +def _array_suffix(array_format: ArrayFormat, array_index: int) -> str: + if array_format == "brackets": + return "[]" + if array_format == "indices": + return f"[{array_index}]" + if array_format == "repeat" or array_format == "comma": + # Both repeat the bare field name for each file part; there is no + # meaningful way to comma-join binary parts. + return "" + raise NotImplementedError( + f"Unknown array_format value: {array_format}, choose from {', '.join(get_args(ArrayFormat))}" + ) + + def _extract_items( obj: object, path: Sequence[str], *, index: int, flattened_key: str | None, + array_format: ArrayFormat, ) -> list[tuple[str, FileTypes]]: try: key = path[index] @@ -75,9 +95,11 @@ def _extract_items( if is_list(obj): files: list[tuple[str, FileTypes]] = [] - for entry in obj: - assert_is_file_content(entry, key=flattened_key + "[]" if flattened_key else "") - files.append((flattened_key + "[]", cast(FileTypes, entry))) + for array_index, entry in enumerate(obj): + suffix = _array_suffix(array_format, array_index) + emitted_key = (flattened_key + suffix) if flattened_key else suffix + assert_is_file_content(entry, key=emitted_key) + files.append((emitted_key, cast(FileTypes, entry))) return files assert_is_file_content(obj, key=flattened_key) @@ -106,6 +128,7 @@ def _extract_items( path, index=index, flattened_key=flattened_key, + array_format=array_format, ) elif is_list(obj): if key != "": @@ -117,9 +140,12 @@ def _extract_items( item, path, index=index, - flattened_key=flattened_key + "[]" if flattened_key is not None else "[]", + flattened_key=( + (flattened_key if flattened_key is not None else "") + _array_suffix(array_format, array_index) + ), + array_format=array_format, ) - for item in obj + for array_index, item in enumerate(obj) ] ) diff --git a/src/letta_client/_version.py b/src/letta_client/_version.py index 8c79a6a4..f2a25490 100644 --- a/src/letta_client/_version.py +++ b/src/letta_client/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. __title__ = "letta_client" -__version__ = "1.10.3" # x-release-please-version +__version__ = "1.11.0" # x-release-please-version diff --git a/src/letta_client/resources/conversations/conversations.py b/src/letta_client/resources/conversations/conversations.py index 3466d855..b96b16bc 100644 --- a/src/letta_client/resources/conversations/conversations.py +++ b/src/letta_client/resources/conversations/conversations.py @@ -16,7 +16,7 @@ conversation_update_params, conversation_recompile_params, ) -from ..._types import Body, Omit, Query, Headers, NotGiven, SequenceNotStr, omit, not_given +from ..._types import Body, Omit, Query, Headers, NotGiven, omit, not_given from ..._utils import path_template, maybe_transform, async_maybe_transform from .messages import ( MessagesResource, @@ -72,7 +72,6 @@ def create( agent_id: str, context_window_limit: Optional[int] | Omit = omit, hidden: bool | Omit = omit, - isolated_block_labels: Optional[SequenceNotStr[str]] | Omit = omit, model: Optional[str] | Omit = omit, model_settings: Optional[conversation_create_params.ModelSettings] | Omit = omit, summary: Optional[str] | Omit = omit, @@ -94,10 +93,6 @@ def create( hidden: Whether the new conversation should be hidden from listings. - isolated_block_labels: List of block labels that should be isolated (conversation-specific) rather than - shared across conversations. New blocks will be created as copies of the agent's - blocks with these labels. - model: The model handle for this conversation (overrides agent's model). Format: provider/model-name. @@ -120,7 +115,6 @@ def create( { "context_window_limit": context_window_limit, "hidden": hidden, - "isolated_block_labels": isolated_block_labels, "model": model, "model_settings": model_settings, "summary": summary, @@ -321,11 +315,9 @@ def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Delete a conversation (soft delete). + Delete a conversation. - This marks the conversation as deleted but does not permanently remove it from - the database. The conversation will no longer appear in list operations. Any - isolated blocks associated with the conversation will be permanently deleted. + The conversation will no longer appear in list operations. Args: conversation_id: The ID of the conv in the format 'conv-' @@ -557,7 +549,6 @@ async def create( agent_id: str, context_window_limit: Optional[int] | Omit = omit, hidden: bool | Omit = omit, - isolated_block_labels: Optional[SequenceNotStr[str]] | Omit = omit, model: Optional[str] | Omit = omit, model_settings: Optional[conversation_create_params.ModelSettings] | Omit = omit, summary: Optional[str] | Omit = omit, @@ -579,10 +570,6 @@ async def create( hidden: Whether the new conversation should be hidden from listings. - isolated_block_labels: List of block labels that should be isolated (conversation-specific) rather than - shared across conversations. New blocks will be created as copies of the agent's - blocks with these labels. - model: The model handle for this conversation (overrides agent's model). Format: provider/model-name. @@ -605,7 +592,6 @@ async def create( { "context_window_limit": context_window_limit, "hidden": hidden, - "isolated_block_labels": isolated_block_labels, "model": model, "model_settings": model_settings, "summary": summary, @@ -808,11 +794,9 @@ async def delete( timeout: float | httpx.Timeout | None | NotGiven = not_given, ) -> object: """ - Delete a conversation (soft delete). + Delete a conversation. - This marks the conversation as deleted but does not permanently remove it from - the database. The conversation will no longer appear in list operations. Any - isolated blocks associated with the conversation will be permanently deleted. + The conversation will no longer appear in list operations. Args: conversation_id: The ID of the conv in the format 'conv-' diff --git a/src/letta_client/types/agent_create_params.py b/src/letta_client/types/agent_create_params.py index 9a9f8a1c..33009220 100644 --- a/src/letta_client/types/agent_create_params.py +++ b/src/letta_client/types/agent_create_params.py @@ -41,9 +41,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -53,9 +58,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -311,6 +321,36 @@ class CompactionSettingsModelSettingsSgLangModelSettings(TypedDict, total=False) """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -348,6 +388,59 @@ class CompactionSettingsModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -422,7 +515,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(TypedDict, total= GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, @@ -519,6 +614,36 @@ class ModelSettingsSgLangModelSettings(TypedDict, total=False): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -556,6 +681,59 @@ class ModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: ModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -630,7 +808,9 @@ class ModelSettingsChatGptoAuthModelSettings(TypedDict, total=False): GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/agent_state.py b/src/letta_client/types/agent_state.py index 2dea9fcb..c0d5effa 100644 --- a/src/letta_client/types/agent_state.py +++ b/src/letta_client/types/agent_state.py @@ -50,9 +50,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -65,9 +70,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -257,6 +267,37 @@ class CompactionSettingsModelSettingsSgLangModelSettings(BaseModel): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(BaseModel): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot"]] = None + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Annotated[ Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], PropertyInfo(discriminator="type"), @@ -295,6 +336,60 @@ class CompactionSettingsModelSettingsZaiModelSettings(BaseModel): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(BaseModel): + """The thinking configuration for the model.""" + + budget_tokens: Optional[int] = None + """The maximum number of tokens the model can use for extended thinking.""" + + type: Optional[Literal["enabled", "disabled"]] = None + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(BaseModel): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] = None + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot_coding"]] = None + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + thinking: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking] = None + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] = None + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(BaseModel): """Baseten model configuration (OpenAI-compatible).""" @@ -371,7 +466,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(BaseModel): GoogleVertexModelSettings, AzureModelSettings, XaiModelSettings, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettings, DeepseekModelSettings, TogetherModelSettings, @@ -566,6 +663,37 @@ class ModelSettingsSgLangModelSettings(BaseModel): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class ModelSettingsMoonshotModelSettings(BaseModel): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot"]] = None + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Annotated[ Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], PropertyInfo(discriminator="type"), @@ -604,6 +732,60 @@ class ModelSettingsZaiModelSettings(BaseModel): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(BaseModel): + """The thinking configuration for the model.""" + + budget_tokens: Optional[int] = None + """The maximum number of tokens the model can use for extended thinking.""" + + type: Optional[Literal["enabled", "disabled"]] = None + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(BaseModel): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] = None + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot_coding"]] = None + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + thinking: Optional[ModelSettingsMoonshotCodingModelSettingsThinking] = None + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] = None + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(BaseModel): """Baseten model configuration (OpenAI-compatible).""" @@ -680,7 +862,9 @@ class ModelSettingsChatGptoAuthModelSettings(BaseModel): GoogleVertexModelSettings, AzureModelSettings, XaiModelSettings, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettings, DeepseekModelSettings, TogetherModelSettings, diff --git a/src/letta_client/types/agent_update_params.py b/src/letta_client/types/agent_update_params.py index 297ffce6..fff6a1ce 100644 --- a/src/letta_client/types/agent_update_params.py +++ b/src/letta_client/types/agent_update_params.py @@ -41,9 +41,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -53,9 +58,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -259,6 +269,36 @@ class CompactionSettingsModelSettingsSgLangModelSettings(TypedDict, total=False) """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -296,6 +336,59 @@ class CompactionSettingsModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -370,7 +463,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(TypedDict, total= GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, @@ -467,6 +562,36 @@ class ModelSettingsSgLangModelSettings(TypedDict, total=False): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -504,6 +629,59 @@ class ModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: ModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -578,7 +756,9 @@ class ModelSettingsChatGptoAuthModelSettings(TypedDict, total=False): GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/agents/message_compact_params.py b/src/letta_client/types/agents/message_compact_params.py index 4899ad28..6d679779 100644 --- a/src/letta_client/types/agents/message_compact_params.py +++ b/src/letta_client/types/agents/message_compact_params.py @@ -26,9 +26,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -91,6 +96,36 @@ class CompactionSettingsModelSettingsSgLangModelSettings(TypedDict, total=False) """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -128,6 +163,59 @@ class CompactionSettingsModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -202,7 +290,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(TypedDict, total= GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/conversation.py b/src/letta_client/types/conversation.py index 69c228bd..23a8022b 100644 --- a/src/letta_client/types/conversation.py +++ b/src/letta_client/types/conversation.py @@ -28,9 +28,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -85,6 +90,37 @@ class ModelSettingsSgLangModelSettings(BaseModel): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class ModelSettingsMoonshotModelSettings(BaseModel): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot"]] = None + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Annotated[ Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], PropertyInfo(discriminator="type"), @@ -123,6 +159,60 @@ class ModelSettingsZaiModelSettings(BaseModel): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Annotated[ + Union[TextResponseFormat, JsonSchemaResponseFormat, JsonObjectResponseFormat, None], + PropertyInfo(discriminator="type"), +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(BaseModel): + """The thinking configuration for the model.""" + + budget_tokens: Optional[int] = None + """The maximum number of tokens the model can use for extended thinking.""" + + type: Optional[Literal["enabled", "disabled"]] = None + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(BaseModel): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] = None + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: Optional[int] = None + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: Optional[bool] = None + """Whether to enable parallel tool calling.""" + + provider_type: Optional[Literal["moonshot_coding"]] = None + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] = None + """The response format for the model.""" + + strict: Optional[bool] = None + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: Optional[float] = None + """The temperature of the model.""" + + thinking: Optional[ModelSettingsMoonshotCodingModelSettingsThinking] = None + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] = None + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(BaseModel): """Baseten model configuration (OpenAI-compatible).""" @@ -199,7 +289,9 @@ class ModelSettingsChatGptoAuthModelSettings(BaseModel): GoogleVertexModelSettings, AzureModelSettings, XaiModelSettings, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettings, DeepseekModelSettings, TogetherModelSettings, @@ -241,12 +333,9 @@ class Conversation(BaseModel): """The id of the user that made this object.""" in_context_message_ids: Optional[List[str]] = None - """The IDs of in-context messages for the conversation.""" + """The IDs of in-context messages for the conversation. - isolated_block_ids: Optional[List[str]] = None - """ - IDs of blocks that are isolated (specific to this conversation, overriding agent - defaults). + Null means this field was not retrieved/hydrated for this response. """ last_message_at: Optional[datetime] = None diff --git a/src/letta_client/types/conversation_create_params.py b/src/letta_client/types/conversation_create_params.py index 142b38b5..af64eadf 100644 --- a/src/letta_client/types/conversation_create_params.py +++ b/src/letta_client/types/conversation_create_params.py @@ -5,7 +5,6 @@ from typing import Union, Optional from typing_extensions import Literal, Required, TypeAlias, TypedDict -from .._types import SequenceNotStr from .xai_model_settings_param import XaiModelSettingsParam from .groq_model_settings_param import GroqModelSettingsParam from .azure_model_settings_param import AzureModelSettingsParam @@ -26,9 +25,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -50,13 +54,6 @@ class ConversationCreateParams(TypedDict, total=False): hidden: bool """Whether the new conversation should be hidden from listings.""" - isolated_block_labels: Optional[SequenceNotStr[str]] - """ - List of block labels that should be isolated (conversation-specific) rather than - shared across conversations. New blocks will be created as copies of the agent's - blocks with these labels. - """ - model: Optional[str] """The model handle for this conversation (overrides agent's model). @@ -115,6 +112,36 @@ class ModelSettingsSgLangModelSettings(TypedDict, total=False): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -152,6 +179,59 @@ class ModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: ModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -226,7 +306,9 @@ class ModelSettingsChatGptoAuthModelSettings(TypedDict, total=False): GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/conversation_recompile_params.py b/src/letta_client/types/conversation_recompile_params.py index 4e551d24..4d49b064 100644 --- a/src/letta_client/types/conversation_recompile_params.py +++ b/src/letta_client/types/conversation_recompile_params.py @@ -26,9 +26,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -100,6 +105,36 @@ class CompactionSettingsModelSettingsSgLangModelSettings(TypedDict, total=False) """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -137,6 +172,59 @@ class CompactionSettingsModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -211,7 +299,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(TypedDict, total= GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/conversation_update_params.py b/src/letta_client/types/conversation_update_params.py index 3692207c..8c388a6a 100644 --- a/src/letta_client/types/conversation_update_params.py +++ b/src/letta_client/types/conversation_update_params.py @@ -27,9 +27,14 @@ "ModelSettingsSgLangModelSettings", "ModelSettingsSgLangModelSettingsReasoning", "ModelSettingsSgLangModelSettingsResponseFormat", + "ModelSettingsMoonshotModelSettings", + "ModelSettingsMoonshotModelSettingsResponseFormat", "ModelSettingsZaiModelSettings", "ModelSettingsZaiModelSettingsResponseFormat", "ModelSettingsZaiModelSettingsThinking", + "ModelSettingsMoonshotCodingModelSettings", + "ModelSettingsMoonshotCodingModelSettingsResponseFormat", + "ModelSettingsMoonshotCodingModelSettingsThinking", "ModelSettingsBasetenModelSettings", "ModelSettingsOpenRouterModelSettings", "ModelSettingsOpenRouterModelSettingsResponseFormat", @@ -109,6 +114,36 @@ class ModelSettingsSgLangModelSettings(TypedDict, total=False): """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +ModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + ModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -146,6 +181,59 @@ class ModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +ModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class ModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class ModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[ModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: ModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class ModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -220,7 +308,9 @@ class ModelSettingsChatGptoAuthModelSettings(TypedDict, total=False): GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + ModelSettingsMoonshotModelSettings, ModelSettingsZaiModelSettings, + ModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/conversations/message_compact_params.py b/src/letta_client/types/conversations/message_compact_params.py index 4854335c..333d7b2a 100644 --- a/src/letta_client/types/conversations/message_compact_params.py +++ b/src/letta_client/types/conversations/message_compact_params.py @@ -26,9 +26,14 @@ "CompactionSettingsModelSettingsSgLangModelSettings", "CompactionSettingsModelSettingsSgLangModelSettingsReasoning", "CompactionSettingsModelSettingsSgLangModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotModelSettings", + "CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettings", "CompactionSettingsModelSettingsZaiModelSettingsResponseFormat", "CompactionSettingsModelSettingsZaiModelSettingsThinking", + "CompactionSettingsModelSettingsMoonshotCodingModelSettings", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat", + "CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking", "CompactionSettingsModelSettingsBasetenModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettings", "CompactionSettingsModelSettingsOpenRouterModelSettingsResponseFormat", @@ -97,6 +102,36 @@ class CompactionSettingsModelSettingsSgLangModelSettings(TypedDict, total=False) """SGLang tool call parser name (for example 'glm47', 'qwen25', or 'hermes').""" +CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotModelSettings(TypedDict, total=False): + """Moonshot/Kimi model configuration (OpenAI-compatible).""" + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + CompactionSettingsModelSettingsZaiModelSettingsResponseFormat: TypeAlias = Union[ TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam ] @@ -134,6 +169,59 @@ class CompactionSettingsModelSettingsZaiModelSettings(TypedDict, total=False): """The thinking configuration for GLM-4.5+ models.""" +CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat: TypeAlias = Union[ + TextResponseFormatParam, JsonSchemaResponseFormatParam, JsonObjectResponseFormatParam +] + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking(TypedDict, total=False): + """The thinking configuration for the model.""" + + budget_tokens: int + """The maximum number of tokens the model can use for extended thinking.""" + + type: Literal["enabled", "disabled"] + """The type of thinking to use.""" + + +class CompactionSettingsModelSettingsMoonshotCodingModelSettings(TypedDict, total=False): + """Kimi Code model configuration (Anthropic-compatible).""" + + effort: Optional[Literal["low", "medium", "high", "xhigh", "max"]] + """Effort level for supported Anthropic models (controls token spending). + + 'xhigh' and 'max' are available on Opus 4.6+. Not setting this gives similar + performance to 'high'. + """ + + max_output_tokens: int + """The maximum number of tokens the model can generate.""" + + parallel_tool_calls: bool + """Whether to enable parallel tool calling.""" + + provider_type: Literal["moonshot_coding"] + """The type of the provider.""" + + response_format: Optional[CompactionSettingsModelSettingsMoonshotCodingModelSettingsResponseFormat] + """The response format for the model.""" + + strict: bool + """Enable strict mode for tool calling. + + When true, tool outputs are guaranteed to match JSON schemas. + """ + + temperature: float + """The temperature of the model.""" + + thinking: CompactionSettingsModelSettingsMoonshotCodingModelSettingsThinking + """The thinking configuration for the model.""" + + verbosity: Optional[Literal["low", "medium", "high"]] + """Soft control for how verbose model output should be, used for GPT-5 models.""" + + class CompactionSettingsModelSettingsBasetenModelSettings(TypedDict, total=False): """Baseten model configuration (OpenAI-compatible).""" @@ -208,7 +296,9 @@ class CompactionSettingsModelSettingsChatGptoAuthModelSettings(TypedDict, total= GoogleVertexModelSettingsParam, AzureModelSettingsParam, XaiModelSettingsParam, + CompactionSettingsModelSettingsMoonshotModelSettings, CompactionSettingsModelSettingsZaiModelSettings, + CompactionSettingsModelSettingsMoonshotCodingModelSettings, GroqModelSettingsParam, DeepseekModelSettingsParam, TogetherModelSettingsParam, diff --git a/src/letta_client/types/llm_config.py b/src/letta_client/types/llm_config.py index 184dacf5..f64e612c 100644 --- a/src/letta_client/types/llm_config.py +++ b/src/letta_client/types/llm_config.py @@ -53,6 +53,8 @@ class LlmConfig(BaseModel): "vllm", "hugging-face", "minimax", + "moonshot", + "moonshot_coding", "mistral", "together", "bedrock", diff --git a/src/letta_client/types/llm_config_param.py b/src/letta_client/types/llm_config_param.py index 3015ffe9..7cca8b75 100644 --- a/src/letta_client/types/llm_config_param.py +++ b/src/letta_client/types/llm_config_param.py @@ -49,6 +49,8 @@ class LlmConfigParam(TypedDict, total=False): "vllm", "hugging-face", "minimax", + "moonshot", + "moonshot_coding", "mistral", "together", "bedrock", diff --git a/src/letta_client/types/model.py b/src/letta_client/types/model.py index 79cbc9bf..13fe0042 100644 --- a/src/letta_client/types/model.py +++ b/src/letta_client/types/model.py @@ -53,6 +53,8 @@ class Model(BaseModel): "hugging-face", "baseten", "minimax", + "moonshot", + "moonshot_coding", "mistral", "together", "bedrock", diff --git a/src/letta_client/types/provider_type.py b/src/letta_client/types/provider_type.py index 98e5919f..48df3f53 100644 --- a/src/letta_client/types/provider_type.py +++ b/src/letta_client/types/provider_type.py @@ -20,6 +20,8 @@ "letta", "lmstudio_openai", "minimax", + "moonshot", + "moonshot_coding", "mistral", "ollama", "openai", diff --git a/tests/api_resources/agents/test_blocks.py b/tests/api_resources/agents/test_blocks.py index 6e15ce88..8a5eb420 100644 --- a/tests/api_resources/agents/test_blocks.py +++ b/tests/api_resources/agents/test_blocks.py @@ -162,7 +162,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="block-123e4567-e89b-42d3-8456-426614174000", before="block-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -456,7 +456,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="block-123e4567-e89b-42d3-8456-426614174000", before="block-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/agents/test_files.py b/tests/api_resources/agents/test_files.py index 7afee971..c364aa30 100644 --- a/tests/api_resources/agents/test_files.py +++ b/tests/api_resources/agents/test_files.py @@ -35,7 +35,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: before="file-123e4567-e89b-42d3-8456-426614174000", cursor="cursor", is_open=True, - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -244,7 +244,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No before="file-123e4567-e89b-42d3-8456-426614174000", cursor="cursor", is_open=True, - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/agents/test_folders.py b/tests/api_resources/agents/test_folders.py index 3da566b0..394fefa4 100644 --- a/tests/api_resources/agents/test_folders.py +++ b/tests/api_resources/agents/test_folders.py @@ -34,7 +34,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="source-123e4567-e89b-42d3-8456-426614174000", before="source-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -199,7 +199,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="source-123e4567-e89b-42d3-8456-426614174000", before="source-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/agents/test_messages.py b/tests/api_resources/agents/test_messages.py index 7725550b..bdb14127 100644 --- a/tests/api_resources/agents/test_messages.py +++ b/tests/api_resources/agents/test_messages.py @@ -249,7 +249,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: group_id="group_id", include_err=True, include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", order_by="created_at", use_assistant_message=True, @@ -888,7 +888,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No group_id="group_id", include_err=True, include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", order_by="created_at", use_assistant_message=True, diff --git a/tests/api_resources/agents/test_passages.py b/tests/api_resources/agents/test_passages.py index 4396fe7f..d4d5c3c1 100644 --- a/tests/api_resources/agents/test_passages.py +++ b/tests/api_resources/agents/test_passages.py @@ -95,7 +95,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: after="after", ascending=True, before="before", - limit=0, + limit=200, search="search", ) assert_matches_type(PassageListResponse, passage, path=["response"]) @@ -325,7 +325,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No after="after", ascending=True, before="before", - limit=0, + limit=200, search="search", ) assert_matches_type(PassageListResponse, passage, path=["response"]) diff --git a/tests/api_resources/agents/test_tools.py b/tests/api_resources/agents/test_tools.py index 528d4992..7111bd14 100644 --- a/tests/api_resources/agents/test_tools.py +++ b/tests/api_resources/agents/test_tools.py @@ -36,7 +36,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="tool-123e4567-e89b-42d3-8456-426614174000", before="tool-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -331,7 +331,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No agent_id="agent-123e4567-e89b-42d3-8456-426614174000", after="tool-123e4567-e89b-42d3-8456-426614174000", before="tool-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/blocks/test_agents.py b/tests/api_resources/blocks/test_agents.py index 5a70a050..68a43c91 100644 --- a/tests/api_resources/blocks/test_agents.py +++ b/tests/api_resources/blocks/test_agents.py @@ -35,7 +35,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: before="agent-123e4567-e89b-42d3-8456-426614174000", include=["agent.blocks", "agent.identities"], include_relationships=["string", "string"], - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -98,7 +98,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No before="agent-123e4567-e89b-42d3-8456-426614174000", include=["agent.blocks", "agent.identities"], include_relationships=["string", "string"], - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/conversations/test_messages.py b/tests/api_resources/conversations/test_messages.py index cffede05..b7f1e8e4 100644 --- a/tests/api_resources/conversations/test_messages.py +++ b/tests/api_resources/conversations/test_messages.py @@ -139,7 +139,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: group_id="group_id", include_err=True, include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -427,7 +427,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No group_id="group_id", include_err=True, include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/folders/test_agents.py b/tests/api_resources/folders/test_agents.py index 068035ca..ae33927e 100644 --- a/tests/api_resources/folders/test_agents.py +++ b/tests/api_resources/folders/test_agents.py @@ -32,7 +32,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: folder_id="source-123e4567-e89b-42d3-8456-426614174000", after="agent-123e4567-e89b-42d3-8456-426614174000", before="agent-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -93,7 +93,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No folder_id="source-123e4567-e89b-42d3-8456-426614174000", after="agent-123e4567-e89b-42d3-8456-426614174000", before="agent-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/folders/test_files.py b/tests/api_resources/folders/test_files.py index 8e4114e1..ab7861c2 100644 --- a/tests/api_resources/folders/test_files.py +++ b/tests/api_resources/folders/test_files.py @@ -100,7 +100,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: after="file-123e4567-e89b-42d3-8456-426614174000", before="file-123e4567-e89b-42d3-8456-426614174000", include_content=True, - limit=0, + limit=1000, order="asc", order_by="created_at", ) @@ -333,7 +333,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No after="file-123e4567-e89b-42d3-8456-426614174000", before="file-123e4567-e89b-42d3-8456-426614174000", include_content=True, - limit=0, + limit=1000, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/runs/test_messages.py b/tests/api_resources/runs/test_messages.py index 4303b9d4..3be0c2ed 100644 --- a/tests/api_resources/runs/test_messages.py +++ b/tests/api_resources/runs/test_messages.py @@ -33,7 +33,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: run_id="run_id", after="message-123e4567-e89b-42d3-8456-426614174000", before="message-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -150,7 +150,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No run_id="run_id", after="message-123e4567-e89b-42d3-8456-426614174000", before="message-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/runs/test_steps.py b/tests/api_resources/runs/test_steps.py index f297ea67..c18a94c6 100644 --- a/tests/api_resources/runs/test_steps.py +++ b/tests/api_resources/runs/test_steps.py @@ -33,7 +33,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: run_id="run_id", after="step-123e4567-e89b-42d3-8456-426614174000", before="step-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -94,7 +94,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No run_id="run_id", after="step-123e4567-e89b-42d3-8456-426614174000", before="step-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/steps/test_messages.py b/tests/api_resources/steps/test_messages.py index c8d3cba2..f98dc9ee 100644 --- a/tests/api_resources/steps/test_messages.py +++ b/tests/api_resources/steps/test_messages.py @@ -33,7 +33,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: step_id="step-123e4567-e89b-42d3-8456-426614174000", after="message-123e4567-e89b-42d3-8456-426614174000", before="message-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) @@ -94,7 +94,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No step_id="step-123e4567-e89b-42d3-8456-426614174000", after="message-123e4567-e89b-42d3-8456-426614174000", before="message-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, order="asc", order_by="created_at", ) diff --git a/tests/api_resources/test_agents.py b/tests/api_resources/test_agents.py index 1883579b..a01ce5c1 100644 --- a/tests/api_resources/test_agents.py +++ b/tests/api_resources/test_agents.py @@ -451,7 +451,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: include=["agent.blocks", "agent.identities"], include_relationships=["string", "string"], last_stop_reason="end_turn", - limit=0, + limit=200, match_all_tags=True, name="name", order="asc", @@ -1124,7 +1124,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No include=["agent.blocks", "agent.identities"], include_relationships=["string", "string"], last_stop_reason="end_turn", - limit=0, + limit=200, match_all_tags=True, name="name", order="asc", diff --git a/tests/api_resources/test_archives.py b/tests/api_resources/test_archives.py index 2eccacb1..ae8d3c9c 100644 --- a/tests/api_resources/test_archives.py +++ b/tests/api_resources/test_archives.py @@ -183,7 +183,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: after="archive-123e4567-e89b-42d3-8456-426614174000", agent_id="agent_id", before="archive-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, name="name", order="asc", order_by="created_at", @@ -423,7 +423,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No after="archive-123e4567-e89b-42d3-8456-426614174000", agent_id="agent_id", before="archive-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, name="name", order="asc", order_by="created_at", diff --git a/tests/api_resources/test_blocks.py b/tests/api_resources/test_blocks.py index b194b0da..2dc78964 100644 --- a/tests/api_resources/test_blocks.py +++ b/tests/api_resources/test_blocks.py @@ -206,7 +206,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: identity_id="identity-123e4567-e89b-42d3-8456-426614174000", label="human", label_search="human", - limit=0, + limit=200, match_all_tags=True, name="My Agent", order="asc", @@ -476,7 +476,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No identity_id="identity-123e4567-e89b-42d3-8456-426614174000", label="human", label_search="human", - limit=0, + limit=200, match_all_tags=True, name="My Agent", order="asc", diff --git a/tests/api_resources/test_conversations.py b/tests/api_resources/test_conversations.py index 96576ecb..f441eb28 100644 --- a/tests/api_resources/test_conversations.py +++ b/tests/api_resources/test_conversations.py @@ -37,7 +37,6 @@ def test_method_create_with_all_params(self, client: Letta) -> None: agent_id="agent_id", context_window_limit=0, hidden=True, - isolated_block_labels=["string"], model="model", model_settings={ "max_output_tokens": 0, @@ -197,7 +196,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: after="conv-123e4567-e89b-42d3-8456-426614174000", agent_id="agent_id", archive_status="unarchived", - limit=0, + limit=200, order="asc", order_by="created_at", summary_search="summary_search", @@ -461,7 +460,6 @@ async def test_method_create_with_all_params(self, async_client: AsyncLetta) -> agent_id="agent_id", context_window_limit=0, hidden=True, - isolated_block_labels=["string"], model="model", model_settings={ "max_output_tokens": 0, @@ -621,7 +619,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No after="conv-123e4567-e89b-42d3-8456-426614174000", agent_id="agent_id", archive_status="unarchived", - limit=0, + limit=200, order="asc", order_by="created_at", summary_search="summary_search", diff --git a/tests/api_resources/test_folders.py b/tests/api_resources/test_folders.py index ce806dd9..41464980 100644 --- a/tests/api_resources/test_folders.py +++ b/tests/api_resources/test_folders.py @@ -197,7 +197,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: folder = client.folders.list( after="source-123e4567-e89b-42d3-8456-426614174000", before="source-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, name="name", order="asc", order_by="created_at", @@ -453,7 +453,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No folder = await async_client.folders.list( after="source-123e4567-e89b-42d3-8456-426614174000", before="source-123e4567-e89b-42d3-8456-426614174000", - limit=0, + limit=200, name="name", order="asc", order_by="created_at", diff --git a/tests/api_resources/test_messages.py b/tests/api_resources/test_messages.py index d903fda6..a40099da 100644 --- a/tests/api_resources/test_messages.py +++ b/tests/api_resources/test_messages.py @@ -78,7 +78,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: before="message-123e4567-e89b-42d3-8456-426614174000", conversation_id="conversation_id", include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", ) assert_matches_type(MessageListResponse, message, path=["response"]) @@ -215,7 +215,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No before="message-123e4567-e89b-42d3-8456-426614174000", conversation_id="conversation_id", include_return_message_types=["system_message", "user_message"], - limit=0, + limit=200, order="asc", ) assert_matches_type(MessageListResponse, message, path=["response"]) diff --git a/tests/api_resources/test_steps.py b/tests/api_resources/test_steps.py index dd525282..37894cc6 100644 --- a/tests/api_resources/test_steps.py +++ b/tests/api_resources/test_steps.py @@ -76,7 +76,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: end_date="end_date", feedback="positive", has_feedback=True, - limit=0, + limit=200, model="model", order="asc", order_by="created_at", @@ -173,7 +173,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No end_date="end_date", feedback="positive", has_feedback=True, - limit=0, + limit=200, model="model", order="asc", order_by="created_at", diff --git a/tests/api_resources/test_tags.py b/tests/api_resources/test_tags.py index 0c90762f..df9af43a 100644 --- a/tests/api_resources/test_tags.py +++ b/tests/api_resources/test_tags.py @@ -29,7 +29,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: tag = client.tags.list( after="after", before="before", - limit=0, + limit=200, name="name", order="asc", order_by="name", @@ -77,7 +77,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No tag = await async_client.tags.list( after="after", before="before", - limit=0, + limit=200, name="name", order="asc", order_by="name", diff --git a/tests/api_resources/test_tools.py b/tests/api_resources/test_tools.py index 8e50bc4a..5bc698dc 100644 --- a/tests/api_resources/test_tools.py +++ b/tests/api_resources/test_tools.py @@ -210,7 +210,7 @@ def test_method_list_with_all_params(self, client: Letta) -> None: after="tool-123e4567-e89b-42d3-8456-426614174000", before="tool-123e4567-e89b-42d3-8456-426614174000", exclude_tool_types=["string", "string"], - limit=0, + limit=200, name="name", names=["string", "string"], order="asc", @@ -583,7 +583,7 @@ async def test_method_list_with_all_params(self, async_client: AsyncLetta) -> No after="tool-123e4567-e89b-42d3-8456-426614174000", before="tool-123e4567-e89b-42d3-8456-426614174000", exclude_tool_types=["string", "string"], - limit=0, + limit=200, name="name", names=["string", "string"], order="asc", diff --git a/tests/test_extract_files.py b/tests/test_extract_files.py index de045f76..b8a5b412 100644 --- a/tests/test_extract_files.py +++ b/tests/test_extract_files.py @@ -4,7 +4,7 @@ import pytest -from letta_client._types import FileTypes +from letta_client._types import FileTypes, ArrayFormat from letta_client._utils import extract_files @@ -37,10 +37,7 @@ def test_multiple_files() -> None: def test_top_level_file_array() -> None: query = {"files": [b"file one", b"file two"], "title": "hello"} - assert extract_files(query, paths=[["files", ""]]) == [ - ("files[]", b"file one"), - ("files[]", b"file two"), - ] + assert extract_files(query, paths=[["files", ""]]) == [("files[]", b"file one"), ("files[]", b"file two")] assert query == {"title": "hello"} @@ -71,3 +68,24 @@ def test_ignores_incorrect_paths( expected: list[tuple[str, FileTypes]], ) -> None: assert extract_files(query, paths=paths) == expected + + +@pytest.mark.parametrize( + "array_format,expected_top_level,expected_nested", + [ + ("brackets", [("files[]", b"a"), ("files[]", b"b")], [("items[][file]", b"a"), ("items[][file]", b"b")]), + ("repeat", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("comma", [("files", b"a"), ("files", b"b")], [("items[file]", b"a"), ("items[file]", b"b")]), + ("indices", [("files[0]", b"a"), ("files[1]", b"b")], [("items[0][file]", b"a"), ("items[1][file]", b"b")]), + ], +) +def test_array_format_controls_file_field_names( + array_format: ArrayFormat, + expected_top_level: list[tuple[str, FileTypes]], + expected_nested: list[tuple[str, FileTypes]], +) -> None: + top_level = {"files": [b"a", b"b"]} + assert extract_files(top_level, paths=[["files", ""]], array_format=array_format) == expected_top_level + + nested = {"items": [{"file": b"a"}, {"file": b"b"}]} + assert extract_files(nested, paths=[["items", "", "file"]], array_format=array_format) == expected_nested diff --git a/tests/test_files.py b/tests/test_files.py index 0fface64..c2db4666 100644 --- a/tests/test_files.py +++ b/tests/test_files.py @@ -131,7 +131,7 @@ def test_extract_files_does_not_mutate_original_nested_array_path(self) -> None: copied = deepcopy_with_paths(original, [["items", "", "file"]]) extracted = extract_files(copied, paths=[["items", "", "file"]]) - assert extracted == [("items[][file]", file1), ("items[][file]", file2)] + assert [entry for _, entry in extracted] == [file1, file2] assert original == { "items": [ {"file": file1, "extra": 1}, diff --git a/tests/test_models.py b/tests/test_models.py index a4557fa5..47db2e86 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,7 +1,8 @@ import json -from typing import TYPE_CHECKING, Any, Dict, List, Union, Optional, cast +from typing import TYPE_CHECKING, Any, Dict, List, Union, Iterable, Optional, cast from datetime import datetime, timezone -from typing_extensions import Literal, Annotated, TypeAliasType +from collections import deque +from typing_extensions import Literal, Annotated, TypedDict, TypeAliasType import pytest import pydantic @@ -9,7 +10,7 @@ from letta_client._utils import PropertyInfo from letta_client._compat import PYDANTIC_V1, parse_obj, model_dump, model_json -from letta_client._models import DISCRIMINATOR_CACHE, BaseModel, construct_type +from letta_client._models import DISCRIMINATOR_CACHE, BaseModel, EagerIterable, construct_type class BasicModel(BaseModel): @@ -961,3 +962,56 @@ def __getattr__(self, attr: str) -> Item: ... assert model.a.prop == 1 assert isinstance(model.a, Item) assert model.other == "foo" + + +# NOTE: Workaround for Pydantic Iterable behavior. +# Iterable fields are replaced with a ValidatorIterator and may be consumed +# during serialization, which can cause subsequent dumps to return empty data. +# See: https://github.com/pydantic/pydantic/issues/9541 +@pytest.mark.parametrize( + "data, expected_validated", + [ + ([1, 2, 3], [1, 2, 3]), + ((1, 2, 3), (1, 2, 3)), + (set([1, 2, 3]), set([1, 2, 3])), + (iter([1, 2, 3]), [1, 2, 3]), + ([], []), + ((x for x in [1, 2, 3]), [1, 2, 3]), + (map(lambda x: x, [1, 2, 3]), [1, 2, 3]), + (frozenset([1, 2, 3]), frozenset([1, 2, 3])), + (deque([1, 2, 3]), deque([1, 2, 3])), + ], + ids=["list", "tuple", "set", "iterator", "empty", "generator", "map", "frozenset", "deque"], +) +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction(data: Iterable[int], expected_validated: Iterable[int]) -> None: + class TypeWithIterable(TypedDict): + items: EagerIterable[int] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": data}}) + assert m.data["items"] == expected_validated + + # Verify repeated dumps don't lose data (the original bug) + assert m.model_dump()["data"]["items"] == list(expected_validated) + assert m.model_dump()["data"]["items"] == list(expected_validated) + + +@pytest.mark.skipif(PYDANTIC_V1, reason="this is only supported in pydantic v2") +def test_iterable_construction_str_falls_back_to_list() -> None: + # str is iterable (over chars), but str(list_of_chars) produces the list's repr + # rather than reconstructing a string from items. We special-case str to fall + # back to list instead of attempting reconstruction. + class TypeWithIterable(TypedDict): + items: EagerIterable[str] + + class Model(BaseModel): + data: TypeWithIterable + + m = Model.model_validate({"data": {"items": "hello"}}) + + # falls back to list of chars rather than calling str(["h", "e", "l", "l", "o"]) + assert m.data["items"] == ["h", "e", "l", "l", "o"] + assert m.model_dump()["data"]["items"] == ["h", "e", "l", "l", "o"]