diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index b514f5cb..c99696a9 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: ac73dc1bf51081552e7151a44f3c2cf9
+ docChecksum: b6ef27de25ec1beeb93612ce649711ae
docVersion: 1.0.0
speakeasyVersion: 1.787.0
generationVersion: 2.914.0
- releaseVersion: 1.0.12
- configChecksum: fafde5cbe14ea40906451b15da0f99e2
+ releaseVersion: 1.0.13
+ configChecksum: e4671d7f9e00903d7e556c10ab605641
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: 2c07838f-f933-4d0c-be44-87bae6f0d894
- pristine_commit_hash: 1568c752bf53fbe4dc24fb76be75f8eab642f4a5
- pristine_tree_hash: a360816f9b026793857a5bd28d7995e76dea97ec
+ generation_id: 8ed81ee4-7cab-4d9c-a2a6-14fe3fff1e3b
+ pristine_commit_hash: 9cdb0772dffcc27510ed382553d3eeac4994c306
+ pristine_tree_hash: 3398bca29c0d3ed633331aa17fecb7ef06870fb9
features:
python:
acceptHeaders: 3.0.0
@@ -626,8 +626,8 @@ trackedFiles:
pristine_git_object: 800b8e4a3fd07f10592e3ee8f9c15c7e57398d4c
docs/components/autorouterplugin.mdx:
id: 4d62f9b36bc2
- last_write_checksum: sha1:b0058abe56fb36523cac5296b6124fa84cb006a2
- pristine_git_object: 6fe8acaab8a38a767f710aebbc3390ca9022417e
+ last_write_checksum: sha1:74e39d385a2b96ab03d37f959364510eaaae2489
+ pristine_git_object: 305de1b54cded7b2bf8290f0595bc35fb24ddc02
docs/components/autorouterpluginid.mdx:
id: ea9862a88ce8
last_write_checksum: sha1:51d6cd6296501209ebc8b721adb3feadeb798f9a
@@ -810,8 +810,8 @@ trackedFiles:
pristine_git_object: 8a36279a112a3f8efc1ee770cb250e510674e7e5
docs/components/chatassistantmessage.mdx:
id: 8ba2a16f77d2
- last_write_checksum: sha1:b77cff879f1f2fbbfb655556591dff5578ff778e
- pristine_git_object: 1d774a92a1698348702b45b07f228fc1cdb3641c
+ last_write_checksum: sha1:16e5d5087f81f0d2e86d935cccfdadcc8d5543ef
+ pristine_git_object: bcd7ebd8cb8e097acd03929e9c08a5c784663467
docs/components/chatassistantmessagecontent.mdx:
id: ab4dd265daa1
last_write_checksum: sha1:9eb82372c50a133da9827ba8251a7a201027a4bc
@@ -6718,8 +6718,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:b3ce090581fdaf709043a6422d86698d40c8aa82
- pristine_git_object: 84abfd4d57b79efa45cfe69db6e7a4ec10d5d35e
+ last_write_checksum: sha1:b682b0fa943da90139db33d7f0e55a3d15b1cf18
+ pristine_git_object: 77b7d178212bd2cf76c76a5c06f64812fd244187
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -6746,8 +6746,8 @@ trackedFiles:
pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137
src/openrouter/_version.py:
id: d8d15ad6c586
- last_write_checksum: sha1:9f7ba5d6a77d463bd3a4392a16eb0ddc14f7401e
- pristine_git_object: cee6b286aab2a1c14e0b932803e08ca2ee05ee34
+ last_write_checksum: sha1:fbb1d6da1a6752ab4f2d9caa42b11652015ee912
+ pristine_git_object: 5a7fc691e1bcc2a94633923a08930b8e0d862e84
src/openrouter/analytics.py:
id: cb406b5aaabb
last_write_checksum: sha1:9e709b71dd0611056dc0cec6150b578defe32841
@@ -7046,8 +7046,8 @@ trackedFiles:
pristine_git_object: 56c32d14e00e66f5415c9ea0d503503f7925d62b
src/openrouter/components/autorouterplugin.py:
id: cf49add5d1ae
- last_write_checksum: sha1:e4ad3fb36054b4d0d05321f07fa025611e76c878
- pristine_git_object: 64a0715572155d0eb3bd297b886670e97837c843
+ last_write_checksum: sha1:4d0e56867780d5b238a8c37378fa53db80c42e69
+ pristine_git_object: db933a4a1660b5ed5b94167b980e296080f10672
src/openrouter/components/badgatewayresponseerrordata.py:
id: f7a33d30d269
last_write_checksum: sha1:d85ab25a06594703cb353767f07f4e1d44e0181c
@@ -7150,8 +7150,8 @@ trackedFiles:
pristine_git_object: c7866f6fa8967c301f6aa11b0b0431384ab79556
src/openrouter/components/chatassistantmessage.py:
id: 16355b51794d
- last_write_checksum: sha1:28fcb03173b448157e39959b0065290baab2803b
- pristine_git_object: 3caa2f311c18889db095a9285308e8a2be2c7e31
+ last_write_checksum: sha1:4f52ea3692076899d6f9d7471d2e37140a5bf261
+ pristine_git_object: 45b8f4907b87aac09253151fa95543dafce7dc83
src/openrouter/components/chataudiooutput.py:
id: 99984fd282ee
last_write_checksum: sha1:d2f5aacb72a261437e357c10e5bd6af16cb61323
@@ -7246,8 +7246,8 @@ trackedFiles:
pristine_git_object: 8bbde153b53887e426989fd5b0486b6dc1122810
src/openrouter/components/chatrequest.py:
id: 5e39eaefa9cf
- last_write_checksum: sha1:eafd7096d8f93a2a08f478fb3b33f9247dc2ed84
- pristine_git_object: 1dd5d233473337e7b06b8714ede20c803a3d87ec
+ last_write_checksum: sha1:c3e6ec77cc4fe808e616afc02312e9d802707f9f
+ pristine_git_object: 761053ae75ce43e0068cf1570d89eae62b8235cd
src/openrouter/components/chatresult.py:
id: 9062fe2935fe
last_write_checksum: sha1:2ff1963c54e7e79500115c8549c8d395f4e336d1
@@ -7994,8 +7994,8 @@ trackedFiles:
pristine_git_object: 7e69d1f775baece5f94b03d35bcd884d5e6f519d
src/openrouter/components/messagesrequest.py:
id: 72b1f339024d
- last_write_checksum: sha1:ec4007a63b5a02e9b0d979e634dc86a3d6fb671c
- pristine_git_object: 318eef45667d28c19c4e7bab5e18e0697c9d1f9f
+ last_write_checksum: sha1:2f2790567bc5bd5445682067925afedc10af2c23
+ pristine_git_object: 13ca0cdb2359abf0b9655070feb2f3588001fd34
src/openrouter/components/messagessearchmodelsservertool.py:
id: 53d755edb120
last_write_checksum: sha1:389786fc22ba4bb47b0a086b7aa321f2f04fe943
@@ -8614,8 +8614,8 @@ trackedFiles:
pristine_git_object: f38c8edcb616d9e7cbd0f724fbb9d9f5aae014f9
src/openrouter/components/responsesrequest.py:
id: 8c850080ec5d
- last_write_checksum: sha1:decf981d5e387e9261ad6e98a54364afbd6a5c1f
- pristine_git_object: 49323df620df833763bdeaef7d9fb85f536b4d7a
+ last_write_checksum: sha1:ec5126af18169474b4b0d233f5b148125acb29b5
+ pristine_git_object: 77ea688083e1aebbf8df27dde16c6ae4c1c551fb
src/openrouter/components/responsesstreamingresponse.py:
id: 142379f3bd90
last_write_checksum: sha1:a48d6f3610f5d15248ef4d25a0d88a0a4a1a9db7
@@ -11241,3 +11241,4 @@ examples:
"500":
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
examplesVersion: 1.0.2
+releaseNotes: "## Python SDK Changes:\n* `open_router.beta.responses.send()`: \n * `request.plugins[].union(auto-router).pin_model` **Added**\n* `open_router.chat.send()`: \n * `request` **Changed**\n * `response.choices[].message.model` **Added**\n* `open_router.presets.create_presets_chat_completions()`: `request` **Changed**\n* `open_router.presets.create_presets_messages()`: \n * `request.plugins[].union(auto-router).pin_model` **Added**\n* `open_router.presets.create_presets_responses()`: \n * `request.plugins[].union(auto-router).pin_model` **Added**\n"
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index e3acf93a..04744f25 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -36,7 +36,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.0.12
+ version: 1.0.13
additionalDependencies:
dev: {}
main: {}
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index 54ae2328..e25758de 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -2904,6 +2904,7 @@ components:
cost_quality_tradeoff: 7
enabled: true
id: 'auto-router'
+ pin_model: false
properties:
allowed_models:
description: 'List of model patterns to filter which models the auto-router can route between. Supports wildcards (e.g., "anthropic/*" matches all Anthropic models). When not specified, uses the default supported models list.'
@@ -2927,6 +2928,10 @@ components:
enum:
- 'auto-router'
type: 'string'
+ pin_model:
+ description: 'When true, reuses the model from the most recent assistant message''s `model` attribute for subsequent turns. Defaults to false.'
+ example: false
+ type: 'boolean'
required:
- 'id'
type: 'object'
@@ -4469,6 +4474,7 @@ components:
description: 'Assistant message for requests and responses'
example:
content: 'The capital of France is Paris.'
+ model: 'openai/gpt-4o'
role: 'assistant'
properties:
audio:
@@ -4483,6 +4489,10 @@ components:
description: 'Assistant message content'
images:
$ref: '#/components/schemas/ChatAssistantImages'
+ model:
+ description: 'Model that generated this assistant message'
+ example: 'openai/gpt-4o'
+ type: 'string'
name:
description: 'Optional name for the assistant'
type: 'string'
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index 2eebf62f..d65162e5 100644
--- a/.speakeasy/workflow.lock
+++ b/.speakeasy/workflow.lock
@@ -2,8 +2,8 @@ speakeasyVersion: 1.787.0
sources:
OpenRouter API:
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:bd71d48f0ef290071ae5dafff04541b2784fa2ac50de8c0d54936f2af9c96cb4
- sourceBlobDigest: sha256:3c6631f154b88330e81172618d74af80665f6a363f002ab2af015503cfba0fdf
+ sourceRevisionDigest: sha256:9c4ad78d1de9d5f6dbde9e345a7ce3c3567e043e6c29c0c9caecad81e5ff0032
+ sourceBlobDigest: sha256:9596e16587468d23db2f0c8762cfa9db49b3d6e05968aeca38eca51cdd2aafdb
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:bd71d48f0ef290071ae5dafff04541b2784fa2ac50de8c0d54936f2af9c96cb4
- sourceBlobDigest: sha256:3c6631f154b88330e81172618d74af80665f6a363f002ab2af015503cfba0fdf
+ sourceRevisionDigest: sha256:9c4ad78d1de9d5f6dbde9e345a7ce3c3567e043e6c29c0c9caecad81e5ff0032
+ sourceBlobDigest: sha256:9596e16587468d23db2f0c8762cfa9db49b3d6e05968aeca38eca51cdd2aafdb
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:231769e9876dbee575f81642357e0da7a62938045fff329910b2cb9a27c0ad7e
+ codeSamplesRevisionDigest: sha256:978d75313edd4861084123ebb3cf6273d0f054ac476b79109688f394a52a8df4
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.787.0
diff --git a/RELEASES.md b/RELEASES.md
index aca81eb4..7a1ce6e6 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -699,4 +699,14 @@ Based on:
### Generated
- [python v1.0.12] .
### Releases
-- [PyPI v1.0.12] https://pypi.org/project/openrouter/1.0.12 - .
\ No newline at end of file
+- [PyPI v1.0.12] https://pypi.org/project/openrouter/1.0.12 - .
+
+## 2026-07-22 19:13:13
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.0.13] .
+### Releases
+- [PyPI v1.0.13] https://pypi.org/project/openrouter/1.0.13 - .
\ No newline at end of file
diff --git a/docs/components/autorouterplugin.mdx b/docs/components/autorouterplugin.mdx
index 6fe8acaa..305de1b5 100644
--- a/docs/components/autorouterplugin.mdx
+++ b/docs/components/autorouterplugin.mdx
@@ -9,4 +9,5 @@ title: "AutoRouterPlugin"
| `allowed_models` | List[*str*] | :heavy_minus_sign: | List of model patterns to filter which models the auto-router can route between. Supports wildcards (e.g., "anthropic/*" matches all Anthropic models). When not specified, uses the default supported models list. | [
"anthropic/*",
"openai/gpt-4o",
"google/*"
] |
| `cost_quality_tradeoff` | *Optional[int]* | :heavy_minus_sign: | Controls cost vs. quality routing tradeoff (0–10). 0 = pure quality (best model regardless of cost), 10 = maximize for cost (cheapest model wins). Intermediate values blend quality and cost signals continuously. Defaults to 7. | 7 |
| `enabled` | *Optional[bool]* | :heavy_minus_sign: | Set to false to disable the auto-router plugin for this request. Defaults to true. | |
-| `id` | [components.AutoRouterPluginID](../components/autorouterpluginid.mdx) | :heavy_check_mark: | N/A | |
\ No newline at end of file
+| `id` | [components.AutoRouterPluginID](../components/autorouterpluginid.mdx) | :heavy_check_mark: | N/A | |
+| `pin_model` | *Optional[bool]* | :heavy_minus_sign: | When true, reuses the model from the most recent assistant message's `model` attribute for subsequent turns. Defaults to false. | false |
\ No newline at end of file
diff --git a/docs/components/chatassistantmessage.mdx b/docs/components/chatassistantmessage.mdx
index 1d774a92..bcd7ebd8 100644
--- a/docs/components/chatassistantmessage.mdx
+++ b/docs/components/chatassistantmessage.mdx
@@ -12,6 +12,7 @@ Assistant message for requests and responses
| `audio` | [Optional[components.ChatAudioOutput]](../components/chataudiooutput.mdx) | :heavy_minus_sign: | Audio output data or reference | \{
"data": "UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1f",
"expires_at": 1677652400,
"id": "audio_abc123",
"transcript": "Hello! How can I help you today?"
} |
| `content` | [OptionalNullable[components.ChatAssistantMessageContent]](../components/chatassistantmessagecontent.mdx) | :heavy_minus_sign: | Assistant message content | |
| `images` | List[[components.ChatAssistantImages](../components/chatassistantimages.mdx)] | :heavy_minus_sign: | Generated images from image generation models | [
\{
"image_url": \{
"url": "data:image/png;base64,iVBORw0KGgo..."
}
}
] |
+| `model` | *Optional[str]* | :heavy_minus_sign: | Model that generated this assistant message | openai/gpt-4o |
| `name` | *Optional[str]* | :heavy_minus_sign: | Optional name for the assistant | |
| `reasoning` | *OptionalNullable[str]* | :heavy_minus_sign: | Reasoning output | |
| `reasoning_details` | List[[components.ReasoningDetailUnion](../components/reasoningdetailunion.mdx)] | :heavy_minus_sign: | Reasoning details for extended thinking models | [
\{
"text": "Let me work through this step by step...",
"type": "reasoning.text"
}
] |
diff --git a/pyproject.toml b/pyproject.toml
index 84abfd4d..77b7d178 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.0.12"
+version = "1.0.13"
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 cee6b286..5a7fc691 100644
--- a/src/openrouter/_version.py
+++ b/src/openrouter/_version.py
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "openrouter"
-__version__: str = "1.0.12"
+__version__: str = "1.0.13"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.914.0"
-__user_agent__: str = "speakeasy-sdk/python 1.0.12 2.914.0 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.0.13 2.914.0 1.0.0 openrouter"
try:
if __package__ is not None:
diff --git a/src/openrouter/components/autorouterplugin.py b/src/openrouter/components/autorouterplugin.py
index 64a07155..db933a4a 100644
--- a/src/openrouter/components/autorouterplugin.py
+++ b/src/openrouter/components/autorouterplugin.py
@@ -18,6 +18,8 @@ class AutoRouterPluginTypedDict(TypedDict):
r"""Controls cost vs. quality routing tradeoff (0–10). 0 = pure quality (best model regardless of cost), 10 = maximize for cost (cheapest model wins). Intermediate values blend quality and cost signals continuously. Defaults to 7."""
enabled: NotRequired[bool]
r"""Set to false to disable the auto-router plugin for this request. Defaults to true."""
+ pin_model: NotRequired[bool]
+ r"""When true, reuses the model from the most recent assistant message's `model` attribute for subsequent turns. Defaults to false."""
class AutoRouterPlugin(BaseModel):
@@ -32,9 +34,14 @@ class AutoRouterPlugin(BaseModel):
enabled: Optional[bool] = None
r"""Set to false to disable the auto-router plugin for this request. Defaults to true."""
+ pin_model: Optional[bool] = None
+ r"""When true, reuses the model from the most recent assistant message's `model` attribute for subsequent turns. Defaults to false."""
+
@model_serializer(mode="wrap")
def serialize_model(self, handler):
- optional_fields = set(["allowed_models", "cost_quality_tradeoff", "enabled"])
+ optional_fields = set(
+ ["allowed_models", "cost_quality_tradeoff", "enabled", "pin_model"]
+ )
serialized = handler(self)
m = {}
diff --git a/src/openrouter/components/chatassistantmessage.py b/src/openrouter/components/chatassistantmessage.py
index 3caa2f31..45b8f490 100644
--- a/src/openrouter/components/chatassistantmessage.py
+++ b/src/openrouter/components/chatassistantmessage.py
@@ -43,6 +43,8 @@ class ChatAssistantMessageTypedDict(TypedDict):
r"""Assistant message content"""
images: NotRequired[List[ChatAssistantImagesTypedDict]]
r"""Generated images from image generation models"""
+ model: NotRequired[str]
+ r"""Model that generated this assistant message"""
name: NotRequired[str]
r"""Optional name for the assistant"""
reasoning: NotRequired[Nullable[str]]
@@ -69,6 +71,9 @@ class ChatAssistantMessage(BaseModel):
images: Optional[List[ChatAssistantImages]] = None
r"""Generated images from image generation models"""
+ model: Optional[str] = None
+ r"""Model that generated this assistant message"""
+
name: Optional[str] = None
r"""Optional name for the assistant"""
@@ -91,6 +96,7 @@ def serialize_model(self, handler):
"audio",
"content",
"images",
+ "model",
"name",
"reasoning",
"reasoning_details",
diff --git a/src/openrouter/components/chatrequest.py b/src/openrouter/components/chatrequest.py
index 1dd5d233..761053ae 100644
--- a/src/openrouter/components/chatrequest.py
+++ b/src/openrouter/components/chatrequest.py
@@ -81,9 +81,9 @@
ResponseHealingPluginTypedDict,
FileParserPluginTypedDict,
ContextCompressionPluginTypedDict,
- AutoRouterPluginTypedDict,
AutoBetaRouterPluginTypedDict,
ParetoRouterPluginTypedDict,
+ AutoRouterPluginTypedDict,
WebFetchPluginTypedDict,
FusionPluginTypedDict,
WebSearchPluginTypedDict,
diff --git a/src/openrouter/components/messagesrequest.py b/src/openrouter/components/messagesrequest.py
index 318eef45..13ca0cdb 100644
--- a/src/openrouter/components/messagesrequest.py
+++ b/src/openrouter/components/messagesrequest.py
@@ -363,9 +363,9 @@ def serialize_model(self, handler):
ResponseHealingPluginTypedDict,
FileParserPluginTypedDict,
ContextCompressionPluginTypedDict,
- AutoRouterPluginTypedDict,
AutoBetaRouterPluginTypedDict,
ParetoRouterPluginTypedDict,
+ AutoRouterPluginTypedDict,
WebFetchPluginTypedDict,
FusionPluginTypedDict,
WebSearchPluginTypedDict,
diff --git a/src/openrouter/components/responsesrequest.py b/src/openrouter/components/responsesrequest.py
index 49323df6..77ea6880 100644
--- a/src/openrouter/components/responsesrequest.py
+++ b/src/openrouter/components/responsesrequest.py
@@ -129,9 +129,9 @@
ResponseHealingPluginTypedDict,
FileParserPluginTypedDict,
ContextCompressionPluginTypedDict,
- AutoRouterPluginTypedDict,
AutoBetaRouterPluginTypedDict,
ParetoRouterPluginTypedDict,
+ AutoRouterPluginTypedDict,
WebFetchPluginTypedDict,
FusionPluginTypedDict,
WebSearchPluginTypedDict,
diff --git a/uv.lock b/uv.lock
index fd4fb006..b35af45f 100644
--- a/uv.lock
+++ b/uv.lock
@@ -213,7 +213,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.0.12"
+version = "1.0.13"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },