diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index 37c9a799..9f63688e 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: b8ef8e6acc081583a4b4b5280d5bc66a
+ docChecksum: 10cc3bd835df5bf3fce4fe2563a34256
docVersion: 1.0.0
speakeasyVersion: 1.787.0
generationVersion: 2.914.0
- releaseVersion: 1.2.7
- configChecksum: aa1b9118eec5df8f4c5665a1e53972cd
+ releaseVersion: 1.2.8
+ configChecksum: 5aa38056cf49b40445697d3786c6310a
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: bca11b04-b80d-49be-a6bd-00fc34f50538
- pristine_commit_hash: c713a8d5543ed7cc25eb572945a4a4c5ea574510
- pristine_tree_hash: ec331e7667fa75e32ef857f3c3ad74172c54ce23
+ generation_id: dce5049f-6fa8-49be-a5f5-bc657ee76aa9
+ pristine_commit_hash: 7f8731cb0345e17e75f6ee2102f01698513004ce
+ pristine_tree_hash: b9165056d686a979117bcf0e228ee3567ce2ffc4
features:
python:
acceptHeaders: 3.0.0
@@ -6841,6 +6841,14 @@ trackedFiles:
id: 56c7ec9966fa
last_write_checksum: sha1:b98cbf395a3bc9b53b859f3b1e8efe9ee35366bb
pristine_git_object: 1832b155e778ebd9eb28ebc4a4af459b95a1a506
+ docs/operations/createsystemoneglobals.mdx:
+ id: 41c14f5ceed1
+ last_write_checksum: sha1:96f8ca57c9f21bbfcd86edb240c79e6ca45a492c
+ pristine_git_object: 6fde4d64361c306141ada1382a473c123cf01b26
+ docs/operations/createsystemonerequest.mdx:
+ id: 482fbce116a8
+ last_write_checksum: sha1:b2631e99056ea9f80865ee9a40ffcbe5c198a432
+ pristine_git_object: 434fb7f89f9489c58dcfbf5dd065c5605206c118
docs/operations/createvideosglobals.mdx:
id: 84de29ff23d6
last_write_checksum: sha1:b0e6bc84afd5b4bcdb3f491c64b3f5c15e74d187
@@ -8141,6 +8149,10 @@ trackedFiles:
id: 190b0dc9a5d1
last_write_checksum: sha1:9a13f8f1e26550bccf3935a36e9c3426febc6fcb
pristine_git_object: 1a12d8375fe6ddf9ef6ee1911ce0ed6831a16942
+ docs/sdks/systemone/README.mdx:
+ id: 55c317c71f3d
+ last_write_checksum: sha1:b1ad82361fe1dbef6bedeead3783c75ec36283b6
+ pristine_git_object: fc7688ebea8e973bebc0525a820ba246b6491f81
docs/sdks/tts/README.mdx:
id: cd1132543884
last_write_checksum: sha1:37918eb124f9ae0234e8047be7ec07a955458cbc
@@ -8163,8 +8175,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:b9b202e55e8f133fe617f5a90f83911d10664e1e
- pristine_git_object: 11ae0f2796eb8bb374a0e12ab2cbcb284f6a1c34
+ last_write_checksum: sha1:9c9aac4feea5df58390f40a1d212f251d3b80123
+ pristine_git_object: 2fa4c827c0a455783b23e7183a3076a34e06723b
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -8191,8 +8203,8 @@ trackedFiles:
pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137
src/openrouter/_version.py:
id: d8d15ad6c586
- last_write_checksum: sha1:f80f256266c26716757ffd8846abb566c67c9557
- pristine_git_object: 9e7f35935b8f44c86d1f2c350d6179a3b5bdfe58
+ last_write_checksum: sha1:bf31610e41c64a659df291327e64114d28656f4f
+ pristine_git_object: 2a441139a5a23bb3841818e1e027427935a32494
src/openrouter/alpha.py:
id: 306c4d93308d
last_write_checksum: sha1:0c25a52ed5fb688ec1e923e4e82bcfc9cae49465
@@ -11163,8 +11175,8 @@ trackedFiles:
pristine_git_object: 8680343bbc90107ae6413bd5686012b1fd75d665
src/openrouter/operations/__init__.py:
id: 9afcea1e7161
- last_write_checksum: sha1:75bfcaac588b4da23900adbd7960f9a633955cf8
- pristine_git_object: 297025948ee72fba5ef27e0efb31207d6caf55d8
+ last_write_checksum: sha1:0c2f16d015e25e4cb302ba60d5aa8cf0e4d29f9f
+ pristine_git_object: f11532262b28c15b5a367afdeff9dd415e78f53e
src/openrouter/operations/bulkaddworkspacemembers.py:
id: e0ed56117619
last_write_checksum: sha1:5c44eb0d40fdece3ac084615f6c6082be4cf1d5a
@@ -11277,6 +11289,10 @@ trackedFiles:
id: 6e34c289d71d
last_write_checksum: sha1:3395583f3df63ed55df668d1172a9fbe507a47f0
pristine_git_object: bafc88732217831ec34ae960b8711e2587640ba9
+ src/openrouter/operations/createsystemone.py:
+ id: 3f135b32567e
+ last_write_checksum: sha1:7afb0a0fdf95fb8c6987c3e43fd6796e63e749ec
+ pristine_git_object: 356ee5d165f57ad1dea59e7064fbaff5a5807ce6
src/openrouter/operations/createvideos.py:
id: d52f6a4a3fe4
last_write_checksum: sha1:dbcf7068a23f48a5d4cfd9c8150206731a40cc9b
@@ -11675,8 +11691,8 @@ trackedFiles:
pristine_git_object: 1bea5be2496b283307c037f131a45a25bcca3c6c
src/openrouter/sdk.py:
id: ee9846c4c9c5
- last_write_checksum: sha1:242d0703dc95b748be45817ef9c7ad376e074b76
- pristine_git_object: 0fb8d63a93c0adc8462682be6e5a0207edebe593
+ last_write_checksum: sha1:524fce02fc013302916d4e533dc358c739f0cbb4
+ pristine_git_object: 28ea1b39c429276d1e06268ac0f60652ff15a989
src/openrouter/sdkconfiguration.py:
id: 55773bb98d7c
last_write_checksum: sha1:c01826125c31a8b8bc99d9d679782c8758fae001
@@ -11685,6 +11701,10 @@ trackedFiles:
id: fc0c2f669423
last_write_checksum: sha1:294961a1d783e04ac54c3733e4563494e241fcd7
pristine_git_object: 7502cb976473e1324ca78330ed0f22505d01c925
+ src/openrouter/systemone.py:
+ id: 7e0a0e237bb1
+ last_write_checksum: sha1:fffd7413e70f4840b793888763631b51929eb766
+ pristine_git_object: aac5cbef3468a6b9c9fe04c3bd6c86e23de4b4e9
src/openrouter/tts.py:
id: 5055d4b95f1d
last_write_checksum: sha1:cdeb84948a22d150b582c65b63a53bfab5c13109
@@ -14954,4 +14974,38 @@ examples:
application/json: {"error": {"code": 409, "message": "That question is no longer waiting for an answer."}}
"502":
application/json: {"error": {"code": 409, "message": "That question is no longer waiting for an answer."}}
+ createSystemone:
+ speakeasy-default-create-systemone:
+ requestBody:
+ application/json: {"model": "Taurus", "questions": {}, "state": {"key": "Utah", "key1": "Alaska", "key2": "Ohio"}}
+ responses:
+ "200":
+ application/json: {"answers": {"key": {"score": 9690, "type": "score"}}, "model": "Model Y", "usage": {"input_tokens": 514823, "output_tokens": 883118}}
+ "400":
+ application/json: {"error": {"code": 400, "message": "Invalid request parameters"}}
+ "401":
+ application/json: {"error": {"code": 401, "message": "Missing Authentication header"}}
+ "402":
+ application/json: {"error": {"code": 402, "message": "Insufficient credits. Add more using https://openrouter.ai/credits"}}
+ "403":
+ application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}}
+ "404":
+ application/json: {"error": {"code": 404, "message": "Resource not found"}}
+ "413":
+ application/json: {"error": {"code": 413, "message": "Request payload too large"}}
+ "429":
+ application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}}
+ "500":
+ application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
+ "502":
+ application/json: {"error": {"code": 502, "message": "Provider returned error"}}
+ "503":
+ application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}}
+ "524":
+ application/json: {"error": {"code": 524, "message": "Request timed out. Please try again later."}}
+ "529":
+ application/json: {"error": {"code": 529, "message": "Provider returned error"}}
examplesVersion: 1.0.2
+releaseNotes: |
+ ## Python SDK Changes:
+ * `open_router.system_one.create()`: **Added**
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index 11d453a8..4aa000a9 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -36,7 +36,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.2.7
+ version: 1.2.8
additionalDependencies:
dev: {}
main: {}
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index b0202321..c2508a42 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -43316,7 +43316,7 @@ paths:
- $ref: "#/components/parameters/AppCategories"
/systemone:
post:
- description: 'TypeSafe SDK compatible alias for `POST /api/alpha/decisions`. Accepts the same request body and returns the same response. Bare TypeSafe model IDs such as `jev-1.13` and `jev-latest` are mapped onto the `typesafe/` namespace.'
+ description: 'Sends state and typed questions to a System One model such as Jev and returns its answers. Compatible with the TypeSafe SDKs. Bare System One model IDs such as `jev-1.13` and `jev-latest` are mapped onto the `typesafe/` namespace.'
operationId: 'createSystemone'
requestBody:
content:
@@ -43509,10 +43509,10 @@ paths:
schema:
$ref: '#/components/schemas/ProviderOverloadedResponse'
description: 'Provider Overloaded - Provider is temporarily overloaded'
- summary: 'Submit a System One request (TypeSafe SDK compatible alias)'
+ summary: 'Submit a System One request'
tags:
- - 'alpha.decisions'
- x-speakeasy-ignore: true
+ - 'SystemOne'
+ x-speakeasy-name-override: 'create'
parameters:
- $ref: "#/components/parameters/AppIdentifier"
- $ref: "#/components/parameters/AppDisplayName"
@@ -46488,6 +46488,9 @@ tags:
- description: 'Speech-to-text endpoints'
name: 'STT'
x-displayName: 'Transcriptions'
+ - description: 'System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk.'
+ name: 'SystemOne'
+ x-displayName: 'System One'
- description: 'Text-to-speech endpoints'
name: 'TTS'
x-displayName: 'Speech'
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index 9dccc52a..3932be46 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:a6fb2582d267b7a3ea83cae1439a32e175a0f65079851685be4ad94d684f4689
- sourceBlobDigest: sha256:b48edb241b574a295970dc9757ce399f317bdb84a4932b017a60cbe5969a6801
+ sourceRevisionDigest: sha256:afa706f4e8224e896a845cf5ab0b73d8e7f98460c6cd9644071c183083268eda
+ sourceBlobDigest: sha256:52077f88403046264219927d45e06d3e45a47bcfcc5aceaeb5c494ec1144ae9a
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:a6fb2582d267b7a3ea83cae1439a32e175a0f65079851685be4ad94d684f4689
- sourceBlobDigest: sha256:b48edb241b574a295970dc9757ce399f317bdb84a4932b017a60cbe5969a6801
+ sourceRevisionDigest: sha256:afa706f4e8224e896a845cf5ab0b73d8e7f98460c6cd9644071c183083268eda
+ sourceBlobDigest: sha256:52077f88403046264219927d45e06d3e45a47bcfcc5aceaeb5c494ec1144ae9a
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:5ec445fcf3f7f6272d47694eeb88a4f2b90932843ec515d063c28b56df1c5ef9
+ codeSamplesRevisionDigest: sha256:b2cd8196b0557606a3c03dd8dfed3be0e421e0c278c63058cb0f8b947b49f6f6
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.787.0
diff --git a/RELEASES.md b/RELEASES.md
index 087109bb..982cd92e 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -2479,4 +2479,14 @@ Based on:
### Generated
- [python v1.2.7] .
### Releases
-- [PyPI v1.2.7] https://pypi.org/project/openrouter/1.2.7 - .
\ No newline at end of file
+- [PyPI v1.2.7] https://pypi.org/project/openrouter/1.2.7 - .
+
+## 2026-09-20 04:43:59
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.2.8] .
+### Releases
+- [PyPI v1.2.8] https://pypi.org/project/openrouter/1.2.8 - .
\ No newline at end of file
diff --git a/docs/docs.json b/docs/docs.json
index 3d453249..d7a03593 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -38,6 +38,7 @@
"sdks/responses/README",
"sdks/scim/README",
"sdks/stt/README",
+ "sdks/systemone/README",
"sdks/tts/README",
"sdks/vault/README",
"sdks/videogeneration/README",
diff --git a/docs/operations/createsystemoneglobals.mdx b/docs/operations/createsystemoneglobals.mdx
new file mode 100644
index 00000000..6fde4d64
--- /dev/null
+++ b/docs/operations/createsystemoneglobals.mdx
@@ -0,0 +1,11 @@
+---
+title: "CreateSystemoneGlobals"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
|
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
|
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
|
\ No newline at end of file
diff --git a/docs/operations/createsystemonerequest.mdx b/docs/operations/createsystemonerequest.mdx
new file mode 100644
index 00000000..434fb7f8
--- /dev/null
+++ b/docs/operations/createsystemonerequest.mdx
@@ -0,0 +1,12 @@
+---
+title: "CreateSystemoneRequest"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
|
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
|
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
|
+| `decisions_request` | [components.DecisionsRequest](../components/decisionsrequest.mdx) | :heavy_check_mark: | N/A |
\ No newline at end of file
diff --git a/docs/sdks/systemone/README.mdx b/docs/sdks/systemone/README.mdx
new file mode 100644
index 00000000..fc7688eb
--- /dev/null
+++ b/docs/sdks/systemone/README.mdx
@@ -0,0 +1,105 @@
+---
+title: "SystemOne"
+description: "System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk."
+---
+
+## Overview
+
+System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk.
+
+### Available Operations
+
+* [create](#create) - Submit a System One request
+
+## create
+
+Sends state and typed questions to a System One model such as Jev and returns its answers. Compatible with the TypeSafe SDKs. Bare System One model IDs such as `jev-1.13` and `jev-latest` are mapped onto the `typesafe/` namespace.
+
+### Example Usage
+
+```python
+from openrouter import OpenRouter
+import os
+
+
+with OpenRouter(
+ http_referer="",
+ x_open_router_title="",
+ x_open_router_categories="",
+ api_key=os.getenv("OPENROUTER_API_KEY", ""),
+) as open_router:
+
+ res = open_router.system_one.create(model="typesafe/jev-1.13", questions={
+ "is_bug": {
+ "criteria": {
+ "false": "The customer is asking a question or requesting a feature.",
+ "true": "The customer describes broken or unexpected product behavior.",
+ },
+ "instructions": "Is the customer reporting a software defect?",
+ "type": "noul",
+ },
+ "team": {
+ "criteria": {
+ "account": "Login, permissions, or profile issues.",
+ "frontend": "Rendering, layout, or browser compatibility issues.",
+ "payments": "Checkout, billing, or payment processing issues.",
+ },
+ "instructions": "Which team should own this ticket?",
+ "type": "choice",
+ },
+ "urgency": {
+ "criteria": [
+ "Can wait for the next release",
+ "Should be fixed this week",
+ "Blocking revenue right now",
+ ],
+ "instructions": "How urgent is this ticket?",
+ "type": "score",
+ },
+ }, state={
+ "customer_tier": "enterprise",
+ "ticket": "My checkout page shows a blank screen after I click Pay. I have tried two browsers.",
+ })
+
+ # Handle response
+ print(res)
+
+```
+
+### Parameters
+
+| Parameter | Type | Required | Description | Example |
+| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `model` | *str* | :heavy_check_mark: | N/A | |
+| `questions` | Dict[str, [components.Questions](../../components/questions.mdx)] | :heavy_check_mark: | N/A | |
+| `state` | [components.State](../../components/state.mdx) | :heavy_check_mark: | The content to evaluate: a plain string, or a JSON object or array of related context. | |
+| `http_referer` | *Optional[str]* | :heavy_minus_sign: | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| |
+| `x_open_router_title` | *Optional[str]* | :heavy_minus_sign: | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| |
+| `x_open_router_categories` | *Optional[str]* | :heavy_minus_sign: | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| |
+| `provider` | [OptionalNullable[components.ProviderPreferences]](../../components/providerpreferences.mdx) | :heavy_minus_sign: | N/A | \{
"allow_fallbacks": true
} |
+| `session_id` | *Optional[str]* | :heavy_minus_sign: | A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters. | session-1234 |
+| `trace` | [Optional[components.TraceConfig]](../../components/traceconfig.mdx) | :heavy_minus_sign: | Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations. | \{
"trace_id": "trace-abc123",
"trace_name": "my-app-trace"
} |
+| `user` | *Optional[str]* | :heavy_minus_sign: | N/A | |
+| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | |
+
+### Response
+
+**[components.DecisionsResponse](../../components/decisionsresponse.mdx)**
+
+### Errors
+
+| Error Type | Status Code | Content Type |
+| -------------------------------------- | -------------------------------------- | -------------------------------------- |
+| errors.BadRequestResponseError | 400 | application/json |
+| errors.UnauthorizedResponseError | 401 | application/json |
+| errors.PaymentRequiredResponseError | 402 | application/json |
+| errors.ForbiddenResponseError | 403 | application/json |
+| errors.NotFoundResponseError | 404 | application/json |
+| errors.PayloadTooLargeResponseError | 413 | application/json |
+| errors.TooManyRequestsResponseError | 429 | application/json |
+| errors.InternalServerResponseError | 500 | application/json |
+| errors.BadGatewayResponseError | 502 | application/json |
+| errors.ServiceUnavailableResponseError | 503 | application/json |
+| errors.EdgeNetworkTimeoutResponseError | 524 | application/json |
+| errors.ProviderOverloadedResponseError | 529 | application/json |
+| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* |
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 11ae0f27..2fa4c827 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.2.7"
+version = "1.2.8"
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 9e7f3593..2a441139 100644
--- a/src/openrouter/_version.py
+++ b/src/openrouter/_version.py
@@ -3,10 +3,10 @@
import importlib.metadata
__title__: str = "openrouter"
-__version__: str = "1.2.7"
+__version__: str = "1.2.8"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.914.0"
-__user_agent__: str = "speakeasy-sdk/python 1.2.7 2.914.0 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.2.8 2.914.0 1.0.0 openrouter"
try:
if __package__ is not None:
diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py
index 29702594..f1153226 100644
--- a/src/openrouter/operations/__init__.py
+++ b/src/openrouter/operations/__init__.py
@@ -252,6 +252,12 @@
CreateScimSyncJobResponse,
CreateScimSyncJobResponseTypedDict,
)
+ from .createsystemone import (
+ CreateSystemoneGlobals,
+ CreateSystemoneGlobalsTypedDict,
+ CreateSystemoneRequest,
+ CreateSystemoneRequestTypedDict,
+ )
from .createvideos import (
CreateVideosGlobals,
CreateVideosGlobalsTypedDict,
@@ -1151,6 +1157,10 @@
"CreateScimSyncJobRequestTypedDict",
"CreateScimSyncJobResponse",
"CreateScimSyncJobResponseTypedDict",
+ "CreateSystemoneGlobals",
+ "CreateSystemoneGlobalsTypedDict",
+ "CreateSystemoneRequest",
+ "CreateSystemoneRequestTypedDict",
"CreateVideosGlobals",
"CreateVideosGlobalsTypedDict",
"CreateVideosRequest",
@@ -1899,6 +1909,10 @@
"CreateScimSyncJobRequestTypedDict": ".createscimsyncjob",
"CreateScimSyncJobResponse": ".createscimsyncjob",
"CreateScimSyncJobResponseTypedDict": ".createscimsyncjob",
+ "CreateSystemoneGlobals": ".createsystemone",
+ "CreateSystemoneGlobalsTypedDict": ".createsystemone",
+ "CreateSystemoneRequest": ".createsystemone",
+ "CreateSystemoneRequestTypedDict": ".createsystemone",
"CreateVideosGlobals": ".createvideos",
"CreateVideosGlobalsTypedDict": ".createvideos",
"CreateVideosRequest": ".createvideos",
diff --git a/src/openrouter/operations/createsystemone.py b/src/openrouter/operations/createsystemone.py
new file mode 100644
index 00000000..356ee5d1
--- /dev/null
+++ b/src/openrouter/operations/createsystemone.py
@@ -0,0 +1,144 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.components import decisionsrequest as components_decisionsrequest
+from openrouter.types import BaseModel, UNSET_SENTINEL
+from openrouter.utils import FieldMetadata, HeaderMetadata, RequestMetadata
+import pydantic
+from pydantic import model_serializer
+from typing import Optional
+from typing_extensions import Annotated, NotRequired, TypedDict
+
+
+class CreateSystemoneGlobalsTypedDict(TypedDict):
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class CreateSystemoneGlobals(BaseModel):
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
+
+
+class CreateSystemoneRequestTypedDict(TypedDict):
+ decisions_request: components_decisionsrequest.DecisionsRequestTypedDict
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class CreateSystemoneRequest(BaseModel):
+ decisions_request: Annotated[
+ components_decisionsrequest.DecisionsRequest,
+ FieldMetadata(request=RequestMetadata(media_type="application/json")),
+ ]
+
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/sdk.py b/src/openrouter/sdk.py
index 0fb8d63a..28ea1b39 100644
--- a/src/openrouter/sdk.py
+++ b/src/openrouter/sdk.py
@@ -44,6 +44,7 @@
from openrouter.responses import Responses
from openrouter.scim import Scim
from openrouter.stt import STT
+ from openrouter.systemone import SystemOne
from openrouter.tts import TTS
from openrouter.vault import Vault
from openrouter.video_generation import VideoGeneration
@@ -110,6 +111,8 @@ class OpenRouter(BaseSDK):
beta: "Beta"
scim: "Scim"
r"""Management endpoints for SCIM group-to-workspace mappings, authenticated with a management key. These are not the SCIM 2.0 connector endpoints for your identity provider. In your identity provider, enter the SCIM endpoint URL shown when you enable provisioning under Settings > Members > SCIM Mappings. See https://openrouter.ai/docs/guides/features/scim-mappings#set-up-provisioning."""
+ system_one: "SystemOne"
+ r"""System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk."""
vault: "Vault"
r"""Store host-bound secrets for a workspace or for one intern. Scope is selected by the API key. Responses return metadata only, never secret values. See https://openrouter.ai/docs/guides/ori/vault."""
video_generation: "VideoGeneration"
@@ -146,6 +149,7 @@ class OpenRouter(BaseSDK):
"responses": ("openrouter.responses", "Responses"),
"beta": ("openrouter.beta", "Beta"),
"scim": ("openrouter.scim", "Scim"),
+ "system_one": ("openrouter.systemone", "SystemOne"),
"vault": ("openrouter.vault", "Vault"),
"video_generation": ("openrouter.video_generation", "VideoGeneration"),
"workspaces": ("openrouter.workspaces", "Workspaces"),
diff --git a/src/openrouter/systemone.py b/src/openrouter/systemone.py
new file mode 100644
index 00000000..aac5cbef
--- /dev/null
+++ b/src/openrouter/systemone.py
@@ -0,0 +1,439 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from .basesdk import BaseSDK
+from openrouter import components, errors, operations, utils
+from openrouter._hooks import HookContext
+from openrouter.types import OptionalNullable, UNSET
+from openrouter.utils import get_security_from_env
+from openrouter.utils.unmarshal_json_response import unmarshal_json_response
+from typing import Any, Dict, Mapping, Optional, Union
+
+
+class SystemOne(BaseSDK):
+ r"""System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk."""
+
+ def create(
+ self,
+ *,
+ model: str,
+ questions: Union[
+ Mapping[str, components.Questions],
+ Mapping[str, components.QuestionsTypedDict],
+ ],
+ state: Union[components.State, components.StateTypedDict],
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ provider: OptionalNullable[
+ Union[
+ components.ProviderPreferences, components.ProviderPreferencesTypedDict
+ ]
+ ] = UNSET,
+ session_id: Optional[str] = None,
+ trace: Optional[
+ Union[components.TraceConfig, components.TraceConfigTypedDict]
+ ] = None,
+ user: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.DecisionsResponse:
+ r"""Submit a System One request
+
+ Sends state and typed questions to a System One model such as Jev and returns its answers. Compatible with the TypeSafe SDKs. Bare System One model IDs such as `jev-1.13` and `jev-latest` are mapped onto the `typesafe/` namespace.
+
+ :param model:
+ :param questions:
+ :param state: The content to evaluate: a plain string, or a JSON object or array of related context.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param provider:
+ :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
+ :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
+ :param user:
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = self._get_url(base_url, url_variables)
+
+ request = operations.CreateSystemoneRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ decisions_request=components.DecisionsRequest(
+ model=model,
+ provider=utils.get_pydantic_model(
+ provider, OptionalNullable[components.ProviderPreferences]
+ ),
+ questions=utils.get_pydantic_model(
+ questions, Dict[str, components.Questions]
+ ),
+ session_id=session_id,
+ state=utils.unmarshal(state, components.State),
+ trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
+ user=user,
+ ),
+ )
+
+ req = self._build_request(
+ method="POST",
+ path="/systemone",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=True,
+ request_has_path_params=False,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.CreateSystemoneGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ get_serialized_body=lambda: utils.serialize_request_body(
+ request.decisions_request,
+ False,
+ False,
+ "json",
+ components.DecisionsRequest,
+ ),
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = self.do_request(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="createSystemone",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["SystemOne"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(components.DecisionsResponse, http_res)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "402", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PaymentRequiredResponseErrorData, http_res
+ )
+ raise errors.PaymentRequiredResponseError(response_data, http_res)
+ if utils.match_response(http_res, "403", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ForbiddenResponseErrorData, http_res
+ )
+ raise errors.ForbiddenResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "413", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PayloadTooLargeResponseErrorData, http_res
+ )
+ raise errors.PayloadTooLargeResponseError(response_data, http_res)
+ if utils.match_response(http_res, "429", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.TooManyRequestsResponseErrorData, http_res
+ )
+ raise errors.TooManyRequestsResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "502", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadGatewayResponseErrorData, http_res
+ )
+ raise errors.BadGatewayResponseError(response_data, http_res)
+ if utils.match_response(http_res, "503", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ServiceUnavailableResponseErrorData, http_res
+ )
+ raise errors.ServiceUnavailableResponseError(response_data, http_res)
+ if utils.match_response(http_res, "524", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.EdgeNetworkTimeoutResponseErrorData, http_res
+ )
+ raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res)
+ if utils.match_response(http_res, "529", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ProviderOverloadedResponseErrorData, http_res
+ )
+ raise errors.ProviderOverloadedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
+
+ async def create_async(
+ self,
+ *,
+ model: str,
+ questions: Union[
+ Mapping[str, components.Questions],
+ Mapping[str, components.QuestionsTypedDict],
+ ],
+ state: Union[components.State, components.StateTypedDict],
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ provider: OptionalNullable[
+ Union[
+ components.ProviderPreferences, components.ProviderPreferencesTypedDict
+ ]
+ ] = UNSET,
+ session_id: Optional[str] = None,
+ trace: Optional[
+ Union[components.TraceConfig, components.TraceConfigTypedDict]
+ ] = None,
+ user: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.DecisionsResponse:
+ r"""Submit a System One request
+
+ Sends state and typed questions to a System One model such as Jev and returns its answers. Compatible with the TypeSafe SDKs. Bare System One model IDs such as `jev-1.13` and `jev-latest` are mapped onto the `typesafe/` namespace.
+
+ :param model:
+ :param questions:
+ :param state: The content to evaluate: a plain string, or a JSON object or array of related context.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param provider:
+ :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
+ :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
+ :param user:
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = self._get_url(base_url, url_variables)
+
+ request = operations.CreateSystemoneRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ decisions_request=components.DecisionsRequest(
+ model=model,
+ provider=utils.get_pydantic_model(
+ provider, OptionalNullable[components.ProviderPreferences]
+ ),
+ questions=utils.get_pydantic_model(
+ questions, Dict[str, components.Questions]
+ ),
+ session_id=session_id,
+ state=utils.unmarshal(state, components.State),
+ trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
+ user=user,
+ ),
+ )
+
+ req = self._build_request_async(
+ method="POST",
+ path="/systemone",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=True,
+ request_has_path_params=False,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.CreateSystemoneGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ get_serialized_body=lambda: utils.serialize_request_body(
+ request.decisions_request,
+ False,
+ False,
+ "json",
+ components.DecisionsRequest,
+ ),
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = await self.do_request_async(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="createSystemone",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["SystemOne"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(components.DecisionsResponse, http_res)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "402", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PaymentRequiredResponseErrorData, http_res
+ )
+ raise errors.PaymentRequiredResponseError(response_data, http_res)
+ if utils.match_response(http_res, "403", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ForbiddenResponseErrorData, http_res
+ )
+ raise errors.ForbiddenResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "413", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PayloadTooLargeResponseErrorData, http_res
+ )
+ raise errors.PayloadTooLargeResponseError(response_data, http_res)
+ if utils.match_response(http_res, "429", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.TooManyRequestsResponseErrorData, http_res
+ )
+ raise errors.TooManyRequestsResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "502", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadGatewayResponseErrorData, http_res
+ )
+ raise errors.BadGatewayResponseError(response_data, http_res)
+ if utils.match_response(http_res, "503", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ServiceUnavailableResponseErrorData, http_res
+ )
+ raise errors.ServiceUnavailableResponseError(response_data, http_res)
+ if utils.match_response(http_res, "524", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.EdgeNetworkTimeoutResponseErrorData, http_res
+ )
+ raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res)
+ if utils.match_response(http_res, "529", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ProviderOverloadedResponseErrorData, http_res
+ )
+ raise errors.ProviderOverloadedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
diff --git a/uv.lock b/uv.lock
index aeb95892..46c838ee 100644
--- a/uv.lock
+++ b/uv.lock
@@ -213,7 +213,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.2.7"
+version = "1.2.8"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },