diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 28e97ad4..5ce87411 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,19 +1,19 @@ lockVersion: 2.0.0 id: c48cf606-fb42-4a45-9c23-8f0555307828 management: - docChecksum: a103037538d332613316e13a17300983 + docChecksum: ca7e6ffbc81c23f4f96f028264d3a0c6 docVersion: 1.0.0 speakeasyVersion: 1.803.2 generationVersion: 2.950.13 - releaseVersion: 1.3.131 - configChecksum: adc032422d0efdef82e0f3fb3c072d6f + releaseVersion: 1.3.132 + configChecksum: e6838479b1c5f69c83e3581e1ec5fdda repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 00299001-7278-4525-85df-299f2c3aa458 - pristine_commit_hash: b4d0a6a296b91d7f678af19ecde12c49c08a9f3c - pristine_tree_hash: 758afb314231c4d0aad04d3f5bb0203ebf49e93b + generation_id: ed8669f6-9e68-4aa9-9ba3-bfbe3f645b6a + pristine_commit_hash: baca27461f2201c3c005cc8adafe4d3e558059d5 + pristine_tree_hash: 9696b5accb25cbb15b40e39f1214bd7e04273282 features: python: acceptHeaders: 3.0.0 @@ -2020,8 +2020,8 @@ trackedFiles: pristine_git_object: e2ecd460775d54a5b43c5bc597f8027424462b8d docs/components/chatrequestreasoning.mdx: id: 8f0176992b3e - last_write_checksum: sha1:784cf74791cfbd6b92cd02b368f97b7826b511aa - pristine_git_object: 1c04df67ad034913cdb2a139f05821023c4977b4 + last_write_checksum: sha1:3247d0ea825f01d20bea2ecee221e3e6b33cf035 + pristine_git_object: 057e91d78f416d541dd4c3ce4d07125fd06aa8e0 docs/components/chatrequestreasoningeffort.mdx: id: a8ac4d0f36fd last_write_checksum: sha1:7cf50deaeb4a20ca64352b8713479059834e5f78 @@ -10440,8 +10440,12 @@ trackedFiles: pristine_git_object: e0298f128f4fac5b60ecbd405fc4f251ed23c128 docs/operations/listresponse.mdx: id: 0fbda0f81ae8 - last_write_checksum: sha1:73963968eb448421e0ad3a5a442192da7c46c6a9 - pristine_git_object: a39b3dad1e5a8250b05181280a5b81e2042244a0 + last_write_checksum: sha1:038d67577055fc228a26c28173b10968f116570a + pristine_git_object: d6a65aadf3cfc06e13ef3c2b40004c3f7d52e3aa + docs/operations/listresponsebody.mdx: + id: 2608b7720d49 + last_write_checksum: sha1:57867f1dcfdfe3106e329a2ba6026b5a4a3acf47 + pristine_git_object: c66af276a0d1722a9b8c9797f651c6af297d3cac docs/operations/listscimgroupmappingsglobals.mdx: id: 895d22ec37c3 last_write_checksum: sha1:32c624e1f723d52068a5de4bb763dac0325b4b1d @@ -10856,8 +10860,8 @@ trackedFiles: pristine_git_object: 2cfd14c40ab962877968c79c6c958ea432a4f083 docs/sdks/apikeys/README.mdx: id: 27fcaae1c346 - last_write_checksum: sha1:80273bedf61e6131728eaafbdea8c2a9e7d8e7e7 - pristine_git_object: c2e930c8fceb2d22431d2a2be01ceb227df72937 + last_write_checksum: sha1:09195a526bc468df6743e47dbdee79949f66e77c + pristine_git_object: 2f4950880ee5164aa8988d13d4eba940778d5f17 docs/sdks/batch/README.mdx: id: e367aa4f4295 last_write_checksum: sha1:e5084fc19c2bfc9aa28e90a86d4accb5c9153130 @@ -11008,8 +11012,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:ec5bd30f505e4052b284661c9a29ff2fac35647c - pristine_git_object: e0c226a4f028f7fc0bd43c0c16ccf7997cf300ae + last_write_checksum: sha1:ddf3436a53d9ced3db7db5e63b0195f1d67a09b0 + pristine_git_object: 326597ffe04f2ab8bcd91c8164128eeef3acc969 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -11036,8 +11040,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:a6b9ba70c16d696c1b6b2786b6bc21465a2da557 - pristine_git_object: 26e24a92c8db5c8328a8fb4655c0c4abc9c72a49 + last_write_checksum: sha1:81469ff054eae539eb5d2bd9ef2ec462ba5f9b17 + pristine_git_object: 4c8151ae024627c7c683ab46a866d3893b3d0efe src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766 @@ -11048,8 +11052,8 @@ trackedFiles: pristine_git_object: 0e567f3a37cc6aeb45a2551d0d500412e4b7796d src/openrouter/api_keys.py: id: 876fac88fff6 - last_write_checksum: sha1:3a2893899424d7129a75bf66fd877c83d54af502 - pristine_git_object: 28616aac95dc38d48923169945f49cf2bceeeaf2 + last_write_checksum: sha1:eee27956e31d7525d8cfbc9177d5b79db2b3aab3 + pristine_git_object: 73c16d709a3b6f578233a79c00211dadd67e77a5 src/openrouter/basesdk.py: id: c5733c5a1e12 last_write_checksum: sha1:65769ff2cb5473f85b364c6213a0ddc8c68644ea @@ -11928,8 +11932,8 @@ trackedFiles: pristine_git_object: 8bbde153b53887e426989fd5b0486b6dc1122810 src/openrouter/components/chatrequest.py: id: 5e39eaefa9cf - last_write_checksum: sha1:ae69df07e940af7449bd9a974d404886becfd00f - pristine_git_object: b278ed4451980d3550bed9907e638a184b28e257 + last_write_checksum: sha1:34203bf0d944f6c4baa608b3600089b7b82d7210 + pristine_git_object: 5fc9915bea11993b3149d3d06dc367b75219f0be src/openrouter/components/chatresult.py: id: 9062fe2935fe last_write_checksum: sha1:832ad4df3f9f92818e36e9d26a73da3bcff3eb7a @@ -14904,8 +14908,8 @@ trackedFiles: pristine_git_object: 4a35ede011d09dddab042e2c00413ce4f6be655e src/openrouter/operations/__init__.py: id: 9afcea1e7161 - last_write_checksum: sha1:3549a224597521d4f1d080a8d9acdfd6a9de3fa7 - pristine_git_object: 7319f555fe88b80496da7b646185e294f6d83d38 + last_write_checksum: sha1:62969538c6bbd7a6bbf9509c09299d5f32e41304 + pristine_git_object: 6f0b96c552f725aa1e7660e7c0afdac1168291b3 src/openrouter/operations/activateprivateendpoint.py: id: 3b39eec5d66f last_write_checksum: sha1:9406e6b3d38c82895fd795f637702ef579cc6d36 @@ -15248,8 +15252,8 @@ trackedFiles: pristine_git_object: 0365c6edd5a01c4086dfcf75d326fb48a67ad9d6 src/openrouter/operations/list.py: id: 3ced31e3804e - last_write_checksum: sha1:ed6233bd58de02cb3126d333c2e361b83d8b5bce - pristine_git_object: bf7d30f58097da5c25d83a257163f280c7276693 + last_write_checksum: sha1:f139bef84fb09ba815b0529517988ff109c13cba + pristine_git_object: 8abf4d7aa09edae2e53f7fac0b90d701e9889f98 src/openrouter/operations/listbatches.py: id: 9ad1345dc956 last_write_checksum: sha1:b7017793a979647ef2ec7fee333e34063664c9eb @@ -20204,7 +20208,4 @@ examples: "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: | - ## Python SDK Changes: - * `open_router.alpha.decisions.create()`: `response.usage` **Changed** - * `open_router.system_one.create()`: `response.usage` **Changed** +releaseNotes: "## Python SDK Changes:\n* `open_router.presets.create_presets_chat_completions()`: \n * `request.reasoning.max_tokens` **Added**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 46a7cb80..1b71fa6c 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -37,7 +37,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.131 + version: 1.3.132 additionalDependencies: dev: pytest: '>=8.3' diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index c517e7f6..7f183d9b 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -8018,6 +8018,12 @@ components: - 'string' - 'null' x-speakeasy-unknown-values: allow + max_tokens: + description: 'Maximum number of tokens the model may spend on reasoning, for models that take a reasoning token budget instead of an effort level. Cannot be combined with `reasoning.effort` or the top-level `reasoning_effort`: a request that sets both is rejected with "Only one of "reasoning.effort" and "reasoning.max_tokens" can be specified".' + example: 2000 + type: + - 'integer' + - 'null' summary: $ref: '#/components/schemas/ChatReasoningSummaryVerbosityEnum' type: 'object' @@ -45949,6 +45955,14 @@ paths: tags: - 'API Keys' x-speakeasy-name-override: 'list' + x-speakeasy-pagination: + inputs: + - in: 'parameters' + name: 'offset' + type: 'offset' + outputs: + results: '$.data' + type: 'offsetLimit' post: description: 'Create a new API key for the authenticated user. The plaintext `key` is returned only in this response. Treat it as a write-only, sensitive value; it cannot be retrieved later. Authenticate with a [management key](/docs/guides/overview/auth/management-api-keys). The optional `external` object associates the key with a partner-defined user and lookup key.' operationId: 'createKeys' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index ed015a05..164f90ea 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.803.2 sources: OpenRouter API: sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:1fbf0ee26aa1ab7658acda2193df1c36156f4f7b68ccdc009f23357819e34c9c - sourceBlobDigest: sha256:877af691c84d4fdbe8207d6f21a620711e2b9ad0b87868945f9082d1e7d90178 + sourceRevisionDigest: sha256:7fa53baff74eba40ecab14053aff50edff9bfeda6cc0c9a253bbf5dacce30f92 + sourceBlobDigest: sha256:25762da0a3ec232b94ad91452bf08c3c87f0fa962252a43cda859120cccaf1ec tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:1fbf0ee26aa1ab7658acda2193df1c36156f4f7b68ccdc009f23357819e34c9c - sourceBlobDigest: sha256:877af691c84d4fdbe8207d6f21a620711e2b9ad0b87868945f9082d1e7d90178 + sourceRevisionDigest: sha256:7fa53baff74eba40ecab14053aff50edff9bfeda6cc0c9a253bbf5dacce30f92 + sourceBlobDigest: sha256:25762da0a3ec232b94ad91452bf08c3c87f0fa962252a43cda859120cccaf1ec codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:15a9b9c933c6560ccfe4b3e78bbf894bb543e3cbdfd67777926d3dccd206fca3 + codeSamplesRevisionDigest: sha256:b78bd40223c09d9bc104a66eb734dd5b5306bbb494ca4b6dff108da6578cf178 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.803.2 diff --git a/RELEASES.md b/RELEASES.md index 4e7fa953..323a5bf8 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4079,4 +4079,14 @@ Based on: ### Generated - [python v1.3.131] . ### Releases -- [PyPI v1.3.131] https://pypi.org/project/openrouter/1.3.131 - . \ No newline at end of file +- [PyPI v1.3.131] https://pypi.org/project/openrouter/1.3.131 - . + +## 2026-11-05 21:39:51 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.132] . +### Releases +- [PyPI v1.3.132] https://pypi.org/project/openrouter/1.3.132 - . \ No newline at end of file diff --git a/docs/components/chatrequestreasoning.mdx b/docs/components/chatrequestreasoning.mdx index 1c04df67..057e91d7 100644 --- a/docs/components/chatrequestreasoning.mdx +++ b/docs/components/chatrequestreasoning.mdx @@ -7,7 +7,8 @@ Configuration options for reasoning models ## Fields -| Field | Type | Required | Description | Example | -| -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| `effort` | [OptionalNullable[components.ChatRequestEffort]](../components/chatrequesteffort.mdx) | ➖ | Constrains effort on reasoning for reasoning models | medium | -| `summary` | [OptionalNullable[components.ChatReasoningSummaryVerbosityEnum]](../components/chatreasoningsummaryverbosityenum.mdx) | ➖ | N/A | concise | \ No newline at end of file +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `effort` | [OptionalNullable[components.ChatRequestEffort]](../components/chatrequesteffort.mdx) | ➖ | Constrains effort on reasoning for reasoning models | medium | +| `max_tokens` | *OptionalNullable[int]* | ➖ | Maximum number of tokens the model may spend on reasoning, for models that take a reasoning token budget instead of an effort level. Cannot be combined with `reasoning.effort` or the top-level `reasoning_effort`: a request that sets both is rejected with "Only one of "reasoning.effort" and "reasoning.max_tokens" can be specified". | 2000 | +| `summary` | [OptionalNullable[components.ChatReasoningSummaryVerbosityEnum]](../components/chatreasoningsummaryverbosityenum.mdx) | ➖ | N/A | concise | \ No newline at end of file diff --git a/docs/operations/listresponse.mdx b/docs/operations/listresponse.mdx index a39b3dad..d6a65aad 100644 --- a/docs/operations/listresponse.mdx +++ b/docs/operations/listresponse.mdx @@ -2,11 +2,8 @@ title: "ListResponse" --- -List of API keys - - ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | -| `data` | List[[operations.ListData](../operations/listdata.mdx)] | ✔️ | List of API keys | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `result` | [operations.ListResponseBody](../operations/listresponsebody.mdx) | ✔️ | N/A | \{
"data": [
\{
"byok_usage": 17.38,
"byok_usage_daily": 17.38,
"byok_usage_monthly": 17.38,
"byok_usage_weekly": 17.38,
"created_at": "2025-08-24T10:30:00Z",
"creator_user_id": "user_2dHFtVWx2n56w6HkM0000000000",
"disabled": false,
"expires_at": "2027-12-31T23:59:59Z",
"external_user": null,
"hash": "f01d52606dc8f0a8303a7b5cc3fa07109c2e346cec7c0a16b40de462992ce943",
"include_byok_in_limit": false,
"label": "Production API Key",
"last_used_at": "2026-09-15T15:45:00Z",
"limit": 100,
"limit_remaining": 74.5,
"limit_reset": "monthly",
"name": "My Production Key",
"updated_at": "2025-08-24T15:45:00Z",
"usage": 25.5,
"usage_daily": 25.5,
"usage_monthly": 25.5,
"usage_weekly": 25.5,
"workspace_id": "0df9e665-d932-5740-b2c7-b52af166bc11"
}
]
} | \ No newline at end of file diff --git a/docs/operations/listresponsebody.mdx b/docs/operations/listresponsebody.mdx new file mode 100644 index 00000000..c66af276 --- /dev/null +++ b/docs/operations/listresponsebody.mdx @@ -0,0 +1,12 @@ +--- +title: "ListResponseBody" +--- + +List of API keys + + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | ------------------------------------------------------ | +| `data` | List[[operations.ListData](../operations/listdata.mdx)] | ✔️ | List of API keys | \ No newline at end of file diff --git a/docs/sdks/apikeys/README.mdx b/docs/sdks/apikeys/README.mdx index c2e930c8..2f495088 100644 --- a/docs/sdks/apikeys/README.mdx +++ b/docs/sdks/apikeys/README.mdx @@ -82,8 +82,10 @@ with OpenRouter( res = open_router.api_keys.list() - # Handle response - print(res) + while res is not None: + # Handle items + + res = res.next() ``` diff --git a/pyproject.toml b/pyproject.toml index e0c226a4..326597ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.131" +version = "1.3.132" description = "Official Python Client SDK for OpenRouter." authors = [{ name = "OpenRouter" },] readme = "README-PYPI.md" diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py index 26e24a92..4c8151ae 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "1.3.131" +__version__: str = "1.3.132" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.950.13" -__user_agent__: str = "speakeasy-sdk/python 1.3.131 2.950.13 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.132 2.950.13 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/api_keys.py b/src/openrouter/api_keys.py index 28616aac..73c16d70 100644 --- a/src/openrouter/api_keys.py +++ b/src/openrouter/api_keys.py @@ -2,12 +2,13 @@ from .basesdk import BaseSDK from datetime import datetime +from jsonpath import JSONPath from openrouter import components, errors, operations, utils from openrouter._hooks import HookContext from openrouter.types import OptionalNullable, UNSET from openrouter.utils import get_security_from_env from openrouter.utils.unmarshal_json_response import unmarshal_json_response -from typing import Any, Mapping, Optional, Union +from typing import Any, Awaitable, Dict, List, Mapping, Optional, Union class APIKeys(BaseSDK): @@ -267,7 +268,7 @@ def list( server_url: Optional[str] = None, timeout_ms: Optional[int] = None, http_headers: Optional[Mapping[str, str]] = None, - ) -> operations.ListResponse: + ) -> Optional[operations.ListResponse]: r"""List API keys List all API keys for the authenticated user. [Management key](/docs/guides/overview/auth/management-api-keys) required. @@ -359,9 +360,38 @@ def list( retry_config=retry_config, ) + def next_func() -> Optional[operations.ListResponse]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return None + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return None + next_offset = offset + len(results[0]) + + return self.list( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + include_disabled=include_disabled, + include_expired=include_expired, + offset=next_offset, + workspace_id=workspace_id, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + response_data: Any = None if utils.match_response(http_res, "200", "application/json"): - return unmarshal_json_response(operations.ListResponse, http_res) + return operations.ListResponse( + result=unmarshal_json_response(operations.ListResponseBody, http_res), + next=next_func, + ) if utils.match_response(http_res, "400", "application/json"): response_data = unmarshal_json_response( errors.BadRequestResponseErrorData, http_res @@ -419,7 +449,7 @@ async def list_async( server_url: Optional[str] = None, timeout_ms: Optional[int] = None, http_headers: Optional[Mapping[str, str]] = None, - ) -> operations.ListResponse: + ) -> Optional[operations.ListResponse]: r"""List API keys List all API keys for the authenticated user. [Management key](/docs/guides/overview/auth/management-api-keys) required. @@ -511,9 +541,41 @@ async def list_async( retry_config=retry_config, ) + def next_func() -> Awaitable[Optional[operations.ListResponse]]: + body = utils.unmarshal_json(http_res.text, Union[Dict[Any, Any], List[Any]]) + + async def empty_result(): + return None + + offset = request.offset if isinstance(request.offset, int) else 0 + + if not http_res.text: + return empty_result() + results = JSONPath("$.data").parse(body) + if len(results) == 0 or len(results[0]) == 0: + return empty_result() + next_offset = offset + len(results[0]) + + return self.list_async( + http_referer=http_referer, + x_open_router_title=x_open_router_title, + x_open_router_categories=x_open_router_categories, + include_disabled=include_disabled, + include_expired=include_expired, + offset=next_offset, + workspace_id=workspace_id, + retries=retries, + server_url=server_url, + timeout_ms=timeout_ms, + http_headers=http_headers, + ) + response_data: Any = None if utils.match_response(http_res, "200", "application/json"): - return unmarshal_json_response(operations.ListResponse, http_res) + return operations.ListResponse( + result=unmarshal_json_response(operations.ListResponseBody, http_res), + next=next_func, + ) if utils.match_response(http_res, "400", "application/json"): response_data = unmarshal_json_response( errors.BadRequestResponseErrorData, http_res diff --git a/src/openrouter/components/chatrequest.py b/src/openrouter/components/chatrequest.py index b278ed44..5fc9915b 100644 --- a/src/openrouter/components/chatrequest.py +++ b/src/openrouter/components/chatrequest.py @@ -144,6 +144,8 @@ class ChatRequestReasoningTypedDict(TypedDict): effort: NotRequired[Nullable[ChatRequestEffort]] r"""Constrains effort on reasoning for reasoning models""" + max_tokens: NotRequired[Nullable[int]] + r"""Maximum number of tokens the model may spend on reasoning, for models that take a reasoning token budget instead of an effort level. Cannot be combined with `reasoning.effort` or the top-level `reasoning_effort`: a request that sets both is rejected with \"Only one of \"reasoning.effort\" and \"reasoning.max_tokens\" can be specified\".""" summary: NotRequired[Nullable[ChatReasoningSummaryVerbosityEnum]] @@ -153,12 +155,15 @@ class ChatRequestReasoning(BaseModel): effort: OptionalNullable[ChatRequestEffort] = UNSET r"""Constrains effort on reasoning for reasoning models""" + max_tokens: OptionalNullable[int] = UNSET + r"""Maximum number of tokens the model may spend on reasoning, for models that take a reasoning token budget instead of an effort level. Cannot be combined with `reasoning.effort` or the top-level `reasoning_effort`: a request that sets both is rejected with \"Only one of \"reasoning.effort\" and \"reasoning.max_tokens\" can be specified\".""" + summary: OptionalNullable[ChatReasoningSummaryVerbosityEnum] = UNSET @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["effort", "summary"]) - nullable_fields = set(["effort", "summary"]) + optional_fields = set(["effort", "max_tokens", "summary"]) + nullable_fields = set(["effort", "max_tokens", "summary"]) serialized = handler(self) m = {} diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py index 7319f555..6f0b96c5 100644 --- a/src/openrouter/operations/__init__.py +++ b/src/openrouter/operations/__init__.py @@ -680,6 +680,8 @@ ListRequest, ListRequestTypedDict, ListResponse, + ListResponseBody, + ListResponseBodyTypedDict, ListResponseTypedDict, ) from .listbatches import ( @@ -1784,6 +1786,8 @@ "ListRequest", "ListRequestTypedDict", "ListResponse", + "ListResponseBody", + "ListResponseBodyTypedDict", "ListResponseTypedDict", "ListScimGroupMappingsGlobals", "ListScimGroupMappingsGlobalsTypedDict", @@ -2474,6 +2478,8 @@ "ListRequest": ".list", "ListRequestTypedDict": ".list", "ListResponse": ".list", + "ListResponseBody": ".list", + "ListResponseBodyTypedDict": ".list", "ListResponseTypedDict": ".list", "ListBatchesGlobals": ".listbatches", "ListBatchesGlobalsTypedDict": ".listbatches", diff --git a/src/openrouter/operations/list.py b/src/openrouter/operations/list.py index bf7d30f5..8abf4d7a 100644 --- a/src/openrouter/operations/list.py +++ b/src/openrouter/operations/list.py @@ -12,7 +12,7 @@ from openrouter.utils import FieldMetadata, HeaderMetadata, QueryParamMetadata import pydantic from pydantic import model_serializer -from typing import List, Optional +from typing import Awaitable, Callable, List, Optional, Union from typing_extensions import Annotated, NotRequired, TypedDict @@ -349,15 +349,28 @@ def serialize_model(self, handler): return m -class ListResponseTypedDict(TypedDict): +class ListResponseBodyTypedDict(TypedDict): r"""List of API keys""" data: List[ListDataTypedDict] r"""List of API keys""" -class ListResponse(BaseModel): +class ListResponseBody(BaseModel): r"""List of API keys""" data: List[ListData] r"""List of API keys""" + + +class ListResponseTypedDict(TypedDict): + result: ListResponseBodyTypedDict + + +class ListResponse(BaseModel): + next: Union[ + Callable[[], Optional[ListResponse]], + Callable[[], Awaitable[Optional[ListResponse]]], + ] + + result: ListResponseBody diff --git a/uv.lock b/uv.lock index d9c9720e..82d077b3 100644 --- a/uv.lock +++ b/uv.lock @@ -231,7 +231,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.131" +version = "1.3.132" source = { editable = "." } dependencies = [ { name = "httpcore" },