From 2988b5e385d9f9a7f956e3be557114a07c4499ec Mon Sep 17 00:00:00 2001 From: David Alberto Adler Date: Sun, 7 Sep 2025 21:48:26 +0100 Subject: [PATCH] fix: examples, enums and regenerate (#2) --- .gitignore | 1 + .speakeasy/OAS_files/overlay.yaml | 90 - .../speakeasy-modifications-overlay.yaml | 28 - .speakeasy/gen.lock | 23 +- .speakeasy/gen.yaml | 9 +- .speakeasy/in.openapi.yaml | 1612 +++++++++++++++++ ...ons-openapi.yaml => original.openapi.yaml} | 2 +- .speakeasy/out.openapi.yaml | 47 +- .speakeasy/workflow.lock | 9 +- .speakeasy/workflow.yaml | 5 +- README-PYPI.md | 66 +- README.md | 66 +- USAGE.md | 12 +- docs/models/chatcompletioncreateparams.md | 2 +- .../chatstreamcompletioncreateparams.md | 2 +- docs/models/error.md | 12 +- docs/models/security.md | 2 +- docs/sdks/chat/README.md | 16 +- examples/.env | 1 - examples/asyncChatCompletion.py | 24 + examples/asyncSseChatCompletion.py | 32 + examples/chatCompletion.py | 7 +- examples/sseChatCompletion.py | 24 +- pyproject.toml | 3 +- src/openrouter/_version.py | 6 +- src/openrouter/basesdk.py | 12 +- src/openrouter/chat.py | 26 +- src/openrouter/errors/__init__.py | 18 +- src/openrouter/models/__init__.py | 15 +- src/openrouter/models/chatcompletion.py | 6 +- .../chatcompletionassistantmessageparam.py | 7 +- src/openrouter/models/chatcompletionchoice.py | 14 +- src/openrouter/models/chatcompletionchunk.py | 6 +- .../models/chatcompletionchunkchoice.py | 11 +- .../models/chatcompletionchunkchoicedelta.py | 9 +- .../chatcompletionchunkchoicedeltatoolcall.py | 9 +- .../models/chatcompletioncontentpartaudio.py | 20 +- .../models/chatcompletioncontentpartimage.py | 15 +- .../models/chatcompletioncontentparttext.py | 5 +- .../models/chatcompletioncreateparams.py | 585 +++--- src/openrouter/models/chatcompletionerror.py | 25 +- .../models/chatcompletionmessage.py | 6 +- .../models/chatcompletionmessagetoolcall.py | 5 +- .../models/chatcompletionnamedtoolchoice.py | 5 +- .../chatcompletionsystemmessageparam.py | 7 +- src/openrouter/models/chatcompletiontool.py | 6 +- .../models/chatcompletiontoolchoiceoption.py | 15 +- .../models/chatcompletiontoolmessageparam.py | 7 +- .../models/chatcompletionusermessageparam.py | 7 +- .../chatstreamcompletioncreateparams.py | 587 +++--- src/openrouter/models/fileannotationdetail.py | 13 +- .../models/reasoningdetailencrypted.py | 16 +- .../models/reasoningdetailsummary.py | 16 +- src/openrouter/models/reasoningdetailtext.py | 16 +- src/openrouter/models/security.py | 4 +- .../models/urlcitationannotationdetail.py | 6 +- src/openrouter/sdk.py | 27 +- src/openrouter/utils/__init__.py | 18 +- src/openrouter/utils/eventstreaming.py | 10 + src/openrouter/utils/security.py | 4 +- uv.lock | 2 +- 61 files changed, 2568 insertions(+), 1093 deletions(-) delete mode 100644 .speakeasy/OAS_files/overlay.yaml delete mode 100644 .speakeasy/OAS_files/speakeasy-modifications-overlay.yaml create mode 100644 .speakeasy/in.openapi.yaml rename .speakeasy/{OAS_files/chat-completions-openapi.yaml => original.openapi.yaml} (99%) delete mode 100644 examples/.env create mode 100644 examples/asyncChatCompletion.py create mode 100644 examples/asyncSseChatCompletion.py diff --git a/.gitignore b/.gitignore index aedee07..1efdd93 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ pyrightconfig.json **/.speakeasy/temp/ **/.speakeasy/logs/ .speakeasy/reports +.env diff --git a/.speakeasy/OAS_files/overlay.yaml b/.speakeasy/OAS_files/overlay.yaml deleted file mode 100644 index dce0ade..0000000 --- a/.speakeasy/OAS_files/overlay.yaml +++ /dev/null @@ -1,90 +0,0 @@ -overlay: 1.0.0 -x-speakeasy-jsonpath: rfc9535 -info: - title: Overlay chat-completions-openapi.yaml => openapi.yaml - version: 0.0.0 -actions: - - target: $["components"]["schemas"]["ChatCompletion"]["properties"]["system_fingerprint"] - update: - type: string - nullable: true - description: System fingerprint - - target: $["components"]["schemas"]["ChatCompletionChunk"]["properties"]["system_fingerprint"] - update: - type: string - nullable: true - - target: $["components"]["schemas"] - update: - ChatStreamCompletionCreateParams: - allOf: - - $ref: "#/components/schemas/ChatCompletionCreateParams" - - type: object - properties: - stream: - type: boolean - enum: - - true - default: true - description: Enable streaming response - - target: $["paths"]["/chat/completions"]["post"]["responses"]["200"]["content"]["application/json"]["schema"] - update: - $ref: '#/components/schemas/ChatCompletion' - - target: $["paths"]["/chat/completions"]["post"]["responses"]["200"]["content"]["application/json"]["schema"] - update: - description: Non-streaming response when stream=false - - target: $["paths"]["/chat/completions"]["post"]["responses"]["200"]["content"]["application/json"]["schema"]["oneOf"] - remove: true - - target: $["paths"]["/chat/completions"]["post"]["responses"]["200"]["content"]["text/event-stream"] - remove: true - - target: $["paths"] - update: - /chat/completions#stream: - post: - operationId: streamChatCompletion - summary: Create a chat completion - description: Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes. - tags: - - Chat - requestBody: - description: Chat completion request parameters - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/ChatStreamCompletionCreateParams' - responses: - '200': - description: Successful chat completion response - content: - text/event-stream: - x-speakeasy-sse-sentinel: '[DONE]' - schema: - type: object - required: [data] - properties: - data: - $ref: '#/components/schemas/ChatCompletionChunk' - '400': - description: Bad request - invalid parameters - content: - application/json: - schema: - $ref: '#/components/schemas/ChatCompletionError' - '401': - description: Unauthorized - invalid API key - content: - application/json: - schema: - $ref: '#/components/schemas/ChatCompletionError' - '429': - description: Too many requests - rate limit exceeded - content: - application/json: - schema: - $ref: '#/components/schemas/ChatCompletionError' - '500': - description: Internal server error - content: - application/json: - schema: - $ref: '#/components/schemas/ChatCompletionError' diff --git a/.speakeasy/OAS_files/speakeasy-modifications-overlay.yaml b/.speakeasy/OAS_files/speakeasy-modifications-overlay.yaml deleted file mode 100644 index 48c33da..0000000 --- a/.speakeasy/OAS_files/speakeasy-modifications-overlay.yaml +++ /dev/null @@ -1,28 +0,0 @@ -overlay: 1.0.0 -x-speakeasy-jsonpath: rfc9535 -info: - title: Speakeasy Modifications - version: 0.0.2 - x-speakeasy-metadata: - after: "" - before: "" - type: speakeasy-modifications -actions: - - target: $["paths"]["/chat/completions"]["post"] - update: - x-speakeasy-name-override: complete - x-speakeasy-metadata: - after: sdk.chat.complete() - before: sdk.Chat.createChatCompletion() - created_at: 1755805257797 - reviewed_at: 1755805262583 - type: method-name - - target: $["paths"]["/chat/completions#stream"]["post"] - update: - x-speakeasy-name-override: completeStream - x-speakeasy-metadata: - after: sdk.chat.completeStream() - before: sdk.Chat.streamChatCompletion() - created_at: 1755805257798 - reviewed_at: 1755805262583 - type: method-name diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 485c0e9..d68657d 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,19 +1,20 @@ lockVersion: 2.0.0 id: 232c6d4f-b0fd-4172-8f1b-e2421566e9b4 management: - docChecksum: 003bbbc167e4db8bd3f147793a6648e1 + docChecksum: 98b4f227e767bb91333b3b3469d93fa5 docVersion: 1.0.0 - speakeasyVersion: 1.606.2 - generationVersion: 2.687.1 - releaseVersion: 0.1.3 - configChecksum: d572a56cfb69d7061ad0319f157ff5d8 + speakeasyVersion: 1.611.1 + generationVersion: 2.694.1 + releaseVersion: 0.5.2 + configChecksum: 4619605fbeb6f4488feb5336aa62bab6 repoURL: https://github.com/speakeasy-sdks/openrouter-python-sdk.git installationURL: https://github.com/speakeasy-sdks/openrouter-python-sdk.git features: python: additionalDependencies: 1.0.0 constsAndDefaults: 1.0.5 - core: 5.19.9 + core: 5.20.3 + customCodeRegions: 0.1.1 defaultEnabledRetries: 0.2.0 devContainers: 3.0.0 enumUnions: 0.1.0 @@ -29,7 +30,7 @@ features: responseFormat: 1.0.1 retries: 3.0.2 sdkHooks: 1.1.0 - serverEvents: 1.0.7 + serverEvents: 1.0.8 serverEventsSentinels: 0.1.0 unions: 3.0.4 generatedFiles: @@ -308,16 +309,16 @@ examples: "200": application/json: {"id": "", "choices": [], "created": 6977.95, "model": "El Camino", "object": "chat.completion"} "400": - application/json: {"error": {"code": "", "message": "", "param": "", "type": ""}} + application/json: {"error": {"code": null, "message": ""}} "500": - application/json: {"error": {"code": "", "message": "", "param": "", "type": ""}} + application/json: {"error": {"code": null, "message": ""}} streamChatCompletion: speakeasy-default-stream-chat-completion: requestBody: application/json: {"messages": [{"role": "user", "content": "Hello, how are you?"}], "stream": true, "temperature": 1, "top_p": 1} responses: "400": - application/json: {"error": {"code": "", "message": "", "param": "", "type": ""}} + application/json: {"error": {"code": null, "message": ""}} "500": - application/json: {"error": {"code": "", "message": "", "param": "", "type": ""}} + application/json: {"error": {"code": null, "message": ""}} examplesVersion: 1.0.2 diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index dbc0051..f8e576d 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -25,18 +25,21 @@ generation: generateNewTests: true skipResponseBodyAssertions: false python: - version: 0.1.3 + version: 0.5.2 additionalDependencies: dev: {} main: {} + allowedRedefinedBuiltins: + - id + - object authors: - Speakeasy baseErrorName: OpenRouterError clientServerStatusCodesAsErrors: true defaultErrorName: OpenRouterDefaultError description: Python Client SDK Generated by Speakeasy. - enableCustomCodeRegions: false - enumFormat: enum + enableCustomCodeRegions: true + enumFormat: union envVarPrefix: OPENROUTER fixFlags: responseRequiredSep2024: true diff --git a/.speakeasy/in.openapi.yaml b/.speakeasy/in.openapi.yaml new file mode 100644 index 0000000..6fb845b --- /dev/null +++ b/.speakeasy/in.openapi.yaml @@ -0,0 +1,1612 @@ +openapi: 3.0.0 +info: + title: OpenRouter Chat Completions API + version: 1.0.0 + description: OpenAI-compatible Chat Completions API with additional OpenRouter features + contact: + name: OpenRouter Support + url: https://openrouter.ai/docs + email: support@openrouter.ai + license: + name: MIT + url: https://opensource.org/licenses/MIT +servers: + - url: https://{provider_url}/api/v1 + variables: + provider_url: + default: openrouter.ai + description: Production server +security: + - ApiKey: [] +tags: + - name: Chat + description: Chat completion operations +externalDocs: + description: OpenRouter Documentation + url: https://openrouter.ai/docs +components: + securitySchemes: + ApiKey: + type: http + scheme: bearer + description: API key as bearer token in Authorization header + schemas: + ChatCompletionChunkWrapper: + type: object + required: [data] + properties: + data: + $ref: '#/components/schemas/ChatCompletionChunk' + ChatCompletionMessageToolCall: + type: object + properties: + id: + type: string + description: Tool call identifier + type: + type: string + enum: + - function + function: + type: object + properties: + name: + type: string + description: Function name to call + arguments: + type: string + description: Function arguments as JSON string + required: + - name + - arguments + required: + - id + - type + - function + description: Tool call made by the assistant + ReasoningDetailSummary: + type: object + properties: + type: + type: string + enum: + - reasoning.summary + summary: + type: string + id: + type: string + nullable: true + format: + type: string + nullable: true + enum: + - unknown + - openai-responses-v1 + - anthropic-claude-v1 + default: anthropic-claude-v1 + index: + type: number + required: + - type + - summary + description: Reasoning summary detail + ReasoningDetailEncrypted: + type: object + properties: + type: + type: string + enum: + - reasoning.encrypted + data: + type: string + id: + type: string + nullable: true + format: + type: string + nullable: true + enum: + - unknown + - openai-responses-v1 + - anthropic-claude-v1 + default: anthropic-claude-v1 + index: + type: number + required: + - type + - data + description: Encrypted reasoning detail + ReasoningDetailText: + type: object + properties: + type: + type: string + enum: + - reasoning.text + text: + type: string + nullable: true + signature: + type: string + nullable: true + id: + type: string + nullable: true + format: + type: string + nullable: true + enum: + - unknown + - openai-responses-v1 + - anthropic-claude-v1 + default: anthropic-claude-v1 + index: + type: number + required: + - type + description: Text reasoning detail + ReasoningDetail: + oneOf: + - $ref: '#/components/schemas/ReasoningDetailSummary' + - $ref: '#/components/schemas/ReasoningDetailEncrypted' + - $ref: '#/components/schemas/ReasoningDetailText' + discriminator: + propertyName: type + mapping: + reasoning.summary: '#/components/schemas/ReasoningDetailSummary' + reasoning.encrypted: '#/components/schemas/ReasoningDetailEncrypted' + reasoning.text: '#/components/schemas/ReasoningDetailText' + description: Reasoning detail information + FileAnnotationDetail: + type: object + properties: + type: + type: string + enum: + - file + file: + type: object + properties: + hash: + type: string + name: + type: string + content: + type: array + items: + anyOf: + - type: object + properties: + type: + type: string + enum: + - text + text: + type: string + required: + - type + - text + - type: object + properties: + type: + type: string + enum: + - image_url + image_url: + type: object + properties: + url: + type: string + required: + - url + required: + - type + - image_url + required: + - hash + - content + required: + - type + - file + description: File annotation with content + URLCitationAnnotationDetail: + type: object + properties: + type: + type: string + enum: + - url_citation + url_citation: + type: object + properties: + end_index: + type: number + start_index: + type: number + title: + type: string + url: + type: string + content: + type: string + required: + - end_index + - start_index + - title + - url + required: + - type + - url_citation + description: URL citation annotation + AnnotationDetail: + oneOf: + - $ref: '#/components/schemas/FileAnnotationDetail' + - $ref: '#/components/schemas/URLCitationAnnotationDetail' + discriminator: + propertyName: type + mapping: + file: '#/components/schemas/FileAnnotationDetail' + url_citation: '#/components/schemas/URLCitationAnnotationDetail' + description: Annotation information + ChatCompletionMessage: + type: object + properties: + role: + type: string + enum: + - assistant + content: + type: string + nullable: true + description: Message content + reasoning: + type: string + nullable: true + description: Reasoning output + refusal: + type: string + nullable: true + description: Refusal message if content was refused + tool_calls: + type: array + items: + $ref: '#/components/schemas/ChatCompletionMessageToolCall' + description: Tool calls made by the assistant + reasoning_details: + type: array + items: + $ref: '#/components/schemas/ReasoningDetail' + description: Reasoning details delta to send reasoning details back to upstream + annotations: + type: array + items: + $ref: '#/components/schemas/AnnotationDetail' + description: Annotations delta to send annotations back to upstream + required: + - role + - content + - refusal + description: Assistant message in completion response + ChatCompletionTokenLogprob: + type: object + properties: + token: + type: string + description: The token + logprob: + type: number + description: Log probability of the token + bytes: + type: array + nullable: true + items: + type: number + description: UTF-8 bytes of the token + top_logprobs: + type: array + items: + type: object + properties: + token: + type: string + logprob: + type: number + bytes: + type: array + nullable: true + items: + type: number + required: + - token + - logprob + - bytes + description: Top alternative tokens with probabilities + required: + - token + - logprob + - bytes + - top_logprobs + description: Token log probability information + ChatCompletionTokenLogprobs: + type: object + nullable: true + properties: + content: + type: array + nullable: true + items: + $ref: '#/components/schemas/ChatCompletionTokenLogprob' + description: Log probabilities for content tokens + refusal: + type: array + nullable: true + items: + $ref: '#/components/schemas/ChatCompletionTokenLogprob' + description: Log probabilities for refusal tokens + required: + - content + - refusal + description: Log probabilities for the completion + ChatCompletionChoice: + type: object + properties: + finish_reason: + type: string + nullable: true + enum: + - tool_calls + - stop + - length + - content_filter + - error + description: Reason the completion finished + index: + type: number + description: Choice index + message: + $ref: '#/components/schemas/ChatCompletionMessage' + logprobs: + $ref: '#/components/schemas/ChatCompletionTokenLogprobs' + required: + - finish_reason + - index + - message + description: Chat completion choice + CompletionUsage: + type: object + properties: + completion_tokens: + type: number + description: Number of tokens in the completion + prompt_tokens: + type: number + description: Number of tokens in the prompt + total_tokens: + type: number + description: Total number of tokens + completion_tokens_details: + type: object + properties: + reasoning_tokens: + type: number + description: Tokens used for reasoning + audio_tokens: + type: number + description: Tokens used for audio output + accepted_prediction_tokens: + type: number + description: Accepted prediction tokens + rejected_prediction_tokens: + type: number + description: Rejected prediction tokens + description: Detailed completion token usage + prompt_tokens_details: + type: object + properties: + cached_tokens: + type: number + description: Cached prompt tokens + audio_tokens: + type: number + description: Audio input tokens + description: Detailed prompt token usage + required: + - completion_tokens + - prompt_tokens + - total_tokens + description: Token usage statistics + ChatCompletion: + type: object + properties: + id: + type: string + description: Unique completion identifier + choices: + type: array + items: + $ref: '#/components/schemas/ChatCompletionChoice' + description: List of completion choices + created: + type: number + description: Unix timestamp of creation + model: + type: string + description: Model used for completion + object: + type: string + enum: + - chat.completion + system_fingerprint: + type: string + description: System fingerprint + nullable: true + usage: + $ref: '#/components/schemas/CompletionUsage' + required: + - id + - choices + - created + - model + - object + description: Chat completion response + ChatCompletionError: + type: object + properties: + error: + type: object + properties: + code: + type: number + nullable: true + message: + type: string + param: + type: string + nullable: true + type: + type: string + required: + - code + - message + description: Error object structure + required: + - error + description: Chat completion error response + ChatCompletionChunkChoiceDeltaToolCall: + type: object + properties: + index: + type: number + description: Tool call index in the array + id: + type: string + description: Tool call identifier + type: + type: string + enum: + - function + description: Tool call type + function: + type: object + properties: + name: + type: string + description: Function name + arguments: + type: string + description: Function arguments as JSON string + description: Function call details + required: + - index + description: Tool call delta for streaming responses + ChatCompletionChunkChoiceDelta: + type: object + properties: + role: + type: string + enum: + - assistant + description: The role of the message author + content: + type: string + nullable: true + description: Message content delta + reasoning: + type: string + nullable: true + description: Reasoning content delta + refusal: + type: string + nullable: true + description: Refusal message delta + tool_calls: + type: array + items: + $ref: '#/components/schemas/ChatCompletionChunkChoiceDeltaToolCall' + description: Tool calls delta + reasoning_details: + type: array + items: + $ref: '#/components/schemas/ReasoningDetail' + description: Reasoning details delta to send reasoning details back to upstream + annotations: + type: array + items: + $ref: '#/components/schemas/AnnotationDetail' + description: Annotations delta to send annotations back to upstream + description: Delta changes in streaming response + ChatCompletionChunkChoice: + type: object + properties: + delta: + $ref: '#/components/schemas/ChatCompletionChunkChoiceDelta' + finish_reason: + type: string + nullable: true + enum: + - tool_calls + - stop + - length + - content_filter + - error + index: + type: number + logprobs: + $ref: '#/components/schemas/ChatCompletionTokenLogprobs' + required: + - delta + - finish_reason + - index + description: Streaming completion choice chunk + ChatCompletionChunk: + type: object + properties: + id: + type: string + choices: + type: array + items: + $ref: '#/components/schemas/ChatCompletionChunkChoice' + created: + type: number + model: + type: string + object: + type: string + enum: + - chat.completion.chunk + system_fingerprint: + type: string + nullable: true + usage: + $ref: '#/components/schemas/CompletionUsage' + required: + - id + - choices + - created + - model + - object + description: Streaming chat completion chunk + ChatCompletionRole: + type: string + enum: + - system + - user + - assistant + - tool + - developer + description: The role of the message author + ChatCompletionContentPartText: + type: object + properties: + type: + type: string + enum: + - text + text: + type: string + required: + - type + - text + description: Text content part + ChatCompletionContentPartImage: + type: object + properties: + type: + type: string + enum: + - image_url + image_url: + type: object + properties: + url: + type: string + description: 'URL of the image (data: URLs supported)' + detail: + type: string + enum: + - auto + - low + - high + description: Image detail level for vision models + required: + - url + required: + - type + - image_url + description: Image content part for vision models + ChatCompletionContentPartAudio: + type: object + properties: + type: + type: string + enum: + - input_audio + input_audio: + type: object + properties: + data: + type: string + description: Base64 encoded audio data + format: + type: string + enum: + - wav + - mp3 + - flac + - m4a + - ogg + - pcm16 + - pcm24 + description: Audio format + required: + - data + - format + required: + - type + - input_audio + description: Audio input content part + ChatCompletionContentPart: + oneOf: + - $ref: '#/components/schemas/ChatCompletionContentPartText' + - $ref: '#/components/schemas/ChatCompletionContentPartImage' + - $ref: '#/components/schemas/ChatCompletionContentPartAudio' + discriminator: + propertyName: type + mapping: + text: '#/components/schemas/ChatCompletionContentPartText' + image_url: '#/components/schemas/ChatCompletionContentPartImage' + input_audio: '#/components/schemas/ChatCompletionContentPartAudio' + description: Content part for chat completion messages + ChatCompletionSystemMessageParam: + type: object + properties: + role: + type: string + enum: + - system + content: + anyOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/ChatCompletionContentPartText' + description: System message content + name: + type: string + description: Optional name for the system message + required: + - role + - content + description: System message for setting behavior + ChatCompletionUserMessageParam: + type: object + properties: + role: + type: string + enum: + - user + content: + anyOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/ChatCompletionContentPart' + description: User message content + name: + type: string + description: Optional name for the user + required: + - role + - content + description: User message + ChatCompletionAssistantMessageParam: + type: object + properties: + role: + type: string + enum: + - assistant + content: + anyOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/ChatCompletionContentPart' + - nullable: true + description: Assistant message content + name: + type: string + description: Optional name for the assistant + tool_calls: + type: array + items: + $ref: '#/components/schemas/ChatCompletionMessageToolCall' + description: Tool calls made by the assistant + refusal: + type: string + nullable: true + description: Refusal message if content was refused + required: + - role + description: Assistant message with tool calls and audio support + ChatCompletionToolMessageParam: + type: object + properties: + role: + type: string + enum: + - tool + content: + anyOf: + - type: string + - type: array + items: + $ref: '#/components/schemas/ChatCompletionContentPart' + description: Tool response content + tool_call_id: + type: string + description: ID of the tool call this message responds to + required: + - role + - content + - tool_call_id + description: Tool response message + ChatCompletionMessageParam: + oneOf: + - $ref: '#/components/schemas/ChatCompletionSystemMessageParam' + - $ref: '#/components/schemas/ChatCompletionUserMessageParam' + - $ref: '#/components/schemas/ChatCompletionAssistantMessageParam' + - $ref: '#/components/schemas/ChatCompletionToolMessageParam' + discriminator: + propertyName: role + mapping: + system: '#/components/schemas/ChatCompletionSystemMessageParam' + user: '#/components/schemas/ChatCompletionUserMessageParam' + assistant: '#/components/schemas/ChatCompletionAssistantMessageParam' + tool: '#/components/schemas/ChatCompletionToolMessageParam' + description: Chat completion message with role-based discrimination + ChatCompletionTool: + type: object + properties: + type: + type: string + enum: + - function + function: + type: object + properties: + name: + type: string + maxLength: 64 + description: Function name (a-z, A-Z, 0-9, underscores, dashes, max 64 chars) + description: + type: string + description: Function description for the model + parameters: + type: object + properties: {} + description: Function parameters as JSON Schema object + strict: + type: boolean + nullable: true + description: Enable strict schema adherence + required: + - name + description: Function definition for tool calling + required: + - type + - function + description: Tool definition for function calling + ChatCompletionNamedToolChoice: + type: object + properties: + type: + type: string + enum: + - function + function: + type: object + properties: + name: + type: string + description: Function name to call + required: + - name + required: + - type + - function + description: Named tool choice for specific function + ChatCompletionToolChoiceOption: + anyOf: + - type: string + enum: + - none + - type: string + enum: + - auto + - type: string + enum: + - required + - $ref: '#/components/schemas/ChatCompletionNamedToolChoice' + description: Tool choice configuration + ChatCompletionStreamOptions: + type: object + properties: + include_usage: + type: boolean + description: Include usage information in streaming response + description: Streaming configuration options + ResponseFormatJsonSchemaSchema: + type: object + properties: {} + description: The schema for the response format, described as a JSON Schema object + ChatCompletionCreateParams: + type: object + properties: + messages: + type: array + items: + $ref: '#/components/schemas/ChatCompletionMessageParam' + minItems: 1 + description: List of messages for the conversation + example: + - role: user + content: Hello, how are you? + model: + type: string + description: Model to use for completion + frequency_penalty: + type: number + nullable: true + minimum: -2 + maximum: 2 + description: Frequency penalty (-2.0 to 2.0) + logit_bias: + type: object + nullable: true + additionalProperties: + type: number + description: Token logit bias adjustments + logprobs: + type: boolean + nullable: true + description: Return log probabilities + top_logprobs: + type: number + nullable: true + minimum: 0 + maximum: 20 + description: Number of top log probabilities to return (0-20) + max_completion_tokens: + type: number + nullable: true + minimum: 1 + description: Maximum tokens in completion + max_tokens: + type: number + nullable: true + minimum: 1 + description: Maximum tokens (deprecated, use max_completion_tokens) + metadata: + type: object + additionalProperties: + type: string + description: Key-value pairs for additional object information (max 16 pairs, 64 char keys, 512 char values) + presence_penalty: + type: number + nullable: true + minimum: -2 + maximum: 2 + description: Presence penalty (-2.0 to 2.0) + reasoning: + type: object + nullable: true + properties: + enabled: + type: boolean + description: Enables reasoning with default settings. Only work for some models. + effort: + type: string + nullable: true + enum: + - high + - medium + - low + - minimal + description: OpenAI-style reasoning effort setting + max_tokens: + type: number + nullable: true + description: non-OpenAI-style reasoning effort setting + exclude: + type: boolean + default: false + description: Reasoning configuration + response_format: + oneOf: + - type: object + properties: + type: + type: string + enum: + - text + required: + - type + description: Default text response format + - type: object + properties: + type: + type: string + enum: + - json_object + required: + - type + description: JSON object response format + - type: object + properties: + type: + type: string + enum: + - json_schema + json_schema: + type: object + properties: + name: + type: string + maxLength: 64 + description: Schema name (a-z, A-Z, 0-9, underscores, dashes, max 64 chars) + description: + type: string + description: Schema description for the model + schema: + $ref: '#/components/schemas/ResponseFormatJsonSchemaSchema' + strict: + type: boolean + nullable: true + description: Enable strict schema adherence + required: + - name + required: + - type + - json_schema + description: JSON Schema response format for structured outputs + - type: object + properties: + type: + type: string + enum: + - grammar + grammar: + type: string + description: Custom grammar for text generation + required: + - type + - grammar + description: Custom grammar response format + - type: object + properties: + type: + type: string + enum: + - python + required: + - type + description: Python code response format + description: Response format configuration + seed: + type: integer + nullable: true + description: Random seed for deterministic outputs + stop: + anyOf: + - type: string + - type: array + items: + type: string + maxItems: 4 + - nullable: true + description: Stop sequences (up to 4) + stream: + type: boolean + nullable: true + default: false + description: Enable streaming response + stream_options: + allOf: + - $ref: '#/components/schemas/ChatCompletionStreamOptions' + - nullable: true + temperature: + type: number + nullable: true + minimum: 0 + maximum: 2 + default: 1 + description: Sampling temperature (0-2) + tool_choice: + $ref: '#/components/schemas/ChatCompletionToolChoiceOption' + tools: + type: array + items: + $ref: '#/components/schemas/ChatCompletionTool' + description: Available tools for function calling + top_p: + type: number + nullable: true + minimum: 0 + maximum: 1 + default: 1 + description: Nucleus sampling parameter (0-1) + user: + type: string + description: Unique user identifier + models: + # Needed to avoid conflict with the `models` directory + x-speakeasy-name-override: fallback_models + type: array + nullable: true + items: + type: string + description: Order of models to fallback to for this request + reasoning_effort: + type: string + nullable: true + enum: + - high + - medium + - low + - minimal + description: Reasoning effort + provider: + type: object + nullable: true + properties: + allow_fallbacks: + type: boolean + nullable: true + description: > + Whether to allow backup providers to serve requests + + - true: (default) when the primary provider (or your custom providers in "order") is unavailable, use + the next best provider. + + - false: use only the primary/custom provider, and return the upstream error if it's unavailable. + require_parameters: + type: boolean + nullable: true + description: >- + Whether to filter providers to only those that support the parameters you've provided. If this setting + is omitted or set to false, then providers will receive only the parameters they support, and ignore the + rest. + data_collection: + type: string + nullable: true + enum: + - deny + - allow + description: > + Data collection setting. If no available model provider meets the requirement, your request will return + an error. + + - allow: (default) allow providers which store user data non-transiently and may train on it + + - deny: use only providers which do not collect user data. + order: + type: array + nullable: true + items: + anyOf: + - type: string + enum: + - AnyScale + - Cent-ML + - HuggingFace + - Hyperbolic 2 + - Lepton + - Lynn 2 + - Lynn + - Mancer + - Modal + - OctoAI + - Recursal + - Reflection + - Replicate + - SambaNova 2 + - SF Compute + - Together 2 + - 01.AI + - AI21 + - AionLabs + - Alibaba + - Amazon Bedrock + - Anthropic + - AtlasCloud + - Atoma + - Avian + - Azure + - BaseTen + - Cerebras + - Chutes + - Cloudflare + - Cohere + - CrofAI + - Crusoe + - DeepInfra + - DeepSeek + - Enfer + - Featherless + - Fireworks + - Friendli + - GMICloud + - Google + - Google AI Studio + - Groq + - Hyperbolic + - Inception + - InferenceNet + - Infermatic + - Inflection + - InoCloud + - Kluster + - Lambda + - Liquid + - Mancer 2 + - Meta + - Minimax + - Mistral + - Moonshot AI + - Morph + - NCompass + - Nebius + - NextBit + - Nineteen + - Novita + - OpenAI + - OpenInference + - Parasail + - Perplexity + - Phala + - SambaNova + - Stealth + - Switchpoint + - Targon + - Together + - Ubicloud + - Venice + - WandB + - xAI + - Z.AI + - type: string + description: >- + An ordered list of provider slugs. The router will attempt to use the first provider in the subset of + this list that supports your requested model, and fall back to the next if it is unavailable. If no + providers are available, the request will fail with an error message. + only: + type: array + nullable: true + items: + anyOf: + - type: string + enum: + - AnyScale + - Cent-ML + - HuggingFace + - Hyperbolic 2 + - Lepton + - Lynn 2 + - Lynn + - Mancer + - Modal + - OctoAI + - Recursal + - Reflection + - Replicate + - SambaNova 2 + - SF Compute + - Together 2 + - 01.AI + - AI21 + - AionLabs + - Alibaba + - Amazon Bedrock + - Anthropic + - AtlasCloud + - Atoma + - Avian + - Azure + - BaseTen + - Cerebras + - Chutes + - Cloudflare + - Cohere + - CrofAI + - Crusoe + - DeepInfra + - DeepSeek + - Enfer + - Featherless + - Fireworks + - Friendli + - GMICloud + - Google + - Google AI Studio + - Groq + - Hyperbolic + - Inception + - InferenceNet + - Infermatic + - Inflection + - InoCloud + - Kluster + - Lambda + - Liquid + - Mancer 2 + - Meta + - Minimax + - Mistral + - Moonshot AI + - Morph + - NCompass + - Nebius + - NextBit + - Nineteen + - Novita + - OpenAI + - OpenInference + - Parasail + - Perplexity + - Phala + - SambaNova + - Stealth + - Switchpoint + - Targon + - Together + - Ubicloud + - Venice + - WandB + - xAI + - Z.AI + - type: string + description: >- + List of provider slugs to allow. If provided, this list is merged with your account-wide allowed + provider settings for this request. + ignore: + type: array + nullable: true + items: + anyOf: + - type: string + enum: + - AnyScale + - Cent-ML + - HuggingFace + - Hyperbolic 2 + - Lepton + - Lynn 2 + - Lynn + - Mancer + - Modal + - OctoAI + - Recursal + - Reflection + - Replicate + - SambaNova 2 + - SF Compute + - Together 2 + - 01.AI + - AI21 + - AionLabs + - Alibaba + - Amazon Bedrock + - Anthropic + - AtlasCloud + - Atoma + - Avian + - Azure + - BaseTen + - Cerebras + - Chutes + - Cloudflare + - Cohere + - CrofAI + - Crusoe + - DeepInfra + - DeepSeek + - Enfer + - Featherless + - Fireworks + - Friendli + - GMICloud + - Google + - Google AI Studio + - Groq + - Hyperbolic + - Inception + - InferenceNet + - Infermatic + - Inflection + - InoCloud + - Kluster + - Lambda + - Liquid + - Mancer 2 + - Meta + - Minimax + - Mistral + - Moonshot AI + - Morph + - NCompass + - Nebius + - NextBit + - Nineteen + - Novita + - OpenAI + - OpenInference + - Parasail + - Perplexity + - Phala + - SambaNova + - Stealth + - Switchpoint + - Targon + - Together + - Ubicloud + - Venice + - WandB + - xAI + - Z.AI + - type: string + description: >- + List of provider slugs to ignore. If provided, this list is merged with your account-wide ignored + provider settings for this request. + quantizations: + type: array + nullable: true + items: + type: string + enum: + - int4 + - int8 + - fp4 + - fp6 + - fp8 + - fp16 + - bf16 + - fp32 + - unknown + description: A list of quantization levels to filter the provider by. + sort: + type: string + nullable: true + enum: + - price + - throughput + - latency + description: >- + The sorting strategy to use for this request, if "order" is not specified. When set, no load balancing + is performed. + max_price: + type: object + properties: + prompt: + anyOf: + - type: number + - type: string + - {} + completion: + anyOf: + - type: number + - type: string + - {} + image: + anyOf: + - type: number + - type: string + - {} + audio: + anyOf: + - type: number + - type: string + - {} + request: + anyOf: + - type: number + - type: string + - {} + additionalProperties: false + description: >- + The object specifying the maximum price you want to pay for this request. USD price per million tokens, + for prompt and completion. + additionalProperties: false + description: When multiple model providers are available, optionally indicate your routing preference. + plugins: + type: array + items: + oneOf: + - type: object + properties: + id: + type: string + enum: + - moderation + required: + - id + - type: object + properties: + id: + type: string + enum: + - web + max_results: + type: number + search_prompt: + type: string + engine: + type: string + enum: + - native + - exa + required: + - id + - type: object + properties: + id: + type: string + enum: + - chain-of-thought + required: + - id + - type: object + properties: + id: + type: string + enum: + - file-parser + max_files: + type: number + pdf: + type: object + properties: + engine: + type: string + enum: + - mistral-ocr + - pdf-text + - native + required: + - id + description: Plugins you want to enable for this request, including their settings. + required: + - messages + description: Chat completion request parameters + ChatStreamCompletionCreateParams: + allOf: + - $ref: '#/components/schemas/ChatCompletionCreateParams' + - type: object + properties: + stream: + type: boolean + enum: + - true + default: true + description: Enable streaming response + parameters: {} +paths: + /chat/completions: + post: + operationId: createChatCompletion + summary: Create a chat completion + description: Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes. + tags: + - Chat + requestBody: + description: Chat completion request parameters + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionCreateParams' + responses: + '200': + description: Successful chat completion response + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletion' + description: Non-streaming response when stream=false + '400': + description: Bad request - invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '401': + description: Unauthorized - invalid API key + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '429': + description: Too many requests - rate limit exceeded + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + x-speakeasy-name-override: complete + /chat/completions#stream: + post: + operationId: streamChatCompletion + summary: Create a chat completion + description: Creates a model response for the given chat conversation. Supports both streaming and non-streaming modes. + tags: + - Chat + requestBody: + description: Chat completion request parameters + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/ChatStreamCompletionCreateParams' + responses: + '200': + description: Successful chat completion response + content: + text/event-stream: + x-speakeasy-sse-sentinel: '[DONE]' + schema: + type: object + required: [data] + properties: + data: + $ref: '#/components/schemas/ChatCompletionChunk' + '400': + description: Bad request - invalid parameters + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '401': + description: Unauthorized - invalid API key + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '429': + description: Too many requests - rate limit exceeded + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + '500': + description: Internal server error + content: + application/json: + schema: + $ref: '#/components/schemas/ChatCompletionError' + x-speakeasy-name-override: completeStream diff --git a/.speakeasy/OAS_files/chat-completions-openapi.yaml b/.speakeasy/original.openapi.yaml similarity index 99% rename from .speakeasy/OAS_files/chat-completions-openapi.yaml rename to .speakeasy/original.openapi.yaml index 0a1ca40..27c8858 100644 --- a/.speakeasy/OAS_files/chat-completions-openapi.yaml +++ b/.speakeasy/original.openapi.yaml @@ -1545,4 +1545,4 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/ChatCompletionError' + $ref: '#/components/schemas/ChatCompletionError' \ No newline at end of file diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 3f27afd..6fb845b 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -17,7 +17,7 @@ servers: default: openrouter.ai description: Production server security: - - BearerAuth: [] + - ApiKey: [] tags: - name: Chat description: Chat completion operations @@ -26,11 +26,17 @@ externalDocs: url: https://openrouter.ai/docs components: securitySchemes: - BearerAuth: + ApiKey: type: http scheme: bearer description: API key as bearer token in Authorization header schemas: + ChatCompletionChunkWrapper: + type: object + required: [data] + properties: + data: + $ref: '#/components/schemas/ChatCompletionChunk' ChatCompletionMessageToolCall: type: object properties: @@ -450,7 +456,7 @@ components: type: object properties: code: - type: string + type: number nullable: true message: type: string @@ -462,8 +468,6 @@ components: required: - code - message - - param - - type description: Error object structure required: - error @@ -1057,7 +1061,8 @@ components: type: string description: Unique user identifier models: - x-speakeasy-name-override: models_llm + # Needed to avoid conflict with the `models` directory + x-speakeasy-name-override: fallback_models type: array nullable: true items: @@ -1082,15 +1087,17 @@ components: description: > Whether to allow backup providers to serve requests - - true: (default) when the primary provider (or your custom providers in "order") is unavailable, use the next best provider. + - true: (default) when the primary provider (or your custom providers in "order") is unavailable, use + the next best provider. - false: use only the primary/custom provider, and return the upstream error if it's unavailable. - require_parameters: type: boolean nullable: true description: >- - Whether to filter providers to only those that support the parameters you've provided. If this setting is omitted or set to false, then providers will receive only the parameters they support, and ignore the rest. + Whether to filter providers to only those that support the parameters you've provided. If this setting + is omitted or set to false, then providers will receive only the parameters they support, and ignore the + rest. data_collection: type: string nullable: true @@ -1098,12 +1105,12 @@ components: - deny - allow description: > - Data collection setting. If no available model provider meets the requirement, your request will return an error. + Data collection setting. If no available model provider meets the requirement, your request will return + an error. - allow: (default) allow providers which store user data non-transiently and may train on it - deny: use only providers which do not collect user data. - order: type: array nullable: true @@ -1191,7 +1198,9 @@ components: - Z.AI - type: string description: >- - An ordered list of provider slugs. The router will attempt to use the first provider in the subset of this list that supports your requested model, and fall back to the next if it is unavailable. If no providers are available, the request will fail with an error message. + An ordered list of provider slugs. The router will attempt to use the first provider in the subset of + this list that supports your requested model, and fall back to the next if it is unavailable. If no + providers are available, the request will fail with an error message. only: type: array nullable: true @@ -1279,7 +1288,8 @@ components: - Z.AI - type: string description: >- - List of provider slugs to allow. If provided, this list is merged with your account-wide allowed provider settings for this request. + List of provider slugs to allow. If provided, this list is merged with your account-wide allowed + provider settings for this request. ignore: type: array nullable: true @@ -1367,7 +1377,8 @@ components: - Z.AI - type: string description: >- - List of provider slugs to ignore. If provided, this list is merged with your account-wide ignored provider settings for this request. + List of provider slugs to ignore. If provided, this list is merged with your account-wide ignored + provider settings for this request. quantizations: type: array nullable: true @@ -1392,7 +1403,8 @@ components: - throughput - latency description: >- - The sorting strategy to use for this request, if "order" is not specified. When set, no load balancing is performed. + The sorting strategy to use for this request, if "order" is not specified. When set, no load balancing + is performed. max_price: type: object properties: @@ -1423,7 +1435,8 @@ components: - {} additionalProperties: false description: >- - The object specifying the maximum price you want to pay for this request. USD price per million tokens, for prompt and completion. + The object specifying the maximum price you want to pay for this request. USD price per million tokens, + for prompt and completion. additionalProperties: false description: When multiple model providers are available, optionally indicate your routing preference. plugins: @@ -1488,7 +1501,7 @@ components: description: Chat completion request parameters ChatStreamCompletionCreateParams: allOf: - - $ref: "#/components/schemas/ChatCompletionCreateParams" + - $ref: '#/components/schemas/ChatCompletionCreateParams' - type: object properties: stream: diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 7d26e5f..2f80ddc 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,4 +1,4 @@ -speakeasyVersion: 1.606.2 +speakeasyVersion: 1.611.1 sources: OpenRouter Chat Completions API: sourceNamespace: open-router-chat-completions-api @@ -14,18 +14,13 @@ targets: sourceNamespace: open-router-chat-completions-api sourceRevisionDigest: sha256:30b19a8759608792fb4d27f6bf28d5982d7e2a8cf5b3faf34ba3507a62f9f106 sourceBlobDigest: sha256:454f1b880a0882a70f78eacccb2c33e3d9d19134a0738b0e21487984a7bf2e63 - codeSamplesNamespace: open-router-chat-completions-api-python-code-samples - codeSamplesRevisionDigest: sha256:9ce1951254983ff6edc533d67fea93254d9e0d124057ce826721a1449a9ba36c workflow: workflowVersion: 1.0.0 speakeasyVersion: latest sources: OpenRouter Chat Completions API: inputs: - - location: .speakeasy/OAS_files/chat-completions-openapi.yaml - overlays: - - location: .speakeasy/OAS_files/overlay.yaml - - location: .speakeasy/OAS_files/speakeasy-modifications-overlay.yaml + - location: .speakeasy/in.openapi.yaml output: .speakeasy/out.openapi.yaml registry: location: registry.speakeasyapi.dev/sheldon-vaughn-test/sandbox/open-router-chat-completions-api diff --git a/.speakeasy/workflow.yaml b/.speakeasy/workflow.yaml index 4069f05..b822d24 100644 --- a/.speakeasy/workflow.yaml +++ b/.speakeasy/workflow.yaml @@ -3,10 +3,7 @@ speakeasyVersion: latest sources: OpenRouter Chat Completions API: inputs: - - location: .speakeasy/OAS_files/chat-completions-openapi.yaml - overlays: - - location: .speakeasy/OAS_files/overlay.yaml - - location: .speakeasy/OAS_files/speakeasy-modifications-overlay.yaml + - location: .speakeasy/in.openapi.yaml output: .speakeasy/out.openapi.yaml registry: location: registry.speakeasyapi.dev/sheldon-vaughn-test/sandbox/open-router-chat-completions-api diff --git a/README-PYPI.md b/README-PYPI.md index 6a6a3c0..cdffb3c 100644 --- a/README-PYPI.md +++ b/README-PYPI.md @@ -125,17 +125,17 @@ Generally, the SDK will work well with most IDEs out of the box. However, when u ```python # Synchronous Example -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -150,18 +150,18 @@ The same SDK client can also be used to make asynchronous requests by importing ```python # Asynchronous Example import asyncio -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os async def main(): async with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = await open_router.chat.complete_async(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -180,23 +180,23 @@ asyncio.run(main()) This SDK supports the following security scheme globally: -| Name | Type | Scheme | Environment Variable | -| ------------- | ---- | ----------- | ------------------------ | -| `bearer_auth` | http | HTTP Bearer | `OPENROUTER_BEARER_AUTH` | +| Name | Type | Scheme | Environment Variable | +| --------- | ---- | ----------- | -------------------- | +| `api_key` | http | HTTP Bearer | `OPENROUTER_API_KEY` | -To authenticate with the API the `bearer_auth` parameter must be set when initializing the SDK client instance. For example: +To authenticate with the API the `api_key` parameter must be set when initializing the SDK client instance. For example: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -235,17 +235,17 @@ The stream is also a [Context Manager][context-manager] and can be used with the underlying connection when the context is exited. ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete_stream(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=True, temperature=1, top_p=1) @@ -269,18 +269,18 @@ Some of the endpoints in this SDK support retries. If you use the SDK without an To change the default retry strategy for a single API call, simply provide a `RetryConfig` object to the call: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter from openrouter.utils import BackoffStrategy, RetryConfig import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1, @@ -293,19 +293,19 @@ with OpenRouter( If you'd like to override the default retry strategy for all operations that support retries, you can use the `retry_config` optional parameter when initializing the SDK: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter from openrouter.utils import BackoffStrategy, RetryConfig import os with OpenRouter( retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -332,19 +332,19 @@ with OpenRouter( ### Example ```python -from openrouter import OpenRouter, errors, models +from openrouter import OpenRouter, errors import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = None try: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -401,18 +401,18 @@ The default server `https://{provider_url}/api/v1` contains variables and is set #### Example ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( provider_url="https://ruddy-guacamole.info/" - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -426,18 +426,18 @@ with OpenRouter( The default server can be overridden globally by passing a URL to the `server_url: str` optional parameter when initializing the SDK client instance. For example: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( server_url="https://openrouter.ai/api/v1", - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -542,7 +542,7 @@ import os def main(): with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: # Rest of application here... @@ -551,7 +551,7 @@ def main(): async def amain(): async with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: # Rest of application here... ``` diff --git a/README.md b/README.md index a005fd9..c092889 100644 --- a/README.md +++ b/README.md @@ -125,17 +125,17 @@ Generally, the SDK will work well with most IDEs out of the box. However, when u ```python # Synchronous Example -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -150,18 +150,18 @@ The same SDK client can also be used to make asynchronous requests by importing ```python # Asynchronous Example import asyncio -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os async def main(): async with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = await open_router.chat.complete_async(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -180,23 +180,23 @@ asyncio.run(main()) This SDK supports the following security scheme globally: -| Name | Type | Scheme | Environment Variable | -| ------------- | ---- | ----------- | ------------------------ | -| `bearer_auth` | http | HTTP Bearer | `OPENROUTER_BEARER_AUTH` | +| Name | Type | Scheme | Environment Variable | +| --------- | ---- | ----------- | -------------------- | +| `api_key` | http | HTTP Bearer | `OPENROUTER_API_KEY` | -To authenticate with the API the `bearer_auth` parameter must be set when initializing the SDK client instance. For example: +To authenticate with the API the `api_key` parameter must be set when initializing the SDK client instance. For example: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -235,17 +235,17 @@ The stream is also a [Context Manager][context-manager] and can be used with the underlying connection when the context is exited. ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete_stream(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=True, temperature=1, top_p=1) @@ -269,18 +269,18 @@ Some of the endpoints in this SDK support retries. If you use the SDK without an To change the default retry strategy for a single API call, simply provide a `RetryConfig` object to the call: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter from openrouter.utils import BackoffStrategy, RetryConfig import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1, @@ -293,19 +293,19 @@ with OpenRouter( If you'd like to override the default retry strategy for all operations that support retries, you can use the `retry_config` optional parameter when initializing the SDK: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter from openrouter.utils import BackoffStrategy, RetryConfig import os with OpenRouter( retry_config=RetryConfig("backoff", BackoffStrategy(1, 50, 1.1, 100), False), - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -332,19 +332,19 @@ with OpenRouter( ### Example ```python -from openrouter import OpenRouter, errors, models +from openrouter import OpenRouter, errors import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = None try: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -401,18 +401,18 @@ The default server `https://{provider_url}/api/v1` contains variables and is set #### Example ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( provider_url="https://ruddy-guacamole.info/" - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -426,18 +426,18 @@ with OpenRouter( The default server can be overridden globally by passing a URL to the `server_url: str` optional parameter when initializing the SDK client instance. For example: ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( server_url="https://openrouter.ai/api/v1", - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -542,7 +542,7 @@ import os def main(): with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: # Rest of application here... @@ -551,7 +551,7 @@ def main(): async def amain(): async with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: # Rest of application here... ``` diff --git a/USAGE.md b/USAGE.md index 4df956d..c79eaba 100644 --- a/USAGE.md +++ b/USAGE.md @@ -1,17 +1,17 @@ ```python # Synchronous Example -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -26,18 +26,18 @@ The same SDK client can also be used to make asynchronous requests by importing ```python # Asynchronous Example import asyncio -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os async def main(): async with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = await open_router.chat.complete_async(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) diff --git a/docs/models/chatcompletioncreateparams.md b/docs/models/chatcompletioncreateparams.md index e06608e..4ad0570 100644 --- a/docs/models/chatcompletioncreateparams.md +++ b/docs/models/chatcompletioncreateparams.md @@ -28,7 +28,7 @@ Chat completion request parameters | `tools` | List[[models.ChatCompletionTool](../models/chatcompletiontool.md)] | :heavy_minus_sign: | Available tools for function calling | | | `top_p` | *OptionalNullable[float]* | :heavy_minus_sign: | Nucleus sampling parameter (0-1) | | | `user` | *Optional[str]* | :heavy_minus_sign: | Unique user identifier | | -| `models_llm` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | +| `fallback_models` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | | `reasoning_effort` | [OptionalNullable[models.ChatCompletionCreateParamsReasoningEffort]](../models/chatcompletioncreateparamsreasoningeffort.md) | :heavy_minus_sign: | Reasoning effort | | | `provider` | [OptionalNullable[models.ChatCompletionCreateParamsProvider]](../models/chatcompletioncreateparamsprovider.md) | :heavy_minus_sign: | When multiple model providers are available, optionally indicate your routing preference. | | | `plugins` | List[[models.ChatCompletionCreateParamsPluginUnion](../models/chatcompletioncreateparamspluginunion.md)] | :heavy_minus_sign: | Plugins you want to enable for this request, including their settings. | | \ No newline at end of file diff --git a/docs/models/chatstreamcompletioncreateparams.md b/docs/models/chatstreamcompletioncreateparams.md index 951d638..a67bebf 100644 --- a/docs/models/chatstreamcompletioncreateparams.md +++ b/docs/models/chatstreamcompletioncreateparams.md @@ -28,7 +28,7 @@ Chat completion request parameters | `tools` | List[[models.ChatCompletionTool](../models/chatcompletiontool.md)] | :heavy_minus_sign: | Available tools for function calling | | | `top_p` | *OptionalNullable[float]* | :heavy_minus_sign: | Nucleus sampling parameter (0-1) | | | `user` | *Optional[str]* | :heavy_minus_sign: | Unique user identifier | | -| `models_llm` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | +| `fallback_models` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | | `reasoning_effort` | [OptionalNullable[models.ChatStreamCompletionCreateParamsReasoningEffort]](../models/chatstreamcompletioncreateparamsreasoningeffort.md) | :heavy_minus_sign: | Reasoning effort | | | `provider` | [OptionalNullable[models.ChatStreamCompletionCreateParamsProvider]](../models/chatstreamcompletioncreateparamsprovider.md) | :heavy_minus_sign: | When multiple model providers are available, optionally indicate your routing preference. | | | `plugins` | List[[models.ChatStreamCompletionCreateParamsPluginUnion](../models/chatstreamcompletioncreateparamspluginunion.md)] | :heavy_minus_sign: | Plugins you want to enable for this request, including their settings. | | \ No newline at end of file diff --git a/docs/models/error.md b/docs/models/error.md index 72bc8b6..30530e7 100644 --- a/docs/models/error.md +++ b/docs/models/error.md @@ -5,9 +5,9 @@ Error object structure ## Fields -| Field | Type | Required | Description | -| ------------------ | ------------------ | ------------------ | ------------------ | -| `code` | *Nullable[str]* | :heavy_check_mark: | N/A | -| `message` | *str* | :heavy_check_mark: | N/A | -| `param` | *Nullable[str]* | :heavy_check_mark: | N/A | -| `type` | *str* | :heavy_check_mark: | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ----------------------- | ----------------------- | ----------------------- | ----------------------- | +| `code` | *Nullable[float]* | :heavy_check_mark: | N/A | +| `message` | *str* | :heavy_check_mark: | N/A | +| `param` | *OptionalNullable[str]* | :heavy_minus_sign: | N/A | +| `type` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/security.md b/docs/models/security.md index 8ca6325..2e0839d 100644 --- a/docs/models/security.md +++ b/docs/models/security.md @@ -5,4 +5,4 @@ | Field | Type | Required | Description | | ------------------ | ------------------ | ------------------ | ------------------ | -| `bearer_auth` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file +| `api_key` | *Optional[str]* | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/sdks/chat/README.md b/docs/sdks/chat/README.md index 343d180..bc639cd 100644 --- a/docs/sdks/chat/README.md +++ b/docs/sdks/chat/README.md @@ -18,17 +18,17 @@ Creates a model response for the given chat conversation. Supports both streamin ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=False, temperature=1, top_p=1) @@ -63,7 +63,7 @@ with OpenRouter( | `tools` | List[[models.ChatCompletionTool](../../models/chatcompletiontool.md)] | :heavy_minus_sign: | Available tools for function calling | | | `top_p` | *OptionalNullable[float]* | :heavy_minus_sign: | Nucleus sampling parameter (0-1) | | | `user` | *Optional[str]* | :heavy_minus_sign: | Unique user identifier | | -| `models_llm` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | +| `fallback_models` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | | `reasoning_effort` | [OptionalNullable[models.ChatCompletionCreateParamsReasoningEffort]](../../models/chatcompletioncreateparamsreasoningeffort.md) | :heavy_minus_sign: | Reasoning effort | | | `provider` | [OptionalNullable[models.ChatCompletionCreateParamsProvider]](../../models/chatcompletioncreateparamsprovider.md) | :heavy_minus_sign: | When multiple model providers are available, optionally indicate your routing preference. | | | `plugins` | List[[models.ChatCompletionCreateParamsPluginUnion](../../models/chatcompletioncreateparamspluginunion.md)] | :heavy_minus_sign: | Plugins you want to enable for this request, including their settings. | | @@ -89,17 +89,17 @@ Creates a model response for the given chat conversation. Supports both streamin ```python -from openrouter import OpenRouter, models +from openrouter import OpenRouter import os with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_BEARER_AUTH", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: res = open_router.chat.complete_stream(messages=[ { - "role": models.ChatCompletionUserMessageParamRole.USER, + "role": "user", "content": "Hello, how are you?", }, ], stream=True, temperature=1, top_p=1) @@ -136,7 +136,7 @@ with OpenRouter( | `tools` | List[[models.ChatCompletionTool](../../models/chatcompletiontool.md)] | :heavy_minus_sign: | Available tools for function calling | | | `top_p` | *OptionalNullable[float]* | :heavy_minus_sign: | Nucleus sampling parameter (0-1) | | | `user` | *Optional[str]* | :heavy_minus_sign: | Unique user identifier | | -| `models_llm` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | +| `fallback_models` | List[*str*] | :heavy_minus_sign: | Order of models to fallback to for this request | | | `reasoning_effort` | [OptionalNullable[models.ChatStreamCompletionCreateParamsReasoningEffort]](../../models/chatstreamcompletioncreateparamsreasoningeffort.md) | :heavy_minus_sign: | Reasoning effort | | | `provider` | [OptionalNullable[models.ChatStreamCompletionCreateParamsProvider]](../../models/chatstreamcompletioncreateparamsprovider.md) | :heavy_minus_sign: | When multiple model providers are available, optionally indicate your routing preference. | | | `plugins` | List[[models.ChatStreamCompletionCreateParamsPluginUnion](../../models/chatstreamcompletioncreateparamspluginunion.md)] | :heavy_minus_sign: | Plugins you want to enable for this request, including their settings. | | diff --git a/examples/.env b/examples/.env deleted file mode 100644 index 85d3b39..0000000 --- a/examples/.env +++ /dev/null @@ -1 +0,0 @@ -OPENROUTER_API_KEY="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" \ No newline at end of file diff --git a/examples/asyncChatCompletion.py b/examples/asyncChatCompletion.py new file mode 100644 index 0000000..69a8028 --- /dev/null +++ b/examples/asyncChatCompletion.py @@ -0,0 +1,24 @@ +dependencies = [ + "openrouter", + "os", + "asyncio", +] + +import os +import asyncio +from openrouter import OpenRouter + +async def main(): + sdk = OpenRouter( + api_key=os.getenv("OPENROUTER_API_KEY"), + ) + result = await sdk.chat.complete_async( + messages=[ + {"role": "user", "content": "Hello, world!"}, + ], + model="openai/gpt-3.5-turbo", + ) + print("Basic async completion:", result) + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/examples/asyncSseChatCompletion.py b/examples/asyncSseChatCompletion.py new file mode 100644 index 0000000..374df2b --- /dev/null +++ b/examples/asyncSseChatCompletion.py @@ -0,0 +1,32 @@ +dependencies = [ + "openrouter", + "os", + "asyncio", +] + +import os +import asyncio +from openrouter import OpenRouter + +async def main(): + open_router = OpenRouter( + api_key=os.getenv("OPENROUTER_API_KEY", ""), + ) + res = await open_router.chat.complete_async( + messages=[ + { + "role": "user", + "content": "Hello, how are you?", + }, + ], + model="openai/gpt-3.5-turbo", + stream=True + ) + + async for event in res: # type: ignore + if event.data.choices and event.data.choices[0].delta.content: + print(event.data.choices[0].delta.content, end='', flush=True) + print() + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/examples/chatCompletion.py b/examples/chatCompletion.py index b422014..d970250 100644 --- a/examples/chatCompletion.py +++ b/examples/chatCompletion.py @@ -8,13 +8,12 @@ import os from openrouter import OpenRouter with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_API_KEY"), + api_key=os.getenv("OPENROUTER_API_KEY"), ) as sdk: result = sdk.chat.complete( - model="openai/gpt-3.5-turbo", messages=[ {"role": "user", "content": "Hello, world!"}, ], + model="openai/gpt-3.5-turbo", ) - -print(result) \ No newline at end of file + print("Basic completion:", result) diff --git a/examples/sseChatCompletion.py b/examples/sseChatCompletion.py index 6b16dfc..c3f252b 100644 --- a/examples/sseChatCompletion.py +++ b/examples/sseChatCompletion.py @@ -5,22 +5,24 @@ dependencies = [ ] import os -from openrouter import OpenRouter, models +from openrouter import OpenRouter with OpenRouter( - bearer_auth=os.getenv("OPENROUTER_API_KEY", ""), + api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - - res = open_router.chat.complete_stream(messages=[ - { - "role": "user", - "content": "Hello, how are you?", - }, - - ], model="openai/gpt-3.5-turbo", stream=True, temperature=1, top_p=1) + res = open_router.chat.complete( + messages=[ + { + "role": "user", + "content": "Hello, how are you?", + }, + ], + model="openai/gpt-3.5-turbo", + stream=True + ) with res as event_stream: for event in event_stream: if event.data.choices and event.data.choices[0].delta.content: print(event.data.choices[0].delta.content, end='', flush=True) - print() # New line at the end \ No newline at end of file + print() \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index fb838d2..573ac55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "0.1.3" +version = "0.5.2" description = "Python Client SDK Generated by Speakeasy." authors = [{ name = "Speakeasy" },] readme = "README-PYPI.md" @@ -30,6 +30,7 @@ build-backend = "setuptools.build_meta" [tool.pytest.ini_options] asyncio_default_fixture_loop_scope = "function" +asyncio_mode = "auto" pythonpath = ["src"] [tool.mypy] diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py index 0fdc8ca..2277dde 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "0.1.3" +__version__: str = "0.5.2" __openapi_doc_version__: str = "1.0.0" -__gen_version__: str = "2.687.1" -__user_agent__: str = "speakeasy-sdk/python 0.1.3 2.687.1 1.0.0 openrouter" +__gen_version__: str = "2.694.1" +__user_agent__: str = "speakeasy-sdk/python 0.5.2 2.694.1 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/basesdk.py b/src/openrouter/basesdk.py index de6dfd0..a550aff 100644 --- a/src/openrouter/basesdk.py +++ b/src/openrouter/basesdk.py @@ -15,9 +15,19 @@ from urllib.parse import parse_qs, urlparse class BaseSDK: sdk_configuration: SDKConfiguration + parent_ref: Optional[object] = None + """ + Reference to the root SDK instance, if any. This will prevent it from + being garbage collected while there are active streams. + """ - def __init__(self, sdk_config: SDKConfiguration) -> None: + def __init__( + self, + sdk_config: SDKConfiguration, + parent_ref: Optional[object] = None, + ) -> None: self.sdk_configuration = sdk_config + self.parent_ref = parent_ref def _get_url(self, base_url, url_variables): sdk_url, sdk_variables = self.sdk_configuration.get_server_details() diff --git a/src/openrouter/chat.py b/src/openrouter/chat.py index 0b8f344..56afd7c 100644 --- a/src/openrouter/chat.py +++ b/src/openrouter/chat.py @@ -69,7 +69,7 @@ class Chat(BaseSDK): ] = None, top_p: OptionalNullable[float] = 1, user: Optional[str] = None, - models_llm: OptionalNullable[List[str]] = UNSET, + fallback_models: OptionalNullable[List[str]] = UNSET, reasoning_effort: OptionalNullable[ models.ChatCompletionCreateParamsReasoningEffort ] = UNSET, @@ -115,7 +115,7 @@ class Chat(BaseSDK): :param tools: Available tools for function calling :param top_p: Nucleus sampling parameter (0-1) :param user: Unique user identifier - :param models_llm: Order of models to fallback to for this request + :param fallback_models: Order of models to fallback to for this request :param reasoning_effort: Reasoning effort :param provider: When multiple model providers are available, optionally indicate your routing preference. :param plugins: Plugins you want to enable for this request, including their settings. @@ -170,7 +170,7 @@ class Chat(BaseSDK): ), top_p=top_p, user=user, - models_llm=models_llm, + fallback_models=fallback_models, reasoning_effort=reasoning_effort, provider=utils.get_pydantic_model( provider, OptionalNullable[models.ChatCompletionCreateParamsProvider] @@ -305,7 +305,7 @@ class Chat(BaseSDK): ] = None, top_p: OptionalNullable[float] = 1, user: Optional[str] = None, - models_llm: OptionalNullable[List[str]] = UNSET, + fallback_models: OptionalNullable[List[str]] = UNSET, reasoning_effort: OptionalNullable[ models.ChatCompletionCreateParamsReasoningEffort ] = UNSET, @@ -351,7 +351,7 @@ class Chat(BaseSDK): :param tools: Available tools for function calling :param top_p: Nucleus sampling parameter (0-1) :param user: Unique user identifier - :param models_llm: Order of models to fallback to for this request + :param fallback_models: Order of models to fallback to for this request :param reasoning_effort: Reasoning effort :param provider: When multiple model providers are available, optionally indicate your routing preference. :param plugins: Plugins you want to enable for this request, including their settings. @@ -406,7 +406,7 @@ class Chat(BaseSDK): ), top_p=top_p, user=user, - models_llm=models_llm, + fallback_models=fallback_models, reasoning_effort=reasoning_effort, provider=utils.get_pydantic_model( provider, OptionalNullable[models.ChatCompletionCreateParamsProvider] @@ -541,7 +541,7 @@ class Chat(BaseSDK): ] = None, top_p: OptionalNullable[float] = 1, user: Optional[str] = None, - models_llm: OptionalNullable[List[str]] = UNSET, + fallback_models: OptionalNullable[List[str]] = UNSET, reasoning_effort: OptionalNullable[ models.ChatStreamCompletionCreateParamsReasoningEffort ] = UNSET, @@ -587,7 +587,7 @@ class Chat(BaseSDK): :param tools: Available tools for function calling :param top_p: Nucleus sampling parameter (0-1) :param user: Unique user identifier - :param models_llm: Order of models to fallback to for this request + :param fallback_models: Order of models to fallback to for this request :param reasoning_effort: Reasoning effort :param provider: When multiple model providers are available, optionally indicate your routing preference. :param plugins: Plugins you want to enable for this request, including their settings. @@ -643,7 +643,7 @@ class Chat(BaseSDK): ), top_p=top_p, user=user, - models_llm=models_llm, + fallback_models=fallback_models, reasoning_effort=reasoning_effort, provider=utils.get_pydantic_model( provider, @@ -706,6 +706,7 @@ class Chat(BaseSDK): raw, models.StreamChatCompletionResponseBody ), sentinel="[DONE]", + client_ref=self, ) if utils.match_response(http_res, ["400", "401", "429"], "application/json"): http_res_text = utils.stream_to_text(http_res) @@ -792,7 +793,7 @@ class Chat(BaseSDK): ] = None, top_p: OptionalNullable[float] = 1, user: Optional[str] = None, - models_llm: OptionalNullable[List[str]] = UNSET, + fallback_models: OptionalNullable[List[str]] = UNSET, reasoning_effort: OptionalNullable[ models.ChatStreamCompletionCreateParamsReasoningEffort ] = UNSET, @@ -838,7 +839,7 @@ class Chat(BaseSDK): :param tools: Available tools for function calling :param top_p: Nucleus sampling parameter (0-1) :param user: Unique user identifier - :param models_llm: Order of models to fallback to for this request + :param fallback_models: Order of models to fallback to for this request :param reasoning_effort: Reasoning effort :param provider: When multiple model providers are available, optionally indicate your routing preference. :param plugins: Plugins you want to enable for this request, including their settings. @@ -894,7 +895,7 @@ class Chat(BaseSDK): ), top_p=top_p, user=user, - models_llm=models_llm, + fallback_models=fallback_models, reasoning_effort=reasoning_effort, provider=utils.get_pydantic_model( provider, @@ -957,6 +958,7 @@ class Chat(BaseSDK): raw, models.StreamChatCompletionResponseBody ), sentinel="[DONE]", + client_ref=self, ) if utils.match_response(http_res, ["400", "401", "429"], "application/json"): http_res_text = await utils.stream_to_text_async(http_res) diff --git a/src/openrouter/errors/__init__.py b/src/openrouter/errors/__init__.py index 5cf95f1..67b0e5d 100644 --- a/src/openrouter/errors/__init__.py +++ b/src/openrouter/errors/__init__.py @@ -1,14 +1,15 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" +from .openroutererror import OpenRouterError from typing import TYPE_CHECKING from importlib import import_module import builtins +import sys if TYPE_CHECKING: from .chatcompletionerror import ChatCompletionError, ChatCompletionErrorData from .no_response_error import NoResponseError from .openrouterdefaulterror import OpenRouterDefaultError - from .openroutererror import OpenRouterError from .responsevalidationerror import ResponseValidationError __all__ = [ @@ -25,11 +26,22 @@ _dynamic_imports: dict[str, str] = { "ChatCompletionErrorData": ".chatcompletionerror", "NoResponseError": ".no_response_error", "OpenRouterDefaultError": ".openrouterdefaulterror", - "OpenRouterError": ".openroutererror", "ResponseValidationError": ".responsevalidationerror", } +def dynamic_import(modname, retries=3): + for attempt in range(retries): + try: + return import_module(modname, __package__) + except KeyError: + # Clear any half-initialized module and retry + sys.modules.pop(modname, None) + if attempt == retries - 1: + break + raise KeyError(f"Failed to import module '{modname}' after {retries} attempts") + + def __getattr__(attr_name: str) -> object: module_name = _dynamic_imports.get(attr_name) if module_name is None: @@ -38,7 +50,7 @@ def __getattr__(attr_name: str) -> object: ) try: - module = import_module(module_name, __package__) + module = dynamic_import(module_name) result = getattr(module, attr_name) return result except ImportError as e: diff --git a/src/openrouter/models/__init__.py b/src/openrouter/models/__init__.py index 59080c2..2ae4b74 100644 --- a/src/openrouter/models/__init__.py +++ b/src/openrouter/models/__init__.py @@ -3,6 +3,7 @@ from typing import TYPE_CHECKING from importlib import import_module import builtins +import sys if TYPE_CHECKING: from .annotationdetail import AnnotationDetail, AnnotationDetailTypedDict @@ -931,6 +932,18 @@ _dynamic_imports: dict[str, str] = { } +def dynamic_import(modname, retries=3): + for attempt in range(retries): + try: + return import_module(modname, __package__) + except KeyError: + # Clear any half-initialized module and retry + sys.modules.pop(modname, None) + if attempt == retries - 1: + break + raise KeyError(f"Failed to import module '{modname}' after {retries} attempts") + + def __getattr__(attr_name: str) -> object: module_name = _dynamic_imports.get(attr_name) if module_name is None: @@ -939,7 +952,7 @@ def __getattr__(attr_name: str) -> object: ) try: - module = import_module(module_name, __package__) + module = dynamic_import(module_name) result = getattr(module, attr_name) return result except ImportError as e: diff --git a/src/openrouter/models/chatcompletion.py b/src/openrouter/models/chatcompletion.py index f4fd50c..e592b38 100644 --- a/src/openrouter/models/chatcompletion.py +++ b/src/openrouter/models/chatcompletion.py @@ -3,7 +3,6 @@ from __future__ import annotations from .chatcompletionchoice import ChatCompletionChoice, ChatCompletionChoiceTypedDict from .completionusage import CompletionUsage, CompletionUsageTypedDict -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -12,12 +11,11 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import List, Optional +from typing import List, Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionObject(str, Enum): - CHAT_COMPLETION = "chat.completion" +ChatCompletionObject = Literal["chat.completion"] class ChatCompletionTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionassistantmessageparam.py b/src/openrouter/models/chatcompletionassistantmessageparam.py index a698ee6..260f034 100644 --- a/src/openrouter/models/chatcompletionassistantmessageparam.py +++ b/src/openrouter/models/chatcompletionassistantmessageparam.py @@ -9,7 +9,6 @@ from .chatcompletionmessagetoolcall import ( ChatCompletionMessageToolCall, ChatCompletionMessageToolCallTypedDict, ) -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -18,13 +17,11 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import Any, List, Optional, Union +from typing import Any, List, Literal, Optional, Union from typing_extensions import NotRequired, TypeAliasType, TypedDict -class ChatCompletionAssistantMessageParamRole(str, Enum): - ASSISTANT = "assistant" - +ChatCompletionAssistantMessageParamRole = Literal["assistant"] ChatCompletionAssistantMessageParamContentTypedDict = TypeAliasType( "ChatCompletionAssistantMessageParamContentTypedDict", diff --git a/src/openrouter/models/chatcompletionchoice.py b/src/openrouter/models/chatcompletionchoice.py index cd7f7ae..f670b8a 100644 --- a/src/openrouter/models/chatcompletionchoice.py +++ b/src/openrouter/models/chatcompletionchoice.py @@ -6,7 +6,6 @@ from .chatcompletiontokenlogprobs import ( ChatCompletionTokenLogprobs, ChatCompletionTokenLogprobsTypedDict, ) -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -15,17 +14,14 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer +from typing import Literal from typing_extensions import NotRequired, TypedDict -class ChatCompletionChoiceFinishReason(str, Enum): - r"""Reason the completion finished""" - - TOOL_CALLS = "tool_calls" - STOP = "stop" - LENGTH = "length" - CONTENT_FILTER = "content_filter" - ERROR = "error" +ChatCompletionChoiceFinishReason = Literal[ + "tool_calls", "stop", "length", "content_filter", "error" +] +r"""Reason the completion finished""" class ChatCompletionChoiceTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionchunk.py b/src/openrouter/models/chatcompletionchunk.py index 54a0dec..0e1a44f 100644 --- a/src/openrouter/models/chatcompletionchunk.py +++ b/src/openrouter/models/chatcompletionchunk.py @@ -6,7 +6,6 @@ from .chatcompletionchunkchoice import ( ChatCompletionChunkChoiceTypedDict, ) from .completionusage import CompletionUsage, CompletionUsageTypedDict -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -15,12 +14,11 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import List, Optional +from typing import List, Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionChunkObject(str, Enum): - CHAT_COMPLETION_CHUNK = "chat.completion.chunk" +ChatCompletionChunkObject = Literal["chat.completion.chunk"] class ChatCompletionChunkTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionchunkchoice.py b/src/openrouter/models/chatcompletionchunkchoice.py index 4ce6418..3e212e4 100644 --- a/src/openrouter/models/chatcompletionchunkchoice.py +++ b/src/openrouter/models/chatcompletionchunkchoice.py @@ -9,7 +9,6 @@ from .chatcompletiontokenlogprobs import ( ChatCompletionTokenLogprobs, ChatCompletionTokenLogprobsTypedDict, ) -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -18,15 +17,13 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer +from typing import Literal from typing_extensions import NotRequired, TypedDict -class ChatCompletionChunkChoiceFinishReason(str, Enum): - TOOL_CALLS = "tool_calls" - STOP = "stop" - LENGTH = "length" - CONTENT_FILTER = "content_filter" - ERROR = "error" +ChatCompletionChunkChoiceFinishReason = Literal[ + "tool_calls", "stop", "length", "content_filter", "error" +] class ChatCompletionChunkChoiceTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionchunkchoicedelta.py b/src/openrouter/models/chatcompletionchunkchoicedelta.py index 1aa2d5c..addd105 100644 --- a/src/openrouter/models/chatcompletionchunkchoicedelta.py +++ b/src/openrouter/models/chatcompletionchunkchoicedelta.py @@ -7,7 +7,6 @@ from .chatcompletionchunkchoicedeltatoolcall import ( ChatCompletionChunkChoiceDeltaToolCallTypedDict, ) from .reasoningdetail import ReasoningDetail, ReasoningDetailTypedDict -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -16,14 +15,12 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import List, Optional +from typing import List, Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionChunkChoiceDeltaRole(str, Enum): - r"""The role of the message author""" - - ASSISTANT = "assistant" +ChatCompletionChunkChoiceDeltaRole = Literal["assistant"] +r"""The role of the message author""" class ChatCompletionChunkChoiceDeltaTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionchunkchoicedeltatoolcall.py b/src/openrouter/models/chatcompletionchunkchoicedeltatoolcall.py index 0501977..e2fe9aa 100644 --- a/src/openrouter/models/chatcompletionchunkchoicedeltatoolcall.py +++ b/src/openrouter/models/chatcompletionchunkchoicedeltatoolcall.py @@ -1,16 +1,13 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel -from typing import Optional +from typing import Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionChunkChoiceDeltaToolCallType(str, Enum): - r"""Tool call type""" - - FUNCTION = "function" +ChatCompletionChunkChoiceDeltaToolCallType = Literal["function"] +r"""Tool call type""" class ChatCompletionChunkChoiceDeltaToolCallFunctionTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletioncontentpartaudio.py b/src/openrouter/models/chatcompletioncontentpartaudio.py index cc5abea..21bfb58 100644 --- a/src/openrouter/models/chatcompletioncontentpartaudio.py +++ b/src/openrouter/models/chatcompletioncontentpartaudio.py @@ -1,26 +1,18 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel import pydantic +from typing import Literal from typing_extensions import Annotated, TypedDict -class ChatCompletionContentPartAudioType(str, Enum): - INPUT_AUDIO = "input_audio" +ChatCompletionContentPartAudioType = Literal["input_audio"] - -class ChatCompletionContentPartAudioFormat(str, Enum): - r"""Audio format""" - - WAV = "wav" - MP3 = "mp3" - FLAC = "flac" - M4A = "m4a" - OGG = "ogg" - PCM16 = "pcm16" - PCM24 = "pcm24" +ChatCompletionContentPartAudioFormat = Literal[ + "wav", "mp3", "flac", "m4a", "ogg", "pcm16", "pcm24" +] +r"""Audio format""" class InputAudioTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletioncontentpartimage.py b/src/openrouter/models/chatcompletioncontentpartimage.py index 4469344..fde5e35 100644 --- a/src/openrouter/models/chatcompletioncontentpartimage.py +++ b/src/openrouter/models/chatcompletioncontentpartimage.py @@ -1,22 +1,15 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel -from typing import Optional +from typing import Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionContentPartImageType(str, Enum): - IMAGE_URL = "image_url" +ChatCompletionContentPartImageType = Literal["image_url"] - -class Detail(str, Enum): - r"""Image detail level for vision models""" - - AUTO = "auto" - LOW = "low" - HIGH = "high" +Detail = Literal["auto", "low", "high"] +r"""Image detail level for vision models""" class ChatCompletionContentPartImageImageURLTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletioncontentparttext.py b/src/openrouter/models/chatcompletioncontentparttext.py index db491d0..cbcf07c 100644 --- a/src/openrouter/models/chatcompletioncontentparttext.py +++ b/src/openrouter/models/chatcompletioncontentparttext.py @@ -1,13 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel +from typing import Literal from typing_extensions import TypedDict -class ChatCompletionContentPartTextType(str, Enum): - TEXT = "text" +ChatCompletionContentPartTextType = Literal["text"] class ChatCompletionContentPartTextTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletioncreateparams.py b/src/openrouter/models/chatcompletioncreateparams.py index 0dcd4cd..75d108c 100644 --- a/src/openrouter/models/chatcompletioncreateparams.py +++ b/src/openrouter/models/chatcompletioncreateparams.py @@ -14,7 +14,6 @@ from .responseformatjsonschemaschema import ( ResponseFormatJSONSchemaSchema, ResponseFormatJSONSchemaSchemaTypedDict, ) -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -24,17 +23,12 @@ from openrouter.types import ( ) import pydantic from pydantic import model_serializer -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Literal, Optional, Union from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -class ChatCompletionCreateParamsEffort(str, Enum): - r"""OpenAI-style reasoning effort setting""" - - HIGH = "high" - MEDIUM = "medium" - LOW = "low" - MINIMAL = "minimal" +ChatCompletionCreateParamsEffort = Literal["high", "medium", "low", "minimal"] +r"""OpenAI-style reasoning effort setting""" class ChatCompletionCreateParamsReasoningTypedDict(TypedDict): @@ -94,8 +88,7 @@ class ChatCompletionCreateParamsReasoning(BaseModel): return m -class ChatCompletionCreateParamsTypePython(str, Enum): - PYTHON = "python" +ChatCompletionCreateParamsTypePython = Literal["python"] class ChatCompletionCreateParamsResponseFormatPythonTypedDict(TypedDict): @@ -110,8 +103,7 @@ class ChatCompletionCreateParamsResponseFormatPython(BaseModel): type: ChatCompletionCreateParamsTypePython -class ChatCompletionCreateParamsTypeGrammar(str, Enum): - GRAMMAR = "grammar" +ChatCompletionCreateParamsTypeGrammar = Literal["grammar"] class ChatCompletionCreateParamsResponseFormatGrammarTypedDict(TypedDict): @@ -131,8 +123,7 @@ class ChatCompletionCreateParamsResponseFormatGrammar(BaseModel): r"""Custom grammar for text generation""" -class ChatCompletionCreateParamsTypeJSONSchema(str, Enum): - JSON_SCHEMA = "json_schema" +ChatCompletionCreateParamsTypeJSONSchema = Literal["json_schema"] class ChatCompletionCreateParamsJSONSchemaTypedDict(TypedDict): @@ -207,8 +198,7 @@ class ChatCompletionCreateParamsResponseFormatJSONSchema(BaseModel): json_schema: ChatCompletionCreateParamsJSONSchema -class ChatCompletionCreateParamsTypeJSONObject(str, Enum): - JSON_OBJECT = "json_object" +ChatCompletionCreateParamsTypeJSONObject = Literal["json_object"] class ChatCompletionCreateParamsResponseFormatJSONObjectTypedDict(TypedDict): @@ -223,8 +213,7 @@ class ChatCompletionCreateParamsResponseFormatJSONObject(BaseModel): type: ChatCompletionCreateParamsTypeJSONObject -class ChatCompletionCreateParamsTypeText(str, Enum): - TEXT = "text" +ChatCompletionCreateParamsTypeText = Literal["text"] class ChatCompletionCreateParamsResponseFormatTextTypedDict(TypedDict): @@ -291,106 +280,96 @@ class ChatCompletionCreateParamsStreamOptions(BaseModel): r"""Include usage information in streaming response""" -class ChatCompletionCreateParamsReasoningEffort(str, Enum): - r"""Reasoning effort""" +ChatCompletionCreateParamsReasoningEffort = Literal["high", "medium", "low", "minimal"] +r"""Reasoning effort""" - HIGH = "high" - MEDIUM = "medium" - LOW = "low" - MINIMAL = "minimal" +ChatCompletionCreateParamsDataCollection = Literal["deny", "allow"] +r"""Data collection setting. If no available model provider meets the requirement, your request will return an error. +- allow: (default) allow providers which store user data non-transiently and may train on it +- deny: use only providers which do not collect user data. +""" -class ChatCompletionCreateParamsDataCollection(str, Enum): - r"""Data collection setting. If no available model provider meets the requirement, your request will return an error. - - allow: (default) allow providers which store user data non-transiently and may train on it - - deny: use only providers which do not collect user data. - - """ - - DENY = "deny" - ALLOW = "allow" - - -class ChatCompletionCreateParamsOrderEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatCompletionCreateParamsOrderEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatCompletionCreateParamsOrderUnionTypedDict = TypeAliasType( "ChatCompletionCreateParamsOrderUnionTypedDict", @@ -404,86 +383,86 @@ ChatCompletionCreateParamsOrderUnion = TypeAliasType( ) -class ChatCompletionCreateParamsOnlyEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatCompletionCreateParamsOnlyEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatCompletionCreateParamsOnlyUnionTypedDict = TypeAliasType( "ChatCompletionCreateParamsOnlyUnionTypedDict", @@ -497,86 +476,86 @@ ChatCompletionCreateParamsOnlyUnion = TypeAliasType( ) -class ChatCompletionCreateParamsIgnoreEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatCompletionCreateParamsIgnoreEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatCompletionCreateParamsIgnoreUnionTypedDict = TypeAliasType( "ChatCompletionCreateParamsIgnoreUnionTypedDict", @@ -590,25 +569,12 @@ ChatCompletionCreateParamsIgnoreUnion = TypeAliasType( ) -class ChatCompletionCreateParamsQuantization(str, Enum): - INT4 = "int4" - INT8 = "int8" - FP4 = "fp4" - FP6 = "fp6" - FP8 = "fp8" - FP16 = "fp16" - BF16 = "bf16" - FP32 = "fp32" - UNKNOWN = "unknown" - - -class ChatCompletionCreateParamsSort(str, Enum): - r"""The sorting strategy to use for this request, if \"order\" is not specified. When set, no load balancing is performed.""" - - PRICE = "price" - THROUGHPUT = "throughput" - LATENCY = "latency" +ChatCompletionCreateParamsQuantization = Literal[ + "int4", "int8", "fp4", "fp6", "fp8", "fp16", "bf16", "fp32", "unknown" +] +ChatCompletionCreateParamsSort = Literal["price", "throughput", "latency"] +r"""The sorting strategy to use for this request, if \"order\" is not specified. When set, no load balancing is performed.""" ChatCompletionCreateParamsPromptTypedDict = TypeAliasType( "ChatCompletionCreateParamsPromptTypedDict", Union[float, str, Any] @@ -805,14 +771,9 @@ class ChatCompletionCreateParamsProvider(BaseModel): return m -class ChatCompletionCreateParamsIDFileParser(str, Enum): - FILE_PARSER = "file-parser" +ChatCompletionCreateParamsIDFileParser = Literal["file-parser"] - -class ChatCompletionCreateParamsPdfEngine(str, Enum): - MISTRAL_OCR = "mistral-ocr" - PDF_TEXT = "pdf-text" - NATIVE = "native" +ChatCompletionCreateParamsPdfEngine = Literal["mistral-ocr", "pdf-text", "native"] class ChatCompletionCreateParamsPdfTypedDict(TypedDict): @@ -837,8 +798,7 @@ class ChatCompletionCreateParamsPluginFileParser(BaseModel): pdf: Optional[ChatCompletionCreateParamsPdf] = None -class ChatCompletionCreateParamsIDChainOfThought(str, Enum): - CHAIN_OF_THOUGHT = "chain-of-thought" +ChatCompletionCreateParamsIDChainOfThought = Literal["chain-of-thought"] class ChatCompletionCreateParamsPluginChainOfThoughtTypedDict(TypedDict): @@ -849,13 +809,9 @@ class ChatCompletionCreateParamsPluginChainOfThought(BaseModel): id: ChatCompletionCreateParamsIDChainOfThought -class ChatCompletionCreateParamsIDWeb(str, Enum): - WEB = "web" +ChatCompletionCreateParamsIDWeb = Literal["web"] - -class ChatCompletionCreateParamsEngine(str, Enum): - NATIVE = "native" - EXA = "exa" +ChatCompletionCreateParamsEngine = Literal["native", "exa"] class ChatCompletionCreateParamsPluginWebTypedDict(TypedDict): @@ -875,8 +831,7 @@ class ChatCompletionCreateParamsPluginWeb(BaseModel): engine: Optional[ChatCompletionCreateParamsEngine] = None -class ChatCompletionCreateParamsIDModeration(str, Enum): - MODERATION = "moderation" +ChatCompletionCreateParamsIDModeration = Literal["moderation"] class ChatCompletionCreateParamsPluginModerationTypedDict(TypedDict): @@ -955,7 +910,7 @@ class ChatCompletionCreateParamsTypedDict(TypedDict): r"""Nucleus sampling parameter (0-1)""" user: NotRequired[str] r"""Unique user identifier""" - models_llm: NotRequired[Nullable[List[str]]] + fallback_models: NotRequired[Nullable[List[str]]] r"""Order of models to fallback to for this request""" reasoning_effort: NotRequired[Nullable[ChatCompletionCreateParamsReasoningEffort]] r"""Reasoning effort""" @@ -1030,7 +985,7 @@ class ChatCompletionCreateParams(BaseModel): user: Optional[str] = None r"""Unique user identifier""" - models_llm: Annotated[ + fallback_models: Annotated[ OptionalNullable[List[str]], pydantic.Field(alias="models") ] = UNSET r"""Order of models to fallback to for this request""" @@ -1069,7 +1024,7 @@ class ChatCompletionCreateParams(BaseModel): "tools", "top_p", "user", - "models_llm", + "fallback_models", "reasoning_effort", "provider", "plugins", @@ -1089,7 +1044,7 @@ class ChatCompletionCreateParams(BaseModel): "stream_options", "temperature", "top_p", - "models_llm", + "fallback_models", "reasoning_effort", "provider", ] diff --git a/src/openrouter/models/chatcompletionerror.py b/src/openrouter/models/chatcompletionerror.py index 55a07b6..3896be8 100644 --- a/src/openrouter/models/chatcompletionerror.py +++ b/src/openrouter/models/chatcompletionerror.py @@ -1,34 +1,41 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -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_extensions import TypedDict +from typing import Optional +from typing_extensions import NotRequired, TypedDict class ErrorTypedDict(TypedDict): r"""Error object structure""" - code: Nullable[str] + code: Nullable[float] message: str - param: Nullable[str] - type: str + param: NotRequired[Nullable[str]] + type: NotRequired[str] class Error(BaseModel): r"""Error object structure""" - code: Nullable[str] + code: Nullable[float] message: str - param: Nullable[str] + param: OptionalNullable[str] = UNSET - type: str + type: Optional[str] = None @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = [] + optional_fields = ["param", "type"] nullable_fields = ["code", "param"] null_default_fields = [] diff --git a/src/openrouter/models/chatcompletionmessage.py b/src/openrouter/models/chatcompletionmessage.py index b4a0c08..18684ce 100644 --- a/src/openrouter/models/chatcompletionmessage.py +++ b/src/openrouter/models/chatcompletionmessage.py @@ -7,7 +7,6 @@ from .chatcompletionmessagetoolcall import ( ChatCompletionMessageToolCallTypedDict, ) from .reasoningdetail import ReasoningDetail, ReasoningDetailTypedDict -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -16,12 +15,11 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import List, Optional +from typing import List, Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionMessageRole(str, Enum): - ASSISTANT = "assistant" +ChatCompletionMessageRole = Literal["assistant"] class ChatCompletionMessageTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionmessagetoolcall.py b/src/openrouter/models/chatcompletionmessagetoolcall.py index cb94229..e34f429 100644 --- a/src/openrouter/models/chatcompletionmessagetoolcall.py +++ b/src/openrouter/models/chatcompletionmessagetoolcall.py @@ -1,13 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel +from typing import Literal from typing_extensions import TypedDict -class ChatCompletionMessageToolCallType(str, Enum): - FUNCTION = "function" +ChatCompletionMessageToolCallType = Literal["function"] class ChatCompletionMessageToolCallFunctionTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionnamedtoolchoice.py b/src/openrouter/models/chatcompletionnamedtoolchoice.py index bf2b838..f1b9b70 100644 --- a/src/openrouter/models/chatcompletionnamedtoolchoice.py +++ b/src/openrouter/models/chatcompletionnamedtoolchoice.py @@ -1,13 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel +from typing import Literal from typing_extensions import TypedDict -class ChatCompletionNamedToolChoiceType(str, Enum): - FUNCTION = "function" +ChatCompletionNamedToolChoiceType = Literal["function"] class ChatCompletionNamedToolChoiceFunctionTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletionsystemmessageparam.py b/src/openrouter/models/chatcompletionsystemmessageparam.py index a60f0a9..29201bb 100644 --- a/src/openrouter/models/chatcompletionsystemmessageparam.py +++ b/src/openrouter/models/chatcompletionsystemmessageparam.py @@ -5,15 +5,12 @@ from .chatcompletioncontentparttext import ( ChatCompletionContentPartText, ChatCompletionContentPartTextTypedDict, ) -from enum import Enum from openrouter.types import BaseModel -from typing import List, Optional, Union +from typing import List, Literal, Optional, Union from typing_extensions import NotRequired, TypeAliasType, TypedDict -class ChatCompletionSystemMessageParamRole(str, Enum): - SYSTEM = "system" - +ChatCompletionSystemMessageParamRole = Literal["system"] ChatCompletionSystemMessageParamContentTypedDict = TypeAliasType( "ChatCompletionSystemMessageParamContentTypedDict", diff --git a/src/openrouter/models/chatcompletiontool.py b/src/openrouter/models/chatcompletiontool.py index 294f401..4ec43fb 100644 --- a/src/openrouter/models/chatcompletiontool.py +++ b/src/openrouter/models/chatcompletiontool.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -10,12 +9,11 @@ from openrouter.types import ( UNSET_SENTINEL, ) from pydantic import model_serializer -from typing import Optional +from typing import Literal, Optional from typing_extensions import NotRequired, TypedDict -class ChatCompletionToolType(str, Enum): - FUNCTION = "function" +ChatCompletionToolType = Literal["function"] class ParametersTypedDict(TypedDict): diff --git a/src/openrouter/models/chatcompletiontoolchoiceoption.py b/src/openrouter/models/chatcompletiontoolchoiceoption.py index a8596ee..49b5d91 100644 --- a/src/openrouter/models/chatcompletiontoolchoiceoption.py +++ b/src/openrouter/models/chatcompletiontoolchoiceoption.py @@ -5,22 +5,15 @@ from .chatcompletionnamedtoolchoice import ( ChatCompletionNamedToolChoice, ChatCompletionNamedToolChoiceTypedDict, ) -from enum import Enum -from typing import Union +from typing import Literal, Union from typing_extensions import TypeAliasType -class ChatCompletionToolChoiceOptionRequired(str, Enum): - REQUIRED = "required" +ChatCompletionToolChoiceOptionRequired = Literal["required"] +ChatCompletionToolChoiceOptionAuto = Literal["auto"] -class ChatCompletionToolChoiceOptionAuto(str, Enum): - AUTO = "auto" - - -class ChatCompletionToolChoiceOptionNone(str, Enum): - NONE = "none" - +ChatCompletionToolChoiceOptionNone = Literal["none"] ChatCompletionToolChoiceOptionTypedDict = TypeAliasType( "ChatCompletionToolChoiceOptionTypedDict", diff --git a/src/openrouter/models/chatcompletiontoolmessageparam.py b/src/openrouter/models/chatcompletiontoolmessageparam.py index 0da1087..9345978 100644 --- a/src/openrouter/models/chatcompletiontoolmessageparam.py +++ b/src/openrouter/models/chatcompletiontoolmessageparam.py @@ -5,15 +5,12 @@ from .chatcompletioncontentpart import ( ChatCompletionContentPart, ChatCompletionContentPartTypedDict, ) -from enum import Enum from openrouter.types import BaseModel -from typing import List, Union +from typing import List, Literal, Union from typing_extensions import TypeAliasType, TypedDict -class ChatCompletionToolMessageParamRole(str, Enum): - TOOL = "tool" - +ChatCompletionToolMessageParamRole = Literal["tool"] ChatCompletionToolMessageParamContentTypedDict = TypeAliasType( "ChatCompletionToolMessageParamContentTypedDict", diff --git a/src/openrouter/models/chatcompletionusermessageparam.py b/src/openrouter/models/chatcompletionusermessageparam.py index b2dd0b0..ca292bd 100644 --- a/src/openrouter/models/chatcompletionusermessageparam.py +++ b/src/openrouter/models/chatcompletionusermessageparam.py @@ -5,15 +5,12 @@ from .chatcompletioncontentpart import ( ChatCompletionContentPart, ChatCompletionContentPartTypedDict, ) -from enum import Enum from openrouter.types import BaseModel -from typing import List, Optional, Union +from typing import List, Literal, Optional, Union from typing_extensions import NotRequired, TypeAliasType, TypedDict -class ChatCompletionUserMessageParamRole(str, Enum): - USER = "user" - +ChatCompletionUserMessageParamRole = Literal["user"] ChatCompletionUserMessageParamContentTypedDict = TypeAliasType( "ChatCompletionUserMessageParamContentTypedDict", diff --git a/src/openrouter/models/chatstreamcompletioncreateparams.py b/src/openrouter/models/chatstreamcompletioncreateparams.py index 45f0faf..aa19b5e 100644 --- a/src/openrouter/models/chatstreamcompletioncreateparams.py +++ b/src/openrouter/models/chatstreamcompletioncreateparams.py @@ -14,7 +14,6 @@ from .responseformatjsonschemaschema import ( ResponseFormatJSONSchemaSchema, ResponseFormatJSONSchemaSchemaTypedDict, ) -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -24,17 +23,12 @@ from openrouter.types import ( ) import pydantic from pydantic import model_serializer -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Literal, Optional, Union from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict -class ChatStreamCompletionCreateParamsEffort(str, Enum): - r"""OpenAI-style reasoning effort setting""" - - HIGH = "high" - MEDIUM = "medium" - LOW = "low" - MINIMAL = "minimal" +ChatStreamCompletionCreateParamsEffort = Literal["high", "medium", "low", "minimal"] +r"""OpenAI-style reasoning effort setting""" class ChatStreamCompletionCreateParamsReasoningTypedDict(TypedDict): @@ -94,8 +88,7 @@ class ChatStreamCompletionCreateParamsReasoning(BaseModel): return m -class ChatStreamCompletionCreateParamsTypePython(str, Enum): - PYTHON = "python" +ChatStreamCompletionCreateParamsTypePython = Literal["python"] class ChatStreamCompletionCreateParamsResponseFormatPythonTypedDict(TypedDict): @@ -110,8 +103,7 @@ class ChatStreamCompletionCreateParamsResponseFormatPython(BaseModel): type: ChatStreamCompletionCreateParamsTypePython -class ChatStreamCompletionCreateParamsTypeGrammar(str, Enum): - GRAMMAR = "grammar" +ChatStreamCompletionCreateParamsTypeGrammar = Literal["grammar"] class ChatStreamCompletionCreateParamsResponseFormatGrammarTypedDict(TypedDict): @@ -131,8 +123,7 @@ class ChatStreamCompletionCreateParamsResponseFormatGrammar(BaseModel): r"""Custom grammar for text generation""" -class ChatStreamCompletionCreateParamsTypeJSONSchema(str, Enum): - JSON_SCHEMA = "json_schema" +ChatStreamCompletionCreateParamsTypeJSONSchema = Literal["json_schema"] class ChatStreamCompletionCreateParamsJSONSchemaTypedDict(TypedDict): @@ -207,8 +198,7 @@ class ChatStreamCompletionCreateParamsResponseFormatJSONSchema(BaseModel): json_schema: ChatStreamCompletionCreateParamsJSONSchema -class ChatStreamCompletionCreateParamsTypeJSONObject(str, Enum): - JSON_OBJECT = "json_object" +ChatStreamCompletionCreateParamsTypeJSONObject = Literal["json_object"] class ChatStreamCompletionCreateParamsResponseFormatJSONObjectTypedDict(TypedDict): @@ -223,8 +213,7 @@ class ChatStreamCompletionCreateParamsResponseFormatJSONObject(BaseModel): type: ChatStreamCompletionCreateParamsTypeJSONObject -class ChatStreamCompletionCreateParamsTypeText(str, Enum): - TEXT = "text" +ChatStreamCompletionCreateParamsTypeText = Literal["text"] class ChatStreamCompletionCreateParamsResponseFormatTextTypedDict(TypedDict): @@ -291,106 +280,98 @@ class ChatStreamCompletionCreateParamsStreamOptions(BaseModel): r"""Include usage information in streaming response""" -class ChatStreamCompletionCreateParamsReasoningEffort(str, Enum): - r"""Reasoning effort""" +ChatStreamCompletionCreateParamsReasoningEffort = Literal[ + "high", "medium", "low", "minimal" +] +r"""Reasoning effort""" - HIGH = "high" - MEDIUM = "medium" - LOW = "low" - MINIMAL = "minimal" +ChatStreamCompletionCreateParamsDataCollection = Literal["deny", "allow"] +r"""Data collection setting. If no available model provider meets the requirement, your request will return an error. +- allow: (default) allow providers which store user data non-transiently and may train on it +- deny: use only providers which do not collect user data. +""" -class ChatStreamCompletionCreateParamsDataCollection(str, Enum): - r"""Data collection setting. If no available model provider meets the requirement, your request will return an error. - - allow: (default) allow providers which store user data non-transiently and may train on it - - deny: use only providers which do not collect user data. - - """ - - DENY = "deny" - ALLOW = "allow" - - -class ChatStreamCompletionCreateParamsOrderEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatStreamCompletionCreateParamsOrderEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatStreamCompletionCreateParamsOrderUnionTypedDict = TypeAliasType( "ChatStreamCompletionCreateParamsOrderUnionTypedDict", @@ -404,86 +385,86 @@ ChatStreamCompletionCreateParamsOrderUnion = TypeAliasType( ) -class ChatStreamCompletionCreateParamsOnlyEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatStreamCompletionCreateParamsOnlyEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatStreamCompletionCreateParamsOnlyUnionTypedDict = TypeAliasType( "ChatStreamCompletionCreateParamsOnlyUnionTypedDict", @@ -497,86 +478,86 @@ ChatStreamCompletionCreateParamsOnlyUnion = TypeAliasType( ) -class ChatStreamCompletionCreateParamsIgnoreEnum(str, Enum): - ANY_SCALE = "AnyScale" - CENT_ML = "Cent-ML" - HUGGING_FACE = "HuggingFace" - HYPERBOLIC_2 = "Hyperbolic 2" - LEPTON = "Lepton" - LYNN_2 = "Lynn 2" - LYNN = "Lynn" - MANCER = "Mancer" - MODAL = "Modal" - OCTO_AI = "OctoAI" - RECURSAL = "Recursal" - REFLECTION = "Reflection" - REPLICATE = "Replicate" - SAMBA_NOVA_2 = "SambaNova 2" - SF_COMPUTE = "SF Compute" - TOGETHER_2 = "Together 2" - ONE_DOT_AI = "01.AI" - AI21 = "AI21" - AION_LABS = "AionLabs" - ALIBABA = "Alibaba" - AMAZON_BEDROCK = "Amazon Bedrock" - ANTHROPIC = "Anthropic" - ATLAS_CLOUD = "AtlasCloud" - ATOMA = "Atoma" - AVIAN = "Avian" - AZURE = "Azure" - BASE_TEN = "BaseTen" - CEREBRAS = "Cerebras" - CHUTES = "Chutes" - CLOUDFLARE = "Cloudflare" - COHERE = "Cohere" - CROF_AI = "CrofAI" - CRUSOE = "Crusoe" - DEEP_INFRA = "DeepInfra" - DEEP_SEEK = "DeepSeek" - ENFER = "Enfer" - FEATHERLESS = "Featherless" - FIREWORKS = "Fireworks" - FRIENDLI = "Friendli" - GMI_CLOUD = "GMICloud" - GOOGLE = "Google" - GOOGLE_AI_STUDIO = "Google AI Studio" - GROQ = "Groq" - HYPERBOLIC = "Hyperbolic" - INCEPTION = "Inception" - INFERENCE_NET = "InferenceNet" - INFERMATIC = "Infermatic" - INFLECTION = "Inflection" - INO_CLOUD = "InoCloud" - KLUSTER = "Kluster" - LAMBDA = "Lambda" - LIQUID = "Liquid" - MANCER_2 = "Mancer 2" - META = "Meta" - MINIMAX = "Minimax" - MISTRAL = "Mistral" - MOONSHOT_AI = "Moonshot AI" - MORPH = "Morph" - N_COMPASS = "NCompass" - NEBIUS = "Nebius" - NEXT_BIT = "NextBit" - NINETEEN = "Nineteen" - NOVITA = "Novita" - OPEN_AI = "OpenAI" - OPEN_INFERENCE = "OpenInference" - PARASAIL = "Parasail" - PERPLEXITY = "Perplexity" - PHALA = "Phala" - SAMBA_NOVA = "SambaNova" - STEALTH = "Stealth" - SWITCHPOINT = "Switchpoint" - TARGON = "Targon" - TOGETHER = "Together" - UBICLOUD = "Ubicloud" - VENICE = "Venice" - WAND_B = "WandB" - X_AI = "xAI" - Z_AI = "Z.AI" - +ChatStreamCompletionCreateParamsIgnoreEnum = Literal[ + "AnyScale", + "Cent-ML", + "HuggingFace", + "Hyperbolic 2", + "Lepton", + "Lynn 2", + "Lynn", + "Mancer", + "Modal", + "OctoAI", + "Recursal", + "Reflection", + "Replicate", + "SambaNova 2", + "SF Compute", + "Together 2", + "01.AI", + "AI21", + "AionLabs", + "Alibaba", + "Amazon Bedrock", + "Anthropic", + "AtlasCloud", + "Atoma", + "Avian", + "Azure", + "BaseTen", + "Cerebras", + "Chutes", + "Cloudflare", + "Cohere", + "CrofAI", + "Crusoe", + "DeepInfra", + "DeepSeek", + "Enfer", + "Featherless", + "Fireworks", + "Friendli", + "GMICloud", + "Google", + "Google AI Studio", + "Groq", + "Hyperbolic", + "Inception", + "InferenceNet", + "Infermatic", + "Inflection", + "InoCloud", + "Kluster", + "Lambda", + "Liquid", + "Mancer 2", + "Meta", + "Minimax", + "Mistral", + "Moonshot AI", + "Morph", + "NCompass", + "Nebius", + "NextBit", + "Nineteen", + "Novita", + "OpenAI", + "OpenInference", + "Parasail", + "Perplexity", + "Phala", + "SambaNova", + "Stealth", + "Switchpoint", + "Targon", + "Together", + "Ubicloud", + "Venice", + "WandB", + "xAI", + "Z.AI", +] ChatStreamCompletionCreateParamsIgnoreUnionTypedDict = TypeAliasType( "ChatStreamCompletionCreateParamsIgnoreUnionTypedDict", @@ -590,25 +571,12 @@ ChatStreamCompletionCreateParamsIgnoreUnion = TypeAliasType( ) -class ChatStreamCompletionCreateParamsQuantization(str, Enum): - INT4 = "int4" - INT8 = "int8" - FP4 = "fp4" - FP6 = "fp6" - FP8 = "fp8" - FP16 = "fp16" - BF16 = "bf16" - FP32 = "fp32" - UNKNOWN = "unknown" - - -class ChatStreamCompletionCreateParamsSort(str, Enum): - r"""The sorting strategy to use for this request, if \"order\" is not specified. When set, no load balancing is performed.""" - - PRICE = "price" - THROUGHPUT = "throughput" - LATENCY = "latency" +ChatStreamCompletionCreateParamsQuantization = Literal[ + "int4", "int8", "fp4", "fp6", "fp8", "fp16", "bf16", "fp32", "unknown" +] +ChatStreamCompletionCreateParamsSort = Literal["price", "throughput", "latency"] +r"""The sorting strategy to use for this request, if \"order\" is not specified. When set, no load balancing is performed.""" ChatStreamCompletionCreateParamsPromptTypedDict = TypeAliasType( "ChatStreamCompletionCreateParamsPromptTypedDict", Union[float, str, Any] @@ -817,14 +785,9 @@ class ChatStreamCompletionCreateParamsProvider(BaseModel): return m -class ChatStreamCompletionCreateParamsIDFileParser(str, Enum): - FILE_PARSER = "file-parser" +ChatStreamCompletionCreateParamsIDFileParser = Literal["file-parser"] - -class ChatStreamCompletionCreateParamsPdfEngine(str, Enum): - MISTRAL_OCR = "mistral-ocr" - PDF_TEXT = "pdf-text" - NATIVE = "native" +ChatStreamCompletionCreateParamsPdfEngine = Literal["mistral-ocr", "pdf-text", "native"] class ChatStreamCompletionCreateParamsPdfTypedDict(TypedDict): @@ -849,8 +812,7 @@ class ChatStreamCompletionCreateParamsPluginFileParser(BaseModel): pdf: Optional[ChatStreamCompletionCreateParamsPdf] = None -class ChatStreamCompletionCreateParamsIDChainOfThought(str, Enum): - CHAIN_OF_THOUGHT = "chain-of-thought" +ChatStreamCompletionCreateParamsIDChainOfThought = Literal["chain-of-thought"] class ChatStreamCompletionCreateParamsPluginChainOfThoughtTypedDict(TypedDict): @@ -861,13 +823,9 @@ class ChatStreamCompletionCreateParamsPluginChainOfThought(BaseModel): id: ChatStreamCompletionCreateParamsIDChainOfThought -class ChatStreamCompletionCreateParamsIDWeb(str, Enum): - WEB = "web" +ChatStreamCompletionCreateParamsIDWeb = Literal["web"] - -class ChatStreamCompletionCreateParamsEngine(str, Enum): - NATIVE = "native" - EXA = "exa" +ChatStreamCompletionCreateParamsEngine = Literal["native", "exa"] class ChatStreamCompletionCreateParamsPluginWebTypedDict(TypedDict): @@ -887,8 +845,7 @@ class ChatStreamCompletionCreateParamsPluginWeb(BaseModel): engine: Optional[ChatStreamCompletionCreateParamsEngine] = None -class ChatStreamCompletionCreateParamsIDModeration(str, Enum): - MODERATION = "moderation" +ChatStreamCompletionCreateParamsIDModeration = Literal["moderation"] class ChatStreamCompletionCreateParamsPluginModerationTypedDict(TypedDict): @@ -969,7 +926,7 @@ class ChatStreamCompletionCreateParamsTypedDict(TypedDict): r"""Nucleus sampling parameter (0-1)""" user: NotRequired[str] r"""Unique user identifier""" - models_llm: NotRequired[Nullable[List[str]]] + fallback_models: NotRequired[Nullable[List[str]]] r"""Order of models to fallback to for this request""" reasoning_effort: NotRequired[ Nullable[ChatStreamCompletionCreateParamsReasoningEffort] @@ -1050,7 +1007,7 @@ class ChatStreamCompletionCreateParams(BaseModel): user: Optional[str] = None r"""Unique user identifier""" - models_llm: Annotated[ + fallback_models: Annotated[ OptionalNullable[List[str]], pydantic.Field(alias="models") ] = UNSET r"""Order of models to fallback to for this request""" @@ -1089,7 +1046,7 @@ class ChatStreamCompletionCreateParams(BaseModel): "tools", "top_p", "user", - "models_llm", + "fallback_models", "reasoning_effort", "provider", "plugins", @@ -1108,7 +1065,7 @@ class ChatStreamCompletionCreateParams(BaseModel): "stream_options", "temperature", "top_p", - "models_llm", + "fallback_models", "reasoning_effort", "provider", ] diff --git a/src/openrouter/models/fileannotationdetail.py b/src/openrouter/models/fileannotationdetail.py index a255f7d..ea1660e 100644 --- a/src/openrouter/models/fileannotationdetail.py +++ b/src/openrouter/models/fileannotationdetail.py @@ -1,18 +1,14 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel -from typing import List, Optional, Union +from typing import List, Literal, Optional, Union from typing_extensions import NotRequired, TypeAliasType, TypedDict -class TypeFile(str, Enum): - FILE = "file" +TypeFile = Literal["file"] - -class ContentTypeImageURL(str, Enum): - IMAGE_URL = "image_url" +ContentTypeImageURL = Literal["image_url"] class FileAnnotationDetailImageURLTypedDict(TypedDict): @@ -34,8 +30,7 @@ class ContentImageURL(BaseModel): image_url: FileAnnotationDetailImageURL -class ContentTypeText(str, Enum): - TEXT = "text" +ContentTypeText = Literal["text"] class ContentTextTypedDict(TypedDict): diff --git a/src/openrouter/models/reasoningdetailencrypted.py b/src/openrouter/models/reasoningdetailencrypted.py index 4008622..d17bd47 100644 --- a/src/openrouter/models/reasoningdetailencrypted.py +++ b/src/openrouter/models/reasoningdetailencrypted.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -11,18 +10,15 @@ from openrouter.types import ( ) import pydantic from pydantic import model_serializer -from typing import Optional +from typing import Literal, Optional from typing_extensions import Annotated, NotRequired, TypedDict -class ReasoningDetailEncryptedType(str, Enum): - REASONING_ENCRYPTED = "reasoning.encrypted" +ReasoningDetailEncryptedType = Literal["reasoning.encrypted"] - -class ReasoningDetailEncryptedFormat(str, Enum): - UNKNOWN = "unknown" - OPENAI_RESPONSES_V1 = "openai-responses-v1" - ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1" +ReasoningDetailEncryptedFormat = Literal[ + "unknown", "openai-responses-v1", "anthropic-claude-v1" +] class ReasoningDetailEncryptedTypedDict(TypedDict): @@ -46,7 +42,7 @@ class ReasoningDetailEncrypted(BaseModel): format_: Annotated[ OptionalNullable[ReasoningDetailEncryptedFormat], pydantic.Field(alias="format") - ] = ReasoningDetailEncryptedFormat.ANTHROPIC_CLAUDE_V1 + ] = "anthropic-claude-v1" index: Optional[float] = None diff --git a/src/openrouter/models/reasoningdetailsummary.py b/src/openrouter/models/reasoningdetailsummary.py index 03faaaf..ac2c376 100644 --- a/src/openrouter/models/reasoningdetailsummary.py +++ b/src/openrouter/models/reasoningdetailsummary.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -11,18 +10,15 @@ from openrouter.types import ( ) import pydantic from pydantic import model_serializer -from typing import Optional +from typing import Literal, Optional from typing_extensions import Annotated, NotRequired, TypedDict -class ReasoningDetailSummaryType(str, Enum): - REASONING_SUMMARY = "reasoning.summary" +ReasoningDetailSummaryType = Literal["reasoning.summary"] - -class ReasoningDetailSummaryFormat(str, Enum): - UNKNOWN = "unknown" - OPENAI_RESPONSES_V1 = "openai-responses-v1" - ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1" +ReasoningDetailSummaryFormat = Literal[ + "unknown", "openai-responses-v1", "anthropic-claude-v1" +] class ReasoningDetailSummaryTypedDict(TypedDict): @@ -46,7 +42,7 @@ class ReasoningDetailSummary(BaseModel): format_: Annotated[ OptionalNullable[ReasoningDetailSummaryFormat], pydantic.Field(alias="format") - ] = ReasoningDetailSummaryFormat.ANTHROPIC_CLAUDE_V1 + ] = "anthropic-claude-v1" index: Optional[float] = None diff --git a/src/openrouter/models/reasoningdetailtext.py b/src/openrouter/models/reasoningdetailtext.py index acecee1..f1beee6 100644 --- a/src/openrouter/models/reasoningdetailtext.py +++ b/src/openrouter/models/reasoningdetailtext.py @@ -1,7 +1,6 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import ( BaseModel, Nullable, @@ -11,18 +10,15 @@ from openrouter.types import ( ) import pydantic from pydantic import model_serializer -from typing import Optional +from typing import Literal, Optional from typing_extensions import Annotated, NotRequired, TypedDict -class ReasoningDetailTextType(str, Enum): - REASONING_TEXT = "reasoning.text" +ReasoningDetailTextType = Literal["reasoning.text"] - -class ReasoningDetailTextFormat(str, Enum): - UNKNOWN = "unknown" - OPENAI_RESPONSES_V1 = "openai-responses-v1" - ANTHROPIC_CLAUDE_V1 = "anthropic-claude-v1" +ReasoningDetailTextFormat = Literal[ + "unknown", "openai-responses-v1", "anthropic-claude-v1" +] class ReasoningDetailTextTypedDict(TypedDict): @@ -49,7 +45,7 @@ class ReasoningDetailText(BaseModel): format_: Annotated[ OptionalNullable[ReasoningDetailTextFormat], pydantic.Field(alias="format") - ] = ReasoningDetailTextFormat.ANTHROPIC_CLAUDE_V1 + ] = "anthropic-claude-v1" index: Optional[float] = None diff --git a/src/openrouter/models/security.py b/src/openrouter/models/security.py index 6a22017..1870d08 100644 --- a/src/openrouter/models/security.py +++ b/src/openrouter/models/security.py @@ -8,11 +8,11 @@ from typing_extensions import Annotated, NotRequired, TypedDict class SecurityTypedDict(TypedDict): - bearer_auth: NotRequired[str] + api_key: NotRequired[str] class Security(BaseModel): - bearer_auth: Annotated[ + api_key: Annotated[ Optional[str], FieldMetadata( security=SecurityMetadata( diff --git a/src/openrouter/models/urlcitationannotationdetail.py b/src/openrouter/models/urlcitationannotationdetail.py index 76bd092..09d30f7 100644 --- a/src/openrouter/models/urlcitationannotationdetail.py +++ b/src/openrouter/models/urlcitationannotationdetail.py @@ -1,14 +1,12 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from enum import Enum from openrouter.types import BaseModel -from typing import Optional +from typing import Literal, Optional from typing_extensions import NotRequired, TypedDict -class URLCitationAnnotationDetailType(str, Enum): - URL_CITATION = "url_citation" +URLCitationAnnotationDetailType = Literal["url_citation"] class URLCitationTypedDict(TypedDict): diff --git a/src/openrouter/sdk.py b/src/openrouter/sdk.py index 0c3ad16..ac72867 100644 --- a/src/openrouter/sdk.py +++ b/src/openrouter/sdk.py @@ -10,6 +10,7 @@ import importlib from openrouter import models, utils from openrouter._hooks import SDKHooks from openrouter.types import OptionalNullable, UNSET +import sys from typing import Any, Callable, Dict, List, Optional, TYPE_CHECKING, Union, cast import weakref @@ -30,7 +31,7 @@ class OpenRouter(BaseSDK): def __init__( self, - bearer_auth: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None, + api_key: Optional[Union[Optional[str], Callable[[], Optional[str]]]] = None, provider_url: Optional[str] = None, server_idx: Optional[int] = None, server_url: Optional[str] = None, @@ -43,7 +44,7 @@ class OpenRouter(BaseSDK): ) -> None: r"""Instantiates the SDK configuring it with the provided parameters. - :param bearer_auth: The bearer_auth required for authentication + :param api_key: The api_key required for authentication :param provider_url: Allows setting the provider_url variable for url substitution :param server_idx: The index of the server to use for all methods :param server_url: The server URL to use for all methods @@ -75,11 +76,11 @@ class OpenRouter(BaseSDK): ), "The provided async_client must implement the AsyncHttpClient protocol." security: Any = None - if callable(bearer_auth): + if callable(api_key): # pylint: disable=unnecessary-lambda-assignment - security = lambda: models.Security(bearer_auth=bearer_auth()) + security = lambda: models.Security(api_key=api_key()) else: - security = models.Security(bearer_auth=bearer_auth) + security = models.Security(api_key=api_key) if server_url is not None: if url_params is not None: @@ -105,6 +106,7 @@ class OpenRouter(BaseSDK): timeout_ms=timeout_ms, debug_logger=debug_logger, ), + parent_ref=self, ) hooks = SDKHooks() @@ -124,13 +126,24 @@ class OpenRouter(BaseSDK): self.sdk_configuration.async_client_supplied, ) + def dynamic_import(self, modname, retries=3): + for attempt in range(retries): + try: + return importlib.import_module(modname) + except KeyError: + # Clear any half-initialized module and retry + sys.modules.pop(modname, None) + if attempt == retries - 1: + break + raise KeyError(f"Failed to import module '{modname}' after {retries} attempts") + def __getattr__(self, name: str): if name in self._sub_sdk_map: module_path, class_name = self._sub_sdk_map[name] try: - module = importlib.import_module(module_path) + module = self.dynamic_import(module_path) klass = getattr(module, class_name) - instance = klass(self.sdk_configuration) + instance = klass(self.sdk_configuration, parent_ref=self) setattr(self, name, instance) return instance except ImportError as e: diff --git a/src/openrouter/utils/__init__.py b/src/openrouter/utils/__init__.py index 5c2c9c2..87192dd 100644 --- a/src/openrouter/utils/__init__.py +++ b/src/openrouter/utils/__init__.py @@ -3,6 +3,7 @@ from typing import TYPE_CHECKING from importlib import import_module import builtins +import sys if TYPE_CHECKING: from .annotations import get_discriminator @@ -162,6 +163,18 @@ _dynamic_imports: dict[str, str] = { } +def dynamic_import(modname, retries=3): + for attempt in range(retries): + try: + return import_module(modname, __package__) + except KeyError: + # Clear any half-initialized module and retry + sys.modules.pop(modname, None) + if attempt == retries - 1: + break + raise KeyError(f"Failed to import module '{modname}' after {retries} attempts") + + def __getattr__(attr_name: str) -> object: module_name = _dynamic_imports.get(attr_name) if module_name is None: @@ -170,9 +183,8 @@ def __getattr__(attr_name: str) -> object: ) try: - module = import_module(module_name, __package__) - result = getattr(module, attr_name) - return result + module = dynamic_import(module_name) + return getattr(module, attr_name) except ImportError as e: raise ImportError( f"Failed to import {attr_name} from {module_name}: {e}" diff --git a/src/openrouter/utils/eventstreaming.py b/src/openrouter/utils/eventstreaming.py index 74a63f7..0969899 100644 --- a/src/openrouter/utils/eventstreaming.py +++ b/src/openrouter/utils/eventstreaming.py @@ -17,6 +17,9 @@ T = TypeVar("T") class EventStream(Generic[T]): + # Holds a reference to the SDK client to avoid it being garbage collected + # and cause termination of the underlying httpx client. + client_ref: Optional[object] response: httpx.Response generator: Generator[T, None, None] @@ -25,9 +28,11 @@ class EventStream(Generic[T]): response: httpx.Response, decoder: Callable[[str], T], sentinel: Optional[str] = None, + client_ref: Optional[object] = None, ): self.response = response self.generator = stream_events(response, decoder, sentinel) + self.client_ref = client_ref def __iter__(self): return self @@ -43,6 +48,9 @@ class EventStream(Generic[T]): class EventStreamAsync(Generic[T]): + # Holds a reference to the SDK client to avoid it being garbage collected + # and cause termination of the underlying httpx client. + client_ref: Optional[object] response: httpx.Response generator: AsyncGenerator[T, None] @@ -51,9 +59,11 @@ class EventStreamAsync(Generic[T]): response: httpx.Response, decoder: Callable[[str], T], sentinel: Optional[str] = None, + client_ref: Optional[object] = None, ): self.response = response self.generator = stream_events_async(response, decoder, sentinel) + self.client_ref = client_ref def __aiter__(self): return self diff --git a/src/openrouter/utils/security.py b/src/openrouter/utils/security.py index 8db6ee7..6996c79 100644 --- a/src/openrouter/utils/security.py +++ b/src/openrouter/utils/security.py @@ -64,8 +64,8 @@ def get_security_from_env(security: Any, security_class: Any) -> Optional[BaseMo security_dict: Any = {} - if os.getenv("OPENROUTER_BEARER_AUTH"): - security_dict["bearer_auth"] = os.getenv("OPENROUTER_BEARER_AUTH") + if os.getenv("OPENROUTER_API_KEY"): + security_dict["api_key"] = os.getenv("OPENROUTER_API_KEY") return security_class(**security_dict) if security_dict else None diff --git a/uv.lock b/uv.lock index 204557b..431c396 100644 --- a/uv.lock +++ b/uv.lock @@ -201,7 +201,7 @@ wheels = [ [[package]] name = "openrouter" -version = "0.1.3" +version = "0.5.2" source = { editable = "." } dependencies = [ { name = "httpcore" },