From dedb9efe1079a805fb73b5dc6b264ce97c0db87d Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Wed, 22 Jul 2026 19:14:22 +0000 Subject: [PATCH 1/2] ## Python SDK Changes: * `open_router.beta.responses.send()`: * `request.plugins[].union(auto-router).pin_model` **Added** * `open_router.chat.send()`: * `request` **Changed** * `response.choices[].message.model` **Added** * `open_router.presets.create_presets_chat_completions()`: `request` **Changed** * `open_router.presets.create_presets_messages()`: * `request.plugins[].union(auto-router).pin_model` **Added** * `open_router.presets.create_presets_responses()`: * `request.plugins[].union(auto-router).pin_model` **Added** --- .speakeasy/gen.lock | 49 ++++++++++--------- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 10 ++++ .speakeasy/workflow.lock | 10 ++-- RELEASES.md | 12 ++++- docs/components/autorouterplugin.mdx | 3 +- docs/components/chatassistantmessage.mdx | 1 + pyproject.toml | 2 +- src/openrouter/_version.py | 4 +- src/openrouter/components/autorouterplugin.py | 9 +++- .../components/chatassistantmessage.py | 6 +++ src/openrouter/components/chatrequest.py | 2 +- src/openrouter/components/messagesrequest.py | 2 +- src/openrouter/components/responsesrequest.py | 2 +- uv.lock | 2 +- 15 files changed, 76 insertions(+), 40 deletions(-) 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" }, From 2dce373e66313afab234d9c4c07373ac7e772880 Mon Sep 17 00:00:00 2001 From: "speakeasy-github[bot]" <128539517+speakeasy-github[bot]@users.noreply.github.com> Date: Wed, 22 Jul 2026 19:14:28 +0000 Subject: [PATCH 2/2] empty commit to trigger [run-tests] workflow