diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index b2c9ba4e..930764ec 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,19 +1,19 @@ lockVersion: 2.0.0 id: c48cf606-fb42-4a45-9c23-8f0555307828 management: - docChecksum: a0be6866e415062274038e3ba19c0f0d + docChecksum: 54f6a56b3ce0196f24d04d18f37ab80a docVersion: 1.0.0 speakeasyVersion: 1.803.2 generationVersion: 2.950.13 - releaseVersion: 1.3.103 - configChecksum: 9ca83bdb4d50a73dd7dc11da2a5485ea + releaseVersion: 1.3.104 + configChecksum: 1787fee2bed548acbc21c5c6887d812c repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 8cb2aeac-f03b-457f-aa3c-90eac8824e0b - pristine_commit_hash: ec03155fe6ece2bb076a44f5d42d993158d04920 - pristine_tree_hash: 1e4e1550f89b80c07082c5a4d5caa19729a8a0e8 + generation_id: 5f665d48-31fb-43ff-b17b-1f44c8e03e26 + pristine_commit_hash: 654fce46a3afc67527b658404a7a088531cfc0ca + pristine_tree_hash: 54a0e2a6d89cfb8fa5c0985bb8dd617f4051f6cd features: python: acceptHeaders: 3.0.0 @@ -6826,6 +6826,10 @@ trackedFiles: id: ffd85d9fcc2c last_write_checksum: sha1:78e406250f9bb607250b74952d4ac7c816bbf7ac pristine_git_object: 523d50326413b82c2b177810f9316f6a29967f94 + docs/components/publiczdrendpoint.mdx: + id: a7b6fd35cd0a + last_write_checksum: sha1:07a130c7902c3c1b307d88d5698930d8570a46a6 + pristine_git_object: 1802fa7faa8ebcace9e0c43d9c5a8898da7275e2 docs/components/purpose.mdx: id: ae295e1d0077 last_write_checksum: sha1:0254976b545dce44c49a9bff2cdfbe687d5fe749 @@ -9900,8 +9904,8 @@ trackedFiles: pristine_git_object: 6f5e7d90f806137d65995f761ab2abdad34381dd docs/operations/listendpointszdrresponse.mdx: id: f8d0c52ac714 - last_write_checksum: sha1:104c6b7cfef65c362d39c30171a0c000ea9538ea - pristine_git_object: 5fc4002e0eb789a99d53328fd768ca4165011701 + last_write_checksum: sha1:c77f5cff2fcd665fc1c804ebcde505a71b67245a + pristine_git_object: 574db8c80c3b9433ea0c4c49133c9d8eae0e6552 docs/operations/listexternalusersglobals.mdx: id: 3e2e62682167 last_write_checksum: sha1:2d313c9d85897161bfc07e3690dd62a48a7b5b28 @@ -10764,8 +10768,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:a47cc255adc52a027c04fdd7296b4bd5b6ac8c18 - pristine_git_object: b80981b1939d111c80f7f03b19c31d09cf70ff6c + last_write_checksum: sha1:80d96447577f36c39ac5a430102b74ec23bd727c + pristine_git_object: 1d7d2dd2e33c2cc456254bd409c6602682a6b16c scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -10792,8 +10796,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:2944b4b1cc6add8381f856b0799c35f709502c3c - pristine_git_object: 60a67b362ef4ba8c3c8ea646460a659482e7748d + last_write_checksum: sha1:893c7d1fb3156ec74b7aaaeb8c3f79b7a4df9568 + pristine_git_object: 7c705ab99672990ae84fdafb09e65b2196e8bc4c src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766 @@ -10840,8 +10844,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:56a6747e365c4882056dd693cabb01a7ad9724ff - pristine_git_object: f74ec63ffe931137169b5c7032aa04075a77bff8 + last_write_checksum: sha1:0306d5fda8ea78f931eacbd7e470ca26b626f5e8 + pristine_git_object: 47676c451dd3c8bd1af0e2864b65641ea1f7c3ab src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -12042,6 +12046,10 @@ trackedFiles: id: 5ecad6212326 last_write_checksum: sha1:53ae856232196a956d66c6363cdaedc9f8abfe3a pristine_git_object: 07e98d54e6a63a4f1e0908b73ce5f8d7e16234f0 + src/openrouter/components/decisions.py: + id: 5d8a5ee323e1 + last_write_checksum: sha1:cfa3429f0fb6d5ef8fcf554d880df7d3e6bbdc4c + pristine_git_object: 6c5a910e6d35cbfc3fe6aa18599837d3a9232ecf src/openrouter/components/decisionsboxanswer.py: id: 59a9ef1c30b7 last_write_checksum: sha1:301ee5be0345940b0f210f797e19e537e0f8126e @@ -12146,6 +12154,10 @@ trackedFiles: id: dc53aae5b171 last_write_checksum: sha1:44373dac3bf06bd752f0c54122949a024f70d3b5 pristine_git_object: 43ddb3328699a301a8948743ac0ead4a4a8ec776 + src/openrouter/components/embeddings.py: + id: 81553b79cc50 + last_write_checksum: sha1:f952180280fef71fe3fac4e41ba122af3b931f12 + pristine_git_object: ade9cf4cc5e9473f422f8d873b30bb44e0d273b0 src/openrouter/components/endpointinfo.py: id: ce049670b5ae last_write_checksum: sha1:914f173c73fe1035e56c9acf4ad9e23555bde95a @@ -12526,6 +12538,10 @@ trackedFiles: id: 7a791a02cb5b last_write_checksum: sha1:497f9be381527fd1ee961450a2364a898dba875b pristine_git_object: 6b9a8990973466285f9b49b366bbc5fc1ae42e41 + src/openrouter/components/imagegeneration.py: + id: 8a20a323529f + last_write_checksum: sha1:d86d0852fbda96fa56ee456e38b0f912c9e96132 + pristine_git_object: fe042dd889e2f17d642f19b0d596cb3e53a7fce2 src/openrouter/components/imagegenerationproviderpreferences.py: id: 100a82a54e2d last_write_checksum: sha1:dc7720fb18eb12dab9ff6e599d31f08c0b196e43 @@ -12902,6 +12918,10 @@ trackedFiles: id: d8236926ce4d last_write_checksum: sha1:fa3012e6809aa0e6d5b94bddb3bd016f29f5b35e pristine_git_object: c0f3bdf2b16b3a90399ef94d1cfbd3bdc7afe0be + src/openrouter/components/nativetools.py: + id: 248c6827f778 + last_write_checksum: sha1:e0f9801526bb8c3dd9245a4fc2a68e29f4762a02 + pristine_git_object: 8afefba911b3d7f74ec76de3aa7bc69b6e7c7ec2 src/openrouter/components/notfoundresponseerrordata.py: id: 6ebceef7a039 last_write_checksum: sha1:bc01cbf5e3da855698de435b270930b4087377fe @@ -13354,6 +13374,10 @@ trackedFiles: id: 652397163aaa last_write_checksum: sha1:a97289b7fd364d4d4d55eaceb452ec0891e97359 pristine_git_object: d4fad42e2a9de3a69093e54375086c2e23854ee0 + src/openrouter/components/perflast30mbyworkload.py: + id: c577beb06381 + last_write_checksum: sha1:b5d22f0aae68222d51270213f2726083be515ede + pristine_git_object: 98d5725c977ffb944f7f649e61ab86c3e96bbcf8 src/openrouter/components/perrequestlimits.py: id: 5a170d7d1f2e last_write_checksum: sha1:9b269bd87a1f704a0f0fa731da57cb35bc960674 @@ -13410,6 +13434,10 @@ trackedFiles: id: 40414eada27a last_write_checksum: sha1:0e241830bf9014e8ea814465c573711d8a7caa2c pristine_git_object: 90bdb267893360608210843a5da0d5d68e80d41e + src/openrouter/components/pricing.py: + id: 33122e4b4dda + last_write_checksum: sha1:0f5b42e8b080ee41e906f4d920958ea5c498f2b7 + pristine_git_object: de6dc2a054ce1e1cb41c32a17c390e6999eee242 src/openrouter/components/pricingoverride.py: id: 8984e4cc7422 last_write_checksum: sha1:e12629320e02396a2aa1dfcbacd6873fba0d4aba @@ -13532,8 +13560,8 @@ trackedFiles: pristine_git_object: 1798ae9dd8c2e4b629bb99cc5c643827895e8231 src/openrouter/components/publicendpoint.py: id: 848aa2ef9129 - last_write_checksum: sha1:db4e23bf4cda6a1829228c83e13d2645f9dd0325 - pristine_git_object: 60cb7bb398758f1f20e19e006ecbb22c537555d9 + last_write_checksum: sha1:24c17812df5c49d3491117fe1c215c47aef83c73 + pristine_git_object: 75eb8e640f7faf5486520c19b5fb131c44255306 src/openrouter/components/publicpricing.py: id: 96d115d83cc5 last_write_checksum: sha1:fd8c320ac83b282eaf2405045329b55076d4311a @@ -13542,6 +13570,10 @@ trackedFiles: id: fc0a585024d6 last_write_checksum: sha1:a9d1074d4ce5c1fcb4cd2fb1ba593458d9174e5e pristine_git_object: 280a4f38f716950fdf00b966409cef5a37d3d6b6 + src/openrouter/components/publiczdrendpoint.py: + id: 96f5b682772d + last_write_checksum: sha1:b61dd30ae315ff73c1173295465ac8518c552fc0 + pristine_git_object: ab5747e096bd23add5166d02c20d12026ca9a2bb src/openrouter/components/quantization.py: id: bde317b3d703 last_write_checksum: sha1:cc9c8d954733d128b53938fbc403bf97b064c09c @@ -13650,6 +13682,10 @@ trackedFiles: id: 2c5f5ceaf22d last_write_checksum: sha1:ec9cf781e7744b582843bdc74f93003e1c19f8a8 pristine_git_object: 72b068484474cb51c64619e8bdbda4c77b64b5f3 + src/openrouter/components/rerank.py: + id: ce0c58ad6b3f + last_write_checksum: sha1:a2abdafd0a7fa4e9845a0156f7b7aacf9fc0e045 + pristine_git_object: e3740a8f28bfe73603bdae2b32153e8188c059ea src/openrouter/components/responsehealingplugin.py: id: 06608e027868 last_write_checksum: sha1:f4ee2caaa09379c52353f8920109f5e3e95f2274 @@ -13918,6 +13954,10 @@ trackedFiles: id: e39bb8998edb last_write_checksum: sha1:aae5b69a7dc7ced3af224d28b6ab485ad33ff2ef pristine_git_object: 79b6d3487431628f261a66e552bd97668ded59a2 + src/openrouter/components/stt.py: + id: 3552839c1a7e + last_write_checksum: sha1:ad5afe645af4f978313b3bd7d801781864903473 + pristine_git_object: 2b0b14c1888a013b2d4afa3dda5c800fcfd760aa src/openrouter/components/sttentity.py: id: a0df8a8395ea last_write_checksum: sha1:1acd9736217b336bd5e87f21401cd733b74585a9 @@ -14014,6 +14054,10 @@ trackedFiles: id: 150a449e46de last_write_checksum: sha1:56b0dc5aaacd994dfa1f16900a4fe1b4eea2f222 pristine_git_object: ffae73647f1060eeb9f46a4d331de6b9760dc5d9 + src/openrouter/components/textgeneration.py: + id: 106a3b45e8ae + last_write_checksum: sha1:0e772f19c60d964f24ba3802431e57c548e7311b + pristine_git_object: 7b2f1c41bf7bb32cc9f2fe854978224f337c2ec8 src/openrouter/components/tokenexchangerequest.py: id: 2359476f8b4b last_write_checksum: sha1:90071f47bf240283f5e58701a2cf8e50fc96f94e @@ -14066,6 +14110,10 @@ trackedFiles: id: 88f4e4be9fc0 last_write_checksum: sha1:69e1f9d19ad27b82d882031c100f8a607344f8af pristine_git_object: 1f8bea3c63592dc738f70d50eac8c69e2e755096 + src/openrouter/components/tts.py: + id: 0f7a05134681 + last_write_checksum: sha1:c91367caf26435698bd7e505a9fe3a08016040d5 + pristine_git_object: 6c89d6bfeb6484b5aac7eafb35bf4e823dad5f74 src/openrouter/components/unauthorizedresponseerrordata.py: id: 7d9755fc8395 last_write_checksum: sha1:fe0c623742ecc4cec29dbae705ca24e5813ccb8f @@ -14102,6 +14150,10 @@ trackedFiles: id: 189239ce6b4f last_write_checksum: sha1:9d85897b7857707fb6a759aaa938f4b5bf5662c2 pristine_git_object: e1b94da161012480960c726a459b3fbd7c1a9bf4 + src/openrouter/components/unknown.py: + id: 7f603dfcda35 + last_write_checksum: sha1:e2a4ba97e9e9c2b710853acbc467284eb38dcc27 + pristine_git_object: b85755f16ed8faf0cc73c8817824f369374844f2 src/openrouter/components/unprocessableentityresponseerrordata.py: id: e8ca4a51f994 last_write_checksum: sha1:e97c277b49f4bb6bcfad8eef8a46b382730729a0 @@ -14226,6 +14278,10 @@ trackedFiles: id: cbb498111508 last_write_checksum: sha1:1b9b952ac06a26237868303362363618c8252f0b pristine_git_object: 70de1bfb3bfb30aaafa4e08251eb7a6cace15be8 + src/openrouter/components/videogeneration.py: + id: 33005645f6fe + last_write_checksum: sha1:d9db0d60d9db6840b086366c6a34c856b845b28f + pristine_git_object: c2f15eb53f14024dfd1e620c52a564bf4682854f src/openrouter/components/videogenerationrequest.py: id: 70e3c9ff288c last_write_checksum: sha1:5a9ecbd49cb4972cffd165ebbc98d6e27bfcf715 @@ -14904,8 +14960,8 @@ trackedFiles: pristine_git_object: 6f25eff59336f48df0ac3c184cd0df135bb1212d src/openrouter/operations/listendpointszdr.py: id: 588bf206e92f - last_write_checksum: sha1:dd1cc08d8779d71a9ad80e0ad764fea72b3fb846 - pristine_git_object: f5bd1f67dc835230e6d282e0500cbf3b5781eab4 + last_write_checksum: sha1:453168ebe0434db364c9ced3c03e84a2c7e39048 + pristine_git_object: 42e3e4915c3f33d5fe6b85029b1082e4ed1a646c src/openrouter/operations/listexternalusers.py: id: 01bd7badf844 last_write_checksum: sha1:05108a63aa626128619f0277f4f61b7c4590ec6a @@ -15567,7 +15623,7 @@ examples: speakeasy-default-list-endpoints-zdr: responses: "200": - application/json: {"data": [{"context_length": 8192, "latency_last_30m": {"p50": 0.25, "p75": 0.35, "p90": 0.48, "p99": 0.85}, "max_completion_tokens": 4096, "max_prompt_tokens": 8192, "model_id": "openai/gpt-4", "model_name": "GPT-4", "name": "OpenAI: GPT-4", "native_tools": {}, "pricing": {"completion": "0.00006", "prompt": "0.00003"}, "provider_name": "OpenAI", "quantization": "fp16", "service_tier": "priority", "supported_parameters": ["temperature", "top_p", "max_tokens"], "supports_diarization": false, "supports_image_reference": false, "supports_implicit_caching": true, "supports_multiple_audio_references": false, "supports_tool_choice": {"auto": true, "function": true, "none": true, "required": true}, "supports_voice_cloning": false, "tag": "openai", "throughput_last_30m": {"p50": 45.2, "p75": 38.5, "p90": 28.3, "p99": 15.1}, "uptime_last_1d": 99.8, "uptime_last_30m": 99.5, "uptime_last_5m": 100}]} + application/json: {"data": [{"context_length": 8192, "latency_last_30m": {"p50": 0.25, "p75": 0.35, "p90": 0.48, "p99": 0.85}, "max_completion_tokens": 4096, "max_prompt_tokens": 8192, "model_id": "openai/gpt-4", "model_name": "GPT-4", "name": "OpenAI: GPT-4", "native_tools": {}, "pricing": {"completion": "0.00006", "prompt": "0.00003"}, "provider_name": "OpenAI", "quantization": "fp16", "service_tier": "priority", "supported_parameters": ["temperature", "top_p", "max_tokens"], "supports_diarization": false, "supports_image_reference": false, "supports_implicit_caching": true, "supports_multiple_audio_references": false, "supports_tool_choice": {"auto": true, "function": true, "none": true, "required": true}, "supports_voice_cloning": false, "tag": "openai", "throughput_last_30m": {"p50": 45.2, "p75": 38.5, "p90": 28.3, "p99": 15.1}, "uptime_last_1d": 99.8, "uptime_last_30m": 99.5, "uptime_last_5m": 100, "safety_retention": false}]} "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} "403": @@ -19818,7 +19874,4 @@ examples: examplesVersion: 1.0.2 releaseNotes: | ## Python SDK Changes: - * `open_router.embeddings.list_models()`: `response.data[].endpoints` **Added** - * `open_router.models.get()`: `response.data.endpoints` **Added** - * `open_router.models.list()`: `response.data[].endpoints` **Added** - * `open_router.models.list_for_user()`: `response.data[].endpoints` **Added** + * `open_router.endpoints.list_zdr_endpoints()`: `response.data[].safety_retention` **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 5043924c..c7aee373 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -37,7 +37,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.103 + version: 1.3.104 additionalDependencies: dev: pytest: '>=8.3' diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 0989d60c..95216b7b 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -11001,6 +11001,26 @@ components: - 'debug' - 'sequence_number' type: 'object' + Decisions: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' DecisionsBoxAnswer: properties: box: @@ -11672,6 +11692,26 @@ components: - 'code' - 'message' type: 'object' + Embeddings: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' EndpointInfo: example: model: 'openai/gpt-4o' @@ -15181,6 +15221,26 @@ components: - 'b64_json' - 'created' type: 'object' + ImageGeneration: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' ImageGenerationProviderPreferences: description: 'Provider routing preferences and provider-specific passthrough configuration.' example: @@ -19994,6 +20054,14 @@ components: - 'description' - 'tools' type: 'object' + NativeTools: + properties: + type: + description: 'The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.' + type: 'string' + required: + - 'type' + type: 'object' NotFoundResponse: description: 'Not Found - Resource does not exist' example: @@ -26366,6 +26434,29 @@ components: - 'number' - 'null' type: 'object' + PerfLast30mByWorkload: + additionalProperties: false + description: 'Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.' + properties: + decisions: + $ref: '#/components/schemas/Decisions' + embeddings: + $ref: '#/components/schemas/Embeddings' + image_generation: + $ref: '#/components/schemas/ImageGeneration' + rerank: + $ref: '#/components/schemas/Rerank' + stt: + $ref: '#/components/schemas/STT' + text_generation: + $ref: '#/components/schemas/TextGeneration' + tts: + $ref: '#/components/schemas/TTS' + unknown: + $ref: '#/components/schemas/Unknown' + video_generation: + $ref: '#/components/schemas/VideoGeneration' + type: 'object' PerRequestLimits: description: 'Per-request token limits' example: @@ -26731,6 +26822,63 @@ components: type: - 'object' - 'null' + Pricing: + properties: + audio: + description: 'Price in USD per audio input token' + type: 'string' + audio_output: + description: 'Price in USD per audio output token' + type: 'string' + completion: + description: 'Price in USD per token for completion (output) generation' + type: 'string' + discount: + description: 'Fractional discount applied to this endpoint''s pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)' + format: 'double' + type: 'number' + image: + description: 'Price in USD per input image' + type: 'string' + image_output: + description: 'Price in USD per output image' + type: 'string' + image_token: + description: 'Price in USD per image token' + type: 'string' + input_audio_cache: + description: 'Price in USD per cached audio input token' + type: 'string' + input_cache_read: + description: 'Price in USD per cached input token (read)' + type: 'string' + input_cache_write: + description: 'Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.' + type: 'string' + input_cache_write_1h: + description: 'Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.' + type: 'string' + internal_reasoning: + description: 'Price in USD per internal reasoning token' + type: 'string' + overrides: + description: 'Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.' + items: + $ref: '#/components/schemas/PricingOverride' + type: 'array' + prompt: + description: 'Price in USD per token for prompt (input) processing' + type: 'string' + request: + description: 'Price in USD per request' + type: 'string' + web_search: + description: 'Price in USD per web search' + type: 'string' + required: + - 'prompt' + - 'completion' + type: 'object' PricingOverride: description: 'A conditional override of the base pricing. An entry applies only when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per price key; price keys absent from an entry inherit the base price.' example: @@ -28609,260 +28757,16 @@ components: type: 'string' native_tools: additionalProperties: - properties: - type: - description: 'The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.' - type: 'string' - required: - - 'type' - type: 'object' + $ref: '#/components/schemas/NativeTools' description: 'The server tools this endpoint accepts as the provider''s own built-in tool (`engine: "native"`) instead of an OpenRouter engine, keyed by canonical `openrouter:*` name. Each value names the provider tool type the request is translated to. Where that tool runs (provider-side, or returned to the client as with Anthropic bash) is documented per tool. Empty when the provider has none.' example: openrouter:web_search: type: 'web_search_20260209' type: 'object' perf_last_30m_by_workload: - additionalProperties: false - description: 'Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.' - properties: - decisions: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - embeddings: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - image_generation: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - rerank: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - stt: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - text_generation: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - tts: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - unknown: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - video_generation: - properties: - latency: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' - request_count: - description: 'Total requests admitted for this workload in the window.' - type: - - 'integer' - - 'null' - throughput: - allOf: - - $ref: '#/components/schemas/PercentileStats' - - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' - required: - - 'latency' - - 'throughput' - - 'request_count' - type: 'object' - type: 'object' + $ref: '#/components/schemas/PerfLast30mByWorkload' pricing: - properties: - audio: - description: 'Price in USD per audio input token' - type: 'string' - audio_output: - description: 'Price in USD per audio output token' - type: 'string' - completion: - description: 'Price in USD per token for completion (output) generation' - type: 'string' - discount: - description: 'Fractional discount applied to this endpoint''s pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)' - format: 'double' - type: 'number' - image: - description: 'Price in USD per input image' - type: 'string' - image_output: - description: 'Price in USD per output image' - type: 'string' - image_token: - description: 'Price in USD per image token' - type: 'string' - input_audio_cache: - description: 'Price in USD per cached audio input token' - type: 'string' - input_cache_read: - description: 'Price in USD per cached input token (read)' - type: 'string' - input_cache_write: - description: 'Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.' - type: 'string' - input_cache_write_1h: - description: 'Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.' - type: 'string' - internal_reasoning: - description: 'Price in USD per internal reasoning token' - type: 'string' - overrides: - description: 'Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.' - items: - $ref: '#/components/schemas/PricingOverride' - type: 'array' - prompt: - description: 'Price in USD per token for prompt (input) processing' - type: 'string' - request: - description: 'Price in USD per request' - type: 'string' - web_search: - description: 'Price in USD per web search' - type: 'string' - required: - - 'prompt' - - 'completion' - type: 'object' + $ref: '#/components/schemas/Pricing' provider_name: $ref: '#/components/schemas/ProviderName' quantization: @@ -29017,6 +28921,56 @@ components: - 'string' - 'null' x-speakeasy-unknown-values: allow + PublicZdrEndpoint: + allOf: + - $ref: '#/components/schemas/PublicEndpoint' + - properties: + safety_retention: + description: 'Whether the endpoint uses Safety Retention: prompts are not retained by default, but the provider may retain prompts its safety classifiers flag. A ZDR-enforced request reaches these endpoints only when the account allows Safety Retention and no applied guardrail disallows it.' + example: false + type: 'boolean' + required: + - 'safety_retention' + type: 'object' + description: 'An endpoint whose data policy does not retain prompts by default' + example: + context_length: 1048576 + latency_last_30m: null + max_completion_tokens: 65535 + max_prompt_tokens: null + model_id: 'google/gemini-2.5-flash' + model_name: 'Gemini 2.5 Flash' + name: 'Google: Gemini 2.5 Flash' + native_tools: {} + pricing: + completion: '0.0000025' + image: '0' + prompt: '0.0000003' + request: '0' + provider_name: 'Google' + quantization: null + safety_retention: true + service_tier: null + status: 0 + supported_parameters: + - 'temperature' + - 'top_p' + - 'max_tokens' + supports_diarization: false + supports_image_reference: false + supports_implicit_caching: true + supports_multiple_audio_references: false + supports_tool_choice: + auto: true + function: true + none: true + required: true + supports_voice_cloning: false + tag: 'google-vertex' + throughput_last_30m: null + uptime_last_1d: 99.8 + uptime_last_30m: 99.5 + uptime_last_5m: 100 Quantization: enum: - 'int4' @@ -29563,6 +29517,26 @@ components: - 'code' - 'message' type: 'object' + Rerank: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' ResponseHealingPlugin: example: enabled: true @@ -31624,6 +31598,26 @@ components: - 111 logprob: -0.5 token: 'Hello' + STT: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' STTEntity: description: 'A detected entity, returned when the provider runs entity detection' example: @@ -32474,6 +32468,26 @@ components: example: format: type: 'text' + TextGeneration: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' TokenExchangeRequest: description: 'RFC 8693 token exchange request body (application/x-www-form-urlencoded).' example: @@ -32923,6 +32937,26 @@ components: - 'string' - 'null' x-speakeasy-unknown-values: allow + TTS: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' UnauthorizedResponse: description: 'Unauthorized - Authentication required or invalid credentials' example: @@ -33432,6 +33466,26 @@ components: - 'reasoning_effort' - 'temperature' type: 'object' + Unknown: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' UnprocessableEntityResponse: description: 'Unprocessable Entity - Semantic validation failure' example: @@ -35016,6 +35070,26 @@ components: - 'value' - 'hosts' type: 'object' + VideoGeneration: + properties: + latency: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Latency percentiles in milliseconds for this workload. Image and video generation report full end-to-end generation time, because their raw latency only measures request acknowledgement; every other workload reports time to first token or result.' + request_count: + description: 'Total requests admitted for this workload in the window.' + type: + - 'integer' + - 'null' + throughput: + allOf: + - $ref: '#/components/schemas/PercentileStats' + - description: 'Throughput percentiles in tokens per second; pN is the speed that N% of requests reached or exceeded, so p90 is lower than p50. Only meaningful for text generation; null for workloads without token throughput.' + required: + - 'latency' + - 'throughput' + - 'request_count' + type: 'object' VideoGenerationRequest: example: aspect_ratio: '16:9' @@ -41094,6 +41168,7 @@ paths: request: '0' provider_name: 'OpenAI' quantization: 'fp16' + safety_retention: false status: 0 supported_parameters: - 'temperature' @@ -41135,6 +41210,7 @@ paths: request: '0' provider_name: 'OpenAI' quantization: 'fp16' + safety_retention: false status: 0 supported_parameters: - 'temperature' @@ -41157,7 +41233,7 @@ paths: properties: data: items: - $ref: '#/components/schemas/PublicEndpoint' + $ref: '#/components/schemas/PublicZdrEndpoint' type: 'array' required: - 'data' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index 537451d7..a929f5df 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.803.2 sources: OpenRouter API: sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:e694f4549e00867798b00834fbd31906ce3579b94a641f0cf0a505160fa427e8 - sourceBlobDigest: sha256:c98e501126c39c5d724e5cf6ccdedb42c9ba794e838f27e7df736e6cbd9b0eff + sourceRevisionDigest: sha256:f2ec7c45abce35a4ee889ecf63e1b7205c07047ad07a01b36cc700933c2f7738 + sourceBlobDigest: sha256:2e4abbb634949f2276fd2e3e2da11e201ba84a654602baf9c60002e28cc8f5f7 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:e694f4549e00867798b00834fbd31906ce3579b94a641f0cf0a505160fa427e8 - sourceBlobDigest: sha256:c98e501126c39c5d724e5cf6ccdedb42c9ba794e838f27e7df736e6cbd9b0eff + sourceRevisionDigest: sha256:f2ec7c45abce35a4ee889ecf63e1b7205c07047ad07a01b36cc700933c2f7738 + sourceBlobDigest: sha256:2e4abbb634949f2276fd2e3e2da11e201ba84a654602baf9c60002e28cc8f5f7 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:3740a7d9bfd42d34b8191df9db9036b30a241191ab34d95f2fff30bff41e2f19 + codeSamplesRevisionDigest: sha256:3f4be72cb1b4642b401e6a72de66c4501e20d8b0880c1017f5825f9a033a58af workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.803.2 diff --git a/RELEASES.md b/RELEASES.md index 6c2ca09d..45c4752f 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -3799,4 +3799,14 @@ Based on: ### Generated - [python v1.3.103] . ### Releases -- [PyPI v1.3.103] https://pypi.org/project/openrouter/1.3.103 - . \ No newline at end of file +- [PyPI v1.3.103] https://pypi.org/project/openrouter/1.3.103 - . + +## 2026-10-30 20:23:39 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.104] . +### Releases +- [PyPI v1.3.104] https://pypi.org/project/openrouter/1.3.104 - . \ No newline at end of file diff --git a/docs/components/publiczdrendpoint.mdx b/docs/components/publiczdrendpoint.mdx new file mode 100644 index 00000000..1802fa7f --- /dev/null +++ b/docs/components/publiczdrendpoint.mdx @@ -0,0 +1,38 @@ +--- +title: "PublicZdrEndpoint" +--- + +An endpoint whose data policy does not retain prompts by default + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `context_length` | *int* | ✔️ | N/A | | +| `latency_last_30m` | [Nullable[components.PercentileStats]](../components/percentilestats.mdx) | ✔️ | Latency percentiles in milliseconds over the last 30 minutes. Latency measures time to first token. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests. | \{
"p50": 25.5,
"p75": 35.2,
"p90": 48.7,
"p99": 85.3
} | +| `max_completion_tokens` | *Nullable[int]* | ✔️ | Maximum completion tokens for this endpoint. Input and output tokens share the context window, so the effective maximum output for a request is further limited by the context remaining after input tokens. | | +| `max_prompt_tokens` | *Nullable[int]* | ✔️ | N/A | | +| `model_id` | *str* | ✔️ | The unique identifier for the model (permaslug) | openai/gpt-4 | +| `model_name` | *str* | ✔️ | N/A | | +| `name` | *str* | ✔️ | N/A | | +| `native_tools` | Dict[str, [components.NativeTools](../components/nativetools.mdx)] | ✔️ | The server tools this endpoint accepts as the provider's own built-in tool (`engine: "native"`) instead of an OpenRouter engine, keyed by canonical `openrouter:*` name. Each value names the provider tool type the request is translated to. Where that tool runs (provider-side, or returned to the client as with Anthropic bash) is documented per tool. Empty when the provider has none. | \{
"openrouter:web_search": \{
"type": "web_search_20260209"
}
} | +| `perf_last_30m_by_workload` | [Optional[components.PerfLast30mByWorkload]](../components/perflast30mbyworkload.mdx) | ➖ | Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie. | | +| `pricing` | [components.Pricing](../components/pricing.mdx) | ✔️ | N/A | | +| `provider_name` | [components.ProviderName](../components/providername.mdx) | ✔️ | N/A | OpenAI | +| `quantization` | [Nullable[components.Quantization]](../components/quantization.mdx) | ✔️ | N/A | fp16 | +| `service_tier` | [Nullable[components.PublicServiceTier]](../components/publicservicetier.mdx) | ✔️ | The service tier this endpoint sells, or null for a standard endpoint. The same value whether the provider selects the tier with a request parameter or with a dedicated model id. Always the canonical tier: priority covers the fast request alias and the turbo, highspeed, and prime provider model-id spellings, none of which this field reports. | priority | +| `status` | [Optional[components.EndpointStatus]](../components/endpointstatus.mdx) | ➖ | N/A | 0 | +| `supported_parameters` | List[[components.Parameter](../components/parameter.mdx)] | ✔️ | N/A | | +| `supports_diarization` | *bool* | ✔️ | Whether this STT endpoint can label each transcript segment with a speaker (speaker diarization). False when the endpoint has not declared support. | | +| `supports_image_reference` | *Optional[bool]* | ➖ | Whether this TTS endpoint accepts an `image_url` reference describing the desired voice. Requests carrying an image reference are only routed to endpoints where this is true. | | +| `supports_implicit_caching` | *bool* | ✔️ | N/A | | +| `supports_multiple_audio_references` | *Optional[bool]* | ➖ | Whether this TTS endpoint accepts more than one `input_audio` reference clip per request. Requests carrying several clips are only routed to endpoints where this is true. | | +| `supports_tool_choice` | [components.ToolChoiceSupport](../components/toolchoicesupport.mdx) | ✔️ | Per-variant `tool_choice` support. `tool_choice` in `supported_parameters` only says the parameter is accepted; these flags say which of its values passed testing. | \{
"auto": true,
"function": true,
"none": true,
"required": true
} | +| `supports_voice_cloning` | *Optional[bool]* | ➖ | Whether this TTS endpoint accepts inline reference audio (`input_references`) for stateless voice cloning. Requests carrying reference audio are only routed to endpoints where this is true. | | +| `tag` | *str* | ✔️ | N/A | | +| `throughput_last_30m` | [Nullable[components.PercentileStats]](../components/percentilestats.mdx) | ✔️ | N/A | \{
"p50": 25.5,
"p75": 35.2,
"p90": 48.7,
"p99": 85.3
} | +| `uptime_last_1d` | *Nullable[float]* | ✔️ | Uptime percentage over the last day: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic. | | +| `uptime_last_30m` | *Nullable[float]* | ✔️ | N/A | | +| `uptime_last_5m` | *Nullable[float]* | ✔️ | Uptime percentage over the last 5 minutes: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic. | | +| `safety_retention` | *bool* | ✔️ | Whether the endpoint uses Safety Retention: prompts are not retained by default, but the provider may retain prompts its safety classifiers flag. A ZDR-enforced request reaches these endpoints only when the account allows Safety Retention and no applied guardrail disallows it. | false | \ No newline at end of file diff --git a/docs/operations/listendpointszdrresponse.mdx b/docs/operations/listendpointszdrresponse.mdx index 5fc4002e..574db8c8 100644 --- a/docs/operations/listendpointszdrresponse.mdx +++ b/docs/operations/listendpointszdrresponse.mdx @@ -7,6 +7,6 @@ Returns a list of endpoints ## Fields -| Field | Type | Required | Description | -| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | -| `data` | List[[components.PublicEndpoint](../components/publicendpoint.mdx)] | ✔️ | N/A | \ No newline at end of file +| Field | Type | Required | Description | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `data` | List[[components.PublicZdrEndpoint](../components/publiczdrendpoint.mdx)] | ✔️ | N/A | \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index b80981b1..1d7d2dd2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.103" +version = "1.3.104" description = "Official Python Client SDK for OpenRouter." authors = [{ name = "OpenRouter" },] readme = "README-PYPI.md" diff --git a/src/openrouter/_version.py b/src/openrouter/_version.py index 60a67b36..7c705ab9 100644 --- a/src/openrouter/_version.py +++ b/src/openrouter/_version.py @@ -3,10 +3,10 @@ import importlib.metadata __title__: str = "openrouter" -__version__: str = "1.3.103" +__version__: str = "1.3.104" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.950.13" -__user_agent__: str = "speakeasy-sdk/python 1.3.103 2.950.13 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.104 2.950.13 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py index f74ec63f..47676c45 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -1625,6 +1625,7 @@ DebugEventType, DebugEventTypedDict, ) + from .decisions import Decisions, DecisionsTypedDict from .decisionsboxanswer import ( Box, BoxTypedDict, @@ -1794,6 +1795,7 @@ EdgeNetworkTimeoutResponseErrorData, EdgeNetworkTimeoutResponseErrorDataTypedDict, ) + from .embeddings import Embeddings, EmbeddingsTypedDict from .endpointinfo import EndpointInfo, EndpointInfoTypedDict from .endpointsmetadata import EndpointsMetadata, EndpointsMetadataTypedDict from .endpointstatus import EndpointStatus @@ -2290,6 +2292,7 @@ ImageGenCompletedEventType, ImageGenCompletedEventTypedDict, ) + from .imagegeneration import ImageGeneration, ImageGenerationTypedDict from .imagegenerationproviderpreferences import ( ImageGenerationProviderPreferences, ImageGenerationProviderPreferencesIgnore, @@ -2905,6 +2908,7 @@ NamespaceToolTypedDict, UnknownNamespaceToolTool, ) + from .nativetools import NativeTools, NativeToolsTypedDict from .notfoundresponseerrordata import ( NotFoundResponseErrorData, NotFoundResponseErrorDataTypedDict, @@ -3644,6 +3648,10 @@ PercentileThroughputCutoffs, PercentileThroughputCutoffsTypedDict, ) + from .perflast30mbyworkload import ( + PerfLast30mByWorkload, + PerfLast30mByWorkloadTypedDict, + ) from .perrequestlimits import PerRequestLimits, PerRequestLimitsTypedDict from .pipelinestage import PipelineStage, PipelineStageTypedDict from .pipelinestagetype import PipelineStageType @@ -3689,6 +3697,7 @@ PreviewWebSearchUserLocationType, PreviewWebSearchUserLocationTypedDict, ) + from .pricing import Pricing, PricingTypedDict from .pricingoverride import PricingOverride, PricingOverrideTypedDict, UtcDay from .privateendpoint import PrivateEndpoint, PrivateEndpointTypedDict from .privateendpointactivation import ( @@ -3803,36 +3812,10 @@ ProviderSortConfig, ProviderSortConfigTypedDict, ) - from .publicendpoint import ( - Decisions, - DecisionsTypedDict, - Embeddings, - EmbeddingsTypedDict, - ImageGeneration, - ImageGenerationTypedDict, - NativeTools, - NativeToolsTypedDict, - PerfLast30mByWorkload, - PerfLast30mByWorkloadTypedDict, - Pricing, - PricingTypedDict, - PublicEndpoint, - PublicEndpointTypedDict, - Rerank, - RerankTypedDict, - STT, - STTTypedDict, - TTS, - TTSTypedDict, - TextGeneration, - TextGenerationTypedDict, - Unknown, - UnknownTypedDict, - VideoGeneration, - VideoGenerationTypedDict, - ) + from .publicendpoint import PublicEndpoint, PublicEndpointTypedDict from .publicpricing import PublicPricing, PublicPricingTypedDict from .publicservicetier import PublicServiceTier + from .publiczdrendpoint import PublicZdrEndpoint, PublicZdrEndpointTypedDict from .quantization import Quantization from .rangecapability import ( RangeCapability, @@ -3943,6 +3926,7 @@ RequestTimeoutResponseErrorData, RequestTimeoutResponseErrorDataTypedDict, ) + from .rerank import Rerank, RerankTypedDict from .responsehealingplugin import ( ResponseHealingPlugin, ResponseHealingPluginID, @@ -4225,6 +4209,7 @@ StreamLogprobTopLogprob, StreamLogprobTopLogprobTypedDict, ) + from .stt import STT, STTTypedDict from .sttentity import STTEntity, STTEntityTypedDict from .sttinlineinputaudio import STTInlineInputAudio, STTInlineInputAudioTypedDict from .sttinputaudio import STTInputAudio, STTInputAudioTypedDict @@ -4303,6 +4288,7 @@ TextExtendedConfigTypedDict, Verbosity, ) + from .textgeneration import TextGeneration, TextGenerationTypedDict from .tokenexchangerequest import ( GrantType, RequestedTokenType, @@ -4366,6 +4352,7 @@ from .topproviderinfo import TopProviderInfo, TopProviderInfoTypedDict from .traceconfig import TraceConfig, TraceConfigTypedDict from .truncation import Truncation + from .tts import TTS, TTSTypedDict from .unauthorizedresponseerrordata import ( UnauthorizedResponseErrorData, UnauthorizedResponseErrorDataTypedDict, @@ -4416,6 +4403,7 @@ UnifiedBenchmarksSearchRunConfig, UnifiedBenchmarksSearchRunConfigTypedDict, ) + from .unknown import Unknown, UnknownTypedDict from .unprocessableentityresponseerrordata import ( UnprocessableEntityResponseErrorData, UnprocessableEntityResponseErrorDataTypedDict, @@ -4591,6 +4579,7 @@ VaultSecretWriteRequest, VaultSecretWriteRequestTypedDict, ) + from .videogeneration import VideoGeneration, VideoGenerationTypedDict from .videogenerationrequest import ( VideoGenerationRequest, VideoGenerationRequestAspectRatio, @@ -7395,6 +7384,8 @@ "PublicPricing", "PublicPricingTypedDict", "PublicServiceTier", + "PublicZdrEndpoint", + "PublicZdrEndpointTypedDict", "Purpose", "Quantization", "Questions", @@ -9341,6 +9332,8 @@ "DebugEventTimingsTypedDict": ".debugevent", "DebugEventType": ".debugevent", "DebugEventTypedDict": ".debugevent", + "Decisions": ".decisions", + "DecisionsTypedDict": ".decisions", "Box": ".decisionsboxanswer", "BoxTypedDict": ".decisionsboxanswer", "DecisionsBoxAnswer": ".decisionsboxanswer", @@ -9461,6 +9454,8 @@ "EasyInputMessageTypedDict": ".easyinputmessage", "EdgeNetworkTimeoutResponseErrorData": ".edgenetworktimeoutresponseerrordata", "EdgeNetworkTimeoutResponseErrorDataTypedDict": ".edgenetworktimeoutresponseerrordata", + "Embeddings": ".embeddings", + "EmbeddingsTypedDict": ".embeddings", "EndpointInfo": ".endpointinfo", "EndpointInfoTypedDict": ".endpointinfo", "EndpointsMetadata": ".endpointsmetadata", @@ -9835,6 +9830,8 @@ "ImageGenCompletedEvent": ".imagegencompletedevent", "ImageGenCompletedEventType": ".imagegencompletedevent", "ImageGenCompletedEventTypedDict": ".imagegencompletedevent", + "ImageGeneration": ".imagegeneration", + "ImageGenerationTypedDict": ".imagegeneration", "ImageGenerationProviderPreferences": ".imagegenerationproviderpreferences", "ImageGenerationProviderPreferencesIgnore": ".imagegenerationproviderpreferences", "ImageGenerationProviderPreferencesIgnoreTypedDict": ".imagegenerationproviderpreferences", @@ -10335,6 +10332,8 @@ "NamespaceToolType": ".namespacetool", "NamespaceToolTypedDict": ".namespacetool", "UnknownNamespaceToolTool": ".namespacetool", + "NativeTools": ".nativetools", + "NativeToolsTypedDict": ".nativetools", "NotFoundResponseErrorData": ".notfoundresponseerrordata", "NotFoundResponseErrorDataTypedDict": ".notfoundresponseerrordata", "ErrorEnum": ".oautherrorresponse", @@ -10884,6 +10883,8 @@ "PercentileStatsTypedDict": ".percentilestats", "PercentileThroughputCutoffs": ".percentilethroughputcutoffs", "PercentileThroughputCutoffsTypedDict": ".percentilethroughputcutoffs", + "PerfLast30mByWorkload": ".perflast30mbyworkload", + "PerfLast30mByWorkloadTypedDict": ".perflast30mbyworkload", "PerRequestLimits": ".perrequestlimits", "PerRequestLimitsTypedDict": ".perrequestlimits", "PipelineStage": ".pipelinestage", @@ -10917,6 +10918,8 @@ "PreviewWebSearchUserLocation": ".preview_websearchuserlocation", "PreviewWebSearchUserLocationType": ".preview_websearchuserlocation", "PreviewWebSearchUserLocationTypedDict": ".preview_websearchuserlocation", + "Pricing": ".pricing", + "PricingTypedDict": ".pricing", "PricingOverride": ".pricingoverride", "PricingOverrideTypedDict": ".pricingoverride", "UtcDay": ".pricingoverride", @@ -10997,35 +11000,13 @@ "Partition": ".providersortconfig", "ProviderSortConfig": ".providersortconfig", "ProviderSortConfigTypedDict": ".providersortconfig", - "Decisions": ".publicendpoint", - "DecisionsTypedDict": ".publicendpoint", - "Embeddings": ".publicendpoint", - "EmbeddingsTypedDict": ".publicendpoint", - "ImageGeneration": ".publicendpoint", - "ImageGenerationTypedDict": ".publicendpoint", - "NativeTools": ".publicendpoint", - "NativeToolsTypedDict": ".publicendpoint", - "PerfLast30mByWorkload": ".publicendpoint", - "PerfLast30mByWorkloadTypedDict": ".publicendpoint", - "Pricing": ".publicendpoint", - "PricingTypedDict": ".publicendpoint", "PublicEndpoint": ".publicendpoint", "PublicEndpointTypedDict": ".publicendpoint", - "Rerank": ".publicendpoint", - "RerankTypedDict": ".publicendpoint", - "STT": ".publicendpoint", - "STTTypedDict": ".publicendpoint", - "TTS": ".publicendpoint", - "TTSTypedDict": ".publicendpoint", - "TextGeneration": ".publicendpoint", - "TextGenerationTypedDict": ".publicendpoint", - "Unknown": ".publicendpoint", - "UnknownTypedDict": ".publicendpoint", - "VideoGeneration": ".publicendpoint", - "VideoGenerationTypedDict": ".publicendpoint", "PublicPricing": ".publicpricing", "PublicPricingTypedDict": ".publicpricing", "PublicServiceTier": ".publicservicetier", + "PublicZdrEndpoint": ".publiczdrendpoint", + "PublicZdrEndpointTypedDict": ".publiczdrendpoint", "Quantization": ".quantization", "RangeCapability": ".rangecapability", "RangeCapabilityType": ".rangecapability", @@ -11097,6 +11078,8 @@ "RefusalDoneEventTypedDict": ".refusaldoneevent", "RequestTimeoutResponseErrorData": ".requesttimeoutresponseerrordata", "RequestTimeoutResponseErrorDataTypedDict": ".requesttimeoutresponseerrordata", + "Rerank": ".rerank", + "RerankTypedDict": ".rerank", "ResponseHealingPlugin": ".responsehealingplugin", "ResponseHealingPluginID": ".responsehealingplugin", "ResponseHealingPluginTypedDict": ".responsehealingplugin", @@ -11302,6 +11285,8 @@ "StreamLogprobTypedDict": ".streamlogprob", "StreamLogprobTopLogprob": ".streamlogprobtoplogprob", "StreamLogprobTopLogprobTypedDict": ".streamlogprobtoplogprob", + "STT": ".stt", + "STTTypedDict": ".stt", "STTEntity": ".sttentity", "STTEntityTypedDict": ".sttentity", "STTInlineInputAudio": ".sttinlineinputaudio", @@ -11366,6 +11351,8 @@ "TextExtendedConfig": ".textextendedconfig", "TextExtendedConfigTypedDict": ".textextendedconfig", "Verbosity": ".textextendedconfig", + "TextGeneration": ".textgeneration", + "TextGenerationTypedDict": ".textgeneration", "GrantType": ".tokenexchangerequest", "RequestedTokenType": ".tokenexchangerequest", "SubjectTokenType": ".tokenexchangerequest", @@ -11416,6 +11403,8 @@ "TraceConfig": ".traceconfig", "TraceConfigTypedDict": ".traceconfig", "Truncation": ".truncation", + "TTS": ".tts", + "TTSTypedDict": ".tts", "UnauthorizedResponseErrorData": ".unauthorizedresponseerrordata", "UnauthorizedResponseErrorDataTypedDict": ".unauthorizedresponseerrordata", "UnifiedBenchmarkPricing": ".unifiedbenchmarkpricing", @@ -11448,6 +11437,8 @@ "UnifiedBenchmarksSearchItemTypedDict": ".unifiedbenchmarkssearchitem", "UnifiedBenchmarksSearchRunConfig": ".unifiedbenchmarkssearchrunconfig", "UnifiedBenchmarksSearchRunConfigTypedDict": ".unifiedbenchmarkssearchrunconfig", + "Unknown": ".unknown", + "UnknownTypedDict": ".unknown", "UnprocessableEntityResponseErrorData": ".unprocessableentityresponseerrordata", "UnprocessableEntityResponseErrorDataTypedDict": ".unprocessableentityresponseerrordata", "UpdateBYOKKeyRequest": ".updatebyokkeyrequest", @@ -11571,6 +11562,8 @@ "VaultSecretResponseTypedDict": ".vaultsecretresponse", "VaultSecretWriteRequest": ".vaultsecretwriterequest", "VaultSecretWriteRequestTypedDict": ".vaultsecretwriterequest", + "VideoGeneration": ".videogeneration", + "VideoGenerationTypedDict": ".videogeneration", "VideoGenerationRequest": ".videogenerationrequest", "VideoGenerationRequestAspectRatio": ".videogenerationrequest", "VideoGenerationRequestOptions": ".videogenerationrequest", diff --git a/src/openrouter/components/decisions.py b/src/openrouter/components/decisions.py new file mode 100644 index 00000000..6c5a910e --- /dev/null +++ b/src/openrouter/components/decisions.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class DecisionsTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class Decisions(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/embeddings.py b/src/openrouter/components/embeddings.py new file mode 100644 index 00000000..ade9cf4c --- /dev/null +++ b/src/openrouter/components/embeddings.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class EmbeddingsTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class Embeddings(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/imagegeneration.py b/src/openrouter/components/imagegeneration.py new file mode 100644 index 00000000..fe042dd8 --- /dev/null +++ b/src/openrouter/components/imagegeneration.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class ImageGenerationTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class ImageGeneration(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/nativetools.py b/src/openrouter/components/nativetools.py new file mode 100644 index 00000000..8afefba9 --- /dev/null +++ b/src/openrouter/components/nativetools.py @@ -0,0 +1,15 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel +from typing_extensions import TypedDict + + +class NativeToolsTypedDict(TypedDict): + type: str + r"""The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.""" + + +class NativeTools(BaseModel): + type: str + r"""The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.""" diff --git a/src/openrouter/components/perflast30mbyworkload.py b/src/openrouter/components/perflast30mbyworkload.py new file mode 100644 index 00000000..98d5725c --- /dev/null +++ b/src/openrouter/components/perflast30mbyworkload.py @@ -0,0 +1,80 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .decisions import Decisions, DecisionsTypedDict +from .embeddings import Embeddings, EmbeddingsTypedDict +from .imagegeneration import ImageGeneration, ImageGenerationTypedDict +from .rerank import Rerank, RerankTypedDict +from .stt import STT, STTTypedDict +from .textgeneration import TextGeneration, TextGenerationTypedDict +from .tts import TTS, TTSTypedDict +from .unknown import Unknown, UnknownTypedDict +from .videogeneration import VideoGeneration, VideoGenerationTypedDict +from openrouter.types import BaseModel, UNSET_SENTINEL +from pydantic import model_serializer +from typing import Optional +from typing_extensions import NotRequired, TypedDict + + +class PerfLast30mByWorkloadTypedDict(TypedDict): + r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" + + decisions: NotRequired[DecisionsTypedDict] + embeddings: NotRequired[EmbeddingsTypedDict] + image_generation: NotRequired[ImageGenerationTypedDict] + rerank: NotRequired[RerankTypedDict] + stt: NotRequired[STTTypedDict] + text_generation: NotRequired[TextGenerationTypedDict] + tts: NotRequired[TTSTypedDict] + unknown: NotRequired[UnknownTypedDict] + video_generation: NotRequired[VideoGenerationTypedDict] + + +class PerfLast30mByWorkload(BaseModel): + r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" + + decisions: Optional[Decisions] = None + + embeddings: Optional[Embeddings] = None + + image_generation: Optional[ImageGeneration] = None + + rerank: Optional[Rerank] = None + + stt: Optional[STT] = None + + text_generation: Optional[TextGeneration] = None + + tts: Optional[TTS] = None + + unknown: Optional[Unknown] = None + + video_generation: Optional[VideoGeneration] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "decisions", + "embeddings", + "image_generation", + "rerank", + "stt", + "text_generation", + "tts", + "unknown", + "video_generation", + ] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/components/pricing.py b/src/openrouter/components/pricing.py new file mode 100644 index 00000000..de6dc2a0 --- /dev/null +++ b/src/openrouter/components/pricing.py @@ -0,0 +1,126 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .pricingoverride import PricingOverride, PricingOverrideTypedDict +from openrouter.types import BaseModel, UNSET_SENTINEL +from pydantic import model_serializer +from typing import List, Optional +from typing_extensions import NotRequired, TypedDict + + +class PricingTypedDict(TypedDict): + completion: str + r"""Price in USD per token for completion (output) generation""" + prompt: str + r"""Price in USD per token for prompt (input) processing""" + audio: NotRequired[str] + r"""Price in USD per audio input token""" + audio_output: NotRequired[str] + r"""Price in USD per audio output token""" + discount: NotRequired[float] + r"""Fractional discount applied to this endpoint's pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)""" + image: NotRequired[str] + r"""Price in USD per input image""" + image_output: NotRequired[str] + r"""Price in USD per output image""" + image_token: NotRequired[str] + r"""Price in USD per image token""" + input_audio_cache: NotRequired[str] + r"""Price in USD per cached audio input token""" + input_cache_read: NotRequired[str] + r"""Price in USD per cached input token (read)""" + input_cache_write: NotRequired[str] + r"""Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.""" + input_cache_write_1h: NotRequired[str] + r"""Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.""" + internal_reasoning: NotRequired[str] + r"""Price in USD per internal reasoning token""" + overrides: NotRequired[List[PricingOverrideTypedDict]] + r"""Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.""" + request: NotRequired[str] + r"""Price in USD per request""" + web_search: NotRequired[str] + r"""Price in USD per web search""" + + +class Pricing(BaseModel): + completion: str + r"""Price in USD per token for completion (output) generation""" + + prompt: str + r"""Price in USD per token for prompt (input) processing""" + + audio: Optional[str] = None + r"""Price in USD per audio input token""" + + audio_output: Optional[str] = None + r"""Price in USD per audio output token""" + + discount: Optional[float] = None + r"""Fractional discount applied to this endpoint's pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)""" + + image: Optional[str] = None + r"""Price in USD per input image""" + + image_output: Optional[str] = None + r"""Price in USD per output image""" + + image_token: Optional[str] = None + r"""Price in USD per image token""" + + input_audio_cache: Optional[str] = None + r"""Price in USD per cached audio input token""" + + input_cache_read: Optional[str] = None + r"""Price in USD per cached input token (read)""" + + input_cache_write: Optional[str] = None + r"""Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.""" + + input_cache_write_1h: Optional[str] = None + r"""Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.""" + + internal_reasoning: Optional[str] = None + r"""Price in USD per internal reasoning token""" + + overrides: Optional[List[PricingOverride]] = None + r"""Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.""" + + request: Optional[str] = None + r"""Price in USD per request""" + + web_search: Optional[str] = None + r"""Price in USD per web search""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "audio", + "audio_output", + "discount", + "image", + "image_output", + "image_token", + "input_audio_cache", + "input_cache_read", + "input_cache_write", + "input_cache_write_1h", + "internal_reasoning", + "overrides", + "request", + "web_search", + ] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + if val is not None or k not in optional_fields: + m[k] = val + + return m diff --git a/src/openrouter/components/publicendpoint.py b/src/openrouter/components/publicendpoint.py index 60cb7bb3..75eb8e64 100644 --- a/src/openrouter/components/publicendpoint.py +++ b/src/openrouter/components/publicendpoint.py @@ -2,9 +2,11 @@ from __future__ import annotations from .endpointstatus import EndpointStatus +from .nativetools import NativeTools, NativeToolsTypedDict from .parameter import Parameter from .percentilestats import PercentileStats, PercentileStatsTypedDict -from .pricingoverride import PricingOverride, PricingOverrideTypedDict +from .perflast30mbyworkload import PerfLast30mByWorkload, PerfLast30mByWorkloadTypedDict +from .pricing import Pricing, PricingTypedDict from .providername import ProviderName from .publicservicetier import PublicServiceTier from .quantization import Quantization @@ -15,468 +17,6 @@ from typing_extensions import NotRequired, TypedDict -class NativeToolsTypedDict(TypedDict): - type: str - r"""The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.""" - - -class NativeTools(BaseModel): - type: str - r"""The provider tool type the request is translated to when this tool runs natively, e.g. `web_search_20260209` on Anthropic or `google_search` on Gemini.""" - - -class DecisionsTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class Decisions(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class EmbeddingsTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class Embeddings(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class ImageGenerationTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class ImageGeneration(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class RerankTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class Rerank(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class STTTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class STT(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class TextGenerationTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class TextGeneration(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class TTSTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class TTS(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class UnknownTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class Unknown(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class VideoGenerationTypedDict(TypedDict): - latency: Nullable[PercentileStatsTypedDict] - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - throughput: Nullable[PercentileStatsTypedDict] - - -class VideoGeneration(BaseModel): - latency: Nullable[PercentileStats] - - request_count: Nullable[int] - r"""Total requests admitted for this workload in the window.""" - - throughput: Nullable[PercentileStats] - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - m[k] = val - - return m - - -class PerfLast30mByWorkloadTypedDict(TypedDict): - r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" - - decisions: NotRequired[DecisionsTypedDict] - embeddings: NotRequired[EmbeddingsTypedDict] - image_generation: NotRequired[ImageGenerationTypedDict] - rerank: NotRequired[RerankTypedDict] - stt: NotRequired[STTTypedDict] - text_generation: NotRequired[TextGenerationTypedDict] - tts: NotRequired[TTSTypedDict] - unknown: NotRequired[UnknownTypedDict] - video_generation: NotRequired[VideoGenerationTypedDict] - - -class PerfLast30mByWorkload(BaseModel): - r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" - - decisions: Optional[Decisions] = None - - embeddings: Optional[Embeddings] = None - - image_generation: Optional[ImageGeneration] = None - - rerank: Optional[Rerank] = None - - stt: Optional[STT] = None - - text_generation: Optional[TextGeneration] = None - - tts: Optional[TTS] = None - - unknown: Optional[Unknown] = None - - video_generation: Optional[VideoGeneration] = None - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - optional_fields = set( - [ - "decisions", - "embeddings", - "image_generation", - "rerank", - "stt", - "text_generation", - "tts", - "unknown", - "video_generation", - ] - ) - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - if val is not None or k not in optional_fields: - m[k] = val - - return m - - -class PricingTypedDict(TypedDict): - completion: str - r"""Price in USD per token for completion (output) generation""" - prompt: str - r"""Price in USD per token for prompt (input) processing""" - audio: NotRequired[str] - r"""Price in USD per audio input token""" - audio_output: NotRequired[str] - r"""Price in USD per audio output token""" - discount: NotRequired[float] - r"""Fractional discount applied to this endpoint's pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)""" - image: NotRequired[str] - r"""Price in USD per input image""" - image_output: NotRequired[str] - r"""Price in USD per output image""" - image_token: NotRequired[str] - r"""Price in USD per image token""" - input_audio_cache: NotRequired[str] - r"""Price in USD per cached audio input token""" - input_cache_read: NotRequired[str] - r"""Price in USD per cached input token (read)""" - input_cache_write: NotRequired[str] - r"""Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.""" - input_cache_write_1h: NotRequired[str] - r"""Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.""" - internal_reasoning: NotRequired[str] - r"""Price in USD per internal reasoning token""" - overrides: NotRequired[List[PricingOverrideTypedDict]] - r"""Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.""" - request: NotRequired[str] - r"""Price in USD per request""" - web_search: NotRequired[str] - r"""Price in USD per web search""" - - -class Pricing(BaseModel): - completion: str - r"""Price in USD per token for completion (output) generation""" - - prompt: str - r"""Price in USD per token for prompt (input) processing""" - - audio: Optional[str] = None - r"""Price in USD per audio input token""" - - audio_output: Optional[str] = None - r"""Price in USD per audio output token""" - - discount: Optional[float] = None - r"""Fractional discount applied to this endpoint's pricing; the price is multiplied by (1 - discount) (0 = no discount, 1 = free)""" - - image: Optional[str] = None - r"""Price in USD per input image""" - - image_output: Optional[str] = None - r"""Price in USD per output image""" - - image_token: Optional[str] = None - r"""Price in USD per image token""" - - input_audio_cache: Optional[str] = None - r"""Price in USD per cached audio input token""" - - input_cache_read: Optional[str] = None - r"""Price in USD per cached input token (read)""" - - input_cache_write: Optional[str] = None - r"""Price per cache-write token, in USD per token. For providers with multiple cache TTLs (e.g. Anthropic), this is the default (5-minute) cache-write rate.""" - - input_cache_write_1h: Optional[str] = None - r"""Price per 1-hour cache-write token, in USD per token. Only present for providers that price an extended (1-hour) cache TTL separately, such as Anthropic.""" - - internal_reasoning: Optional[str] = None - r"""Price in USD per internal reasoning token""" - - overrides: Optional[List[PricingOverride]] = None - r"""Conditional overrides of the base pricing (e.g. long-context or time-based pricing). An entry applies when all of its condition fields (e.g. min_prompt_tokens, or the utc_start/utc_end time window) match the request; among applicable entries, later entries win per key; price keys absent from an entry inherit the base price. The top-level pricing keys always reflect the price that applies under default conditions.""" - - request: Optional[str] = None - r"""Price in USD per request""" - - web_search: Optional[str] = None - r"""Price in USD per web search""" - - @model_serializer(mode="wrap") - def serialize_model(self, handler): - optional_fields = set( - [ - "audio", - "audio_output", - "discount", - "image", - "image_output", - "image_token", - "input_audio_cache", - "input_cache_read", - "input_cache_write", - "input_cache_write_1h", - "internal_reasoning", - "overrides", - "request", - "web_search", - ] - ) - serialized = handler(self) - m = {} - - for n, f in type(self).model_fields.items(): - k = f.alias or n - val = serialized.get(k, serialized.get(n)) - - if val != UNSET_SENTINEL: - if val is not None or k not in optional_fields: - m[k] = val - - return m - - class PublicEndpointTypedDict(TypedDict): r"""Information about a specific model endpoint""" diff --git a/src/openrouter/components/publiczdrendpoint.py b/src/openrouter/components/publiczdrendpoint.py new file mode 100644 index 00000000..ab5747e0 --- /dev/null +++ b/src/openrouter/components/publiczdrendpoint.py @@ -0,0 +1,180 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .endpointstatus import EndpointStatus +from .nativetools import NativeTools, NativeToolsTypedDict +from .parameter import Parameter +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from .perflast30mbyworkload import PerfLast30mByWorkload, PerfLast30mByWorkloadTypedDict +from .pricing import Pricing, PricingTypedDict +from .providername import ProviderName +from .publicservicetier import PublicServiceTier +from .quantization import Quantization +from .toolchoicesupport import ToolChoiceSupport, ToolChoiceSupportTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing import Dict, List, Optional +from typing_extensions import NotRequired, TypedDict + + +class PublicZdrEndpointTypedDict(TypedDict): + r"""An endpoint whose data policy does not retain prompts by default""" + + context_length: int + latency_last_30m: Nullable[PercentileStatsTypedDict] + r"""Latency percentiles in milliseconds over the last 30 minutes. Latency measures time to first token. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests.""" + max_completion_tokens: Nullable[int] + r"""Maximum completion tokens for this endpoint. Input and output tokens share the context window, so the effective maximum output for a request is further limited by the context remaining after input tokens.""" + max_prompt_tokens: Nullable[int] + model_id: str + r"""The unique identifier for the model (permaslug)""" + model_name: str + name: str + native_tools: Dict[str, NativeToolsTypedDict] + r"""The server tools this endpoint accepts as the provider's own built-in tool (`engine: \"native\"`) instead of an OpenRouter engine, keyed by canonical `openrouter:*` name. Each value names the provider tool type the request is translated to. Where that tool runs (provider-side, or returned to the client as with Anthropic bash) is documented per tool. Empty when the provider has none.""" + pricing: PricingTypedDict + provider_name: ProviderName + quantization: Nullable[Quantization] + service_tier: Nullable[PublicServiceTier] + r"""The service tier this endpoint sells, or null for a standard endpoint. The same value whether the provider selects the tier with a request parameter or with a dedicated model id. Always the canonical tier: priority covers the fast request alias and the turbo, highspeed, and prime provider model-id spellings, none of which this field reports.""" + supported_parameters: List[Parameter] + supports_diarization: bool + r"""Whether this STT endpoint can label each transcript segment with a speaker (speaker diarization). False when the endpoint has not declared support.""" + supports_implicit_caching: bool + supports_tool_choice: ToolChoiceSupportTypedDict + r"""Per-variant `tool_choice` support. `tool_choice` in `supported_parameters` only says the parameter is accepted; these flags say which of its values passed testing.""" + tag: str + throughput_last_30m: Nullable[PercentileStatsTypedDict] + uptime_last_1d: Nullable[float] + r"""Uptime percentage over the last day: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic.""" + uptime_last_30m: Nullable[float] + uptime_last_5m: Nullable[float] + r"""Uptime percentage over the last 5 minutes: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic.""" + safety_retention: bool + r"""Whether the endpoint uses Safety Retention: prompts are not retained by default, but the provider may retain prompts its safety classifiers flag. A ZDR-enforced request reaches these endpoints only when the account allows Safety Retention and no applied guardrail disallows it.""" + perf_last_30m_by_workload: NotRequired[PerfLast30mByWorkloadTypedDict] + r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" + status: NotRequired[EndpointStatus] + supports_image_reference: NotRequired[bool] + r"""Whether this TTS endpoint accepts an `image_url` reference describing the desired voice. Requests carrying an image reference are only routed to endpoints where this is true.""" + supports_multiple_audio_references: NotRequired[bool] + r"""Whether this TTS endpoint accepts more than one `input_audio` reference clip per request. Requests carrying several clips are only routed to endpoints where this is true.""" + supports_voice_cloning: NotRequired[bool] + r"""Whether this TTS endpoint accepts inline reference audio (`input_references`) for stateless voice cloning. Requests carrying reference audio are only routed to endpoints where this is true.""" + + +class PublicZdrEndpoint(BaseModel): + r"""An endpoint whose data policy does not retain prompts by default""" + + context_length: int + + latency_last_30m: Nullable[PercentileStats] + r"""Latency percentiles in milliseconds over the last 30 minutes. Latency measures time to first token. Only visible when authenticated with an API key or cookie; returns null for unauthenticated requests.""" + + max_completion_tokens: Nullable[int] + r"""Maximum completion tokens for this endpoint. Input and output tokens share the context window, so the effective maximum output for a request is further limited by the context remaining after input tokens.""" + + max_prompt_tokens: Nullable[int] + + model_id: str + r"""The unique identifier for the model (permaslug)""" + + model_name: str + + name: str + + native_tools: Dict[str, NativeTools] + r"""The server tools this endpoint accepts as the provider's own built-in tool (`engine: \"native\"`) instead of an OpenRouter engine, keyed by canonical `openrouter:*` name. Each value names the provider tool type the request is translated to. Where that tool runs (provider-side, or returned to the client as with Anthropic bash) is documented per tool. Empty when the provider has none.""" + + pricing: Pricing + + provider_name: ProviderName + + quantization: Nullable[Quantization] + + service_tier: Nullable[PublicServiceTier] + r"""The service tier this endpoint sells, or null for a standard endpoint. The same value whether the provider selects the tier with a request parameter or with a dedicated model id. Always the canonical tier: priority covers the fast request alias and the turbo, highspeed, and prime provider model-id spellings, none of which this field reports.""" + + supported_parameters: List[Parameter] + + supports_diarization: bool + r"""Whether this STT endpoint can label each transcript segment with a speaker (speaker diarization). False when the endpoint has not declared support.""" + + supports_implicit_caching: bool + + supports_tool_choice: ToolChoiceSupport + r"""Per-variant `tool_choice` support. `tool_choice` in `supported_parameters` only says the parameter is accepted; these flags say which of its values passed testing.""" + + tag: str + + throughput_last_30m: Nullable[PercentileStats] + + uptime_last_1d: Nullable[float] + r"""Uptime percentage over the last day: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic.""" + + uptime_last_30m: Nullable[float] + + uptime_last_5m: Nullable[float] + r"""Uptime percentage over the last 5 minutes: the share of minutes in which at least 80% of provider attempts succeeded, counting only minutes with 10 or more attempts. Rate-limited and caller-caused failures are excluded. Null when no minute had enough traffic.""" + + safety_retention: bool + r"""Whether the endpoint uses Safety Retention: prompts are not retained by default, but the provider may retain prompts its safety classifiers flag. A ZDR-enforced request reaches these endpoints only when the account allows Safety Retention and no applied guardrail disallows it.""" + + perf_last_30m_by_workload: Optional[PerfLast30mByWorkload] = None + r"""Endpoint performance over the last 30 minutes, keyed by the kind of request served (e.g. `text_generation`, `image_generation`). Additive to the legacy singular latency and throughput fields; image and video generation report end-to-end latency. Only visible when authenticated with an API key or cookie.""" + + status: Optional[EndpointStatus] = None + + supports_image_reference: Optional[bool] = False + r"""Whether this TTS endpoint accepts an `image_url` reference describing the desired voice. Requests carrying an image reference are only routed to endpoints where this is true.""" + + supports_multiple_audio_references: Optional[bool] = False + r"""Whether this TTS endpoint accepts more than one `input_audio` reference clip per request. Requests carrying several clips are only routed to endpoints where this is true.""" + + supports_voice_cloning: Optional[bool] = False + r"""Whether this TTS endpoint accepts inline reference audio (`input_references`) for stateless voice cloning. Requests carrying reference audio are only routed to endpoints where this is true.""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + [ + "perf_last_30m_by_workload", + "status", + "supports_image_reference", + "supports_multiple_audio_references", + "supports_voice_cloning", + ] + ) + nullable_fields = set( + [ + "latency_last_30m", + "max_completion_tokens", + "max_prompt_tokens", + "quantization", + "service_tier", + "throughput_last_30m", + "uptime_last_1d", + "uptime_last_30m", + "uptime_last_5m", + ] + ) + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + is_nullable_and_explicitly_set = ( + k in nullable_fields + and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member + ) + + if val != UNSET_SENTINEL: + if ( + val is not None + or k not in optional_fields + or is_nullable_and_explicitly_set + ): + m[k] = val + + return m diff --git a/src/openrouter/components/rerank.py b/src/openrouter/components/rerank.py new file mode 100644 index 00000000..e3740a8f --- /dev/null +++ b/src/openrouter/components/rerank.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class RerankTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class Rerank(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/stt.py b/src/openrouter/components/stt.py new file mode 100644 index 00000000..2b0b14c1 --- /dev/null +++ b/src/openrouter/components/stt.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class STTTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class STT(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/textgeneration.py b/src/openrouter/components/textgeneration.py new file mode 100644 index 00000000..7b2f1c41 --- /dev/null +++ b/src/openrouter/components/textgeneration.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class TextGenerationTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class TextGeneration(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/tts.py b/src/openrouter/components/tts.py new file mode 100644 index 00000000..6c89d6bf --- /dev/null +++ b/src/openrouter/components/tts.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class TTSTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class TTS(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/unknown.py b/src/openrouter/components/unknown.py new file mode 100644 index 00000000..b85755f1 --- /dev/null +++ b/src/openrouter/components/unknown.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class UnknownTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class Unknown(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/components/videogeneration.py b/src/openrouter/components/videogeneration.py new file mode 100644 index 00000000..c2f15eb5 --- /dev/null +++ b/src/openrouter/components/videogeneration.py @@ -0,0 +1,37 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .percentilestats import PercentileStats, PercentileStatsTypedDict +from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL +from pydantic import model_serializer +from typing_extensions import TypedDict + + +class VideoGenerationTypedDict(TypedDict): + latency: Nullable[PercentileStatsTypedDict] + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + throughput: Nullable[PercentileStatsTypedDict] + + +class VideoGeneration(BaseModel): + latency: Nullable[PercentileStats] + + request_count: Nullable[int] + r"""Total requests admitted for this workload in the window.""" + + throughput: Nullable[PercentileStats] + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + serialized = handler(self) + m = {} + + for n, f in type(self).model_fields.items(): + k = f.alias or n + val = serialized.get(k, serialized.get(n)) + + if val != UNSET_SENTINEL: + m[k] = val + + return m diff --git a/src/openrouter/operations/listendpointszdr.py b/src/openrouter/operations/listendpointszdr.py index f5bd1f67..42e3e491 100644 --- a/src/openrouter/operations/listendpointszdr.py +++ b/src/openrouter/operations/listendpointszdr.py @@ -1,7 +1,7 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations -from openrouter.components import publicendpoint as components_publicendpoint +from openrouter.components import publiczdrendpoint as components_publiczdrendpoint from openrouter.types import BaseModel, UNSET_SENTINEL from openrouter.utils import FieldMetadata, HeaderMetadata import pydantic @@ -141,10 +141,10 @@ def serialize_model(self, handler): class ListEndpointsZdrResponseTypedDict(TypedDict): r"""Returns a list of endpoints""" - data: List[components_publicendpoint.PublicEndpointTypedDict] + data: List[components_publiczdrendpoint.PublicZdrEndpointTypedDict] class ListEndpointsZdrResponse(BaseModel): r"""Returns a list of endpoints""" - data: List[components_publicendpoint.PublicEndpoint] + data: List[components_publiczdrendpoint.PublicZdrEndpoint] diff --git a/uv.lock b/uv.lock index d64d302a..4d199f01 100644 --- a/uv.lock +++ b/uv.lock @@ -231,7 +231,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.103" +version = "1.3.104" source = { editable = "." } dependencies = [ { name = "httpcore" },