From c6d389aa63d33e9cd9f465d865137e27fedd6e11 Mon Sep 17 00:00:00 2001 From: speakeasybot Date: Tue, 29 Sep 2026 22:12:42 +0000 Subject: [PATCH 1/3] ## Go SDK Changes: * `OpenRouter.Tools.ListTools()`: **Added** * `OpenRouter.Tools.GetTool()`: **Added** --- .speakeasy/gen.lock | 262 +++++++- .speakeasy/gen.yaml | 2 +- .speakeasy/out.openapi.yaml | 501 ++++++++++++++ .speakeasy/workflow.lock | 10 +- README.md | 5 + RELEASES.md | 12 +- chat.go | 14 + docs/models/components/byok.mdx | 27 + docs/models/components/dataregion.mdx | 27 - .../components/generationresponsedata.mdx | 2 +- .../generationresponsedataregion.mdx | 27 + docs/models/components/gettoolresponse.mdx | 9 + docs/models/components/listtoolsresponse.mdx | 11 + .../components/listtoolsresponselinks.mdx | 9 + docs/models/components/modelslistresponse.mdx | 2 +- ...{links.mdx => modelslistresponselinks.mdx} | 2 +- docs/models/components/nativesupport.mdx | 14 + docs/models/components/pricingsource.mdx | 28 + docs/models/components/servertool.mdx | 23 + docs/models/components/servertooldetails.mdx | 23 + .../components/servertooldetailsstatus.mdx | 24 + .../servertooldetailssupportedapiformat.mdx | 25 + docs/models/components/servertoolengine.mdx | 17 + .../components/servertoolenginedataregion.mdx | 25 + .../components/servertoolexecutedby.mdx | 27 + .../models/components/servertoolinputname.mdx | 11 + .../servertoolinputnameapiformat.mdx | 25 + .../components/servertoolnativemodel.mdx | 10 + .../components/servertoolnativesupport.mdx | 13 + .../components/servertooloutputname.mdx | 11 + .../servertooloutputnameapiformat.mdx | 25 + docs/models/components/servertoolprice.mdx | 12 + docs/models/components/servertoolstatus.mdx | 24 + .../servertoolsupportedapiformat.mdx | 25 + docs/models/operations/apiformat.mdx | 27 + docs/models/operations/gettoolrequest.mdx | 9 + docs/models/operations/gettoolresponse.mdx | 10 + docs/models/operations/gettoolsecurity.mdx | 9 + docs/models/operations/listtoolsrequest.mdx | 11 + docs/models/operations/listtoolssecurity.mdx | 9 + docs/sdks/tools/README.mdx | 130 ++++ models/components/generationresponse.go | 20 +- models/components/gettoolresponse.go | 14 + models/components/listtoolsresponse.go | 43 ++ models/components/modelslistresponse.go | 16 +- models/components/servertool.go | 181 +++++ models/components/servertooldetails.go | 209 ++++++ models/components/servertoolengine.go | 158 +++++ models/components/servertoolexecutedby.go | 27 + models/components/servertoolinputname.go | 55 ++ models/components/servertoolnativemodel.go | 22 + models/components/servertoolnativesupport.go | 23 + models/components/servertooloutputname.go | 55 ++ models/components/servertoolprice.go | 40 ++ models/operations/gettool.go | 61 ++ models/operations/listtools.go | 84 +++ openrouter.go | 21 +- tools.go | 632 ++++++++++++++++++ 58 files changed, 3066 insertions(+), 84 deletions(-) create mode 100644 docs/models/components/byok.mdx delete mode 100644 docs/models/components/dataregion.mdx create mode 100644 docs/models/components/generationresponsedataregion.mdx create mode 100644 docs/models/components/gettoolresponse.mdx create mode 100644 docs/models/components/listtoolsresponse.mdx create mode 100644 docs/models/components/listtoolsresponselinks.mdx rename docs/models/components/{links.mdx => modelslistresponselinks.mdx} (97%) create mode 100644 docs/models/components/nativesupport.mdx create mode 100644 docs/models/components/pricingsource.mdx create mode 100644 docs/models/components/servertool.mdx create mode 100644 docs/models/components/servertooldetails.mdx create mode 100644 docs/models/components/servertooldetailsstatus.mdx create mode 100644 docs/models/components/servertooldetailssupportedapiformat.mdx create mode 100644 docs/models/components/servertoolengine.mdx create mode 100644 docs/models/components/servertoolenginedataregion.mdx create mode 100644 docs/models/components/servertoolexecutedby.mdx create mode 100644 docs/models/components/servertoolinputname.mdx create mode 100644 docs/models/components/servertoolinputnameapiformat.mdx create mode 100644 docs/models/components/servertoolnativemodel.mdx create mode 100644 docs/models/components/servertoolnativesupport.mdx create mode 100644 docs/models/components/servertooloutputname.mdx create mode 100644 docs/models/components/servertooloutputnameapiformat.mdx create mode 100644 docs/models/components/servertoolprice.mdx create mode 100644 docs/models/components/servertoolstatus.mdx create mode 100644 docs/models/components/servertoolsupportedapiformat.mdx create mode 100644 docs/models/operations/apiformat.mdx create mode 100644 docs/models/operations/gettoolrequest.mdx create mode 100644 docs/models/operations/gettoolresponse.mdx create mode 100644 docs/models/operations/gettoolsecurity.mdx create mode 100644 docs/models/operations/listtoolsrequest.mdx create mode 100644 docs/models/operations/listtoolssecurity.mdx create mode 100644 docs/sdks/tools/README.mdx create mode 100644 models/components/gettoolresponse.go create mode 100644 models/components/listtoolsresponse.go create mode 100644 models/components/servertool.go create mode 100644 models/components/servertooldetails.go create mode 100644 models/components/servertoolengine.go create mode 100644 models/components/servertoolexecutedby.go create mode 100644 models/components/servertoolinputname.go create mode 100644 models/components/servertoolnativemodel.go create mode 100644 models/components/servertoolnativesupport.go create mode 100644 models/components/servertooloutputname.go create mode 100644 models/components/servertoolprice.go create mode 100644 models/operations/gettool.go create mode 100644 models/operations/listtools.go create mode 100644 tools.go diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 34ad2cb81..433467b15 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,18 +1,18 @@ lockVersion: 2.0.0 id: 9eea3e30-2722-4060-973b-57b7f1f75dc0 management: - docChecksum: caf05e10ee0693a1cd785ea6e5b05922 + docChecksum: f6287b44eec441ca9cbf10af1348f07e docVersion: 1.0.0 speakeasyVersion: 1.787.0 generationVersion: 2.914.0 - releaseVersion: 0.9.7 - configChecksum: c30b9960e0a1b148adbff09ac87bfbc4 + releaseVersion: 0.9.8 + configChecksum: bfcebb1c4851823b945f667a6850f7b8 repoURL: https://github.com/OpenRouterTeam/go-sdk.git installationURL: https://github.com/OpenRouterTeam/go-sdk persistentEdits: - generation_id: f1484579-717c-4f1b-8f7d-560b9fd6191e - pristine_commit_hash: 559df721273b33f017ea7185430214eac1e43efc - pristine_tree_hash: 6c47857cc5085c74c96431408926e2be492e95cb + generation_id: 296c36d4-1b9c-4cb1-8686-ecdad7684599 + pristine_commit_hash: 587aa4716843881bc29e0a2067a0f71e8870ff92 + pristine_tree_hash: 63e694cfcf5ab707e1dd72787004f73f147fc19b features: go: acceptHeaders: 2.81.2 @@ -105,8 +105,8 @@ trackedFiles: pristine_git_object: 300f5ee15b73e7ecfd6b16e25d132ad1e4af8442 chat.go: id: 81535ccb3ff5 - last_write_checksum: sha1:3fe05c99a2a3f927bac689dc6dd9f0e6c51bc7b3 - pristine_git_object: fedc9b46b5d2a7a4fc521b1af68b563cf4e116d8 + last_write_checksum: sha1:bf12b147b40656ae0086e01601410f01ae94e039 + pristine_git_object: 3ec067932ab585739098c417f40010f895bed95e classifications.go: id: 711367120ab6 last_write_checksum: sha1:1503d324707d56ecefdc2ec29ada40857bbff956 @@ -1631,6 +1631,10 @@ trackedFiles: id: 4ef94be56e86 last_write_checksum: sha1:750d335bdcc4a126bdbc92d1803b4727c9ac3285 pristine_git_object: 34054994358106abdfdd3125f477e7cb77446b6a + docs/models/components/byok.mdx: + id: f3f5960e0c62 + last_write_checksum: sha1:75caa7dd0d2e9f10f4b9481b42cc6ea27f79a02f + pristine_git_object: a9c9c12ce66a7d513c3d1fe0d6ccd2a0bf720c54 docs/models/components/byokkey.mdx: id: a689c50ba543 last_write_checksum: sha1:5f7f62348666b2faf78e0507df8608c2f88ebe43 @@ -2615,10 +2619,6 @@ trackedFiles: id: e3f31dc301c8 last_write_checksum: sha1:d425a24084172e4ab170debeab693524f37aaefe pristine_git_object: ec1493a3e06c92e1c5c6e0f63e867eb5a1b62000 - docs/models/components/dataregion.mdx: - id: ceeff1d642eb - last_write_checksum: sha1:045e52ca4a676f9724f4877ae98ba13b02575db5 - pristine_git_object: 93e02e0d13605bef5d0d3f9095418912a0ae4c86 docs/models/components/datetimeservertool.mdx: id: 13a5b7aef81b last_write_checksum: sha1:6cfffd3acf18be661e656c096b55a683aa8692df @@ -3289,8 +3289,12 @@ trackedFiles: pristine_git_object: 11f8aa4d512973530d1e1e1faa5dc9d41f9cf807 docs/models/components/generationresponsedata.mdx: id: a263f499e0b9 - last_write_checksum: sha1:16486084ec76d7362c67f827194c9dc24cfef22b - pristine_git_object: 652848596e16c8f15a75579947edf8c6f6710b51 + last_write_checksum: sha1:67ac89573fede5da11a3a36140b06094a54f8df4 + pristine_git_object: d1c9630b0b651e5e4329680d1464523cddb17ae9 + docs/models/components/generationresponsedataregion.mdx: + id: 35fc9233928d + last_write_checksum: sha1:297ddc32e91e67a3a45b5e0d8bb98ba4ab5c97c0 + pristine_git_object: 97fb1f9cf3a77654d4047fdf03e7fc7fa12710b6 docs/models/components/getbyokkeyresponse.mdx: id: 89b1af960b4c last_write_checksum: sha1:e15c043cd2f11ddbbec2a5604927f2a6e1d163a5 @@ -3319,6 +3323,10 @@ trackedFiles: id: 8f17f3f06379 last_write_checksum: sha1:cbd7266a308b0564a9370c719a9fbcbfc2a37672 pristine_git_object: 08b956297d8c3080db0fca1dc750637a775b730b + docs/models/components/gettoolresponse.mdx: + id: 38e99b1f9d29 + last_write_checksum: sha1:ec3ec805d95d3a511b841a907e975e3a54987dfa + pristine_git_object: 2d4e098d79943c9029540e1a1238c49f82f6f327 docs/models/components/getworkspacebudgetresponse.mdx: id: 2b81bc5e9bbc last_write_checksum: sha1:68459beeb3d74216aa4209c9d50ccd1ca09957ff @@ -4067,10 +4075,6 @@ trackedFiles: id: a4b33069df62 last_write_checksum: sha1:21bfc9f86084b6841a2593b35d1ee79184d98541 pristine_git_object: 62c0f324f0654aeb1a1fdd7afb561040904de531 - docs/models/components/links.mdx: - id: 335cc2d580ea - last_write_checksum: sha1:babf9cf18a407ed3f38e85683ee084298a459823 - pristine_git_object: d002dbe50034a20868b84c3c978bd07b99fa9fd2 docs/models/components/listbyokkeysresponse.mdx: id: 643df9cf4181 last_write_checksum: sha1:534135f6551dc101e678ce154fa018275b710a0e @@ -4115,6 +4119,14 @@ trackedFiles: id: 8a5350c708ed last_write_checksum: sha1:d936e6dac6a03301e6624322bcd243920f429ae0 pristine_git_object: 003a65257b988c39458ca8e7604a03f69ff36519 + docs/models/components/listtoolsresponse.mdx: + id: ca9343ce4fff + last_write_checksum: sha1:c2efbe4222c3c2de913267bb613ee08d89061d0f + pristine_git_object: d420c9693464bc05f6d0ef28f66b34d203df5896 + docs/models/components/listtoolsresponselinks.mdx: + id: f788c04ff146 + last_write_checksum: sha1:02d2d4ed806b6e8204cfdbd80d33523728920dd0 + pristine_git_object: 20891cf29eb577bf164fa04bfdb0033c89cbe9f4 docs/models/components/listworkspacebudgetsresponse.mdx: id: 888d0cd446fd last_write_checksum: sha1:928739926d688c79a7c4a336f38cd6525a444402 @@ -4537,8 +4549,12 @@ trackedFiles: pristine_git_object: 42e60f32c3a6ce0a54fa0f0b508ea9a6a9db9a17 docs/models/components/modelslistresponse.mdx: id: 626241479d1d - last_write_checksum: sha1:131226941bad9bd3f97a00bd854c720499f799a1 - pristine_git_object: 65083cbaa69a0d0a889dfc3a64978ca5919956c5 + last_write_checksum: sha1:8cff48baa868b83a867cb8c699d4860f26f58d07 + pristine_git_object: ef5d7e350878d13794736a27b6b6648e3e24ee9b + docs/models/components/modelslistresponselinks.mdx: + id: bd31ed630d76 + last_write_checksum: sha1:8cbc5cb88ef37203dcbb7fa7666f5a897cfd046a + pristine_git_object: 3e5dbd139b3d2a0ff03f805eb176adffe1c0a1f1 docs/models/components/moderation.mdx: id: 915c30853d58 last_write_checksum: sha1:649fa06172133c010b184c59f82ae9f53552dc0e @@ -4599,6 +4615,10 @@ trackedFiles: id: 36b32810b1a6 last_write_checksum: sha1:5016e1735735518c5f74a05f22ff6e30bc2b1dfa pristine_git_object: b2b31df11731a73f724da5909216592f05c812a2 + docs/models/components/nativesupport.mdx: + id: 64e0e73e349f + last_write_checksum: sha1:389f5c0384904750814ce9618c091d861c665cbd + pristine_git_object: 712f26a7bf0d6e3a472eb2d3df18dfef16096751 docs/models/components/nativetools.mdx: id: c694d17d85f4 last_write_checksum: sha1:7628c27be35dc1d45b2bd2c45eaab791f9a66092 @@ -5827,6 +5847,10 @@ trackedFiles: id: 6352e897cc34 last_write_checksum: sha1:a9e48dbd46aeba446d8f0ff8f73bb6c1169d299a pristine_git_object: 081646d353a2dea7841d79363cb42f41425299b5 + docs/models/components/pricingsource.mdx: + id: 3e93d5fe8ca6 + last_write_checksum: sha1:0e8c93827c591fb2f5d888d871e7dc813c1ce076 + pristine_git_object: 803ad42e0d994d2947f99233cca72be7acee4c69 docs/models/components/primarymetric.mdx: id: 9a70273779ff last_write_checksum: sha1:c96c2382cec197baa47ab50364a7d06c9819196a @@ -6359,6 +6383,70 @@ trackedFiles: id: a95db74ad7a7 last_write_checksum: sha1:402c1b5a7c491fbdfbb5ff59cf469d739e4d8bc1 pristine_git_object: 8015ad3c4c87db9cdeb9b37bad4e1d64e1d820da + docs/models/components/servertool.mdx: + id: 92227db4a329 + last_write_checksum: sha1:24032c944fd9fa0439d52785eb78ec4c6e071d79 + pristine_git_object: 1728fb9881fc02707199dae3d75c61420555ef63 + docs/models/components/servertooldetails.mdx: + id: d7c636401a4f + last_write_checksum: sha1:d6aedd112e0b88eca72b4ccbfa38af871a4f33bc + pristine_git_object: 57eccdd99e645b78e5a0485551f8f78f689a090e + docs/models/components/servertooldetailsstatus.mdx: + id: a587a9d345f0 + last_write_checksum: sha1:f9d65cd17dd3e4435bdfcb2f29ecb18c5a33f848 + pristine_git_object: 01d76b51f7b19690e4180bb99051e6f3d104b864 + docs/models/components/servertooldetailssupportedapiformat.mdx: + id: 54e722af5878 + last_write_checksum: sha1:2f2a46920c72f2cf9c56fc33c2dc4ac94e73fce3 + pristine_git_object: 398c2874f77ceaca5a3d2ad8eac03bd46af7d244 + docs/models/components/servertoolengine.mdx: + id: d5f1752eaf4d + last_write_checksum: sha1:f89bed6da1096f2f796e7435216cf97d7f597927 + pristine_git_object: 153d0301a80d5dd7eaae6ebd415074b376b50e4d + docs/models/components/servertoolenginedataregion.mdx: + id: 908a40dcc434 + last_write_checksum: sha1:39a5c10375c06564cd200035521a11d1cfd06d8f + pristine_git_object: 7ed9cbebe3e23ee133eb1b3d95a388a78ff680ee + docs/models/components/servertoolexecutedby.mdx: + id: 8108acf14a0e + last_write_checksum: sha1:9f7acfcb1c986c69a59085aab26135ece70e3c0d + pristine_git_object: 90b2232a2df48ea173a0aa155671b143a070142c + docs/models/components/servertoolinputname.mdx: + id: 2204875efeb1 + last_write_checksum: sha1:01b97b12a45dcfbe6bb9e5392f0f184ed2f3dcb8 + pristine_git_object: 0092ef47e4c35b857cee9752e90731f1dc3e5e29 + docs/models/components/servertoolinputnameapiformat.mdx: + id: 2ea9959fa4c3 + last_write_checksum: sha1:f27be2e62a321b5e7601805e6961376f39ee6bac + pristine_git_object: 887e36267e7860984c396367dfef2822ccc898b9 + docs/models/components/servertoolnativemodel.mdx: + id: 54944551ecaf + last_write_checksum: sha1:5ddf86ca46ca5720940bff27bc800423a77371a4 + pristine_git_object: d1184a9aeb8881c85ac6955d09124f3ab9fd00db + docs/models/components/servertoolnativesupport.mdx: + id: dd3cf40a26a1 + last_write_checksum: sha1:1b057b3201d48eccc954374d74651aafa2f9a922 + pristine_git_object: a99eb2c601e13784577038fbc81cb3186777ff3b + docs/models/components/servertooloutputname.mdx: + id: 6363f90ba330 + last_write_checksum: sha1:5c5de29b9950745e804869e2434bab21fcd91d21 + pristine_git_object: 91081a7efd74fe32dabe7ce3e22daf4ffb9e83ed + docs/models/components/servertooloutputnameapiformat.mdx: + id: 3825f556ef95 + last_write_checksum: sha1:4b05dc58354848934093ef34517d6d9b247186c7 + pristine_git_object: 499304a1c981dba94d0cdac132d1d7e381ab0509 + docs/models/components/servertoolprice.mdx: + id: 741772e466fc + last_write_checksum: sha1:c21a987b0ac69edb782e823ceaf6cf741f6e5d3a + pristine_git_object: 1a81fcea2da68d07d8c19b5817bd4004e4e540d3 + docs/models/components/servertoolstatus.mdx: + id: a2f553a750c5 + last_write_checksum: sha1:e68ae454b23db7caf9c9563b72d4d71234b36e9a + pristine_git_object: a11a690e7e35e81bd07d4cc18608bfecc5c7258d + docs/models/components/servertoolsupportedapiformat.mdx: + id: 3211e2f9205b + last_write_checksum: sha1:5f27cfd64aae54ebce32d13c979890fe066ea8ec + pristine_git_object: a3cd75224d6bf9a94280990f5429e441d36f0e8f docs/models/components/servertoolusedetails.mdx: id: 3a7263bc987f last_write_checksum: sha1:9d33ca53cec78aeb6c7dfab37f7429986cc7836c @@ -7555,6 +7643,10 @@ trackedFiles: id: 149c27f32b70 last_write_checksum: sha1:460ee17bb1be5ce200b98c1f235efd6dc25ac18a pristine_git_object: 2c5e4e35bfc15a8033b6262bef1c7a236fa23661 + docs/models/operations/apiformat.mdx: + id: 7ca6f151cc13 + last_write_checksum: sha1:bf98e783394098d548845d65020b4633a302638f + pristine_git_object: 364cb969980b701ce12b70945e3c772e192fd298 docs/models/operations/arena.mdx: id: b411a7021bf4 last_write_checksum: sha1:729c7b705eb4bdaa8d14764d004bd9f571e2d889 @@ -8039,6 +8131,18 @@ trackedFiles: id: 798b3d7c2623 last_write_checksum: sha1:52895edaf43251a6ff3c53ee5d0a810250ccb0f8 pristine_git_object: a80174e6920bef239b91dc2daa19052e152c95a5 + docs/models/operations/gettoolrequest.mdx: + id: d8325ac6bd5d + last_write_checksum: sha1:dbcb247cbfb684438a14411a00a42c27c295b284 + pristine_git_object: 3fafe4f614aee59581c4873ab1b26967a6ff4c97 + docs/models/operations/gettoolresponse.mdx: + id: cb12da37e876 + last_write_checksum: sha1:b1ea316ae78ea57a567a74b96bc3ef5f4c5edbe9 + pristine_git_object: 1fa45c0b5fa75e44508cb5bd2eda1d1bb0414b6c + docs/models/operations/gettoolsecurity.mdx: + id: d91c16fd247e + last_write_checksum: sha1:1a238f51f3ed5a4b6847060bab05a5e42095c926 + pristine_git_object: 95a591f909030ade5756de08a0445fe3774b40c6 docs/models/operations/getuseractivityrequest.mdx: id: b7abe086a57c last_write_checksum: sha1:9c7abddef0b068917da208be0ca04c46baf0ddbe @@ -8303,6 +8407,14 @@ trackedFiles: id: 061ed874493a last_write_checksum: sha1:53d49ae6d78d0b1e7b324b8c6c0d50182854f239 pristine_git_object: 95eac2366da17c8a9765a19633a0a3d914250051 + docs/models/operations/listtoolsrequest.mdx: + id: 4cd9c8d395ad + last_write_checksum: sha1:a9d09d5d7cf59f1cd5337d6dc7d5a6e331bff1ae + pristine_git_object: aea2db8b1a1466780303256360a1bd1a27cc55f0 + docs/models/operations/listtoolssecurity.mdx: + id: c10a0d9fd934 + last_write_checksum: sha1:7d7d293dcbb8c523fb35d6648a17404d554aeb46 + pristine_git_object: 5047967a3eab07c16cd19b90c649cec8ce620aaa docs/models/operations/listvaultsecretsrequest.mdx: id: d4bec5cda3fd last_write_checksum: sha1:73ad86484eeda90f4bb60693c0be8b581047ef0c @@ -8823,6 +8935,10 @@ trackedFiles: id: 55c317c71f3d last_write_checksum: sha1:739b8fba36aac7167efff65e0af7a881e41b09ce pristine_git_object: cd471b881e9ce02ac2a08fcb0ce564fee15383f9 + docs/sdks/tools/README.mdx: + id: 32d2a83beeba + last_write_checksum: sha1:ee52046cd043b7437e2f017512bd98b426417f98 + pristine_git_object: 5edb3770d14279e365c5533b82137011aff5c013 docs/sdks/tts/README.mdx: id: cd1132543884 last_write_checksum: sha1:c475d1fb3062b103be5c84f6ba06c8559d926662 @@ -10297,8 +10413,8 @@ trackedFiles: pristine_git_object: 9fa4e66f1b9e1a0882870f2633e90ffec3e2f698 models/components/generationresponse.go: id: 89ce21b091ac - last_write_checksum: sha1:96e8c0c39d1db71e446bd7129da6ff645152b75a - pristine_git_object: a6faf9411794f4ae55fbaea67ac735f08c437445 + last_write_checksum: sha1:f5000a8503fe986c86582d46d213814bae730aa6 + pristine_git_object: f34c6cd2dab6521154427fedf6e6403c73d5b7b5 models/components/getbyokkeyresponse.go: id: 7a2bc074b2e0 last_write_checksum: sha1:2c730a305b0f4628e664405f1a4f9e23a2285cf4 @@ -10327,6 +10443,10 @@ trackedFiles: id: df8beabac43c last_write_checksum: sha1:af1e7c390e3ca3cc9a95a7485b695214007db386 pristine_git_object: 2191c8f1e9829bd8bae28a4f3f641133ba154f72 + models/components/gettoolresponse.go: + id: 20510cedb211 + last_write_checksum: sha1:3626682feef0bbf8995e2d88a2bb80c14f3ed065 + pristine_git_object: 298c18ed83d05b19c20bcfd1e8e6bcc34c28f748 models/components/getworkspacebudgetresponse.go: id: ac241afa5c0b last_write_checksum: sha1:ffcf50d12a77c7e6d9c2eae7c255266bd8829ad7 @@ -10695,6 +10815,10 @@ trackedFiles: id: 69fcc6e29f34 last_write_checksum: sha1:24b32dd6445f85055ce791b3402219d007a8bc7c pristine_git_object: b7c0e85423aaacbf6089b2f3bb0cf51546fabb61 + models/components/listtoolsresponse.go: + id: a02287eb4c03 + last_write_checksum: sha1:941ffb5325a6ff1329f9c34256a729dd8576beb6 + pristine_git_object: dc5386a12a27354c35ead95e403f833877df064b models/components/listworkspacebudgetsresponse.go: id: 5c4fb3fd8183 last_write_checksum: sha1:05c74026a05f818dafad049f32e8c772f3b7c843 @@ -10845,8 +10969,8 @@ trackedFiles: pristine_git_object: 1fb3fb4b7f70edcdee06284e9a805828529fec53 models/components/modelslistresponse.go: id: f0bab5dbbb23 - last_write_checksum: sha1:26d26a956ea5cb0c777764f403387ecf71dac4a1 - pristine_git_object: 5ff4902824044b07a68a8064e646071e41316a07 + last_write_checksum: sha1:c863a877729d1d833b6425fd72450d0f747c7451 + pristine_git_object: 294a5c217d102961cd6a0f6b56f1c59244346191 models/components/moderationplugin.go: id: 264d90fc7675 last_write_checksum: sha1:eb03ee7cce228ccacd0cd63a3def3802e921455f @@ -11591,6 +11715,42 @@ trackedFiles: id: 3a5eba5fe9e0 last_write_checksum: sha1:ba147a49efdcf0ada3f56c0bde50f3ec8ec4473e pristine_git_object: 0b3f6896eb279a78025db42c60b7ed4be491dab2 + models/components/servertool.go: + id: d51a58238b9c + last_write_checksum: sha1:51447c241c8bb384648d0d26c9d549f7d4e1a643 + pristine_git_object: 3b6317f358d808b3a1404394c057c8e4c21db626 + models/components/servertooldetails.go: + id: 954cc878c896 + last_write_checksum: sha1:91727350abdeaf8a399df297ff5b9efaab261582 + pristine_git_object: e0dc1355ceed9aacc568e56fe33ab3c4f47fb5e2 + models/components/servertoolengine.go: + id: f8efceafb524 + last_write_checksum: sha1:c69600bd2b33745af427263e775272b002aaf1fc + pristine_git_object: 58f6590565830eb38047407ee1a9b84a012a7bdd + models/components/servertoolexecutedby.go: + id: 71076dd1aa2a + last_write_checksum: sha1:7123d5d8074182dfaada1972af4c14e24e5da9c5 + pristine_git_object: 149bc438743ee05f6c549d3ab3cf126167e64987 + models/components/servertoolinputname.go: + id: a9fe8d1f3f7f + last_write_checksum: sha1:ff50d45a064a59fef42013c4ac4631ede3bfdebb + pristine_git_object: fc4a6adecf1019a2e4e6a95aaadb2f1920b5ae37 + models/components/servertoolnativemodel.go: + id: f09edbf58bb4 + last_write_checksum: sha1:f3a6f2692c40d7351ac7de815c3780b0e1f1f225 + pristine_git_object: 4a1f9b1b7f7f282af40e781b425c968cc7c1bd89 + models/components/servertoolnativesupport.go: + id: 8384f9aee7e2 + last_write_checksum: sha1:8f1d292a71b99893ed48c16d73811f562267ee22 + pristine_git_object: aa591180474659996706618348d80f06e63132df + models/components/servertooloutputname.go: + id: d64d24628958 + last_write_checksum: sha1:9b06d611d41be22cfb58a353c24277e1649a7b53 + pristine_git_object: 8f6546092a0cb997d74502561d331598cc1043d4 + models/components/servertoolprice.go: + id: 0883abc1e399 + last_write_checksum: sha1:b85f7d423247c2f53c948385e500302c5f177e07 + pristine_git_object: 0a8d8940f025c342edc55c7d0960a40413c25023 models/components/servertoolusedetails.go: id: ed0a944e6b72 last_write_checksum: sha1:162ef7aa260968358fda8b044065bcf223a3198a @@ -12407,6 +12567,10 @@ trackedFiles: id: 17d586566d2c last_write_checksum: sha1:809778acd86893bb476c38687234dc600ec0f03d pristine_git_object: 623ea9514d2e2fdabe284ca185447fe47bb84daf + models/operations/gettool.go: + id: ffaddb7f817a + last_write_checksum: sha1:53f470cad0a5797d7736160679aff676b73b750e + pristine_git_object: c558c0232302a597d241a00000673b20f265aa1d models/operations/getuseractivity.go: id: 8a5bc3bac8e8 last_write_checksum: sha1:94e34765444d1d7f2dbc9f48b8baa2f0f6bfad4b @@ -12535,6 +12699,10 @@ trackedFiles: id: 75cbce5df5cc last_write_checksum: sha1:1ac32f0f37ae0e89ace90d8acce60c2cb6ffe35c pristine_git_object: d23168fbe3d842e9c7b44d1bff5d2d7d404d026b + models/operations/listtools.go: + id: 20febb8aa906 + last_write_checksum: sha1:88db826b3ceb8423ee0e71a1bbd453ed2cc1df69 + pristine_git_object: 09b94db27fd1b5ffbafc2deffc8b312f097c7884 models/operations/listvaultsecrets.go: id: 0b6e1fecab0f last_write_checksum: sha1:98527a92bbe02efee5cce8fa9279a7db7a93032c @@ -12745,8 +12913,8 @@ trackedFiles: pristine_git_object: 5e3a2cdf8cb4ed4f5378b712293cba9c82074f16 openrouter.go: id: 207ad004b774 - last_write_checksum: sha1:e29b6498ff14c0064b63c87af71c81b36aeac386 - pristine_git_object: 74fad63db31256cc18708935c803d8bec3bd136e + last_write_checksum: sha1:b850529c36cacc083c65d841d8abd21bc594f8b0 + pristine_git_object: ef00634cbed3b5a1c57fa2950a862eff826e6781 optionalnullable/optionalnullable.go: id: ce60f259ead3 last_write_checksum: sha1:d6aff1a420c31e025ea21d46cf056e305ae76fe8 @@ -12795,6 +12963,10 @@ trackedFiles: id: 846025a374ee last_write_checksum: sha1:d56a96069b2a07be61c0dd4458005639b9e8b588 pristine_git_object: 5e49d441bf9c6b866c0bc5c84e12927f1da33348 + tools.go: + id: 3387d70491f4 + last_write_checksum: sha1:84a278d91c2b126bc30ffdd1148d080ba8ae2e30 + pristine_git_object: 34e98085ac93fbd3782da8486a6a0e00b483e25d tts.go: id: 9feb76579e2d last_write_checksum: sha1:733e0079c2e46ba7d5f90b4f89a7c4ed3a636513 @@ -16592,5 +16764,41 @@ examples: responses: "504": application/json: {"error": {"code": 504, "message": "Vault request timed out"}} + listTools: + speakeasy-default-list-tools: + parameters: + query: + offset: 0 + limit: 50 + responses: + "200": + application/json: {"data": [], "links": {"next": null}, "total_count": 12} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} + getTool: + speakeasy-default-get-tool: + parameters: + path: + name: "openrouter:web_search" + responses: + "200": + application/json: {"data": {"aliases": [], "default_engine": "native", "docs_url": "https://mad-skyline.info/", "engines": [{"byok": "none", "data_regions": ["global", "us"], "default_mode": "auto", "executed_by": "openrouter", "id": "exa", "name": "Exa", "pricing": [], "pricing_doc_url": null, "pricing_source": "openrouter"}], "fallback_engine": "exa", "id": "openrouter:web_search", "input_schema": {"properties": {}, "type": "object"}, "name": "Web search", "native_support": {"endpoint_count": 18, "model_count": 12, "models": []}, "output_schema": {"properties": {}, "type": "object"}, "parameters_schema": {"properties": {}, "type": "object"}, "status": "active", "summary": "", "supported_api_formats": [], "tool_description": ""}} + "401": + application/json: {"error": {"code": 401, "message": "Missing Authentication header"}} + "403": + application/json: {"error": {"code": 403, "message": "Only management keys can perform this operation"}} + "404": + application/json: {"error": {"code": 404, "message": "Resource not found"}} + "500": + application/json: {"error": {"code": 500, "message": "Internal Server Error"}} examplesVersion: 1.0.2 -releaseNotes: "## Go SDK Changes:\n* `OpenRouter.Chat.Send()`: \n * `request.ChatRequest.ServiceTier.Enum(ultrafast)` **Added**\n* `OpenRouter.Generations.GetGeneration()`: `response.Data.ProviderResponses[].RoutedServiceTier.Enum(ultrafast)` **Added**\n* `OpenRouter.Presets.CreatePresetsChatCompletions()`: \n * `request.ChatRequest.ServiceTier.Enum(ultrafast)` **Added**\n* `OpenRouter.Presets.CreatePresetsResponses()`: \n * `request.ResponsesRequest.ServiceTier.Enum(ultrafast)` **Added**\n* `OpenRouter.Responses.Send()`: \n * `request.ResponsesRequest.ServiceTier.Enum(ultrafast)` **Added**\n* `OpenRouter.Beta.Responses.Send()`: \n * `request.ResponsesRequest.ServiceTier.Enum(ultrafast)` **Added**\n" +releaseNotes: | + ## Go SDK Changes: + * `OpenRouter.Tools.ListTools()`: **Added** + * `OpenRouter.Tools.GetTool()`: **Added** diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index aca89a211..4b370045b 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -36,7 +36,7 @@ generation: documentation: mintlify preApplyUnionDiscriminators: true go: - version: 0.9.7 + version: 0.9.8 additionalDependencies: {} baseErrorName: OpenRouterError clientServerStatusCodesAsErrors: true diff --git a/.speakeasy/out.openapi.yaml b/.speakeasy/out.openapi.yaml index 874139e1e..032c13709 100644 --- a/.speakeasy/out.openapi.yaml +++ b/.speakeasy/out.openapi.yaml @@ -12442,6 +12442,13 @@ components: required: - 'data' type: 'object' + GetToolResponse: + properties: + data: + $ref: '#/components/schemas/ServerToolDetails' + required: + - 'data' + type: 'object' GetWorkspaceBudgetResponse: example: data: @@ -15503,6 +15510,32 @@ components: - 'data' - 'total_count' type: 'object' + ListToolsResponse: + properties: + data: + items: + $ref: '#/components/schemas/ServerTool' + type: 'array' + links: + properties: + next: + description: 'URL for the next page of results, or null if this is the last page' + example: null + type: + - 'string' + - 'null' + required: + - 'next' + type: 'object' + total_count: + description: 'Total number of tools' + example: 12 + type: 'integer' + required: + - 'data' + - 'total_count' + - 'links' + type: 'object' ListWorkspaceBudgetsResponse: example: data: @@ -27530,6 +27563,306 @@ components: example: 'medium' type: 'string' x-speakeasy-unknown-values: allow + ServerTool: + properties: + aliases: + description: 'Every spelling accepted in `tools[].type` for this tool, including the canonical `id`, and what the call surfaces as under each' + items: + $ref: '#/components/schemas/ServerToolInputName' + type: 'array' + default_engine: + description: 'The engine a request without `parameters.engine` (or with `engine: "auto"`) runs on; `native` applies where the endpoint runs the tool itself, otherwise `fallback_engine`. A request pinned to a data region skips either engine when its `data_regions` does not list that region. Null for a tool without an engine parameter' + example: 'native' + type: + - 'string' + - 'null' + docs_url: + format: 'uri' + type: 'string' + engines: + items: + $ref: '#/components/schemas/ServerToolEngine' + type: 'array' + fallback_engine: + description: 'The engine an unpinned request runs on when `default_engine` is `native` and the endpoint does not run the tool itself; null when there is no fallback' + example: 'exa' + type: + - 'string' + - 'null' + id: + description: 'Canonical `openrouter:*` name; the stable `tools[].type` on every API format in `supported_api_formats`' + example: 'openrouter:web_search' + type: 'string' + input_schema: + additionalProperties: {} + description: 'JSON Schema of the arguments the model emits when calling the tool' + example: + properties: {} + type: 'object' + type: 'object' + name: + example: 'Web search' + type: 'string' + native_support: + $ref: '#/components/schemas/ServerToolNativeSupport' + output_schema: + additionalProperties: {} + description: 'JSON Schema of the result returned to the model; null when undeclared' + example: + properties: {} + type: 'object' + type: + - 'object' + - 'null' + parameters_schema: + additionalProperties: {} + description: 'JSON Schema for the caller-side `tools[].parameters` object' + example: + properties: {} + type: 'object' + type: 'object' + status: + enum: + - 'active' + - 'deprecated' + example: 'active' + type: 'string' + x-speakeasy-unknown-values: allow + summary: + description: 'One sentence for cards and search results; never sent to a model' + type: 'string' + supported_api_formats: + items: + enum: + - 'responses' + - 'chat-completions' + - 'anthropic-messages' + type: 'string' + x-speakeasy-unknown-values: allow + type: 'array' + tool_description: + description: 'The description sent upstream as the function tool description' + type: 'string' + required: + - 'id' + - 'name' + - 'summary' + - 'tool_description' + - 'status' + - 'docs_url' + - 'aliases' + - 'supported_api_formats' + - 'default_engine' + - 'fallback_engine' + - 'parameters_schema' + - 'input_schema' + - 'output_schema' + - 'engines' + - 'native_support' + type: 'object' + ServerToolDetails: + allOf: + - $ref: '#/components/schemas/ServerTool' + - properties: + native_support: + allOf: + - $ref: '#/components/schemas/ServerToolNativeSupport' + - properties: + models: + items: + $ref: '#/components/schemas/ServerToolNativeModel' + type: 'array' + required: + - 'models' + type: 'object' + description: 'Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively.' + example: + endpoint_count: 18 + model_count: 12 + type: 'object' + ServerToolEngine: + properties: + byok: + description: 'Whether the engine needs the caller''s own key, saved in plugin settings: `required` (OpenRouter holds none), `optional` (OpenRouter''s key is used unless the caller saved one), or `none`' + enum: + - 'required' + - 'optional' + - 'none' + example: 'none' + type: 'string' + x-speakeasy-unknown-values: allow + data_regions: + description: 'The data regions whose requests this engine serves without leaving the region. A request pinned to a region can only use engines that list it; `global` is always listed.' + example: + - 'global' + - 'us' + items: + enum: + - 'global' + - 'europe' + - 'us' + type: 'string' + x-speakeasy-unknown-values: allow + type: 'array' + default_mode: + description: 'The `parameters.mode` a request without one runs and bills as; null for engines without modes. The `pricing[]` row with this `mode` is what an unmoded request bills' + example: 'auto' + type: + - 'string' + - 'null' + executed_by: + $ref: '#/components/schemas/ServerToolExecutedBy' + id: + description: 'The `parameters.engine` value that selects this engine; null for the single engine of a tool without an engine parameter' + example: 'exa' + type: + - 'string' + - 'null' + name: + example: 'Exa' + type: 'string' + pricing: + description: 'The rows OpenRouter bills; non-empty exactly when `pricing_source` is `openrouter`' + items: + $ref: '#/components/schemas/ServerToolPrice' + type: 'array' + pricing_doc_url: + description: 'Where the rates are documented when `pricing_source` is `provider` or `byok`; null otherwise' + example: null + type: + - 'string' + - 'null' + pricing_source: + description: 'Who bills the engine''s calls beyond the model''s tokens: `openrouter` (the `pricing` rows, from the caller''s credits), `provider` (a per-call tool fee from the model''s provider on the inference call, at its own rates), `byok` (the engine''s vendor, against the caller''s own key), or `none` (no charge)' + enum: + - 'openrouter' + - 'provider' + - 'byok' + - 'none' + example: 'openrouter' + type: 'string' + x-speakeasy-unknown-values: allow + required: + - 'id' + - 'name' + - 'executed_by' + - 'data_regions' + - 'byok' + - 'default_mode' + - 'pricing_source' + - 'pricing_doc_url' + - 'pricing' + type: 'object' + ServerToolExecutedBy: + description: 'Who runs the tool call: the model provider during inference (`provider`), OpenRouter (`openrouter`), or the caller''s application after the call is returned (`client`).' + enum: + - 'provider' + - 'openrouter' + - 'client' + example: 'openrouter' + type: 'string' + x-speakeasy-unknown-values: allow + ServerToolInputName: + properties: + api_formats: + description: 'API formats that accept this spelling in `tools[].type`' + items: + enum: + - 'responses' + - 'chat-completions' + - 'anthropic-messages' + type: 'string' + x-speakeasy-unknown-values: allow + type: 'array' + output_names: + description: 'What the call surfaces as on each accepting API format when requested under this spelling; a format is absent when the call is not visible to the caller' + items: + $ref: '#/components/schemas/ServerToolOutputName' + type: 'array' + type: + example: 'web_search_20250305' + type: 'string' + required: + - 'type' + - 'api_formats' + - 'output_names' + type: 'object' + ServerToolNativeModel: + properties: + providers: + example: + - 'Anthropic' + - 'Google' + items: + type: 'string' + type: 'array' + slug: + example: 'anthropic/claude-4.5-sonnet' + type: 'string' + required: + - 'slug' + - 'providers' + type: 'object' + ServerToolNativeSupport: + description: 'Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively.' + example: + endpoint_count: 18 + model_count: 12 + properties: + endpoint_count: + example: 18 + type: 'integer' + model_count: + example: 12 + type: 'integer' + required: + - 'endpoint_count' + - 'model_count' + type: 'object' + ServerToolOutputName: + properties: + api_format: + enum: + - 'responses' + - 'chat-completions' + - 'anthropic-messages' + type: 'string' + x-speakeasy-unknown-values: allow + name: + description: 'Anthropic Messages `server_tool_use` block `name`, when the call surfaces as one' + example: 'web_search' + type: 'string' + type: + description: 'Output item `type` on Responses, content block `type` on Anthropic Messages, `reasoning_details[].type` on Chat Completions' + example: 'web_search_call' + type: 'string' + required: + - 'api_format' + - 'type' + type: 'object' + ServerToolPrice: + properties: + max_units_per_call: + type: 'integer' + mode: + description: 'The `parameters.mode` this price applies to; null for prices that do not depend on the mode. A request bills exactly one `request` row' + example: 'auto' + type: + - 'string' + - 'null' + price: + description: 'USD per unit, as a decimal string' + example: '0.007' + type: 'string' + unit: + example: 'request' + type: 'string' + required: + - 'mode' + - 'unit' + - 'price' + - 'max_units_per_call' + type: 'object' ServerToolUseDetails: description: 'Usage for server-side tool execution (e.g., web search)' example: @@ -48193,6 +48526,172 @@ paths: tags: - 'SystemOne' x-speakeasy-name-override: 'create' + /tools: + get: + description: 'Lists every server tool OpenRouter can run on behalf of a model: accepted `tools[].type` spellings per API format, the engines behind it with their pricing, and how many endpoints run it natively.' + operationId: 'listTools' + parameters: + - description: 'Number of records to skip for pagination. When both offset and limit are omitted, the full list is returned' + in: 'query' + name: 'offset' + required: false + schema: + default: 0 + description: 'Number of records to skip for pagination. When both offset and limit are omitted, the full list is returned' + example: 0 + minimum: 0 + type: + - 'integer' + - 'null' + - description: 'Maximum number of records to return (max 100). When both offset and limit are omitted, the full list is returned' + in: 'query' + name: 'limit' + required: false + schema: + default: 50 + description: 'Maximum number of records to return (max 100). When both offset and limit are omitted, the full list is returned' + example: 50 + maximum: 100 + minimum: 1 + type: 'integer' + - description: 'Only tools usable on this API format' + in: 'query' + name: 'api_format' + required: false + schema: + description: 'Only tools usable on this API format' + enum: + - 'responses' + - 'chat-completions' + - 'anthropic-messages' + example: 'responses' + type: 'string' + x-speakeasy-unknown-values: allow + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/ListToolsResponse' + description: 'The server tool catalog' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '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' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + security: + - bearer: [] + summary: 'List server tools' + tags: + - 'Tools' + /tools/{name}: + get: + description: 'One server tool by canonical name or any accepted alias, with the models that run it natively.' + operationId: 'getTool' + parameters: + - description: 'Canonical `openrouter:*` name or any accepted `tools[].type` alias' + in: 'path' + name: 'name' + required: true + schema: + description: 'Canonical `openrouter:*` name or any accepted `tools[].type` alias' + example: 'openrouter:web_search' + type: 'string' + responses: + '200': + content: + application/json: + schema: + $ref: '#/components/schemas/GetToolResponse' + description: 'The server tool' + '308': + description: 'An alias was given; `Location` is the canonical tool URL' + headers: + Location: + required: true + schema: + example: '/api/v1/tools/openrouter:web_search' + type: 'string' + '401': + content: + application/json: + example: + error: + code: 401 + message: 'Missing Authentication header' + schema: + $ref: '#/components/schemas/UnauthorizedResponse' + description: 'Unauthorized - Authentication required or invalid credentials' + '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' + '500': + content: + application/json: + example: + error: + code: 500 + message: 'Internal Server Error' + schema: + $ref: '#/components/schemas/InternalServerResponse' + description: 'Internal Server Error - Unexpected server error' + security: + - bearer: [] + summary: 'Get a server tool' + tags: + - 'Tools' /vault/interns/{internId}/effective-secrets: get: description: 'Lists, one entry per name, the secret the intern''s outbound requests receive: its own secrets, secrets from an attached vault, and workspace secrets, including ones stored before workspace-scoped storage. Where several vaults hold a name, the entry is the one that wins, in the order intern, attached, workspace. The same resolution decides what outbound requests receive, so this list and the intern''s requests agree. `scope` says which vault the entry comes from. Responses carry metadata only, never values. Results are ordered by name and paginated with `limit` and `offset`. Returns 404 when the intern''s attached vault is no longer available, since the intern then receives no secrets. The scope is selected by the API key: workspace routes act on the key''s active workspace and intern routes act on one intern inside that workspace. There is no default workspace and no fallback to another scope. Every vault route, including reads, requires access to the Intern API programme and returns 404 outside it. An intern''s own API key is confined to that intern: it can always read the intern''s secrets and effective secrets, writes to them follow the rules above, and every other intern and every workspace route answers 404. Requests on regional hostnames such as `eu.openrouter.ai` are refused. [API key](/docs/api-reference/authentication) required.' @@ -51332,6 +51831,8 @@ tags: - description: 'Text-to-speech endpoints' name: 'TTS' x-displayName: 'Speech' + - description: 'The catalog of server tools OpenRouter runs on behalf of a model: accepted `tools[].type` spellings per API format, engines and pricing, and which endpoints run each tool natively. See https://openrouter.ai/docs/guides/features/server-tools.' + name: 'Tools' - description: 'Store host-bound secrets for a workspace or for one intern. Scope is selected by the API key. Responses return metadata only, never secret values. See https://openrouter.ai/docs/guides/ori/vault.' name: 'Vault' - description: 'Video Generation endpoints' diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index b1d8b4c7c..8f0e708d8 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -2,8 +2,8 @@ speakeasyVersion: 1.787.0 sources: OpenRouter API: sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:eec283665f21145bba37304f988b94fcfe9ccfbfb8be06d5182fca4a544fa679 - sourceBlobDigest: sha256:c9ae53e96df2892197b7804c88e27de0b3fe6345d65e7dcb27feb04a0211f7b0 + sourceRevisionDigest: sha256:db2283c5cdc8d6469924f497c85210ea2ac9060b28c79fba996852a0926ab9ce + sourceBlobDigest: sha256:ba113aff532fbcc75a71f9dcf99d3b4e88c5dce39d7331f9e806a59d946b442a tags: - latest - 1.0.0 @@ -11,10 +11,10 @@ targets: openrouter: source: OpenRouter API sourceNamespace: open-router-chat-completions-api - sourceRevisionDigest: sha256:eec283665f21145bba37304f988b94fcfe9ccfbfb8be06d5182fca4a544fa679 - sourceBlobDigest: sha256:c9ae53e96df2892197b7804c88e27de0b3fe6345d65e7dcb27feb04a0211f7b0 + sourceRevisionDigest: sha256:db2283c5cdc8d6469924f497c85210ea2ac9060b28c79fba996852a0926ab9ce + sourceBlobDigest: sha256:ba113aff532fbcc75a71f9dcf99d3b4e88c5dce39d7331f9e806a59d946b442a codeSamplesNamespace: open-router-chat-completions-api-go-code-samples - codeSamplesRevisionDigest: sha256:c2b136d11da15f314ac9bb4bf9da240b0a7ee23ed1f4bd526e8c2692309cc1fd + codeSamplesRevisionDigest: sha256:22269985c136aa58cfea5c13f05342d3bb6db3db3acebac7bcd2da81f0f380e6 workflow: workflowVersion: 1.0.0 speakeasyVersion: 1.787.0 diff --git a/README.md b/README.md index b5e900a51..a4e3c0ebf 100644 --- a/README.md +++ b/README.md @@ -395,6 +395,11 @@ func main() { * [Create](docs/sdks/systemone/README.md#create) - Submit a System One request +### [Tools](docs/sdks/tools/README.md) + +* [ListTools](docs/sdks/tools/README.md#listtools) - List server tools +* [GetTool](docs/sdks/tools/README.md#gettool) - Get a server tool + ### [TTS](docs/sdks/tts/README.md) * [CreateSpeech](docs/sdks/tts/README.md#createspeech) - Create speech diff --git a/RELEASES.md b/RELEASES.md index b602595c8..7bcb0bc0b 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2588,4 +2588,14 @@ Based on: ### Generated - [go v0.9.7] . ### Releases -- [Go v0.9.7] https://github.com/OpenRouterTeam/go-sdk/releases/tag/v0.9.7 - . \ No newline at end of file +- [Go v0.9.7] https://github.com/OpenRouterTeam/go-sdk/releases/tag/v0.9.7 - . + +## 2026-09-29 22:07:44 +### Changes +Based on: +- OpenAPI Doc +- Speakeasy CLI 1.787.0 (2.914.0) https://github.com/speakeasy-api/speakeasy +### Generated +- [go v0.9.8] . +### Releases +- [Go v0.9.8] https://github.com/OpenRouterTeam/go-sdk/releases/tag/v0.9.8 - . \ No newline at end of file diff --git a/chat.go b/chat.go index fedc9b46b..3ec067932 100644 --- a/chat.go +++ b/chat.go @@ -18,6 +18,20 @@ import ( "net/url" ) +// Chat - Stream a chat completion with an intern +// Sends a prompt to one of your interns and streams the reply as OpenAI-compatible server-sent events ending with `[DONE]`. The run executes on the intern, which may pause to ask you something. It then streams one `openrouter.provide_input` tool call and finishes with `finish_reason: "tool_calls"`, and the run stays open on the intern. +// +// Every response, whether it ends with `stop`, `tool_calls` or `error`, is followed by a final chunk with empty `choices` that carries `session_id`, then `data: [DONE]`. That chunk carries the `usage` the intern reported for the run, after `stop` or `error`, and `null` when the intern reported none. After `tool_calls` its `usage` is `null` because the turn is not over. Read through `[DONE]`: the `session_id` you need to reply arrives after the `tool_calls` finish chunk. +// +// To answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline. +// +// Closing the connection after the `[DONE]` that follows `finish_reason: "tool_calls"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent. +// +// A run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: "error"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event. +// +// Set `approval_mode` to `manual` to have the intern ask before approval-bearing tools such as the shell. Omitted, the run self-drives and consents on your behalf. The mode belongs to the run started by that prompt and must be repeated on later prompts. +// +// Available to interns programme members. Callers outside the programme receive `404` for every path under `/api/v1/interns`. type Chat struct { rootSDK *OpenRouter sdkConfiguration config.SDKConfiguration diff --git a/docs/models/components/byok.mdx b/docs/models/components/byok.mdx new file mode 100644 index 000000000..a9c9c12ce --- /dev/null +++ b/docs/models/components/byok.mdx @@ -0,0 +1,27 @@ +--- +title: "BYOK" +--- + +Whether the engine needs the caller's own key, saved in plugin settings: `required` (OpenRouter holds none), `optional` (OpenRouter's key is used unless the caller saved one), or `none` + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.BYOKRequired + +// Open enum: custom values can be created with a direct type cast +custom := components.BYOK("custom_value") +``` + + +## Values + +| Name | Value | +| -------------- | -------------- | +| `BYOKRequired` | required | +| `BYOKOptional` | optional | +| `BYOKNone` | none | \ No newline at end of file diff --git a/docs/models/components/dataregion.mdx b/docs/models/components/dataregion.mdx deleted file mode 100644 index 93e02e0d1..000000000 --- a/docs/models/components/dataregion.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: "DataRegion" ---- - -The data region this generation was routed through: 'global', 'europe', or 'us'. - -## Example Usage - -```go -import ( - "github.com/OpenRouterTeam/go-sdk/models/components" -) - -value := components.DataRegionGlobal - -// Open enum: custom values can be created with a direct type cast -custom := components.DataRegion("custom_value") -``` - - -## Values - -| Name | Value | -| ------------------ | ------------------ | -| `DataRegionGlobal` | global | -| `DataRegionEurope` | europe | -| `DataRegionUs` | us | \ No newline at end of file diff --git a/docs/models/components/generationresponsedata.mdx b/docs/models/components/generationresponsedata.mdx index 652848596..d1c9630b0 100644 --- a/docs/models/components/generationresponsedata.mdx +++ b/docs/models/components/generationresponsedata.mdx @@ -14,7 +14,7 @@ Generation data | `CacheDiscount` | `*float64` | :heavy_check_mark: | Discount applied due to caching | 0.0002 | | `Cancelled` | `*bool` | :heavy_check_mark: | Whether the generation was cancelled | false | | `CreatedAt` | `string` | :heavy_check_mark: | ISO 8601 timestamp of when the generation was created | 2024-07-15T23:33:19.433273+00:00 | -| `DataRegion` | [components.DataRegion](../../models/components/dataregion.mdx) | :heavy_check_mark: | The data region this generation was routed through: 'global', 'europe', or 'us'. | global | +| `DataRegion` | [components.GenerationResponseDataRegion](../../models/components/generationresponsedataregion.mdx) | :heavy_check_mark: | The data region this generation was routed through: 'global', 'europe', or 'us'. | global | | `ExternalUser` | `*string` | :heavy_check_mark: | External user identifier | user-123 | | `FinishReason` | `*string` | :heavy_check_mark: | Reason the generation finished | stop | | `GenerationTime` | `*float64` | :heavy_check_mark: | Time taken for generation in milliseconds | 1200 | diff --git a/docs/models/components/generationresponsedataregion.mdx b/docs/models/components/generationresponsedataregion.mdx new file mode 100644 index 000000000..97fb1f9cf --- /dev/null +++ b/docs/models/components/generationresponsedataregion.mdx @@ -0,0 +1,27 @@ +--- +title: "GenerationResponseDataRegion" +--- + +The data region this generation was routed through: 'global', 'europe', or 'us'. + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.GenerationResponseDataRegionGlobal + +// Open enum: custom values can be created with a direct type cast +custom := components.GenerationResponseDataRegion("custom_value") +``` + + +## Values + +| Name | Value | +| ------------------------------------ | ------------------------------------ | +| `GenerationResponseDataRegionGlobal` | global | +| `GenerationResponseDataRegionEurope` | europe | +| `GenerationResponseDataRegionUs` | us | \ No newline at end of file diff --git a/docs/models/components/gettoolresponse.mdx b/docs/models/components/gettoolresponse.mdx new file mode 100644 index 000000000..2d4e098d7 --- /dev/null +++ b/docs/models/components/gettoolresponse.mdx @@ -0,0 +1,9 @@ +--- +title: "GetToolResponse" +--- + +## Fields + +| Field | Type | Required | Description | +| ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | +| `Data` | [components.ServerToolDetails](../../models/components/servertooldetails.mdx) | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/components/listtoolsresponse.mdx b/docs/models/components/listtoolsresponse.mdx new file mode 100644 index 000000000..d420c9693 --- /dev/null +++ b/docs/models/components/listtoolsresponse.mdx @@ -0,0 +1,11 @@ +--- +title: "ListToolsResponse" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `Data` | [][components.ServerTool](../../models/components/servertool.mdx) | :heavy_check_mark: | N/A | | +| `Links` | [components.ListToolsResponseLinks](../../models/components/listtoolsresponselinks.mdx) | :heavy_check_mark: | N/A | | +| `TotalCount` | `int64` | :heavy_check_mark: | Total number of tools | 12 | \ No newline at end of file diff --git a/docs/models/components/listtoolsresponselinks.mdx b/docs/models/components/listtoolsresponselinks.mdx new file mode 100644 index 000000000..20891cf29 --- /dev/null +++ b/docs/models/components/listtoolsresponselinks.mdx @@ -0,0 +1,9 @@ +--- +title: "ListToolsResponseLinks" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `Next` | `*string` | :heavy_check_mark: | URL for the next page of results, or null if this is the last page | null | \ No newline at end of file diff --git a/docs/models/components/modelslistresponse.mdx b/docs/models/components/modelslistresponse.mdx index 65083cbaa..ef5d7e350 100644 --- a/docs/models/components/modelslistresponse.mdx +++ b/docs/models/components/modelslistresponse.mdx @@ -10,5 +10,5 @@ List of available models | Field | Type | Required | Description | Example | | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Data` | [][components.Model](../../models/components/model.mdx) | :heavy_check_mark: | List of available models | [
\{
"architecture": \{
"input_modalities": [
"text"
],
"instruct_type": "chatml",
"modality": "text-\u003etext",
"output_modalities": [
"text"
],
"tokenizer": "GPT"
},
"canonical_slug": "openai/gpt-4",
"context_length": 8192,
"created": 1692901234,
"default_parameters": null,
"description": "GPT-4 is a large multimodal model that can solve difficult problems with greater accuracy.",
"expiration_date": null,
"id": "openai/gpt-4",
"knowledge_cutoff": null,
"links": \{
"details": "/api/v1/models/openai/gpt-4/endpoints"
},
"name": "GPT-4",
"per_request_limits": null,
"pricing": \{
"completion": "0.00006",
"image": "0",
"prompt": "0.00003",
"request": "0"
},
"supported_parameters": [
"temperature",
"top_p",
"max_tokens"
],
"supported_voices": null,
"top_provider": \{
"context_length": 8192,
"is_moderated": true,
"max_completion_tokens": 4096
}
}
] | -| `Links` | [components.Links](../../models/components/links.mdx) | :heavy_check_mark: | Pagination links | | +| `Links` | [components.ModelsListResponseLinks](../../models/components/modelslistresponselinks.mdx) | :heavy_check_mark: | Pagination links | | | `TotalCount` | `int64` | :heavy_check_mark: | Total number of models matching the query | 150 | \ No newline at end of file diff --git a/docs/models/components/links.mdx b/docs/models/components/modelslistresponselinks.mdx similarity index 97% rename from docs/models/components/links.mdx rename to docs/models/components/modelslistresponselinks.mdx index d002dbe50..3e5dbd139 100644 --- a/docs/models/components/links.mdx +++ b/docs/models/components/modelslistresponselinks.mdx @@ -1,5 +1,5 @@ --- -title: "Links" +title: "ModelsListResponseLinks" --- Pagination links diff --git a/docs/models/components/nativesupport.mdx b/docs/models/components/nativesupport.mdx new file mode 100644 index 000000000..712f26a7b --- /dev/null +++ b/docs/models/components/nativesupport.mdx @@ -0,0 +1,14 @@ +--- +title: "NativeSupport" +--- + +Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. + + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| `EndpointCount` | `int64` | :heavy_check_mark: | N/A | 18 | +| `ModelCount` | `int64` | :heavy_check_mark: | N/A | 12 | +| `Models` | [][components.ServerToolNativeModel](../../models/components/servertoolnativemodel.mdx) | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/components/pricingsource.mdx b/docs/models/components/pricingsource.mdx new file mode 100644 index 000000000..803ad42e0 --- /dev/null +++ b/docs/models/components/pricingsource.mdx @@ -0,0 +1,28 @@ +--- +title: "PricingSource" +--- + +Who bills the engine's calls beyond the model's tokens: `openrouter` (the `pricing` rows, from the caller's credits), `provider` (a per-call tool fee from the model's provider on the inference call, at its own rates), `byok` (the engine's vendor, against the caller's own key), or `none` (no charge) + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.PricingSourceOpenrouter + +// Open enum: custom values can be created with a direct type cast +custom := components.PricingSource("custom_value") +``` + + +## Values + +| Name | Value | +| ------------------------- | ------------------------- | +| `PricingSourceOpenrouter` | openrouter | +| `PricingSourceProvider` | provider | +| `PricingSourceBYOK` | byok | +| `PricingSourceNone` | none | \ No newline at end of file diff --git a/docs/models/components/servertool.mdx b/docs/models/components/servertool.mdx new file mode 100644 index 000000000..1728fb988 --- /dev/null +++ b/docs/models/components/servertool.mdx @@ -0,0 +1,23 @@ +--- +title: "ServerTool" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Aliases` | [][components.ServerToolInputName](../../models/components/servertoolinputname.mdx) | :heavy_check_mark: | Every spelling accepted in `tools[].type` for this tool, including the canonical `id`, and what the call surfaces as under each | | +| `DefaultEngine` | `*string` | :heavy_check_mark: | The engine a request without `parameters.engine` (or with `engine: "auto"`) runs on; `native` applies where the endpoint runs the tool itself, otherwise `fallback_engine`. A request pinned to a data region skips either engine when its `data_regions` does not list that region. Null for a tool without an engine parameter | native | +| `DocsURL` | `string` | :heavy_check_mark: | N/A | | +| `Engines` | [][components.ServerToolEngine](../../models/components/servertoolengine.mdx) | :heavy_check_mark: | N/A | | +| `FallbackEngine` | `*string` | :heavy_check_mark: | The engine an unpinned request runs on when `default_engine` is `native` and the endpoint does not run the tool itself; null when there is no fallback | exa | +| `ID` | `string` | :heavy_check_mark: | Canonical `openrouter:*` name; the stable `tools[].type` on every API format in `supported_api_formats` | openrouter:web_search | +| `InputSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema of the arguments the model emits when calling the tool | \{
"properties": \{},
"type": "object"
} | +| `Name` | `string` | :heavy_check_mark: | N/A | Web search | +| `NativeSupport` | [components.ServerToolNativeSupport](../../models/components/servertoolnativesupport.mdx) | :heavy_check_mark: | Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. | \{
"endpoint_count": 18,
"model_count": 12
} | +| `OutputSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema of the result returned to the model; null when undeclared | \{
"properties": \{},
"type": "object"
} | +| `ParametersSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema for the caller-side `tools[].parameters` object | \{
"properties": \{},
"type": "object"
} | +| `Status` | [components.ServerToolStatus](../../models/components/servertoolstatus.mdx) | :heavy_check_mark: | N/A | active | +| `Summary` | `string` | :heavy_check_mark: | One sentence for cards and search results; never sent to a model | | +| `SupportedAPIFormats` | [][components.ServerToolSupportedAPIFormat](../../models/components/servertoolsupportedapiformat.mdx) | :heavy_check_mark: | N/A | | +| `ToolDescription` | `string` | :heavy_check_mark: | The description sent upstream as the function tool description | | \ No newline at end of file diff --git a/docs/models/components/servertooldetails.mdx b/docs/models/components/servertooldetails.mdx new file mode 100644 index 000000000..57eccdd99 --- /dev/null +++ b/docs/models/components/servertooldetails.mdx @@ -0,0 +1,23 @@ +--- +title: "ServerToolDetails" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Aliases` | [][components.ServerToolInputName](../../models/components/servertoolinputname.mdx) | :heavy_check_mark: | Every spelling accepted in `tools[].type` for this tool, including the canonical `id`, and what the call surfaces as under each | | +| `DefaultEngine` | `*string` | :heavy_check_mark: | The engine a request without `parameters.engine` (or with `engine: "auto"`) runs on; `native` applies where the endpoint runs the tool itself, otherwise `fallback_engine`. A request pinned to a data region skips either engine when its `data_regions` does not list that region. Null for a tool without an engine parameter | native | +| `DocsURL` | `string` | :heavy_check_mark: | N/A | | +| `Engines` | [][components.ServerToolEngine](../../models/components/servertoolengine.mdx) | :heavy_check_mark: | N/A | | +| `FallbackEngine` | `*string` | :heavy_check_mark: | The engine an unpinned request runs on when `default_engine` is `native` and the endpoint does not run the tool itself; null when there is no fallback | exa | +| `ID` | `string` | :heavy_check_mark: | Canonical `openrouter:*` name; the stable `tools[].type` on every API format in `supported_api_formats` | openrouter:web_search | +| `InputSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema of the arguments the model emits when calling the tool | \{
"properties": \{},
"type": "object"
} | +| `Name` | `string` | :heavy_check_mark: | N/A | Web search | +| `NativeSupport` | [components.NativeSupport](../../models/components/nativesupport.mdx) | :heavy_check_mark: | Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. | \{
"endpoint_count": 18,
"model_count": 12
} | +| `OutputSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema of the result returned to the model; null when undeclared | \{
"properties": \{},
"type": "object"
} | +| `ParametersSchema` | map[string]`any` | :heavy_check_mark: | JSON Schema for the caller-side `tools[].parameters` object | \{
"properties": \{},
"type": "object"
} | +| `Status` | [components.ServerToolDetailsStatus](../../models/components/servertooldetailsstatus.mdx) | :heavy_check_mark: | N/A | active | +| `Summary` | `string` | :heavy_check_mark: | One sentence for cards and search results; never sent to a model | | +| `SupportedAPIFormats` | [][components.ServerToolDetailsSupportedAPIFormat](../../models/components/servertooldetailssupportedapiformat.mdx) | :heavy_check_mark: | N/A | | +| `ToolDescription` | `string` | :heavy_check_mark: | The description sent upstream as the function tool description | | \ No newline at end of file diff --git a/docs/models/components/servertooldetailsstatus.mdx b/docs/models/components/servertooldetailsstatus.mdx new file mode 100644 index 000000000..01d76b51f --- /dev/null +++ b/docs/models/components/servertooldetailsstatus.mdx @@ -0,0 +1,24 @@ +--- +title: "ServerToolDetailsStatus" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolDetailsStatusActive + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolDetailsStatus("custom_value") +``` + + +## Values + +| Name | Value | +| ----------------------------------- | ----------------------------------- | +| `ServerToolDetailsStatusActive` | active | +| `ServerToolDetailsStatusDeprecated` | deprecated | \ No newline at end of file diff --git a/docs/models/components/servertooldetailssupportedapiformat.mdx b/docs/models/components/servertooldetailssupportedapiformat.mdx new file mode 100644 index 000000000..398c2874f --- /dev/null +++ b/docs/models/components/servertooldetailssupportedapiformat.mdx @@ -0,0 +1,25 @@ +--- +title: "ServerToolDetailsSupportedAPIFormat" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolDetailsSupportedAPIFormatResponses + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolDetailsSupportedAPIFormat("custom_value") +``` + + +## Values + +| Name | Value | +| ------------------------------------------------------ | ------------------------------------------------------ | +| `ServerToolDetailsSupportedAPIFormatResponses` | responses | +| `ServerToolDetailsSupportedAPIFormatChatCompletions` | chat-completions | +| `ServerToolDetailsSupportedAPIFormatAnthropicMessages` | anthropic-messages | \ No newline at end of file diff --git a/docs/models/components/servertoolengine.mdx b/docs/models/components/servertoolengine.mdx new file mode 100644 index 000000000..153d0301a --- /dev/null +++ b/docs/models/components/servertoolengine.mdx @@ -0,0 +1,17 @@ +--- +title: "ServerToolEngine" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `BYOK` | [components.BYOK](../../models/components/byok.mdx) | :heavy_check_mark: | Whether the engine needs the caller's own key, saved in plugin settings: `required` (OpenRouter holds none), `optional` (OpenRouter's key is used unless the caller saved one), or `none` | none | +| `DataRegions` | [][components.ServerToolEngineDataRegion](../../models/components/servertoolenginedataregion.mdx) | :heavy_check_mark: | The data regions whose requests this engine serves without leaving the region. A request pinned to a region can only use engines that list it; `global` is always listed. | [
"global",
"us"
] | +| `DefaultMode` | `*string` | :heavy_check_mark: | The `parameters.mode` a request without one runs and bills as; null for engines without modes. The `pricing[]` row with this `mode` is what an unmoded request bills | auto | +| `ExecutedBy` | [components.ServerToolExecutedBy](../../models/components/servertoolexecutedby.mdx) | :heavy_check_mark: | Who runs the tool call: the model provider during inference (`provider`), OpenRouter (`openrouter`), or the caller's application after the call is returned (`client`). | openrouter | +| `ID` | `*string` | :heavy_check_mark: | The `parameters.engine` value that selects this engine; null for the single engine of a tool without an engine parameter | exa | +| `Name` | `string` | :heavy_check_mark: | N/A | Exa | +| `Pricing` | [][components.ServerToolPrice](../../models/components/servertoolprice.mdx) | :heavy_check_mark: | The rows OpenRouter bills; non-empty exactly when `pricing_source` is `openrouter` | | +| `PricingDocURL` | `*string` | :heavy_check_mark: | Where the rates are documented when `pricing_source` is `provider` or `byok`; null otherwise | null | +| `PricingSource` | [components.PricingSource](../../models/components/pricingsource.mdx) | :heavy_check_mark: | Who bills the engine's calls beyond the model's tokens: `openrouter` (the `pricing` rows, from the caller's credits), `provider` (a per-call tool fee from the model's provider on the inference call, at its own rates), `byok` (the engine's vendor, against the caller's own key), or `none` (no charge) | openrouter | \ No newline at end of file diff --git a/docs/models/components/servertoolenginedataregion.mdx b/docs/models/components/servertoolenginedataregion.mdx new file mode 100644 index 000000000..7ed9cbebe --- /dev/null +++ b/docs/models/components/servertoolenginedataregion.mdx @@ -0,0 +1,25 @@ +--- +title: "ServerToolEngineDataRegion" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolEngineDataRegionGlobal + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolEngineDataRegion("custom_value") +``` + + +## Values + +| Name | Value | +| ---------------------------------- | ---------------------------------- | +| `ServerToolEngineDataRegionGlobal` | global | +| `ServerToolEngineDataRegionEurope` | europe | +| `ServerToolEngineDataRegionUs` | us | \ No newline at end of file diff --git a/docs/models/components/servertoolexecutedby.mdx b/docs/models/components/servertoolexecutedby.mdx new file mode 100644 index 000000000..90b2232a2 --- /dev/null +++ b/docs/models/components/servertoolexecutedby.mdx @@ -0,0 +1,27 @@ +--- +title: "ServerToolExecutedBy" +--- + +Who runs the tool call: the model provider during inference (`provider`), OpenRouter (`openrouter`), or the caller's application after the call is returned (`client`). + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolExecutedByProvider + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolExecutedBy("custom_value") +``` + + +## Values + +| Name | Value | +| -------------------------------- | -------------------------------- | +| `ServerToolExecutedByProvider` | provider | +| `ServerToolExecutedByOpenrouter` | openrouter | +| `ServerToolExecutedByClient` | client | \ No newline at end of file diff --git a/docs/models/components/servertoolinputname.mdx b/docs/models/components/servertoolinputname.mdx new file mode 100644 index 000000000..0092ef47e --- /dev/null +++ b/docs/models/components/servertoolinputname.mdx @@ -0,0 +1,11 @@ +--- +title: "ServerToolInputName" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `APIFormats` | [][components.ServerToolInputNameAPIFormat](../../models/components/servertoolinputnameapiformat.mdx) | :heavy_check_mark: | API formats that accept this spelling in `tools[].type` | | +| `OutputNames` | [][components.ServerToolOutputName](../../models/components/servertooloutputname.mdx) | :heavy_check_mark: | What the call surfaces as on each accepting API format when requested under this spelling; a format is absent when the call is not visible to the caller | | +| `Type` | `string` | :heavy_check_mark: | N/A | web_search_20250305 | \ No newline at end of file diff --git a/docs/models/components/servertoolinputnameapiformat.mdx b/docs/models/components/servertoolinputnameapiformat.mdx new file mode 100644 index 000000000..887e36267 --- /dev/null +++ b/docs/models/components/servertoolinputnameapiformat.mdx @@ -0,0 +1,25 @@ +--- +title: "ServerToolInputNameAPIFormat" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolInputNameAPIFormatResponses + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolInputNameAPIFormat("custom_value") +``` + + +## Values + +| Name | Value | +| ----------------------------------------------- | ----------------------------------------------- | +| `ServerToolInputNameAPIFormatResponses` | responses | +| `ServerToolInputNameAPIFormatChatCompletions` | chat-completions | +| `ServerToolInputNameAPIFormatAnthropicMessages` | anthropic-messages | \ No newline at end of file diff --git a/docs/models/components/servertoolnativemodel.mdx b/docs/models/components/servertoolnativemodel.mdx new file mode 100644 index 000000000..d1184a9ae --- /dev/null +++ b/docs/models/components/servertoolnativemodel.mdx @@ -0,0 +1,10 @@ +--- +title: "ServerToolNativeModel" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------- | --------------------------- | --------------------------- | --------------------------- | --------------------------- | +| `Providers` | []`string` | :heavy_check_mark: | N/A | [
"Anthropic",
"Google"
] | +| `Slug` | `string` | :heavy_check_mark: | N/A | anthropic/claude-4.5-sonnet | \ No newline at end of file diff --git a/docs/models/components/servertoolnativesupport.mdx b/docs/models/components/servertoolnativesupport.mdx new file mode 100644 index 000000000..a99eb2c60 --- /dev/null +++ b/docs/models/components/servertoolnativesupport.mdx @@ -0,0 +1,13 @@ +--- +title: "ServerToolNativeSupport" +--- + +Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. + + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------ | ------------------ | ------------------ | ------------------ | ------------------ | +| `EndpointCount` | `int64` | :heavy_check_mark: | N/A | 18 | +| `ModelCount` | `int64` | :heavy_check_mark: | N/A | 12 | \ No newline at end of file diff --git a/docs/models/components/servertooloutputname.mdx b/docs/models/components/servertooloutputname.mdx new file mode 100644 index 000000000..91081a7ef --- /dev/null +++ b/docs/models/components/servertooloutputname.mdx @@ -0,0 +1,11 @@ +--- +title: "ServerToolOutputName" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `APIFormat` | [components.ServerToolOutputNameAPIFormat](../../models/components/servertooloutputnameapiformat.mdx) | :heavy_check_mark: | N/A | | +| `Name` | `*string` | :heavy_minus_sign: | Anthropic Messages `server_tool_use` block `name`, when the call surfaces as one | web_search | +| `Type` | `string` | :heavy_check_mark: | Output item `type` on Responses, content block `type` on Anthropic Messages, `reasoning_details[].type` on Chat Completions | web_search_call | \ No newline at end of file diff --git a/docs/models/components/servertooloutputnameapiformat.mdx b/docs/models/components/servertooloutputnameapiformat.mdx new file mode 100644 index 000000000..499304a1c --- /dev/null +++ b/docs/models/components/servertooloutputnameapiformat.mdx @@ -0,0 +1,25 @@ +--- +title: "ServerToolOutputNameAPIFormat" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolOutputNameAPIFormatResponses + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolOutputNameAPIFormat("custom_value") +``` + + +## Values + +| Name | Value | +| ------------------------------------------------ | ------------------------------------------------ | +| `ServerToolOutputNameAPIFormatResponses` | responses | +| `ServerToolOutputNameAPIFormatChatCompletions` | chat-completions | +| `ServerToolOutputNameAPIFormatAnthropicMessages` | anthropic-messages | \ No newline at end of file diff --git a/docs/models/components/servertoolprice.mdx b/docs/models/components/servertoolprice.mdx new file mode 100644 index 000000000..1a81fcea2 --- /dev/null +++ b/docs/models/components/servertoolprice.mdx @@ -0,0 +1,12 @@ +--- +title: "ServerToolPrice" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | +| `MaxUnitsPerCall` | `int64` | :heavy_check_mark: | N/A | | +| `Mode` | `*string` | :heavy_check_mark: | The `parameters.mode` this price applies to; null for prices that do not depend on the mode. A request bills exactly one `request` row | auto | +| `Price` | `string` | :heavy_check_mark: | USD per unit, as a decimal string | 0.007 | +| `Unit` | `string` | :heavy_check_mark: | N/A | request | \ No newline at end of file diff --git a/docs/models/components/servertoolstatus.mdx b/docs/models/components/servertoolstatus.mdx new file mode 100644 index 000000000..a11a690e7 --- /dev/null +++ b/docs/models/components/servertoolstatus.mdx @@ -0,0 +1,24 @@ +--- +title: "ServerToolStatus" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolStatusActive + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolStatus("custom_value") +``` + + +## Values + +| Name | Value | +| ---------------------------- | ---------------------------- | +| `ServerToolStatusActive` | active | +| `ServerToolStatusDeprecated` | deprecated | \ No newline at end of file diff --git a/docs/models/components/servertoolsupportedapiformat.mdx b/docs/models/components/servertoolsupportedapiformat.mdx new file mode 100644 index 000000000..a3cd75224 --- /dev/null +++ b/docs/models/components/servertoolsupportedapiformat.mdx @@ -0,0 +1,25 @@ +--- +title: "ServerToolSupportedAPIFormat" +--- + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +value := components.ServerToolSupportedAPIFormatResponses + +// Open enum: custom values can be created with a direct type cast +custom := components.ServerToolSupportedAPIFormat("custom_value") +``` + + +## Values + +| Name | Value | +| ----------------------------------------------- | ----------------------------------------------- | +| `ServerToolSupportedAPIFormatResponses` | responses | +| `ServerToolSupportedAPIFormatChatCompletions` | chat-completions | +| `ServerToolSupportedAPIFormatAnthropicMessages` | anthropic-messages | \ No newline at end of file diff --git a/docs/models/operations/apiformat.mdx b/docs/models/operations/apiformat.mdx new file mode 100644 index 000000000..364cb9699 --- /dev/null +++ b/docs/models/operations/apiformat.mdx @@ -0,0 +1,27 @@ +--- +title: "APIFormat" +--- + +Only tools usable on this API format + +## Example Usage + +```go +import ( + "github.com/OpenRouterTeam/go-sdk/models/operations" +) + +value := operations.APIFormatResponses + +// Open enum: custom values can be created with a direct type cast +custom := operations.APIFormat("custom_value") +``` + + +## Values + +| Name | Value | +| ---------------------------- | ---------------------------- | +| `APIFormatResponses` | responses | +| `APIFormatChatCompletions` | chat-completions | +| `APIFormatAnthropicMessages` | anthropic-messages | \ No newline at end of file diff --git a/docs/models/operations/gettoolrequest.mdx b/docs/models/operations/gettoolrequest.mdx new file mode 100644 index 000000000..3fafe4f61 --- /dev/null +++ b/docs/models/operations/gettoolrequest.mdx @@ -0,0 +1,9 @@ +--- +title: "GetToolRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | +| `Name` | `string` | :heavy_check_mark: | Canonical `openrouter:*` name or any accepted `tools[].type` alias | openrouter:web_search | \ No newline at end of file diff --git a/docs/models/operations/gettoolresponse.mdx b/docs/models/operations/gettoolresponse.mdx new file mode 100644 index 000000000..1fa45c0b5 --- /dev/null +++ b/docs/models/operations/gettoolresponse.mdx @@ -0,0 +1,10 @@ +--- +title: "GetToolResponse" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------- | +| `Headers` | map[string][]`string` | :heavy_check_mark: | N/A | +| `Result` | [*components.GetToolResponse](../../models/components/gettoolresponse.mdx) | :heavy_minus_sign: | N/A | \ No newline at end of file diff --git a/docs/models/operations/gettoolsecurity.mdx b/docs/models/operations/gettoolsecurity.mdx new file mode 100644 index 000000000..95a591f90 --- /dev/null +++ b/docs/models/operations/gettoolsecurity.mdx @@ -0,0 +1,9 @@ +--- +title: "GetToolSecurity" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `Bearer` | `string` | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/operations/listtoolsrequest.mdx b/docs/models/operations/listtoolsrequest.mdx new file mode 100644 index 000000000..aea2db8b1 --- /dev/null +++ b/docs/models/operations/listtoolsrequest.mdx @@ -0,0 +1,11 @@ +--- +title: "ListToolsRequest" +--- + +## Fields + +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `Offset` | optionalnullable.OptionalNullable[`int64`] | :heavy_minus_sign: | Number of records to skip for pagination. When both offset and limit are omitted, the full list is returned | 0 | +| `Limit` | `*int64` | :heavy_minus_sign: | Maximum number of records to return (max 100). When both offset and limit are omitted, the full list is returned | 50 | +| `APIFormat` | [*operations.APIFormat](../../models/operations/apiformat.mdx) | :heavy_minus_sign: | Only tools usable on this API format | responses | \ No newline at end of file diff --git a/docs/models/operations/listtoolssecurity.mdx b/docs/models/operations/listtoolssecurity.mdx new file mode 100644 index 000000000..5047967a3 --- /dev/null +++ b/docs/models/operations/listtoolssecurity.mdx @@ -0,0 +1,9 @@ +--- +title: "ListToolsSecurity" +--- + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `Bearer` | `string` | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/sdks/tools/README.mdx b/docs/sdks/tools/README.mdx new file mode 100644 index 000000000..5edb3770d --- /dev/null +++ b/docs/sdks/tools/README.mdx @@ -0,0 +1,130 @@ +--- +title: "Tools" +description: "The catalog of server tools OpenRouter runs on behalf of a model: accepted `tools[].type` spellings per API format, engines and pricing, and which endpoints run each tool natively. See https://openrouter.ai/docs/guides/features/server-tools." +--- + +## Overview + +The catalog of server tools OpenRouter runs on behalf of a model: accepted `tools[].type` spellings per API format, engines and pricing, and which endpoints run each tool natively. See https://openrouter.ai/docs/guides/features/server-tools. + +### Available Operations + +* [ListTools](#listtools) - List server tools +* [GetTool](#gettool) - Get a server tool + +## ListTools + +Lists every server tool OpenRouter can run on behalf of a model: accepted `tools[].type` spellings per API format, the engines behind it with their pricing, and how many endpoints run it natively. + +### Example Usage + +```go +package main + +import( + "context" + openrouter "github.com/OpenRouterTeam/go-sdk" + "os" + "github.com/OpenRouterTeam/go-sdk/models/operations" + "github.com/OpenRouterTeam/go-sdk/optionalnullable" + "log" +) + +func main() { + ctx := context.Background() + + s := openrouter.New() + + res, err := s.Tools.ListTools(ctx, operations.ListToolsSecurity{ + Bearer: os.Getenv("OPENROUTER_BEARER"), + }, optionalnullable.From(openrouter.Pointer[int64](0)), openrouter.Pointer[int64](50), nil) + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | | +| `security` | [operations.ListToolsSecurity](../../models/operations/listtoolssecurity.mdx) | :heavy_check_mark: | The security requirements to use for the request. | | +| `offset` | optionalnullable.OptionalNullable[`int64`] | :heavy_minus_sign: | Number of records to skip for pagination. When both offset and limit are omitted, the full list is returned | 0 | +| `limit` | `*int64` | :heavy_minus_sign: | Maximum number of records to return (max 100). When both offset and limit are omitted, the full list is returned | 50 | +| `apiFormat` | [*operations.APIFormat](../../models/operations/apiformat.mdx) | :heavy_minus_sign: | Only tools usable on this API format | responses | +| `opts` | [][operations.Option](../../models/operations/option.mdx) | :heavy_minus_sign: | The options for this request. | | + +### Response + +**[*components.ListToolsResponse](../../models/components/listtoolsresponse.mdx), error** + +### Errors + +| Error Type | Status Code | Content Type | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | +| sdkerrors.UnauthorizedResponseError | 401 | application/json | +| sdkerrors.ForbiddenResponseError | 403 | application/json | +| sdkerrors.NotFoundResponseError | 404 | application/json | +| sdkerrors.InternalServerResponseError | 500 | application/json | +| sdkerrors.APIError | 4XX, 5XX | \*/\* | + +## GetTool + +One server tool by canonical name or any accepted alias, with the models that run it natively. + +### Example Usage + +```go +package main + +import( + "context" + openrouter "github.com/OpenRouterTeam/go-sdk" + "os" + "github.com/OpenRouterTeam/go-sdk/models/operations" + "log" +) + +func main() { + ctx := context.Background() + + s := openrouter.New() + + res, err := s.Tools.GetTool(ctx, operations.GetToolSecurity{ + Bearer: os.Getenv("OPENROUTER_BEARER"), + }, "openrouter:web_search") + if err != nil { + log.Fatal(err) + } + if res != nil { + // handle response + } +} +``` + +### Parameters + +| Parameter | Type | Required | Description | Example | +| ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ | +| `ctx` | [context.Context](https://pkg.go.dev/context#Context) | :heavy_check_mark: | The context to use for the request. | | +| `security` | [operations.GetToolSecurity](../../models/operations/gettoolsecurity.mdx) | :heavy_check_mark: | The security requirements to use for the request. | | +| `name` | `string` | :heavy_check_mark: | Canonical `openrouter:*` name or any accepted `tools[].type` alias | openrouter:web_search | +| `opts` | [][operations.Option](../../models/operations/option.mdx) | :heavy_minus_sign: | The options for this request. | | + +### Response + +**[*operations.GetToolResponse](../../models/operations/gettoolresponse.mdx), error** + +### Errors + +| Error Type | Status Code | Content Type | +| ------------------------------------- | ------------------------------------- | ------------------------------------- | +| sdkerrors.UnauthorizedResponseError | 401 | application/json | +| sdkerrors.ForbiddenResponseError | 403 | application/json | +| sdkerrors.NotFoundResponseError | 404 | application/json | +| sdkerrors.InternalServerResponseError | 500 | application/json | +| sdkerrors.APIError | 4XX, 5XX | \*/\* | \ No newline at end of file diff --git a/models/components/generationresponse.go b/models/components/generationresponse.go index a6faf9411..f34c6cd2d 100644 --- a/models/components/generationresponse.go +++ b/models/components/generationresponse.go @@ -35,21 +35,21 @@ func (e *APIType) IsExact() bool { return false } -// DataRegion - The data region this generation was routed through: 'global', 'europe', or 'us'. -type DataRegion string +// GenerationResponseDataRegion - The data region this generation was routed through: 'global', 'europe', or 'us'. +type GenerationResponseDataRegion string const ( - DataRegionGlobal DataRegion = "global" - DataRegionEurope DataRegion = "europe" - DataRegionUs DataRegion = "us" + GenerationResponseDataRegionGlobal GenerationResponseDataRegion = "global" + GenerationResponseDataRegionEurope GenerationResponseDataRegion = "europe" + GenerationResponseDataRegionUs GenerationResponseDataRegion = "us" ) -func (e DataRegion) ToPointer() *DataRegion { +func (e GenerationResponseDataRegion) ToPointer() *GenerationResponseDataRegion { return &e } // IsExact returns true if the value matches a known enum value, false otherwise. -func (e *DataRegion) IsExact() bool { +func (e *GenerationResponseDataRegion) IsExact() bool { if e != nil { switch *e { case "global", "europe", "us": @@ -72,7 +72,7 @@ type GenerationResponseData struct { // ISO 8601 timestamp of when the generation was created CreatedAt string `json:"created_at"` // The data region this generation was routed through: 'global', 'europe', or 'us'. - DataRegion DataRegion `json:"data_region"` + DataRegion GenerationResponseDataRegion `json:"data_region"` // External user identifier ExternalUser *string `json:"external_user"` // Reason the generation finished @@ -188,9 +188,9 @@ func (g *GenerationResponseData) GetCreatedAt() string { return g.CreatedAt } -func (g *GenerationResponseData) GetDataRegion() DataRegion { +func (g *GenerationResponseData) GetDataRegion() GenerationResponseDataRegion { if g == nil { - return DataRegion("") + return GenerationResponseDataRegion("") } return g.DataRegion } diff --git a/models/components/gettoolresponse.go b/models/components/gettoolresponse.go new file mode 100644 index 000000000..298c18ed8 --- /dev/null +++ b/models/components/gettoolresponse.go @@ -0,0 +1,14 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type GetToolResponse struct { + Data ServerToolDetails `json:"data"` +} + +func (g *GetToolResponse) GetData() ServerToolDetails { + if g == nil { + return ServerToolDetails{} + } + return g.Data +} diff --git a/models/components/listtoolsresponse.go b/models/components/listtoolsresponse.go new file mode 100644 index 000000000..dc5386a12 --- /dev/null +++ b/models/components/listtoolsresponse.go @@ -0,0 +1,43 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ListToolsResponseLinks struct { + // URL for the next page of results, or null if this is the last page + Next *string `json:"next"` +} + +func (l *ListToolsResponseLinks) GetNext() *string { + if l == nil { + return nil + } + return l.Next +} + +type ListToolsResponse struct { + Data []ServerTool `json:"data"` + Links ListToolsResponseLinks `json:"links"` + // Total number of tools + TotalCount int64 `json:"total_count"` +} + +func (l *ListToolsResponse) GetData() []ServerTool { + if l == nil { + return []ServerTool{} + } + return l.Data +} + +func (l *ListToolsResponse) GetLinks() ListToolsResponseLinks { + if l == nil { + return ListToolsResponseLinks{} + } + return l.Links +} + +func (l *ListToolsResponse) GetTotalCount() int64 { + if l == nil { + return 0 + } + return l.TotalCount +} diff --git a/models/components/modelslistresponse.go b/models/components/modelslistresponse.go index 5ff490282..294a5c217 100644 --- a/models/components/modelslistresponse.go +++ b/models/components/modelslistresponse.go @@ -2,17 +2,17 @@ package components -// Links - Pagination links -type Links struct { +// ModelsListResponseLinks - Pagination links +type ModelsListResponseLinks struct { // URL for the next page of results, or null if this is the last page Next *string `json:"next"` } -func (l *Links) GetNext() *string { - if l == nil { +func (m *ModelsListResponseLinks) GetNext() *string { + if m == nil { return nil } - return l.Next + return m.Next } // ModelsListResponse - List of available models @@ -20,7 +20,7 @@ type ModelsListResponse struct { // List of available models Data []Model `json:"data"` // Pagination links - Links Links `json:"links"` + Links ModelsListResponseLinks `json:"links"` // Total number of models matching the query TotalCount int64 `json:"total_count"` } @@ -32,9 +32,9 @@ func (m *ModelsListResponse) GetData() []Model { return m.Data } -func (m *ModelsListResponse) GetLinks() Links { +func (m *ModelsListResponse) GetLinks() ModelsListResponseLinks { if m == nil { - return Links{} + return ModelsListResponseLinks{} } return m.Links } diff --git a/models/components/servertool.go b/models/components/servertool.go new file mode 100644 index 000000000..3b6317f35 --- /dev/null +++ b/models/components/servertool.go @@ -0,0 +1,181 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ServerToolStatus string + +const ( + ServerToolStatusActive ServerToolStatus = "active" + ServerToolStatusDeprecated ServerToolStatus = "deprecated" +) + +func (e ServerToolStatus) ToPointer() *ServerToolStatus { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolStatus) IsExact() bool { + if e != nil { + switch *e { + case "active", "deprecated": + return true + } + } + return false +} + +type ServerToolSupportedAPIFormat string + +const ( + ServerToolSupportedAPIFormatResponses ServerToolSupportedAPIFormat = "responses" + ServerToolSupportedAPIFormatChatCompletions ServerToolSupportedAPIFormat = "chat-completions" + ServerToolSupportedAPIFormatAnthropicMessages ServerToolSupportedAPIFormat = "anthropic-messages" +) + +func (e ServerToolSupportedAPIFormat) ToPointer() *ServerToolSupportedAPIFormat { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolSupportedAPIFormat) IsExact() bool { + if e != nil { + switch *e { + case "responses", "chat-completions", "anthropic-messages": + return true + } + } + return false +} + +type ServerTool struct { + // Every spelling accepted in `tools[].type` for this tool, including the canonical `id`, and what the call surfaces as under each + Aliases []ServerToolInputName `json:"aliases"` + // The engine a request without `parameters.engine` (or with `engine: "auto"`) runs on; `native` applies where the endpoint runs the tool itself, otherwise `fallback_engine`. A request pinned to a data region skips either engine when its `data_regions` does not list that region. Null for a tool without an engine parameter + DefaultEngine *string `json:"default_engine"` + DocsURL string `json:"docs_url"` + Engines []ServerToolEngine `json:"engines"` + // The engine an unpinned request runs on when `default_engine` is `native` and the endpoint does not run the tool itself; null when there is no fallback + FallbackEngine *string `json:"fallback_engine"` + // Canonical `openrouter:*` name; the stable `tools[].type` on every API format in `supported_api_formats` + ID string `json:"id"` + // JSON Schema of the arguments the model emits when calling the tool + InputSchema map[string]any `json:"input_schema"` + Name string `json:"name"` + // Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. + NativeSupport ServerToolNativeSupport `json:"native_support"` + // JSON Schema of the result returned to the model; null when undeclared + OutputSchema map[string]any `json:"output_schema"` + // JSON Schema for the caller-side `tools[].parameters` object + ParametersSchema map[string]any `json:"parameters_schema"` + Status ServerToolStatus `json:"status"` + // One sentence for cards and search results; never sent to a model + Summary string `json:"summary"` + SupportedAPIFormats []ServerToolSupportedAPIFormat `json:"supported_api_formats"` + // The description sent upstream as the function tool description + ToolDescription string `json:"tool_description"` +} + +func (s *ServerTool) GetAliases() []ServerToolInputName { + if s == nil { + return []ServerToolInputName{} + } + return s.Aliases +} + +func (s *ServerTool) GetDefaultEngine() *string { + if s == nil { + return nil + } + return s.DefaultEngine +} + +func (s *ServerTool) GetDocsURL() string { + if s == nil { + return "" + } + return s.DocsURL +} + +func (s *ServerTool) GetEngines() []ServerToolEngine { + if s == nil { + return []ServerToolEngine{} + } + return s.Engines +} + +func (s *ServerTool) GetFallbackEngine() *string { + if s == nil { + return nil + } + return s.FallbackEngine +} + +func (s *ServerTool) GetID() string { + if s == nil { + return "" + } + return s.ID +} + +func (s *ServerTool) GetInputSchema() map[string]any { + if s == nil { + return map[string]any{} + } + return s.InputSchema +} + +func (s *ServerTool) GetName() string { + if s == nil { + return "" + } + return s.Name +} + +func (s *ServerTool) GetNativeSupport() ServerToolNativeSupport { + if s == nil { + return ServerToolNativeSupport{} + } + return s.NativeSupport +} + +func (s *ServerTool) GetOutputSchema() map[string]any { + if s == nil { + return nil + } + return s.OutputSchema +} + +func (s *ServerTool) GetParametersSchema() map[string]any { + if s == nil { + return map[string]any{} + } + return s.ParametersSchema +} + +func (s *ServerTool) GetStatus() ServerToolStatus { + if s == nil { + return ServerToolStatus("") + } + return s.Status +} + +func (s *ServerTool) GetSummary() string { + if s == nil { + return "" + } + return s.Summary +} + +func (s *ServerTool) GetSupportedAPIFormats() []ServerToolSupportedAPIFormat { + if s == nil { + return []ServerToolSupportedAPIFormat{} + } + return s.SupportedAPIFormats +} + +func (s *ServerTool) GetToolDescription() string { + if s == nil { + return "" + } + return s.ToolDescription +} diff --git a/models/components/servertooldetails.go b/models/components/servertooldetails.go new file mode 100644 index 000000000..e0dc1355c --- /dev/null +++ b/models/components/servertooldetails.go @@ -0,0 +1,209 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +// NativeSupport - Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. +type NativeSupport struct { + EndpointCount int64 `json:"endpoint_count"` + ModelCount int64 `json:"model_count"` + Models []ServerToolNativeModel `json:"models"` +} + +func (n *NativeSupport) GetEndpointCount() int64 { + if n == nil { + return 0 + } + return n.EndpointCount +} + +func (n *NativeSupport) GetModelCount() int64 { + if n == nil { + return 0 + } + return n.ModelCount +} + +func (n *NativeSupport) GetModels() []ServerToolNativeModel { + if n == nil { + return []ServerToolNativeModel{} + } + return n.Models +} + +type ServerToolDetailsStatus string + +const ( + ServerToolDetailsStatusActive ServerToolDetailsStatus = "active" + ServerToolDetailsStatusDeprecated ServerToolDetailsStatus = "deprecated" +) + +func (e ServerToolDetailsStatus) ToPointer() *ServerToolDetailsStatus { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolDetailsStatus) IsExact() bool { + if e != nil { + switch *e { + case "active", "deprecated": + return true + } + } + return false +} + +type ServerToolDetailsSupportedAPIFormat string + +const ( + ServerToolDetailsSupportedAPIFormatResponses ServerToolDetailsSupportedAPIFormat = "responses" + ServerToolDetailsSupportedAPIFormatChatCompletions ServerToolDetailsSupportedAPIFormat = "chat-completions" + ServerToolDetailsSupportedAPIFormatAnthropicMessages ServerToolDetailsSupportedAPIFormat = "anthropic-messages" +) + +func (e ServerToolDetailsSupportedAPIFormat) ToPointer() *ServerToolDetailsSupportedAPIFormat { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolDetailsSupportedAPIFormat) IsExact() bool { + if e != nil { + switch *e { + case "responses", "chat-completions", "anthropic-messages": + return true + } + } + return false +} + +type ServerToolDetails struct { + // Every spelling accepted in `tools[].type` for this tool, including the canonical `id`, and what the call surfaces as under each + Aliases []ServerToolInputName `json:"aliases"` + // The engine a request without `parameters.engine` (or with `engine: "auto"`) runs on; `native` applies where the endpoint runs the tool itself, otherwise `fallback_engine`. A request pinned to a data region skips either engine when its `data_regions` does not list that region. Null for a tool without an engine parameter + DefaultEngine *string `json:"default_engine"` + DocsURL string `json:"docs_url"` + Engines []ServerToolEngine `json:"engines"` + // The engine an unpinned request runs on when `default_engine` is `native` and the endpoint does not run the tool itself; null when there is no fallback + FallbackEngine *string `json:"fallback_engine"` + // Canonical `openrouter:*` name; the stable `tools[].type` on every API format in `supported_api_formats` + ID string `json:"id"` + // JSON Schema of the arguments the model emits when calling the tool + InputSchema map[string]any `json:"input_schema"` + Name string `json:"name"` + // Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. + NativeSupport NativeSupport `json:"native_support"` + // JSON Schema of the result returned to the model; null when undeclared + OutputSchema map[string]any `json:"output_schema"` + // JSON Schema for the caller-side `tools[].parameters` object + ParametersSchema map[string]any `json:"parameters_schema"` + Status ServerToolDetailsStatus `json:"status"` + // One sentence for cards and search results; never sent to a model + Summary string `json:"summary"` + SupportedAPIFormats []ServerToolDetailsSupportedAPIFormat `json:"supported_api_formats"` + // The description sent upstream as the function tool description + ToolDescription string `json:"tool_description"` +} + +func (s *ServerToolDetails) GetAliases() []ServerToolInputName { + if s == nil { + return []ServerToolInputName{} + } + return s.Aliases +} + +func (s *ServerToolDetails) GetDefaultEngine() *string { + if s == nil { + return nil + } + return s.DefaultEngine +} + +func (s *ServerToolDetails) GetDocsURL() string { + if s == nil { + return "" + } + return s.DocsURL +} + +func (s *ServerToolDetails) GetEngines() []ServerToolEngine { + if s == nil { + return []ServerToolEngine{} + } + return s.Engines +} + +func (s *ServerToolDetails) GetFallbackEngine() *string { + if s == nil { + return nil + } + return s.FallbackEngine +} + +func (s *ServerToolDetails) GetID() string { + if s == nil { + return "" + } + return s.ID +} + +func (s *ServerToolDetails) GetInputSchema() map[string]any { + if s == nil { + return map[string]any{} + } + return s.InputSchema +} + +func (s *ServerToolDetails) GetName() string { + if s == nil { + return "" + } + return s.Name +} + +func (s *ServerToolDetails) GetNativeSupport() NativeSupport { + if s == nil { + return NativeSupport{} + } + return s.NativeSupport +} + +func (s *ServerToolDetails) GetOutputSchema() map[string]any { + if s == nil { + return nil + } + return s.OutputSchema +} + +func (s *ServerToolDetails) GetParametersSchema() map[string]any { + if s == nil { + return map[string]any{} + } + return s.ParametersSchema +} + +func (s *ServerToolDetails) GetStatus() ServerToolDetailsStatus { + if s == nil { + return ServerToolDetailsStatus("") + } + return s.Status +} + +func (s *ServerToolDetails) GetSummary() string { + if s == nil { + return "" + } + return s.Summary +} + +func (s *ServerToolDetails) GetSupportedAPIFormats() []ServerToolDetailsSupportedAPIFormat { + if s == nil { + return []ServerToolDetailsSupportedAPIFormat{} + } + return s.SupportedAPIFormats +} + +func (s *ServerToolDetails) GetToolDescription() string { + if s == nil { + return "" + } + return s.ToolDescription +} diff --git a/models/components/servertoolengine.go b/models/components/servertoolengine.go new file mode 100644 index 000000000..58f659056 --- /dev/null +++ b/models/components/servertoolengine.go @@ -0,0 +1,158 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +// BYOK - Whether the engine needs the caller's own key, saved in plugin settings: `required` (OpenRouter holds none), `optional` (OpenRouter's key is used unless the caller saved one), or `none` +type BYOK string + +const ( + BYOKRequired BYOK = "required" + BYOKOptional BYOK = "optional" + BYOKNone BYOK = "none" +) + +func (e BYOK) ToPointer() *BYOK { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *BYOK) IsExact() bool { + if e != nil { + switch *e { + case "required", "optional", "none": + return true + } + } + return false +} + +type ServerToolEngineDataRegion string + +const ( + ServerToolEngineDataRegionGlobal ServerToolEngineDataRegion = "global" + ServerToolEngineDataRegionEurope ServerToolEngineDataRegion = "europe" + ServerToolEngineDataRegionUs ServerToolEngineDataRegion = "us" +) + +func (e ServerToolEngineDataRegion) ToPointer() *ServerToolEngineDataRegion { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolEngineDataRegion) IsExact() bool { + if e != nil { + switch *e { + case "global", "europe", "us": + return true + } + } + return false +} + +// PricingSource - Who bills the engine's calls beyond the model's tokens: `openrouter` (the `pricing` rows, from the caller's credits), `provider` (a per-call tool fee from the model's provider on the inference call, at its own rates), `byok` (the engine's vendor, against the caller's own key), or `none` (no charge) +type PricingSource string + +const ( + PricingSourceOpenrouter PricingSource = "openrouter" + PricingSourceProvider PricingSource = "provider" + PricingSourceBYOK PricingSource = "byok" + PricingSourceNone PricingSource = "none" +) + +func (e PricingSource) ToPointer() *PricingSource { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *PricingSource) IsExact() bool { + if e != nil { + switch *e { + case "openrouter", "provider", "byok", "none": + return true + } + } + return false +} + +type ServerToolEngine struct { + // Whether the engine needs the caller's own key, saved in plugin settings: `required` (OpenRouter holds none), `optional` (OpenRouter's key is used unless the caller saved one), or `none` + BYOK BYOK `json:"byok"` + // The data regions whose requests this engine serves without leaving the region. A request pinned to a region can only use engines that list it; `global` is always listed. + DataRegions []ServerToolEngineDataRegion `json:"data_regions"` + // The `parameters.mode` a request without one runs and bills as; null for engines without modes. The `pricing[]` row with this `mode` is what an unmoded request bills + DefaultMode *string `json:"default_mode"` + // Who runs the tool call: the model provider during inference (`provider`), OpenRouter (`openrouter`), or the caller's application after the call is returned (`client`). + ExecutedBy ServerToolExecutedBy `json:"executed_by"` + // The `parameters.engine` value that selects this engine; null for the single engine of a tool without an engine parameter + ID *string `json:"id"` + Name string `json:"name"` + // The rows OpenRouter bills; non-empty exactly when `pricing_source` is `openrouter` + Pricing []ServerToolPrice `json:"pricing"` + // Where the rates are documented when `pricing_source` is `provider` or `byok`; null otherwise + PricingDocURL *string `json:"pricing_doc_url"` + // Who bills the engine's calls beyond the model's tokens: `openrouter` (the `pricing` rows, from the caller's credits), `provider` (a per-call tool fee from the model's provider on the inference call, at its own rates), `byok` (the engine's vendor, against the caller's own key), or `none` (no charge) + PricingSource PricingSource `json:"pricing_source"` +} + +func (s *ServerToolEngine) GetBYOK() BYOK { + if s == nil { + return BYOK("") + } + return s.BYOK +} + +func (s *ServerToolEngine) GetDataRegions() []ServerToolEngineDataRegion { + if s == nil { + return []ServerToolEngineDataRegion{} + } + return s.DataRegions +} + +func (s *ServerToolEngine) GetDefaultMode() *string { + if s == nil { + return nil + } + return s.DefaultMode +} + +func (s *ServerToolEngine) GetExecutedBy() ServerToolExecutedBy { + if s == nil { + return ServerToolExecutedBy("") + } + return s.ExecutedBy +} + +func (s *ServerToolEngine) GetID() *string { + if s == nil { + return nil + } + return s.ID +} + +func (s *ServerToolEngine) GetName() string { + if s == nil { + return "" + } + return s.Name +} + +func (s *ServerToolEngine) GetPricing() []ServerToolPrice { + if s == nil { + return []ServerToolPrice{} + } + return s.Pricing +} + +func (s *ServerToolEngine) GetPricingDocURL() *string { + if s == nil { + return nil + } + return s.PricingDocURL +} + +func (s *ServerToolEngine) GetPricingSource() PricingSource { + if s == nil { + return PricingSource("") + } + return s.PricingSource +} diff --git a/models/components/servertoolexecutedby.go b/models/components/servertoolexecutedby.go new file mode 100644 index 000000000..149bc4387 --- /dev/null +++ b/models/components/servertoolexecutedby.go @@ -0,0 +1,27 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +// ServerToolExecutedBy - Who runs the tool call: the model provider during inference (`provider`), OpenRouter (`openrouter`), or the caller's application after the call is returned (`client`). +type ServerToolExecutedBy string + +const ( + ServerToolExecutedByProvider ServerToolExecutedBy = "provider" + ServerToolExecutedByOpenrouter ServerToolExecutedBy = "openrouter" + ServerToolExecutedByClient ServerToolExecutedBy = "client" +) + +func (e ServerToolExecutedBy) ToPointer() *ServerToolExecutedBy { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolExecutedBy) IsExact() bool { + if e != nil { + switch *e { + case "provider", "openrouter", "client": + return true + } + } + return false +} diff --git a/models/components/servertoolinputname.go b/models/components/servertoolinputname.go new file mode 100644 index 000000000..fc4a6adec --- /dev/null +++ b/models/components/servertoolinputname.go @@ -0,0 +1,55 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ServerToolInputNameAPIFormat string + +const ( + ServerToolInputNameAPIFormatResponses ServerToolInputNameAPIFormat = "responses" + ServerToolInputNameAPIFormatChatCompletions ServerToolInputNameAPIFormat = "chat-completions" + ServerToolInputNameAPIFormatAnthropicMessages ServerToolInputNameAPIFormat = "anthropic-messages" +) + +func (e ServerToolInputNameAPIFormat) ToPointer() *ServerToolInputNameAPIFormat { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolInputNameAPIFormat) IsExact() bool { + if e != nil { + switch *e { + case "responses", "chat-completions", "anthropic-messages": + return true + } + } + return false +} + +type ServerToolInputName struct { + // API formats that accept this spelling in `tools[].type` + APIFormats []ServerToolInputNameAPIFormat `json:"api_formats"` + // What the call surfaces as on each accepting API format when requested under this spelling; a format is absent when the call is not visible to the caller + OutputNames []ServerToolOutputName `json:"output_names"` + Type string `json:"type"` +} + +func (s *ServerToolInputName) GetAPIFormats() []ServerToolInputNameAPIFormat { + if s == nil { + return []ServerToolInputNameAPIFormat{} + } + return s.APIFormats +} + +func (s *ServerToolInputName) GetOutputNames() []ServerToolOutputName { + if s == nil { + return []ServerToolOutputName{} + } + return s.OutputNames +} + +func (s *ServerToolInputName) GetType() string { + if s == nil { + return "" + } + return s.Type +} diff --git a/models/components/servertoolnativemodel.go b/models/components/servertoolnativemodel.go new file mode 100644 index 000000000..4a1f9b1b7 --- /dev/null +++ b/models/components/servertoolnativemodel.go @@ -0,0 +1,22 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ServerToolNativeModel struct { + Providers []string `json:"providers"` + Slug string `json:"slug"` +} + +func (s *ServerToolNativeModel) GetProviders() []string { + if s == nil { + return []string{} + } + return s.Providers +} + +func (s *ServerToolNativeModel) GetSlug() string { + if s == nil { + return "" + } + return s.Slug +} diff --git a/models/components/servertoolnativesupport.go b/models/components/servertoolnativesupport.go new file mode 100644 index 000000000..aa5911804 --- /dev/null +++ b/models/components/servertoolnativesupport.go @@ -0,0 +1,23 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +// ServerToolNativeSupport - Endpoints whose provider runs this tool itself during inference. Zero for tools no provider runs natively. +type ServerToolNativeSupport struct { + EndpointCount int64 `json:"endpoint_count"` + ModelCount int64 `json:"model_count"` +} + +func (s *ServerToolNativeSupport) GetEndpointCount() int64 { + if s == nil { + return 0 + } + return s.EndpointCount +} + +func (s *ServerToolNativeSupport) GetModelCount() int64 { + if s == nil { + return 0 + } + return s.ModelCount +} diff --git a/models/components/servertooloutputname.go b/models/components/servertooloutputname.go new file mode 100644 index 000000000..8f6546092 --- /dev/null +++ b/models/components/servertooloutputname.go @@ -0,0 +1,55 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ServerToolOutputNameAPIFormat string + +const ( + ServerToolOutputNameAPIFormatResponses ServerToolOutputNameAPIFormat = "responses" + ServerToolOutputNameAPIFormatChatCompletions ServerToolOutputNameAPIFormat = "chat-completions" + ServerToolOutputNameAPIFormatAnthropicMessages ServerToolOutputNameAPIFormat = "anthropic-messages" +) + +func (e ServerToolOutputNameAPIFormat) ToPointer() *ServerToolOutputNameAPIFormat { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *ServerToolOutputNameAPIFormat) IsExact() bool { + if e != nil { + switch *e { + case "responses", "chat-completions", "anthropic-messages": + return true + } + } + return false +} + +type ServerToolOutputName struct { + APIFormat ServerToolOutputNameAPIFormat `json:"api_format"` + // Anthropic Messages `server_tool_use` block `name`, when the call surfaces as one + Name *string `json:"name,omitzero"` + // Output item `type` on Responses, content block `type` on Anthropic Messages, `reasoning_details[].type` on Chat Completions + Type string `json:"type"` +} + +func (s *ServerToolOutputName) GetAPIFormat() ServerToolOutputNameAPIFormat { + if s == nil { + return ServerToolOutputNameAPIFormat("") + } + return s.APIFormat +} + +func (s *ServerToolOutputName) GetName() *string { + if s == nil { + return nil + } + return s.Name +} + +func (s *ServerToolOutputName) GetType() string { + if s == nil { + return "" + } + return s.Type +} diff --git a/models/components/servertoolprice.go b/models/components/servertoolprice.go new file mode 100644 index 000000000..0a8d8940f --- /dev/null +++ b/models/components/servertoolprice.go @@ -0,0 +1,40 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package components + +type ServerToolPrice struct { + MaxUnitsPerCall int64 `json:"max_units_per_call"` + // The `parameters.mode` this price applies to; null for prices that do not depend on the mode. A request bills exactly one `request` row + Mode *string `json:"mode"` + // USD per unit, as a decimal string + Price string `json:"price"` + Unit string `json:"unit"` +} + +func (s *ServerToolPrice) GetMaxUnitsPerCall() int64 { + if s == nil { + return 0 + } + return s.MaxUnitsPerCall +} + +func (s *ServerToolPrice) GetMode() *string { + if s == nil { + return nil + } + return s.Mode +} + +func (s *ServerToolPrice) GetPrice() string { + if s == nil { + return "" + } + return s.Price +} + +func (s *ServerToolPrice) GetUnit() string { + if s == nil { + return "" + } + return s.Unit +} diff --git a/models/operations/gettool.go b/models/operations/gettool.go new file mode 100644 index 000000000..c558c0232 --- /dev/null +++ b/models/operations/gettool.go @@ -0,0 +1,61 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "github.com/OpenRouterTeam/go-sdk/internal/utils" + "github.com/OpenRouterTeam/go-sdk/models/components" +) + +type GetToolSecurity struct { + Bearer string `security:"scheme,type=http,subtype=bearer,name=Authorization,env=openrouter_bearer"` +} + +func (g *GetToolSecurity) GetBearer() string { + if g == nil { + return "" + } + return g.Bearer +} + +type GetToolRequest struct { + // Canonical `openrouter:*` name or any accepted `tools[].type` alias + Name string `pathParam:"style=simple,explode=false,name=name"` +} + +func (g *GetToolRequest) GetName() string { + if g == nil { + return "" + } + return g.Name +} + +type GetToolResponse struct { + Headers map[string][]string + Result *components.GetToolResponse +} + +func (g GetToolResponse) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(g, "", false) +} + +func (g *GetToolResponse) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &g, "", false, nil); err != nil { + return err + } + return nil +} + +func (g *GetToolResponse) GetHeaders() map[string][]string { + if g == nil { + return map[string][]string{} + } + return g.Headers +} + +func (g *GetToolResponse) GetResult() *components.GetToolResponse { + if g == nil { + return nil + } + return g.Result +} diff --git a/models/operations/listtools.go b/models/operations/listtools.go new file mode 100644 index 000000000..09b94db27 --- /dev/null +++ b/models/operations/listtools.go @@ -0,0 +1,84 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package operations + +import ( + "github.com/OpenRouterTeam/go-sdk/internal/utils" + "github.com/OpenRouterTeam/go-sdk/optionalnullable" +) + +type ListToolsSecurity struct { + Bearer string `security:"scheme,type=http,subtype=bearer,name=Authorization,env=openrouter_bearer"` +} + +func (l *ListToolsSecurity) GetBearer() string { + if l == nil { + return "" + } + return l.Bearer +} + +// APIFormat - Only tools usable on this API format +type APIFormat string + +const ( + APIFormatResponses APIFormat = "responses" + APIFormatChatCompletions APIFormat = "chat-completions" + APIFormatAnthropicMessages APIFormat = "anthropic-messages" +) + +func (e APIFormat) ToPointer() *APIFormat { + return &e +} + +// IsExact returns true if the value matches a known enum value, false otherwise. +func (e *APIFormat) IsExact() bool { + if e != nil { + switch *e { + case "responses", "chat-completions", "anthropic-messages": + return true + } + } + return false +} + +type ListToolsRequest struct { + // Number of records to skip for pagination. When both offset and limit are omitted, the full list is returned + Offset optionalnullable.OptionalNullable[int64] `default:"0" queryParam:"style=form,explode=true,name=offset"` + // Maximum number of records to return (max 100). When both offset and limit are omitted, the full list is returned + Limit *int64 `default:"50" queryParam:"style=form,explode=true,name=limit"` + // Only tools usable on this API format + APIFormat *APIFormat `queryParam:"style=form,explode=true,name=api_format"` +} + +func (l ListToolsRequest) MarshalJSON() ([]byte, error) { + return utils.MarshalJSON(l, "", false) +} + +func (l *ListToolsRequest) UnmarshalJSON(data []byte) error { + if err := utils.UnmarshalJSON(data, &l, "", false, nil); err != nil { + return err + } + return nil +} + +func (l *ListToolsRequest) GetOffset() optionalnullable.OptionalNullable[int64] { + if l == nil { + return nil + } + return l.Offset +} + +func (l *ListToolsRequest) GetLimit() *int64 { + if l == nil { + return nil + } + return l.Limit +} + +func (l *ListToolsRequest) GetAPIFormat() *APIFormat { + if l == nil { + return nil + } + return l.APIFormat +} diff --git a/openrouter.go b/openrouter.go index 74fad63db..ef00634cb 100644 --- a/openrouter.go +++ b/openrouter.go @@ -73,6 +73,20 @@ type OpenRouter struct { Benchmarks *Benchmarks // BYOK endpoints BYOK *BYOK + // Stream a chat completion with an intern + // Sends a prompt to one of your interns and streams the reply as OpenAI-compatible server-sent events ending with `[DONE]`. The run executes on the intern, which may pause to ask you something. It then streams one `openrouter.provide_input` tool call and finishes with `finish_reason: "tool_calls"`, and the run stays open on the intern. + // + // Every response, whether it ends with `stop`, `tool_calls` or `error`, is followed by a final chunk with empty `choices` that carries `session_id`, then `data: [DONE]`. That chunk carries the `usage` the intern reported for the run, after `stop` or `error`, and `null` when the intern reported none. After `tool_calls` its `usage` is `null` because the turn is not over. Read through `[DONE]`: the `session_id` you need to reply arrives after the `tool_calls` finish chunk. + // + // To answer, send a second request with the same `session_id`, the assistant message echoing that tool call, and a `tool` message whose `tool_call_id` is the tool call id and whose `content` is the answer. The answer is delivered to the run that asked and the stream continues from where it paused. A question stays open for its interaction deadline (5 minutes by default) and the run is cancelled when that passes. Rejected replies do not extend the deadline. + // + // Closing the connection after the `[DONE]` that follows `finish_reason: "tool_calls"` keeps the run alive. Disconnecting while a response is still streaming cancels the run. The stream writes a `: keepalive` comment whenever nothing else has been written for 30 seconds, so a disconnect is noticed within that interval even while the intern is silent. + // + // A run the intern ends while you are still connected, by cancellation or by a deadline, ends the stream with a `finish_reason: "error"` chunk carrying `410` and reason `run_ended`, then the final empty-`choices` chunk and `[DONE]`. That error reports only an ending the intern confirmed. A connection that breaks without that confirmation ends with reason `stream_severed`, and a client that has already disconnected is promised no final event. + // + // Set `approval_mode` to `manual` to have the intern ask before approval-bearing tools such as the shell. Omitted, the run self-drives and consents on your behalf. The mode belongs to the run started by that prompt and must be repeated on later prompts. + // + // Available to interns programme members. Callers outside the programme receive `404` for every path under `/api/v1/interns`. Chat *Chat // Task classification market-share endpoints Classifications *Classifications @@ -119,6 +133,8 @@ type OpenRouter struct { Scim *Scim // System One endpoints for models such as Jev, compatible with the TypeSafe SDKs. See https://openrouter.ai/docs/guides/community/typesafe-sdk. SystemOne *SystemOne + // The catalog of server tools OpenRouter runs on behalf of a model: accepted `tools[].type` spellings per API format, engines and pricing, and which endpoints run each tool natively. See https://openrouter.ai/docs/guides/features/server-tools. + Tools *Tools // Store host-bound secrets for a workspace or for one intern. Scope is selected by the API key. Responses return metadata only, never secret values. See https://openrouter.ai/docs/guides/ori/vault. Vault *Vault // Video Generation endpoints @@ -216,9 +232,9 @@ func WithTimeout(timeout time.Duration) SDKOption { // New creates a new instance of the SDK with the provided options func New(opts ...SDKOption) *OpenRouter { sdk := &OpenRouter{ - SDKVersion: "0.9.7", + SDKVersion: "0.9.8", sdkConfiguration: config.SDKConfiguration{ - UserAgent: "speakeasy-sdk/go 0.9.7 2.914.0 1.0.0 github.com/OpenRouterTeam/go-sdk", + UserAgent: "speakeasy-sdk/go 0.9.8 2.914.0 1.0.0 github.com/OpenRouterTeam/go-sdk", Globals: globals.Globals{}, ServerList: ServerList, }, @@ -276,6 +292,7 @@ func New(opts ...SDKOption) *OpenRouter { sdk.Beta = newBeta(sdk, sdk.sdkConfiguration, sdk.hooks) sdk.Scim = newScim(sdk, sdk.sdkConfiguration, sdk.hooks) sdk.SystemOne = newSystemOne(sdk, sdk.sdkConfiguration, sdk.hooks) + sdk.Tools = newTools(sdk, sdk.sdkConfiguration, sdk.hooks) sdk.Vault = newVault(sdk, sdk.sdkConfiguration, sdk.hooks) sdk.VideoGeneration = newVideoGeneration(sdk, sdk.sdkConfiguration, sdk.hooks) sdk.Workspaces = newWorkspaces(sdk, sdk.sdkConfiguration, sdk.hooks) diff --git a/tools.go b/tools.go new file mode 100644 index 000000000..34e98085a --- /dev/null +++ b/tools.go @@ -0,0 +1,632 @@ +// Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + +package openrouter + +import ( + "bytes" + "context" + "fmt" + "github.com/OpenRouterTeam/go-sdk/internal/config" + "github.com/OpenRouterTeam/go-sdk/internal/hooks" + "github.com/OpenRouterTeam/go-sdk/internal/utils" + "github.com/OpenRouterTeam/go-sdk/models/components" + "github.com/OpenRouterTeam/go-sdk/models/operations" + "github.com/OpenRouterTeam/go-sdk/models/sdkerrors" + "github.com/OpenRouterTeam/go-sdk/optionalnullable" + "github.com/OpenRouterTeam/go-sdk/retry" + "net/http" + "net/url" +) + +// Tools - The catalog of server tools OpenRouter runs on behalf of a model: accepted `tools[].type` spellings per API format, engines and pricing, and which endpoints run each tool natively. See https://openrouter.ai/docs/guides/features/server-tools. +type Tools struct { + rootSDK *OpenRouter + sdkConfiguration config.SDKConfiguration + hooks *hooks.Hooks +} + +func newTools(rootSDK *OpenRouter, sdkConfig config.SDKConfiguration, hooks *hooks.Hooks) *Tools { + return &Tools{ + rootSDK: rootSDK, + sdkConfiguration: sdkConfig, + hooks: hooks, + } +} + +// ListTools - List server tools +// Lists every server tool OpenRouter can run on behalf of a model: accepted `tools[].type` spellings per API format, the engines behind it with their pricing, and how many endpoints run it natively. +func (s *Tools) ListTools(ctx context.Context, security operations.ListToolsSecurity, offset optionalnullable.OptionalNullable[int64], limit *int64, apiFormat *operations.APIFormat, opts ...operations.Option) (*components.ListToolsResponse, error) { + request := operations.ListToolsRequest{ + Offset: offset, + Limit: limit, + APIFormat: apiFormat, + } + + o := operations.Options{} + supportedOptions := []string{ + operations.SupportedOptionRetries, + operations.SupportedOptionTimeout, + } + + for _, opt := range opts { + if err := opt(&o, supportedOptions...); err != nil { + return nil, fmt.Errorf("error applying option: %w", err) + } + } + + var baseURL string + if o.ServerURL == nil { + baseURL = utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + } else { + baseURL = *o.ServerURL + } + opURL, err := url.JoinPath(baseURL, "/tools") + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + hookCtx := hooks.HookContext{ + SDK: s.rootSDK, + SDKConfiguration: s.sdkConfiguration, + BaseURL: baseURL, + Context: ctx, + OperationID: "listTools", + OAuth2Scopes: nil, + SecuritySource: utils.AsSecuritySource(security), + } + + timeout := o.Timeout + if timeout == nil { + timeout = s.sdkConfiguration.Timeout + } + + if timeout != nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, *timeout) + defer cancel() + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateQueryParams(ctx, req, request, nil, nil); err != nil { + return nil, fmt.Errorf("error populating query params: %w", err) + } + + if err := utils.PopulateSecurity(ctx, req, utils.AsSecuritySource(security)); err != nil { + return nil, err + } + + for k, v := range o.SetHeaders { + req.Header.Set(k, v) + } + + globalRetryConfig := s.sdkConfiguration.RetryConfig + retryConfig := o.Retries + if retryConfig == nil { + if globalRetryConfig != nil { + retryConfig = globalRetryConfig + } else { + retryConfig = &retry.Config{ + Strategy: "backoff", Backoff: &retry.BackoffStrategy{ + InitialInterval: 500, + MaxInterval: 60000, + Exponent: 1.5, + MaxElapsedTime: 3600000, + }, + RetryConnectionErrors: true, + } + } + } + + var httpRes *http.Response + if retryConfig != nil { + httpRes, err = utils.Retry(ctx, utils.Retries{ + Config: retryConfig, + StatusCodes: []string{ + "5XX", + }, + }, func() (*http.Response, error) { + if req.Body != nil && req.Body != http.NoBody && req.GetBody != nil { + copyBody, err := req.GetBody() + + if err != nil { + return nil, err + } + + req.Body = copyBody + } + + req, err = s.hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + if retry.IsPermanentError(err) || retry.IsTemporaryError(err) { + return nil, err + } + + return nil, retry.Permanent(err) + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + } + return httpRes, err + }) + + if err != nil { + return nil, err + } else { + httpRes, err = s.hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } else { + req, err = s.hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err = s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"4XX", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out components.ListToolsResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return &out, nil + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.UnauthorizedResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.ForbiddenResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.NotFoundResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.InternalServerResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } + + return nil, nil + +} + +// GetTool - Get a server tool +// One server tool by canonical name or any accepted alias, with the models that run it natively. +func (s *Tools) GetTool(ctx context.Context, security operations.GetToolSecurity, name string, opts ...operations.Option) (*operations.GetToolResponse, error) { + request := operations.GetToolRequest{ + Name: name, + } + + o := operations.Options{} + supportedOptions := []string{ + operations.SupportedOptionRetries, + operations.SupportedOptionTimeout, + } + + for _, opt := range opts { + if err := opt(&o, supportedOptions...); err != nil { + return nil, fmt.Errorf("error applying option: %w", err) + } + } + + var baseURL string + if o.ServerURL == nil { + baseURL = utils.ReplaceParameters(s.sdkConfiguration.GetServerDetails()) + } else { + baseURL = *o.ServerURL + } + opURL, err := utils.GenerateURL(ctx, baseURL, "/tools/{name}", request, nil) + if err != nil { + return nil, fmt.Errorf("error generating URL: %w", err) + } + + hookCtx := hooks.HookContext{ + SDK: s.rootSDK, + SDKConfiguration: s.sdkConfiguration, + BaseURL: baseURL, + Context: ctx, + OperationID: "getTool", + OAuth2Scopes: nil, + SecuritySource: utils.AsSecuritySource(security), + } + + timeout := o.Timeout + if timeout == nil { + timeout = s.sdkConfiguration.Timeout + } + + if timeout != nil { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(ctx, *timeout) + defer cancel() + } + + req, err := http.NewRequestWithContext(ctx, "GET", opURL, nil) + if err != nil { + return nil, fmt.Errorf("error creating request: %w", err) + } + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", s.sdkConfiguration.UserAgent) + + if err := utils.PopulateSecurity(ctx, req, utils.AsSecuritySource(security)); err != nil { + return nil, err + } + + for k, v := range o.SetHeaders { + req.Header.Set(k, v) + } + + globalRetryConfig := s.sdkConfiguration.RetryConfig + retryConfig := o.Retries + if retryConfig == nil { + if globalRetryConfig != nil { + retryConfig = globalRetryConfig + } else { + retryConfig = &retry.Config{ + Strategy: "backoff", Backoff: &retry.BackoffStrategy{ + InitialInterval: 500, + MaxInterval: 60000, + Exponent: 1.5, + MaxElapsedTime: 3600000, + }, + RetryConnectionErrors: true, + } + } + } + + var httpRes *http.Response + if retryConfig != nil { + httpRes, err = utils.Retry(ctx, utils.Retries{ + Config: retryConfig, + StatusCodes: []string{ + "5XX", + }, + }, func() (*http.Response, error) { + if req.Body != nil && req.Body != http.NoBody && req.GetBody != nil { + copyBody, err := req.GetBody() + + if err != nil { + return nil, err + } + + req.Body = copyBody + } + + req, err = s.hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + if retry.IsPermanentError(err) || retry.IsTemporaryError(err) { + return nil, err + } + + return nil, retry.Permanent(err) + } + + httpRes, err := s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + } + return httpRes, err + }) + + if err != nil { + return nil, err + } else { + httpRes, err = s.hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } else { + req, err = s.hooks.BeforeRequest(hooks.BeforeRequestContext{HookContext: hookCtx}, req) + if err != nil { + return nil, err + } + + httpRes, err = s.sdkConfiguration.Client.Do(req) + if err != nil || httpRes == nil { + if err != nil { + err = fmt.Errorf("error sending request: %w", err) + } else { + err = fmt.Errorf("error sending request: no response") + } + + _, err = s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, nil, err) + return nil, err + } else if utils.MatchStatusCodes([]string{"4XX", "5XX"}, httpRes.StatusCode) { + _httpRes, err := s.hooks.AfterError(hooks.AfterErrorContext{HookContext: hookCtx}, httpRes, nil) + if err != nil { + return nil, err + } else if _httpRes != nil { + httpRes = _httpRes + } + } else { + httpRes, err = s.hooks.AfterSuccess(hooks.AfterSuccessContext{HookContext: hookCtx}, httpRes) + if err != nil { + return nil, err + } + } + } + + res := &operations.GetToolResponse{} + + switch { + case httpRes.StatusCode == 200: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out components.GetToolResponse + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + res.Result = &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 308: + res.Headers = httpRes.Header + + utils.DrainBody(httpRes) + case httpRes.StatusCode == 401: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.UnauthorizedResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 403: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.ForbiddenResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 404: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.NotFoundResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode == 500: + switch { + case utils.MatchContentType(httpRes.Header.Get("Content-Type"), `application/json`): + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + + var out sdkerrors.InternalServerResponseError + if err := utils.UnmarshalJsonFromResponseBody(bytes.NewBuffer(rawBody), &out, ""); err != nil { + return nil, err + } + + return nil, &out + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError(fmt.Sprintf("unknown content-type received: %s", httpRes.Header.Get("Content-Type")), httpRes.StatusCode, string(rawBody), httpRes) + } + case httpRes.StatusCode >= 400 && httpRes.StatusCode < 500: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + case httpRes.StatusCode >= 500 && httpRes.StatusCode < 600: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("API error occurred", httpRes.StatusCode, string(rawBody), httpRes) + default: + rawBody, err := utils.ConsumeRawBody(httpRes) + if err != nil { + return nil, err + } + return nil, sdkerrors.NewAPIError("unknown status code returned", httpRes.StatusCode, string(rawBody), httpRes) + } + + return res, nil + +} From e93a66db226684aadd52b804df7d64d34532fb65 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:15:12 +0000 Subject: [PATCH 2/3] docs: sync install snippets to v0.9.8 --- OVERVIEW.md | 2 +- README.md | 2 +- doc.go | 2 +- example_test.go | 2 +- examples/README.md | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/OVERVIEW.md b/OVERVIEW.md index 44fe4bc8d..a1b7e5099 100644 --- a/OVERVIEW.md +++ b/OVERVIEW.md @@ -117,7 +117,7 @@ go get github.com/OpenRouterTeam/go-sdk For beta releases, pin an explicit version: ```bash -go get github.com/OpenRouterTeam/go-sdk@v0.9.7 +go get github.com/OpenRouterTeam/go-sdk@v0.9.8 ``` **Requirements:** Go 1.25 or higher diff --git a/README.md b/README.md index a4e3c0ebf..7274be45c 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ To learn more, see the [API Reference](https://openrouter.ai/docs/sdks/go/api-re > This SDK is in **beta**. Pin to a specific version to avoid unexpected breaking changes: > > ```bash -> go get github.com/OpenRouterTeam/go-sdk@v0.9.7 +> go get github.com/OpenRouterTeam/go-sdk@v0.9.8 > ``` diff --git a/doc.go b/doc.go index 6933edf29..3ad9e44a9 100644 --- a/doc.go +++ b/doc.go @@ -6,7 +6,7 @@ provider selection, and unified billing. This SDK is in beta. Pin to a specific module version to avoid unexpected breaking changes: - go get github.com/OpenRouterTeam/go-sdk@v0.9.7 + go get github.com/OpenRouterTeam/go-sdk@v0.9.8 For full API documentation, visit: https://openrouter.ai/docs/client-sdks/go/overview diff --git a/example_test.go b/example_test.go index 9b48471bc..b3408852d 100644 --- a/example_test.go +++ b/example_test.go @@ -18,7 +18,7 @@ func ExampleNew() { openrouter.WithSecurity("your-api-key"), ) fmt.Println(sdk.SDKVersion) - // Output: 0.9.7 + // Output: 0.9.8 } // Example demonstrates basic usage of the OpenRouter SDK for chat completions. diff --git a/examples/README.md b/examples/README.md index 97b811a33..63c911751 100644 --- a/examples/README.md +++ b/examples/README.md @@ -43,7 +43,7 @@ cd ../generation && go run . Each example pins a released SDK version in `go.mod`: ```go -require github.com/OpenRouterTeam/go-sdk v0.9.7 +require github.com/OpenRouterTeam/go-sdk v0.9.8 ``` This should match the version in [README.md](../README.md) and `.speakeasy/gen.lock` `releaseVersion`. CI runs `scripts/bump-examples.sh` after releases to keep these in sync. @@ -51,7 +51,7 @@ This should match the version in [README.md](../README.md) and `.speakeasy/gen.l To use a different version: ```bash -go get github.com/OpenRouterTeam/go-sdk@v0.9.7 +go get github.com/OpenRouterTeam/go-sdk@v0.9.8 go run . ``` From 005d4a7f10d9879eebf6359ba946bc67329fb0f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 22:15:26 +0000 Subject: [PATCH 3/3] Chore: regenerate docs navigation Auto-generated-by: update-generated-files-action; https://github.com/OpenRouterTeam/go-sdk/actions/runs/36638460478 --- docs/docs.json | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/docs.json b/docs/docs.json index f5f2b8062..be5b6d62b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -41,6 +41,7 @@ "sdks/scim/README", "sdks/stt/README", "sdks/systemone/README", + "sdks/tools/README", "sdks/tts/README", "sdks/vault/README", "sdks/videogeneration/README",