diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 8e0ac73c1..76609a282 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: 0e1fabf2c30c9f54a340f2447063dceb + docChecksum: 2205836b07e480eb94e378e278a07533 docVersion: 1.0.0 speakeasyVersion: 1.803.2 generationVersion: 2.950.13 - releaseVersion: 1.3.173 - configChecksum: 4bb368da7e1df14f3800ae26851e3274 + releaseVersion: 1.3.174 + configChecksum: 48bd28ea918cf731101910f098786208 repoURL: https://github.com/OpenRouterTeam/python-sdk.git installationURL: https://github.com/OpenRouterTeam/python-sdk.git published: true persistentEdits: - generation_id: 53663775-4c34-42d3-b5b0-8dca0e1d1c0c - pristine_commit_hash: c0c18828d88982022dd2c8bad26bab02da527167 - pristine_tree_hash: 6135a60193bc1956199150528b823bda30d35e72 + generation_id: 45ffa607-a655-4c7e-a91d-4a8b4135f788 + pristine_commit_hash: b8ccba62afb47fa4fe6352425b53c079e310e10a + pristine_tree_hash: 223532ab41f1cb4ce21a2678dec29c591570b4e3 features: python: acceptHeaders: 3.0.0 @@ -1494,10 +1494,14 @@ trackedFiles: id: 2f458adb351e last_write_checksum: sha1:610064187d560203fccfb7e65a9ff7e7350bbb81 pristine_git_object: bdaf4ed396310a47770724e89d190f3166aa428e + docs/components/batchinputreference.mdx: + id: 5720c0dc0b92 + last_write_checksum: sha1:822b56a26c049a8ec1eb9270a8c9d0c4d67584a4 + pristine_git_object: efd0f12da0d58dd68b09d7c48e825da2e541c98a docs/components/batchlistitem.mdx: id: 78998bff3044 - last_write_checksum: sha1:9d30a82754d72704851240958f43c499c6edd5b1 - pristine_git_object: b8b1a0d5c23603215a06efae7953ef77d4e3f58a + last_write_checksum: sha1:2855746b53d67679e71c853ba5479387344e7cca + pristine_git_object: b9557da4d68cfbcd0a331a796a480afab6858dac docs/components/batchlistitemcompletiontokensdetails.mdx: id: 70f3adf88e68 last_write_checksum: sha1:ace0c3427a56fc3793980e6e9cf319703e4c932d @@ -1548,8 +1552,8 @@ trackedFiles: pristine_git_object: c7629b16bb3a2df3eb7a2c784a30953e137f6d60 docs/components/batchobject.mdx: id: 58b4e759b75f - last_write_checksum: sha1:4c806a567027ddbe388d5eb9b9558ac8754a123b - pristine_git_object: cfdad69c74e4e6bb9d97b21c19f9c74a7af30b2a + last_write_checksum: sha1:ab9fcbf72c4af14a594a212a14e84e4e53c8caa6 + pristine_git_object: 9980ba5d8910e06582a1c6a952aae8c302dbd290 docs/components/batchobjectcompletiontokensdetails.mdx: id: a27cfa43c4a8 last_write_checksum: sha1:12ac8d5a81f625e607190425946f2cd5af941a38 @@ -1642,6 +1646,10 @@ trackedFiles: id: eb710c8f044a last_write_checksum: sha1:ab3efbc4596bc00eac51a627189fa5c58ee87a0c pristine_git_object: 431974abae3c59ee27963a1066b6b49fbfe75bef + docs/components/batchoutputreference.mdx: + id: 6d31c5e326df + last_write_checksum: sha1:c2b3d8069e3ef23383fcfdc8e84158b53ef0ffa0 + pristine_git_object: 569d717d34969d1d98416dc6738f465ebbc6e45a docs/components/batchpaymentrequiredresponsecompletiontokensdetails.mdx: id: 5ae2aae74ddc last_write_checksum: sha1:fd2dd9b4c268bcc89bae3006af66cdb0ee59ac25 @@ -1688,8 +1696,8 @@ trackedFiles: pristine_git_object: d25f8767c5f193ee085eca684f5af8c606392c17 docs/components/batchsubmitbody.mdx: id: 2102d576a5e0 - last_write_checksum: sha1:ddf7f59f39abc8756c4a0fb230e46d2fa3828824 - pristine_git_object: 9ee22fec771f513af30f310865fc75e65dbec489 + last_write_checksum: sha1:603a9dc3616c12f97ddc46d512d4e9c5d4b1468e + pristine_git_object: ae6c0959f6804aadcca86f1a05f976b0a014fe84 docs/components/batchsubmitbodycompletionwindow.mdx: id: 71af0bee298c last_write_checksum: sha1:8fbf3915f9a5f59a214bd5144758f57d7f9d2485 @@ -4338,6 +4346,26 @@ trackedFiles: id: fd23e84c1023 last_write_checksum: sha1:4eb0e66226a08389218d6fd55fb5083bb0ff8f75 pristine_git_object: 05c9c94997c650c01c49e7b40f6d278573458b9a + docs/components/imagegenerationlayer.mdx: + id: 27f2c3372295 + last_write_checksum: sha1:d7bf9511b4821dd8fd955e1115749fe0597f2b38 + pristine_git_object: 0f210b4bc6ec6007d12e38075af5b9f618a81a67 + docs/components/imagegenerationlayerbackground.mdx: + id: 49f854f8643c + last_write_checksum: sha1:24c623e7c5b153d0a5575fe97ec97b8bc18a9d32 + pristine_git_object: 12014328c746bf1c07f58b4c086e6d04979733fc + docs/components/imagegenerationlayerboundingbox.mdx: + id: f8bf0c40712a + last_write_checksum: sha1:2b56308decdc3e2433b91677b07d4a855c9dd637 + pristine_git_object: 930f2d77a6ad89a48711ea16907841419d2cd266 + docs/components/imagegenerationlayertextrecognition.mdx: + id: 68e81ab88301 + last_write_checksum: sha1:cd6197415ab81b5f48552491fd3145fffa8be05d + pristine_git_object: 24551bc089452aeea5c0d088cad97d19e988c3b2 + docs/components/imagegenerationlayertextrun.mdx: + id: a58435d5e76e + last_write_checksum: sha1:1feb82175be662f7d9ac896aa58759235047de3c + pristine_git_object: bcce3f327e9c26e34544c80df20bde3085c6bca1 docs/components/imagegenerationproviderpreferences.mdx: id: 96067cea4257 last_write_checksum: sha1:683e768cd22cb882e63ac710bcfd07cf4fe7006c @@ -4400,8 +4428,8 @@ trackedFiles: pristine_git_object: 82ea0ef2f042092163584589dfe1bafdb684361d docs/components/imagegenerationresponsedata.mdx: id: 1afc55d56268 - last_write_checksum: sha1:7d6c978d40802f5ae2d69b12683c4ed72f0dd615 - pristine_git_object: 1f1b31c9cbbb9eb555910a60bff945d9f3aeed83 + last_write_checksum: sha1:96cd9afa714deff6f2ff8318e6e748df474efb3d + pristine_git_object: 3b470b255b9172acb2a60152ae372306245b7254 docs/components/imagegenerationservertool.mdx: id: "299013078656" last_write_checksum: sha1:a92538e6ebce9431f7ea9976cd678437cbcd00c2 @@ -4858,6 +4886,10 @@ trackedFiles: id: 241b46c3af41 last_write_checksum: sha1:87f6ccd952555f98fa58ea6231cb5e02dea633ba pristine_git_object: 84e5be99fde18ac05e85c2ec21e97204be5957c4 + docs/components/line.mdx: + id: 4cca1794fafd + last_write_checksum: sha1:45e3d8d2831553a256bd0091b4c0c7da27030a84 + pristine_git_object: b81b579a511b3f46b9a9971bc5f468203f56e595 docs/components/listaccountguardrailpoliciesresponse.mdx: id: c40c5fdfaf95 last_write_checksum: sha1:06f4f6e788a4d1aa92b91b8e2a1ed73f636e9ba4 @@ -8310,6 +8342,10 @@ trackedFiles: id: f7dc430a99ee last_write_checksum: sha1:8c400ba5d1640a195532dd47f20d10346f350b17 pristine_git_object: 76b0577c9e3e61bda3c499ca130526d9bcd9b241 + docs/components/style.mdx: + id: 66f0aa4b718c + last_write_checksum: sha1:21fa88c1ebb3f75d5934d6996954618bafa51c62 + pristine_git_object: 8cf7766c8bf64143cc9917a91192cd2ac15cfdfc docs/components/subagentnestedtool.mdx: id: 12547a9efd5f last_write_checksum: sha1:d95435e6a2a67d3c82052954b9357f2ede704f53 @@ -9380,8 +9416,8 @@ trackedFiles: pristine_git_object: c58311e31dc96a72425a1e7e72524ea6f4949723 docs/errors/batchpaymentrequiredresponseerror.mdx: id: 7621fe876155 - last_write_checksum: sha1:82af676d1a14bacb2a6e1f3cdbd71ebe6b1eb8e2 - pristine_git_object: d6153b7ad1919343df01a4301919a7846c827c93 + last_write_checksum: sha1:8dc2c6bb44338dd49f825c564541b3d2de7e92d5 + pristine_git_object: bcd883fac41337542dc6c96fca7b94d4307d4fcc docs/errors/clientclosedrequestresponseerror.mdx: id: fc75571fe5d6 last_write_checksum: sha1:86e7d79653c2ae191fac95097fd4be3009b41625 @@ -11484,8 +11520,8 @@ trackedFiles: pristine_git_object: c57d9d064d27b93eee0d99f597c6f7785c27503b docs/sdks/batch/README.mdx: id: e367aa4f4295 - last_write_checksum: sha1:a9395712d06a85088deae5d274d3c44a09ef0354 - pristine_git_object: 545e4c043057437610e981e4517531cb6fb782e4 + last_write_checksum: sha1:f3aedb152c958de7f1d88188c4f48809a898a428 + pristine_git_object: da036c8d6c4687d13b0f9eb9f129c2b887cea674 docs/sdks/benchmarks/README.mdx: id: 5b483a6770ba last_write_checksum: sha1:1123cde0a42d442dd80c502c40b3072f795cdd84 @@ -11636,8 +11672,8 @@ trackedFiles: pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544 pyproject.toml: id: 5d07e7d72637 - last_write_checksum: sha1:1bb0564d42e0e94ee4586650474554e91e55eee8 - pristine_git_object: e59d19d3b8e8b71149c22dba20bcefad42bc4570 + last_write_checksum: sha1:286d3c09753a180a5f42ae6abacf59a94b7f2e28 + pristine_git_object: bf40014fc1cfa58f72dcef88afa697a72930c914 scripts/prepare_readme.py: id: e0c5957a6035 last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54 @@ -11664,8 +11700,8 @@ trackedFiles: pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137 src/openrouter/_version.py: id: d8d15ad6c586 - last_write_checksum: sha1:c97143447a05904bd3175aa882ece8c76de58752 - pristine_git_object: 0a73b37da38c198fc124b832ee094cd707a4acd9 + last_write_checksum: sha1:be9b9e66b25a87f0243ab300e4c0518a7f714a4b + pristine_git_object: a264f3b4cf6a55d2e7b2261c3dc24b2d685fccf8 src/openrouter/alpha.py: id: 306c4d93308d last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766 @@ -11684,8 +11720,8 @@ trackedFiles: pristine_git_object: 7a562e21c7e66c9db666ead83748b73adefe4278 src/openrouter/batch.py: id: 148f61e34d5b - last_write_checksum: sha1:770b5760feb60cece2c7a5afbf5c20f34bfbb25d - pristine_git_object: e7a0b932c361d1b17d4ff200178f6e5b05df8906 + last_write_checksum: sha1:4dbaba567412dc37c29aafe381d5699408eef9d8 + pristine_git_object: abb2983f059efef628e7875aef34f5d93cf2b4fa src/openrouter/benchmarks.py: id: 178d2ad8d706 last_write_checksum: sha1:15b8a7ea05a7550032afb15981958aa73b756881 @@ -11712,8 +11748,8 @@ trackedFiles: pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1 src/openrouter/components/__init__.py: id: 81754e97b3f4 - last_write_checksum: sha1:43b8464cd93aff7843b793ccdc334cdeda04755a - pristine_git_object: cfdfb3cf4efc0e170e3a60b747656228ea906135 + last_write_checksum: sha1:9bb43306cf9197dc1aec78a1a3bfe8795a2c73d3 + pristine_git_object: 0ade14c3fa36bfe51e26469c5ee50e9ff3bdc35b src/openrouter/components/aabenchmarkentry.py: id: e2e0f0b48c82 last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c @@ -12370,10 +12406,14 @@ trackedFiles: id: 393c248e7a90 last_write_checksum: sha1:fbe6541534d864016398625646c046fa2e5e21df pristine_git_object: 8c105d9beae361eba8dc0775f17eec450fe35888 + src/openrouter/components/batchinputreference.py: + id: 95f4d52590ef + last_write_checksum: sha1:ac9f979df88caacf169728a25b600ed8867e89f1 + pristine_git_object: 3a72ddbd0e1373d7816ff9210979a76b93dd3541 src/openrouter/components/batchlistitem.py: id: f539fc72cf19 - last_write_checksum: sha1:bacd43c729e2e9af687fe3eea2280e1de42e85aa - pristine_git_object: e35446f3f5ec8e231d5329ef23ccf1ac8eebd2bd + last_write_checksum: sha1:173bfdba42b1108b6be13d6d5918c3a890ea0ed1 + pristine_git_object: 47f692ea5e1d656e85695fe30e547cfb110d0038 src/openrouter/components/batchlistresponse.py: id: 7e0643661b7d last_write_checksum: sha1:8efc75b2f2300bc7dbe9c3889af79c431ded7d32 @@ -12384,8 +12424,12 @@ trackedFiles: pristine_git_object: 8650957337063ba3aef94341108448ec19bd2945 src/openrouter/components/batchobject.py: id: caf1ef2414a3 - last_write_checksum: sha1:5d342f4f271ed7d5f04ba184ef1cf263a876ab12 - pristine_git_object: aef368a29570342346022dcc706ac59db00fa6f2 + last_write_checksum: sha1:3f7d7f0ed824fb7ccead98528c567fcd27fa632e + pristine_git_object: 73bf293c64dc4560ac7bf1d153b9296417d0454f + src/openrouter/components/batchoutputreference.py: + id: 7790c9506cde + last_write_checksum: sha1:47b65d37c720877601fd8ca69033ab574f0b9825 + pristine_git_object: 41a4e7641232c85c52ed64671faef29112c077f4 src/openrouter/components/batchpaymentrequiredresponse_error.py: id: 29d3620e8858 last_write_checksum: sha1:c797fbfd8a88561c101aca8a4d556352213b8096 @@ -12396,8 +12440,8 @@ trackedFiles: pristine_git_object: b2bbac635f94d6fe9f4eba2eded41b1990a9d5da src/openrouter/components/batchsubmitbody.py: id: 26e5100bce4e - last_write_checksum: sha1:7b56eb4484a8aabdcfb43bfad888db6a9d15f92a - pristine_git_object: 943fbb092773ad5e3b3dfe6297877e3cd7853133 + last_write_checksum: sha1:0478e538c0bb3b9226bc66c0e6514b6f5d22b255 + pristine_git_object: 8262b20a4b0fd6ef13c47d17a58948b671aa8fa2 src/openrouter/components/booleancapability.py: id: 6009fd660c03 last_write_checksum: sha1:2615f4f9eecdf753ece20adc9897553404c71cc1 @@ -13530,6 +13574,22 @@ trackedFiles: id: 8a20a323529f last_write_checksum: sha1:d86d0852fbda96fa56ee456e38b0f912c9e96132 pristine_git_object: fe042dd889e2f17d642f19b0d596cb3e53a7fce2 + src/openrouter/components/imagegenerationlayer.py: + id: 2f67266c0973 + last_write_checksum: sha1:b9173dfb36de61c9ad83dd8364944ec5be470b10 + pristine_git_object: 1e5b9d13be148ad4bf63f4c5329bd48d16032115 + src/openrouter/components/imagegenerationlayerboundingbox.py: + id: 1d698f3fa29b + last_write_checksum: sha1:3ff2bbd9951c3543799e9cb8ef2da74d2ea709aa + pristine_git_object: 4f30c5d08f06f412e7d1803cb876162fd902a458 + src/openrouter/components/imagegenerationlayertextrecognition.py: + id: d723dd11fc86 + last_write_checksum: sha1:0ecd8f57d947f81fab12db3b777bc7083c7c9bd2 + pristine_git_object: 509bbcf4984852ba6d41dcb9b1049aeeb15beab8 + src/openrouter/components/imagegenerationlayertextrun.py: + id: efe2a7489efb + last_write_checksum: sha1:42072ebb3196fb0e7911fa60d36fea0de8506bc3 + pristine_git_object: 9cb42cff16d478f29066a6e09d32ea9d7bfe41db src/openrouter/components/imagegenerationproviderpreferences.py: id: 100a82a54e2d last_write_checksum: sha1:9c14ec41b48270241d5a56433c93aa6da5bcc691 @@ -13540,8 +13600,8 @@ trackedFiles: pristine_git_object: 8457fb8478ecec520da1808ffbb30a19dacf775c src/openrouter/components/imagegenerationresponse.py: id: 53354cd0cbfc - last_write_checksum: sha1:53f1cde7b8bfe4f9e786a76f6e57b0a1f76aced2 - pristine_git_object: 687008d328b39a67390cdf0ab3eb8f6179ae6f7c + last_write_checksum: sha1:579cb046c956dbe27b82aa58e42277b33902b651 + pristine_git_object: 3f2061536222d2b88913bca039f434e25194f566 src/openrouter/components/imagegenerationservertool.py: id: 9c95bc975f2e last_write_checksum: sha1:808635f6a028797cd87918e3a3353d6c3bf00226 @@ -15568,8 +15628,8 @@ trackedFiles: pristine_git_object: 9ce16f01d0d2525e766ecf20ce17a472b3587bff src/openrouter/errors/batchpaymentrequiredresponse_error.py: id: a45e11aec23b - last_write_checksum: sha1:944b92f07158a09fda14ca8ef0971210127369b4 - pristine_git_object: 1b1e4508d032253a0e01e318dbba24fa4b4acd1c + last_write_checksum: sha1:8196bf79702a080428407f323a818f3123a786b8 + pristine_git_object: a2ef2962ea3a016e36d8d0693ef165dae0d32d01 src/openrouter/errors/clientclosedrequestresponse_error.py: id: 57b29c61472b last_write_checksum: sha1:9168a84f8a1579190c6a28da1c1d0bc85d778217 @@ -20032,7 +20092,7 @@ examples: createBatches: chatCompletions: requestBody: - application/json: {"completion_window": "24h", "endpoint": "/v1/chat/completions", "model": "openai/gpt-4o", "requests": [{"body": {"messages": [{"content": "Summarize ...", "role": "user"}], "model": "openai/gpt-4o"}, "custom_id": "req-0001"}]} + application/json: {"completion_window": "24h", "endpoint": "/v1/chat/completions", "model": "openai/gpt-4o"} responses: "202": application/json: {"completion_window": "24h", "created_at": 511243, "endpoint": "", "error": {"message": ""}, "expires_at": 239149, "finalized_at": 665164, "id": "", "model": "CX-9", "object": "batch", "provider": "", "request_counts": {"completed": 719289, "failed": 238478, "total": 928444}, "results": [{"custom_id": "", "error": {"message": "", "param": "", "type": ""}, "id": "", "response": {"body": {"completed_at": 1704067210, "created_at": 1704067200, "error": null, "frequency_penalty": null, "id": "resp-abc123", "incomplete_details": null, "instructions": null, "metadata": null, "model": "gpt-4", "object": "response", "output": [{"content": [{"text": "Hello! How can I help you today?", "type": "output_text"}], "id": "msg-abc123", "role": "assistant", "type": "message"}], "parallel_tool_calls": true, "presence_penalty": null, "status": "completed", "temperature": null, "tool_choice": "auto", "tools": [], "top_p": null}, "request_id": "", "status_code": 296735}}], "status": "in_progress", "usage": {"completion_tokens": 323461, "prompt_tokens": 784076, "total_tokens": 757531}} @@ -20042,7 +20102,7 @@ examples: application/json: {"error": {"code": 400, "message": "custom_id is required on requests[0]."}} messages: requestBody: - application/json: {"completion_window": "24h", "endpoint": "/v1/messages", "model": "openai/gpt-5-nano", "requests": [{"body": {"max_tokens": 1024, "messages": [{"content": "Summarize ...", "role": "user"}], "model": "openai/gpt-5-nano"}, "custom_id": "req-0001"}]} + application/json: {"completion_window": "24h", "endpoint": "/v1/messages", "model": "openai/gpt-5-nano"} responses: "202": application/json: {"completion_window": "24h", "created_at": 511243, "endpoint": "", "error": {"message": ""}, "expires_at": 239149, "finalized_at": 665164, "id": "", "model": "CX-9", "object": "batch", "provider": "", "request_counts": {"completed": 719289, "failed": 238478, "total": 928444}, "results": [{"custom_id": "", "error": {"message": "", "param": "", "type": ""}, "id": "", "response": {"body": {"completed_at": 1704067210, "created_at": 1704067200, "error": null, "frequency_penalty": null, "id": "resp-abc123", "incomplete_details": null, "instructions": null, "metadata": null, "model": "gpt-4", "object": "response", "output": [{"content": [{"text": "Hello! How can I help you today?", "type": "output_text"}], "id": "msg-abc123", "role": "assistant", "type": "message"}], "parallel_tool_calls": true, "presence_penalty": null, "status": "completed", "temperature": null, "tool_choice": "auto", "tools": [], "top_p": null}, "request_id": "", "status_code": 296735}}], "status": "in_progress", "usage": {"completion_tokens": 323461, "prompt_tokens": 784076, "total_tokens": 757531}} @@ -20052,7 +20112,7 @@ examples: application/json: {"error": {"code": 400, "message": "custom_id is required on requests[0]."}} providerPinned: requestBody: - application/json: {"completion_window": "24h", "endpoint": "/v1/chat/completions", "model": "google/gemini-3.6-flash", "requests": [{"body": {"messages": [{"content": "Summarize ...", "role": "user"}], "model": "google/gemini-3.6-flash"}, "custom_id": "req-0001"}]} + application/json: {"completion_window": "24h", "endpoint": "/v1/chat/completions", "model": "google/gemini-3.6-flash"} responses: "202": application/json: {"completion_window": "24h", "created_at": 511243, "endpoint": "", "error": {"message": ""}, "expires_at": 239149, "finalized_at": 665164, "id": "", "model": "CX-9", "object": "batch", "provider": "", "request_counts": {"completed": 719289, "failed": 238478, "total": 928444}, "results": [{"custom_id": "", "error": {"message": "", "param": "", "type": ""}, "id": "", "response": {"body": {"completed_at": 1704067210, "created_at": 1704067200, "error": null, "frequency_penalty": null, "id": "resp-abc123", "incomplete_details": null, "instructions": null, "metadata": null, "model": "gpt-4", "object": "response", "output": [{"content": [{"text": "Hello! How can I help you today?", "type": "output_text"}], "id": "msg-abc123", "role": "assistant", "type": "message"}], "parallel_tool_calls": true, "presence_penalty": null, "status": "completed", "temperature": null, "tool_choice": "auto", "tools": [], "top_p": null}, "request_id": "", "status_code": 296735}}], "status": "in_progress", "usage": {"completion_tokens": 323461, "prompt_tokens": 784076, "total_tokens": 757531}} @@ -20062,7 +20122,7 @@ examples: application/json: {"error": {"code": 400, "message": "custom_id is required on requests[0]."}} responses: requestBody: - application/json: {"completion_window": "24h", "endpoint": "/v1/responses", "model": "openai/gpt-4o", "requests": [{"body": {"input": [{"content": [{"text": "Summarize ...", "type": "input_text"}], "role": "user"}], "model": "openai/gpt-4o"}, "custom_id": "req-0001"}]} + application/json: {"completion_window": "24h", "endpoint": "/v1/responses", "model": "openai/gpt-4o"} responses: "202": application/json: {"completion_window": "24h", "created_at": 511243, "endpoint": "", "error": {"message": ""}, "expires_at": 239149, "finalized_at": 665164, "id": "", "model": "CX-9", "object": "batch", "provider": "", "request_counts": {"completed": 719289, "failed": 238478, "total": 928444}, "results": [{"custom_id": "", "error": {"message": "", "param": "", "type": ""}, "id": "", "response": {"body": {"completed_at": 1704067210, "created_at": 1704067200, "error": null, "frequency_penalty": null, "id": "resp-abc123", "incomplete_details": null, "instructions": null, "metadata": null, "model": "gpt-4", "object": "response", "output": [{"content": [{"text": "Hello! How can I help you today?", "type": "output_text"}], "id": "msg-abc123", "role": "assistant", "type": "message"}], "parallel_tool_calls": true, "presence_penalty": null, "status": "completed", "temperature": null, "tool_choice": "auto", "tools": [], "top_p": null}, "request_id": "", "status_code": 296735}}], "status": "in_progress", "usage": {"completion_tokens": 323461, "prompt_tokens": 784076, "total_tokens": 757531}} @@ -20072,7 +20132,7 @@ examples: application/json: {"error": {"code": 400, "message": "custom_id is required on requests[0]."}} speakeasy-default-create-batches: requestBody: - application/json: {"completion_window": "24h", "endpoint": "/v1/responses", "model": "Land Cruiser", "requests": [{"body": {"key": "", "key1": "", "key2": ""}, "custom_id": ""}]} + application/json: {"completion_window": "24h", "endpoint": "/v1/responses", "model": "Land Cruiser"} responses: "202": application/json: {"completion_window": "24h", "created_at": 511243, "endpoint": "", "error": {"message": ""}, "expires_at": 239149, "finalized_at": 665164, "id": "", "model": "CX-9", "object": "batch", "provider": "", "request_counts": {"completed": 719289, "failed": 238478, "total": 928444}, "results": [{"custom_id": "", "error": {"message": "", "param": "", "type": ""}, "id": "", "response": {"body": {"completed_at": 1704067210, "created_at": 1704067200, "error": null, "frequency_penalty": null, "id": "resp-abc123", "incomplete_details": null, "instructions": null, "metadata": null, "model": "gpt-4", "object": "response", "output": [{"content": [{"text": "Hello! How can I help you today?", "type": "output_text"}], "id": "msg-abc123", "role": "assistant", "type": "message"}], "parallel_tool_calls": true, "presence_penalty": null, "status": "completed", "temperature": null, "tool_choice": "auto", "tools": [], "top_p": null}, "request_id": "", "status_code": 296735}}], "status": "in_progress", "usage": {"completion_tokens": 323461, "prompt_tokens": 784076, "total_tokens": 757531}} @@ -21649,4 +21709,4 @@ examples: "500": application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: "## Python SDK Changes:\n* `open_router.batch.create_batches()`: `response.results[].response.body.union(OpenResponsesResult).output[].union(openrouter:web_fetch).retrieved_at` **Added**\n* `open_router.batch.get_batches()`: `response.results[].response.body.union(OpenResponsesResult).output[].union(openrouter:web_fetch).retrieved_at` **Added**\n* `open_router.presets.create_presets_responses()`: \n * `request.input.union(Array<>)[].union(OutputWebFetchServerToolItem).retrieved_at` **Added**\n" +releaseNotes: "## Python SDK Changes:\n* `open_router.batch.list()`: `response.data[].output` **Added**\n* `open_router.batch.create_batches()`: \n * `request` **Changed**\n * `response.output` **Added**\n* `open_router.batch.get_batches()`: \n * `response.output` **Added**\n * `error.output` **Added**\n" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index 6da26bc54..6cf6d12c6 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -37,7 +37,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true python: - version: 1.3.173 + version: 1.3.174 additionalDependencies: dev: pytest: '>=8.3' diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 18fbdb7c4..9737cf31d 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -5285,6 +5285,17 @@ components: required: - 'error' type: 'object' + BatchInputReference: + additionalProperties: false + description: 'A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only.' + properties: + uri: + description: 'Cloud Storage URI of the batch input file, in the form `gs://bucket/object`. The file stays in your bucket and must already be in the provider batch input format.' + example: 'gs://my-bucket/batches/input.jsonl' + type: 'string' + required: + - 'uri' + type: 'object' BatchListItem: description: 'Metadata-only batch object. `results` is always `null` in list responses.' properties: @@ -5322,6 +5333,8 @@ components: enum: - 'batch' type: 'string' + output: + $ref: '#/components/schemas/BatchOutputReference' provider: description: 'Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses.' type: @@ -5580,6 +5593,8 @@ components: enum: - 'batch' type: 'string' + output: + $ref: '#/components/schemas/BatchOutputReference' provider: description: 'Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses.' type: @@ -6562,6 +6577,16 @@ components: - 'results' - 'error' type: 'object' + BatchOutputReference: + description: 'The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.' + properties: + uri: + description: 'URI of the batch output in your own storage. For a Cloud Storage input file it is the output folder, in the form `gs://bucket/folder`, and the files are in the provider batch output format.' + example: 'gs://my-bucket/openrouter-batch/output/org_abc/batch_123/batch_123/prediction-model-2026-01-01T00:00:00.000000Z' + type: 'string' + required: + - 'uri' + type: 'object' BatchPaymentRequiredResponse: description: 'Batch metadata with results withheld (results: null) plus the standard error envelope. Add credits to unlock the already-computed results; the batch is not re-run.' properties: @@ -6600,6 +6625,8 @@ components: enum: - 'batch' type: 'string' + output: + $ref: '#/components/schemas/BatchOutputReference' provider: description: 'Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses.' type: @@ -6813,12 +6840,15 @@ components: - '/v1/audio/speech' type: 'string' x-speakeasy-unknown-values: allow + input: + $ref: '#/components/schemas/BatchInputReference' model: minLength: 1 type: 'string' provider: $ref: '#/components/schemas/BatchProviderPreferences' requests: + description: 'The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body.' items: properties: body: @@ -6837,7 +6867,6 @@ components: required: - 'endpoint' - 'model' - - 'requests' type: 'object' BooleanCapability: description: 'A supported-or-not flag. Present means the parameter is accepted.' @@ -16806,6 +16835,140 @@ components: - 'throughput' - 'request_count' type: 'object' + ImageGenerationLayer: + description: 'Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers).' + example: + background: 'transparent' + bounding_box: + absolute: + - 238 + - 124 + - 786 + - 673 + normalized: + - 232 + - 121 + - 768 + - 657 + description: 'A solid red circle' + name: 'Red circle' + z_index: 1 + properties: + background: + description: 'Whether the layer image has a transparent background' + enum: + - 'opaque' + - 'transparent' + type: 'string' + x-speakeasy-unknown-values: allow + bounding_box: + $ref: '#/components/schemas/ImageGenerationLayerBoundingBox' + description: + description: 'Provider description of the layer' + type: 'string' + name: + description: 'Short provider-assigned layer name' + type: 'string' + text_recognition: + $ref: '#/components/schemas/ImageGenerationLayerTextRecognition' + z_index: + description: 'Stacking order; 0 is the opaque base image and higher values sit on top' + type: 'integer' + required: + - 'z_index' + type: 'object' + ImageGenerationLayerBoundingBox: + description: 'Where a layer sits on the base image' + example: + absolute: + - 238 + - 124 + - 786 + - 673 + normalized: + - 232 + - 121 + - 768 + - 657 + properties: + absolute: + description: 'Layer box in pixels of the base image, as `[x_min, y_min, x_max, y_max]`' + items: + type: 'integer' + maxItems: 4 + minItems: 4 + type: 'array' + normalized: + description: 'Layer box scaled to 0-1000 on each axis, as `[x_min, y_min, x_max, y_max]`' + items: + type: 'integer' + maxItems: 4 + minItems: 4 + type: 'array' + required: + - 'absolute' + - 'normalized' + type: 'object' + ImageGenerationLayerTextRecognition: + description: 'Text found in the layer, present when the provider ran text recognition' + example: + lines: + - bounding_box: + absolute: + - 238 + - 124 + - 786 + - 673 + normalized: + - 232 + - 121 + - 768 + - 657 + runs: + - text: 'SALE' + text: 'SALE' + properties: + lines: + items: + properties: + bounding_box: + $ref: '#/components/schemas/ImageGenerationLayerBoundingBox' + runs: + items: + $ref: '#/components/schemas/ImageGenerationLayerTextRun' + type: 'array' + required: + - 'runs' + type: 'object' + type: 'array' + text: + description: 'Full text recognized in the layer' + type: 'string' + required: + - 'text' + type: 'object' + ImageGenerationLayerTextRun: + description: 'A run of text that shares one style' + example: + style: + bold: true + similar_font_family: 'Menlo' + text: 'SALE' + properties: + style: + additionalProperties: + anyOf: + - type: 'string' + - type: 'boolean' + - format: 'double' + type: 'number' + description: 'Font and style the provider recognized for this run, e.g. `similar_font_family`, `foreground_color`, `bold`' + type: 'object' + text: + type: 'string' + required: + - 'text' + type: 'object' ImageGenerationProviderPreferences: description: 'Provider routing preferences and provider-specific passthrough configuration.' example: @@ -17045,6 +17208,8 @@ components: b64_json: description: 'Base64-encoded image bytes' type: 'string' + layer: + $ref: '#/components/schemas/ImageGenerationLayer' media_type: description: 'Media type (MIME type) of the image, e.g. `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`. May be omitted if the format could not be determined.' example: 'image/png' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index f906135ab..d8530f0f1 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:4100c04773812225ff2a16b50da56fd1c8f7429c2113fb26f45000a777a5ad1d - sourceBlobDigest: sha256:157c2988d2ec07340dcc3c2aad865382d0bd1692432d82b712928c6efc6ba4bb + sourceRevisionDigest: sha256:f13ca5625de6da93692c286f2ea9582d47416366895c704efd83a37610af9083 + sourceBlobDigest: sha256:5efffcadb17c704cfdfe2afd0993653a1dee468b27c65dbd75bf33762477ad31 tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: open-router: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:4100c04773812225ff2a16b50da56fd1c8f7429c2113fb26f45000a777a5ad1d - sourceBlobDigest: sha256:157c2988d2ec07340dcc3c2aad865382d0bd1692432d82b712928c6efc6ba4bb + sourceRevisionDigest: sha256:f13ca5625de6da93692c286f2ea9582d47416366895c704efd83a37610af9083 + sourceBlobDigest: sha256:5efffcadb17c704cfdfe2afd0993653a1dee468b27c65dbd75bf33762477ad31 codeSamplesNamespace: open-router-python-code-samples - codeSamplesRevisionDigest: sha256:76b299f5f1bc5cdb7980e207dad7b5507f940a2bc978001220b94f61c8230718 + codeSamplesRevisionDigest: sha256:744f2ff6d8d2dcdb17a5d6e2fbef7125f9b2de0c2b49cd290859908cd78d67db workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.803.2 diff --git a/RELEASES.md b/RELEASES.md index 7c01e0962..c69143004 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -4499,4 +4499,14 @@ Based on: ### Generated - [python v1.3.173] . ### Releases -- [PyPI v1.3.173] https://pypi.org/project/openrouter/1.3.173 - . \ No newline at end of file +- [PyPI v1.3.173] https://pypi.org/project/openrouter/1.3.173 - . + +## 2026-11-13 07:07:26 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy +### Generated +- [python v1.3.174] . +### Releases +- [PyPI v1.3.174] https://pypi.org/project/openrouter/1.3.174 - . \ No newline at end of file diff --git a/docs/components/batchinputreference.mdx b/docs/components/batchinputreference.mdx new file mode 100644 index 000000000..efd0f12da --- /dev/null +++ b/docs/components/batchinputreference.mdx @@ -0,0 +1,12 @@ +--- +title: "BatchInputReference" +--- + +A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `uri` | *str* | ✔️ | Cloud Storage URI of the batch input file, in the form `gs://bucket/object`. The file stays in your bucket and must already be in the provider batch input format. | gs://my-bucket/batches/input.jsonl | \ No newline at end of file diff --git a/docs/components/batchlistitem.mdx b/docs/components/batchlistitem.mdx index b8b1a0d5c..b9557da4d 100644 --- a/docs/components/batchlistitem.mdx +++ b/docs/components/batchlistitem.mdx @@ -18,6 +18,7 @@ Metadata-only batch object. `results` is always `null` in list responses. | `id` | *str* | ✔️ | N/A | | `model` | *str* | ✔️ | N/A | | `object` | [components.BatchListItemObject](../components/batchlistitemobject.mdx) | ✔️ | N/A | +| `output` | [Optional[components.BatchOutputReference]](../components/batchoutputreference.mdx) | ➖ | The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out. | | `provider` | *Nullable[str]* | ✔️ | Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses. | | `request_counts` | [components.BatchListItemRequestCounts](../components/batchlistitemrequestcounts.mdx) | ✔️ | N/A | | `results` | *Nullable[Any]* | ✔️ | Always null: retrieve the batch with `GET /batches/{id}` to access its results. | diff --git a/docs/components/batchobject.mdx b/docs/components/batchobject.mdx index cfdad69c7..9980ba5d8 100644 --- a/docs/components/batchobject.mdx +++ b/docs/components/batchobject.mdx @@ -15,6 +15,7 @@ title: "BatchObject" | `id` | *str* | ✔️ | N/A | | `model` | *str* | ✔️ | N/A | | `object` | [components.BatchObjectObjectBatch](../components/batchobjectobjectbatch.mdx) | ✔️ | N/A | +| `output` | [Optional[components.BatchOutputReference]](../components/batchoutputreference.mdx) | ➖ | The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out. | | `provider` | *Nullable[str]* | ✔️ | Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses. | | `request_counts` | [components.BatchObjectRequestCounts](../components/batchobjectrequestcounts.mdx) | ✔️ | N/A | | `results` | List[[components.Result](../components/result.mdx)] | ✔️ | N/A | diff --git a/docs/components/batchoutputreference.mdx b/docs/components/batchoutputreference.mdx new file mode 100644 index 000000000..569d717d3 --- /dev/null +++ b/docs/components/batchoutputreference.mdx @@ -0,0 +1,12 @@ +--- +title: "BatchOutputReference" +--- + +The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out. + + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `uri` | *str* | ✔️ | URI of the batch output in your own storage. For a Cloud Storage input file it is the output folder, in the form `gs://bucket/folder`, and the files are in the provider batch output format. | gs://my-bucket/openrouter-batch/output/org_abc/batch_123/batch_123/prediction-model-2026-01-01T00:00:00.000000Z | \ No newline at end of file diff --git a/docs/components/batchsubmitbody.mdx b/docs/components/batchsubmitbody.mdx index 9ee22fec7..ae6c0959f 100644 --- a/docs/components/batchsubmitbody.mdx +++ b/docs/components/batchsubmitbody.mdx @@ -12,6 +12,7 @@ Batch submit request body. | `callback_url` | *Optional[str]* | ➖ | HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body. | | | `completion_window` | [Optional[components.BatchSubmitBodyCompletionWindow]](../components/batchsubmitbodycompletionwindow.mdx) | ➖ | N/A | | | `endpoint` | [components.Endpoint](../components/endpoint.mdx) | ✔️ | N/A | | +| `input` | [Optional[components.BatchInputReference]](../components/batchinputreference.mdx) | ➖ | A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only. | | | `model` | *str* | ✔️ | N/A | | | `provider` | [OptionalNullable[components.BatchProviderPreferences]](../components/batchproviderpreferences.mdx) | ➖ | Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported. | \{
"only": [
"google-vertex"
]
} | -| `requests` | List[[components.Request](../components/request.mdx)] | ✔️ | N/A | | \ No newline at end of file +| `requests` | List[[components.Request](../components/request.mdx)] | ➖ | The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body. | | \ No newline at end of file diff --git a/docs/components/imagegenerationlayer.mdx b/docs/components/imagegenerationlayer.mdx new file mode 100644 index 000000000..0f210b4bc --- /dev/null +++ b/docs/components/imagegenerationlayer.mdx @@ -0,0 +1,17 @@ +--- +title: "ImageGenerationLayer" +--- + +Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers). + + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `background` | [Optional[components.ImageGenerationLayerBackground]](../components/imagegenerationlayerbackground.mdx) | ➖ | Whether the layer image has a transparent background | | +| `bounding_box` | [Optional[components.ImageGenerationLayerBoundingBox]](../components/imagegenerationlayerboundingbox.mdx) | ➖ | Where a layer sits on the base image | \{
"absolute": [
238,
124,
786,
673
],
"normalized": [
232,
121,
768,
657
]
} | +| `description` | *Optional[str]* | ➖ | Provider description of the layer | | +| `name` | *Optional[str]* | ➖ | Short provider-assigned layer name | | +| `text_recognition` | [Optional[components.ImageGenerationLayerTextRecognition]](../components/imagegenerationlayertextrecognition.mdx) | ➖ | Text found in the layer, present when the provider ran text recognition | \{
"lines": [
\{
"bounding_box": \{
"absolute": [
238,
124,
786,
673
],
"normalized": [
232,
121,
768,
657
]
},
"runs": [
\{
"text": "SALE"
}
]
}
],
"text": "SALE"
} | +| `z_index` | *int* | ✔️ | Stacking order; 0 is the opaque base image and higher values sit on top | | \ No newline at end of file diff --git a/docs/components/imagegenerationlayerbackground.mdx b/docs/components/imagegenerationlayerbackground.mdx new file mode 100644 index 000000000..12014328c --- /dev/null +++ b/docs/components/imagegenerationlayerbackground.mdx @@ -0,0 +1,22 @@ +--- +title: "ImageGenerationLayerBackground" +--- + +Whether the layer image has a transparent background + +## Example Usage + +```python +from openrouter.components import ImageGenerationLayerBackground + +# Open enum: unrecognized values are captured as UnrecognizedStr +value: ImageGenerationLayerBackground = "opaque" +``` + + +## Values + +This is an open enum. Unrecognized values will not fail type checks. + +- `"opaque"` +- `"transparent"` diff --git a/docs/components/imagegenerationlayerboundingbox.mdx b/docs/components/imagegenerationlayerboundingbox.mdx new file mode 100644 index 000000000..930f2d77a --- /dev/null +++ b/docs/components/imagegenerationlayerboundingbox.mdx @@ -0,0 +1,13 @@ +--- +title: "ImageGenerationLayerBoundingBox" +--- + +Where a layer sits on the base image + + +## Fields + +| Field | Type | Required | Description | +| -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------- | +| `absolute` | List[*int*] | ✔️ | Layer box in pixels of the base image, as `[x_min, y_min, x_max, y_max]` | +| `normalized` | List[*int*] | ✔️ | Layer box scaled to 0-1000 on each axis, as `[x_min, y_min, x_max, y_max]` | \ No newline at end of file diff --git a/docs/components/imagegenerationlayertextrecognition.mdx b/docs/components/imagegenerationlayertextrecognition.mdx new file mode 100644 index 000000000..24551bc08 --- /dev/null +++ b/docs/components/imagegenerationlayertextrecognition.mdx @@ -0,0 +1,13 @@ +--- +title: "ImageGenerationLayerTextRecognition" +--- + +Text found in the layer, present when the provider ran text recognition + + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | ---------------------------------------------- | +| `lines` | List[[components.Line](../components/line.mdx)] | ➖ | N/A | +| `text` | *str* | ✔️ | Full text recognized in the layer | \ No newline at end of file diff --git a/docs/components/imagegenerationlayertextrun.mdx b/docs/components/imagegenerationlayertextrun.mdx new file mode 100644 index 000000000..bcce3f327 --- /dev/null +++ b/docs/components/imagegenerationlayertextrun.mdx @@ -0,0 +1,13 @@ +--- +title: "ImageGenerationLayerTextRun" +--- + +A run of text that shares one style + + +## Fields + +| Field | Type | Required | Description | +| ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | +| `style` | Dict[str, [components.Style](../components/style.mdx)] | ➖ | Font and style the provider recognized for this run, e.g. `similar_font_family`, `foreground_color`, `bold` | +| `text` | *str* | ✔️ | N/A | \ No newline at end of file diff --git a/docs/components/imagegenerationresponsedata.mdx b/docs/components/imagegenerationresponsedata.mdx index 1f1b31c9c..3b470b255 100644 --- a/docs/components/imagegenerationresponsedata.mdx +++ b/docs/components/imagegenerationresponsedata.mdx @@ -4,7 +4,8 @@ title: "ImageGenerationResponseData" ## Fields -| Field | Type | Required | Description | Example | -| --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `b64_json` | *str* | ✔️ | Base64-encoded image bytes | | -| `media_type` | *Optional[str]* | ➖ | Media type (MIME type) of the image, e.g. `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`. May be omitted if the format could not be determined. | image/png | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `b64_json` | *str* | ✔️ | Base64-encoded image bytes | | +| `layer` | [Optional[components.ImageGenerationLayer]](../components/imagegenerationlayer.mdx) | ➖ | Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers). | \{
"background": "transparent",
"bounding_box": \{
"absolute": [
238,
124,
786,
673
],
"normalized": [
232,
121,
768,
657
]
},
"description": "A solid red circle",
"name": "Red circle",
"z_index": 1
} | +| `media_type` | *Optional[str]* | ➖ | Media type (MIME type) of the image, e.g. `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`. May be omitted if the format could not be determined. | image/png | \ No newline at end of file diff --git a/docs/components/line.mdx b/docs/components/line.mdx new file mode 100644 index 000000000..b81b579a5 --- /dev/null +++ b/docs/components/line.mdx @@ -0,0 +1,10 @@ +--- +title: "Line" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | +| `bounding_box` | [Optional[components.ImageGenerationLayerBoundingBox]](../components/imagegenerationlayerboundingbox.mdx) | ➖ | Where a layer sits on the base image | \{
"absolute": [
238,
124,
786,
673
],
"normalized": [
232,
121,
768,
657
]
} | +| `runs` | List[[components.ImageGenerationLayerTextRun](../components/imagegenerationlayertextrun.mdx)] | ✔️ | N/A | | \ No newline at end of file diff --git a/docs/components/style.mdx b/docs/components/style.mdx new file mode 100644 index 000000000..8cf7766c8 --- /dev/null +++ b/docs/components/style.mdx @@ -0,0 +1,24 @@ +--- +title: "Style" +--- + +## Supported Types + +### `str` + +```python +value: str = /* values here */ +``` + +### `bool` + +```python +value: bool = /* values here */ +``` + +### `float` + +```python +value: float = /* values here */ +``` + diff --git a/docs/errors/batchpaymentrequiredresponseerror.mdx b/docs/errors/batchpaymentrequiredresponseerror.mdx index d6153b7ad..bcd883fac 100644 --- a/docs/errors/batchpaymentrequiredresponseerror.mdx +++ b/docs/errors/batchpaymentrequiredresponseerror.mdx @@ -18,6 +18,7 @@ Batch metadata with results withheld (results: null) plus the standard error env | `id` | *str* | ✔️ | N/A | | `model` | *str* | ✔️ | N/A | | `object` | [components.BatchPaymentRequiredResponseObject](../components/batchpaymentrequiredresponseobject.mdx) | ✔️ | N/A | +| `output` | [Optional[components.BatchOutputReference]](../components/batchoutputreference.mdx) | ➖ | The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out. | | `provider` | *Nullable[str]* | ✔️ | Provider OpenRouter assigned to run the batch, using the same name as the `provider` field of sync responses. | | `request_counts` | [components.BatchPaymentRequiredResponseRequestCounts](../components/batchpaymentrequiredresponserequestcounts.mdx) | ✔️ | N/A | | `results` | *Nullable[Any]* | ✔️ | Always null: results are withheld until the batch charge is covered. | diff --git a/docs/sdks/batch/README.mdx b/docs/sdks/batch/README.mdx index 545e4c043..da036c8d6 100644 --- a/docs/sdks/batch/README.mdx +++ b/docs/sdks/batch/README.mdx @@ -85,20 +85,7 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.batch.create_batches(endpoint="/v1/chat/completions", model="openai/gpt-4o", requests=[ - { - "body": { - "messages": [ - { - "content": "Summarize ...", - "role": "user", - }, - ], - "model": "openai/gpt-4o", - }, - "custom_id": "req-0001", - }, - ], completion_window="24h") + res = open_router.batch.create_batches(endpoint="/v1/chat/completions", model="openai/gpt-4o", completion_window="24h") # Handle response print(res) @@ -118,21 +105,7 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.batch.create_batches(endpoint="/v1/messages", model="openai/gpt-5-nano", requests=[ - { - "body": { - "max_tokens": 1024, - "messages": [ - { - "content": "Summarize ...", - "role": "user", - }, - ], - "model": "openai/gpt-5-nano", - }, - "custom_id": "req-0001", - }, - ], completion_window="24h") + res = open_router.batch.create_batches(endpoint="/v1/messages", model="openai/gpt-5-nano", completion_window="24h") # Handle response print(res) @@ -152,20 +125,7 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.batch.create_batches(endpoint="/v1/chat/completions", model="google/gemini-3.6-flash", requests=[ - { - "body": { - "messages": [ - { - "content": "Summarize ...", - "role": "user", - }, - ], - "model": "google/gemini-3.6-flash", - }, - "custom_id": "req-0001", - }, - ], completion_window="24h") + res = open_router.batch.create_batches(endpoint="/v1/chat/completions", model="google/gemini-3.6-flash", completion_window="24h") # Handle response print(res) @@ -185,25 +145,7 @@ with OpenRouter( api_key=os.getenv("OPENROUTER_API_KEY", ""), ) as open_router: - res = open_router.batch.create_batches(endpoint="/v1/responses", model="openai/gpt-4o", requests=[ - { - "body": { - "input": [ - { - "content": [ - { - "text": "Summarize ...", - "type": "input_text", - }, - ], - "role": "user", - }, - ], - "model": "openai/gpt-4o", - }, - "custom_id": "req-0001", - }, - ], completion_window="24h") + res = open_router.batch.create_batches(endpoint="/v1/responses", model="openai/gpt-4o", completion_window="24h") # Handle response print(res) @@ -216,13 +158,14 @@ with OpenRouter( | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `endpoint` | [components.Endpoint](../../components/endpoint.mdx) | ✔️ | N/A | | | `model` | *str* | ✔️ | N/A | | -| `requests` | List[[components.Request](../../components/request.mdx)] | ✔️ | N/A | | | `http_referer` | *Optional[str]* | ➖ | The app identifier should be your app's URL and is used as the primary identifier for rankings.
This is used to track API usage per application.
| | | `x_open_router_title` | *Optional[str]* | ➖ | The app display name allows you to customize how your app appears in OpenRouter's dashboard.
| | | `x_open_router_categories` | *Optional[str]* | ➖ | Comma-separated list of app categories (e.g. "cli-agent,cloud-agent"). Used for marketplace rankings.
| | | `callback_url` | *Optional[str]* | ➖ | HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body. | | | `completion_window` | [Optional[components.BatchSubmitBodyCompletionWindow]](../../components/batchsubmitbodycompletionwindow.mdx) | ➖ | N/A | | +| `input` | [Optional[components.BatchInputReference]](../../components/batchinputreference.mdx) | ➖ | A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only. | | | `provider` | [OptionalNullable[components.BatchProviderPreferences]](../../components/batchproviderpreferences.mdx) | ➖ | Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported. | \{
"only": [
"google-vertex"
]
} | +| `requests` | List[[components.Request](../../components/request.mdx)] | ➖ | The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body. | | | `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | ➖ | Configuration to override the default retry behavior of the client. | | ### Response diff --git a/pyproject.toml b/pyproject.toml index e59d19d3b..bf40014fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openrouter" -version = "1.3.173" +version = "1.3.174" 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 0a73b37da..a264f3b4c 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.173" +__version__: str = "1.3.174" __openapi_doc_version__: str = "1.0.0" __gen_version__: str = "2.950.13" -__user_agent__: str = "speakeasy-sdk/python 1.3.173 2.950.13 1.0.0 openrouter" +__user_agent__: str = "speakeasy-sdk/python 1.3.174 2.950.13 1.0.0 openrouter" try: if __package__ is not None: diff --git a/src/openrouter/batch.py b/src/openrouter/batch.py index e7a0b932c..abb2983f0 100644 --- a/src/openrouter/batch.py +++ b/src/openrouter/batch.py @@ -357,20 +357,25 @@ def create_batches( *, endpoint: components.Endpoint, model: str, - requests: Union[ - Iterable[components.Request], Iterable[components.RequestTypedDict] - ], http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, callback_url: Optional[str] = None, completion_window: Optional[components.BatchSubmitBodyCompletionWindow] = "24h", + input: Optional[ + Union[ + components.BatchInputReference, components.BatchInputReferenceTypedDict + ] + ] = None, provider: OptionalNullable[ Union[ components.BatchProviderPreferences, components.BatchProviderPreferencesTypedDict, ] ] = UNSET, + requests: Optional[ + Union[Iterable[components.Request], Iterable[components.RequestTypedDict]] + ] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -382,7 +387,6 @@ def create_batches( :param endpoint: :param model: - :param requests: :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. This is used to track API usage per application. @@ -392,7 +396,9 @@ def create_batches( :param callback_url: HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body. :param completion_window: + :param input: A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only. :param provider: Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported. + :param requests: The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method :param timeout_ms: Override the default request timeout configuration for this method in milliseconds @@ -416,11 +422,16 @@ def create_batches( callback_url=callback_url, completion_window=completion_window, endpoint=endpoint, + input=utils.get_pydantic_model( + input, Optional[components.BatchInputReference] + ), model=model, provider=utils.get_pydantic_model( provider, OptionalNullable[components.BatchProviderPreferences] ), - requests=utils.get_pydantic_model(requests, List[components.Request]), + requests=utils.get_pydantic_model( + requests, Optional[List[components.Request]] + ), ), ) @@ -517,20 +528,25 @@ async def create_batches_async( *, endpoint: components.Endpoint, model: str, - requests: Union[ - Iterable[components.Request], Iterable[components.RequestTypedDict] - ], http_referer: Optional[str] = None, x_open_router_title: Optional[str] = None, x_open_router_categories: Optional[str] = None, callback_url: Optional[str] = None, completion_window: Optional[components.BatchSubmitBodyCompletionWindow] = "24h", + input: Optional[ + Union[ + components.BatchInputReference, components.BatchInputReferenceTypedDict + ] + ] = None, provider: OptionalNullable[ Union[ components.BatchProviderPreferences, components.BatchProviderPreferencesTypedDict, ] ] = UNSET, + requests: Optional[ + Union[Iterable[components.Request], Iterable[components.RequestTypedDict]] + ] = None, retries: OptionalNullable[utils.RetryConfig] = UNSET, server_url: Optional[str] = None, timeout_ms: Optional[int] = None, @@ -542,7 +558,6 @@ async def create_batches_async( :param endpoint: :param model: - :param requests: :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings. This is used to track API usage per application. @@ -552,7 +567,9 @@ async def create_batches_async( :param callback_url: HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body. :param completion_window: + :param input: A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only. :param provider: Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported. + :param requests: The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body. :param retries: Override the default retry configuration for this method :param server_url: Override the default server URL for this method :param timeout_ms: Override the default request timeout configuration for this method in milliseconds @@ -576,11 +593,16 @@ async def create_batches_async( callback_url=callback_url, completion_window=completion_window, endpoint=endpoint, + input=utils.get_pydantic_model( + input, Optional[components.BatchInputReference] + ), model=model, provider=utils.get_pydantic_model( provider, OptionalNullable[components.BatchProviderPreferences] ), - requests=utils.get_pydantic_model(requests, List[components.Request]), + requests=utils.get_pydantic_model( + requests, Optional[List[components.Request]] + ), ), ) diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py index cfdfb3cf4..0ade14c3f 100644 --- a/src/openrouter/components/__init__.py +++ b/src/openrouter/components/__init__.py @@ -822,6 +822,7 @@ BatchErrorResponseError, BatchErrorResponseErrorTypedDict, ) + from .batchinputreference import BatchInputReference, BatchInputReferenceTypedDict from .batchlistitem import ( BatchListItem, BatchListItemCompletionTokensDetails, @@ -980,6 +981,10 @@ WebSearchCitation, WebSearchCitationTypedDict, ) + from .batchoutputreference import ( + BatchOutputReference, + BatchOutputReferenceTypedDict, + ) from .batchpaymentrequiredresponse_error import ( BatchPaymentRequiredResponseCompletionTokensDetails, BatchPaymentRequiredResponseCompletionTokensDetailsTypedDict, @@ -2463,6 +2468,27 @@ ImageGenCompletedEventTypedDict, ) from .imagegeneration import ImageGeneration, ImageGenerationTypedDict + from .imagegenerationlayer import ( + ImageGenerationLayer, + ImageGenerationLayerBackground, + ImageGenerationLayerTypedDict, + ) + from .imagegenerationlayerboundingbox import ( + ImageGenerationLayerBoundingBox, + ImageGenerationLayerBoundingBoxTypedDict, + ) + from .imagegenerationlayertextrecognition import ( + ImageGenerationLayerTextRecognition, + ImageGenerationLayerTextRecognitionTypedDict, + Line, + LineTypedDict, + ) + from .imagegenerationlayertextrun import ( + ImageGenerationLayerTextRun, + ImageGenerationLayerTextRunTypedDict, + Style, + StyleTypedDict, + ) from .imagegenerationproviderpreferences import ( ImageGenerationProviderPreferences, ImageGenerationProviderPreferencesIgnore, @@ -5640,6 +5666,8 @@ "BatchDeletionTargetsTypedDict", "BatchErrorResponseError", "BatchErrorResponseErrorTypedDict", + "BatchInputReference", + "BatchInputReferenceTypedDict", "BatchListItem", "BatchListItemCompletionTokensDetails", "BatchListItemCompletionTokensDetailsTypedDict", @@ -5701,6 +5729,8 @@ "BatchObjectURLCitationTypedDict", "BatchObjectUsage", "BatchObjectUsageTypedDict", + "BatchOutputReference", + "BatchOutputReferenceTypedDict", "BatchPaymentRequiredResponseCompletionTokensDetails", "BatchPaymentRequiredResponseCompletionTokensDetailsTypedDict", "BatchPaymentRequiredResponseCompletionWindow", @@ -6813,6 +6843,15 @@ "ImageGenTextChunkEventType", "ImageGenTextChunkEventTypedDict", "ImageGeneration", + "ImageGenerationLayer", + "ImageGenerationLayerBackground", + "ImageGenerationLayerBoundingBox", + "ImageGenerationLayerBoundingBoxTypedDict", + "ImageGenerationLayerTextRecognition", + "ImageGenerationLayerTextRecognitionTypedDict", + "ImageGenerationLayerTextRun", + "ImageGenerationLayerTextRunTypedDict", + "ImageGenerationLayerTypedDict", "ImageGenerationProviderPreferences", "ImageGenerationProviderPreferencesIgnore", "ImageGenerationProviderPreferencesIgnoreTypedDict", @@ -7001,6 +7040,8 @@ "LegacyWebSearchServerToolTypedDict", "Legend", "LegendTypedDict", + "Line", + "LineTypedDict", "ListAccountGuardrailPoliciesResponse", "ListAccountGuardrailPoliciesResponseTypedDict", "ListBYOKKeysResponse", @@ -8357,6 +8398,8 @@ "StreamLogprobTopLogprob", "StreamLogprobTopLogprobTypedDict", "StreamLogprobTypedDict", + "Style", + "StyleTypedDict", "SubagentNestedTool", "SubagentNestedToolTypedDict", "SubagentReasoning", @@ -9384,6 +9427,8 @@ "UpstreamTypedDict": ".batchdeletiontargets", "BatchErrorResponseError": ".batcherrorresponse", "BatchErrorResponseErrorTypedDict": ".batcherrorresponse", + "BatchInputReference": ".batchinputreference", + "BatchInputReferenceTypedDict": ".batchinputreference", "BatchListItem": ".batchlistitem", "BatchListItemCompletionTokensDetails": ".batchlistitem", "BatchListItemCompletionTokensDetailsTypedDict": ".batchlistitem", @@ -9536,6 +9581,8 @@ "UnknownReasoningDetail": ".batchobject", "WebSearchCitation": ".batchobject", "WebSearchCitationTypedDict": ".batchobject", + "BatchOutputReference": ".batchoutputreference", + "BatchOutputReferenceTypedDict": ".batchoutputreference", "BatchPaymentRequiredResponseCompletionTokensDetails": ".batchpaymentrequiredresponse_error", "BatchPaymentRequiredResponseCompletionTokensDetailsTypedDict": ".batchpaymentrequiredresponse_error", "BatchPaymentRequiredResponseCompletionWindow": ".batchpaymentrequiredresponse_error", @@ -10589,6 +10636,19 @@ "ImageGenCompletedEventTypedDict": ".imagegencompletedevent", "ImageGeneration": ".imagegeneration", "ImageGenerationTypedDict": ".imagegeneration", + "ImageGenerationLayer": ".imagegenerationlayer", + "ImageGenerationLayerBackground": ".imagegenerationlayer", + "ImageGenerationLayerTypedDict": ".imagegenerationlayer", + "ImageGenerationLayerBoundingBox": ".imagegenerationlayerboundingbox", + "ImageGenerationLayerBoundingBoxTypedDict": ".imagegenerationlayerboundingbox", + "ImageGenerationLayerTextRecognition": ".imagegenerationlayertextrecognition", + "ImageGenerationLayerTextRecognitionTypedDict": ".imagegenerationlayertextrecognition", + "Line": ".imagegenerationlayertextrecognition", + "LineTypedDict": ".imagegenerationlayertextrecognition", + "ImageGenerationLayerTextRun": ".imagegenerationlayertextrun", + "ImageGenerationLayerTextRunTypedDict": ".imagegenerationlayertextrun", + "Style": ".imagegenerationlayertextrun", + "StyleTypedDict": ".imagegenerationlayertextrun", "ImageGenerationProviderPreferences": ".imagegenerationproviderpreferences", "ImageGenerationProviderPreferencesIgnore": ".imagegenerationproviderpreferences", "ImageGenerationProviderPreferencesIgnoreTypedDict": ".imagegenerationproviderpreferences", diff --git a/src/openrouter/components/batchinputreference.py b/src/openrouter/components/batchinputreference.py new file mode 100644 index 000000000..3a72ddbd0 --- /dev/null +++ b/src/openrouter/components/batchinputreference.py @@ -0,0 +1,19 @@ +"""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 BatchInputReferenceTypedDict(TypedDict): + r"""A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only.""" + + uri: str + r"""Cloud Storage URI of the batch input file, in the form `gs://bucket/object`. The file stays in your bucket and must already be in the provider batch input format.""" + + +class BatchInputReference(BaseModel): + r"""A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only.""" + + uri: str + r"""Cloud Storage URI of the batch input file, in the form `gs://bucket/object`. The file stays in your bucket and must already be in the provider batch input format.""" diff --git a/src/openrouter/components/batchlistitem.py b/src/openrouter/components/batchlistitem.py index e35446f3f..47f692ea5 100644 --- a/src/openrouter/components/batchlistitem.py +++ b/src/openrouter/components/batchlistitem.py @@ -10,6 +10,7 @@ AnthropicUsageIteration, AnthropicUsageIterationTypedDict, ) +from .batchoutputreference import BatchOutputReference, BatchOutputReferenceTypedDict from .costdetails import CostDetails, CostDetailsTypedDict from openrouter.types import ( BaseModel, @@ -378,6 +379,8 @@ class BatchListItemTypedDict(TypedDict): r"""Always null: retrieve the batch with `GET /batches/{id}` to access its results.""" status: BatchListItemStatus usage: Nullable[BatchListItemUsageTypedDict] + output: NotRequired[BatchOutputReferenceTypedDict] + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" class BatchListItem(BaseModel): @@ -414,16 +417,32 @@ class BatchListItem(BaseModel): usage: Nullable[BatchListItemUsage] + output: Optional[BatchOutputReference] = None + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" + @model_serializer(mode="wrap") def serialize_model(self, handler): + optional_fields = set(["output"]) + nullable_fields = set( + ["error", "expires_at", "finalized_at", "provider", "results", "usage"] + ) 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: - m[k] = val + 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/batchobject.py b/src/openrouter/components/batchobject.py index aef368a29..73bf293c6 100644 --- a/src/openrouter/components/batchobject.py +++ b/src/openrouter/components/batchobject.py @@ -31,6 +31,7 @@ ) from .apierrortype import APIErrorType from .armorsafeguardresult import ArmorSafeguardResult, ArmorSafeguardResultTypedDict +from .batchoutputreference import BatchOutputReference, BatchOutputReferenceTypedDict from .costdetails import CostDetails, CostDetailsTypedDict from .finishreason import FinishReason from .openresponsesresult import OpenResponsesResult, OpenResponsesResultTypedDict @@ -2102,6 +2103,8 @@ class BatchObjectTypedDict(TypedDict): results: Nullable[List[ResultTypedDict]] status: BatchObjectStatus usage: Nullable[BatchObjectUsageTypedDict] + output: NotRequired[BatchOutputReferenceTypedDict] + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" class BatchObject(BaseModel): @@ -2135,17 +2138,33 @@ class BatchObject(BaseModel): usage: Nullable[BatchObjectUsage] + output: Optional[BatchOutputReference] = None + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" + @model_serializer(mode="wrap") def serialize_model(self, handler): + optional_fields = set(["output"]) + nullable_fields = set( + ["error", "expires_at", "finalized_at", "provider", "results", "usage"] + ) 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: - m[k] = val + 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/batchoutputreference.py b/src/openrouter/components/batchoutputreference.py new file mode 100644 index 000000000..41a4e7641 --- /dev/null +++ b/src/openrouter/components/batchoutputreference.py @@ -0,0 +1,19 @@ +"""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 BatchOutputReferenceTypedDict(TypedDict): + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" + + uri: str + r"""URI of the batch output in your own storage. For a Cloud Storage input file it is the output folder, in the form `gs://bucket/folder`, and the files are in the provider batch output format.""" + + +class BatchOutputReference(BaseModel): + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" + + uri: str + r"""URI of the batch output in your own storage. For a Cloud Storage input file it is the output folder, in the form `gs://bucket/folder`, and the files are in the provider batch output format.""" diff --git a/src/openrouter/components/batchsubmitbody.py b/src/openrouter/components/batchsubmitbody.py index 943fbb092..8262b20a4 100644 --- a/src/openrouter/components/batchsubmitbody.py +++ b/src/openrouter/components/batchsubmitbody.py @@ -1,6 +1,7 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations +from .batchinputreference import BatchInputReference, BatchInputReferenceTypedDict from .batchproviderpreferences import ( BatchProviderPreferences, BatchProviderPreferencesTypedDict, @@ -51,12 +52,15 @@ class BatchSubmitBodyTypedDict(TypedDict): endpoint: Endpoint model: str - requests: List[RequestTypedDict] callback_url: NotRequired[str] r"""HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body.""" completion_window: NotRequired[BatchSubmitBodyCompletionWindow] + input: NotRequired[BatchInputReferenceTypedDict] + r"""A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only.""" provider: NotRequired[Nullable[BatchProviderPreferencesTypedDict]] r"""Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported.""" + requests: NotRequired[List[RequestTypedDict]] + r"""The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body.""" class BatchSubmitBody(BaseModel): @@ -66,19 +70,25 @@ class BatchSubmitBody(BaseModel): model: str - requests: List[Request] - callback_url: Optional[str] = None r"""HTTPS URL that receives a `batch.completed`, `batch.failed`, `batch.cancelled` or `batch.expired` webhook event when the batch reaches a terminal status. Must appear before `requests` in the request body.""" completion_window: Optional[BatchSubmitBodyCompletionWindow] = "24h" + input: Optional[BatchInputReference] = None + r"""A batch input file in your own storage, named in place of `requests`. Available to allowlisted callers on Google Vertex BYOK endpoints only.""" + provider: OptionalNullable[BatchProviderPreferences] = UNSET r"""Batch provider routing preferences. Only `provider.only` and `provider.allow_fallbacks` are supported.""" + requests: Optional[List[Request]] = None + r"""The batch requests. Send exactly one of `requests` or `input`; `requests` must be the last field in the request body.""" + @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["callback_url", "completion_window", "provider"]) + optional_fields = set( + ["callback_url", "completion_window", "input", "provider", "requests"] + ) nullable_fields = set(["provider"]) serialized = handler(self) m = {} diff --git a/src/openrouter/components/imagegenerationlayer.py b/src/openrouter/components/imagegenerationlayer.py new file mode 100644 index 000000000..1e5b9d13b --- /dev/null +++ b/src/openrouter/components/imagegenerationlayer.py @@ -0,0 +1,82 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .imagegenerationlayerboundingbox import ( + ImageGenerationLayerBoundingBox, + ImageGenerationLayerBoundingBoxTypedDict, +) +from .imagegenerationlayertextrecognition import ( + ImageGenerationLayerTextRecognition, + ImageGenerationLayerTextRecognitionTypedDict, +) +from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr +from pydantic import model_serializer +from typing import Literal, Optional, Union +from typing_extensions import NotRequired, TypedDict + + +ImageGenerationLayerBackground = Union[ + Literal[ + "opaque", + "transparent", + ], + UnrecognizedStr, +] +r"""Whether the layer image has a transparent background""" + + +class ImageGenerationLayerTypedDict(TypedDict): + r"""Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers).""" + + z_index: int + r"""Stacking order; 0 is the opaque base image and higher values sit on top""" + background: NotRequired[ImageGenerationLayerBackground] + r"""Whether the layer image has a transparent background""" + bounding_box: NotRequired[ImageGenerationLayerBoundingBoxTypedDict] + r"""Where a layer sits on the base image""" + description: NotRequired[str] + r"""Provider description of the layer""" + name: NotRequired[str] + r"""Short provider-assigned layer name""" + text_recognition: NotRequired[ImageGenerationLayerTextRecognitionTypedDict] + r"""Text found in the layer, present when the provider ran text recognition""" + + +class ImageGenerationLayer(BaseModel): + r"""Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers).""" + + z_index: int + r"""Stacking order; 0 is the opaque base image and higher values sit on top""" + + background: Optional[ImageGenerationLayerBackground] = None + r"""Whether the layer image has a transparent background""" + + bounding_box: Optional[ImageGenerationLayerBoundingBox] = None + r"""Where a layer sits on the base image""" + + description: Optional[str] = None + r"""Provider description of the layer""" + + name: Optional[str] = None + r"""Short provider-assigned layer name""" + + text_recognition: Optional[ImageGenerationLayerTextRecognition] = None + r"""Text found in the layer, present when the provider ran text recognition""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set( + ["background", "bounding_box", "description", "name", "text_recognition"] + ) + 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/imagegenerationlayerboundingbox.py b/src/openrouter/components/imagegenerationlayerboundingbox.py new file mode 100644 index 000000000..4f30c5d08 --- /dev/null +++ b/src/openrouter/components/imagegenerationlayerboundingbox.py @@ -0,0 +1,25 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel +from typing import List +from typing_extensions import TypedDict + + +class ImageGenerationLayerBoundingBoxTypedDict(TypedDict): + r"""Where a layer sits on the base image""" + + absolute: List[int] + r"""Layer box in pixels of the base image, as `[x_min, y_min, x_max, y_max]`""" + normalized: List[int] + r"""Layer box scaled to 0-1000 on each axis, as `[x_min, y_min, x_max, y_max]`""" + + +class ImageGenerationLayerBoundingBox(BaseModel): + r"""Where a layer sits on the base image""" + + absolute: List[int] + r"""Layer box in pixels of the base image, as `[x_min, y_min, x_max, y_max]`""" + + normalized: List[int] + r"""Layer box scaled to 0-1000 on each axis, as `[x_min, y_min, x_max, y_max]`""" diff --git a/src/openrouter/components/imagegenerationlayertextrecognition.py b/src/openrouter/components/imagegenerationlayertextrecognition.py new file mode 100644 index 000000000..509bbcf49 --- /dev/null +++ b/src/openrouter/components/imagegenerationlayertextrecognition.py @@ -0,0 +1,77 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from .imagegenerationlayerboundingbox import ( + ImageGenerationLayerBoundingBox, + ImageGenerationLayerBoundingBoxTypedDict, +) +from .imagegenerationlayertextrun import ( + ImageGenerationLayerTextRun, + ImageGenerationLayerTextRunTypedDict, +) +from openrouter.types import BaseModel, UNSET_SENTINEL +from pydantic import model_serializer +from typing import List, Optional +from typing_extensions import NotRequired, TypedDict + + +class LineTypedDict(TypedDict): + runs: List[ImageGenerationLayerTextRunTypedDict] + bounding_box: NotRequired[ImageGenerationLayerBoundingBoxTypedDict] + r"""Where a layer sits on the base image""" + + +class Line(BaseModel): + runs: List[ImageGenerationLayerTextRun] + + bounding_box: Optional[ImageGenerationLayerBoundingBox] = None + r"""Where a layer sits on the base image""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["bounding_box"]) + 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 ImageGenerationLayerTextRecognitionTypedDict(TypedDict): + r"""Text found in the layer, present when the provider ran text recognition""" + + text: str + r"""Full text recognized in the layer""" + lines: NotRequired[List[LineTypedDict]] + + +class ImageGenerationLayerTextRecognition(BaseModel): + r"""Text found in the layer, present when the provider ran text recognition""" + + text: str + r"""Full text recognized in the layer""" + + lines: Optional[List[Line]] = None + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["lines"]) + 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/imagegenerationlayertextrun.py b/src/openrouter/components/imagegenerationlayertextrun.py new file mode 100644 index 000000000..9cb42cff1 --- /dev/null +++ b/src/openrouter/components/imagegenerationlayertextrun.py @@ -0,0 +1,46 @@ +"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" + +from __future__ import annotations +from openrouter.types import BaseModel, UNSET_SENTINEL +from pydantic import model_serializer +from typing import Dict, Optional, Union +from typing_extensions import NotRequired, TypeAliasType, TypedDict + + +StyleTypedDict = TypeAliasType("StyleTypedDict", Union[str, bool, float]) + + +Style = TypeAliasType("Style", Union[str, bool, float]) + + +class ImageGenerationLayerTextRunTypedDict(TypedDict): + r"""A run of text that shares one style""" + + text: str + style: NotRequired[Dict[str, StyleTypedDict]] + r"""Font and style the provider recognized for this run, e.g. `similar_font_family`, `foreground_color`, `bold`""" + + +class ImageGenerationLayerTextRun(BaseModel): + r"""A run of text that shares one style""" + + text: str + + style: Optional[Dict[str, Style]] = None + r"""Font and style the provider recognized for this run, e.g. `similar_font_family`, `foreground_color`, `bold`""" + + @model_serializer(mode="wrap") + def serialize_model(self, handler): + optional_fields = set(["style"]) + 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/imagegenerationresponse.py b/src/openrouter/components/imagegenerationresponse.py index 687008d32..3f2061536 100644 --- a/src/openrouter/components/imagegenerationresponse.py +++ b/src/openrouter/components/imagegenerationresponse.py @@ -1,6 +1,7 @@ """Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT.""" from __future__ import annotations +from .imagegenerationlayer import ImageGenerationLayer, ImageGenerationLayerTypedDict from .imagegenerationusage import ImageGenerationUsage, ImageGenerationUsageTypedDict from openrouter.types import BaseModel, UNSET_SENTINEL from pydantic import model_serializer @@ -11,6 +12,8 @@ class ImageGenerationResponseDataTypedDict(TypedDict): b64_json: str r"""Base64-encoded image bytes""" + layer: NotRequired[ImageGenerationLayerTypedDict] + r"""Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers).""" media_type: NotRequired[str] r"""Media type (MIME type) of the image, e.g. `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`. May be omitted if the format could not be determined.""" @@ -19,12 +22,15 @@ class ImageGenerationResponseData(BaseModel): b64_json: str r"""Base64-encoded image bytes""" + layer: Optional[ImageGenerationLayer] = None + r"""Layer metadata, present when the request asked the provider to split the image into layers (Seedream: `provider.options.seed.layer_decomposition: true` with the required `layer_decomposition_options.max_images`, 2 to 16). Decomposition requires `n` to be 1 or omitted; the response returns up to `max_images` images (the base image plus its layers).""" + media_type: Optional[str] = None r"""Media type (MIME type) of the image, e.g. `image/png`, `image/jpeg`, `image/webp`, `image/svg+xml`. May be omitted if the format could not be determined.""" @model_serializer(mode="wrap") def serialize_model(self, handler): - optional_fields = set(["media_type"]) + optional_fields = set(["layer", "media_type"]) serialized = handler(self) m = {} diff --git a/src/openrouter/errors/batchpaymentrequiredresponse_error.py b/src/openrouter/errors/batchpaymentrequiredresponse_error.py index 1b1e4508d..a2ef2962e 100644 --- a/src/openrouter/errors/batchpaymentrequiredresponse_error.py +++ b/src/openrouter/errors/batchpaymentrequiredresponse_error.py @@ -4,6 +4,7 @@ from dataclasses import dataclass, field import httpx from openrouter.components import ( + batchoutputreference as components_batchoutputreference, batchpaymentrequiredresponse_error as components_batchpaymentrequiredresponse_error, ) from openrouter.errors import OpenRouterError @@ -37,6 +38,8 @@ class BatchPaymentRequiredResponseErrorData(BaseModel): usage: Nullable[ components_batchpaymentrequiredresponse_error.BatchPaymentRequiredResponseUsage ] + output: Optional[components_batchoutputreference.BatchOutputReference] = None + r"""The output location of a batch submitted with `input`, whose `results` are `null`. Returned only by `GET /batches/{id}`, once the batch has ended and the provider reported an output folder. Batch lists and responses for a batch with an unpaid charge leave it out.""" @dataclass(unsafe_hash=True) diff --git a/uv.lock b/uv.lock index 4e4def99c..ef3bd9c52 100644 --- a/uv.lock +++ b/uv.lock @@ -231,7 +231,7 @@ wheels = [ [[package]] name = "openrouter" -version = "1.3.173" +version = "1.3.174" source = { editable = "." } dependencies = [ { name = "httpcore" },