diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index e1f02e1c..0adec213 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: f8dc91b3c81bf3d705cc827ec9e7a539 + docChecksum: c64e8a1bb43b3df7d97e44bed1a86038 docVersion: 1.0.0 speakeasyVersion: 1.803.2 generationVersion: 2.950.13 - releaseVersion: 1.3.140 - configChecksum: b0f67e896d3d65b70c35fa0825854655 + releaseVersion: 1.3.141 + configChecksum: 57e51fee9c5d53ea72d3e0b8381f6ea8 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: be94a227-9141-446d-b19d-de1422a044e0 - pristine_commit_hash: ae558382b3860a6debb78b1c5edde81051fd2bae - pristine_tree_hash: f6896a0ef56bff0ee3e1998d8adfa81a83450425 + generation_id: 080eb84b-a268-48e1-88f8-5387670ca0b7 + pristine_commit_hash: 0a133e3a8370c6b6c7ffcd95f439e50de8a1f3d2 + pristine_tree_hash: d6eea92a6d82c2e5be1e8de78b4ad087f8b07218 features: python: acceptHeaders: 3.0.0 @@ -3132,8 +3132,8 @@ trackedFiles: pristine_git_object: 78c74a24e624245cbbfe2f989c4301442bbb5fee docs/components/deferredbm25search.mdx: id: 28b5539be31d - last_write_checksum: sha1:446e5ba3ff5fd0dce149be2f9ec5f33d0cad2231 - pristine_git_object: 88953c20c366fc3c0afc37193fb9dbaecaa1db9d + last_write_checksum: sha1:a15bcc6774c01064019b8322f75c420d16fcd615 + pristine_git_object: 2ca788fa3c94eb09e32070aa7042e4074fc96ccc docs/components/deferredbm25searchtype.mdx: id: 7c08005a05ac last_write_checksum: sha1:4c12129e0ab52db31056314a17628cbfedb600b8 @@ -3148,16 +3148,16 @@ trackedFiles: pristine_git_object: 8accaf302940a8ab39f159badc6daccad7fddd75 docs/components/deferredregexsearch.mdx: id: 8b88be545243 - last_write_checksum: sha1:76e75788f5d4a2541baf1bd0735807fab396d01b - pristine_git_object: 7ca608b0a48483bfa6de68614faf8423e56cff5d + last_write_checksum: sha1:03a700d04a33be1a412a4e02cf78384bfac7aa12 + pristine_git_object: c1b67599df1b7edf23020afca6f28224ebf6ef4b docs/components/deferredregexsearchtype.mdx: id: bcec87810dd1 last_write_checksum: sha1:59b772e53fc1109c2cc4f42f4cf21405c35830a6 pristine_git_object: a226240fb3b94358d33acc91761a8bba03309b63 docs/components/deferredtoolscontrol.mdx: id: 13db9fb1f102 - last_write_checksum: sha1:d6924c2b7eaf02cb8eaef07d30556cf43cc711e0 - pristine_git_object: b2034e5bdc974166dd428e27eaf9e1764b3bc7d4 + last_write_checksum: sha1:bc65f901da52e95d9b0b352635d44bb9d2908700 + pristine_git_object: 3c02fcdc8dfc6fc694c6e63707e320d60394b392 docs/components/deferredtoolscontrolscope.mdx: id: 61fade4412af last_write_checksum: sha1:ff698d00ab177a0e0ac4ffe495004205f89ab63b @@ -7304,8 +7304,8 @@ trackedFiles: pristine_git_object: 6c3e7e5d4da71c9aa3052bf628a98a37de57a648 docs/components/profile.mdx: id: cb682ce5da89 - last_write_checksum: sha1:85fc558652373eaf48459a2c14c15da8cd7c990e - pristine_git_object: f9eb1da620f71c083b8db1563c4b424f3ece8bcf + last_write_checksum: sha1:7738987aa74bc6cbc779bd83392e58465bf8161b + pristine_git_object: 5e99f04a7fe5467a4da14f03fe4227909ebf8949 docs/components/promptcachebreakpoint.mdx: id: c135956dc623 last_write_checksum: sha1:581974fd4042ee26dd8a88d28a084c28b3ccdef9 @@ -11572,8 +11572,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:9f0dca296be25de0a997509a6f5e337f4f7962df - pristine_git_object: e92db736d76e6e2927d74cacba0553e74f8e64b9 + last_write_checksum: sha1:4e8e9761c42ce8a62aa8067fe8b61d6420853214 + pristine_git_object: 3c2f24271d9e9d34c5a0b77afa52ebe2133e7475 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -11600,8 +11600,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:39d91473d7e7c29a245937ae51baece1dc05e2d3 - pristine_git_object: 949b502ab5d9ce1a5f75345dfcff095fec57dd04 + last_write_checksum: sha1:d5a41727fce325bc07490814cee31abfb1c339a7 + pristine_git_object: 2c06f86bfa6db8f5f0fa6987c7456476c3411647 src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766 @@ -12980,28 +12980,28 @@ trackedFiles: pristine_git_object: dccefb2123d06d6d9920e7035f21a8ab5e7b86a8 src/openrouter/components/deferredbm25search.py: id: b988bf147d9f - last_write_checksum: sha1:c18b3d46bd22aa8225a0e8bd437a2216d5e2b1f1 - pristine_git_object: 88170eac0664366f3623bddd70c333150e803192 + last_write_checksum: sha1:844c2abcc0abfe97fb0fc674433fbe562b13d1be + pristine_git_object: fc8e02ddf1351afcd9eea9bb0f0b22c70f56455d src/openrouter/components/deferredcustomsearch.py: id: 71d9d33ba373 last_write_checksum: sha1:1b308d057e8b27d8a7da76b1edf47734ab11dd0c pristine_git_object: b47ed4f8a5b51b416f3105bb22b93dddf23e7aa6 src/openrouter/components/deferredregexsearch.py: id: 64f28f2cc1af - last_write_checksum: sha1:59a3ca23434f478644f04a42515477a02bd09567 - pristine_git_object: 21eb6b48f7b5a7eb922a55c395c18b87393913ee + last_write_checksum: sha1:5b1e7421dd0cfce6630b734abd5419c17b7e4ca0 + pristine_git_object: 3df7acb264606e29fc26a79c5f5eda4166b8e206 src/openrouter/components/deferredtoolscontrol.py: id: b8b6ceef6f86 - last_write_checksum: sha1:371b8a26ed641aee9c4061cd973a014197b3aa5e - pristine_git_object: dfd1e0ce16b72379fe36f077b5f1c92a700d58cd + last_write_checksum: sha1:400370e0b6065417a670fba03fc5faa713f503c3 + pristine_git_object: 75217e5d298f3e26d8f229a6ae82e5df3e6f1665 src/openrouter/components/deferredtoolsdetails.py: id: 044f0e33803d last_write_checksum: sha1:2f8fcc43fc779a0cb9621149875a5e7bbfa5e6dc pristine_git_object: 1cc2be0d154e3487e2f7b33b6cf3baa652f21e5b src/openrouter/components/deferredtoolssearchstrategy.py: id: 6bd66af4513f - last_write_checksum: sha1:fa3e06da0ca4390085a58f5ded26a64ebe157fff - pristine_git_object: 6eaf9b612691a2b5fd8029449e8fa32a6053db19 + last_write_checksum: sha1:cf617a6ed86ddebbd9ecd386e5d3ff22daa29611 + pristine_git_object: 011b09b1ebeb104153d77561f1ebfc9679b6ff91 src/openrouter/components/deletebyokkeyresponse.py: id: f9a1e677521f last_write_checksum: sha1:371aa071eb7da7c466521eed203e32e441c6abb3 @@ -21507,8 +21507,6 @@ examples: examplesVersion: 1.0.2 releaseNotes: | ## Python SDK Changes: - * `open_router.batch.create_batches()`: `response.results[].response.body.union(OpenResponsesResult).output[].union(openrouter:tool_search).catalog_changes` **Added** - * `open_router.batch.get_batches()`: `response.results[].response.body.union(OpenResponsesResult).output[].union(openrouter:tool_search).catalog_changes` **Added** * `open_router.presets.create_presets_chat_completions()`: `request.deferred_tools` **Changed** * `open_router.presets.create_presets_messages()`: `request.deferred_tools` **Changed** - * `open_router.presets.create_presets_responses()`: `request` **Changed** + * `open_router.presets.create_presets_responses()`: `request.deferred_tools` **Changed** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 4f53d4c8..8b939a9f 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -37,7 +37,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.140 + version: 1.3.141 additionalDependencies: dev: pytest: '>=8.3' diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index c00e4d50..35d617ea 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -12109,6 +12109,9 @@ components: properties: max_results: type: 'integer' + miss_sources: + description: 'Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client''s built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.' + type: 'boolean' siblings: description: 'Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.' type: 'boolean' @@ -12155,6 +12158,9 @@ components: properties: max_results: type: 'integer' + miss_sources: + description: 'Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client''s built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.' + type: 'boolean' siblings: description: 'Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.' type: 'boolean' @@ -12197,8 +12203,11 @@ components: - 'code_mode' type: 'string' x-speakeasy-unknown-values: allow + min_deferred_tools: + description: 'Universal profile only. When fewer tools than this would be deferred, the universal profile defers none of them and sends the client tools unchanged, so a harness with a handful of non-core tools and no MCP servers pays no search turn for them. Counted after the interface exclusions; ignored with a custom search, whose client decides what it loads. Absent: every wrappable tool in scope is deferred.' + type: 'integer' profile: - description: 'Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation.' + description: 'Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation.' enum: - 'portable' - 'universal' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 1bb07cae..c5fee74f 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:37aa1e6df993cf6f4b6dc7546a7cd770f8ba5da6894821053e47f6d921c66d14 - sourceBlobDigest: sha256:78be206324d2799a542bffa4b6224b31b5284ad94e7b914eac21523272ac7afd + sourceRevisionDigest: sha256:dc1791abea34c3b54da7554eb2636d9378f6958fe52dc9b02c7a391561b6803c + sourceBlobDigest: sha256:a5d9fb0ee44c6ed55e7daf20a8b4849087a8173a1579cc76233167915af91d29 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:37aa1e6df993cf6f4b6dc7546a7cd770f8ba5da6894821053e47f6d921c66d14 - sourceBlobDigest: sha256:78be206324d2799a542bffa4b6224b31b5284ad94e7b914eac21523272ac7afd + sourceRevisionDigest: sha256:dc1791abea34c3b54da7554eb2636d9378f6958fe52dc9b02c7a391561b6803c + sourceBlobDigest: sha256:a5d9fb0ee44c6ed55e7daf20a8b4849087a8173a1579cc76233167915af91d29 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:b23c29a29f211d8968416eeea6a6304ceb1c7ae9cd3e44cdf085101a01063237 + codeSamplesRevisionDigest: sha256:6903f04c32a0eed4f2e5d36b8172901cfe6bcd3902c8fbe414b6546d3eb0a6a1 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.803.2 diff --git a/RELEASES.md b/RELEASES.md index fb243237..dab60a81 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4169,4 +4169,14 @@ Based on: ### Generated - [python v1.3.140] . ### Releases -- [PyPI v1.3.140] https://pypi.org/project/openrouter/1.3.140 - . \ No newline at end of file +- [PyPI v1.3.140] https://pypi.org/project/openrouter/1.3.140 - . + +## 2026-11-08 14:21:10 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.141] . +### Releases +- [PyPI v1.3.141] https://pypi.org/project/openrouter/1.3.141 - . \ No newline at end of file diff --git a/docs/components/deferredbm25search.mdx b/docs/components/deferredbm25search.mdx index 88953c20..2ca788fa 100644 --- a/docs/components/deferredbm25search.mdx +++ b/docs/components/deferredbm25search.mdx @@ -7,9 +7,10 @@ Deterministic BM25 retrieval over supplied tool definitions. ## Fields -| Field | Type | Required | Description | -| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `max_results` | *Optional[int]* | ➖ | N/A | -| `siblings` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone. | -| `spread` | *Optional[bool]* | ➖ | Universal profile only, for keyword searches the router answers through the `tool_search` wrapper. When true, a result spreads across sources: of the 3 x limit best-scoring candidates, those scoring at least 60% of the best match take at most 2 slots per source (MCP server, namespace or shared `_` prefix; a tool with no source is never capped), and the remaining slots fill in score order, so a catalog with several systems for one job (web search, page extraction) shows one of each instead of the top system's siblings. Absent or false: results are the best matches in score order. | -| `type` | [components.DeferredBm25SearchType](../components/deferredbm25searchtype.mdx) | ✔️ | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `max_results` | *Optional[int]* | ➖ | N/A | +| `miss_sources` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only. | +| `siblings` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone. | +| `spread` | *Optional[bool]* | ➖ | Universal profile only, for keyword searches the router answers through the `tool_search` wrapper. When true, a result spreads across sources: of the 3 x limit best-scoring candidates, those scoring at least 60% of the best match take at most 2 slots per source (MCP server, namespace or shared `_` prefix; a tool with no source is never capped), and the remaining slots fill in score order, so a catalog with several systems for one job (web search, page extraction) shows one of each instead of the top system's siblings. Absent or false: results are the best matches in score order. | +| `type` | [components.DeferredBm25SearchType](../components/deferredbm25searchtype.mdx) | ✔️ | N/A | \ No newline at end of file diff --git a/docs/components/deferredregexsearch.mdx b/docs/components/deferredregexsearch.mdx index 7ca608b0..c1b67599 100644 --- a/docs/components/deferredregexsearch.mdx +++ b/docs/components/deferredregexsearch.mdx @@ -7,8 +7,9 @@ Versioned safe-regex retrieval over supplied tool definitions. ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `max_results` | *Optional[int]* | ➖ | N/A | -| `siblings` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone. | -| `type` | [components.DeferredRegexSearchType](../components/deferredregexsearchtype.mdx) | ✔️ | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `max_results` | *Optional[int]* | ➖ | N/A | +| `miss_sources` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only. | +| `siblings` | *Optional[bool]* | ➖ | Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone. | +| `type` | [components.DeferredRegexSearchType](../components/deferredregexsearchtype.mdx) | ✔️ | N/A | \ No newline at end of file diff --git a/docs/components/deferredtoolscontrol.mdx b/docs/components/deferredtoolscontrol.mdx index b2034e5b..3c02fcdc 100644 --- a/docs/components/deferredtoolscontrol.mdx +++ b/docs/components/deferredtoolscontrol.mdx @@ -13,7 +13,8 @@ Opt-in versioned router-level deferred-tool protocol. Replay assistant reasoning | `cascade_mode` | [Optional[components.CascadeMode]](../components/cascademode.mdx) | ➖ | How a universal `tool_search` query reaches the client's own tool search. Absent or `keywords`: a `select:` query becomes the words of the selected names and the limit is always filled. `native`: a `select:` query passes through verbatim when the client search documents `select:`, and the limit field is sent only when the model gave one, unless the client search requires it, in which case its documented default is sent. Experimental. | | | `hint` | *Optional[str]* | ➖ | Universal profile only. Caller text announced to the model with the deferred catalog before its first turn, for example which sources the task needs. Repeated only when it changes. Trimmed before the length bounds apply. Recorded in the `catalog_index` discovery record of the response, so it is replayed with the conversation. | | | `interface` | [Optional[components.Interface]](../components/interface.mdx) | ➖ | How the universal profile exposes the hidden catalog to the provider. Absent or `wrappers`: the `tool_search` and `tool_exec` tools. `code_mode`: one `tool_code` tool that runs a short JavaScript program in which `search()` and `call()` reach the catalog, so several searches and calls complete in one tool result. Experimental. | | -| `profile` | [components.Profile](../components/profile.mdx) | ✔️ | Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation. | | +| `min_deferred_tools` | *Optional[int]* | ➖ | Universal profile only. When fewer tools than this would be deferred, the universal profile defers none of them and sends the client tools unchanged, so a harness with a handful of non-core tools and no MCP servers pays no search turn for them. Counted after the interface exclusions; ignored with a custom search, whose client decides what it loads. Absent: every wrappable tool in scope is deferred. | | +| `profile` | [components.Profile](../components/profile.mdx) | ✔️ | Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation. | | | `protocol` | [components.Protocol](../components/protocol.mdx) | ✔️ | N/A | | | `scope` | [Optional[components.DeferredToolsControlScope]](../components/deferredtoolscontrolscope.mdx) | ➖ | Which tools the universal profile defers. Absent or `all`: every wrappable tool outside the coding-harness core set. `mcp`: only MCP server tools (`mcp__*` names and Responses namespaces outside `functions`); the harness keeps its own built-in tools direct. `client`: only the tools the client itself marked `defer_loading`, so a harness with its own tool search keeps its other direct tools direct; an adopted client tool search is still replaced by the router wrappers, and a client-deferred tool the router cannot wrap stays direct. Experimental. | | | `search` | [components.DeferredToolsSearchStrategy](../components/deferredtoolssearchstrategy.mdx) | ✔️ | Router-local regex/BM25 or caller-owned custom search. | \{
"max_results": 5,
"type": "bm25"
} | diff --git a/docs/components/profile.mdx b/docs/components/profile.mdx index f9eb1da6..5e99f04a 100644 --- a/docs/components/profile.mdx +++ b/docs/components/profile.mdx @@ -2,7 +2,7 @@ title: "Profile" --- -Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation. +Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation. ## Example Usage diff --git a/pyproject.toml b/pyproject.toml index e92db736..3c2f2427 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.140" +version = "1.3.141" 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 949b502a..2c06f86b 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.140" +__version__: str = "1.3.141" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.950.13" -__user_agent__: str = "speakeasy-sdk/python 1.3.140 2.950.13 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.141 2.950.13 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/deferredbm25search.py b/src/openrouter/components/deferredbm25search.py index 88170eac..fc8e02dd 100644 --- a/src/openrouter/components/deferredbm25search.py +++ b/src/openrouter/components/deferredbm25search.py @@ -15,6 +15,8 @@ class DeferredBm25SearchTypedDict(TypedDict): type: DeferredBm25SearchType max_results: NotRequired[int] + miss_sources: NotRequired[bool] + r"""Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.""" siblings: NotRequired[bool] r"""Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.""" spread: NotRequired[bool] @@ -28,6 +30,9 @@ class DeferredBm25Search(BaseModel): max_results: Optional[int] = None + miss_sources: Optional[bool] = None + r"""Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.""" + siblings: Optional[bool] = None r"""Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.""" @@ -36,7 +41,7 @@ class DeferredBm25Search(BaseModel): @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["max_results", "siblings", "spread"]) + optional_fields = set(["max_results", "miss_sources", "siblings", "spread"]) serialized = handler(self) m = {} diff --git a/src/openrouter/components/deferredregexsearch.py b/src/openrouter/components/deferredregexsearch.py index 21eb6b48..3df7acb2 100644 --- a/src/openrouter/components/deferredregexsearch.py +++ b/src/openrouter/components/deferredregexsearch.py @@ -15,6 +15,8 @@ class DeferredRegexSearchTypedDict(TypedDict): type: DeferredRegexSearchType max_results: NotRequired[int] + miss_sources: NotRequired[bool] + r"""Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.""" siblings: NotRequired[bool] r"""Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.""" @@ -26,12 +28,15 @@ class DeferredRegexSearch(BaseModel): max_results: Optional[int] = None + miss_sources: Optional[bool] = None + r"""Universal profile only, for searches the router answers through the `tool_search` wrapper. When true, a search that matches nothing also names the deferred sources this search covers (namespaces, MCP servers, and shared `_` prefixes; up to 40 names or 2,000 characters, with a count of any omitted) and tells the model that a source the search does not cover is unreachable through it in this request, so it can make a client tool call the task already needs (or a read-only one) and search again on a later turn instead of concluding the integration is missing. Direct tools, including a client's built-in tools, are already in the tool list and are not named. Absent or false: a miss suggests other keywords and the closest names only.""" + siblings: Optional[bool] = None r"""Universal profile only, for searches the router answers through the `tool_search` wrapper; code-mode `search()` and a client-owned tool search list the matched tools alone. When true, each result also names up to 16 other deferred tools of every source a match came from, so a model that found one tool of an MCP server learns its neighbours without another search. Absent or false: results list the matched tools alone.""" @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["max_results", "siblings"]) + optional_fields = set(["max_results", "miss_sources", "siblings"]) serialized = handler(self) m = {} diff --git a/src/openrouter/components/deferredtoolscontrol.py b/src/openrouter/components/deferredtoolscontrol.py index dfd1e0ce..75217e5d 100644 --- a/src/openrouter/components/deferredtoolscontrol.py +++ b/src/openrouter/components/deferredtoolscontrol.py @@ -38,7 +38,7 @@ ], UnrecognizedStr, ] -r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" +r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" Protocol = Literal["v1",] @@ -63,7 +63,7 @@ class DeferredToolsControlTypedDict(TypedDict): r"""Opt-in versioned router-level deferred-tool protocol. Replay assistant reasoning unchanged on continuation. The portable profile needs the catalog unchanged across a continuation; the universal profile accepts a changed catalog and, with `announce_catalog_changes`, tells the model about it.""" profile: Profile - r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" + r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" protocol: Protocol search: DeferredToolsSearchStrategyTypedDict r"""Router-local regex/BM25 or caller-owned custom search.""" @@ -77,6 +77,8 @@ class DeferredToolsControlTypedDict(TypedDict): r"""Universal profile only. Caller text announced to the model with the deferred catalog before its first turn, for example which sources the task needs. Repeated only when it changes. Trimmed before the length bounds apply. Recorded in the `catalog_index` discovery record of the response, so it is replayed with the conversation.""" interface: NotRequired[Interface] r"""How the universal profile exposes the hidden catalog to the provider. Absent or `wrappers`: the `tool_search` and `tool_exec` tools. `code_mode`: one `tool_code` tool that runs a short JavaScript program in which `search()` and `call()` reach the catalog, so several searches and calls complete in one tool result. Experimental.""" + min_deferred_tools: NotRequired[int] + r"""Universal profile only. When fewer tools than this would be deferred, the universal profile defers none of them and sends the client tools unchanged, so a harness with a handful of non-core tools and no MCP servers pays no search turn for them. Counted after the interface exclusions; ignored with a custom search, whose client decides what it loads. Absent: every wrappable tool in scope is deferred.""" scope: NotRequired[DeferredToolsControlScope] r"""Which tools the universal profile defers. Absent or `all`: every wrappable tool outside the coding-harness core set. `mcp`: only MCP server tools (`mcp__*` names and Responses namespaces outside `functions`); the harness keeps its own built-in tools direct. `client`: only the tools the client itself marked `defer_loading`, so a harness with its own tool search keeps its other direct tools direct; an adopted client tool search is still replaced by the router wrappers, and a client-deferred tool the router cannot wrap stays direct. Experimental.""" @@ -85,7 +87,7 @@ class DeferredToolsControl(BaseModel): r"""Opt-in versioned router-level deferred-tool protocol. Replay assistant reasoning unchanged on continuation. The portable profile needs the catalog unchanged across a continuation; the universal profile accepts a changed catalog and, with `announce_catalog_changes`, tells the model about it.""" profile: Profile - r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes, and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" + r"""Loading profile. `portable` serves the `defer_loading` tools with router-built search and call wrappers on any model and keeps the catalog fixed. `universal` defers every wrappable tool behind the same wrappers so the provider-facing tool list never changes (unless `min_deferred_tools` inlines a small catalog), and rebuilds the catalog from each request so tools can be added or removed mid-conversation.""" protocol: Protocol @@ -107,13 +109,23 @@ class DeferredToolsControl(BaseModel): interface: Optional[Interface] = None r"""How the universal profile exposes the hidden catalog to the provider. Absent or `wrappers`: the `tool_search` and `tool_exec` tools. `code_mode`: one `tool_code` tool that runs a short JavaScript program in which `search()` and `call()` reach the catalog, so several searches and calls complete in one tool result. Experimental.""" + min_deferred_tools: Optional[int] = None + r"""Universal profile only. When fewer tools than this would be deferred, the universal profile defers none of them and sends the client tools unchanged, so a harness with a handful of non-core tools and no MCP servers pays no search turn for them. Counted after the interface exclusions; ignored with a custom search, whose client decides what it loads. Absent: every wrappable tool in scope is deferred.""" + scope: Optional[DeferredToolsControlScope] = None r"""Which tools the universal profile defers. Absent or `all`: every wrappable tool outside the coding-harness core set. `mcp`: only MCP server tools (`mcp__*` names and Responses namespaces outside `functions`); the harness keeps its own built-in tools direct. `client`: only the tools the client itself marked `defer_loading`, so a harness with its own tool search keeps its other direct tools direct; an adopted client tool search is still replaced by the router wrappers, and a client-deferred tool the router cannot wrap stays direct. Experimental.""" @model_serializer(mode="wrap") def serialize_model(self, handler): optional_fields = set( - ["announce_catalog_changes", "cascade_mode", "hint", "interface", "scope"] + [ + "announce_catalog_changes", + "cascade_mode", + "hint", + "interface", + "min_deferred_tools", + "scope", + ] ) serialized = handler(self) m = {} diff --git a/src/openrouter/components/deferredtoolssearchstrategy.py b/src/openrouter/components/deferredtoolssearchstrategy.py index 6eaf9b61..011b09b1 100644 --- a/src/openrouter/components/deferredtoolssearchstrategy.py +++ b/src/openrouter/components/deferredtoolssearchstrategy.py @@ -14,8 +14,8 @@ "DeferredToolsSearchStrategyTypedDict", Union[ DeferredRegexSearchTypedDict, - DeferredBm25SearchTypedDict, DeferredCustomSearchTypedDict, + DeferredBm25SearchTypedDict, ], ) r"""Router-local regex/BM25 or caller-owned custom search.""" diff --git a/uv.lock b/uv.lock index 49d09b37..d3ce92f0 100644 --- a/uv.lock +++ b/uv.lock @@ -231,7 +231,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.140" +version = "1.3.141" source = { editable = "." } dependencies = [ { name = "httpcore" },