diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index 9edc46b93..e6aac2d97 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: 7716ae43f004bad996f81fb0bcc1aa3e
+ docChecksum: 1b1f9cc5495f868369dd84584b66a331
docVersion: 1.0.0
speakeasyVersion: 1.803.2
generationVersion: 2.950.13
- releaseVersion: 1.3.138
- configChecksum: 42c8fc774282817b5cfaa48f57cd6b12
+ releaseVersion: 1.3.139
+ configChecksum: 9c9450a578517447d539f313154059b5
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: d5ccaf0d-c9b2-414c-b711-369a1fb5ae3c
- pristine_commit_hash: 27099b97dc999a2e291ec3bacea6f3dd824bd51f
- pristine_tree_hash: 24436c555e0f5b6d480a9ca13e3fcb78b26241ce
+ generation_id: feede6d2-82b6-4fd2-8f6c-122e26ca84ee
+ pristine_commit_hash: c7fe652bd0c7da52e532eb126bc4e1bd1ec76415
+ pristine_tree_hash: b545496ced13bf94a4abb55d0d51b6ec7de8e408
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:7f897adc605d54cbb0d10b2c4aac7b99b7fd7dd8
- pristine_git_object: 7e7e8fe87115b5a47fdd1cd5460eca2b328885f6
+ last_write_checksum: sha1:d6bcb91024febe3a5b810798068faa6c4a4b97cc
+ pristine_git_object: abed2b5ad521676845a4f3cb6450a369667d4886
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:7d6ba06a0da494cc9a099002ee00f284257f271e
- pristine_git_object: 57a008e97ca9aba598f7c1fb2d5d9afc8f74222b
+ last_write_checksum: sha1:76e75788f5d4a2541baf1bd0735807fab396d01b
+ pristine_git_object: 7ca608b0a48483bfa6de68614faf8423e56cff5d
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:edb3f5df24f9b51c0d96160709b357acee685208
- pristine_git_object: 66c21dc09f85514331d8a4d007a1f20d78b7112b
+ last_write_checksum: sha1:9c5955892248ef08dc9801c6677bdfe3b0fb9fff
+ pristine_git_object: 06a67d94e470dae5da499da820a53cb5aee28d25
docs/components/deferredtoolscontrolscope.mdx:
id: 61fade4412af
last_write_checksum: sha1:ff698d00ab177a0e0ac4ffe495004205f89ab63b
@@ -6940,8 +6940,8 @@ trackedFiles:
pristine_git_object: d68bd61421859df1e00c0ec15f5a6946ed52dfd1
docs/components/outputtoolsearchservertoolitem.mdx:
id: 7106fbb89729
- last_write_checksum: sha1:624ad5b5ea8b46034cde801d3322141411bbda4c
- pristine_git_object: c49ae6e87990a02aa270c6d26b98669fd6af4760
+ last_write_checksum: sha1:014db8181b4d1da4e46bc283a0b55a24b53fa312
+ pristine_git_object: 6b1e2f064260e0f05bdfbd2ea1658a5615a2b1ca
docs/components/outputtoolsearchservertoolitemformat.mdx:
id: 717072e9e3e8
last_write_checksum: sha1:04cf65dbe63614cfee6df054640472e679b4faac
@@ -11572,8 +11572,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:e4f3bd5236af27c73505b71ffef2658bab4dc5da
- pristine_git_object: 9d1e2b520b78e127173f8b538d0f0cdf6348eb15
+ last_write_checksum: sha1:e28f7bb317d0079eba0f37a7a2e7cabc321602e8
+ pristine_git_object: c467f2034850c4a2372520ddf74fa3b8cebb10a3
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:7bdb608247c3d26ede5cf675632c57af2b93d311
- pristine_git_object: a9eb8bdc052fffeb00325457e6848a11f0b936bb
+ last_write_checksum: sha1:3cea337387abf552d701b1ece5b3b97f00dde6c0
+ pristine_git_object: c7a3b0845924c4f6bfe20338a3360003e3185e9b
src/openrouter/alpha.py:
id: 306c4d93308d
last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766
@@ -12980,20 +12980,20 @@ trackedFiles:
pristine_git_object: dccefb2123d06d6d9920e7035f21a8ab5e7b86a8
src/openrouter/components/deferredbm25search.py:
id: b988bf147d9f
- last_write_checksum: sha1:d0f5d39b8dd69d70f7d6117a3385a36f131c330a
- pristine_git_object: e472cb0ac59aa64f778263ec78524205c3919ce8
+ last_write_checksum: sha1:d5415833d3abe21b9f6afd0af43c476bf8073181
+ pristine_git_object: add59e787cc3b1cde02c026c2d30c38301949934
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:e0461c23a9d8a11ed441b1657421630a01bb0597
- pristine_git_object: 8a4e94425724c374a040ea028d0933db39ec1451
+ last_write_checksum: sha1:59a3ca23434f478644f04a42515477a02bd09567
+ pristine_git_object: 21eb6b48f7b5a7eb922a55c395c18b87393913ee
src/openrouter/components/deferredtoolscontrol.py:
id: b8b6ceef6f86
- last_write_checksum: sha1:08f2c8a631e138a2826f7c1d81ba0696f7bbfdaa
- pristine_git_object: 795ceaf6e4ada26051dea36a625f95dc0a42e86f
+ last_write_checksum: sha1:a34cd0144997c8f54067331cb03e492d63cc6604
+ pristine_git_object: 1fd04fedb8959253991a926d32f68be2aaecc7cb
src/openrouter/components/deferredtoolsdetails.py:
id: 044f0e33803d
last_write_checksum: sha1:2f8fcc43fc779a0cb9621149875a5e7bbfa5e6dc
@@ -13572,8 +13572,8 @@ trackedFiles:
pristine_git_object: f499cbbb546232f5cfbfe2c44fb41aefb306c87f
src/openrouter/components/inputs_union.py:
id: 17d6239cb6a7
- last_write_checksum: sha1:4bc1d972ad7487d88145caf30f8e712fc8adbb7d
- pristine_git_object: b5b2ac90b2d7fd66a06259ff5ada7f4122492dbf
+ last_write_checksum: sha1:b01abadae0cb5a540783a46739c38c06185377e5
+ pristine_git_object: 6325458c261665ab39eaa8a83f0cce1333d8038e
src/openrouter/components/inputtext.py:
id: a995ae96be99
last_write_checksum: sha1:94c720a449e0d5a3f23ee7195f648422f61ac114
@@ -14312,8 +14312,8 @@ trackedFiles:
pristine_git_object: 616b0f5112e106777b4c096aeea6fef58ff32020
src/openrouter/components/outputitems.py:
id: 90f107de3116
- last_write_checksum: sha1:9503275f7e69cf4cee8af2060e917268a7e8f2e9
- pristine_git_object: f4c0864d6648b885b2ee2afe5fd7ab80009b10c7
+ last_write_checksum: sha1:c1175a76eefa7cee18379c7af6bffb7f8de2aecd
+ pristine_git_object: b9bd8442c9f14f506b421573ffe47210e079414e
src/openrouter/components/outputitemwebsearchcall.py:
id: bac8732aecb9
last_write_checksum: sha1:00d5b67226d6ff2c6a5497e6e01c764aeede496e
@@ -14372,8 +14372,8 @@ trackedFiles:
pristine_git_object: d5a5c820aff0971a68a725af296d68d8d3891992
src/openrouter/components/outputtoolsearchservertoolitem.py:
id: fb4ec737039d
- last_write_checksum: sha1:26f3a6e53d940ea78b3317e86a1e4da6eb1a63e0
- pristine_git_object: b1cd35a559ceebe4b5b6d9f85915bb311fca343c
+ last_write_checksum: sha1:eda6d37533b1e7f37a102bfc98ca9a93c26c797e
+ pristine_git_object: 4829ddb5e43ef9468d66e8fb5b336024e46f4874
src/openrouter/components/outputwebfetchservertoolitem.py:
id: 2b12eb287cdf
last_write_checksum: sha1:60ec6ef59d691699c092120ea7dffed824197872
@@ -21507,6 +21507,8 @@ 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).sources` **Added**
+ * `open_router.batch.get_batches()`: `response.results[].response.body.union(OpenResponsesResult).output[].union(openrouter:tool_search).sources` **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.deferred_tools` **Changed**
+ * `open_router.presets.create_presets_responses()`: `request` **Changed**
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index 5fba6b468..674389101 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -37,7 +37,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.3.138
+ version: 1.3.139
additionalDependencies:
dev:
pytest: '>=8.3'
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index 3a7b0d06c..749a42d15 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -12109,6 +12109,9 @@ components:
properties:
max_results:
type: 'integer'
+ 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'
type:
enum:
- 'bm25'
@@ -12149,6 +12152,9 @@ components:
properties:
max_results:
type: 'integer'
+ 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'
type:
enum:
- 'regex'
@@ -12173,6 +12179,11 @@ components:
- 'native'
type: 'string'
x-speakeasy-unknown-values: allow
+ hint:
+ description: '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.'
+ maxLength: 2000
+ minLength: 1
+ type: 'string'
interface:
description: '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.'
enum:
@@ -28638,6 +28649,17 @@ components:
type: 'array'
query:
type: 'string'
+ sources:
+ additionalProperties:
+ items:
+ type: 'string'
+ type: 'array'
+ description: 'The other deferred tools of each source a match came from, by name, when the search listed siblings. Replaying the item shows the same names.'
+ example:
+ mcp__tavily:
+ - 'mcp__tavily__tavily_extract'
+ - 'mcp__tavily__tavily_crawl'
+ type: 'object'
status:
$ref: '#/components/schemas/FailableToolCallStatus'
turn_call_ids:
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index 812da3bd8..6c1aea095 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:d76eae41d07734b31ea35d8025d572c90403f24db9e0f3c3559413465afad962
- sourceBlobDigest: sha256:ef8e085f7c2edf026810b4e8a42ea28ce5561489933f22f4806c9259ed31948b
+ sourceRevisionDigest: sha256:baa5345d553e8c08c25ae5eebfd9e6ad8bc1d5c89412972464dcd0c7bb50f9b0
+ sourceBlobDigest: sha256:dfc0969ec07dc0510a783f65038a0e3f0cc8eb18a69ffa0615c9980af9db8236
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:d76eae41d07734b31ea35d8025d572c90403f24db9e0f3c3559413465afad962
- sourceBlobDigest: sha256:ef8e085f7c2edf026810b4e8a42ea28ce5561489933f22f4806c9259ed31948b
+ sourceRevisionDigest: sha256:baa5345d553e8c08c25ae5eebfd9e6ad8bc1d5c89412972464dcd0c7bb50f9b0
+ sourceBlobDigest: sha256:dfc0969ec07dc0510a783f65038a0e3f0cc8eb18a69ffa0615c9980af9db8236
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:197c7aeeaf9a5c99da5facf10fcd18b80bd333683482aa20eb70725275d07b2a
+ codeSamplesRevisionDigest: sha256:9baf4b11c2a0203b1649672707f4d5ce5fdcf06f8eb40ab2264b74ef3e267866
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.803.2
diff --git a/RELEASES.md b/RELEASES.md
index 3ebe7e534..0920ab14e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -4149,4 +4149,14 @@ Based on:
### Generated
- [python v1.3.138] .
### Releases
-- [PyPI v1.3.138] https://pypi.org/project/openrouter/1.3.138 - .
\ No newline at end of file
+- [PyPI v1.3.138] https://pypi.org/project/openrouter/1.3.138 - .
+
+## 2026-11-07 21:03:34
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.3.139] .
+### Releases
+- [PyPI v1.3.139] https://pypi.org/project/openrouter/1.3.139 - .
\ No newline at end of file
diff --git a/docs/components/deferredbm25search.mdx b/docs/components/deferredbm25search.mdx
index 7e7e8fe87..abed2b5ad 100644
--- a/docs/components/deferredbm25search.mdx
+++ b/docs/components/deferredbm25search.mdx
@@ -7,7 +7,8 @@ Deterministic BM25 retrieval over supplied tool definitions.
## Fields
-| Field | Type | Required | Description |
-| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
-| `max_results` | *Optional[int]* | ➖ | N/A |
-| `type` | [components.DeferredBm25SearchType](../components/deferredbm25searchtype.mdx) | ✔️ | N/A |
\ No newline at end of file
+| 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.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 57a008e97..7ca608b0a 100644
--- a/docs/components/deferredregexsearch.mdx
+++ b/docs/components/deferredregexsearch.mdx
@@ -7,7 +7,8 @@ Versioned safe-regex retrieval over supplied tool definitions.
## Fields
-| Field | Type | Required | Description |
-| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
-| `max_results` | *Optional[int]* | ➖ | N/A |
-| `type` | [components.DeferredRegexSearchType](../components/deferredregexsearchtype.mdx) | ✔️ | N/A |
\ No newline at end of file
+| 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
diff --git a/docs/components/deferredtoolscontrol.mdx b/docs/components/deferredtoolscontrol.mdx
index 66c21dc09..06a67d94e 100644
--- a/docs/components/deferredtoolscontrol.mdx
+++ b/docs/components/deferredtoolscontrol.mdx
@@ -10,6 +10,7 @@ Opt-in versioned router-level deferred-tool protocol. Replay assistant reasoning
| Field | Type | Required | Description | Example |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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. | |
| `protocol` | [components.Protocol](../components/protocol.mdx) | ✔️ | N/A | |
diff --git a/docs/components/outputtoolsearchservertoolitem.mdx b/docs/components/outputtoolsearchservertoolitem.mdx
index c49ae6e87..6b1e2f064 100644
--- a/docs/components/outputtoolsearchservertoolitem.mdx
+++ b/docs/components/outputtoolsearchservertoolitem.mdx
@@ -18,6 +18,7 @@ An openrouter:tool_search server tool output item
| `id` | *Optional[str]* | ➖ | N/A | |
| `matches` | List[[components.Match](../components/match.mdx)] | ➖ | N/A | |
| `query` | *Optional[str]* | ➖ | N/A | |
+| `sources` | Dict[str, List[*str*]] | ➖ | The other deferred tools of each source a match came from, by name, when the search listed siblings. Replaying the item shows the same names. | \{
"mcp__tavily": [
"mcp__tavily__tavily_extract",
"mcp__tavily__tavily_crawl"
]
} |
| `status` | [components.FailableToolCallStatus](../components/failabletoolcallstatus.mdx) | ✔️ | N/A | completed |
| `turn_call_ids` | List[*str*] | ➖ | The IDs of every tool call in the model response that ran the search, in order. Replaying the item keeps those calls in one turn. | [
"call_search_1",
"call_exec_1"
] |
| `type` | [components.OutputToolSearchServerToolItemType](../components/outputtoolsearchservertoolitemtype.mdx) | ✔️ | N/A | |
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 9d1e2b520..c467f2034 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.3.138"
+version = "1.3.139"
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 a9eb8bdc0..c7a3b0845 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.138"
+__version__: str = "1.3.139"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.950.13"
-__user_agent__: str = "speakeasy-sdk/python 1.3.138 2.950.13 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.3.139 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 e472cb0ac..add59e787 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]
+ 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."""
class DeferredBm25Search(BaseModel):
@@ -24,9 +26,12 @@ class DeferredBm25Search(BaseModel):
max_results: Optional[int] = None
+ 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"])
+ optional_fields = set(["max_results", "siblings"])
serialized = handler(self)
m = {}
diff --git a/src/openrouter/components/deferredregexsearch.py b/src/openrouter/components/deferredregexsearch.py
index 8a4e94425..21eb6b48f 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]
+ 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."""
class DeferredRegexSearch(BaseModel):
@@ -24,9 +26,12 @@ class DeferredRegexSearch(BaseModel):
max_results: Optional[int] = None
+ 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"])
+ optional_fields = set(["max_results", "siblings"])
serialized = handler(self)
m = {}
diff --git a/src/openrouter/components/deferredtoolscontrol.py b/src/openrouter/components/deferredtoolscontrol.py
index 795ceaf6e..1fd04fedb 100644
--- a/src/openrouter/components/deferredtoolscontrol.py
+++ b/src/openrouter/components/deferredtoolscontrol.py
@@ -71,6 +71,8 @@ class DeferredToolsControlTypedDict(TypedDict):
r"""Where tool-call arguments are checked against the original schema. Only `runtime` (in OpenRouter) is available in this release."""
cascade_mode: NotRequired[CascadeMode]
r"""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: NotRequired[str]
+ 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."""
scope: NotRequired[DeferredToolsControlScope]
@@ -94,6 +96,9 @@ class DeferredToolsControl(BaseModel):
cascade_mode: Optional[CascadeMode] = None
r"""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] = None
+ 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: 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."""
@@ -102,7 +107,7 @@ class DeferredToolsControl(BaseModel):
@model_serializer(mode="wrap")
def serialize_model(self, handler):
- optional_fields = set(["cascade_mode", "interface", "scope"])
+ optional_fields = set(["cascade_mode", "hint", "interface", "scope"])
serialized = handler(self)
m = {}
diff --git a/src/openrouter/components/inputs_union.py b/src/openrouter/components/inputs_union.py
index b5b2ac90b..6325458c2 100644
--- a/src/openrouter/components/inputs_union.py
+++ b/src/openrouter/components/inputs_union.py
@@ -428,8 +428,8 @@ def serialize_model(self, handler):
OutputFilesServerToolItemTypedDict,
FunctionCallItemTypedDict,
OutputSubagentServerToolItemTypedDict,
- OutputToolSearchServerToolItemTypedDict,
OutputBashServerToolItemTypedDict,
+ OutputToolSearchServerToolItemTypedDict,
],
)
@@ -487,8 +487,8 @@ def serialize_model(self, handler):
OutputFilesServerToolItem,
FunctionCallItem,
OutputSubagentServerToolItem,
- OutputToolSearchServerToolItem,
OutputBashServerToolItem,
+ OutputToolSearchServerToolItem,
],
)
diff --git a/src/openrouter/components/outputitems.py b/src/openrouter/components/outputitems.py
index f4c0864d6..b9bd8442c 100644
--- a/src/openrouter/components/outputitems.py
+++ b/src/openrouter/components/outputitems.py
@@ -170,8 +170,8 @@
OutputShellServerToolItemTypedDict,
OutputFunctionCallItemTypedDict,
OutputSubagentServerToolItemTypedDict,
- OutputToolSearchServerToolItemTypedDict,
OutputBashServerToolItemTypedDict,
+ OutputToolSearchServerToolItemTypedDict,
],
)
r"""An output item from the response"""
diff --git a/src/openrouter/components/outputtoolsearchservertoolitem.py b/src/openrouter/components/outputtoolsearchservertoolitem.py
index b1cd35a55..4829ddb5e 100644
--- a/src/openrouter/components/outputtoolsearchservertoolitem.py
+++ b/src/openrouter/components/outputtoolsearchservertoolitem.py
@@ -50,6 +50,8 @@ class OutputToolSearchServerToolItemTypedDict(TypedDict):
id: NotRequired[str]
matches: NotRequired[List[MatchTypedDict]]
query: NotRequired[str]
+ sources: NotRequired[Dict[str, List[str]]]
+ r"""The other deferred tools of each source a match came from, by name, when the search listed siblings. Replaying the item shows the same names."""
turn_call_ids: NotRequired[List[str]]
r"""The IDs of every tool call in the model response that ran the search, in order. Replaying the item keeps those calls in one turn."""
@@ -87,6 +89,9 @@ class OutputToolSearchServerToolItem(BaseModel):
query: Optional[str] = None
+ sources: Optional[Dict[str, List[str]]] = None
+ r"""The other deferred tools of each source a match came from, by name, when the search listed siblings. Replaying the item shows the same names."""
+
turn_call_ids: Optional[List[str]] = None
r"""The IDs of every tool call in the model response that ran the search, in order. Replaying the item keeps those calls in one turn."""
@@ -103,6 +108,7 @@ def serialize_model(self, handler):
"id",
"matches",
"query",
+ "sources",
"turn_call_ids",
]
)
diff --git a/uv.lock b/uv.lock
index 1535ce317..1eb6bf16e 100644
--- a/uv.lock
+++ b/uv.lock
@@ -231,7 +231,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.3.138"
+version = "1.3.139"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },