diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock
index ffbc41b1..2950f3ae 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: bf7efebbd1334a05c1d10f0179e02638
+ docChecksum: ebb86fd9ee4754adb526de8106523587
docVersion: 1.0.0
speakeasyVersion: 1.803.2
generationVersion: 2.950.13
- releaseVersion: 1.3.97
- configChecksum: 144876b9db2a6c6394375ec606f1c8e1
+ releaseVersion: 1.3.98
+ configChecksum: f11ba8dca058b377b96226232678d3dc
repoURL: https://github.com/OpenRouterTeam/python-sdk.git
installationURL: https://github.com/OpenRouterTeam/python-sdk.git
published: true
persistentEdits:
- generation_id: fb7705d3-ce5f-404f-ba0d-243370cdd3e2
- pristine_commit_hash: 8d60b162a4f57caa5b7d01b6fc8a6cbcf0455d7c
- pristine_tree_hash: 20c9709ca0b5a07cd16df04f7a498bb8be745b1f
+ generation_id: 810b9860-9905-493e-a786-6b74d0b0fa7f
+ pristine_commit_hash: b96d41b05c7310535ab8d10569775fa47df2365a
+ pristine_tree_hash: 9a9bad552c0c93dad9a579038f7437948adf9eb4
features:
python:
acceptHeaders: 3.0.0
@@ -338,10 +338,6 @@ trackedFiles:
id: 3548da377e76
last_write_checksum: sha1:5971de690221bb04b13701125af0e0e5fd6005dc
pristine_git_object: d0e61b435d9ae4f0ffd0a4a13c4fd73564357d90
- docs/components/answers.mdx:
- id: 82e99c991e20
- last_write_checksum: sha1:5ef9a00452ff852a462ae1d311c98c677f84b160
- pristine_git_object: 43893fe77c341f9deeed76ad83ebb2800807c7ba
docs/components/anthropicadvisormessageusageiteration.mdx:
id: ca0effff715e
last_write_checksum: sha1:e6f879860ffd51e40118d0c2970fa39834395637
@@ -1184,8 +1180,8 @@ trackedFiles:
pristine_git_object: 53c45463b67a1365c2700f73ddb7330b048e79f0
docs/components/apitype.mdx:
id: 1a902c4c05f3
- last_write_checksum: sha1:16bd16cad6941c0f50ca57224d5792ae2efdc8dd
- pristine_git_object: d43e0f95c7d37c2a51033cebc9549b08d861f56d
+ last_write_checksum: sha1:b9635d894979098f1fc14257becdcf48a20e20fd
+ pristine_git_object: f5c299e575db8208331ab49fdb1b3a5460fe31f5
docs/components/app.mdx:
id: aa5cb5867777
last_write_checksum: sha1:4cf8185961b17ac1c29f800372c0056e974a863f
@@ -2960,8 +2956,12 @@ trackedFiles:
pristine_git_object: 66c77147a8e3e171803119890707e8a6c82c1874
docs/components/decisionsresponse.mdx:
id: 5c77b727e5dc
- last_write_checksum: sha1:6139375f225be12f8c05d1025888e8920808c812
- pristine_git_object: f2aad0029cb79654ecee7177c009c2743837523a
+ last_write_checksum: sha1:018dc1dfbaefe2589a3f89b0baf65e9946ec29e7
+ pristine_git_object: 8ebd49f4e9be29988efff99b53a1310857177e9b
+ docs/components/decisionsresponseanswers.mdx:
+ id: 1a49d5f960ce
+ last_write_checksum: sha1:298ba679b1c38494e4b5d610e9949397450ced46
+ pristine_git_object: 0aa4353ad48b79986a1b903e69894b35f52b440b
docs/components/decisionsresponseusage.mdx:
id: ab10cb1b5675
last_write_checksum: sha1:698696e29f3ec0fc40c4cd263971d6a9d0ef3506
@@ -3202,6 +3202,338 @@ trackedFiles:
id: 1375aa431642
last_write_checksum: sha1:adf88fd707bde0d0d0dff2a708375aedc96289c4
pristine_git_object: 06652bc3b30c292ff98d6a2e8008c995ec6f20ff
+ docs/components/extractiondateanswer.mdx:
+ id: 7976b6922576
+ last_write_checksum: sha1:76279bf162344dbde8b120abc01012ac3b742bd5
+ pristine_git_object: c79d84d31c6f6f8f6ff4cd1ef502525ea6575dd0
+ docs/components/extractiondateanswersource.mdx:
+ id: f2dc9a38b450
+ last_write_checksum: sha1:69dfe9a77c71401ec9060094762e0c92d61c1e26
+ pristine_git_object: 3efa8603a29cd9b32ac8f7e5ff471d4a1b694541
+ docs/components/extractiondateanswertype.mdx:
+ id: abeec0e94885
+ last_write_checksum: sha1:de756e78c8179ea2843d77f04b3d5e0dd9f1e920
+ pristine_git_object: a369fe5e74cf3bc602de52bc19303571c0cbb5ed
+ docs/components/extractiondatefield.mdx:
+ id: 50f934145dab
+ last_write_checksum: sha1:ad409200bf0d85825ef97b78f29ceb9d07586d09
+ pristine_git_object: ecceaea22da768adf5d954e1306950977cf7ca9e
+ docs/components/extractiondatefieldtype.mdx:
+ id: 976a6667e313
+ last_write_checksum: sha1:194899ea1ae103de16de3c73b54bd39c075c4ff6
+ pristine_git_object: 93062f3dbe496a05750406736b128b2024805d40
+ docs/components/extractiondatetimeanswer.mdx:
+ id: 2559fb1d6b75
+ last_write_checksum: sha1:78deb90c4130c7bde23cf31e52ad9838a9786849
+ pristine_git_object: c3a07d0ecbdd66b90e33297cb8a787dfbd1be73f
+ docs/components/extractiondatetimeanswersource.mdx:
+ id: f99304f92143
+ last_write_checksum: sha1:4afa61640a4b87f40831cec68587432f28d98a1a
+ pristine_git_object: 4de96384d0e018f93d79310419dc3077f94b88ef
+ docs/components/extractiondatetimeanswertype.mdx:
+ id: a4a06b605800
+ last_write_checksum: sha1:f2d0b24fa2348e1646a9496482153d30337a169a
+ pristine_git_object: 73da000cf03250c3cd6ba9234592528a92c7d3a0
+ docs/components/extractiondatetimefield.mdx:
+ id: 557a13f5ece9
+ last_write_checksum: sha1:8bff6c0c698352a62efc0816ffcd9920eb94bf40
+ pristine_git_object: 1c6a9f4efad49dc74d8fe2ceb939fac6fa888723
+ docs/components/extractiondatetimefieldtype.mdx:
+ id: 7b4c8da8a8fc
+ last_write_checksum: sha1:ab28a072b87f84a504c3eb2c1d6975df1a25c6c3
+ pristine_git_object: a8fb1fa450654191a98d7520a41ae6c9a8ef83cf
+ docs/components/extractiondurationanswer.mdx:
+ id: 87764531da90
+ last_write_checksum: sha1:727fac67bef295c5ed9899bedfd9d12e7763c58f
+ pristine_git_object: 9d2fe99cc51f98c982533074d878d4e4a511f153
+ docs/components/extractiondurationanswersource.mdx:
+ id: 7129cb29eb99
+ last_write_checksum: sha1:6ed2c1d9d8339786b931afe04c278a34876d0ade
+ pristine_git_object: 05bfe9cbaf910c5fd3acbb07dd50aad6e076b487
+ docs/components/extractiondurationanswertype.mdx:
+ id: f65b90cd2758
+ last_write_checksum: sha1:25dfe4272d867f6b5d594f830afcb611b7b82441
+ pristine_git_object: 66980844e78972960fe82a9c6ad833d425b466b9
+ docs/components/extractiondurationfield.mdx:
+ id: e2926531241a
+ last_write_checksum: sha1:b5da3d9d924b1e6690a9eda93e441c1ce44f11c5
+ pristine_git_object: 1bcc7faa0507c576c046199ab2a82d8753fd75f7
+ docs/components/extractiondurationfieldtype.mdx:
+ id: 5deb436240f3
+ last_write_checksum: sha1:1b44d15a33912cbc98c81081ed60a10be140428d
+ pristine_git_object: 53575c65bbe75d45548d77d37e0cdd9033f35643
+ docs/components/extractionestimateanswer.mdx:
+ id: d008b8a78f78
+ last_write_checksum: sha1:b1530aab8091481947dfa9f2f3f2cbdcb7ff5dfd
+ pristine_git_object: 1c076a0699df60c9e879a82574eb29dd8140a8a1
+ docs/components/extractionestimateanswerguess.mdx:
+ id: 114df7c91c74
+ last_write_checksum: sha1:98ce310132c579080c330d767b50d3791b73d545
+ pristine_git_object: 7a2425fe2a99255faadc5c53ec7860dae149d430
+ docs/components/extractionestimateanswermean.mdx:
+ id: a618ca617920
+ last_write_checksum: sha1:7f78d86554813b5b163e7c0f5f99b68027fcd9b1
+ pristine_git_object: b9dace3e20d7daad1e0439c881ddc508c11122d0
+ docs/components/extractionestimateanswermedian.mdx:
+ id: 1c4ae3b04699
+ last_write_checksum: sha1:d5d75718ae5204db4f5c2d19ce1ba9ceda2275a9
+ pristine_git_object: 612874e1df0628dbad550433e74eac17b8c222f8
+ docs/components/extractionestimateanswerp10.mdx:
+ id: 881349a91c39
+ last_write_checksum: sha1:bb36b612ff3255710f92d33bdb09a85130fe0e28
+ pristine_git_object: 73fd2a370e7840a454d7a71508c01b962a85764d
+ docs/components/extractionestimateanswerp90.mdx:
+ id: ae49d47799a1
+ last_write_checksum: sha1:c474392287b12ed98ecb1e855d4cf3fb84a91881
+ pristine_git_object: 7036166a9ba1aa5ff62ec2863536a9ee31c20268
+ docs/components/extractionestimateanswerquantile.mdx:
+ id: 2500f1893f0a
+ last_write_checksum: sha1:ffb9543249ec0d1baab66ab5d2b8b3f694bf4142
+ pristine_git_object: bbe9e23cf21369dc8422e6356a09cea8c2adc9b4
+ docs/components/extractionestimateanswersource.mdx:
+ id: 25ad13931218
+ last_write_checksum: sha1:7c245dd3e884e70e4b5f62d33d8b5bf2f613372c
+ pristine_git_object: 146c7bca9497c72873644db5fe6e3bb1e35702f2
+ docs/components/extractionestimateanswertype.mdx:
+ id: 57d58d8241d8
+ last_write_checksum: sha1:c2cb2b3ff108ea7d23dcf564963c18e77ef9972f
+ pristine_git_object: a777d831b0f954ab81bcdc1c21701b5b5370c336
+ docs/components/extractionestimateanswervalue.mdx:
+ id: bb09f678bef1
+ last_write_checksum: sha1:5409c95bc5a5b7c717429cca1d74b18ac03478e4
+ pristine_git_object: 768b5466ce39074982b45dc41af427734b9d7df9
+ docs/components/extractionestimatefield.mdx:
+ id: c3e4f8aec39b
+ last_write_checksum: sha1:7b7ee8f23d27c28e17ac68f3938a6ef3bba45297
+ pristine_git_object: 7f18a341b46300d447ccb89b40284e74383de5e1
+ docs/components/extractionestimatefieldmax.mdx:
+ id: d21954e95f10
+ last_write_checksum: sha1:88246885ef65033e22e4580db6f96a2314b38499
+ pristine_git_object: 9fffe5a3d598baf5ff4012f26f4270ee7a57bcf4
+ docs/components/extractionestimatefieldmin.mdx:
+ id: 21ecd7c17b5f
+ last_write_checksum: sha1:bd4c788ec9e358f65f659862956f0f37b5f6f18d
+ pristine_git_object: 2fd6dc6f82867defd80852a96c17c94b185d4637
+ docs/components/extractionestimatefieldscale.mdx:
+ id: 846b601551ac
+ last_write_checksum: sha1:9d46282ab853a9f3d84942c838da5f662d5dd869
+ pristine_git_object: d50a188af245f354fd89ad0ae86d0d405091a769
+ docs/components/extractionestimatefieldstepmonth.mdx:
+ id: 599076b0c548
+ last_write_checksum: sha1:c44708127ecfb6d8e8bb795e85e3144e61903547
+ pristine_git_object: ae39f752b20c0af2551d0dc085a769f927bf8991
+ docs/components/extractionestimatefieldstepunion.mdx:
+ id: 49a1515d59c7
+ last_write_checksum: sha1:83fa6aaa43dc030cbc896ec4da9b7fe191e7b04c
+ pristine_git_object: c9eff1dd308670e25190cb5ec6411843757628e3
+ docs/components/extractionestimatefieldstepyear.mdx:
+ id: 8b00f3283378
+ last_write_checksum: sha1:755933966c313740bcbef82d767e50b4bdc30ddf
+ pristine_git_object: ed71a17cfcdc46976903711644a120cea99e85a7
+ docs/components/extractionestimatefieldtype.mdx:
+ id: f7a4cca3fc4f
+ last_write_checksum: sha1:ce36b62497faf85e3cf3fcb693ec19b228fbf4a1
+ pristine_git_object: 752c86c48b4f3c9acad9f547c168a4541980fae3
+ docs/components/extractionforecastanswer.mdx:
+ id: ae25d129b50f
+ last_write_checksum: sha1:d4f0cdf6efd7cf9e5dbcbd96411506e7679b7beb
+ pristine_git_object: c6372d9e9d48abf359aa6cc4b77a3a20c9555849
+ docs/components/extractionforecastanswerguess.mdx:
+ id: ee54bcc9ab3b
+ last_write_checksum: sha1:1a3c83f874d3d69a28c40620362e56e34ba13a1b
+ pristine_git_object: 7547003215e51efb682830403781fe35a39e1e9d
+ docs/components/extractionforecastanswermean.mdx:
+ id: a34208fd3873
+ last_write_checksum: sha1:c94f53e1b605c7167a9a8de8735a738326777040
+ pristine_git_object: 8c60cac3106e48736cfafaa8a87243a16e1a7398
+ docs/components/extractionforecastanswermedian.mdx:
+ id: f1ed83bed855
+ last_write_checksum: sha1:9d3a323dbf9b7e111b84d066384d5f65f6157126
+ pristine_git_object: df34bf9db46e962f451584c7a44409fe5a3a8f4c
+ docs/components/extractionforecastanswerp10.mdx:
+ id: f2ac4bbf02a2
+ last_write_checksum: sha1:2215974edaf60559e6e9d1d5a749446d40493502
+ pristine_git_object: 781d0ecfb58472c593311d9879be049cf6f2cb24
+ docs/components/extractionforecastanswerp90.mdx:
+ id: b00dd61b6307
+ last_write_checksum: sha1:ae904139438dbe840324ef2b2751e59b8c7efbdf
+ pristine_git_object: 35fe4d981c3bb14311eb3d6ec9e74ef0a544ad2c
+ docs/components/extractionforecastanswersource.mdx:
+ id: 5303ce080293
+ last_write_checksum: sha1:d2e1fb806e264a567a60ddea46dc28c1a34085fc
+ pristine_git_object: 8e82e1771d87dcd1ff71c7ed2698802aca3636f1
+ docs/components/extractionforecastanswertype.mdx:
+ id: 1dfae7b75165
+ last_write_checksum: sha1:8610885da1c70f0098c80785fa1326197324aafc
+ pristine_git_object: 50ac0374f3a11ee3aaa6a09ff450d6c3962edac6
+ docs/components/extractionforecastanswervalue.mdx:
+ id: ce55374b7aeb
+ last_write_checksum: sha1:ec5e27d452e4473317035c134a582790dd1ac36a
+ pristine_git_object: e5996b4fd39061c9145b9bb051c024144baf8703
+ docs/components/extractionforecastfield.mdx:
+ id: 77bac4df4bbf
+ last_write_checksum: sha1:5066ff0d09fe43af57b78b5e7d9064db86ec2d2d
+ pristine_git_object: db299598c34efcdf97c6b43f2701b35dbf6fd9d2
+ docs/components/extractionforecastfieldmax.mdx:
+ id: ca5002f79a98
+ last_write_checksum: sha1:05f9be530fb544e95465070b856a7a55a8c402a7
+ pristine_git_object: 297f60537038984983ecbd562f7fa13756d3c60a
+ docs/components/extractionforecastfieldmin.mdx:
+ id: 11e919a0f8d3
+ last_write_checksum: sha1:d5fa1ca68ca24cc534c811056bafecd2042bd5a4
+ pristine_git_object: 08794f2069be056543b85dca68fbad9b2cd677e6
+ docs/components/extractionforecastfieldscale.mdx:
+ id: 4862daecea11
+ last_write_checksum: sha1:e54b5871bcde1aee90a67619694b57b3ec9807c2
+ pristine_git_object: d49150a39a35bd1ec668adc0a801b77f1dc20716
+ docs/components/extractionforecastfieldstepmonth.mdx:
+ id: 140f6b6732cc
+ last_write_checksum: sha1:c6a047acdbe5032d41b66e8dfca8f4241db11cb9
+ pristine_git_object: 4daa57c1269c3a7b2463390ed1e9cda4516a7df3
+ docs/components/extractionforecastfieldstepunion.mdx:
+ id: 652688c5bc80
+ last_write_checksum: sha1:7ed17f6a2d57e9aeb71bfe441b8535baece459a4
+ pristine_git_object: e3b3462e77f6f165a0ae359c4a664429e9dc1421
+ docs/components/extractionforecastfieldstepyear.mdx:
+ id: d84489dd1548
+ last_write_checksum: sha1:4f15e90bae5c00cafcf425ca4257011429f7d061
+ pristine_git_object: 6de0cc1dc7cca2fd8e549653e43a3b7024b24977
+ docs/components/extractionforecastfieldtype.mdx:
+ id: 868417946a64
+ last_write_checksum: sha1:63bc7b957903c47ff94f7103fcebea3003399635
+ pristine_git_object: 510e9cdfd734349975ac882b512ece8dbef942e8
+ docs/components/extractionforecaststep.mdx:
+ id: 094cc213bc49
+ last_write_checksum: sha1:fdc856ffd67ae44ccba43867240666338f17ee54
+ pristine_git_object: c7bb76111ba8e50bf221fe0b42ab2d2030f75b12
+ docs/components/extractionforecaststepmean.mdx:
+ id: 6a7af0a88a94
+ last_write_checksum: sha1:a949fae7c5e0d3d3612de8aeb10acae863ac2631
+ pristine_git_object: 582379e240b09f24182c5cfaac61f1cec6ada661
+ docs/components/extractionforecaststepmedian.mdx:
+ id: f793904c70ff
+ last_write_checksum: sha1:af829857aac45dc67339df2fae59093775d74364
+ pristine_git_object: 724fd4d3413897e883236f7e02947a5bb06bc713
+ docs/components/extractionforecaststepp10.mdx:
+ id: 7e144a204801
+ last_write_checksum: sha1:0b49f1d58ecc96f1645b683594819930e1ec9a09
+ pristine_git_object: 53cd66d44320fb33cd39722b791cc553bd2d93d3
+ docs/components/extractionforecaststepp90.mdx:
+ id: 071271b54cc2
+ last_write_checksum: sha1:232b6fc146c05ae220fc6810690006b16b77865b
+ pristine_git_object: 55daa9605cf76c97f6d7692c552accb0dcaedf47
+ docs/components/extractionforecaststepquantile.mdx:
+ id: 97fb7c585809
+ last_write_checksum: sha1:5640a4bbcbb03fa13328e9f523df84072ed6baa5
+ pristine_git_object: 1ba0e060e2d4138f00ccd45fde151ebcc375da02
+ docs/components/extractionforecaststepvalue.mdx:
+ id: 2dd19e6ec7a6
+ last_write_checksum: sha1:39ceef7f5601f340f8da17e9dd3db9149707729c
+ pristine_git_object: e971ec1fa26c3043eeef4862f105546922e4a7bd
+ docs/components/extractionlistanswer.mdx:
+ id: a2388a5a8321
+ last_write_checksum: sha1:eb9733d9eb4ae1b2a2db51f75f4f6583cb3ea695
+ pristine_git_object: b6ff7aefb8602417c36c6fb4d5250d63389703f3
+ docs/components/extractionlistanswerguess.mdx:
+ id: 3a1738d5a4b3
+ last_write_checksum: sha1:67f869f2bdbc3fe19e4c5ba0c48e0f7b0d1b3f91
+ pristine_git_object: d429b35572a8201202dd6066b1b5c831ca3b0962
+ docs/components/extractionlistanswersource.mdx:
+ id: 339b9df8e667
+ last_write_checksum: sha1:c654822b16d199d273f2e8d5213a7f591f9c63fb
+ pristine_git_object: 1f178170f6285af32a3b5c047e4e03b80a0a59db
+ docs/components/extractionlistanswertype.mdx:
+ id: 56ebb6469ae6
+ last_write_checksum: sha1:af6bcf33a99bb5f3e7baea1cebcbcbdc57625f6b
+ pristine_git_object: 8abd78235db7ae06e4ce0242e9d79d4638d2c722
+ docs/components/extractionlistanswervalue.mdx:
+ id: f5e30efa0630
+ last_write_checksum: sha1:8355d6d598f876cc2286774fee5b9bce9cd5d7c9
+ pristine_git_object: cd38d0f80e1308bbe350d994ac95d7d7480d8d5e
+ docs/components/extractionlistfield.mdx:
+ id: 0f37220bbf24
+ last_write_checksum: sha1:5a043f2e402e1f70cc88e0404ee7c8cca2390299
+ pristine_git_object: 0a3b5068b5927108233e98e3a0032c8f6d1a2ba5
+ docs/components/extractionlistfieldtype.mdx:
+ id: e6b5572fc728
+ last_write_checksum: sha1:9bb887d2a882763a72f908f344f3ebd39acf4d4d
+ pristine_git_object: 1c3e50bcb691651feb7ba737ce8f9e5625a6b1bc
+ docs/components/extractionnumberanswer.mdx:
+ id: 9c9ff12897b6
+ last_write_checksum: sha1:f3c5920dda252683b577a0b7d1c4db7da43eba94
+ pristine_git_object: 910b88e2b888414bfa128f6eef3f3777e22b47b4
+ docs/components/extractionnumberanswersource.mdx:
+ id: b410ee01d94a
+ last_write_checksum: sha1:cd38040c34649937901e8bc0e4be4a377099658e
+ pristine_git_object: 9bd790768b7486e45891cc713e2161bd76445f2e
+ docs/components/extractionnumberanswertype.mdx:
+ id: 71297fbae75c
+ last_write_checksum: sha1:eb7cb0386bece38284bea47d30ab590cd3f46d17
+ pristine_git_object: 62e2f6af31134e390cb01ee252ead10a42172054
+ docs/components/extractionnumberfield.mdx:
+ id: 75d3b348f9f4
+ last_write_checksum: sha1:d3587b55b5d0304f5caef646c9a9b048bf310630
+ pristine_git_object: a57a6dc65c9711dfc49ca7838e1a00c7ce5d497d
+ docs/components/extractionnumberfieldtype.mdx:
+ id: e108f7192502
+ last_write_checksum: sha1:f829893f702262b25e8599c2f5d36387f9b9e564
+ pristine_git_object: 0f381107c5f4271335895826cb89b0791a0b80c1
+ docs/components/extractionsrequest.mdx:
+ id: 8e3359e7a4eb
+ last_write_checksum: sha1:4b60df894e656bb033bafd1e79efda1cd00bc19e
+ pristine_git_object: d0d122a3ee63730c7813403ea08ad30127bdce45
+ docs/components/extractionsresponse.mdx:
+ id: 9b1ac791359b
+ last_write_checksum: sha1:680a79be2427f7e882cd973188c50d1f8fef56c1
+ pristine_git_object: 58b0baeb598e9b07cf992f48f454f5baf62300f1
+ docs/components/extractionsresponseanswers.mdx:
+ id: 3ef78108dd20
+ last_write_checksum: sha1:edaeb29e86b991c077690b2e02d057b041d5b879
+ pristine_git_object: b44b7055903365cc387935da3563e52c5aeeefae
+ docs/components/extractionsusage.mdx:
+ id: 2c2b9eba3ff8
+ last_write_checksum: sha1:78d7c111a7f8e79570f5612f342e47815262ba4f
+ pristine_git_object: 7d335f16309b405175e5225f2b9b8cd66f63fc31
+ docs/components/extractiontextanswer.mdx:
+ id: 7f03372c93b9
+ last_write_checksum: sha1:7b96dbe002ec49e2b6b84c49a3d2ef9a4230c91f
+ pristine_git_object: b8f0fe6cd2659dd9075fb37cebf07c2cf8f49541
+ docs/components/extractiontextanswersource.mdx:
+ id: 769d49d5b121
+ last_write_checksum: sha1:b3a4ae20b4824df3b052e824a0e09dd1d6d5a26f
+ pristine_git_object: 29c1e18622dea31e6f776c7128dc4d58f1a05eca
+ docs/components/extractiontextanswertype.mdx:
+ id: d0a19b4f52a6
+ last_write_checksum: sha1:7181b0279cf9fb01695e7360f391292a82924301
+ pristine_git_object: 190c505afbcf5eebaac432affd94c520705f8e7a
+ docs/components/extractiontextfield.mdx:
+ id: 3ff89fcc9280
+ last_write_checksum: sha1:2047717efa86fba3edb806525a5ffb2a58b33fa7
+ pristine_git_object: 7f4c2d28f3555e93830a4683ae0778aaeeeee317
+ docs/components/extractiontextfieldtype.mdx:
+ id: 5feaf7058394
+ last_write_checksum: sha1:521db15d7e9819c8b6ee8d33bd0d515c2bdedb33
+ pristine_git_object: d8d4a00ca072f643c2fad4a13ce37e9032e5c0ff
+ docs/components/extractiontimeanswer.mdx:
+ id: 518a28381666
+ last_write_checksum: sha1:d01f80e8a2ad8e3c770357529f92e3546b103248
+ pristine_git_object: 065ab42c4b2bbed00d74c3e30cc6783b2b86cf6a
+ docs/components/extractiontimeanswersource.mdx:
+ id: ed64b325414c
+ last_write_checksum: sha1:ac66b2b2f1daf2468cc1a53a958aa27f91aa1afd
+ pristine_git_object: 068f14a4beb56762a1d7eb9c7a3d9edf8756e81b
+ docs/components/extractiontimeanswertype.mdx:
+ id: 5ebcc17e8181
+ last_write_checksum: sha1:c521cf4a98af256d9ff58a179efa822d6a0a443c
+ pristine_git_object: 9fd70049e82c9cdd684cce5a3efe2b5e8f01de79
+ docs/components/extractiontimefield.mdx:
+ id: f492f70dc285
+ last_write_checksum: sha1:bdd61c12fe3b3fe4f5c7be4c6530b70ac212021f
+ pristine_git_object: 3d48fdab6594c98f73706dd606d8362f71a09c80
+ docs/components/extractiontimefieldtype.mdx:
+ id: 6f8903f71ef7
+ last_write_checksum: sha1:f70cf2a555bd4253079e23f641d9b765fcf5c348
+ pristine_git_object: 24971de209397631b4c8134d26ff1b11a0ed4427
docs/components/failabletoolcallstatus.mdx:
id: 66c801061bd7
last_write_checksum: sha1:3beed4470126b7cc6bf271423ad03db0163d7bd0
@@ -3214,6 +3546,10 @@ trackedFiles:
id: 538c871219f3
last_write_checksum: sha1:52ed81e463594f421f6459f9d363b76cba584711
pristine_git_object: 4b6c1a197ad3fa4a117c0919bbaf30129f454fed
+ docs/components/fields.mdx:
+ id: 8b32f4bd19c8
+ last_write_checksum: sha1:1918a386c69669321ebe08f399c98afb62996481
+ pristine_git_object: 15e95b7db7b79c3b03b08ba7c8812c06ce942e18
docs/components/fieldt.mdx:
id: e7b48abef959
last_write_checksum: sha1:e535734499fa6e4afcc05ba296d0c54f49b2388b
@@ -4134,6 +4470,10 @@ trackedFiles:
id: 9a443dea63c5
last_write_checksum: sha1:5ebe83b940cb6501be7ffc5d87524957ed7a2823
pristine_git_object: 0b806e0177715464c4187d2dadfe3538bb29137b
+ docs/components/interval.mdx:
+ id: 98d6e6322568
+ last_write_checksum: sha1:7b5df037aacca684b6abb18bfd9595d5d7f6c512
+ pristine_git_object: cca739368800a640542f78f199644269660d28ff
docs/components/issuedtokentype.mdx:
id: b5c747e2aaf8
last_write_checksum: sha1:33d9e8b021a11c7168f66a288dd5d7ed3aa0a78e
@@ -4146,6 +4486,10 @@ trackedFiles:
id: 4a97a0028d93
last_write_checksum: sha1:a80dda1fb6cc098102c643649ac1fac2c9df4bb9
pristine_git_object: 74c61e5f750e2df770862017b6b406065398ca9e
+ docs/components/items.mdx:
+ id: 92f4a944bcca
+ last_write_checksum: sha1:d0796cab2ee36f13c29961ab1e9c80a2d3b29fdb
+ pristine_git_object: 5949fbaa48fde55f28b1597cd0ac15ae13c5852a
docs/components/jevrouterplugin.mdx:
id: 258aa7058bc5
last_write_checksum: sha1:f1ba78a999fd265a4ae83caa21fcca1997292eb7
@@ -8566,6 +8910,14 @@ trackedFiles:
id: 493cca2a6d0d
last_write_checksum: sha1:d939de01c61c42ddba1c9e1f198984035b5efead
pristine_git_object: 49c68dc9660803b7c1be1530487834a54a8a8f55
+ docs/operations/createapialphaextractionsglobals.mdx:
+ id: e29358aef02d
+ last_write_checksum: sha1:4afa24dfc325399035baa9c2d50d937fa3859495
+ pristine_git_object: 2ea0c6770a5c06bfdabc0176cb13261d481c92ea
+ docs/operations/createapialphaextractionsrequest.mdx:
+ id: 9791689fb37e
+ last_write_checksum: sha1:0f347ced7bca57ca02913d7955202a90501fa352
+ pristine_git_object: eebccfea53b63b139fb0206e4e6d02c0ba47f657
docs/operations/createaudiospeechglobals.mdx:
id: 9b19782b0fc7
last_write_checksum: sha1:4b7fad5dac8a256bdc55553b4ae5c7f4cefc0b3a
@@ -10282,6 +10634,10 @@ trackedFiles:
id: 16a97e1de35f
last_write_checksum: sha1:f28388cae1e8a1593017a2d0e08a33b678802d1c
pristine_git_object: 895dba6170d02cbf49dd87e817d260574e17841a
+ docs/sdks/extractions/README.mdx:
+ id: 7b1a30cfc1d9
+ last_write_checksum: sha1:eb0f02e6edd22c1087af709d8641b966e4a092c3
+ pristine_git_object: d2368a310672c66c7cb9d8ccc5365057a17f604c
docs/sdks/files/README.mdx:
id: 1a0c257e330c
last_write_checksum: sha1:853537439b97cd6606f2d9f12de4b00deda6f912
@@ -10376,8 +10732,8 @@ trackedFiles:
pristine_git_object: 3e38f1a929f7d6b1d6de74604aa87e3d8f010544
pyproject.toml:
id: 5d07e7d72637
- last_write_checksum: sha1:8fad3cffe46f4d50ce3f0511b448b8109420f471
- pristine_git_object: 8b292d5ab165cd664d3d5b99e83a409a3c63bb95
+ last_write_checksum: sha1:00ca77422ea11b862ee93dd9847d6516d2e9c064
+ pristine_git_object: 20718a5173915010fbfa5c1a218b30e8f6f62253
scripts/prepare_readme.py:
id: e0c5957a6035
last_write_checksum: sha1:77f44b60b98bc126557ec27391f91dfba764bb54
@@ -10404,12 +10760,12 @@ trackedFiles:
pristine_git_object: 86713cfea633e09d33b3d4e65281071fe20e6137
src/openrouter/_version.py:
id: d8d15ad6c586
- last_write_checksum: sha1:dc0b44bcd636ba335341a17cb308842f88808a29
- pristine_git_object: 7efe4512397baf1d7f754381ec04f0f2ad8393d1
+ last_write_checksum: sha1:63189687f123ce263236cf1b56fa6056f3484c48
+ pristine_git_object: 0fe77311f1f36bd87c34ce532c5e0b2258c924a4
src/openrouter/alpha.py:
id: 306c4d93308d
- last_write_checksum: sha1:30f55a360f41376ab194b9ea725fe4e001a5ae1a
- pristine_git_object: ae90121fa5d2d4bab7294f22f42d2251bce6690d
+ last_write_checksum: sha1:80cc0f39649445431cc2247ed0e0765438467766
+ pristine_git_object: f512ec0a9dab3feb43c9add635c0a926b7728b2d
src/openrouter/analytics.py:
id: cb406b5aaabb
last_write_checksum: sha1:0ae5a0c89591d8bc3982d4e7c526a3ac66b7d845
@@ -10452,8 +10808,8 @@ trackedFiles:
pristine_git_object: ad3d247954547814054c01989a2dff3d12b3e4e1
src/openrouter/components/__init__.py:
id: 81754e97b3f4
- last_write_checksum: sha1:e278fd9116c324be177d7d66c415be9ee80632b0
- pristine_git_object: 5dc45660695b98d93b66093eab5d57d8bfc22335
+ last_write_checksum: sha1:c0b37e8243526ef606f1b8dee052727b121761af
+ pristine_git_object: 9d5f56952989fd5239415358ef6d02a761d343ed
src/openrouter/components/aabenchmarkentry.py:
id: e2e0f0b48c82
last_write_checksum: sha1:fab4d9a24d2cea937bb749d46c5f83941e99d65c
@@ -11688,8 +12044,8 @@ trackedFiles:
pristine_git_object: 1a44020b9512f2bcbc275bc0cd73cbbb7f90de40
src/openrouter/components/decisionsresponse.py:
id: b91b81c2cf95
- last_write_checksum: sha1:525f6ff5bd402e9d848fe5e15c32bd0eee14d236
- pristine_git_object: 687789c6ab7c35f36394e0c3028376b24b670044
+ last_write_checksum: sha1:66617d3c417a5de7674773ffda05044d373f1580
+ pristine_git_object: bf57dc6e0b20df8b501c1e5abe389f8b93cbfd85
src/openrouter/components/decisionsscoreanswer.py:
id: af8597465725
last_write_checksum: sha1:e12a52051ccd6f841e0238d789b816a05156d299
@@ -11786,6 +12142,94 @@ trackedFiles:
id: c380cfecd177
last_write_checksum: sha1:06d354a069eb17d3cbd13932e0258dc1d3ea6f9f
pristine_git_object: cb4e716656633b8d070646198b4fe0f560ee94d0
+ src/openrouter/components/extractiondateanswer.py:
+ id: 2606de693996
+ last_write_checksum: sha1:cc70acaabff93d67e1ee21f99852100a78411832
+ pristine_git_object: 7fca50880986c85db36cc61bc5fc2b6170f201d3
+ src/openrouter/components/extractiondatefield.py:
+ id: d61917ea9968
+ last_write_checksum: sha1:c288f7fdb316615c0105f3ed0b44d55d9b2514ab
+ pristine_git_object: ecb2d421f5fe3688e40a23add97613488a9f9cfe
+ src/openrouter/components/extractiondatetimeanswer.py:
+ id: 81153f9833e4
+ last_write_checksum: sha1:3622c58108370ec500e2aebae03c0f036ee181d5
+ pristine_git_object: 6de327cce2051e62db78360090130747623e9cb2
+ src/openrouter/components/extractiondatetimefield.py:
+ id: c19ff7161d38
+ last_write_checksum: sha1:a1ddc34fbdbd254e443f163bd68e92dbec938d2b
+ pristine_git_object: 7bd5a82d649b994453bb1bcdc9ea31fc88cc5c4f
+ src/openrouter/components/extractiondurationanswer.py:
+ id: 9dee37484997
+ last_write_checksum: sha1:4bff9e0426b235103426676aae88cae451179779
+ pristine_git_object: da48cb14fabe210dee57eeac3390c07b57f8194a
+ src/openrouter/components/extractiondurationfield.py:
+ id: af1aa9d859dd
+ last_write_checksum: sha1:cffdbb364074d650fe2c46e4b0a2f35375c0c2b3
+ pristine_git_object: 9909d58fb25d505c57dcbbbbb7fd4d1f8f13caf3
+ src/openrouter/components/extractionestimateanswer.py:
+ id: d224919feae7
+ last_write_checksum: sha1:e87c1f692beb24ef6073ae20daff3775b68a97cf
+ pristine_git_object: 49ba18a0167370ce69fe9958d8941578520c23ae
+ src/openrouter/components/extractionestimatefield.py:
+ id: c3eda81242f7
+ last_write_checksum: sha1:2cb350e3a451d63a3157a27018b0de2c08deb5e5
+ pristine_git_object: 27a5f24e392ea0da8187188bd3c2ef9d72b9285c
+ src/openrouter/components/extractionforecastanswer.py:
+ id: eb06525c8e62
+ last_write_checksum: sha1:0336c7527a29cd0d61322f62a728c8a24a41eef4
+ pristine_git_object: 46a911b68f2527d5693f9112b97cf926ac495939
+ src/openrouter/components/extractionforecastfield.py:
+ id: 6cc5b70bbdaa
+ last_write_checksum: sha1:b1e7a06ae90aea89f42a176e6b431c7690bf9f95
+ pristine_git_object: 7b2bf5d0be73d231121130ff9b06ce51877978c8
+ src/openrouter/components/extractionforecaststep.py:
+ id: a8c0caf63050
+ last_write_checksum: sha1:fc813d24d026f1ce37427f8ab111961c5ada2598
+ pristine_git_object: 47809e77d553ffe84129e51a757ba394c662929b
+ src/openrouter/components/extractionlistanswer.py:
+ id: c7aaa4f5afb4
+ last_write_checksum: sha1:9b9771df15e9745f37377c166c8d6d99106c720c
+ pristine_git_object: 82ad80fe1a214135854207e1cf7526e0a3cbb403
+ src/openrouter/components/extractionlistfield.py:
+ id: dab2a75a880d
+ last_write_checksum: sha1:7c25db467c8f01cba924c3885ca3236e0e5cb358
+ pristine_git_object: 282b863b6a9cc1a53fdb78a36ae6dbec73876784
+ src/openrouter/components/extractionnumberanswer.py:
+ id: 9a87b682eef5
+ last_write_checksum: sha1:cf6b3acf15a73dc16bb3ee81344b359f6a5ffc99
+ pristine_git_object: adea072191b14099ab7702c29efbc1c17672f9ea
+ src/openrouter/components/extractionnumberfield.py:
+ id: 1529d36e4196
+ last_write_checksum: sha1:0c2cde20943acaa47d3a6aef845cff1c1d6dfeb1
+ pristine_git_object: 1823b0109214ebfbe1fa1a29581594beb30c4280
+ src/openrouter/components/extractionsrequest.py:
+ id: afe9f8e432cb
+ last_write_checksum: sha1:c943666b7398497d17de2490fbb6981fbb96bf5f
+ pristine_git_object: a75599b1b05639839c777303fb392e0139afd6dc
+ src/openrouter/components/extractionsresponse.py:
+ id: c453ec16798e
+ last_write_checksum: sha1:5981cad6a37d5ef1947efd6454d0b328e3fd4096
+ pristine_git_object: edada0cbb8f95fc9f8bed1e4aa2980f1f70c2809
+ src/openrouter/components/extractionsusage.py:
+ id: 4a18cd53e383
+ last_write_checksum: sha1:8d9f5dd7e6cb58070d4346cdb6143efaf62073e9
+ pristine_git_object: e42e2df4a4829e4e41fdbc9f12f30697babb0ad4
+ src/openrouter/components/extractiontextanswer.py:
+ id: 2d6f419e73eb
+ last_write_checksum: sha1:5d06ab73ceceac08cad2c95f716565bad4fb207a
+ pristine_git_object: b72f0066eebe6b45af1df620211327f07bd2dbb9
+ src/openrouter/components/extractiontextfield.py:
+ id: 5d0da20614ae
+ last_write_checksum: sha1:1754a6adb25664515628f5ad636d52d91d578fd4
+ pristine_git_object: 4624afa9f690195186ee91309c4c7dad5225eb06
+ src/openrouter/components/extractiontimeanswer.py:
+ id: d6e27db7d4ad
+ last_write_checksum: sha1:bc728c14ecfb892c98eb08a708729fe69187fbed
+ pristine_git_object: 11a35dabcf6427c0cf62213a56edd6e8bd915017
+ src/openrouter/components/extractiontimefield.py:
+ id: bb90e69521cd
+ last_write_checksum: sha1:e2ee89e44d983012bfbea96449a2e1d44e6a1eb0
+ pristine_git_object: 8007f9e5a21b679b4bce52854359c928cd829bb2
src/openrouter/components/failabletoolcallstatus.py:
id: 9d8a9ed81db6
last_write_checksum: sha1:8b044a17497f3674f16642f17634e633f5d95df2
@@ -11960,8 +12404,8 @@ trackedFiles:
pristine_git_object: 5caeacf169f3edff5b6e9823264aeeff8be1e8ff
src/openrouter/components/generationresponse.py:
id: 84d4e3e7da8b
- last_write_checksum: sha1:59154d0011d5bfee6a874ac7a66cbccd6eed1ec8
- pristine_git_object: ac86c1281db121fac5adb0f87317b02aaa1bf15b
+ last_write_checksum: sha1:4e50ef1462f88af24561f68a988cd49d84f32e32
+ pristine_git_object: 44f3b91999a80a1eb0fad29edb223f2b17aab3e8
src/openrouter/components/getbyokkeyresponse.py:
id: ca3a8db80018
last_write_checksum: sha1:9b428028a01ffb73915a278096ca51bd1c660326
@@ -14006,6 +14450,10 @@ trackedFiles:
id: cc70585846df
last_write_checksum: sha1:205ad795bb94aa435f1480f5dc43902317ddbb28
pristine_git_object: 2b03ccea82b6bb60876b63ef75445a9e2a3760bd
+ src/openrouter/extractions.py:
+ id: 27f1e1fb0fc0
+ last_write_checksum: sha1:9da3c6198cb5e5354f400d635cd00e066edd1918
+ pristine_git_object: 1def6665b48bef8c2f7a746a50e7f44caec1c968
src/openrouter/files.py:
id: 7baf7ee1f5b3
last_write_checksum: sha1:a780217e0d86c5893c5df4877b5451385144e876
@@ -14052,8 +14500,8 @@ trackedFiles:
pristine_git_object: 4a35ede011d09dddab042e2c00413ce4f6be655e
src/openrouter/operations/__init__.py:
id: 9afcea1e7161
- last_write_checksum: sha1:c0be70a8c0ce2dd43ff95886f8974298fb2ea1ee
- pristine_git_object: fa711f8146d00f5432e71959bd70ce6e3c08da33
+ last_write_checksum: sha1:4e959ebb759123c93e000899931b130d2bc42ad8
+ pristine_git_object: b84b6753e694b04ce63fce0e34c7c3cfa5f12658
src/openrouter/operations/activateprivateendpoint.py:
id: 3b39eec5d66f
last_write_checksum: sha1:9406e6b3d38c82895fd795f637702ef579cc6d36
@@ -14090,6 +14538,10 @@ trackedFiles:
id: f685307a800b
last_write_checksum: sha1:d92c222928d91f6b2e7f2b121084413e62573112
pristine_git_object: c9d1c139911fc0ba8c9047220f1abaca6a414a12
+ src/openrouter/operations/createapialphaextractions.py:
+ id: 45f4ba87017c
+ last_write_checksum: sha1:fd17d26cc0ffc7ca02ad66fa76690fc2c91cd163
+ pristine_git_object: 1c5bc60f63871d13cf22d9e3366c9c67e1322d0c
src/openrouter/operations/createaudiospeech.py:
id: af9df6195878
last_write_checksum: sha1:5beec05ba93a68805ad27e05603265864a608dc9
@@ -19296,7 +19748,39 @@ examples:
application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
"502":
application/json: {"error": {"code": 502, "message": "Provider returned error"}}
+ createApiAlphaExtractions:
+ speakeasy-default-create-api-alpha-extractions:
+ requestBody:
+ application/json: {"fields": {}, "model": "Grand Cherokee", "state": "Massachusetts"}
+ responses:
+ "200":
+ application/json: {"answers": {}, "model": "Malibu", "usage": {"input_tokens": 125155, "output_tokens": 101104}}
+ "400":
+ application/json: {"error": {"code": 400, "message": "Invalid request parameters"}}
+ "401":
+ application/json: {"error": {"code": 401, "message": "Missing Authentication header"}}
+ "402":
+ application/json: {"error": {"code": 402, "message": "Insufficient credits. Add more using https://openrouter.ai/credits"}}
+ "403":
+ application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}}
+ "404":
+ application/json: {"error": {"code": 404, "message": "Resource not found"}}
+ "413":
+ application/json: {"error": {"code": 413, "message": "Request payload too large"}}
+ "429":
+ application/json: {"error": {"code": 429, "message": "Rate limit exceeded"}}
+ "500":
+ application/json: {"error": {"code": 500, "message": "Internal Server Error"}}
+ "502":
+ application/json: {"error": {"code": 502, "message": "Provider returned error"}}
+ "503":
+ application/json: {"error": {"code": 503, "message": "Service temporarily unavailable"}}
+ "524":
+ application/json: {"error": {"code": 524, "message": "Request timed out. Please try again later."}}
+ "529":
+ application/json: {"error": {"code": 529, "message": "Provider returned error"}}
examplesVersion: 1.0.2
releaseNotes: |
## Python SDK Changes:
- * `open_router.analytics.query_analytics()`: `request` **Changed** (Breaking ⚠️)
+ * `open_router.alpha.extractions.create()`: **Added**
+ * `open_router.generations.get_generation()`: `response.data.api_type.enum(extractions)` **Added**
diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml
index e59f6f70..c6b2a120 100644
--- a/.speakeasy/gen.yaml
+++ b/.speakeasy/gen.yaml
@@ -37,7 +37,7 @@ generation:
documentation: mintlify
preApplyUnionDiscriminators: true
python:
- version: 1.3.97
+ version: 1.3.98
additionalDependencies:
dev:
pytest: '>=8.3'
diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml
index 91356232..61f6bc14 100644
--- a/.speakeasy/out.openapi.yaml
+++ b/.speakeasy/out.openapi.yaml
@@ -11799,6 +11799,927 @@ components:
required:
- 'data'
type: 'object'
+ ExtractionDateAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ type: 'string'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'date'
+ type: 'string'
+ value:
+ type:
+ - 'string'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionDateField:
+ properties:
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'date'
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
+ ExtractionDatetimeAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ type: 'string'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'datetime'
+ type: 'string'
+ value:
+ type:
+ - 'string'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionDatetimeField:
+ properties:
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'datetime'
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
+ ExtractionDurationAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ format: 'double'
+ type: 'number'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'duration'
+ type: 'string'
+ unit:
+ description: 'The unit `value` is expressed in.'
+ type: 'string'
+ value:
+ format: 'double'
+ type:
+ - 'number'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionDurationField:
+ properties:
+ decimals:
+ description: 'Decimal places kept in `value`.'
+ maximum: 6
+ minimum: 0
+ type: 'integer'
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ integer:
+ type: 'boolean'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'duration'
+ type: 'string'
+ unit:
+ description: 'seconds, minutes, hours, days, weeks, months or years.'
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
+ ExtractionEstimateAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ mean:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ median:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ p_above:
+ description: 'Probability mass above `max`.'
+ format: 'double'
+ type: 'number'
+ p_below:
+ description: 'Probability mass below `min`.'
+ format: 'double'
+ type: 'number'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ p10:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ p90:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ quantiles:
+ description: '99 percentiles, present when the provider is asked for quantiles.'
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'estimate'
+ type: 'string'
+ value:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ - type: 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionEstimateField:
+ properties:
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ max:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ min:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ scale:
+ enum:
+ - 'linear'
+ - 'log'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ step:
+ anyOf:
+ - exclusiveMinimum: 0
+ format: 'double'
+ type: 'number'
+ - enum:
+ - 'month'
+ type: 'string'
+ - enum:
+ - 'year'
+ type: 'string'
+ type:
+ enum:
+ - 'estimate'
+ type: 'string'
+ unit:
+ type: 'string'
+ required:
+ - 'type'
+ - 'min'
+ - 'max'
+ type: 'object'
+ ExtractionForecastAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ mean:
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ median:
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ p10:
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ p90:
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ steps:
+ items:
+ $ref: '#/components/schemas/ExtractionForecastStep'
+ type: 'array'
+ type:
+ enum:
+ - 'forecast'
+ type: 'string'
+ value:
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type:
+ - 'array'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionForecastField:
+ properties:
+ horizon:
+ description: 'Number of forecast steps.'
+ maximum: 64
+ minimum: 1
+ type: 'integer'
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ interval:
+ enum:
+ - 'step'
+ - 'minute'
+ - 'hour'
+ - 'day'
+ - 'week'
+ - 'month'
+ - 'quarter'
+ - 'year'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ max:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ min:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ scale:
+ enum:
+ - 'linear'
+ - 'log'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ step:
+ anyOf:
+ - exclusiveMinimum: 0
+ format: 'double'
+ type: 'number'
+ - enum:
+ - 'month'
+ type: 'string'
+ - enum:
+ - 'year'
+ type: 'string'
+ type:
+ enum:
+ - 'forecast'
+ type: 'string'
+ unit:
+ type: 'string'
+ required:
+ - 'type'
+ - 'min'
+ - 'max'
+ - 'horizon'
+ - 'interval'
+ type: 'object'
+ ExtractionForecastStep:
+ properties:
+ mean:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ median:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ p_above:
+ description: 'Probability mass above `max`.'
+ format: 'double'
+ type: 'number'
+ p_below:
+ description: 'Probability mass below `min`.'
+ format: 'double'
+ type: 'number'
+ p10:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ p90:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ quantiles:
+ description: '99 percentiles, present when the provider is asked for quantiles.'
+ items:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ type: 'array'
+ value:
+ anyOf:
+ - format: 'double'
+ type: 'number'
+ - type: 'string'
+ - type: 'null'
+ required:
+ - 'value'
+ type: 'object'
+ ExtractionListAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ items:
+ anyOf:
+ - type: 'string'
+ - format: 'double'
+ type: 'number'
+ type: 'array'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ spans:
+ items:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'list'
+ type: 'string'
+ value:
+ items:
+ anyOf:
+ - type: 'string'
+ - format: 'double'
+ type: 'number'
+ type:
+ - 'array'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionListField:
+ properties:
+ decimals:
+ description: 'Decimal places kept in `value`.'
+ maximum: 6
+ minimum: 0
+ type: 'integer'
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ items:
+ enum:
+ - 'text'
+ - 'number'
+ - 'date'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'list'
+ type: 'string'
+ required:
+ - 'type'
+ - 'items'
+ type: 'object'
+ ExtractionNumberAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ format: 'double'
+ type: 'number'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'number'
+ type: 'string'
+ value:
+ format: 'double'
+ type:
+ - 'number'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionNumberField:
+ properties:
+ decimals:
+ description: 'Decimal places kept in `value`.'
+ maximum: 6
+ minimum: 0
+ type: 'integer'
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ integer:
+ type: 'boolean'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'number'
+ type: 'string'
+ unit:
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
+ ExtractionsRequest:
+ properties:
+ assets:
+ additionalProperties:
+ $ref: '#/components/schemas/DecisionsImageAsset'
+ description: 'Images keyed by reference string, as in TypeSafe''s API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text.'
+ type: 'object'
+ fields:
+ additionalProperties:
+ description: 'A typed field to extract, compute, estimate or forecast from the state. Which types a model answers is model-specific; unsupported types are rejected with 400.'
+ discriminator:
+ mapping:
+ date: '#/components/schemas/ExtractionDateField'
+ datetime: '#/components/schemas/ExtractionDatetimeField'
+ duration: '#/components/schemas/ExtractionDurationField'
+ estimate: '#/components/schemas/ExtractionEstimateField'
+ forecast: '#/components/schemas/ExtractionForecastField'
+ list: '#/components/schemas/ExtractionListField'
+ number: '#/components/schemas/ExtractionNumberField'
+ text: '#/components/schemas/ExtractionTextField'
+ time: '#/components/schemas/ExtractionTimeField'
+ propertyName: 'type'
+ oneOf:
+ - $ref: '#/components/schemas/ExtractionTextField'
+ - $ref: '#/components/schemas/ExtractionNumberField'
+ - $ref: '#/components/schemas/ExtractionDateField'
+ - $ref: '#/components/schemas/ExtractionTimeField'
+ - $ref: '#/components/schemas/ExtractionDatetimeField'
+ - $ref: '#/components/schemas/ExtractionDurationField'
+ - $ref: '#/components/schemas/ExtractionListField'
+ - $ref: '#/components/schemas/ExtractionEstimateField'
+ - $ref: '#/components/schemas/ExtractionForecastField'
+ description: 'Map of field name to typed field spec.'
+ type: 'object'
+ model:
+ type: 'string'
+ provider:
+ allOf:
+ - $ref: '#/components/schemas/ProviderPreferences'
+ - description: 'Provider routing preferences for the request.'
+ reference_date:
+ description: 'ISO date that anchors dates written without a year.'
+ pattern: '^\d{4}-\d{2}-\d{2}$'
+ type: 'string'
+ session_id:
+ description: 'A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.'
+ example: 'session-1234'
+ maxLength: 256
+ type: 'string'
+ state:
+ description: 'The text to read from. May be empty only when the request carries image assets.'
+ type: 'string'
+ trace:
+ $ref: '#/components/schemas/TraceConfig'
+ user:
+ maxLength: 256
+ type: 'string'
+ required:
+ - 'model'
+ - 'state'
+ - 'fields'
+ type: 'object'
+ ExtractionsResponse:
+ properties:
+ answers:
+ additionalProperties:
+ description: 'One answer per requested field. `value` is null when the state does not determine it.'
+ discriminator:
+ mapping:
+ date: '#/components/schemas/ExtractionDateAnswer'
+ datetime: '#/components/schemas/ExtractionDatetimeAnswer'
+ duration: '#/components/schemas/ExtractionDurationAnswer'
+ estimate: '#/components/schemas/ExtractionEstimateAnswer'
+ forecast: '#/components/schemas/ExtractionForecastAnswer'
+ list: '#/components/schemas/ExtractionListAnswer'
+ number: '#/components/schemas/ExtractionNumberAnswer'
+ text: '#/components/schemas/ExtractionTextAnswer'
+ time: '#/components/schemas/ExtractionTimeAnswer'
+ propertyName: 'type'
+ oneOf:
+ - $ref: '#/components/schemas/ExtractionTextAnswer'
+ - $ref: '#/components/schemas/ExtractionNumberAnswer'
+ - $ref: '#/components/schemas/ExtractionDateAnswer'
+ - $ref: '#/components/schemas/ExtractionTimeAnswer'
+ - $ref: '#/components/schemas/ExtractionDatetimeAnswer'
+ - $ref: '#/components/schemas/ExtractionDurationAnswer'
+ - $ref: '#/components/schemas/ExtractionListAnswer'
+ - $ref: '#/components/schemas/ExtractionEstimateAnswer'
+ - $ref: '#/components/schemas/ExtractionForecastAnswer'
+ type: 'object'
+ id:
+ type: 'string'
+ model:
+ type: 'string'
+ provider:
+ type: 'string'
+ state_text:
+ description: 'The text that spans index into, when requested through provider options.'
+ type:
+ - 'string'
+ - 'null'
+ truncated:
+ description: 'True when the provider read only a prefix of the state.'
+ type: 'boolean'
+ usage:
+ $ref: '#/components/schemas/ExtractionsUsage'
+ required:
+ - 'model'
+ - 'answers'
+ - 'usage'
+ type: 'object'
+ ExtractionsUsage:
+ properties:
+ cost:
+ format: 'double'
+ type: 'number'
+ image_tokens:
+ type: 'integer'
+ input_tokens:
+ type: 'integer'
+ output_tokens:
+ type: 'integer'
+ passes:
+ description: 'Number of upstream passes when the fields did not fit in one.'
+ type: 'integer'
+ schema_tokens:
+ type: 'integer'
+ state_tokens:
+ type: 'integer'
+ required:
+ - 'input_tokens'
+ - 'output_tokens'
+ type: 'object'
+ ExtractionTextAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ type: 'string'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'text'
+ type: 'string'
+ value:
+ type:
+ - 'string'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionTextField:
+ properties:
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'text'
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
+ ExtractionTimeAnswer:
+ properties:
+ confidence:
+ format: 'double'
+ type: 'number'
+ guess:
+ description: 'The most likely value even when `value` is null because `p_null` crossed the threshold.'
+ type: 'string'
+ p_null:
+ description: 'Probability that the state contains nothing for this field.'
+ format: 'double'
+ type: 'number'
+ source:
+ description: 'Set to `image` when the answer was read from an image rather than the state text.'
+ enum:
+ - 'state'
+ - 'image'
+ type: 'string'
+ x-speakeasy-unknown-values: allow
+ span:
+ description: 'Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once.'
+ items:
+ type: 'integer'
+ maxItems: 2
+ minItems: 2
+ type: 'array'
+ spell_confidence:
+ description: 'Confidence in the spelling of text read from an image.'
+ format: 'double'
+ type: 'number'
+ type:
+ enum:
+ - 'time'
+ type: 'string'
+ value:
+ type:
+ - 'string'
+ - 'null'
+ required:
+ - 'type'
+ - 'value'
+ type: 'object'
+ ExtractionTimeField:
+ properties:
+ instructions:
+ description: 'What the field should contain.'
+ type: 'string'
+ null_threshold:
+ description: 'Probability of null above which `value` is null. Default 0.5.'
+ format: 'double'
+ maximum: 1
+ minimum: 0
+ type: 'number'
+ type:
+ enum:
+ - 'time'
+ type: 'string'
+ required:
+ - 'type'
+ type: 'object'
FailableToolCallStatus:
enum:
- 'in_progress'
@@ -13220,6 +14141,7 @@ components:
- 'embeddings'
- 'rerank'
- 'decisions'
+ - 'extractions'
- 'video'
- 'tts'
- 'stt'
@@ -35938,6 +36860,227 @@ paths:
- $ref: "#/components/parameters/AppIdentifier"
- $ref: "#/components/parameters/AppDisplayName"
- $ref: "#/components/parameters/AppCategories"
+ /api/alpha/extractions:
+ post:
+ description: 'Extracts, computes, estimates or forecasts typed fields from a state string and image assets using an extraction-style System One model. Alpha: the shape is not stable.'
+ operationId: 'createApiAlphaExtractions'
+ requestBody:
+ content:
+ application/json:
+ example:
+ fields:
+ contacts:
+ items: 'text'
+ type: 'list'
+ days_to_pay:
+ max: 120
+ min: 0
+ step: 1
+ type: 'estimate'
+ due_date:
+ instructions: 'Issue date plus the net payment days'
+ type: 'date'
+ invoice_number:
+ type: 'text'
+ total:
+ decimals: 2
+ type: 'number'
+ unit: 'USD'
+ model: 'cloudflare/clairic'
+ reference_date: '2026-10-28'
+ state: 'Invoice INV-2291 issued 2026-09-02, net 30. Contacts: Dana Ruiz, Priya Shah. Total $1080.'
+ schema:
+ $ref: '#/components/schemas/ExtractionsRequest'
+ required: true
+ responses:
+ '200':
+ content:
+ application/json:
+ example:
+ answers:
+ contacts:
+ confidence: 0.9999
+ spans:
+ - - 53
+ - 62
+ - - 64
+ - 74
+ type: 'list'
+ value:
+ - 'Dana Ruiz'
+ - 'Priya Shah'
+ days_to_pay:
+ mean: 29.5
+ median: 30
+ p10: 21
+ p90: 38
+ type: 'estimate'
+ value: 30
+ due_date:
+ guess: '2026-10-02'
+ p_null: 1.9e-8
+ type: 'date'
+ value: '2026-10-02'
+ invoice_number:
+ confidence: 1
+ guess: 'INV-2291'
+ p_null: 3.8e-10
+ span:
+ - 8
+ - 16
+ type: 'text'
+ value: 'INV-2291'
+ total:
+ confidence: 0.9999
+ guess: 1080
+ p_null: 2.3e-8
+ type: 'number'
+ value: 1080
+ id: 'gen-dec-1793251006-X5e5eKGQdvR9rblyX250'
+ model: 'cloudflare/clairic'
+ provider: 'Cloudflare'
+ truncated: false
+ usage:
+ cost: 0.0000655
+ image_tokens: 0
+ input_tokens: 655
+ output_tokens: 0
+ passes: 3
+ schema_tokens: 472
+ state_tokens: 61
+ schema:
+ $ref: '#/components/schemas/ExtractionsResponse'
+ description: 'Extractions response'
+ '400':
+ content:
+ application/json:
+ example:
+ error:
+ code: 400
+ message: 'Invalid request parameters'
+ schema:
+ $ref: '#/components/schemas/BadRequestResponse'
+ description: 'Bad Request - Invalid request parameters or malformed input'
+ '401':
+ content:
+ application/json:
+ example:
+ error:
+ code: 401
+ message: 'Missing Authentication header'
+ schema:
+ $ref: '#/components/schemas/UnauthorizedResponse'
+ description: 'Unauthorized - Authentication required or invalid credentials'
+ '402':
+ content:
+ application/json:
+ example:
+ error:
+ code: 402
+ message: 'Insufficient credits. Add more using https://openrouter.ai/credits'
+ schema:
+ $ref: '#/components/schemas/PaymentRequiredResponse'
+ description: 'Payment Required - Insufficient credits or quota to complete request'
+ '403':
+ content:
+ application/json:
+ example:
+ error:
+ code: 403
+ message: 'Only management keys can perform this operation'
+ schema:
+ $ref: '#/components/schemas/ForbiddenResponse'
+ description: 'Forbidden - Authentication successful but insufficient permissions'
+ '404':
+ content:
+ application/json:
+ example:
+ error:
+ code: 404
+ message: 'Resource not found'
+ schema:
+ $ref: '#/components/schemas/NotFoundResponse'
+ description: 'Not Found - Resource does not exist'
+ '413':
+ content:
+ application/json:
+ example:
+ error:
+ code: 413
+ message: 'Request payload too large'
+ schema:
+ $ref: '#/components/schemas/PayloadTooLargeResponse'
+ description: 'Payload Too Large - Request payload exceeds size limits'
+ '429':
+ content:
+ application/json:
+ example:
+ error:
+ code: 429
+ message: 'Rate limit exceeded'
+ schema:
+ $ref: '#/components/schemas/TooManyRequestsResponse'
+ description: 'Too Many Requests - Rate limit exceeded'
+ '500':
+ content:
+ application/json:
+ example:
+ error:
+ code: 500
+ message: 'Internal Server Error'
+ schema:
+ $ref: '#/components/schemas/InternalServerResponse'
+ description: 'Internal Server Error - Unexpected server error'
+ '502':
+ content:
+ application/json:
+ example:
+ error:
+ code: 502
+ message: 'Provider returned error'
+ schema:
+ $ref: '#/components/schemas/BadGatewayResponse'
+ description: 'Bad Gateway - Provider/upstream API failure'
+ '503':
+ content:
+ application/json:
+ example:
+ error:
+ code: 503
+ message: 'Service temporarily unavailable'
+ schema:
+ $ref: '#/components/schemas/ServiceUnavailableResponse'
+ description: 'Service Unavailable - Service temporarily unavailable'
+ '524':
+ content:
+ application/json:
+ example:
+ error:
+ code: 524
+ message: 'Request timed out. Please try again later.'
+ schema:
+ $ref: '#/components/schemas/EdgeNetworkTimeoutResponse'
+ description: 'Infrastructure Timeout - Provider request timed out at edge network'
+ '529':
+ content:
+ application/json:
+ example:
+ error:
+ code: 529
+ message: 'Provider returned error'
+ schema:
+ $ref: '#/components/schemas/ProviderOverloadedResponse'
+ description: 'Provider Overloaded - Provider is temporarily overloaded'
+ servers:
+ - url: 'https://openrouter.ai'
+ summary: 'Submit an Extractions request'
+ tags:
+ - 'alpha.extractions'
+ x-speakeasy-name-override: 'create'
+ parameters:
+ - $ref: "#/components/parameters/AppIdentifier"
+ - $ref: "#/components/parameters/AppDisplayName"
+ - $ref: "#/components/parameters/AppCategories"
/audio/speech:
post:
description: 'Synthesizes audio from the input text. Returns a raw audio bytestream in the requested format (e.g. mp3, pcm, wav).'
@@ -55421,6 +56564,8 @@ tags:
name: 'Workspaces'
- description: 'Alpha feature endpoints for Decisions requests'
name: 'alpha.decisions'
+ - description: 'Alpha feature endpoints for Extractions requests'
+ name: 'alpha.extractions'
- name: beta.responses
deprecated: true
description: Deprecated alias for responses endpoints. Use responses instead. Scheduled for removal (sunset date TBD).
diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock
index e10d8e02..38b6e2a4 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:e68f6e81a66c91c18611abd72e741995f83228a5e69c34acdc1f570ed66ef012
- sourceBlobDigest: sha256:95a532f816db55bae4bb6529bb8239de9e69b235023a5a0a7da4d138433477dc
+ sourceRevisionDigest: sha256:7224bdebdfb7db7db21a3050cdddd9e46a77cc1dc494e74f33d3ff4344212e54
+ sourceBlobDigest: sha256:85a5ebe697954c14ab896e89182ac6604c4f70c8727f0f597e8366d0e35ac5a6
tags:
- latest
- 1.0.0
@@ -11,10 +11,10 @@ targets:
open-router:
source: OpenRouter API
sourceNamespace: open-router-chat-completions-api
- sourceRevisionDigest: sha256:e68f6e81a66c91c18611abd72e741995f83228a5e69c34acdc1f570ed66ef012
- sourceBlobDigest: sha256:95a532f816db55bae4bb6529bb8239de9e69b235023a5a0a7da4d138433477dc
+ sourceRevisionDigest: sha256:7224bdebdfb7db7db21a3050cdddd9e46a77cc1dc494e74f33d3ff4344212e54
+ sourceBlobDigest: sha256:85a5ebe697954c14ab896e89182ac6604c4f70c8727f0f597e8366d0e35ac5a6
codeSamplesNamespace: open-router-python-code-samples
- codeSamplesRevisionDigest: sha256:83249b88a852f8f22434d3cff10a3509e964f9a2e17cf03cb80d14f7c497ff4c
+ codeSamplesRevisionDigest: sha256:5b837c7e38f346679203ee28da73c821659089d8aa6a6fd99589edfbd8b3e771
workflow:
workflowVersion: 1.0.0
speakeasyVersion: 1.803.2
diff --git a/RELEASES.md b/RELEASES.md
index c62c8a65..f4774583 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -3739,4 +3739,14 @@ Based on:
### Generated
- [python v1.3.97] .
### Releases
-- [PyPI v1.3.97] https://pypi.org/project/openrouter/1.3.97 - .
\ No newline at end of file
+- [PyPI v1.3.97] https://pypi.org/project/openrouter/1.3.97 - .
+
+## 2026-10-30 01:44:01
+### Changes
+Based on:
+- OpenAPI Doc
+- Speakeasy CLI 1.803.2 (2.950.13) https://github.com/speakeasy-api/speakeasy
+### Generated
+- [python v1.3.98] .
+### Releases
+- [PyPI v1.3.98] https://pypi.org/project/openrouter/1.3.98 - .
\ No newline at end of file
diff --git a/docs/components/apitype.mdx b/docs/components/apitype.mdx
index d43e0f95..f5c299e5 100644
--- a/docs/components/apitype.mdx
+++ b/docs/components/apitype.mdx
@@ -22,6 +22,7 @@ This is an open enum. Unrecognized values will not fail type checks.
- `"embeddings"`
- `"rerank"`
- `"decisions"`
+- `"extractions"`
- `"video"`
- `"tts"`
- `"stt"`
diff --git a/docs/components/decisionsresponse.mdx b/docs/components/decisionsresponse.mdx
index f2aad002..8ebd49f4 100644
--- a/docs/components/decisionsresponse.mdx
+++ b/docs/components/decisionsresponse.mdx
@@ -4,10 +4,10 @@ title: "DecisionsResponse"
## Fields
-| Field | Type | Required | Description |
-| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
-| `answers` | Dict[str, [components.Answers](../components/answers.mdx)] | ✔️ | N/A |
-| `id` | *Optional[str]* | ➖ | N/A |
-| `model` | *str* | ✔️ | N/A |
-| `provider` | *Optional[str]* | ➖ | N/A |
-| `usage` | [components.DecisionsResponseUsage](../components/decisionsresponseusage.mdx) | ✔️ | N/A |
\ No newline at end of file
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
+| `answers` | Dict[str, [components.DecisionsResponseAnswers](../components/decisionsresponseanswers.mdx)] | ✔️ | N/A |
+| `id` | *Optional[str]* | ➖ | N/A |
+| `model` | *str* | ✔️ | N/A |
+| `provider` | *Optional[str]* | ➖ | N/A |
+| `usage` | [components.DecisionsResponseUsage](../components/decisionsresponseusage.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/answers.mdx b/docs/components/decisionsresponseanswers.mdx
similarity index 94%
rename from docs/components/answers.mdx
rename to docs/components/decisionsresponseanswers.mdx
index 43893fe7..0aa4353a 100644
--- a/docs/components/answers.mdx
+++ b/docs/components/decisionsresponseanswers.mdx
@@ -1,5 +1,5 @@
---
-title: "Answers"
+title: "DecisionsResponseAnswers"
---
A Decisions answer using a boolean, choice, score, or image bounding-box evaluation.
diff --git a/docs/components/extractiondateanswer.mdx b/docs/components/extractiondateanswer.mdx
new file mode 100644
index 00000000..c79d84d3
--- /dev/null
+++ b/docs/components/extractiondateanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionDateAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[str]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionDateAnswerSource]](../components/extractiondateanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionDateAnswerType](../components/extractiondateanswertype.mdx) | ✔️ | N/A |
+| `value` | *Nullable[str]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiondateanswersource.mdx b/docs/components/extractiondateanswersource.mdx
new file mode 100644
index 00000000..3efa8603
--- /dev/null
+++ b/docs/components/extractiondateanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionDateAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDateAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionDateAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractiondateanswertype.mdx b/docs/components/extractiondateanswertype.mdx
new file mode 100644
index 00000000..a369fe5e
--- /dev/null
+++ b/docs/components/extractiondateanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDateAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDateAnswerType
+value: ExtractionDateAnswerType = "date"
+```
+
+
+## Values
+
+- `"date"`
diff --git a/docs/components/extractiondatefield.mdx b/docs/components/extractiondatefield.mdx
new file mode 100644
index 00000000..ecceaea2
--- /dev/null
+++ b/docs/components/extractiondatefield.mdx
@@ -0,0 +1,11 @@
+---
+title: "ExtractionDateField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionDateFieldType](../components/extractiondatefieldtype.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiondatefieldtype.mdx b/docs/components/extractiondatefieldtype.mdx
new file mode 100644
index 00000000..93062f3d
--- /dev/null
+++ b/docs/components/extractiondatefieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDateFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDateFieldType
+value: ExtractionDateFieldType = "date"
+```
+
+
+## Values
+
+- `"date"`
diff --git a/docs/components/extractiondatetimeanswer.mdx b/docs/components/extractiondatetimeanswer.mdx
new file mode 100644
index 00000000..c3a07d0e
--- /dev/null
+++ b/docs/components/extractiondatetimeanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionDatetimeAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[str]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionDatetimeAnswerSource]](../components/extractiondatetimeanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionDatetimeAnswerType](../components/extractiondatetimeanswertype.mdx) | ✔️ | N/A |
+| `value` | *Nullable[str]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiondatetimeanswersource.mdx b/docs/components/extractiondatetimeanswersource.mdx
new file mode 100644
index 00000000..4de96384
--- /dev/null
+++ b/docs/components/extractiondatetimeanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionDatetimeAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDatetimeAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionDatetimeAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractiondatetimeanswertype.mdx b/docs/components/extractiondatetimeanswertype.mdx
new file mode 100644
index 00000000..73da000c
--- /dev/null
+++ b/docs/components/extractiondatetimeanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDatetimeAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDatetimeAnswerType
+value: ExtractionDatetimeAnswerType = "datetime"
+```
+
+
+## Values
+
+- `"datetime"`
diff --git a/docs/components/extractiondatetimefield.mdx b/docs/components/extractiondatetimefield.mdx
new file mode 100644
index 00000000..1c6a9f4e
--- /dev/null
+++ b/docs/components/extractiondatetimefield.mdx
@@ -0,0 +1,11 @@
+---
+title: "ExtractionDatetimeField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionDatetimeFieldType](../components/extractiondatetimefieldtype.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiondatetimefieldtype.mdx b/docs/components/extractiondatetimefieldtype.mdx
new file mode 100644
index 00000000..a8fb1fa4
--- /dev/null
+++ b/docs/components/extractiondatetimefieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDatetimeFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDatetimeFieldType
+value: ExtractionDatetimeFieldType = "datetime"
+```
+
+
+## Values
+
+- `"datetime"`
diff --git a/docs/components/extractiondurationanswer.mdx b/docs/components/extractiondurationanswer.mdx
new file mode 100644
index 00000000..9d2fe99c
--- /dev/null
+++ b/docs/components/extractiondurationanswer.mdx
@@ -0,0 +1,17 @@
+---
+title: "ExtractionDurationAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[float]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionDurationAnswerSource]](../components/extractiondurationanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionDurationAnswerType](../components/extractiondurationanswertype.mdx) | ✔️ | N/A |
+| `unit` | *Optional[str]* | ➖ | The unit `value` is expressed in. |
+| `value` | *Nullable[float]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiondurationanswersource.mdx b/docs/components/extractiondurationanswersource.mdx
new file mode 100644
index 00000000..05bfe9cb
--- /dev/null
+++ b/docs/components/extractiondurationanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionDurationAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDurationAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionDurationAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractiondurationanswertype.mdx b/docs/components/extractiondurationanswertype.mdx
new file mode 100644
index 00000000..66980844
--- /dev/null
+++ b/docs/components/extractiondurationanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDurationAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDurationAnswerType
+value: ExtractionDurationAnswerType = "duration"
+```
+
+
+## Values
+
+- `"duration"`
diff --git a/docs/components/extractiondurationfield.mdx b/docs/components/extractiondurationfield.mdx
new file mode 100644
index 00000000..1bcc7faa
--- /dev/null
+++ b/docs/components/extractiondurationfield.mdx
@@ -0,0 +1,14 @@
+---
+title: "ExtractionDurationField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
+| `decimals` | *Optional[int]* | ➖ | Decimal places kept in `value`. |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `integer` | *Optional[bool]* | ➖ | N/A |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionDurationFieldType](../components/extractiondurationfieldtype.mdx) | ✔️ | N/A |
+| `unit` | *Optional[str]* | ➖ | seconds, minutes, hours, days, weeks, months or years. |
\ No newline at end of file
diff --git a/docs/components/extractiondurationfieldtype.mdx b/docs/components/extractiondurationfieldtype.mdx
new file mode 100644
index 00000000..53575c65
--- /dev/null
+++ b/docs/components/extractiondurationfieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionDurationFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionDurationFieldType
+value: ExtractionDurationFieldType = "duration"
+```
+
+
+## Values
+
+- `"duration"`
diff --git a/docs/components/extractionestimateanswer.mdx b/docs/components/extractionestimateanswer.mdx
new file mode 100644
index 00000000..1c076a06
--- /dev/null
+++ b/docs/components/extractionestimateanswer.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionEstimateAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | [Optional[components.ExtractionEstimateAnswerGuess]](../components/extractionestimateanswerguess.mdx) | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `mean` | [Optional[components.ExtractionEstimateAnswerMean]](../components/extractionestimateanswermean.mdx) | ➖ | N/A |
+| `median` | [Optional[components.ExtractionEstimateAnswerMedian]](../components/extractionestimateanswermedian.mdx) | ➖ | N/A |
+| `p_above` | *Optional[float]* | ➖ | Probability mass above `max`. |
+| `p_below` | *Optional[float]* | ➖ | Probability mass below `min`. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `p10` | [Optional[components.ExtractionEstimateAnswerP10]](../components/extractionestimateanswerp10.mdx) | ➖ | N/A |
+| `p90` | [Optional[components.ExtractionEstimateAnswerP90]](../components/extractionestimateanswerp90.mdx) | ➖ | N/A |
+| `quantiles` | List[[components.ExtractionEstimateAnswerQuantile](../components/extractionestimateanswerquantile.mdx)] | ➖ | 99 percentiles, present when the provider is asked for quantiles. |
+| `source` | [Optional[components.ExtractionEstimateAnswerSource]](../components/extractionestimateanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionEstimateAnswerType](../components/extractionestimateanswertype.mdx) | ✔️ | N/A |
+| `value` | [Nullable[components.ExtractionEstimateAnswerValue]](../components/extractionestimateanswervalue.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionestimateanswerguess.mdx b/docs/components/extractionestimateanswerguess.mdx
new file mode 100644
index 00000000..7a2425fe
--- /dev/null
+++ b/docs/components/extractionestimateanswerguess.mdx
@@ -0,0 +1,21 @@
+---
+title: "ExtractionEstimateAnswerGuess"
+---
+
+The most likely value even when `value` is null because `p_null` crossed the threshold.
+
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswermean.mdx b/docs/components/extractionestimateanswermean.mdx
new file mode 100644
index 00000000..b9dace3e
--- /dev/null
+++ b/docs/components/extractionestimateanswermean.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerMean"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswermedian.mdx b/docs/components/extractionestimateanswermedian.mdx
new file mode 100644
index 00000000..612874e1
--- /dev/null
+++ b/docs/components/extractionestimateanswermedian.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerMedian"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswerp10.mdx b/docs/components/extractionestimateanswerp10.mdx
new file mode 100644
index 00000000..73fd2a37
--- /dev/null
+++ b/docs/components/extractionestimateanswerp10.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerP10"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswerp90.mdx b/docs/components/extractionestimateanswerp90.mdx
new file mode 100644
index 00000000..7036166a
--- /dev/null
+++ b/docs/components/extractionestimateanswerp90.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerP90"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswerquantile.mdx b/docs/components/extractionestimateanswerquantile.mdx
new file mode 100644
index 00000000..bbe9e23c
--- /dev/null
+++ b/docs/components/extractionestimateanswerquantile.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerQuantile"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimateanswersource.mdx b/docs/components/extractionestimateanswersource.mdx
new file mode 100644
index 00000000..146c7bca
--- /dev/null
+++ b/docs/components/extractionestimateanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionEstimateAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionEstimateAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractionestimateanswertype.mdx b/docs/components/extractionestimateanswertype.mdx
new file mode 100644
index 00000000..a777d831
--- /dev/null
+++ b/docs/components/extractionestimateanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionEstimateAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateAnswerType
+value: ExtractionEstimateAnswerType = "estimate"
+```
+
+
+## Values
+
+- `"estimate"`
diff --git a/docs/components/extractionestimateanswervalue.mdx b/docs/components/extractionestimateanswervalue.mdx
new file mode 100644
index 00000000..768b5466
--- /dev/null
+++ b/docs/components/extractionestimateanswervalue.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateAnswerValue"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimatefield.mdx b/docs/components/extractionestimatefield.mdx
new file mode 100644
index 00000000..7f18a341
--- /dev/null
+++ b/docs/components/extractionestimatefield.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionEstimateField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `max` | [components.ExtractionEstimateFieldMax](../components/extractionestimatefieldmax.mdx) | ✔️ | N/A |
+| `min` | [components.ExtractionEstimateFieldMin](../components/extractionestimatefieldmin.mdx) | ✔️ | N/A |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `scale` | [Optional[components.ExtractionEstimateFieldScale]](../components/extractionestimatefieldscale.mdx) | ➖ | N/A |
+| `step` | [Optional[components.ExtractionEstimateFieldStepUnion]](../components/extractionestimatefieldstepunion.mdx) | ➖ | N/A |
+| `type` | [components.ExtractionEstimateFieldType](../components/extractionestimatefieldtype.mdx) | ✔️ | N/A |
+| `unit` | *Optional[str]* | ➖ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionestimatefieldmax.mdx b/docs/components/extractionestimatefieldmax.mdx
new file mode 100644
index 00000000..9fffe5a3
--- /dev/null
+++ b/docs/components/extractionestimatefieldmax.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateFieldMax"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimatefieldmin.mdx b/docs/components/extractionestimatefieldmin.mdx
new file mode 100644
index 00000000..2fd6dc6f
--- /dev/null
+++ b/docs/components/extractionestimatefieldmin.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionEstimateFieldMin"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionestimatefieldscale.mdx b/docs/components/extractionestimatefieldscale.mdx
new file mode 100644
index 00000000..d50a188a
--- /dev/null
+++ b/docs/components/extractionestimatefieldscale.mdx
@@ -0,0 +1,20 @@
+---
+title: "ExtractionEstimateFieldScale"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateFieldScale
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionEstimateFieldScale = "linear"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"linear"`
+- `"log"`
diff --git a/docs/components/extractionestimatefieldstepmonth.mdx b/docs/components/extractionestimatefieldstepmonth.mdx
new file mode 100644
index 00000000..ae39f752
--- /dev/null
+++ b/docs/components/extractionestimatefieldstepmonth.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionEstimateFieldStepMonth"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateFieldStepMonth
+value: ExtractionEstimateFieldStepMonth = "month"
+```
+
+
+## Values
+
+- `"month"`
diff --git a/docs/components/extractionestimatefieldstepunion.mdx b/docs/components/extractionestimatefieldstepunion.mdx
new file mode 100644
index 00000000..c9eff1dd
--- /dev/null
+++ b/docs/components/extractionestimatefieldstepunion.mdx
@@ -0,0 +1,24 @@
+---
+title: "ExtractionEstimateFieldStepUnion"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `components.ExtractionEstimateFieldStepMonth`
+
+```python
+value: components.ExtractionEstimateFieldStepMonth = /* values here */
+```
+
+### `components.ExtractionEstimateFieldStepYear`
+
+```python
+value: components.ExtractionEstimateFieldStepYear = /* values here */
+```
+
diff --git a/docs/components/extractionestimatefieldstepyear.mdx b/docs/components/extractionestimatefieldstepyear.mdx
new file mode 100644
index 00000000..ed71a17c
--- /dev/null
+++ b/docs/components/extractionestimatefieldstepyear.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionEstimateFieldStepYear"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateFieldStepYear
+value: ExtractionEstimateFieldStepYear = "year"
+```
+
+
+## Values
+
+- `"year"`
diff --git a/docs/components/extractionestimatefieldtype.mdx b/docs/components/extractionestimatefieldtype.mdx
new file mode 100644
index 00000000..752c86c4
--- /dev/null
+++ b/docs/components/extractionestimatefieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionEstimateFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionEstimateFieldType
+value: ExtractionEstimateFieldType = "estimate"
+```
+
+
+## Values
+
+- `"estimate"`
diff --git a/docs/components/extractionforecastanswer.mdx b/docs/components/extractionforecastanswer.mdx
new file mode 100644
index 00000000..c6372d9e
--- /dev/null
+++ b/docs/components/extractionforecastanswer.mdx
@@ -0,0 +1,20 @@
+---
+title: "ExtractionForecastAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | List[[components.ExtractionForecastAnswerGuess](../components/extractionforecastanswerguess.mdx)] | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `mean` | List[[components.ExtractionForecastAnswerMean](../components/extractionforecastanswermean.mdx)] | ➖ | N/A |
+| `median` | List[[components.ExtractionForecastAnswerMedian](../components/extractionforecastanswermedian.mdx)] | ➖ | N/A |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `p10` | List[[components.ExtractionForecastAnswerP10](../components/extractionforecastanswerp10.mdx)] | ➖ | N/A |
+| `p90` | List[[components.ExtractionForecastAnswerP90](../components/extractionforecastanswerp90.mdx)] | ➖ | N/A |
+| `source` | [Optional[components.ExtractionForecastAnswerSource]](../components/extractionforecastanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `steps` | List[[components.ExtractionForecastStep](../components/extractionforecaststep.mdx)] | ➖ | N/A |
+| `type` | [components.ExtractionForecastAnswerType](../components/extractionforecastanswertype.mdx) | ✔️ | N/A |
+| `value` | List[[components.ExtractionForecastAnswerValue](../components/extractionforecastanswervalue.mdx)] | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionforecastanswerguess.mdx b/docs/components/extractionforecastanswerguess.mdx
new file mode 100644
index 00000000..75470032
--- /dev/null
+++ b/docs/components/extractionforecastanswerguess.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerGuess"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastanswermean.mdx b/docs/components/extractionforecastanswermean.mdx
new file mode 100644
index 00000000..8c60cac3
--- /dev/null
+++ b/docs/components/extractionforecastanswermean.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerMean"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastanswermedian.mdx b/docs/components/extractionforecastanswermedian.mdx
new file mode 100644
index 00000000..df34bf9d
--- /dev/null
+++ b/docs/components/extractionforecastanswermedian.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerMedian"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastanswerp10.mdx b/docs/components/extractionforecastanswerp10.mdx
new file mode 100644
index 00000000..781d0ecf
--- /dev/null
+++ b/docs/components/extractionforecastanswerp10.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerP10"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastanswerp90.mdx b/docs/components/extractionforecastanswerp90.mdx
new file mode 100644
index 00000000..35fe4d98
--- /dev/null
+++ b/docs/components/extractionforecastanswerp90.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerP90"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastanswersource.mdx b/docs/components/extractionforecastanswersource.mdx
new file mode 100644
index 00000000..8e82e177
--- /dev/null
+++ b/docs/components/extractionforecastanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionForecastAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionForecastAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractionforecastanswertype.mdx b/docs/components/extractionforecastanswertype.mdx
new file mode 100644
index 00000000..50ac0374
--- /dev/null
+++ b/docs/components/extractionforecastanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionForecastAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastAnswerType
+value: ExtractionForecastAnswerType = "forecast"
+```
+
+
+## Values
+
+- `"forecast"`
diff --git a/docs/components/extractionforecastanswervalue.mdx b/docs/components/extractionforecastanswervalue.mdx
new file mode 100644
index 00000000..e5996b4f
--- /dev/null
+++ b/docs/components/extractionforecastanswervalue.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastAnswerValue"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastfield.mdx b/docs/components/extractionforecastfield.mdx
new file mode 100644
index 00000000..db299598
--- /dev/null
+++ b/docs/components/extractionforecastfield.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
+| `horizon` | *int* | ✔️ | Number of forecast steps. |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `interval` | [components.Interval](../components/interval.mdx) | ✔️ | N/A |
+| `max` | [components.ExtractionForecastFieldMax](../components/extractionforecastfieldmax.mdx) | ✔️ | N/A |
+| `min` | [components.ExtractionForecastFieldMin](../components/extractionforecastfieldmin.mdx) | ✔️ | N/A |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `scale` | [Optional[components.ExtractionForecastFieldScale]](../components/extractionforecastfieldscale.mdx) | ➖ | N/A |
+| `step` | [Optional[components.ExtractionForecastFieldStepUnion]](../components/extractionforecastfieldstepunion.mdx) | ➖ | N/A |
+| `type` | [components.ExtractionForecastFieldType](../components/extractionforecastfieldtype.mdx) | ✔️ | N/A |
+| `unit` | *Optional[str]* | ➖ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionforecastfieldmax.mdx b/docs/components/extractionforecastfieldmax.mdx
new file mode 100644
index 00000000..297f6053
--- /dev/null
+++ b/docs/components/extractionforecastfieldmax.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastFieldMax"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastfieldmin.mdx b/docs/components/extractionforecastfieldmin.mdx
new file mode 100644
index 00000000..08794f20
--- /dev/null
+++ b/docs/components/extractionforecastfieldmin.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastFieldMin"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecastfieldscale.mdx b/docs/components/extractionforecastfieldscale.mdx
new file mode 100644
index 00000000..d49150a3
--- /dev/null
+++ b/docs/components/extractionforecastfieldscale.mdx
@@ -0,0 +1,20 @@
+---
+title: "ExtractionForecastFieldScale"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastFieldScale
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionForecastFieldScale = "linear"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"linear"`
+- `"log"`
diff --git a/docs/components/extractionforecastfieldstepmonth.mdx b/docs/components/extractionforecastfieldstepmonth.mdx
new file mode 100644
index 00000000..4daa57c1
--- /dev/null
+++ b/docs/components/extractionforecastfieldstepmonth.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionForecastFieldStepMonth"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastFieldStepMonth
+value: ExtractionForecastFieldStepMonth = "month"
+```
+
+
+## Values
+
+- `"month"`
diff --git a/docs/components/extractionforecastfieldstepunion.mdx b/docs/components/extractionforecastfieldstepunion.mdx
new file mode 100644
index 00000000..e3b3462e
--- /dev/null
+++ b/docs/components/extractionforecastfieldstepunion.mdx
@@ -0,0 +1,24 @@
+---
+title: "ExtractionForecastFieldStepUnion"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `components.ExtractionForecastFieldStepMonth`
+
+```python
+value: components.ExtractionForecastFieldStepMonth = /* values here */
+```
+
+### `components.ExtractionForecastFieldStepYear`
+
+```python
+value: components.ExtractionForecastFieldStepYear = /* values here */
+```
+
diff --git a/docs/components/extractionforecastfieldstepyear.mdx b/docs/components/extractionforecastfieldstepyear.mdx
new file mode 100644
index 00000000..6de0cc1d
--- /dev/null
+++ b/docs/components/extractionforecastfieldstepyear.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionForecastFieldStepYear"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastFieldStepYear
+value: ExtractionForecastFieldStepYear = "year"
+```
+
+
+## Values
+
+- `"year"`
diff --git a/docs/components/extractionforecastfieldtype.mdx b/docs/components/extractionforecastfieldtype.mdx
new file mode 100644
index 00000000..510e9cdf
--- /dev/null
+++ b/docs/components/extractionforecastfieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionForecastFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionForecastFieldType
+value: ExtractionForecastFieldType = "forecast"
+```
+
+
+## Values
+
+- `"forecast"`
diff --git a/docs/components/extractionforecaststep.mdx b/docs/components/extractionforecaststep.mdx
new file mode 100644
index 00000000..c7bb7611
--- /dev/null
+++ b/docs/components/extractionforecaststep.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionForecastStep"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
+| `mean` | [Optional[components.ExtractionForecastStepMean]](../components/extractionforecaststepmean.mdx) | ➖ | N/A |
+| `median` | [Optional[components.ExtractionForecastStepMedian]](../components/extractionforecaststepmedian.mdx) | ➖ | N/A |
+| `p_above` | *Optional[float]* | ➖ | Probability mass above `max`. |
+| `p_below` | *Optional[float]* | ➖ | Probability mass below `min`. |
+| `p10` | [Optional[components.ExtractionForecastStepP10]](../components/extractionforecaststepp10.mdx) | ➖ | N/A |
+| `p90` | [Optional[components.ExtractionForecastStepP90]](../components/extractionforecaststepp90.mdx) | ➖ | N/A |
+| `quantiles` | List[[components.ExtractionForecastStepQuantile](../components/extractionforecaststepquantile.mdx)] | ➖ | 99 percentiles, present when the provider is asked for quantiles. |
+| `value` | [Nullable[components.ExtractionForecastStepValue]](../components/extractionforecaststepvalue.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionforecaststepmean.mdx b/docs/components/extractionforecaststepmean.mdx
new file mode 100644
index 00000000..582379e2
--- /dev/null
+++ b/docs/components/extractionforecaststepmean.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepMean"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecaststepmedian.mdx b/docs/components/extractionforecaststepmedian.mdx
new file mode 100644
index 00000000..724fd4d3
--- /dev/null
+++ b/docs/components/extractionforecaststepmedian.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepMedian"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecaststepp10.mdx b/docs/components/extractionforecaststepp10.mdx
new file mode 100644
index 00000000..53cd66d4
--- /dev/null
+++ b/docs/components/extractionforecaststepp10.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepP10"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecaststepp90.mdx b/docs/components/extractionforecaststepp90.mdx
new file mode 100644
index 00000000..55daa960
--- /dev/null
+++ b/docs/components/extractionforecaststepp90.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepP90"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecaststepquantile.mdx b/docs/components/extractionforecaststepquantile.mdx
new file mode 100644
index 00000000..1ba0e060
--- /dev/null
+++ b/docs/components/extractionforecaststepquantile.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepQuantile"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionforecaststepvalue.mdx b/docs/components/extractionforecaststepvalue.mdx
new file mode 100644
index 00000000..e971ec1f
--- /dev/null
+++ b/docs/components/extractionforecaststepvalue.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionForecastStepValue"
+---
+
+## Supported Types
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
diff --git a/docs/components/extractionlistanswer.mdx b/docs/components/extractionlistanswer.mdx
new file mode 100644
index 00000000..b6ff7aef
--- /dev/null
+++ b/docs/components/extractionlistanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionListAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | List[[components.ExtractionListAnswerGuess](../components/extractionlistanswerguess.mdx)] | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionListAnswerSource]](../components/extractionlistanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `spans` | List[List[*int*]] | ➖ | N/A |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionListAnswerType](../components/extractionlistanswertype.mdx) | ✔️ | N/A |
+| `value` | List[[components.ExtractionListAnswerValue](../components/extractionlistanswervalue.mdx)] | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionlistanswerguess.mdx b/docs/components/extractionlistanswerguess.mdx
new file mode 100644
index 00000000..d429b355
--- /dev/null
+++ b/docs/components/extractionlistanswerguess.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionListAnswerGuess"
+---
+
+## Supported Types
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
diff --git a/docs/components/extractionlistanswersource.mdx b/docs/components/extractionlistanswersource.mdx
new file mode 100644
index 00000000..1f178170
--- /dev/null
+++ b/docs/components/extractionlistanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionListAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionListAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionListAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractionlistanswertype.mdx b/docs/components/extractionlistanswertype.mdx
new file mode 100644
index 00000000..8abd7823
--- /dev/null
+++ b/docs/components/extractionlistanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionListAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionListAnswerType
+value: ExtractionListAnswerType = "list"
+```
+
+
+## Values
+
+- `"list"`
diff --git a/docs/components/extractionlistanswervalue.mdx b/docs/components/extractionlistanswervalue.mdx
new file mode 100644
index 00000000..cd38d0f8
--- /dev/null
+++ b/docs/components/extractionlistanswervalue.mdx
@@ -0,0 +1,18 @@
+---
+title: "ExtractionListAnswerValue"
+---
+
+## Supported Types
+
+### `str`
+
+```python
+value: str = /* values here */
+```
+
+### `float`
+
+```python
+value: float = /* values here */
+```
+
diff --git a/docs/components/extractionlistfield.mdx b/docs/components/extractionlistfield.mdx
new file mode 100644
index 00000000..0a3b5068
--- /dev/null
+++ b/docs/components/extractionlistfield.mdx
@@ -0,0 +1,13 @@
+---
+title: "ExtractionListField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
+| `decimals` | *Optional[int]* | ➖ | Decimal places kept in `value`. |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `items` | [components.Items](../components/items.mdx) | ✔️ | N/A |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionListFieldType](../components/extractionlistfieldtype.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionlistfieldtype.mdx b/docs/components/extractionlistfieldtype.mdx
new file mode 100644
index 00000000..1c3e50bc
--- /dev/null
+++ b/docs/components/extractionlistfieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionListFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionListFieldType
+value: ExtractionListFieldType = "list"
+```
+
+
+## Values
+
+- `"list"`
diff --git a/docs/components/extractionnumberanswer.mdx b/docs/components/extractionnumberanswer.mdx
new file mode 100644
index 00000000..910b88e2
--- /dev/null
+++ b/docs/components/extractionnumberanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionNumberAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[float]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionNumberAnswerSource]](../components/extractionnumberanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionNumberAnswerType](../components/extractionnumberanswertype.mdx) | ✔️ | N/A |
+| `value` | *Nullable[float]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionnumberanswersource.mdx b/docs/components/extractionnumberanswersource.mdx
new file mode 100644
index 00000000..9bd79076
--- /dev/null
+++ b/docs/components/extractionnumberanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionNumberAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionNumberAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionNumberAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractionnumberanswertype.mdx b/docs/components/extractionnumberanswertype.mdx
new file mode 100644
index 00000000..62e2f6af
--- /dev/null
+++ b/docs/components/extractionnumberanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionNumberAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionNumberAnswerType
+value: ExtractionNumberAnswerType = "number"
+```
+
+
+## Values
+
+- `"number"`
diff --git a/docs/components/extractionnumberfield.mdx b/docs/components/extractionnumberfield.mdx
new file mode 100644
index 00000000..a57a6dc6
--- /dev/null
+++ b/docs/components/extractionnumberfield.mdx
@@ -0,0 +1,14 @@
+---
+title: "ExtractionNumberField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
+| `decimals` | *Optional[int]* | ➖ | Decimal places kept in `value`. |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `integer` | *Optional[bool]* | ➖ | N/A |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionNumberFieldType](../components/extractionnumberfieldtype.mdx) | ✔️ | N/A |
+| `unit` | *Optional[str]* | ➖ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionnumberfieldtype.mdx b/docs/components/extractionnumberfieldtype.mdx
new file mode 100644
index 00000000..0f381107
--- /dev/null
+++ b/docs/components/extractionnumberfieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionNumberFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionNumberFieldType
+value: ExtractionNumberFieldType = "number"
+```
+
+
+## Values
+
+- `"number"`
diff --git a/docs/components/extractionsrequest.mdx b/docs/components/extractionsrequest.mdx
new file mode 100644
index 00000000..d0d122a3
--- /dev/null
+++ b/docs/components/extractionsrequest.mdx
@@ -0,0 +1,17 @@
+---
+title: "ExtractionsRequest"
+---
+
+## Fields
+
+| Field | Type | Required | Description | Example |
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `assets` | Dict[str, [components.DecisionsImageAsset](../components/decisionsimageasset.mdx)] | ➖ | Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text. | |
+| `fields` | Dict[str, [components.Fields](../components/fields.mdx)] | ✔️ | Map of field name to typed field spec. | |
+| `model` | *str* | ✔️ | N/A | |
+| `provider` | [OptionalNullable[components.ProviderPreferences]](../components/providerpreferences.mdx) | ➖ | N/A | \{
"allow_fallbacks": true
} |
+| `reference_date` | *Optional[str]* | ➖ | ISO date that anchors dates written without a year. | |
+| `session_id` | *Optional[str]* | ➖ | A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters. | session-1234 |
+| `state` | *str* | ✔️ | The text to read from. May be empty only when the request carries image assets. | |
+| `trace` | [Optional[components.TraceConfig]](../components/traceconfig.mdx) | ➖ | Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations. | \{
"trace_id": "trace-abc123",
"trace_name": "my-app-trace"
} |
+| `user` | *Optional[str]* | ➖ | N/A | |
\ No newline at end of file
diff --git a/docs/components/extractionsresponse.mdx b/docs/components/extractionsresponse.mdx
new file mode 100644
index 00000000..58b0baeb
--- /dev/null
+++ b/docs/components/extractionsresponse.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionsResponse"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
+| `answers` | Dict[str, [components.ExtractionsResponseAnswers](../components/extractionsresponseanswers.mdx)] | ✔️ | N/A |
+| `id` | *Optional[str]* | ➖ | N/A |
+| `model` | *str* | ✔️ | N/A |
+| `provider` | *Optional[str]* | ➖ | N/A |
+| `state_text` | *OptionalNullable[str]* | ➖ | The text that spans index into, when requested through provider options. |
+| `truncated` | *Optional[bool]* | ➖ | True when the provider read only a prefix of the state. |
+| `usage` | [components.ExtractionsUsage](../components/extractionsusage.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractionsresponseanswers.mdx b/docs/components/extractionsresponseanswers.mdx
new file mode 100644
index 00000000..b44b7055
--- /dev/null
+++ b/docs/components/extractionsresponseanswers.mdx
@@ -0,0 +1,63 @@
+---
+title: "ExtractionsResponseAnswers"
+---
+
+One answer per requested field. `value` is null when the state does not determine it.
+
+
+## Supported Types
+
+### `components.ExtractionDateAnswer`
+
+```python
+value: components.ExtractionDateAnswer = /* values here */
+```
+
+### `components.ExtractionDatetimeAnswer`
+
+```python
+value: components.ExtractionDatetimeAnswer = /* values here */
+```
+
+### `components.ExtractionDurationAnswer`
+
+```python
+value: components.ExtractionDurationAnswer = /* values here */
+```
+
+### `components.ExtractionEstimateAnswer`
+
+```python
+value: components.ExtractionEstimateAnswer = /* values here */
+```
+
+### `components.ExtractionForecastAnswer`
+
+```python
+value: components.ExtractionForecastAnswer = /* values here */
+```
+
+### `components.ExtractionListAnswer`
+
+```python
+value: components.ExtractionListAnswer = /* values here */
+```
+
+### `components.ExtractionNumberAnswer`
+
+```python
+value: components.ExtractionNumberAnswer = /* values here */
+```
+
+### `components.ExtractionTextAnswer`
+
+```python
+value: components.ExtractionTextAnswer = /* values here */
+```
+
+### `components.ExtractionTimeAnswer`
+
+```python
+value: components.ExtractionTimeAnswer = /* values here */
+```
+
diff --git a/docs/components/extractionsusage.mdx b/docs/components/extractionsusage.mdx
new file mode 100644
index 00000000..7d335f16
--- /dev/null
+++ b/docs/components/extractionsusage.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionsUsage"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------- |
+| `cost` | *Optional[float]* | ➖ | N/A |
+| `image_tokens` | *Optional[int]* | ➖ | N/A |
+| `input_tokens` | *int* | ✔️ | N/A |
+| `output_tokens` | *int* | ✔️ | N/A |
+| `passes` | *Optional[int]* | ➖ | Number of upstream passes when the fields did not fit in one. |
+| `schema_tokens` | *Optional[int]* | ➖ | N/A |
+| `state_tokens` | *Optional[int]* | ➖ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiontextanswer.mdx b/docs/components/extractiontextanswer.mdx
new file mode 100644
index 00000000..b8f0fe6c
--- /dev/null
+++ b/docs/components/extractiontextanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionTextAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[str]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionTextAnswerSource]](../components/extractiontextanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionTextAnswerType](../components/extractiontextanswertype.mdx) | ✔️ | N/A |
+| `value` | *Nullable[str]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiontextanswersource.mdx b/docs/components/extractiontextanswersource.mdx
new file mode 100644
index 00000000..29c1e186
--- /dev/null
+++ b/docs/components/extractiontextanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionTextAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTextAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionTextAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractiontextanswertype.mdx b/docs/components/extractiontextanswertype.mdx
new file mode 100644
index 00000000..190c505a
--- /dev/null
+++ b/docs/components/extractiontextanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionTextAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTextAnswerType
+value: ExtractionTextAnswerType = "text"
+```
+
+
+## Values
+
+- `"text"`
diff --git a/docs/components/extractiontextfield.mdx b/docs/components/extractiontextfield.mdx
new file mode 100644
index 00000000..7f4c2d28
--- /dev/null
+++ b/docs/components/extractiontextfield.mdx
@@ -0,0 +1,11 @@
+---
+title: "ExtractionTextField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionTextFieldType](../components/extractiontextfieldtype.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiontextfieldtype.mdx b/docs/components/extractiontextfieldtype.mdx
new file mode 100644
index 00000000..d8d4a00c
--- /dev/null
+++ b/docs/components/extractiontextfieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionTextFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTextFieldType
+value: ExtractionTextFieldType = "text"
+```
+
+
+## Values
+
+- `"text"`
diff --git a/docs/components/extractiontimeanswer.mdx b/docs/components/extractiontimeanswer.mdx
new file mode 100644
index 00000000..065ab42c
--- /dev/null
+++ b/docs/components/extractiontimeanswer.mdx
@@ -0,0 +1,16 @@
+---
+title: "ExtractionTimeAnswer"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `confidence` | *Optional[float]* | ➖ | N/A |
+| `guess` | *Optional[str]* | ➖ | The most likely value even when `value` is null because `p_null` crossed the threshold. |
+| `p_null` | *Optional[float]* | ➖ | Probability that the state contains nothing for this field. |
+| `source` | [Optional[components.ExtractionTimeAnswerSource]](../components/extractiontimeanswersource.mdx) | ➖ | Set to `image` when the answer was read from an image rather than the state text. |
+| `span` | List[*int*] | ➖ | Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once. |
+| `spell_confidence` | *Optional[float]* | ➖ | Confidence in the spelling of text read from an image. |
+| `type` | [components.ExtractionTimeAnswerType](../components/extractiontimeanswertype.mdx) | ✔️ | N/A |
+| `value` | *Nullable[str]* | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiontimeanswersource.mdx b/docs/components/extractiontimeanswersource.mdx
new file mode 100644
index 00000000..068f14a4
--- /dev/null
+++ b/docs/components/extractiontimeanswersource.mdx
@@ -0,0 +1,22 @@
+---
+title: "ExtractionTimeAnswerSource"
+---
+
+Set to `image` when the answer was read from an image rather than the state text.
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTimeAnswerSource
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: ExtractionTimeAnswerSource = "state"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"state"`
+- `"image"`
diff --git a/docs/components/extractiontimeanswertype.mdx b/docs/components/extractiontimeanswertype.mdx
new file mode 100644
index 00000000..9fd70049
--- /dev/null
+++ b/docs/components/extractiontimeanswertype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionTimeAnswerType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTimeAnswerType
+value: ExtractionTimeAnswerType = "time"
+```
+
+
+## Values
+
+- `"time"`
diff --git a/docs/components/extractiontimefield.mdx b/docs/components/extractiontimefield.mdx
new file mode 100644
index 00000000..3d48fdab
--- /dev/null
+++ b/docs/components/extractiontimefield.mdx
@@ -0,0 +1,11 @@
+---
+title: "ExtractionTimeField"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------ |
+| `instructions` | *Optional[str]* | ➖ | What the field should contain. |
+| `null_threshold` | *Optional[float]* | ➖ | Probability of null above which `value` is null. Default 0.5. |
+| `type` | [components.ExtractionTimeFieldType](../components/extractiontimefieldtype.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/components/extractiontimefieldtype.mdx b/docs/components/extractiontimefieldtype.mdx
new file mode 100644
index 00000000..24971de2
--- /dev/null
+++ b/docs/components/extractiontimefieldtype.mdx
@@ -0,0 +1,15 @@
+---
+title: "ExtractionTimeFieldType"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import ExtractionTimeFieldType
+value: ExtractionTimeFieldType = "time"
+```
+
+
+## Values
+
+- `"time"`
diff --git a/docs/components/fields.mdx b/docs/components/fields.mdx
new file mode 100644
index 00000000..15e95b7d
--- /dev/null
+++ b/docs/components/fields.mdx
@@ -0,0 +1,63 @@
+---
+title: "Fields"
+---
+
+A typed field to extract, compute, estimate or forecast from the state. Which types a model answers is model-specific; unsupported types are rejected with 400.
+
+
+## Supported Types
+
+### `components.ExtractionDateField`
+
+```python
+value: components.ExtractionDateField = /* values here */
+```
+
+### `components.ExtractionDatetimeField`
+
+```python
+value: components.ExtractionDatetimeField = /* values here */
+```
+
+### `components.ExtractionDurationField`
+
+```python
+value: components.ExtractionDurationField = /* values here */
+```
+
+### `components.ExtractionEstimateField`
+
+```python
+value: components.ExtractionEstimateField = /* values here */
+```
+
+### `components.ExtractionForecastField`
+
+```python
+value: components.ExtractionForecastField = /* values here */
+```
+
+### `components.ExtractionListField`
+
+```python
+value: components.ExtractionListField = /* values here */
+```
+
+### `components.ExtractionNumberField`
+
+```python
+value: components.ExtractionNumberField = /* values here */
+```
+
+### `components.ExtractionTextField`
+
+```python
+value: components.ExtractionTextField = /* values here */
+```
+
+### `components.ExtractionTimeField`
+
+```python
+value: components.ExtractionTimeField = /* values here */
+```
+
diff --git a/docs/components/interval.mdx b/docs/components/interval.mdx
new file mode 100644
index 00000000..cca73936
--- /dev/null
+++ b/docs/components/interval.mdx
@@ -0,0 +1,26 @@
+---
+title: "Interval"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import Interval
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: Interval = "step"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"step"`
+- `"minute"`
+- `"hour"`
+- `"day"`
+- `"week"`
+- `"month"`
+- `"quarter"`
+- `"year"`
diff --git a/docs/components/items.mdx b/docs/components/items.mdx
new file mode 100644
index 00000000..5949fbaa
--- /dev/null
+++ b/docs/components/items.mdx
@@ -0,0 +1,21 @@
+---
+title: "Items"
+---
+
+## Example Usage
+
+```python
+from openrouter.components import Items
+
+# Open enum: unrecognized values are captured as UnrecognizedStr
+value: Items = "text"
+```
+
+
+## Values
+
+This is an open enum. Unrecognized values will not fail type checks.
+
+- `"text"`
+- `"number"`
+- `"date"`
diff --git a/docs/docs.json b/docs/docs.json
index e4149f6e..d7e14135 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -25,6 +25,7 @@
"sdks/embeddings/README",
"sdks/endpoints/README",
"sdks/externalusers/README",
+ "sdks/extractions/README",
"sdks/files/README",
"sdks/generations/README",
"sdks/guardrails/README",
diff --git a/docs/operations/createapialphaextractionsglobals.mdx b/docs/operations/createapialphaextractionsglobals.mdx
new file mode 100644
index 00000000..2ea0c677
--- /dev/null
+++ b/docs/operations/createapialphaextractionsglobals.mdx
@@ -0,0 +1,11 @@
+---
+title: "CreateAPIAlphaExtractionsGlobals"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `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.
|
\ No newline at end of file
diff --git a/docs/operations/createapialphaextractionsrequest.mdx b/docs/operations/createapialphaextractionsrequest.mdx
new file mode 100644
index 00000000..eebccfea
--- /dev/null
+++ b/docs/operations/createapialphaextractionsrequest.mdx
@@ -0,0 +1,12 @@
+---
+title: "CreateAPIAlphaExtractionsRequest"
+---
+
+## Fields
+
+| Field | Type | Required | Description |
+| ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `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.
|
+| `extractions_request` | [components.ExtractionsRequest](../components/extractionsrequest.mdx) | ✔️ | N/A |
\ No newline at end of file
diff --git a/docs/sdks/extractions/README.mdx b/docs/sdks/extractions/README.mdx
new file mode 100644
index 00000000..d2368a31
--- /dev/null
+++ b/docs/sdks/extractions/README.mdx
@@ -0,0 +1,101 @@
+---
+title: "Alpha.Extractions"
+description: "Alpha feature endpoints for Extractions requests"
+---
+
+## Overview
+
+Alpha feature endpoints for Extractions requests
+
+### Available Operations
+
+* [create](#create) - Submit an Extractions request
+
+## create
+
+Extracts, computes, estimates or forecasts typed fields from a state string and image assets using an extraction-style System One model. Alpha: the shape is not stable.
+
+### Example Usage
+
+```python
+from openrouter import OpenRouter
+import os
+
+
+with OpenRouter(
+ http_referer="",
+ x_open_router_title="",
+ x_open_router_categories="",
+ api_key=os.getenv("OPENROUTER_API_KEY", ""),
+) as open_router:
+
+ res = open_router.alpha.extractions.create(fields={
+ "contacts": {
+ "items": "text",
+ "type": "list",
+ },
+ "days_to_pay": {
+ "max": 120.0,
+ "min": 0.0,
+ "step": 1.0,
+ "type": "estimate",
+ },
+ "due_date": {
+ "instructions": "Issue date plus the net payment days",
+ "type": "date",
+ },
+ "invoice_number": {
+ "type": "text",
+ },
+ "total": {
+ "decimals": 2,
+ "type": "number",
+ "unit": "USD",
+ },
+ }, model="cloudflare/clairic", state="Invoice INV-2291 issued 2026-09-02, net 30. Contacts: Dana Ruiz, Priya Shah. Total $1080.", reference_date="2026-10-28")
+
+ # Handle response
+ print(res)
+
+```
+
+### Parameters
+
+| Parameter | Type | Required | Description | Example |
+| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `fields` | Dict[str, [components.Fields](../../components/fields.mdx)] | ✔️ | Map of field name to typed field spec. | |
+| `model` | *str* | ✔️ | N/A | |
+| `state` | *str* | ✔️ | The text to read from. May be empty only when the request carries image assets. | |
+| `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.
| |
+| `assets` | Dict[str, [components.DecisionsImageAsset](../../components/decisionsimageasset.mdx)] | ➖ | Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text. | |
+| `provider` | [OptionalNullable[components.ProviderPreferences]](../../components/providerpreferences.mdx) | ➖ | N/A | \{
"allow_fallbacks": true
} |
+| `reference_date` | *Optional[str]* | ➖ | ISO date that anchors dates written without a year. | |
+| `session_id` | *Optional[str]* | ➖ | A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters. | session-1234 |
+| `trace` | [Optional[components.TraceConfig]](../../components/traceconfig.mdx) | ➖ | Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations. | \{
"trace_id": "trace-abc123",
"trace_name": "my-app-trace"
} |
+| `user` | *Optional[str]* | ➖ | N/A | |
+| `retries` | [Optional[utils.RetryConfig]](../../models/utils/retryconfig.mdx) | ➖ | Configuration to override the default retry behavior of the client. | |
+| `server_url` | *Optional[str]* | ➖ | An optional server URL to use. | http://localhost:8080 |
+
+### Response
+
+**[components.ExtractionsResponse](../../components/extractionsresponse.mdx)**
+
+### Errors
+
+| Error Type | Status Code | Content Type |
+| -------------------------------------- | -------------------------------------- | -------------------------------------- |
+| errors.BadRequestResponseError | 400 | application/json |
+| errors.UnauthorizedResponseError | 401 | application/json |
+| errors.PaymentRequiredResponseError | 402 | application/json |
+| errors.ForbiddenResponseError | 403 | application/json |
+| errors.NotFoundResponseError | 404 | application/json |
+| errors.PayloadTooLargeResponseError | 413 | application/json |
+| errors.TooManyRequestsResponseError | 429 | application/json |
+| errors.InternalServerResponseError | 500 | application/json |
+| errors.BadGatewayResponseError | 502 | application/json |
+| errors.ServiceUnavailableResponseError | 503 | application/json |
+| errors.EdgeNetworkTimeoutResponseError | 524 | application/json |
+| errors.ProviderOverloadedResponseError | 529 | application/json |
+| errors.OpenRouterDefaultError | 4XX, 5XX | \*/\* |
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 8b292d5a..20718a51 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "openrouter"
-version = "1.3.97"
+version = "1.3.98"
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 7efe4512..0fe77311 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.97"
+__version__: str = "1.3.98"
__openapi_doc_version__: str = "1.0.0"
__gen_version__: str = "2.950.13"
-__user_agent__: str = "speakeasy-sdk/python 1.3.97 2.950.13 1.0.0 openrouter"
+__user_agent__: str = "speakeasy-sdk/python 1.3.98 2.950.13 1.0.0 openrouter"
try:
if __package__ is not None:
diff --git a/src/openrouter/alpha.py b/src/openrouter/alpha.py
index ae90121f..f512ec0a 100644
--- a/src/openrouter/alpha.py
+++ b/src/openrouter/alpha.py
@@ -3,12 +3,15 @@
from .basesdk import BaseSDK
from .sdkconfiguration import SDKConfiguration
from openrouter.decisions import Decisions
+from openrouter.extractions import Extractions
from typing import Optional
class Alpha(BaseSDK):
decisions: Decisions
r"""Alpha feature endpoints for Decisions requests"""
+ extractions: Extractions
+ r"""Alpha feature endpoints for Extractions requests"""
def __init__(
self, sdk_config: SDKConfiguration, parent_ref: Optional[object] = None
@@ -19,3 +22,6 @@ def __init__(
def _init_sdks(self):
self.decisions = Decisions(self.sdk_configuration, parent_ref=self.parent_ref)
+ self.extractions = Extractions(
+ self.sdk_configuration, parent_ref=self.parent_ref
+ )
diff --git a/src/openrouter/components/__init__.py b/src/openrouter/components/__init__.py
index 5dc45660..9d5f5695 100644
--- a/src/openrouter/components/__init__.py
+++ b/src/openrouter/components/__init__.py
@@ -1686,13 +1686,13 @@
StateTypedDict,
)
from .decisionsresponse import (
- Answers,
- AnswersTypedDict,
DecisionsResponse,
+ DecisionsResponseAnswers,
+ DecisionsResponseAnswersTypedDict,
DecisionsResponseTypedDict,
DecisionsResponseUsage,
DecisionsResponseUsageTypedDict,
- UnknownAnswers,
+ UnknownDecisionsResponseAnswers,
)
from .decisionsscoreanswer import (
DecisionsScoreAnswer,
@@ -1808,6 +1808,185 @@
ExternalUserResponse,
ExternalUserResponseTypedDict,
)
+ from .extractiondateanswer import (
+ ExtractionDateAnswer,
+ ExtractionDateAnswerSource,
+ ExtractionDateAnswerType,
+ ExtractionDateAnswerTypedDict,
+ )
+ from .extractiondatefield import (
+ ExtractionDateField,
+ ExtractionDateFieldType,
+ ExtractionDateFieldTypedDict,
+ )
+ from .extractiondatetimeanswer import (
+ ExtractionDatetimeAnswer,
+ ExtractionDatetimeAnswerSource,
+ ExtractionDatetimeAnswerType,
+ ExtractionDatetimeAnswerTypedDict,
+ )
+ from .extractiondatetimefield import (
+ ExtractionDatetimeField,
+ ExtractionDatetimeFieldType,
+ ExtractionDatetimeFieldTypedDict,
+ )
+ from .extractiondurationanswer import (
+ ExtractionDurationAnswer,
+ ExtractionDurationAnswerSource,
+ ExtractionDurationAnswerType,
+ ExtractionDurationAnswerTypedDict,
+ )
+ from .extractiondurationfield import (
+ ExtractionDurationField,
+ ExtractionDurationFieldType,
+ ExtractionDurationFieldTypedDict,
+ )
+ from .extractionestimateanswer import (
+ ExtractionEstimateAnswer,
+ ExtractionEstimateAnswerGuess,
+ ExtractionEstimateAnswerGuessTypedDict,
+ ExtractionEstimateAnswerMean,
+ ExtractionEstimateAnswerMeanTypedDict,
+ ExtractionEstimateAnswerMedian,
+ ExtractionEstimateAnswerMedianTypedDict,
+ ExtractionEstimateAnswerP10,
+ ExtractionEstimateAnswerP10TypedDict,
+ ExtractionEstimateAnswerP90,
+ ExtractionEstimateAnswerP90TypedDict,
+ ExtractionEstimateAnswerQuantile,
+ ExtractionEstimateAnswerQuantileTypedDict,
+ ExtractionEstimateAnswerSource,
+ ExtractionEstimateAnswerType,
+ ExtractionEstimateAnswerTypedDict,
+ ExtractionEstimateAnswerValue,
+ ExtractionEstimateAnswerValueTypedDict,
+ )
+ from .extractionestimatefield import (
+ ExtractionEstimateField,
+ ExtractionEstimateFieldMax,
+ ExtractionEstimateFieldMaxTypedDict,
+ ExtractionEstimateFieldMin,
+ ExtractionEstimateFieldMinTypedDict,
+ ExtractionEstimateFieldScale,
+ ExtractionEstimateFieldStepMonth,
+ ExtractionEstimateFieldStepUnion,
+ ExtractionEstimateFieldStepUnionTypedDict,
+ ExtractionEstimateFieldStepYear,
+ ExtractionEstimateFieldType,
+ ExtractionEstimateFieldTypedDict,
+ )
+ from .extractionforecastanswer import (
+ ExtractionForecastAnswer,
+ ExtractionForecastAnswerGuess,
+ ExtractionForecastAnswerGuessTypedDict,
+ ExtractionForecastAnswerMean,
+ ExtractionForecastAnswerMeanTypedDict,
+ ExtractionForecastAnswerMedian,
+ ExtractionForecastAnswerMedianTypedDict,
+ ExtractionForecastAnswerP10,
+ ExtractionForecastAnswerP10TypedDict,
+ ExtractionForecastAnswerP90,
+ ExtractionForecastAnswerP90TypedDict,
+ ExtractionForecastAnswerSource,
+ ExtractionForecastAnswerType,
+ ExtractionForecastAnswerTypedDict,
+ ExtractionForecastAnswerValue,
+ ExtractionForecastAnswerValueTypedDict,
+ )
+ from .extractionforecastfield import (
+ ExtractionForecastField,
+ ExtractionForecastFieldMax,
+ ExtractionForecastFieldMaxTypedDict,
+ ExtractionForecastFieldMin,
+ ExtractionForecastFieldMinTypedDict,
+ ExtractionForecastFieldScale,
+ ExtractionForecastFieldStepMonth,
+ ExtractionForecastFieldStepUnion,
+ ExtractionForecastFieldStepUnionTypedDict,
+ ExtractionForecastFieldStepYear,
+ ExtractionForecastFieldType,
+ ExtractionForecastFieldTypedDict,
+ Interval,
+ )
+ from .extractionforecaststep import (
+ ExtractionForecastStep,
+ ExtractionForecastStepMean,
+ ExtractionForecastStepMeanTypedDict,
+ ExtractionForecastStepMedian,
+ ExtractionForecastStepMedianTypedDict,
+ ExtractionForecastStepP10,
+ ExtractionForecastStepP10TypedDict,
+ ExtractionForecastStepP90,
+ ExtractionForecastStepP90TypedDict,
+ ExtractionForecastStepQuantile,
+ ExtractionForecastStepQuantileTypedDict,
+ ExtractionForecastStepTypedDict,
+ ExtractionForecastStepValue,
+ ExtractionForecastStepValueTypedDict,
+ )
+ from .extractionlistanswer import (
+ ExtractionListAnswer,
+ ExtractionListAnswerGuess,
+ ExtractionListAnswerGuessTypedDict,
+ ExtractionListAnswerSource,
+ ExtractionListAnswerType,
+ ExtractionListAnswerTypedDict,
+ ExtractionListAnswerValue,
+ ExtractionListAnswerValueTypedDict,
+ )
+ from .extractionlistfield import (
+ ExtractionListField,
+ ExtractionListFieldType,
+ ExtractionListFieldTypedDict,
+ Items,
+ )
+ from .extractionnumberanswer import (
+ ExtractionNumberAnswer,
+ ExtractionNumberAnswerSource,
+ ExtractionNumberAnswerType,
+ ExtractionNumberAnswerTypedDict,
+ )
+ from .extractionnumberfield import (
+ ExtractionNumberField,
+ ExtractionNumberFieldType,
+ ExtractionNumberFieldTypedDict,
+ )
+ from .extractionsrequest import (
+ ExtractionsRequest,
+ ExtractionsRequestTypedDict,
+ Fields,
+ FieldsTypedDict,
+ )
+ from .extractionsresponse import (
+ ExtractionsResponse,
+ ExtractionsResponseAnswers,
+ ExtractionsResponseAnswersTypedDict,
+ ExtractionsResponseTypedDict,
+ UnknownExtractionsResponseAnswers,
+ )
+ from .extractionsusage import ExtractionsUsage, ExtractionsUsageTypedDict
+ from .extractiontextanswer import (
+ ExtractionTextAnswer,
+ ExtractionTextAnswerSource,
+ ExtractionTextAnswerType,
+ ExtractionTextAnswerTypedDict,
+ )
+ from .extractiontextfield import (
+ ExtractionTextField,
+ ExtractionTextFieldType,
+ ExtractionTextFieldTypedDict,
+ )
+ from .extractiontimeanswer import (
+ ExtractionTimeAnswer,
+ ExtractionTimeAnswerSource,
+ ExtractionTimeAnswerType,
+ ExtractionTimeAnswerTypedDict,
+ )
+ from .extractiontimefield import (
+ ExtractionTimeField,
+ ExtractionTimeFieldType,
+ ExtractionTimeFieldTypedDict,
+ )
from .failabletoolcallstatus import FailableToolCallStatus
from .filecitation import FileCitation, FileCitationType, FileCitationTypedDict
from .filedeleteresponse import (
@@ -4632,8 +4811,6 @@
"AnnotationURLCitationTypedDict",
"AnnotationWebSearchCitation",
"AnnotationWebSearchCitationTypedDict",
- "Answers",
- "AnswersTypedDict",
"AnthropicAdvisorMessageUsageIteration",
"AnthropicAdvisorMessageUsageIterationType",
"AnthropicAdvisorMessageUsageIterationTypedDict",
@@ -5677,6 +5854,8 @@
"DecisionsRequest",
"DecisionsRequestTypedDict",
"DecisionsResponse",
+ "DecisionsResponseAnswers",
+ "DecisionsResponseAnswersTypedDict",
"DecisionsResponseTypedDict",
"DecisionsResponseUsage",
"DecisionsResponseUsageTypedDict",
@@ -5777,12 +5956,147 @@
"ExternalUserResponse",
"ExternalUserResponseTypedDict",
"ExternalUserTypedDict",
+ "ExtractionDateAnswer",
+ "ExtractionDateAnswerSource",
+ "ExtractionDateAnswerType",
+ "ExtractionDateAnswerTypedDict",
+ "ExtractionDateField",
+ "ExtractionDateFieldType",
+ "ExtractionDateFieldTypedDict",
+ "ExtractionDatetimeAnswer",
+ "ExtractionDatetimeAnswerSource",
+ "ExtractionDatetimeAnswerType",
+ "ExtractionDatetimeAnswerTypedDict",
+ "ExtractionDatetimeField",
+ "ExtractionDatetimeFieldType",
+ "ExtractionDatetimeFieldTypedDict",
+ "ExtractionDurationAnswer",
+ "ExtractionDurationAnswerSource",
+ "ExtractionDurationAnswerType",
+ "ExtractionDurationAnswerTypedDict",
+ "ExtractionDurationField",
+ "ExtractionDurationFieldType",
+ "ExtractionDurationFieldTypedDict",
+ "ExtractionEstimateAnswer",
+ "ExtractionEstimateAnswerGuess",
+ "ExtractionEstimateAnswerGuessTypedDict",
+ "ExtractionEstimateAnswerMean",
+ "ExtractionEstimateAnswerMeanTypedDict",
+ "ExtractionEstimateAnswerMedian",
+ "ExtractionEstimateAnswerMedianTypedDict",
+ "ExtractionEstimateAnswerP10",
+ "ExtractionEstimateAnswerP10TypedDict",
+ "ExtractionEstimateAnswerP90",
+ "ExtractionEstimateAnswerP90TypedDict",
+ "ExtractionEstimateAnswerQuantile",
+ "ExtractionEstimateAnswerQuantileTypedDict",
+ "ExtractionEstimateAnswerSource",
+ "ExtractionEstimateAnswerType",
+ "ExtractionEstimateAnswerTypedDict",
+ "ExtractionEstimateAnswerValue",
+ "ExtractionEstimateAnswerValueTypedDict",
+ "ExtractionEstimateField",
+ "ExtractionEstimateFieldMax",
+ "ExtractionEstimateFieldMaxTypedDict",
+ "ExtractionEstimateFieldMin",
+ "ExtractionEstimateFieldMinTypedDict",
+ "ExtractionEstimateFieldScale",
+ "ExtractionEstimateFieldStepMonth",
+ "ExtractionEstimateFieldStepUnion",
+ "ExtractionEstimateFieldStepUnionTypedDict",
+ "ExtractionEstimateFieldStepYear",
+ "ExtractionEstimateFieldType",
+ "ExtractionEstimateFieldTypedDict",
+ "ExtractionForecastAnswer",
+ "ExtractionForecastAnswerGuess",
+ "ExtractionForecastAnswerGuessTypedDict",
+ "ExtractionForecastAnswerMean",
+ "ExtractionForecastAnswerMeanTypedDict",
+ "ExtractionForecastAnswerMedian",
+ "ExtractionForecastAnswerMedianTypedDict",
+ "ExtractionForecastAnswerP10",
+ "ExtractionForecastAnswerP10TypedDict",
+ "ExtractionForecastAnswerP90",
+ "ExtractionForecastAnswerP90TypedDict",
+ "ExtractionForecastAnswerSource",
+ "ExtractionForecastAnswerType",
+ "ExtractionForecastAnswerTypedDict",
+ "ExtractionForecastAnswerValue",
+ "ExtractionForecastAnswerValueTypedDict",
+ "ExtractionForecastField",
+ "ExtractionForecastFieldMax",
+ "ExtractionForecastFieldMaxTypedDict",
+ "ExtractionForecastFieldMin",
+ "ExtractionForecastFieldMinTypedDict",
+ "ExtractionForecastFieldScale",
+ "ExtractionForecastFieldStepMonth",
+ "ExtractionForecastFieldStepUnion",
+ "ExtractionForecastFieldStepUnionTypedDict",
+ "ExtractionForecastFieldStepYear",
+ "ExtractionForecastFieldType",
+ "ExtractionForecastFieldTypedDict",
+ "ExtractionForecastStep",
+ "ExtractionForecastStepMean",
+ "ExtractionForecastStepMeanTypedDict",
+ "ExtractionForecastStepMedian",
+ "ExtractionForecastStepMedianTypedDict",
+ "ExtractionForecastStepP10",
+ "ExtractionForecastStepP10TypedDict",
+ "ExtractionForecastStepP90",
+ "ExtractionForecastStepP90TypedDict",
+ "ExtractionForecastStepQuantile",
+ "ExtractionForecastStepQuantileTypedDict",
+ "ExtractionForecastStepTypedDict",
+ "ExtractionForecastStepValue",
+ "ExtractionForecastStepValueTypedDict",
+ "ExtractionListAnswer",
+ "ExtractionListAnswerGuess",
+ "ExtractionListAnswerGuessTypedDict",
+ "ExtractionListAnswerSource",
+ "ExtractionListAnswerType",
+ "ExtractionListAnswerTypedDict",
+ "ExtractionListAnswerValue",
+ "ExtractionListAnswerValueTypedDict",
+ "ExtractionListField",
+ "ExtractionListFieldType",
+ "ExtractionListFieldTypedDict",
+ "ExtractionNumberAnswer",
+ "ExtractionNumberAnswerSource",
+ "ExtractionNumberAnswerType",
+ "ExtractionNumberAnswerTypedDict",
+ "ExtractionNumberField",
+ "ExtractionNumberFieldType",
+ "ExtractionNumberFieldTypedDict",
+ "ExtractionTextAnswer",
+ "ExtractionTextAnswerSource",
+ "ExtractionTextAnswerType",
+ "ExtractionTextAnswerTypedDict",
+ "ExtractionTextField",
+ "ExtractionTextFieldType",
+ "ExtractionTextFieldTypedDict",
+ "ExtractionTimeAnswer",
+ "ExtractionTimeAnswerSource",
+ "ExtractionTimeAnswerType",
+ "ExtractionTimeAnswerTypedDict",
+ "ExtractionTimeField",
+ "ExtractionTimeFieldType",
+ "ExtractionTimeFieldTypedDict",
+ "ExtractionsRequest",
+ "ExtractionsRequestTypedDict",
+ "ExtractionsResponse",
+ "ExtractionsResponseAnswers",
+ "ExtractionsResponseAnswersTypedDict",
+ "ExtractionsResponseTypedDict",
+ "ExtractionsUsage",
+ "ExtractionsUsageTypedDict",
"FailableToolCallStatus",
"FailedModel",
"FailedModelTypedDict",
"FalseT",
"FalseTTypedDict",
"FieldT",
+ "Fields",
+ "FieldsTypedDict",
"FileCitation",
"FileCitationType",
"FileCitationTypedDict",
@@ -6151,10 +6465,12 @@
"InstructType",
"InternalServerResponseErrorData",
"InternalServerResponseErrorDataTypedDict",
+ "Interval",
"IssuedTokenType",
"ItemReferenceItem",
"ItemReferenceItemType",
"ItemReferenceItemTypedDict",
+ "Items",
"JevRouterPlugin",
"JevRouterPluginID",
"JevRouterPluginTypedDict",
@@ -7624,7 +7940,6 @@
"UnknownAlignmentResponsesRejected",
"UnknownAnnotation",
"UnknownAnnotationContentUnion",
- "UnknownAnswers",
"UnknownAnthropicBashCodeExecutionContent",
"UnknownAnthropicCaller",
"UnknownAnthropicCodeExecutionContent",
@@ -7639,6 +7954,8 @@
"UnknownChatContentItems",
"UnknownContentPartAddedEventPart",
"UnknownContentPartDoneEventPart",
+ "UnknownDecisionsResponseAnswers",
+ "UnknownExtractionsResponseAnswers",
"UnknownFileDeleteResponse",
"UnknownFileListResponse",
"UnknownFileResponse",
@@ -9046,13 +9363,13 @@
"QuestionsTypedDict": ".decisionsrequest",
"State": ".decisionsrequest",
"StateTypedDict": ".decisionsrequest",
- "Answers": ".decisionsresponse",
- "AnswersTypedDict": ".decisionsresponse",
"DecisionsResponse": ".decisionsresponse",
+ "DecisionsResponseAnswers": ".decisionsresponse",
+ "DecisionsResponseAnswersTypedDict": ".decisionsresponse",
"DecisionsResponseTypedDict": ".decisionsresponse",
"DecisionsResponseUsage": ".decisionsresponse",
"DecisionsResponseUsageTypedDict": ".decisionsresponse",
- "UnknownAnswers": ".decisionsresponse",
+ "UnknownDecisionsResponseAnswers": ".decisionsresponse",
"DecisionsScoreAnswer": ".decisionsscoreanswer",
"DecisionsScoreAnswerType": ".decisionsscoreanswer",
"DecisionsScoreAnswerTypedDict": ".decisionsscoreanswer",
@@ -9137,6 +9454,144 @@
"ExternalUserTypedDict": ".externaluser",
"ExternalUserResponse": ".externaluserresponse",
"ExternalUserResponseTypedDict": ".externaluserresponse",
+ "ExtractionDateAnswer": ".extractiondateanswer",
+ "ExtractionDateAnswerSource": ".extractiondateanswer",
+ "ExtractionDateAnswerType": ".extractiondateanswer",
+ "ExtractionDateAnswerTypedDict": ".extractiondateanswer",
+ "ExtractionDateField": ".extractiondatefield",
+ "ExtractionDateFieldType": ".extractiondatefield",
+ "ExtractionDateFieldTypedDict": ".extractiondatefield",
+ "ExtractionDatetimeAnswer": ".extractiondatetimeanswer",
+ "ExtractionDatetimeAnswerSource": ".extractiondatetimeanswer",
+ "ExtractionDatetimeAnswerType": ".extractiondatetimeanswer",
+ "ExtractionDatetimeAnswerTypedDict": ".extractiondatetimeanswer",
+ "ExtractionDatetimeField": ".extractiondatetimefield",
+ "ExtractionDatetimeFieldType": ".extractiondatetimefield",
+ "ExtractionDatetimeFieldTypedDict": ".extractiondatetimefield",
+ "ExtractionDurationAnswer": ".extractiondurationanswer",
+ "ExtractionDurationAnswerSource": ".extractiondurationanswer",
+ "ExtractionDurationAnswerType": ".extractiondurationanswer",
+ "ExtractionDurationAnswerTypedDict": ".extractiondurationanswer",
+ "ExtractionDurationField": ".extractiondurationfield",
+ "ExtractionDurationFieldType": ".extractiondurationfield",
+ "ExtractionDurationFieldTypedDict": ".extractiondurationfield",
+ "ExtractionEstimateAnswer": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerGuess": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerGuessTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerMean": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerMeanTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerMedian": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerMedianTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerP10": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerP10TypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerP90": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerP90TypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerQuantile": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerQuantileTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerSource": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerType": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerValue": ".extractionestimateanswer",
+ "ExtractionEstimateAnswerValueTypedDict": ".extractionestimateanswer",
+ "ExtractionEstimateField": ".extractionestimatefield",
+ "ExtractionEstimateFieldMax": ".extractionestimatefield",
+ "ExtractionEstimateFieldMaxTypedDict": ".extractionestimatefield",
+ "ExtractionEstimateFieldMin": ".extractionestimatefield",
+ "ExtractionEstimateFieldMinTypedDict": ".extractionestimatefield",
+ "ExtractionEstimateFieldScale": ".extractionestimatefield",
+ "ExtractionEstimateFieldStepMonth": ".extractionestimatefield",
+ "ExtractionEstimateFieldStepUnion": ".extractionestimatefield",
+ "ExtractionEstimateFieldStepUnionTypedDict": ".extractionestimatefield",
+ "ExtractionEstimateFieldStepYear": ".extractionestimatefield",
+ "ExtractionEstimateFieldType": ".extractionestimatefield",
+ "ExtractionEstimateFieldTypedDict": ".extractionestimatefield",
+ "ExtractionForecastAnswer": ".extractionforecastanswer",
+ "ExtractionForecastAnswerGuess": ".extractionforecastanswer",
+ "ExtractionForecastAnswerGuessTypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerMean": ".extractionforecastanswer",
+ "ExtractionForecastAnswerMeanTypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerMedian": ".extractionforecastanswer",
+ "ExtractionForecastAnswerMedianTypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerP10": ".extractionforecastanswer",
+ "ExtractionForecastAnswerP10TypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerP90": ".extractionforecastanswer",
+ "ExtractionForecastAnswerP90TypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerSource": ".extractionforecastanswer",
+ "ExtractionForecastAnswerType": ".extractionforecastanswer",
+ "ExtractionForecastAnswerTypedDict": ".extractionforecastanswer",
+ "ExtractionForecastAnswerValue": ".extractionforecastanswer",
+ "ExtractionForecastAnswerValueTypedDict": ".extractionforecastanswer",
+ "ExtractionForecastField": ".extractionforecastfield",
+ "ExtractionForecastFieldMax": ".extractionforecastfield",
+ "ExtractionForecastFieldMaxTypedDict": ".extractionforecastfield",
+ "ExtractionForecastFieldMin": ".extractionforecastfield",
+ "ExtractionForecastFieldMinTypedDict": ".extractionforecastfield",
+ "ExtractionForecastFieldScale": ".extractionforecastfield",
+ "ExtractionForecastFieldStepMonth": ".extractionforecastfield",
+ "ExtractionForecastFieldStepUnion": ".extractionforecastfield",
+ "ExtractionForecastFieldStepUnionTypedDict": ".extractionforecastfield",
+ "ExtractionForecastFieldStepYear": ".extractionforecastfield",
+ "ExtractionForecastFieldType": ".extractionforecastfield",
+ "ExtractionForecastFieldTypedDict": ".extractionforecastfield",
+ "Interval": ".extractionforecastfield",
+ "ExtractionForecastStep": ".extractionforecaststep",
+ "ExtractionForecastStepMean": ".extractionforecaststep",
+ "ExtractionForecastStepMeanTypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepMedian": ".extractionforecaststep",
+ "ExtractionForecastStepMedianTypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepP10": ".extractionforecaststep",
+ "ExtractionForecastStepP10TypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepP90": ".extractionforecaststep",
+ "ExtractionForecastStepP90TypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepQuantile": ".extractionforecaststep",
+ "ExtractionForecastStepQuantileTypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepTypedDict": ".extractionforecaststep",
+ "ExtractionForecastStepValue": ".extractionforecaststep",
+ "ExtractionForecastStepValueTypedDict": ".extractionforecaststep",
+ "ExtractionListAnswer": ".extractionlistanswer",
+ "ExtractionListAnswerGuess": ".extractionlistanswer",
+ "ExtractionListAnswerGuessTypedDict": ".extractionlistanswer",
+ "ExtractionListAnswerSource": ".extractionlistanswer",
+ "ExtractionListAnswerType": ".extractionlistanswer",
+ "ExtractionListAnswerTypedDict": ".extractionlistanswer",
+ "ExtractionListAnswerValue": ".extractionlistanswer",
+ "ExtractionListAnswerValueTypedDict": ".extractionlistanswer",
+ "ExtractionListField": ".extractionlistfield",
+ "ExtractionListFieldType": ".extractionlistfield",
+ "ExtractionListFieldTypedDict": ".extractionlistfield",
+ "Items": ".extractionlistfield",
+ "ExtractionNumberAnswer": ".extractionnumberanswer",
+ "ExtractionNumberAnswerSource": ".extractionnumberanswer",
+ "ExtractionNumberAnswerType": ".extractionnumberanswer",
+ "ExtractionNumberAnswerTypedDict": ".extractionnumberanswer",
+ "ExtractionNumberField": ".extractionnumberfield",
+ "ExtractionNumberFieldType": ".extractionnumberfield",
+ "ExtractionNumberFieldTypedDict": ".extractionnumberfield",
+ "ExtractionsRequest": ".extractionsrequest",
+ "ExtractionsRequestTypedDict": ".extractionsrequest",
+ "Fields": ".extractionsrequest",
+ "FieldsTypedDict": ".extractionsrequest",
+ "ExtractionsResponse": ".extractionsresponse",
+ "ExtractionsResponseAnswers": ".extractionsresponse",
+ "ExtractionsResponseAnswersTypedDict": ".extractionsresponse",
+ "ExtractionsResponseTypedDict": ".extractionsresponse",
+ "UnknownExtractionsResponseAnswers": ".extractionsresponse",
+ "ExtractionsUsage": ".extractionsusage",
+ "ExtractionsUsageTypedDict": ".extractionsusage",
+ "ExtractionTextAnswer": ".extractiontextanswer",
+ "ExtractionTextAnswerSource": ".extractiontextanswer",
+ "ExtractionTextAnswerType": ".extractiontextanswer",
+ "ExtractionTextAnswerTypedDict": ".extractiontextanswer",
+ "ExtractionTextField": ".extractiontextfield",
+ "ExtractionTextFieldType": ".extractiontextfield",
+ "ExtractionTextFieldTypedDict": ".extractiontextfield",
+ "ExtractionTimeAnswer": ".extractiontimeanswer",
+ "ExtractionTimeAnswerSource": ".extractiontimeanswer",
+ "ExtractionTimeAnswerType": ".extractiontimeanswer",
+ "ExtractionTimeAnswerTypedDict": ".extractiontimeanswer",
+ "ExtractionTimeField": ".extractiontimefield",
+ "ExtractionTimeFieldType": ".extractiontimefield",
+ "ExtractionTimeFieldTypedDict": ".extractiontimefield",
"FailableToolCallStatus": ".failabletoolcallstatus",
"FileCitation": ".filecitation",
"FileCitationType": ".filecitation",
diff --git a/src/openrouter/components/decisionsresponse.py b/src/openrouter/components/decisionsresponse.py
index 687789c6..bf57dc6e 100644
--- a/src/openrouter/components/decisionsresponse.py
+++ b/src/openrouter/components/decisionsresponse.py
@@ -14,8 +14,8 @@
from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
-AnswersTypedDict = TypeAliasType(
- "AnswersTypedDict",
+DecisionsResponseAnswersTypedDict = TypeAliasType(
+ "DecisionsResponseAnswersTypedDict",
Union[
DecisionsNoulAnswerTypedDict,
DecisionsBoxAnswerTypedDict,
@@ -26,8 +26,8 @@
r"""A Decisions answer using a boolean, choice, score, or image bounding-box evaluation."""
-class UnknownAnswers(BaseModel):
- r"""A Answers variant the SDK doesn't recognize. Preserves the raw payload."""
+class UnknownDecisionsResponseAnswers(BaseModel):
+ r"""A DecisionsResponseAnswers variant the SDK doesn't recognize. Preserves the raw payload."""
type: Literal["UNKNOWN"] = "UNKNOWN"
raw: Any
@@ -36,7 +36,7 @@ class UnknownAnswers(BaseModel):
model_config = ConfigDict(frozen=True)
-_ANSWERS_VARIANTS: dict[str, Any] = {
+_DECISIONS_RESPONSE_ANSWERS_VARIANTS: dict[str, Any] = {
"box": DecisionsBoxAnswer,
"choice": DecisionsChoiceAnswer,
"noul": DecisionsNoulAnswer,
@@ -44,21 +44,21 @@ class UnknownAnswers(BaseModel):
}
-Answers = Annotated[
+DecisionsResponseAnswers = Annotated[
Union[
DecisionsBoxAnswer,
DecisionsChoiceAnswer,
DecisionsNoulAnswer,
DecisionsScoreAnswer,
- UnknownAnswers,
+ UnknownDecisionsResponseAnswers,
],
BeforeValidator(
partial(
parse_open_union,
disc_key="type",
- variants=_ANSWERS_VARIANTS,
- unknown_cls=UnknownAnswers,
- union_name="Answers",
+ variants=_DECISIONS_RESPONSE_ANSWERS_VARIANTS,
+ unknown_cls=UnknownDecisionsResponseAnswers,
+ union_name="DecisionsResponseAnswers",
)
),
]
@@ -96,7 +96,7 @@ def serialize_model(self, handler):
class DecisionsResponseTypedDict(TypedDict):
- answers: Dict[str, AnswersTypedDict]
+ answers: Dict[str, DecisionsResponseAnswersTypedDict]
model: str
usage: DecisionsResponseUsageTypedDict
id: NotRequired[str]
@@ -104,7 +104,7 @@ class DecisionsResponseTypedDict(TypedDict):
class DecisionsResponse(BaseModel):
- answers: Dict[str, Answers]
+ answers: Dict[str, DecisionsResponseAnswers]
model: str
diff --git a/src/openrouter/components/extractiondateanswer.py b/src/openrouter/components/extractiondateanswer.py
new file mode 100644
index 00000000..7fca5088
--- /dev/null
+++ b/src/openrouter/components/extractiondateanswer.py
@@ -0,0 +1,86 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDateAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionDateAnswerType = Literal["date",]
+
+
+class ExtractionDateAnswerTypedDict(TypedDict):
+ type: ExtractionDateAnswerType
+ value: Nullable[str]
+ confidence: NotRequired[float]
+ guess: NotRequired[str]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionDateAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionDateAnswer(BaseModel):
+ type: ExtractionDateAnswerType
+
+ value: Nullable[str]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[str] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionDateAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "span", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractiondatefield.py b/src/openrouter/components/extractiondatefield.py
new file mode 100644
index 00000000..ecb2d421
--- /dev/null
+++ b/src/openrouter/components/extractiondatefield.py
@@ -0,0 +1,44 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDateFieldType = Literal["date",]
+
+
+class ExtractionDateFieldTypedDict(TypedDict):
+ type: ExtractionDateFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+
+class ExtractionDateField(BaseModel):
+ type: ExtractionDateFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["instructions", "null_threshold"])
+ 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/extractiondatetimeanswer.py b/src/openrouter/components/extractiondatetimeanswer.py
new file mode 100644
index 00000000..6de327cc
--- /dev/null
+++ b/src/openrouter/components/extractiondatetimeanswer.py
@@ -0,0 +1,86 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDatetimeAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionDatetimeAnswerType = Literal["datetime",]
+
+
+class ExtractionDatetimeAnswerTypedDict(TypedDict):
+ type: ExtractionDatetimeAnswerType
+ value: Nullable[str]
+ confidence: NotRequired[float]
+ guess: NotRequired[str]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionDatetimeAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionDatetimeAnswer(BaseModel):
+ type: ExtractionDatetimeAnswerType
+
+ value: Nullable[str]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[str] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionDatetimeAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "span", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractiondatetimefield.py b/src/openrouter/components/extractiondatetimefield.py
new file mode 100644
index 00000000..7bd5a82d
--- /dev/null
+++ b/src/openrouter/components/extractiondatetimefield.py
@@ -0,0 +1,44 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDatetimeFieldType = Literal["datetime",]
+
+
+class ExtractionDatetimeFieldTypedDict(TypedDict):
+ type: ExtractionDatetimeFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+
+class ExtractionDatetimeField(BaseModel):
+ type: ExtractionDatetimeFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["instructions", "null_threshold"])
+ 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/extractiondurationanswer.py b/src/openrouter/components/extractiondurationanswer.py
new file mode 100644
index 00000000..da48cb14
--- /dev/null
+++ b/src/openrouter/components/extractiondurationanswer.py
@@ -0,0 +1,99 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDurationAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionDurationAnswerType = Literal["duration",]
+
+
+class ExtractionDurationAnswerTypedDict(TypedDict):
+ type: ExtractionDurationAnswerType
+ value: Nullable[float]
+ confidence: NotRequired[float]
+ guess: NotRequired[float]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionDurationAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+ unit: NotRequired[str]
+ r"""The unit `value` is expressed in."""
+
+
+class ExtractionDurationAnswer(BaseModel):
+ type: ExtractionDurationAnswerType
+
+ value: Nullable[float]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[float] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionDurationAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ unit: Optional[str] = None
+ r"""The unit `value` is expressed in."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ [
+ "confidence",
+ "guess",
+ "p_null",
+ "source",
+ "span",
+ "spell_confidence",
+ "unit",
+ ]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractiondurationfield.py b/src/openrouter/components/extractiondurationfield.py
new file mode 100644
index 00000000..9909d58f
--- /dev/null
+++ b/src/openrouter/components/extractiondurationfield.py
@@ -0,0 +1,59 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionDurationFieldType = Literal["duration",]
+
+
+class ExtractionDurationFieldTypedDict(TypedDict):
+ type: ExtractionDurationFieldType
+ decimals: NotRequired[int]
+ r"""Decimal places kept in `value`."""
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ integer: NotRequired[bool]
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+ unit: NotRequired[str]
+ r"""seconds, minutes, hours, days, weeks, months or years."""
+
+
+class ExtractionDurationField(BaseModel):
+ type: ExtractionDurationFieldType
+
+ decimals: Optional[int] = None
+ r"""Decimal places kept in `value`."""
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ integer: Optional[bool] = None
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ unit: Optional[str] = None
+ r"""seconds, minutes, hours, days, weeks, months or years."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["decimals", "instructions", "integer", "null_threshold", "unit"]
+ )
+ 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/extractionestimateanswer.py b/src/openrouter/components/extractionestimateanswer.py
new file mode 100644
index 00000000..49ba18a0
--- /dev/null
+++ b/src/openrouter/components/extractionestimateanswer.py
@@ -0,0 +1,193 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionEstimateAnswerGuessTypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerGuessTypedDict", Union[float, str]
+)
+r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+
+ExtractionEstimateAnswerGuess = TypeAliasType(
+ "ExtractionEstimateAnswerGuess", Union[float, str]
+)
+r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+
+ExtractionEstimateAnswerMeanTypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerMeanTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerMean = TypeAliasType(
+ "ExtractionEstimateAnswerMean", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerMedianTypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerMedianTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerMedian = TypeAliasType(
+ "ExtractionEstimateAnswerMedian", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerP10TypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerP10TypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerP10 = TypeAliasType(
+ "ExtractionEstimateAnswerP10", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerP90TypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerP90TypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerP90 = TypeAliasType(
+ "ExtractionEstimateAnswerP90", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerQuantileTypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerQuantileTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerQuantile = TypeAliasType(
+ "ExtractionEstimateAnswerQuantile", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionEstimateAnswerType = Literal["estimate",]
+
+
+ExtractionEstimateAnswerValueTypedDict = TypeAliasType(
+ "ExtractionEstimateAnswerValueTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateAnswerValue = TypeAliasType(
+ "ExtractionEstimateAnswerValue", Union[float, str]
+)
+
+
+class ExtractionEstimateAnswerTypedDict(TypedDict):
+ type: ExtractionEstimateAnswerType
+ value: Nullable[ExtractionEstimateAnswerValueTypedDict]
+ confidence: NotRequired[float]
+ guess: NotRequired[ExtractionEstimateAnswerGuessTypedDict]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ mean: NotRequired[ExtractionEstimateAnswerMeanTypedDict]
+ median: NotRequired[ExtractionEstimateAnswerMedianTypedDict]
+ p_above: NotRequired[float]
+ r"""Probability mass above `max`."""
+ p_below: NotRequired[float]
+ r"""Probability mass below `min`."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ p10: NotRequired[ExtractionEstimateAnswerP10TypedDict]
+ p90: NotRequired[ExtractionEstimateAnswerP90TypedDict]
+ quantiles: NotRequired[List[ExtractionEstimateAnswerQuantileTypedDict]]
+ r"""99 percentiles, present when the provider is asked for quantiles."""
+ source: NotRequired[ExtractionEstimateAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionEstimateAnswer(BaseModel):
+ type: ExtractionEstimateAnswerType
+
+ value: Nullable[ExtractionEstimateAnswerValue]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[ExtractionEstimateAnswerGuess] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ mean: Optional[ExtractionEstimateAnswerMean] = None
+
+ median: Optional[ExtractionEstimateAnswerMedian] = None
+
+ p_above: Optional[float] = None
+ r"""Probability mass above `max`."""
+
+ p_below: Optional[float] = None
+ r"""Probability mass below `min`."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ p10: Optional[ExtractionEstimateAnswerP10] = None
+
+ p90: Optional[ExtractionEstimateAnswerP90] = None
+
+ quantiles: Optional[List[ExtractionEstimateAnswerQuantile]] = None
+ r"""99 percentiles, present when the provider is asked for quantiles."""
+
+ source: Optional[ExtractionEstimateAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ [
+ "confidence",
+ "guess",
+ "mean",
+ "median",
+ "p_above",
+ "p_below",
+ "p_null",
+ "p10",
+ "p90",
+ "quantiles",
+ "source",
+ "spell_confidence",
+ ]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionestimatefield.py b/src/openrouter/components/extractionestimatefield.py
new file mode 100644
index 00000000..27a5f24e
--- /dev/null
+++ b/src/openrouter/components/extractionestimatefield.py
@@ -0,0 +1,108 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import Literal, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionEstimateFieldMaxTypedDict = TypeAliasType(
+ "ExtractionEstimateFieldMaxTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateFieldMax = TypeAliasType(
+ "ExtractionEstimateFieldMax", Union[float, str]
+)
+
+
+ExtractionEstimateFieldMinTypedDict = TypeAliasType(
+ "ExtractionEstimateFieldMinTypedDict", Union[float, str]
+)
+
+
+ExtractionEstimateFieldMin = TypeAliasType(
+ "ExtractionEstimateFieldMin", Union[float, str]
+)
+
+
+ExtractionEstimateFieldScale = Union[
+ Literal[
+ "linear",
+ "log",
+ ],
+ UnrecognizedStr,
+]
+
+
+ExtractionEstimateFieldStepYear = Literal["year",]
+
+
+ExtractionEstimateFieldStepMonth = Literal["month",]
+
+
+ExtractionEstimateFieldStepUnionTypedDict = TypeAliasType(
+ "ExtractionEstimateFieldStepUnionTypedDict",
+ Union[float, ExtractionEstimateFieldStepMonth, ExtractionEstimateFieldStepYear],
+)
+
+
+ExtractionEstimateFieldStepUnion = TypeAliasType(
+ "ExtractionEstimateFieldStepUnion",
+ Union[float, ExtractionEstimateFieldStepMonth, ExtractionEstimateFieldStepYear],
+)
+
+
+ExtractionEstimateFieldType = Literal["estimate",]
+
+
+class ExtractionEstimateFieldTypedDict(TypedDict):
+ max: ExtractionEstimateFieldMaxTypedDict
+ min: ExtractionEstimateFieldMinTypedDict
+ type: ExtractionEstimateFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+ scale: NotRequired[ExtractionEstimateFieldScale]
+ step: NotRequired[ExtractionEstimateFieldStepUnionTypedDict]
+ unit: NotRequired[str]
+
+
+class ExtractionEstimateField(BaseModel):
+ max: ExtractionEstimateFieldMax
+
+ min: ExtractionEstimateFieldMin
+
+ type: ExtractionEstimateFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ scale: Optional[ExtractionEstimateFieldScale] = None
+
+ step: Optional[ExtractionEstimateFieldStepUnion] = None
+
+ unit: Optional[str] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["instructions", "null_threshold", "scale", "step", "unit"]
+ )
+ 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/extractionforecastanswer.py b/src/openrouter/components/extractionforecastanswer.py
new file mode 100644
index 00000000..46a911b6
--- /dev/null
+++ b/src/openrouter/components/extractionforecastanswer.py
@@ -0,0 +1,171 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from .extractionforecaststep import (
+ ExtractionForecastStep,
+ ExtractionForecastStepTypedDict,
+)
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionForecastAnswerGuessTypedDict = TypeAliasType(
+ "ExtractionForecastAnswerGuessTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerGuess = TypeAliasType(
+ "ExtractionForecastAnswerGuess", Union[float, str]
+)
+
+
+ExtractionForecastAnswerMeanTypedDict = TypeAliasType(
+ "ExtractionForecastAnswerMeanTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerMean = TypeAliasType(
+ "ExtractionForecastAnswerMean", Union[float, str]
+)
+
+
+ExtractionForecastAnswerMedianTypedDict = TypeAliasType(
+ "ExtractionForecastAnswerMedianTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerMedian = TypeAliasType(
+ "ExtractionForecastAnswerMedian", Union[float, str]
+)
+
+
+ExtractionForecastAnswerP10TypedDict = TypeAliasType(
+ "ExtractionForecastAnswerP10TypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerP10 = TypeAliasType(
+ "ExtractionForecastAnswerP10", Union[float, str]
+)
+
+
+ExtractionForecastAnswerP90TypedDict = TypeAliasType(
+ "ExtractionForecastAnswerP90TypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerP90 = TypeAliasType(
+ "ExtractionForecastAnswerP90", Union[float, str]
+)
+
+
+ExtractionForecastAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionForecastAnswerType = Literal["forecast",]
+
+
+ExtractionForecastAnswerValueTypedDict = TypeAliasType(
+ "ExtractionForecastAnswerValueTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastAnswerValue = TypeAliasType(
+ "ExtractionForecastAnswerValue", Union[float, str]
+)
+
+
+class ExtractionForecastAnswerTypedDict(TypedDict):
+ type: ExtractionForecastAnswerType
+ value: Nullable[List[ExtractionForecastAnswerValueTypedDict]]
+ confidence: NotRequired[float]
+ guess: NotRequired[List[ExtractionForecastAnswerGuessTypedDict]]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ mean: NotRequired[List[ExtractionForecastAnswerMeanTypedDict]]
+ median: NotRequired[List[ExtractionForecastAnswerMedianTypedDict]]
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ p10: NotRequired[List[ExtractionForecastAnswerP10TypedDict]]
+ p90: NotRequired[List[ExtractionForecastAnswerP90TypedDict]]
+ source: NotRequired[ExtractionForecastAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+ steps: NotRequired[List[ExtractionForecastStepTypedDict]]
+
+
+class ExtractionForecastAnswer(BaseModel):
+ type: ExtractionForecastAnswerType
+
+ value: Nullable[List[ExtractionForecastAnswerValue]]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[List[ExtractionForecastAnswerGuess]] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ mean: Optional[List[ExtractionForecastAnswerMean]] = None
+
+ median: Optional[List[ExtractionForecastAnswerMedian]] = None
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ p10: Optional[List[ExtractionForecastAnswerP10]] = None
+
+ p90: Optional[List[ExtractionForecastAnswerP90]] = None
+
+ source: Optional[ExtractionForecastAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ steps: Optional[List[ExtractionForecastStep]] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ [
+ "confidence",
+ "guess",
+ "mean",
+ "median",
+ "p_null",
+ "p10",
+ "p90",
+ "source",
+ "spell_confidence",
+ "steps",
+ ]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionforecastfield.py b/src/openrouter/components/extractionforecastfield.py
new file mode 100644
index 00000000..7b2bf5d0
--- /dev/null
+++ b/src/openrouter/components/extractionforecastfield.py
@@ -0,0 +1,131 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import Literal, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+Interval = Union[
+ Literal[
+ "step",
+ "minute",
+ "hour",
+ "day",
+ "week",
+ "month",
+ "quarter",
+ "year",
+ ],
+ UnrecognizedStr,
+]
+
+
+ExtractionForecastFieldMaxTypedDict = TypeAliasType(
+ "ExtractionForecastFieldMaxTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastFieldMax = TypeAliasType(
+ "ExtractionForecastFieldMax", Union[float, str]
+)
+
+
+ExtractionForecastFieldMinTypedDict = TypeAliasType(
+ "ExtractionForecastFieldMinTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastFieldMin = TypeAliasType(
+ "ExtractionForecastFieldMin", Union[float, str]
+)
+
+
+ExtractionForecastFieldScale = Union[
+ Literal[
+ "linear",
+ "log",
+ ],
+ UnrecognizedStr,
+]
+
+
+ExtractionForecastFieldStepYear = Literal["year",]
+
+
+ExtractionForecastFieldStepMonth = Literal["month",]
+
+
+ExtractionForecastFieldStepUnionTypedDict = TypeAliasType(
+ "ExtractionForecastFieldStepUnionTypedDict",
+ Union[float, ExtractionForecastFieldStepMonth, ExtractionForecastFieldStepYear],
+)
+
+
+ExtractionForecastFieldStepUnion = TypeAliasType(
+ "ExtractionForecastFieldStepUnion",
+ Union[float, ExtractionForecastFieldStepMonth, ExtractionForecastFieldStepYear],
+)
+
+
+ExtractionForecastFieldType = Literal["forecast",]
+
+
+class ExtractionForecastFieldTypedDict(TypedDict):
+ horizon: int
+ r"""Number of forecast steps."""
+ interval: Interval
+ max: ExtractionForecastFieldMaxTypedDict
+ min: ExtractionForecastFieldMinTypedDict
+ type: ExtractionForecastFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+ scale: NotRequired[ExtractionForecastFieldScale]
+ step: NotRequired[ExtractionForecastFieldStepUnionTypedDict]
+ unit: NotRequired[str]
+
+
+class ExtractionForecastField(BaseModel):
+ horizon: int
+ r"""Number of forecast steps."""
+
+ interval: Interval
+
+ max: ExtractionForecastFieldMax
+
+ min: ExtractionForecastFieldMin
+
+ type: ExtractionForecastFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ scale: Optional[ExtractionForecastFieldScale] = None
+
+ step: Optional[ExtractionForecastFieldStepUnion] = None
+
+ unit: Optional[str] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["instructions", "null_threshold", "scale", "step", "unit"]
+ )
+ 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/extractionforecaststep.py b/src/openrouter/components/extractionforecaststep.py
new file mode 100644
index 00000000..47809e77
--- /dev/null
+++ b/src/openrouter/components/extractionforecaststep.py
@@ -0,0 +1,129 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL
+from pydantic import model_serializer
+from typing import List, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionForecastStepMeanTypedDict = TypeAliasType(
+ "ExtractionForecastStepMeanTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepMean = TypeAliasType(
+ "ExtractionForecastStepMean", Union[float, str]
+)
+
+
+ExtractionForecastStepMedianTypedDict = TypeAliasType(
+ "ExtractionForecastStepMedianTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepMedian = TypeAliasType(
+ "ExtractionForecastStepMedian", Union[float, str]
+)
+
+
+ExtractionForecastStepP10TypedDict = TypeAliasType(
+ "ExtractionForecastStepP10TypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepP10 = TypeAliasType(
+ "ExtractionForecastStepP10", Union[float, str]
+)
+
+
+ExtractionForecastStepP90TypedDict = TypeAliasType(
+ "ExtractionForecastStepP90TypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepP90 = TypeAliasType(
+ "ExtractionForecastStepP90", Union[float, str]
+)
+
+
+ExtractionForecastStepQuantileTypedDict = TypeAliasType(
+ "ExtractionForecastStepQuantileTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepQuantile = TypeAliasType(
+ "ExtractionForecastStepQuantile", Union[float, str]
+)
+
+
+ExtractionForecastStepValueTypedDict = TypeAliasType(
+ "ExtractionForecastStepValueTypedDict", Union[float, str]
+)
+
+
+ExtractionForecastStepValue = TypeAliasType(
+ "ExtractionForecastStepValue", Union[float, str]
+)
+
+
+class ExtractionForecastStepTypedDict(TypedDict):
+ value: Nullable[ExtractionForecastStepValueTypedDict]
+ mean: NotRequired[ExtractionForecastStepMeanTypedDict]
+ median: NotRequired[ExtractionForecastStepMedianTypedDict]
+ p_above: NotRequired[float]
+ r"""Probability mass above `max`."""
+ p_below: NotRequired[float]
+ r"""Probability mass below `min`."""
+ p10: NotRequired[ExtractionForecastStepP10TypedDict]
+ p90: NotRequired[ExtractionForecastStepP90TypedDict]
+ quantiles: NotRequired[List[ExtractionForecastStepQuantileTypedDict]]
+ r"""99 percentiles, present when the provider is asked for quantiles."""
+
+
+class ExtractionForecastStep(BaseModel):
+ value: Nullable[ExtractionForecastStepValue]
+
+ mean: Optional[ExtractionForecastStepMean] = None
+
+ median: Optional[ExtractionForecastStepMedian] = None
+
+ p_above: Optional[float] = None
+ r"""Probability mass above `max`."""
+
+ p_below: Optional[float] = None
+ r"""Probability mass below `min`."""
+
+ p10: Optional[ExtractionForecastStepP10] = None
+
+ p90: Optional[ExtractionForecastStepP90] = None
+
+ quantiles: Optional[List[ExtractionForecastStepQuantile]] = None
+ r"""99 percentiles, present when the provider is asked for quantiles."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["mean", "median", "p_above", "p_below", "p10", "p90", "quantiles"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionlistanswer.py b/src/openrouter/components/extractionlistanswer.py
new file mode 100644
index 00000000..82ad80fe
--- /dev/null
+++ b/src/openrouter/components/extractionlistanswer.py
@@ -0,0 +1,104 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionListAnswerGuessTypedDict = TypeAliasType(
+ "ExtractionListAnswerGuessTypedDict", Union[str, float]
+)
+
+
+ExtractionListAnswerGuess = TypeAliasType(
+ "ExtractionListAnswerGuess", Union[str, float]
+)
+
+
+ExtractionListAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionListAnswerType = Literal["list",]
+
+
+ExtractionListAnswerValueTypedDict = TypeAliasType(
+ "ExtractionListAnswerValueTypedDict", Union[str, float]
+)
+
+
+ExtractionListAnswerValue = TypeAliasType(
+ "ExtractionListAnswerValue", Union[str, float]
+)
+
+
+class ExtractionListAnswerTypedDict(TypedDict):
+ type: ExtractionListAnswerType
+ value: Nullable[List[ExtractionListAnswerValueTypedDict]]
+ confidence: NotRequired[float]
+ guess: NotRequired[List[ExtractionListAnswerGuessTypedDict]]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionListAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ spans: NotRequired[List[List[int]]]
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionListAnswer(BaseModel):
+ type: ExtractionListAnswerType
+
+ value: Nullable[List[ExtractionListAnswerValue]]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[List[ExtractionListAnswerGuess]] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionListAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ spans: Optional[List[List[int]]] = None
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "spans", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionlistfield.py b/src/openrouter/components/extractionlistfield.py
new file mode 100644
index 00000000..282b863b
--- /dev/null
+++ b/src/openrouter/components/extractionlistfield.py
@@ -0,0 +1,62 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+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
+
+
+Items = Union[
+ Literal[
+ "text",
+ "number",
+ "date",
+ ],
+ UnrecognizedStr,
+]
+
+
+ExtractionListFieldType = Literal["list",]
+
+
+class ExtractionListFieldTypedDict(TypedDict):
+ items: Items
+ type: ExtractionListFieldType
+ decimals: NotRequired[int]
+ r"""Decimal places kept in `value`."""
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+
+class ExtractionListField(BaseModel):
+ items: Items
+
+ type: ExtractionListFieldType
+
+ decimals: Optional[int] = None
+ r"""Decimal places kept in `value`."""
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["decimals", "instructions", "null_threshold"])
+ 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/extractionnumberanswer.py b/src/openrouter/components/extractionnumberanswer.py
new file mode 100644
index 00000000..adea0721
--- /dev/null
+++ b/src/openrouter/components/extractionnumberanswer.py
@@ -0,0 +1,86 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionNumberAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionNumberAnswerType = Literal["number",]
+
+
+class ExtractionNumberAnswerTypedDict(TypedDict):
+ type: ExtractionNumberAnswerType
+ value: Nullable[float]
+ confidence: NotRequired[float]
+ guess: NotRequired[float]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionNumberAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionNumberAnswer(BaseModel):
+ type: ExtractionNumberAnswerType
+
+ value: Nullable[float]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[float] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionNumberAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "span", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionnumberfield.py b/src/openrouter/components/extractionnumberfield.py
new file mode 100644
index 00000000..1823b010
--- /dev/null
+++ b/src/openrouter/components/extractionnumberfield.py
@@ -0,0 +1,57 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionNumberFieldType = Literal["number",]
+
+
+class ExtractionNumberFieldTypedDict(TypedDict):
+ type: ExtractionNumberFieldType
+ decimals: NotRequired[int]
+ r"""Decimal places kept in `value`."""
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ integer: NotRequired[bool]
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+ unit: NotRequired[str]
+
+
+class ExtractionNumberField(BaseModel):
+ type: ExtractionNumberFieldType
+
+ decimals: Optional[int] = None
+ r"""Decimal places kept in `value`."""
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ integer: Optional[bool] = None
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ unit: Optional[str] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["decimals", "instructions", "integer", "null_threshold", "unit"]
+ )
+ 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/extractionsrequest.py b/src/openrouter/components/extractionsrequest.py
new file mode 100644
index 00000000..a75599b1
--- /dev/null
+++ b/src/openrouter/components/extractionsrequest.py
@@ -0,0 +1,143 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from .decisionsimageasset import DecisionsImageAsset, DecisionsImageAssetTypedDict
+from .extractiondatefield import ExtractionDateField, ExtractionDateFieldTypedDict
+from .extractiondatetimefield import (
+ ExtractionDatetimeField,
+ ExtractionDatetimeFieldTypedDict,
+)
+from .extractiondurationfield import (
+ ExtractionDurationField,
+ ExtractionDurationFieldTypedDict,
+)
+from .extractionestimatefield import (
+ ExtractionEstimateField,
+ ExtractionEstimateFieldTypedDict,
+)
+from .extractionforecastfield import (
+ ExtractionForecastField,
+ ExtractionForecastFieldTypedDict,
+)
+from .extractionlistfield import ExtractionListField, ExtractionListFieldTypedDict
+from .extractionnumberfield import ExtractionNumberField, ExtractionNumberFieldTypedDict
+from .extractiontextfield import ExtractionTextField, ExtractionTextFieldTypedDict
+from .extractiontimefield import ExtractionTimeField, ExtractionTimeFieldTypedDict
+from .providerpreferences import ProviderPreferences, ProviderPreferencesTypedDict
+from .traceconfig import TraceConfig, TraceConfigTypedDict
+from openrouter.types import (
+ BaseModel,
+ Nullable,
+ OptionalNullable,
+ UNSET,
+ UNSET_SENTINEL,
+)
+from openrouter.utils import get_discriminator
+from pydantic import Discriminator, Tag, model_serializer
+from typing import Dict, Optional, Union
+from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
+
+
+FieldsTypedDict = TypeAliasType(
+ "FieldsTypedDict",
+ Union[
+ ExtractionTextFieldTypedDict,
+ ExtractionDateFieldTypedDict,
+ ExtractionTimeFieldTypedDict,
+ ExtractionDatetimeFieldTypedDict,
+ ExtractionListFieldTypedDict,
+ ExtractionNumberFieldTypedDict,
+ ExtractionDurationFieldTypedDict,
+ ExtractionEstimateFieldTypedDict,
+ ExtractionForecastFieldTypedDict,
+ ],
+)
+r"""A typed field to extract, compute, estimate or forecast from the state. Which types a model answers is model-specific; unsupported types are rejected with 400."""
+
+
+Fields = Annotated[
+ Union[
+ Annotated[ExtractionDateField, Tag("date")],
+ Annotated[ExtractionDatetimeField, Tag("datetime")],
+ Annotated[ExtractionDurationField, Tag("duration")],
+ Annotated[ExtractionEstimateField, Tag("estimate")],
+ Annotated[ExtractionForecastField, Tag("forecast")],
+ Annotated[ExtractionListField, Tag("list")],
+ Annotated[ExtractionNumberField, Tag("number")],
+ Annotated[ExtractionTextField, Tag("text")],
+ Annotated[ExtractionTimeField, Tag("time")],
+ ],
+ Discriminator(lambda m: get_discriminator(m, "type", "type")),
+]
+r"""A typed field to extract, compute, estimate or forecast from the state. Which types a model answers is model-specific; unsupported types are rejected with 400."""
+
+
+class ExtractionsRequestTypedDict(TypedDict):
+ fields: Dict[str, FieldsTypedDict]
+ r"""Map of field name to typed field spec."""
+ model: str
+ state: str
+ r"""The text to read from. May be empty only when the request carries image assets."""
+ assets: NotRequired[Dict[str, DecisionsImageAssetTypedDict]]
+ r"""Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text."""
+ provider: NotRequired[Nullable[ProviderPreferencesTypedDict]]
+ reference_date: NotRequired[str]
+ r"""ISO date that anchors dates written without a year."""
+ session_id: NotRequired[str]
+ r"""A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters."""
+ trace: NotRequired[TraceConfigTypedDict]
+ r"""Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations."""
+ user: NotRequired[str]
+
+
+class ExtractionsRequest(BaseModel):
+ fields: Dict[str, Fields]
+ r"""Map of field name to typed field spec."""
+
+ model: str
+
+ state: str
+ r"""The text to read from. May be empty only when the request carries image assets."""
+
+ assets: Optional[Dict[str, DecisionsImageAsset]] = None
+ r"""Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text."""
+
+ provider: OptionalNullable[ProviderPreferences] = UNSET
+
+ reference_date: Optional[str] = None
+ r"""ISO date that anchors dates written without a year."""
+
+ session_id: Optional[str] = None
+ r"""A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters."""
+
+ trace: Optional[TraceConfig] = None
+ r"""Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations."""
+
+ user: Optional[str] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["assets", "provider", "reference_date", "session_id", "trace", "user"]
+ )
+ nullable_fields = set(["provider"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionsresponse.py b/src/openrouter/components/extractionsresponse.py
new file mode 100644
index 00000000..edada0cb
--- /dev/null
+++ b/src/openrouter/components/extractionsresponse.py
@@ -0,0 +1,162 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from .extractiondateanswer import ExtractionDateAnswer, ExtractionDateAnswerTypedDict
+from .extractiondatetimeanswer import (
+ ExtractionDatetimeAnswer,
+ ExtractionDatetimeAnswerTypedDict,
+)
+from .extractiondurationanswer import (
+ ExtractionDurationAnswer,
+ ExtractionDurationAnswerTypedDict,
+)
+from .extractionestimateanswer import (
+ ExtractionEstimateAnswer,
+ ExtractionEstimateAnswerTypedDict,
+)
+from .extractionforecastanswer import (
+ ExtractionForecastAnswer,
+ ExtractionForecastAnswerTypedDict,
+)
+from .extractionlistanswer import ExtractionListAnswer, ExtractionListAnswerTypedDict
+from .extractionnumberanswer import (
+ ExtractionNumberAnswer,
+ ExtractionNumberAnswerTypedDict,
+)
+from .extractionsusage import ExtractionsUsage, ExtractionsUsageTypedDict
+from .extractiontextanswer import ExtractionTextAnswer, ExtractionTextAnswerTypedDict
+from .extractiontimeanswer import ExtractionTimeAnswer, ExtractionTimeAnswerTypedDict
+from functools import partial
+from openrouter.types import (
+ BaseModel,
+ Nullable,
+ OptionalNullable,
+ UNSET,
+ UNSET_SENTINEL,
+)
+from openrouter.utils.unions import parse_open_union
+from pydantic import ConfigDict, model_serializer
+from pydantic.functional_validators import BeforeValidator
+from typing import Any, Dict, Literal, Optional, Union
+from typing_extensions import Annotated, NotRequired, TypeAliasType, TypedDict
+
+
+ExtractionsResponseAnswersTypedDict = TypeAliasType(
+ "ExtractionsResponseAnswersTypedDict",
+ Union[
+ ExtractionTextAnswerTypedDict,
+ ExtractionNumberAnswerTypedDict,
+ ExtractionDateAnswerTypedDict,
+ ExtractionTimeAnswerTypedDict,
+ ExtractionDatetimeAnswerTypedDict,
+ ExtractionListAnswerTypedDict,
+ ExtractionDurationAnswerTypedDict,
+ ExtractionForecastAnswerTypedDict,
+ ExtractionEstimateAnswerTypedDict,
+ ],
+)
+r"""One answer per requested field. `value` is null when the state does not determine it."""
+
+
+class UnknownExtractionsResponseAnswers(BaseModel):
+ r"""A ExtractionsResponseAnswers variant the SDK doesn't recognize. Preserves the raw payload."""
+
+ type: Literal["UNKNOWN"] = "UNKNOWN"
+ raw: Any
+ is_unknown: Literal[True] = True
+
+ model_config = ConfigDict(frozen=True)
+
+
+_EXTRACTIONS_RESPONSE_ANSWERS_VARIANTS: dict[str, Any] = {
+ "date": ExtractionDateAnswer,
+ "datetime": ExtractionDatetimeAnswer,
+ "duration": ExtractionDurationAnswer,
+ "estimate": ExtractionEstimateAnswer,
+ "forecast": ExtractionForecastAnswer,
+ "list": ExtractionListAnswer,
+ "number": ExtractionNumberAnswer,
+ "text": ExtractionTextAnswer,
+ "time": ExtractionTimeAnswer,
+}
+
+
+ExtractionsResponseAnswers = Annotated[
+ Union[
+ ExtractionDateAnswer,
+ ExtractionDatetimeAnswer,
+ ExtractionDurationAnswer,
+ ExtractionEstimateAnswer,
+ ExtractionForecastAnswer,
+ ExtractionListAnswer,
+ ExtractionNumberAnswer,
+ ExtractionTextAnswer,
+ ExtractionTimeAnswer,
+ UnknownExtractionsResponseAnswers,
+ ],
+ BeforeValidator(
+ partial(
+ parse_open_union,
+ disc_key="type",
+ variants=_EXTRACTIONS_RESPONSE_ANSWERS_VARIANTS,
+ unknown_cls=UnknownExtractionsResponseAnswers,
+ union_name="ExtractionsResponseAnswers",
+ )
+ ),
+]
+r"""One answer per requested field. `value` is null when the state does not determine it."""
+
+
+class ExtractionsResponseTypedDict(TypedDict):
+ answers: Dict[str, ExtractionsResponseAnswersTypedDict]
+ model: str
+ usage: ExtractionsUsageTypedDict
+ id: NotRequired[str]
+ provider: NotRequired[str]
+ state_text: NotRequired[Nullable[str]]
+ r"""The text that spans index into, when requested through provider options."""
+ truncated: NotRequired[bool]
+ r"""True when the provider read only a prefix of the state."""
+
+
+class ExtractionsResponse(BaseModel):
+ answers: Dict[str, ExtractionsResponseAnswers]
+
+ model: str
+
+ usage: ExtractionsUsage
+
+ id: Optional[str] = None
+
+ provider: Optional[str] = None
+
+ state_text: OptionalNullable[str] = UNSET
+ r"""The text that spans index into, when requested through provider options."""
+
+ truncated: Optional[bool] = None
+ r"""True when the provider read only a prefix of the state."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["id", "provider", "state_text", "truncated"])
+ nullable_fields = set(["state_text"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractionsusage.py b/src/openrouter/components/extractionsusage.py
new file mode 100644
index 00000000..e42e2df4
--- /dev/null
+++ b/src/openrouter/components/extractionsusage.py
@@ -0,0 +1,53 @@
+"""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 Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+class ExtractionsUsageTypedDict(TypedDict):
+ input_tokens: int
+ output_tokens: int
+ cost: NotRequired[float]
+ image_tokens: NotRequired[int]
+ passes: NotRequired[int]
+ r"""Number of upstream passes when the fields did not fit in one."""
+ schema_tokens: NotRequired[int]
+ state_tokens: NotRequired[int]
+
+
+class ExtractionsUsage(BaseModel):
+ input_tokens: int
+
+ output_tokens: int
+
+ cost: Optional[float] = None
+
+ image_tokens: Optional[int] = None
+
+ passes: Optional[int] = None
+ r"""Number of upstream passes when the fields did not fit in one."""
+
+ schema_tokens: Optional[int] = None
+
+ state_tokens: Optional[int] = None
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["cost", "image_tokens", "passes", "schema_tokens", "state_tokens"]
+ )
+ 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/extractiontextanswer.py b/src/openrouter/components/extractiontextanswer.py
new file mode 100644
index 00000000..b72f0066
--- /dev/null
+++ b/src/openrouter/components/extractiontextanswer.py
@@ -0,0 +1,86 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionTextAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionTextAnswerType = Literal["text",]
+
+
+class ExtractionTextAnswerTypedDict(TypedDict):
+ type: ExtractionTextAnswerType
+ value: Nullable[str]
+ confidence: NotRequired[float]
+ guess: NotRequired[str]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionTextAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionTextAnswer(BaseModel):
+ type: ExtractionTextAnswerType
+
+ value: Nullable[str]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[str] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionTextAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "span", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractiontextfield.py b/src/openrouter/components/extractiontextfield.py
new file mode 100644
index 00000000..4624afa9
--- /dev/null
+++ b/src/openrouter/components/extractiontextfield.py
@@ -0,0 +1,44 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionTextFieldType = Literal["text",]
+
+
+class ExtractionTextFieldTypedDict(TypedDict):
+ type: ExtractionTextFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+
+class ExtractionTextField(BaseModel):
+ type: ExtractionTextFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["instructions", "null_threshold"])
+ 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/extractiontimeanswer.py b/src/openrouter/components/extractiontimeanswer.py
new file mode 100644
index 00000000..11a35dab
--- /dev/null
+++ b/src/openrouter/components/extractiontimeanswer.py
@@ -0,0 +1,86 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.types import BaseModel, Nullable, UNSET_SENTINEL, UnrecognizedStr
+from pydantic import model_serializer
+from typing import List, Literal, Optional, Union
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionTimeAnswerSource = Union[
+ Literal[
+ "state",
+ "image",
+ ],
+ UnrecognizedStr,
+]
+r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+
+ExtractionTimeAnswerType = Literal["time",]
+
+
+class ExtractionTimeAnswerTypedDict(TypedDict):
+ type: ExtractionTimeAnswerType
+ value: Nullable[str]
+ confidence: NotRequired[float]
+ guess: NotRequired[str]
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+ p_null: NotRequired[float]
+ r"""Probability that the state contains nothing for this field."""
+ source: NotRequired[ExtractionTimeAnswerSource]
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+ span: NotRequired[List[int]]
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+ spell_confidence: NotRequired[float]
+ r"""Confidence in the spelling of text read from an image."""
+
+
+class ExtractionTimeAnswer(BaseModel):
+ type: ExtractionTimeAnswerType
+
+ value: Nullable[str]
+
+ confidence: Optional[float] = None
+
+ guess: Optional[str] = None
+ r"""The most likely value even when `value` is null because `p_null` crossed the threshold."""
+
+ p_null: Optional[float] = None
+ r"""Probability that the state contains nothing for this field."""
+
+ source: Optional[ExtractionTimeAnswerSource] = None
+ r"""Set to `image` when the answer was read from an image rather than the state text."""
+
+ span: Optional[List[int]] = None
+ r"""Unicode code point offsets [start, end) into the state text: index code points (not UTF-16 code units or UTF-8 bytes), so an emoji or accented letter counts once."""
+
+ spell_confidence: Optional[float] = None
+ r"""Confidence in the spelling of text read from an image."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["confidence", "guess", "p_null", "source", "span", "spell_confidence"]
+ )
+ nullable_fields = set(["value"])
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+ is_nullable_and_explicitly_set = (
+ k in nullable_fields
+ and (self.__pydantic_fields_set__.intersection({n})) # pylint: disable=no-member
+ )
+
+ if val != UNSET_SENTINEL:
+ if (
+ val is not None
+ or k not in optional_fields
+ or is_nullable_and_explicitly_set
+ ):
+ m[k] = val
+
+ return m
diff --git a/src/openrouter/components/extractiontimefield.py b/src/openrouter/components/extractiontimefield.py
new file mode 100644
index 00000000..8007f9e5
--- /dev/null
+++ b/src/openrouter/components/extractiontimefield.py
@@ -0,0 +1,44 @@
+"""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 Literal, Optional
+from typing_extensions import NotRequired, TypedDict
+
+
+ExtractionTimeFieldType = Literal["time",]
+
+
+class ExtractionTimeFieldTypedDict(TypedDict):
+ type: ExtractionTimeFieldType
+ instructions: NotRequired[str]
+ r"""What the field should contain."""
+ null_threshold: NotRequired[float]
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+
+class ExtractionTimeField(BaseModel):
+ type: ExtractionTimeFieldType
+
+ instructions: Optional[str] = None
+ r"""What the field should contain."""
+
+ null_threshold: Optional[float] = None
+ r"""Probability of null above which `value` is null. Default 0.5."""
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(["instructions", "null_threshold"])
+ 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/generationresponse.py b/src/openrouter/components/generationresponse.py
index ac86c128..44f3b919 100644
--- a/src/openrouter/components/generationresponse.py
+++ b/src/openrouter/components/generationresponse.py
@@ -21,6 +21,7 @@
"embeddings",
"rerank",
"decisions",
+ "extractions",
"video",
"tts",
"stt",
diff --git a/src/openrouter/extractions.py b/src/openrouter/extractions.py
new file mode 100644
index 00000000..1def6665
--- /dev/null
+++ b/src/openrouter/extractions.py
@@ -0,0 +1,459 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from .basesdk import BaseSDK
+from openrouter import components, errors, operations, utils
+from openrouter._hooks import HookContext
+from openrouter.types import OptionalNullable, UNSET
+from openrouter.utils import get_security_from_env
+from openrouter.utils.unmarshal_json_response import unmarshal_json_response
+from typing import Any, Dict, Mapping, Optional, Union
+
+
+class Extractions(BaseSDK):
+ r"""Alpha feature endpoints for Extractions requests"""
+
+ def create(
+ self,
+ *,
+ fields: Union[
+ Mapping[str, components.Fields], Mapping[str, components.FieldsTypedDict]
+ ],
+ model: str,
+ state: str,
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ assets: Optional[
+ Union[
+ Mapping[str, components.DecisionsImageAsset],
+ Mapping[str, components.DecisionsImageAssetTypedDict],
+ ]
+ ] = None,
+ provider: OptionalNullable[
+ Union[
+ components.ProviderPreferences, components.ProviderPreferencesTypedDict
+ ]
+ ] = UNSET,
+ reference_date: Optional[str] = None,
+ session_id: Optional[str] = None,
+ trace: Optional[
+ Union[components.TraceConfig, components.TraceConfigTypedDict]
+ ] = None,
+ user: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.ExtractionsResponse:
+ r"""Submit an Extractions request
+
+ Extracts, computes, estimates or forecasts typed fields from a state string and image assets using an extraction-style System One model. Alpha: the shape is not stable.
+
+ :param fields: Map of field name to typed field spec.
+ :param model:
+ :param state: The text to read from. May be empty only when the request carries image assets.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param assets: Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text.
+ :param provider:
+ :param reference_date: ISO date that anchors dates written without a year.
+ :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
+ :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
+ :param user:
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = operations.CREATE_API_ALPHA_EXTRACTIONS_SERVERS[0]
+
+ request = operations.CreateAPIAlphaExtractionsRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ extractions_request=components.ExtractionsRequest(
+ assets=utils.get_pydantic_model(
+ assets, Optional[Dict[str, components.DecisionsImageAsset]]
+ ),
+ fields=utils.get_pydantic_model(fields, Dict[str, components.Fields]),
+ model=model,
+ provider=utils.get_pydantic_model(
+ provider, OptionalNullable[components.ProviderPreferences]
+ ),
+ reference_date=reference_date,
+ session_id=session_id,
+ state=state,
+ trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
+ user=user,
+ ),
+ )
+
+ req = self._build_request(
+ method="POST",
+ path="/api/alpha/extractions",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=True,
+ request_has_path_params=False,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.CreateAPIAlphaExtractionsGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ get_serialized_body=lambda: utils.serialize_request_body(
+ request.extractions_request,
+ False,
+ False,
+ "json",
+ components.ExtractionsRequest,
+ ),
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = self.do_request(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="createApiAlphaExtractions",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["alpha.extractions"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(components.ExtractionsResponse, http_res)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "402", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PaymentRequiredResponseErrorData, http_res
+ )
+ raise errors.PaymentRequiredResponseError(response_data, http_res)
+ if utils.match_response(http_res, "403", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ForbiddenResponseErrorData, http_res
+ )
+ raise errors.ForbiddenResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "413", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PayloadTooLargeResponseErrorData, http_res
+ )
+ raise errors.PayloadTooLargeResponseError(response_data, http_res)
+ if utils.match_response(http_res, "429", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.TooManyRequestsResponseErrorData, http_res
+ )
+ raise errors.TooManyRequestsResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "502", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadGatewayResponseErrorData, http_res
+ )
+ raise errors.BadGatewayResponseError(response_data, http_res)
+ if utils.match_response(http_res, "503", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ServiceUnavailableResponseErrorData, http_res
+ )
+ raise errors.ServiceUnavailableResponseError(response_data, http_res)
+ if utils.match_response(http_res, "524", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.EdgeNetworkTimeoutResponseErrorData, http_res
+ )
+ raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res)
+ if utils.match_response(http_res, "529", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ProviderOverloadedResponseErrorData, http_res
+ )
+ raise errors.ProviderOverloadedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = utils.stream_to_text(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
+
+ async def create_async(
+ self,
+ *,
+ fields: Union[
+ Mapping[str, components.Fields], Mapping[str, components.FieldsTypedDict]
+ ],
+ model: str,
+ state: str,
+ http_referer: Optional[str] = None,
+ x_open_router_title: Optional[str] = None,
+ x_open_router_categories: Optional[str] = None,
+ assets: Optional[
+ Union[
+ Mapping[str, components.DecisionsImageAsset],
+ Mapping[str, components.DecisionsImageAssetTypedDict],
+ ]
+ ] = None,
+ provider: OptionalNullable[
+ Union[
+ components.ProviderPreferences, components.ProviderPreferencesTypedDict
+ ]
+ ] = UNSET,
+ reference_date: Optional[str] = None,
+ session_id: Optional[str] = None,
+ trace: Optional[
+ Union[components.TraceConfig, components.TraceConfigTypedDict]
+ ] = None,
+ user: Optional[str] = None,
+ retries: OptionalNullable[utils.RetryConfig] = UNSET,
+ server_url: Optional[str] = None,
+ timeout_ms: Optional[int] = None,
+ http_headers: Optional[Mapping[str, str]] = None,
+ ) -> components.ExtractionsResponse:
+ r"""Submit an Extractions request
+
+ Extracts, computes, estimates or forecasts typed fields from a state string and image assets using an extraction-style System One model. Alpha: the shape is not stable.
+
+ :param fields: Map of field name to typed field spec.
+ :param model:
+ :param state: The text to read from. May be empty only when the request carries image assets.
+ :param http_referer: The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ :param x_open_router_title: The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ :param x_open_router_categories: Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ :param assets: Images keyed by reference string, as in TypeSafe's API. Write a reference wherever the image belongs in `state`, `instructions`, or `criteria`; every asset must be referenced at least once. Jev reads a reference as a whole string value or inside longer text. Other Decisions models read a whole-string reference wherever they read an `image_url` part and reject a reference inside longer text.
+ :param provider:
+ :param reference_date: ISO date that anchors dates written without a year.
+ :param session_id: A unique identifier for grouping related requests (e.g., a conversation or agent workflow). Used for observability grouping in Broadcast and private logging; never sent to the provider. If provided in both the request body and the x-session-id header, the body value takes precedence. Maximum of 256 characters.
+ :param trace: Metadata for observability and tracing. Known keys (trace_id, trace_name, span_name, generation_name, parent_span_id) have special handling. Additional keys are passed through as custom metadata to configured broadcast destinations.
+ :param user:
+ :param retries: Override the default retry configuration for this method
+ :param server_url: Override the default server URL for this method
+ :param timeout_ms: Override the default request timeout configuration for this method in milliseconds
+ :param http_headers: Additional headers to set or replace on requests.
+ """
+ base_url = None
+ url_variables = None
+ if timeout_ms is None:
+ timeout_ms = self.sdk_configuration.timeout_ms
+
+ if server_url is not None:
+ base_url = server_url
+ else:
+ base_url = operations.CREATE_API_ALPHA_EXTRACTIONS_SERVERS[0]
+
+ request = operations.CreateAPIAlphaExtractionsRequest(
+ http_referer=http_referer,
+ x_open_router_title=x_open_router_title,
+ x_open_router_categories=x_open_router_categories,
+ extractions_request=components.ExtractionsRequest(
+ assets=utils.get_pydantic_model(
+ assets, Optional[Dict[str, components.DecisionsImageAsset]]
+ ),
+ fields=utils.get_pydantic_model(fields, Dict[str, components.Fields]),
+ model=model,
+ provider=utils.get_pydantic_model(
+ provider, OptionalNullable[components.ProviderPreferences]
+ ),
+ reference_date=reference_date,
+ session_id=session_id,
+ state=state,
+ trace=utils.get_pydantic_model(trace, Optional[components.TraceConfig]),
+ user=user,
+ ),
+ )
+
+ req = self._build_request_async(
+ method="POST",
+ path="/api/alpha/extractions",
+ base_url=base_url,
+ url_variables=url_variables,
+ request=request,
+ request_body_required=True,
+ request_has_path_params=False,
+ request_has_query_params=True,
+ user_agent_header="user-agent",
+ accept_header_value="application/json",
+ http_headers=http_headers,
+ _globals=operations.CreateAPIAlphaExtractionsGlobals(
+ http_referer=self.sdk_configuration.globals.http_referer,
+ x_open_router_title=self.sdk_configuration.globals.x_open_router_title,
+ x_open_router_categories=self.sdk_configuration.globals.x_open_router_categories,
+ ),
+ security=self.sdk_configuration.security,
+ get_serialized_body=lambda: utils.serialize_request_body(
+ request.extractions_request,
+ False,
+ False,
+ "json",
+ components.ExtractionsRequest,
+ ),
+ allow_empty_value=None,
+ timeout_ms=timeout_ms,
+ )
+
+ if retries == UNSET:
+ if self.sdk_configuration.retry_config is not UNSET:
+ retries = self.sdk_configuration.retry_config
+ else:
+ retries = utils.RetryConfig(
+ "backoff", utils.BackoffStrategy(500, 60000, 1.5, 3600000), True
+ )
+
+ retry_config = None
+ if isinstance(retries, utils.RetryConfig):
+ retry_config = (retries, ["5XX"])
+
+ http_res = await self.do_request_async(
+ hook_ctx=HookContext(
+ config=self.sdk_configuration,
+ base_url=base_url or "",
+ operation_id="createApiAlphaExtractions",
+ oauth2_scopes=None,
+ security_source=get_security_from_env(
+ self.sdk_configuration.security, components.Security
+ ),
+ tags=["alpha.extractions"],
+ extensions=None,
+ ),
+ request=req,
+ is_error_status_code=lambda c: utils.match_status_codes(["4XX", "5XX"], c),
+ retry_config=retry_config,
+ )
+
+ response_data: Any = None
+ if utils.match_response(http_res, "200", "application/json"):
+ return unmarshal_json_response(components.ExtractionsResponse, http_res)
+ if utils.match_response(http_res, "400", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadRequestResponseErrorData, http_res
+ )
+ raise errors.BadRequestResponseError(response_data, http_res)
+ if utils.match_response(http_res, "401", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.UnauthorizedResponseErrorData, http_res
+ )
+ raise errors.UnauthorizedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "402", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PaymentRequiredResponseErrorData, http_res
+ )
+ raise errors.PaymentRequiredResponseError(response_data, http_res)
+ if utils.match_response(http_res, "403", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ForbiddenResponseErrorData, http_res
+ )
+ raise errors.ForbiddenResponseError(response_data, http_res)
+ if utils.match_response(http_res, "404", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.NotFoundResponseErrorData, http_res
+ )
+ raise errors.NotFoundResponseError(response_data, http_res)
+ if utils.match_response(http_res, "413", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.PayloadTooLargeResponseErrorData, http_res
+ )
+ raise errors.PayloadTooLargeResponseError(response_data, http_res)
+ if utils.match_response(http_res, "429", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.TooManyRequestsResponseErrorData, http_res
+ )
+ raise errors.TooManyRequestsResponseError(response_data, http_res)
+ if utils.match_response(http_res, "500", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.InternalServerResponseErrorData, http_res
+ )
+ raise errors.InternalServerResponseError(response_data, http_res)
+ if utils.match_response(http_res, "502", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.BadGatewayResponseErrorData, http_res
+ )
+ raise errors.BadGatewayResponseError(response_data, http_res)
+ if utils.match_response(http_res, "503", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ServiceUnavailableResponseErrorData, http_res
+ )
+ raise errors.ServiceUnavailableResponseError(response_data, http_res)
+ if utils.match_response(http_res, "524", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.EdgeNetworkTimeoutResponseErrorData, http_res
+ )
+ raise errors.EdgeNetworkTimeoutResponseError(response_data, http_res)
+ if utils.match_response(http_res, "529", "application/json"):
+ response_data = unmarshal_json_response(
+ errors.ProviderOverloadedResponseErrorData, http_res
+ )
+ raise errors.ProviderOverloadedResponseError(response_data, http_res)
+ if utils.match_response(http_res, "4XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+ if utils.match_response(http_res, "5XX", "*"):
+ http_res_text = await utils.stream_to_text_async(http_res)
+ raise errors.OpenRouterDefaultError(
+ "API error occurred", http_res, http_res_text
+ )
+
+ raise errors.OpenRouterDefaultError("Unexpected response received", http_res)
diff --git a/src/openrouter/operations/__init__.py b/src/openrouter/operations/__init__.py
index fa711f81..b84b6753 100644
--- a/src/openrouter/operations/__init__.py
+++ b/src/openrouter/operations/__init__.py
@@ -60,6 +60,13 @@
CreateAPIAlphaDecisionsRequest,
CreateAPIAlphaDecisionsRequestTypedDict,
)
+ from .createapialphaextractions import (
+ CREATE_API_ALPHA_EXTRACTIONS_SERVERS,
+ CreateAPIAlphaExtractionsGlobals,
+ CreateAPIAlphaExtractionsGlobalsTypedDict,
+ CreateAPIAlphaExtractionsRequest,
+ CreateAPIAlphaExtractionsRequestTypedDict,
+ )
from .createaudiospeech import (
CreateAudioSpeechGlobals,
CreateAudioSpeechGlobalsTypedDict,
@@ -1167,6 +1174,7 @@
"BulkUnassignMembersFromGuardrailRequest",
"BulkUnassignMembersFromGuardrailRequestTypedDict",
"CREATE_API_ALPHA_DECISIONS_SERVERS",
+ "CREATE_API_ALPHA_EXTRACTIONS_SERVERS",
"ClassifierDimensions",
"ClassifierDimensionsTypedDict",
"ClassifierFilters",
@@ -1186,6 +1194,10 @@
"CreateAPIAlphaDecisionsGlobalsTypedDict",
"CreateAPIAlphaDecisionsRequest",
"CreateAPIAlphaDecisionsRequestTypedDict",
+ "CreateAPIAlphaExtractionsGlobals",
+ "CreateAPIAlphaExtractionsGlobalsTypedDict",
+ "CreateAPIAlphaExtractionsRequest",
+ "CreateAPIAlphaExtractionsRequestTypedDict",
"CreateAudioSpeechGlobals",
"CreateAudioSpeechGlobalsTypedDict",
"CreateAudioSpeechRequest",
@@ -2013,6 +2025,11 @@
"CreateAPIAlphaDecisionsGlobalsTypedDict": ".createapialphadecisions",
"CreateAPIAlphaDecisionsRequest": ".createapialphadecisions",
"CreateAPIAlphaDecisionsRequestTypedDict": ".createapialphadecisions",
+ "CREATE_API_ALPHA_EXTRACTIONS_SERVERS": ".createapialphaextractions",
+ "CreateAPIAlphaExtractionsGlobals": ".createapialphaextractions",
+ "CreateAPIAlphaExtractionsGlobalsTypedDict": ".createapialphaextractions",
+ "CreateAPIAlphaExtractionsRequest": ".createapialphaextractions",
+ "CreateAPIAlphaExtractionsRequestTypedDict": ".createapialphaextractions",
"CreateAudioSpeechGlobals": ".createaudiospeech",
"CreateAudioSpeechGlobalsTypedDict": ".createaudiospeech",
"CreateAudioSpeechRequest": ".createaudiospeech",
diff --git a/src/openrouter/operations/createapialphaextractions.py b/src/openrouter/operations/createapialphaextractions.py
new file mode 100644
index 00000000..1c5bc60f
--- /dev/null
+++ b/src/openrouter/operations/createapialphaextractions.py
@@ -0,0 +1,149 @@
+"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""
+
+from __future__ import annotations
+from openrouter.components import extractionsrequest as components_extractionsrequest
+from openrouter.types import BaseModel, UNSET_SENTINEL
+from openrouter.utils import FieldMetadata, HeaderMetadata, RequestMetadata
+import pydantic
+from pydantic import model_serializer
+from typing import Optional
+from typing_extensions import Annotated, NotRequired, TypedDict
+
+
+CREATE_API_ALPHA_EXTRACTIONS_SERVERS = [
+ "https://openrouter.ai",
+]
+
+
+class CreateAPIAlphaExtractionsGlobalsTypedDict(TypedDict):
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class CreateAPIAlphaExtractionsGlobals(BaseModel):
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
+
+
+class CreateAPIAlphaExtractionsRequestTypedDict(TypedDict):
+ extractions_request: components_extractionsrequest.ExtractionsRequestTypedDict
+ http_referer: NotRequired[str]
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+ x_open_router_title: NotRequired[str]
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+ x_open_router_categories: NotRequired[str]
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+
+class CreateAPIAlphaExtractionsRequest(BaseModel):
+ extractions_request: Annotated[
+ components_extractionsrequest.ExtractionsRequest,
+ FieldMetadata(request=RequestMetadata(media_type="application/json")),
+ ]
+
+ http_referer: Annotated[
+ Optional[str],
+ pydantic.Field(alias="HTTP-Referer"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app identifier should be your app's URL and is used as the primary identifier for rankings.
+ This is used to track API usage per application.
+
+ """
+
+ x_open_router_title: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Title"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""The app display name allows you to customize how your app appears in OpenRouter's dashboard.
+
+ """
+
+ x_open_router_categories: Annotated[
+ Optional[str],
+ pydantic.Field(alias="X-OpenRouter-Categories"),
+ FieldMetadata(header=HeaderMetadata(style="simple", explode=False)),
+ ] = None
+ r"""Comma-separated list of app categories (e.g. \"cli-agent,cloud-agent\"). Used for marketplace rankings.
+
+ """
+
+ @model_serializer(mode="wrap")
+ def serialize_model(self, handler):
+ optional_fields = set(
+ ["HTTP-Referer", "X-OpenRouter-Title", "X-OpenRouter-Categories"]
+ )
+ serialized = handler(self)
+ m = {}
+
+ for n, f in type(self).model_fields.items():
+ k = f.alias or n
+ val = serialized.get(k, serialized.get(n))
+
+ if val != UNSET_SENTINEL:
+ if val is not None or k not in optional_fields:
+ m[k] = val
+
+ return m
diff --git a/uv.lock b/uv.lock
index 4ae6a0b0..77de9d5d 100644
--- a/uv.lock
+++ b/uv.lock
@@ -231,7 +231,7 @@ wheels = [
[[package]]
name = "openrouter"
-version = "1.3.97"
+version = "1.3.98"
source = { editable = "." }
dependencies = [
{ name = "httpcore" },