From 6ce9ab79b0102b182f8d56089ce8dcba453f1f9c Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Sat, 19 Sep 2026 17:31:27 +0000 Subject: [PATCH 1/2] ## Python SDK Changes: * `open_router.interns.create_intern()`: `request.workspace_id` **Changed** * `open_router.interns.chat()`: * `request.messages[].union(assistant).content` **Changed** --- .speakeasy/gen.lock | 47 ++++++++++--------- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 8 ++-- .speakeasy/workflow.lock | 10 ++-- RELEASES.md | 12 ++++- docs/components/createinternrequest.mdx | 18 +++---- .../components/internchatassistantmessage.mdx | 2 +- docs/sdks/interns/README.mdx | 6 +-- pyproject.toml | 2 +- src/openrouter/_version.py | 4 +- .../components/createinternrequest.py | 18 +++---- .../components/internchatassistantmessage.py | 20 +++++--- src/openrouter/interns.py | 12 ++--- uv.lock | 2 +- 14 files changed, 90 insertions(+), 73 deletions(-) diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index c2c4f3a9..063fde66 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: b50edb303a275cd87528559fa56a9f23 + docChecksum: 98e7150b3031e3fd420a1417065c8c33 docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 1.2.2 - configChecksum: f59aacfc0651c61a9fc72baa8dd7804a + releaseVersion: 1.2.3 + configChecksum: 623dce73439db2a40cf9981582190d03 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: c9534058-2165-4649-a72f-2119e436b427 - pristine_commit_hash: 44783a354d54bd8233f5daff2b0b59b41b3d3a43 - pristine_tree_hash: 509d8ec43d574910bf9c0480151873c9fd9fc0a4 + generation_id: 5d7c21fa-536d-4272-9c2a-e55016282111 + pristine_commit_hash: 1b3d14226546a1c7499d1c2514b24bb578f5cca2 + pristine_tree_hash: 0eba64490d21ab3a4f5b7aa4e08a595d88dfb716 features: python: acceptHeaders: 3.0.0 @@ -1659,8 +1659,8 @@ trackedFiles: pristine_git_object: 63cc820d2e3f4ddaa6d42dfef4c80006f7810cb2 docs/components/createinternrequest.mdx: id: 31228037ef68 - last_write_checksum: sha1:adb8b817fb517aae23e9417988c9e6231ef493fd - pristine_git_object: a14e0eafcb0825429ad47197f7036617870488a7 + last_write_checksum: sha1:7f6dd17a2cc45ed74745d9147ec34be3530c9459 + pristine_git_object: 28e8aee5c2ddf7faea52b6f4515b4f25bcaa77fe docs/components/createobservabilitydestinationrequest.mdx: id: 8d942a601a6e last_write_checksum: sha1:a266eb148b179de43a1b08282d7cadd013e5eaa1 @@ -2951,8 +2951,8 @@ trackedFiles: pristine_git_object: 14f94bb02c48a460c14d50a0595fc0e89b52e6af docs/components/internchatassistantmessage.mdx: id: 041634b73e1e - last_write_checksum: sha1:1e1737a7dad6fe27cc46dd8ade384869c3405784 - pristine_git_object: c8cd00acd8a2ba6fc9deb39eb67c88f5df721d02 + last_write_checksum: sha1:94e8b73e31c14adcdb26c27494e527c308a6a15b + pristine_git_object: 3334fd334d99f2fbb41a8991fbd1065e5aa4234d docs/components/internchatassistantmessagerole.mdx: id: 129e5368066f last_write_checksum: sha1:82c992193fb0cc60c16db0c54e827830edd565dc @@ -8095,8 +8095,8 @@ trackedFiles: pristine_git_object: 08c687694efbecf50406ae7929029d39fb121295 docs/sdks/interns/README.mdx: id: 2f8a053ffe78 - last_write_checksum: sha1:da31cdf965e76b3d7407859c77195597dfc0f3f3 - pristine_git_object: 7c93035351f6c24a0dbc6ad9ffa88ff6983436be + last_write_checksum: sha1:761b9ca2d74d524a438c0c28d6b2a8eaf094d02f + pristine_git_object: e1629ebefd58b9bc114f18c18ca4f789f9e28cf2 docs/sdks/models/README.mdx: id: 58f1ca464e0b last_write_checksum: sha1:093dd30ebdd18b9763a6956915e0dcae4ae7d5e5 @@ -8159,8 +8159,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:9afc3fd39db73dc4ebc9191ca2f946f7d0fb314f - pristine_git_object: e226a37cb10351e696db48eaa6c6756d8b606fd1 + last_write_checksum: sha1:53b3f141b22a6643e7a6482d3a925c184cde880a + pristine_git_object: 4617f98a2d78d6cd1d6cf7f71dad83c97abdf784 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -8187,8 +8187,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:6fff83400b77ac7544e0264ec4947cf99d180892 - pristine_git_object: d221360b25686132fe7f6ceba3fda75bc2a14bcb + last_write_checksum: sha1:f76f1919ba451dd947efe64925dbc5eff1939bd3 + pristine_git_object: 2ea5bbe6f2011c6d8e394549eb4b0ef9d503dcc5 src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:0c25a52ed5fb688ec1e923e4e82bcfc9cae49465 @@ -8963,8 +8963,8 @@ trackedFiles: pristine_git_object: d6c4a4dc73222668daddc2a1788d314ff30e8fe6 src/openrouter/components/createinternrequest.py: id: 5722cff28787 - last_write_checksum: sha1:304835f2ff0852585a88d22e902f5ba63b0a749c - pristine_git_object: f8da7513209307490563f91eeff184cd46c745a5 + last_write_checksum: sha1:7bb6aa692c02e2c844df09e1109d47b82c53433f + pristine_git_object: b65a8d59c7513566b243b61ba052e2d921186153 src/openrouter/components/createobservabilitydestinationrequest.py: id: 58587fb98a32 last_write_checksum: sha1:e0acb6b3d5dda9f6101b69ab9048dfea1492bb73 @@ -9511,8 +9511,8 @@ trackedFiles: pristine_git_object: 988b3a736faf813db2adf006f36e0c400935bb46 src/openrouter/components/internchatassistantmessage.py: id: c730f5412099 - last_write_checksum: sha1:45ffb3fbffa40a876abaf6178c6a6cc520c49fee - pristine_git_object: dcace16b45df1feb6cff3cf26a81e4e57dcff01f + last_write_checksum: sha1:b7604b2f9bf91090ef9e55f6d77a85aeaf771762 + pristine_git_object: 208a06d25920d4bfd39bb527b54e78be44adf9f3 src/openrouter/components/internchatchoice.py: id: 9ff5592609ff last_write_checksum: sha1:485dfd417ca8af7b2be21f8618179db06f598076 @@ -11127,8 +11127,8 @@ trackedFiles: pristine_git_object: 50643a126668498dd668c7cceb9f78c03d413d32 src/openrouter/interns.py: id: d18df05c5c6d - last_write_checksum: sha1:b0bfde773d639616f1ace6bbe828aaf443c0db2a - pristine_git_object: 4e354feedb9e31941e080333c7280852fcd4c823 + last_write_checksum: sha1:46da31cb08d788fef4b47deb9da667d2ac46d7aa + pristine_git_object: d1dac0bfa081eb17a14a363f4c0c7d688b4b45c7 src/openrouter/models/__init__.py: id: ed73b93abb3f last_write_checksum: sha1:932a790ae66ccd7d7022b39c659bcf72a664ebea @@ -14825,7 +14825,7 @@ examples: createIntern: speakeasy-default-create-intern: requestBody: - application/json: {"name": "research-assistant", "provision": true, "workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"} + application/json: {"name": "research-assistant", "provision": true} responses: "200": application/json: {"attached_vault_id": null, "created_at": "2026-09-16T08:30:00.000Z", "description": "Researches customer questions", "hostname": "research-assistant.openrouter.ai", "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7", "instructions": null, "last_failure_message": null, "model": "openai/gpt-5.4", "name": "research-assistant", "progress": null, "status": "running", "updated_at": "2026-09-16T08:45:00.000Z", "vault_id": "b431c59d-6eed-41ac-bc89-9a89be79a121", "workspace_id": "89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb"} @@ -14941,3 +14941,4 @@ examples: "502": application/json: {"error": {"code": 409, "message": "That question is no longer waiting for an answer."}} examplesVersion: 1.0.2 +releaseNotes: "## Python SDK Changes:\n* `open_router.interns.create_intern()`: `request.workspace_id` **Changed**\n* `open_router.interns.chat()`: \n * `request.messages[].union(assistant).content` **Changed**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 10cdd576..46873894 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.2.2 + version: 1.2.3 additionalDependencies: dev: {} main: {} diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 21ac3c14..a2f942f0 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -7714,7 +7714,7 @@ components: type: 'object' CreateInternRequest: additionalProperties: false - description: 'Settings for a new intern in an explicit workspace.' + description: 'Settings for a new intern.' example: name: 'research-assistant' provision: true @@ -7747,12 +7747,11 @@ components: format: 'uuid' type: 'string' workspace_id: - description: 'Workspace that will own the intern. It must match the API key workspace.' + description: 'Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace.' format: 'uuid' type: 'string' required: - 'name' - - 'workspace_id' type: 'object' CreateObservabilityDestinationRequest: example: @@ -12557,7 +12556,6 @@ components: $ref: '#/components/schemas/InternChatEchoedToolCall' type: 'array' required: - - 'content' - 'role' type: 'object' InternChatChoice: @@ -36936,7 +36934,7 @@ paths: - $ref: "#/components/parameters/AppCategories" /interns/{internId}/chat/completions: post: - description: "Sends a prompt to one of your interns and streams the reply as OpenAI-compatible server-sent events ending with `[DONE]`. The run executes on the intern, which may pause to ask you something. It then streams one `openrouter.provide_input` tool call and finishes with `finish_reason: \"tool_calls\"`, and the run stays open on the intern.\n\nEvery response, whether it ends with `stop`, `tool_calls` or `error`, is followed by a final chunk with empty `choices` that carries `session_id`, then `data: [DONE]`. That chunk carries the `usage` the intern reported for the run, after `stop` or `error`, and `null` when the intern reported none. After `tool_calls` its `usage` is `null` because the turn is not over. Read through `[DONE]`: the `session_id` you need to reply arrives after the `tool_calls` finish chunk.\n\nTo answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline.\n\nClosing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The disconnect is noticed when the intern next writes to the stream, which during a silent tool run can take more than one 30 second heartbeat interval.\n\nA run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: \"error\"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event.\n\nSet `approval_mode` to `manual` to have the intern ask before approval-bearing tools such as the shell. Omitted, the run self-drives and consents on your behalf. The mode belongs to the run started by that prompt and must be repeated on later prompts.\n\nAvailable to interns programme members. Callers outside the programme receive `404` for every path under `/api/v1/interns`." + description: "Sends a prompt to one of your interns and streams the reply as OpenAI-compatible server-sent events ending with `[DONE]`. The run executes on the intern, which may pause to ask you something. It then streams one `openrouter.provide_input` tool call and finishes with `finish_reason: \"tool_calls\"`, and the run stays open on the intern.\n\nEvery response, whether it ends with `stop`, `tool_calls` or `error`, is followed by a final chunk with empty `choices` that carries `session_id`, then `data: [DONE]`. That chunk carries the `usage` the intern reported for the run, after `stop` or `error`, and `null` when the intern reported none. After `tool_calls` its `usage` is `null` because the turn is not over. Read through `[DONE]`: the `session_id` you need to reply arrives after the `tool_calls` finish chunk.\n\nTo answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline.\n\nClosing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent.\n\nA run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: \"error\"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event.\n\nSet `approval_mode` to `manual` to have the intern ask before approval-bearing tools such as the shell. Omitted, the run self-drives and consents on your behalf. The mode belongs to the run started by that prompt and must be repeated on later prompts.\n\nAvailable to interns programme members. Callers outside the programme receive `404` for every path under `/api/v1/interns`." operationId: 'createInternChatCompletion' parameters: - description: 'The intern to talk to.' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 83326f80..17487a39 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:2a5f58c93ded285d2ea44843c2be64279bf9f883f2507c941cd7c3e6fffc1cf6 - sourceBlobDigest: sha256:b675b6683675edd5bbfb18635aa9b01a0aef7c99e2360292069370339c7d1577 + sourceRevisionDigest: sha256:f0fb9fa202382f14a83873f69b9d5b003cd33e065510c8821c67a663199a416f + sourceBlobDigest: sha256:59e9c8a835a3892c62f41b61b4fa7fc9875e22c07ed105629f1bf1ef40247e24 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:2a5f58c93ded285d2ea44843c2be64279bf9f883f2507c941cd7c3e6fffc1cf6 - sourceBlobDigest: sha256:b675b6683675edd5bbfb18635aa9b01a0aef7c99e2360292069370339c7d1577 + sourceRevisionDigest: sha256:f0fb9fa202382f14a83873f69b9d5b003cd33e065510c8821c67a663199a416f + sourceBlobDigest: sha256:59e9c8a835a3892c62f41b61b4fa7fc9875e22c07ed105629f1bf1ef40247e24 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:346062ca02f81ae3d976e78102fdc231b473c80fd7327c0a48b1023cadb5e99a + codeSamplesRevisionDigest: sha256:5f67b7a6c5047267d59779ec3bfd641d2362b080355e376e8d1f2c4452c0669d workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/RELEASES.md b/RELEASES.md index b0192391..657a70e7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2429,4 +2429,14 @@ Based on: ### Generated - [python v1.2.2] . ### Releases -- [PyPI v1.2.2] https://pypi.org/project/openrouter/1.2.2 - . \ No newline at end of file +- [PyPI v1.2.2] https://pypi.org/project/openrouter/1.2.2 - . + +## 2026-09-19 17:29:06 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.2.3] . +### Releases +- [PyPI v1.2.3] https://pypi.org/project/openrouter/1.2.3 - . \ No newline at end of file diff --git a/docs/components/createinternrequest.mdx b/docs/components/createinternrequest.mdx index a14e0eaf..28e8aee5 100644 --- a/docs/components/createinternrequest.mdx +++ b/docs/components/createinternrequest.mdx @@ -2,16 +2,16 @@ title: "CreateInternRequest" --- -Settings for a new intern in an explicit workspace. +Settings for a new intern. ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | -| `description` | *OptionalNullable[str]* | :heavy_minus_sign: | Free-form description, or null. | -| `instructions` | *OptionalNullable[str]* | :heavy_minus_sign: | Standing instructions the intern boots with, or null. | -| `name` | *str* | :heavy_check_mark: | Intern name, unique per creator within the workspace. | -| `provision` | *Optional[bool]* | :heavy_minus_sign: | Start provisioning during this create operation. Defaults to false. | -| `vault_id` | *Optional[str]* | :heavy_minus_sign: | Vault owned by another intern in this workspace to attach as a borrowed vault. | -| `workspace_id` | *str* | :heavy_check_mark: | Workspace that will own the intern. It must match the API key workspace. | \ No newline at end of file +| Field | Type | Required | Description | +| --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- | +| `description` | *OptionalNullable[str]* | :heavy_minus_sign: | Free-form description, or null. | +| `instructions` | *OptionalNullable[str]* | :heavy_minus_sign: | Standing instructions the intern boots with, or null. | +| `name` | *str* | :heavy_check_mark: | Intern name, unique per creator within the workspace. | +| `provision` | *Optional[bool]* | :heavy_minus_sign: | Start provisioning during this create operation. Defaults to false. | +| `vault_id` | *Optional[str]* | :heavy_minus_sign: | Vault owned by another intern in this workspace to attach as a borrowed vault. | +| `workspace_id` | *Optional[str]* | :heavy_minus_sign: | Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace. | \ No newline at end of file diff --git a/docs/components/internchatassistantmessage.mdx b/docs/components/internchatassistantmessage.mdx index c8cd00ac..3334fd33 100644 --- a/docs/components/internchatassistantmessage.mdx +++ b/docs/components/internchatassistantmessage.mdx @@ -9,6 +9,6 @@ An assistant message from an earlier response. When answering an interaction, ec | Field | Type | Required | Description | Example | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `content` | [Nullable[components.InternChatMessageContent]](../components/internchatmessagecontent.mdx) | :heavy_check_mark: | Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history. | Summarize the open pull requests. | +| `content` | [OptionalNullable[components.InternChatMessageContent]](../components/internchatmessagecontent.mdx) | :heavy_minus_sign: | Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history. | Summarize the open pull requests. | | `role` | [components.InternChatAssistantMessageRole](../components/internchatassistantmessagerole.mdx) | :heavy_check_mark: | N/A | | | `tool_calls` | List[[components.InternChatEchoedToolCall](../components/internchatechoedtoolcall.mdx)] | :heavy_minus_sign: | N/A | | \ No newline at end of file diff --git a/docs/sdks/interns/README.mdx b/docs/sdks/interns/README.mdx index 7c930353..e1629ebe 100644 --- a/docs/sdks/interns/README.mdx +++ b/docs/sdks/interns/README.mdx @@ -85,7 +85,7 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.interns.create_intern(name="research-assistant", workspace_id="89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb", provision=True) + res = open_router.interns.create_intern(name="research-assistant", provision=True, workspace_id="89f9f5b2-3f89-4eaf-83ca-5ceae149e8bb") # Handle response print(res) @@ -97,7 +97,6 @@ with OpenRouter( | Parameter | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | `name` | *str* | :heavy_check_mark: | Intern name, unique per creator within the workspace. | | -| `workspace_id` | *str* | :heavy_check_mark: | Workspace that will own the intern. It must match the API key workspace. | | | `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.
| | @@ -106,6 +105,7 @@ with OpenRouter( | `instructions` | *OptionalNullable[str]* | :heavy_minus_sign: | Standing instructions the intern boots with, or null. | | | `provision` | *Optional[bool]* | :heavy_minus_sign: | Start provisioning during this create operation. Defaults to false. | | | `vault_id` | *Optional[str]* | :heavy_minus_sign: | Vault owned by another intern in this workspace to attach as a borrowed vault. | | +| `workspace_id` | *Optional[str]* | :heavy_minus_sign: | Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace. | | | `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | :heavy_minus_sign: | Configuration to override the default retry behavior of the client. | | ### Response @@ -367,7 +367,7 @@ Every response, whether it ends with `stop`, `tool_calls` or `error`, is followe To answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline. -Closing the connection after the `[DONE]` that follows `finish_reason: "tool_calls"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The disconnect is noticed when the intern next writes to the stream, which during a silent tool run can take more than one 30 second heartbeat interval. +Closing the connection after the `[DONE]` that follows `finish_reason: "tool_calls"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent. A run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: "error"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event. diff --git a/pyproject.toml b/pyproject.toml index e226a37c..4617f98a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.2.2" +version = "1.2.3" 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 d221360b..2ea5bbe6 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.2" +__version__: str = "1.2.3" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.914.0" -__user_agent__: str = "speakeasy-sdk/python 1.2.2 2.914.0 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.2.3 2.914.0 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/createinternrequest.py b/src/openrouter/components/createinternrequest.py index f8da7513..b65a8d59 100644 --- a/src/openrouter/components/createinternrequest.py +++ b/src/openrouter/components/createinternrequest.py @@ -14,12 +14,10 @@ class CreateInternRequestTypedDict(TypedDict): - r"""Settings for a new intern in an explicit workspace.""" + r"""Settings for a new intern.""" name: str r"""Intern name, unique per creator within the workspace.""" - workspace_id: str - r"""Workspace that will own the intern. It must match the API key workspace.""" description: NotRequired[Nullable[str]] r"""Free-form description, or null.""" instructions: NotRequired[Nullable[str]] @@ -28,17 +26,16 @@ class CreateInternRequestTypedDict(TypedDict): r"""Start provisioning during this create operation. Defaults to false.""" vault_id: NotRequired[str] r"""Vault owned by another intern in this workspace to attach as a borrowed vault.""" + workspace_id: NotRequired[str] + r"""Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace.""" class CreateInternRequest(BaseModel): - r"""Settings for a new intern in an explicit workspace.""" + r"""Settings for a new intern.""" name: str r"""Intern name, unique per creator within the workspace.""" - workspace_id: str - r"""Workspace that will own the intern. It must match the API key workspace.""" - description: OptionalNullable[str] = UNSET r"""Free-form description, or null.""" @@ -51,9 +48,14 @@ class CreateInternRequest(BaseModel): vault_id: Optional[str] = None r"""Vault owned by another intern in this workspace to attach as a borrowed vault.""" + workspace_id: Optional[str] = None + r"""Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace.""" + @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["description", "instructions", "provision", "vault_id"]) + optional_fields = set( + ["description", "instructions", "provision", "vault_id", "workspace_id"] + ) nullable_fields = set(["description", "instructions"]) serialized = handler(self) m = {} diff --git a/src/openrouter/components/internchatassistantmessage.py b/src/openrouter/components/internchatassistantmessage.py index dcace16b..208a06d2 100644 --- a/src/openrouter/components/internchatassistantmessage.py +++ b/src/openrouter/components/internchatassistantmessage.py @@ -9,7 +9,13 @@ InternChatMessageContent, InternChatMessageContentTypedDict, ) -from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from openrouter.types import ( + BaseModel, + Nullable, + OptionalNullable, + UNSET, + UNSET_SENTINEL, +) from pydantic import model_serializer from typing import List, Literal, Optional from typing_extensions import NotRequired, TypedDict @@ -21,25 +27,25 @@ class InternChatAssistantMessageTypedDict(TypedDict): r"""An assistant message from an earlier response. When answering an interaction, echo the streamed `tool_calls` here before the `tool` message.""" - content: Nullable[InternChatMessageContentTypedDict] - r"""Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history.""" role: InternChatAssistantMessageRole + content: NotRequired[Nullable[InternChatMessageContentTypedDict]] + r"""Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history.""" tool_calls: NotRequired[List[InternChatEchoedToolCallTypedDict]] class InternChatAssistantMessage(BaseModel): r"""An assistant message from an earlier response. When answering an interaction, echo the streamed `tool_calls` here before the `tool` message.""" - content: Nullable[InternChatMessageContent] - r"""Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history.""" - role: InternChatAssistantMessageRole + content: OptionalNullable[InternChatMessageContent] = UNSET + r"""Message text as a string or a list of text parts. Assistant history may carry null. Only the last message is read; earlier messages are accepted so ordinary clients can resend history.""" + tool_calls: Optional[List[InternChatEchoedToolCall]] = None @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["tool_calls"]) + optional_fields = set(["content", "tool_calls"]) nullable_fields = set(["content"]) serialized = handler(self) m = {} diff --git a/src/openrouter/interns.py b/src/openrouter/interns.py index 4e354fee..d1dac0bf 100644 --- a/src/openrouter/interns.py +++ b/src/openrouter/interns.py @@ -284,7 +284,6 @@ def create_intern( self, *, name: str, - workspace_id: str, http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, @@ -293,6 +292,7 @@ def create_intern( instructions: OptionalNullable[str] = UNSET, provision: Optional[bool] = False, vault_id: Optional[str] = None, + workspace_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -305,7 +305,6 @@ def create_intern( If set, this operation will use `api_key` from the global security. :param name: Intern name, unique per creator within the workspace. - :param workspace_id: Workspace that will own the intern. It must match the API key workspace. :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. @@ -318,6 +317,7 @@ def create_intern( :param instructions: Standing instructions the intern boots with, or null. :param provision: Start provisioning during this create operation. Defaults to false. :param vault_id: Vault owned by another intern in this workspace to attach as a borrowed vault. + :param workspace_id: Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace. :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 @@ -441,7 +441,6 @@ async def create_intern_async( self, *, name: str, - workspace_id: str, http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, @@ -450,6 +449,7 @@ async def create_intern_async( instructions: OptionalNullable[str] = UNSET, provision: Optional[bool] = False, vault_id: Optional[str] = None, + workspace_id: Optional[str] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -462,7 +462,6 @@ async def create_intern_async( If set, this operation will use `api_key` from the global security. :param name: Intern name, unique per creator within the workspace. - :param workspace_id: Workspace that will own the intern. It must match the API key workspace. :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. @@ -475,6 +474,7 @@ async def create_intern_async( :param instructions: Standing instructions the intern boots with, or null. :param provision: Start provisioning during this create operation. Defaults to false. :param vault_id: Vault owned by another intern in this workspace to attach as a borrowed vault. + :param workspace_id: Workspace that will own the intern. Defaults to the workspace the API key resolves to. When given, it must match the API key workspace. :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 @@ -1946,7 +1946,7 @@ def chat( To answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline. - Closing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The disconnect is noticed when the intern next writes to the stream, which during a silent tool run can take more than one 30 second heartbeat interval. + Closing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent. A run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: \"error\"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event. @@ -2137,7 +2137,7 @@ async def chat_async( To answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline. - Closing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The disconnect is noticed when the intern next writes to the stream, which during a silent tool run can take more than one 30 second heartbeat interval. + Closing the connection after the `[DONE]` that follows `finish_reason: \"tool_calls\"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent. A run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: \"error\"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event. diff --git a/uv.lock b/uv.lock index fab0a96a..720589a0 100644 --- a/uv.lock +++ b/uv.lock @@ -213,7 +213,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.2.2" +version = "1.2.3" source = { editable = "." } dependencies = [ { name = "httpcore" }, From 140362d49c1ed0423f3000b1acf1d38ebc3c1914 Mon Sep 17 00:00:00 2001 From: "speakeasy-github[bot]" <128539517+speakeasy-github[bot]@users.noreply.github.com> Date: Sat, 19 Sep 2026 17:31:34 +0000 Subject: [PATCH 2/2] empty commit to trigger [run-tests] workflow