@markusylisiurunen/tau 0.3.79 → 0.3.80

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (240) hide show
  1. package/dist/core/agent/agent_runtime.js +68 -76
  2. package/dist/core/agent/agent_runtime.js.map +1 -1
  3. package/dist/core/auth/auth_manager.js +3 -7
  4. package/dist/core/auth/auth_manager.js.map +1 -1
  5. package/dist/core/auth/auth_messages.js +1 -1
  6. package/dist/core/auth/auth_messages.js.map +1 -1
  7. package/dist/core/auth/auth_storage.js +71 -7
  8. package/dist/core/auth/auth_storage.js.map +1 -1
  9. package/dist/core/auth/cli.js +8 -7
  10. package/dist/core/auth/cli.js.map +1 -1
  11. package/dist/core/auth/credential_store.js +88 -186
  12. package/dist/core/auth/credential_store.js.map +1 -1
  13. package/dist/core/auth/index.js +1 -1
  14. package/dist/core/auth/index.js.map +1 -1
  15. package/dist/core/auth/providers/openai_codex.js +51 -229
  16. package/dist/core/auth/providers/openai_codex.js.map +1 -1
  17. package/dist/core/cli.js +1 -2
  18. package/dist/core/cli.js.map +1 -1
  19. package/dist/core/config/content_loader.js +27 -130
  20. package/dist/core/config/content_loader.js.map +1 -1
  21. package/dist/core/config/index.js.map +1 -1
  22. package/dist/core/config/paths.js +0 -1
  23. package/dist/core/config/paths.js.map +1 -1
  24. package/dist/core/config/runtime.js +3 -2
  25. package/dist/core/config/runtime.js.map +1 -1
  26. package/dist/core/config/runtime_config_snapshot.js +23 -9
  27. package/dist/core/config/runtime_config_snapshot.js.map +1 -1
  28. package/dist/core/config/schema.js +13 -69
  29. package/dist/core/config/schema.js.map +1 -1
  30. package/dist/core/config/skills_loader.js +6 -2
  31. package/dist/core/config/skills_loader.js.map +1 -1
  32. package/dist/core/debug.js +1 -16
  33. package/dist/core/debug.js.map +1 -1
  34. package/dist/core/index.js +2 -2
  35. package/dist/core/index.js.map +1 -1
  36. package/dist/core/models/catalog.js +2 -239
  37. package/dist/core/models/catalog.js.map +1 -1
  38. package/dist/core/personas.js +0 -14
  39. package/dist/core/personas.js.map +1 -1
  40. package/dist/core/runtime/agent_model.js +0 -3
  41. package/dist/core/runtime/agent_model.js.map +1 -1
  42. package/dist/core/runtime/chat_runtime.js +16 -13
  43. package/dist/core/runtime/chat_runtime.js.map +1 -1
  44. package/dist/core/runtime/runtime_bootstrap.js +12 -59
  45. package/dist/core/runtime/runtime_bootstrap.js.map +1 -1
  46. package/dist/core/session/auto_compaction_archive.js +1 -1
  47. package/dist/core/session/auto_compaction_archive.js.map +1 -1
  48. package/dist/core/session/compaction.js +79 -506
  49. package/dist/core/session/compaction.js.map +1 -1
  50. package/dist/core/static/tau_docs/config-reference.md +12 -37
  51. package/dist/core/static/tau_docs/configuration.md +3 -16
  52. package/dist/core/static/tau_docs/credentials.md +20 -50
  53. package/dist/core/static/tau_docs/index.md +2 -1
  54. package/dist/core/static/tau_docs/manifest.json +1 -0
  55. package/dist/core/static/tau_docs/models.md +8 -159
  56. package/dist/core/static/tau_docs/openrouter.md +165 -0
  57. package/dist/core/static/tau_docs/ownership-and-scope.md +3 -3
  58. package/dist/core/static/tau_docs/personas.md +9 -41
  59. package/dist/core/static/tau_docs/prompts-and-project-context.md +10 -44
  60. package/dist/core/static/tau_docs/remote-sessions.md +6 -7
  61. package/dist/core/static/tau_docs/security.md +4 -5
  62. package/dist/core/static/tau_docs/session-protocol-methods.md +0 -1
  63. package/dist/core/static/tau_docs/session-protocol.md +11 -9
  64. package/dist/core/static/tau_docs/sessions.md +8 -6
  65. package/dist/core/static/tau_docs/skills.md +8 -32
  66. package/dist/core/static/tau_docs/subagents.md +2 -2
  67. package/dist/core/static/tau_docs/telegram.md +2 -2
  68. package/dist/core/static/tau_docs/tools.md +2 -1
  69. package/dist/core/static/tau_docs/troubleshooting.md +11 -12
  70. package/dist/core/static/tau_docs/tui.md +4 -2
  71. package/dist/core/subagents/agent_supervisor.js +0 -1
  72. package/dist/core/subagents/agent_supervisor.js.map +1 -1
  73. package/dist/core/telegram/adapter.js +1 -1
  74. package/dist/core/telegram/adapter.js.map +1 -1
  75. package/dist/core/tool/cli.js +10 -2
  76. package/dist/core/tool/cli.js.map +1 -1
  77. package/dist/core/tool/openrouter.js +291 -0
  78. package/dist/core/tool/openrouter.js.map +1 -0
  79. package/dist/core/tool/openrouter_decisions.js +97 -0
  80. package/dist/core/tool/openrouter_decisions.js.map +1 -0
  81. package/dist/core/tool/openrouter_media.js +180 -0
  82. package/dist/core/tool/openrouter_media.js.map +1 -0
  83. package/dist/core/tools/tau_docs.js +1 -0
  84. package/dist/core/tools/tau_docs.js.map +1 -1
  85. package/dist/core/utils/model_stream.js +47 -34
  86. package/dist/core/utils/model_stream.js.map +1 -1
  87. package/dist/core/utils/user_metadata.js +2 -27
  88. package/dist/core/utils/user_metadata.js.map +1 -1
  89. package/dist/core/version.js +2 -2
  90. package/dist/core/version.js.map +1 -1
  91. package/dist/diff_tool/app/dist/assets/{ada-C5qYipkI.js → ada-X3Y2mlq2.js} +1 -1
  92. package/dist/diff_tool/app/dist/assets/{ahk-CA9gdOdF.js → ahk-DwADkxyd.js} +1 -1
  93. package/dist/diff_tool/app/dist/assets/{angular-html-CnO8qept.js → angular-html-BbLgbIhq.js} +1 -1
  94. package/dist/diff_tool/app/dist/assets/{angular-ts-DPXUio9Z.js → angular-ts-DXk17TRM.js} +1 -1
  95. package/dist/diff_tool/app/dist/assets/{apl-X8YsymsQ.js → apl-BsvksCXR.js} +1 -1
  96. package/dist/diff_tool/app/dist/assets/{astro-BQ9k8AQ0.js → astro-DH775E4V.js} +1 -1
  97. package/dist/diff_tool/app/dist/assets/beancount-C2IN4Vk8.js +1 -0
  98. package/dist/diff_tool/app/dist/assets/{blade-DZ1LYIzB.js → blade-Ck99Rm59.js} +1 -1
  99. package/dist/diff_tool/app/dist/assets/{c-VLTwNh7z.js → c-DJpHqu5J.js} +1 -1
  100. package/dist/diff_tool/app/dist/assets/{chapel-5s-sGN8D.js → chapel-Owff0Csy.js} +1 -1
  101. package/dist/diff_tool/app/dist/assets/{cobol-C9RzwrVu.js → cobol-Cv2gZuhO.js} +1 -1
  102. package/dist/diff_tool/app/dist/assets/{coffee-BHvjZ343.js → coffee-Bji0YCf_.js} +1 -1
  103. package/dist/diff_tool/app/dist/assets/coq-CGaSfhwR.js +1 -0
  104. package/dist/diff_tool/app/dist/assets/{cpp-CBTVXbBp.js → cpp-DTjA_yFF.js} +1 -1
  105. package/dist/diff_tool/app/dist/assets/{crystal-DQJua4y4.js → crystal-Dd00NOeb.js} +1 -1
  106. package/dist/diff_tool/app/dist/assets/csharp-dmMxLVLW.js +1 -0
  107. package/dist/diff_tool/app/dist/assets/css-D44TN1V6.js +1 -0
  108. package/dist/diff_tool/app/dist/assets/dart-CHZY9Xhz.js +1 -0
  109. package/dist/diff_tool/app/dist/assets/dotenv-CuH5my32.js +1 -0
  110. package/dist/diff_tool/app/dist/assets/{edge-BmdmXGH4.js → edge-CVmGSi2m.js} +1 -1
  111. package/dist/diff_tool/app/dist/assets/{elixir-oiOLs98L.js → elixir-B8Mq7no2.js} +1 -1
  112. package/dist/diff_tool/app/dist/assets/{elm-BgYuiU4E.js → elm-CXS0I3Z2.js} +1 -1
  113. package/dist/diff_tool/app/dist/assets/emacs-lisp-DR2vtWaj.js +1 -0
  114. package/dist/diff_tool/app/dist/assets/{erb-CvFrXpyY.js → erb-B9oDKaUo.js} +1 -1
  115. package/dist/diff_tool/app/dist/assets/{git-rebase-D3Zo1BLH.js → git-rebase-DT-YFebH.js} +1 -1
  116. package/dist/diff_tool/app/dist/assets/{glimmer-js-B4-8E3lJ.js → glimmer-js-s0DXlNjq.js} +1 -1
  117. package/dist/diff_tool/app/dist/assets/{glimmer-ts-CtKkD0t_.js → glimmer-ts-QgEB5S2z.js} +1 -1
  118. package/dist/diff_tool/app/dist/assets/{glsl-BAqforx_.js → glsl-NA0icwbY.js} +1 -1
  119. package/dist/diff_tool/app/dist/assets/gn-CAXYAgV-.js +1 -0
  120. package/dist/diff_tool/app/dist/assets/{graphql-DuE1RMyL.js → graphql-0_dOlfV0.js} +1 -1
  121. package/dist/diff_tool/app/dist/assets/{hack-CHBcXjz1.js → hack-D-mr7l1l.js} +1 -1
  122. package/dist/diff_tool/app/dist/assets/{haml-DAs2z3tD.js → haml-B0-oQmz7.js} +1 -1
  123. package/dist/diff_tool/app/dist/assets/handlebars-Yq9bXpWN.js +1 -0
  124. package/dist/diff_tool/app/dist/assets/{html-D5co0BLD.js → html-B8bMmdRK.js} +1 -1
  125. package/dist/diff_tool/app/dist/assets/{html-derivative-BZaWEmAT.js → html-derivative-BpxSlQb_.js} +1 -1
  126. package/dist/diff_tool/app/dist/assets/{http-Cii5MjJE.js → http-hS_53mxt.js} +1 -1
  127. package/dist/diff_tool/app/dist/assets/{hurl-Bur-XdJO.js → hurl-B2ST1kwl.js} +1 -1
  128. package/dist/diff_tool/app/dist/assets/index-CBT_sNIz.js +340 -0
  129. package/dist/diff_tool/app/dist/assets/{java-DN39wI4w.js → java-D4mj0lZJ.js} +1 -1
  130. package/dist/diff_tool/app/dist/assets/{javascript-VUReF1H4.js → javascript-wC7rrKiV.js} +1 -1
  131. package/dist/diff_tool/app/dist/assets/{jinja-BcrfV1JB.js → jinja-DbQ3o87F.js} +1 -1
  132. package/dist/diff_tool/app/dist/assets/{jison-Bez5Mtmy.js → jison-CrE9FdvP.js} +1 -1
  133. package/dist/diff_tool/app/dist/assets/{json-ChV8m0Le.js → json-xjicDyWN.js} +1 -1
  134. package/dist/diff_tool/app/dist/assets/{jsx-D0SXNtM0.js → jsx-m28lXojQ.js} +1 -1
  135. package/dist/diff_tool/app/dist/assets/{julia-DvhpcBwG.js → julia-19xkOmop.js} +1 -1
  136. package/dist/diff_tool/app/dist/assets/{just-BGwe8S6x.js → just-Cf7OorTr.js} +1 -1
  137. package/dist/diff_tool/app/dist/assets/latex-DDb7GQOy.js +1 -0
  138. package/dist/diff_tool/app/dist/assets/{liquid-UdnqDjKz.js → liquid-DHOuQ0rf.js} +1 -1
  139. package/dist/diff_tool/app/dist/assets/{lua-CjDHeHEr.js → lua-BGyIvonw.js} +1 -1
  140. package/dist/diff_tool/app/dist/assets/luau-VGWVLoqX.js +1 -0
  141. package/dist/diff_tool/app/dist/assets/marko-DB5OqI1C.js +1 -0
  142. package/dist/diff_tool/app/dist/assets/{mdc-BOLj6Oyq.js → mdc-DTyNMupO.js} +1 -1
  143. package/dist/diff_tool/app/dist/assets/monokai-BscAjiQZ.js +1 -0
  144. package/dist/diff_tool/app/dist/assets/moonbit-D9W784E_.js +1 -0
  145. package/dist/diff_tool/app/dist/assets/nextflow-CSgcYZcx.js +1 -0
  146. package/dist/diff_tool/app/dist/assets/{nextflow-groovy-DJMQeKeT.js → nextflow-groovy-D7IRt6Pp.js} +1 -1
  147. package/dist/diff_tool/app/dist/assets/{nginx-5r5xPc2T.js → nginx-DfF0fMYD.js} +1 -1
  148. package/dist/diff_tool/app/dist/assets/{nim-9exKQYMz.js → nim-BbwsXuZD.js} +1 -1
  149. package/dist/diff_tool/app/dist/assets/nushell--0fT3PI1.js +1 -0
  150. package/dist/diff_tool/app/dist/assets/one-dark-pro-C6YyR8OD.js +1 -0
  151. package/dist/diff_tool/app/dist/assets/{org-B2fpAlbt.js → org-BkOBBl1f.js} +1 -1
  152. package/dist/diff_tool/app/dist/assets/{perl-DV2fcwyY.js → perl-BTXTOl4K.js} +1 -1
  153. package/dist/diff_tool/app/dist/assets/php-DIMVQWiA.js +1 -0
  154. package/dist/diff_tool/app/dist/assets/{powershell-CCSX75yM.js → powershell-QtSnmXcu.js} +1 -1
  155. package/dist/diff_tool/app/dist/assets/{pug-DuKcQxFj.js → pug-B_nrb4dJ.js} +1 -1
  156. package/dist/diff_tool/app/dist/assets/{qml-C16b4SYx.js → qml-1PXi8G8Z.js} +1 -1
  157. package/dist/diff_tool/app/dist/assets/{r-B1ZldnJf.js → r-CJrAkc2Z.js} +1 -1
  158. package/dist/diff_tool/app/dist/assets/{razor-TYmslaAB.js → razor-DgPUftNd.js} +1 -1
  159. package/dist/diff_tool/app/dist/assets/red-CYlAq2b0.js +1 -0
  160. package/dist/diff_tool/app/dist/assets/{regexp-dWCffmDD.js → regexp-C2hS8XvL.js} +1 -1
  161. package/dist/diff_tool/app/dist/assets/{rst-DEkLr2YR.js → rst-CDouhKnc.js} +1 -1
  162. package/dist/diff_tool/app/dist/assets/{ruby-BJnJzr4u.js → ruby-CAjKW1uO.js} +1 -1
  163. package/dist/diff_tool/app/dist/assets/rust-DpiIf5JO.js +1 -0
  164. package/dist/diff_tool/app/dist/assets/{sas-DeRsDbUE.js → sas-qAHkHLc1.js} +1 -1
  165. package/dist/diff_tool/app/dist/assets/{scss-SGV_CwKm.js → scss-Bfx2Ydid.js} +1 -1
  166. package/dist/diff_tool/app/dist/assets/{shellscript-BI7khmmR.js → shellscript-Bu76R8y2.js} +1 -1
  167. package/dist/diff_tool/app/dist/assets/{shellsession-Nupw_Vvw.js → shellsession-BU8BL0oL.js} +1 -1
  168. package/dist/diff_tool/app/dist/assets/solarized-dark-b97czJOk.js +1 -0
  169. package/dist/diff_tool/app/dist/assets/solarized-light-DFPxpIYQ.js +1 -0
  170. package/dist/diff_tool/app/dist/assets/{soy-B96cBzxv.js → soy-FRl8ozP-.js} +1 -1
  171. package/dist/diff_tool/app/dist/assets/sql-BacQgsEs.js +1 -0
  172. package/dist/diff_tool/app/dist/assets/{stata-Dnq48cE6.js → stata-B9kkG-ET.js} +1 -1
  173. package/dist/diff_tool/app/dist/assets/{surrealql-D6lw4TiD.js → surrealql-qvETr7iY.js} +1 -1
  174. package/dist/diff_tool/app/dist/assets/{svelte-ChVoq9tB.js → svelte-B0z1MgHc.js} +1 -1
  175. package/dist/diff_tool/app/dist/assets/{templ-Dh1EXuHD.js → templ-DTnPshKb.js} +1 -1
  176. package/dist/diff_tool/app/dist/assets/{tex-KTYusNFe.js → tex-Cosab9_H.js} +1 -1
  177. package/dist/diff_tool/app/dist/assets/{ts-tags-DC2RU1_R.js → ts-tags-DNYvLFUH.js} +1 -1
  178. package/dist/diff_tool/app/dist/assets/{tsx-DtIM39Jy.js → tsx-Dstq6j1a.js} +1 -1
  179. package/dist/diff_tool/app/dist/assets/twig-BzqZdwaX.js +1 -0
  180. package/dist/diff_tool/app/dist/assets/{typescript-BGAE5iuw.js → typescript-YOQ_oE25.js} +1 -1
  181. package/dist/diff_tool/app/dist/assets/typespec-BGhR2SqG.js +1 -0
  182. package/dist/diff_tool/app/dist/assets/{typst-nWoGZ22y.js → typst-DTffwfpc.js} +1 -1
  183. package/dist/diff_tool/app/dist/assets/{vue-iyHf-l4z.js → vue-D4OMj_C5.js} +1 -1
  184. package/dist/diff_tool/app/dist/assets/{vue-html-prNdIjLu.js → vue-html-kT4WrHGK.js} +1 -1
  185. package/dist/diff_tool/app/dist/assets/{vue-vine-KSSlnVeg.js → vue-vine-CxeapeMO.js} +1 -1
  186. package/dist/diff_tool/app/dist/assets/{xml-DdCC83Xd.js → xml-DWVpuurg.js} +1 -1
  187. package/dist/diff_tool/app/dist/assets/{xsl-DSqZxsez.js → xsl-C0ciup5a.js} +1 -1
  188. package/dist/diff_tool/app/dist/assets/{yaml-CZcBUWvf.js → yaml-98Fvyfpc.js} +1 -1
  189. package/dist/diff_tool/app/dist/index.html +1 -1
  190. package/dist/execution/execution_environment.js.map +1 -1
  191. package/dist/execution/fly_sprite_execution_environment.js +5 -10
  192. package/dist/execution/fly_sprite_execution_environment.js.map +1 -1
  193. package/dist/execution/tool_backend_execution_environment.js +0 -2
  194. package/dist/execution/tool_backend_execution_environment.js.map +1 -1
  195. package/dist/host/execution_runtime.js +5 -4
  196. package/dist/host/execution_runtime.js.map +1 -1
  197. package/dist/host/hosted_ephemeral_agent_session.js +0 -2
  198. package/dist/host/hosted_ephemeral_agent_session.js.map +1 -1
  199. package/dist/host/local_session_host.js +15 -31
  200. package/dist/host/local_session_host.js.map +1 -1
  201. package/dist/main.js +14 -29
  202. package/dist/main.js.map +1 -1
  203. package/dist/protocol/session_protocol.d.ts +3 -6
  204. package/dist/protocol/session_protocol.js +3 -6
  205. package/dist/protocol/session_protocol.js.map +1 -1
  206. package/dist/sdk/local_client.js +3 -3
  207. package/dist/sdk/local_client.js.map +1 -1
  208. package/dist/store/session_snapshot_migrations.js +28 -1
  209. package/dist/store/session_snapshot_migrations.js.map +1 -1
  210. package/dist/tui/session_chat_app.js +2 -4
  211. package/dist/tui/session_chat_app.js.map +1 -1
  212. package/dist/tui/session_chat_controller.js +10 -1
  213. package/dist/tui/session_chat_controller.js.map +1 -1
  214. package/package.json +8 -8
  215. package/dist/diff_tool/app/dist/assets/beancount-D-usSTwE.js +0 -1
  216. package/dist/diff_tool/app/dist/assets/coq-DuBRPxYg.js +0 -1
  217. package/dist/diff_tool/app/dist/assets/csharp-oqKa8noW.js +0 -1
  218. package/dist/diff_tool/app/dist/assets/css-BQflXFb6.js +0 -1
  219. package/dist/diff_tool/app/dist/assets/dart-CnvKMtbv.js +0 -1
  220. package/dist/diff_tool/app/dist/assets/dotenv-_5a1GRtc.js +0 -1
  221. package/dist/diff_tool/app/dist/assets/emacs-lisp-c_oH4hRZ.js +0 -1
  222. package/dist/diff_tool/app/dist/assets/gn-ilITqXS6.js +0 -1
  223. package/dist/diff_tool/app/dist/assets/handlebars-CfAla6QK.js +0 -1
  224. package/dist/diff_tool/app/dist/assets/index-CZUi_I-p.js +0 -340
  225. package/dist/diff_tool/app/dist/assets/latex-pWSag83P.js +0 -1
  226. package/dist/diff_tool/app/dist/assets/luau-C2pBCSgt.js +0 -1
  227. package/dist/diff_tool/app/dist/assets/marko-yLX6iW68.js +0 -1
  228. package/dist/diff_tool/app/dist/assets/monokai-B_bV9PQ9.js +0 -1
  229. package/dist/diff_tool/app/dist/assets/moonbit-DgjMoLWr.js +0 -1
  230. package/dist/diff_tool/app/dist/assets/nextflow-BJtWHP5T.js +0 -1
  231. package/dist/diff_tool/app/dist/assets/nushell-DHYfO66s.js +0 -1
  232. package/dist/diff_tool/app/dist/assets/one-dark-pro-CLwyXe_n.js +0 -1
  233. package/dist/diff_tool/app/dist/assets/php-D-AthX_E.js +0 -1
  234. package/dist/diff_tool/app/dist/assets/red-DX1BQOs8.js +0 -1
  235. package/dist/diff_tool/app/dist/assets/rust-Cfkwpbl8.js +0 -1
  236. package/dist/diff_tool/app/dist/assets/solarized-dark-UdsmMDCL.js +0 -1
  237. package/dist/diff_tool/app/dist/assets/solarized-light-C1IUL_tW.js +0 -1
  238. package/dist/diff_tool/app/dist/assets/sql-CsIdKfaO.js +0 -1
  239. package/dist/diff_tool/app/dist/assets/twig-C6D_TA3n.js +0 -1
  240. package/dist/diff_tool/app/dist/assets/typespec-BRdr0IET.js +0 -1
@@ -0,0 +1,291 @@
1
+ import { resolve } from "node:path";
2
+ import { parseArgs } from "node:util";
3
+ import { z } from "zod";
4
+ import { getApiKeyForProvider } from "../config/schema.js";
5
+ import { spawnWithCapture } from "../utils/spawn_capture.js";
6
+ import { ToolCliError } from "./errors.js";
7
+ import { parseMediaJson, readMediaResponse, requiredArg } from "./media.js";
8
+ import { decisionResponse, parseDecisionInput, validateDecisionAnswers, } from "./openrouter_decisions.js";
9
+ import { decodeOpenRouterText, OPENROUTER_REQUEST_BYTES, OPENROUTER_TEXT_BYTES, prepareOpenRouterAttachments, readOpenRouterFile, readOpenRouterStdin, } from "./openrouter_media.js";
10
+ const models = {
11
+ decisions: [
12
+ {
13
+ id: "typesafe/jev-1.13",
14
+ inputs: ["state", "questions"],
15
+ reasoning: [],
16
+ role: "Typed classification, scoring, and verification with probabilities.",
17
+ },
18
+ ],
19
+ chat: [
20
+ {
21
+ id: "google/gemini-3.8-flash",
22
+ inputs: ["text", "image", "audio", "video"],
23
+ reasoning: ["low", "medium", "high"],
24
+ role: "Audio/video understanding and image-heavy analysis.",
25
+ },
26
+ {
27
+ id: "openai/gpt-6-luna",
28
+ inputs: ["text", "image"],
29
+ reasoning: ["none", "low", "medium", "high", "xhigh", "max"],
30
+ role: "Cheap everyday extraction, summarization, and routine image understanding.",
31
+ },
32
+ {
33
+ id: "openai/gpt-6.1-sol",
34
+ inputs: ["text", "image"],
35
+ reasoning: ["low", "medium", "high", "xhigh", "max"],
36
+ role: "Coding, debugging, and technical reasoning.",
37
+ },
38
+ {
39
+ id: "anthropic/claude-opus-5.5",
40
+ inputs: ["text", "image"],
41
+ reasoning: ["low", "medium", "high", "xhigh", "max"],
42
+ role: "Premium generalist for writing, synthesis, and difficult second opinions.",
43
+ },
44
+ ],
45
+ };
46
+ function modelHelp(operation) {
47
+ return models[operation].map((model) => `${model.id}\n inputs: ${model.inputs.join(", ")}; reasoning: ${model.reasoning.join(", ") || "not supported"}\n ${model.role}`);
48
+ }
49
+ async function printHelp(operation, log) {
50
+ await log([
51
+ `usage: tau tool openrouter ${operation ?? "<decisions|chat>"} [flags]`,
52
+ "",
53
+ " --help, -h show help without reading input or making a request.",
54
+ " --list-models list this operation's fixed models (standalone mode).",
55
+ " --model <id> required exact model ID for requests.",
56
+ ...(operation === "decisions"
57
+ ? [
58
+ " --input <path|-> required UTF-8 JSON containing state and questions; - reads stdin.",
59
+ ]
60
+ : operation === "chat"
61
+ ? [
62
+ " --prompt <text> | --prompt-file <path> required user prompt.",
63
+ " --system <text> | --system-file <path> optional explicit system instructions.",
64
+ " --image <path> repeatable PNG/JPEG/WebP attachment.",
65
+ " --audio <path> repeatable WAV/MP3 attachment (Gemini only).",
66
+ " --video <path> MP4 attachment (Gemini only).",
67
+ " --reasoning <effort> model-supported effort; omitted uses provider default.",
68
+ ]
69
+ : [
70
+ "",
71
+ "operations: decisions (typed judgments), chat (text and media understanding).",
72
+ "place flags after the operation; use its --help for options.",
73
+ ]),
74
+ ...(operation ? ["", ...modelHelp(operation)] : []),
75
+ "",
76
+ "one standalone request; JSON stdout; no automatic retries or Tau session context.",
77
+ "requires OPENROUTER_API_KEY or global apiKeys.openrouter; audio/video also require ffprobe.",
78
+ "no output token cap is sent; provider defaults and model limits apply.",
79
+ "documentation: https://github.com/markusylisiurunen/tau/blob/main/docs/openrouter.md",
80
+ ].join("\n"));
81
+ }
82
+ function parseOptions(argv, operation) {
83
+ const shared = {
84
+ help: { type: "boolean", short: "h" },
85
+ "list-models": { type: "boolean" },
86
+ model: { type: "string" },
87
+ };
88
+ const options = operation === "decisions"
89
+ ? { ...shared, input: { type: "string" } }
90
+ : {
91
+ ...shared,
92
+ prompt: { type: "string" },
93
+ "prompt-file": { type: "string" },
94
+ system: { type: "string" },
95
+ "system-file": { type: "string" },
96
+ reasoning: { type: "string" },
97
+ image: { type: "string", multiple: true },
98
+ audio: { type: "string", multiple: true },
99
+ video: { type: "string", multiple: true },
100
+ };
101
+ try {
102
+ const parsed = parseArgs({ args: argv, options, tokens: true, allowPositionals: false });
103
+ const seen = new Set();
104
+ const attachments = [];
105
+ for (const token of parsed.tokens) {
106
+ if (token.kind !== "option")
107
+ continue;
108
+ if (token.name === "image" || token.name === "audio" || token.name === "video") {
109
+ attachments.push({ kind: token.name, path: requiredArg(token.value, token.name) });
110
+ }
111
+ else if (seen.has(token.name)) {
112
+ throw new ToolCliError(`duplicate --${token.name}`);
113
+ }
114
+ seen.add(token.name);
115
+ }
116
+ return {
117
+ values: parsed.values,
118
+ attachments,
119
+ };
120
+ }
121
+ catch (error) {
122
+ throw new ToolCliError(error instanceof Error ? error.message : String(error));
123
+ }
124
+ }
125
+ async function textInput(inline, file, name, cwd) {
126
+ if ((inline === undefined) === (file === undefined))
127
+ throw new ToolCliError(`provide exactly one of --${name} or --${name}-file`);
128
+ const text = inline === undefined
129
+ ? decodeOpenRouterText(await readOpenRouterFile(resolve(cwd, requiredArg(file, `${name}-file`)), OPENROUTER_TEXT_BYTES))
130
+ : requiredArg(inline, name);
131
+ if (!text.trim() || Buffer.byteLength(text) > OPENROUTER_TEXT_BYTES)
132
+ throw new ToolCliError(`${name} must be nonblank and at most ${OPENROUTER_TEXT_BYTES} UTF-8 bytes`);
133
+ return text;
134
+ }
135
+ const chatResponse = z.object({
136
+ model: z.string().min(1),
137
+ id: z.string().optional(),
138
+ provider: z.string().optional(),
139
+ usage: z
140
+ .looseObject({
141
+ prompt_tokens: z.number().int().nonnegative(),
142
+ completion_tokens: z.number().int().nonnegative(),
143
+ total_tokens: z.number().int().nonnegative(),
144
+ cost: z.number().nonnegative().nullable().optional(),
145
+ })
146
+ .optional(),
147
+ choices: z.tuple([
148
+ z.object({
149
+ finish_reason: z.enum(["stop", "length", "content_filter"]),
150
+ native_finish_reason: z.string().nullable().optional(),
151
+ message: z.object({
152
+ role: z.literal("assistant"),
153
+ content: z
154
+ .union([z.string(), z.array(z.object({ type: z.literal("text"), text: z.string() }))])
155
+ .nullish()
156
+ .transform((content) => typeof content === "string"
157
+ ? content
158
+ : (content?.map((part) => part.text).join("") ?? null)),
159
+ refusal: z.string().nullable().optional(),
160
+ tool_calls: z.array(z.unknown()).max(0).optional(),
161
+ }),
162
+ }),
163
+ ]),
164
+ });
165
+ function requestFailure(status) {
166
+ const kind = status === 401
167
+ ? "authentication failed; check OPENROUTER_API_KEY or global apiKeys.openrouter"
168
+ : status === 402
169
+ ? "insufficient credits; check OpenRouter billing"
170
+ : status === 403
171
+ ? "request forbidden; check key permissions and content policy"
172
+ : status === 429
173
+ ? "rate limited; wait before deciding whether to retry"
174
+ : status >= 500
175
+ ? "provider or OpenRouter service failure"
176
+ : "request rejected";
177
+ return new ToolCliError(`OpenRouter ${kind} (status ${status}); no automatic retry`);
178
+ }
179
+ async function request(operation, body, options) {
180
+ const payload = JSON.stringify(body);
181
+ if (Buffer.byteLength(payload) > OPENROUTER_REQUEST_BYTES)
182
+ throw new ToolCliError("encoded request exceeds 20 MB; reduce text or attachments");
183
+ const key = (options.env ?? process.env).OPENROUTER_API_KEY?.trim() ||
184
+ getApiKeyForProvider(options.config, "openrouter");
185
+ if (!key)
186
+ throw new ToolCliError("configure OPENROUTER_API_KEY or global apiKeys.openrouter on this machine");
187
+ if (!/^[\x21-\x7e]+$/.test(key))
188
+ throw new ToolCliError("OpenRouter API key must contain only printable ASCII without whitespace");
189
+ const response = await (options.fetchImpl ?? fetch)(`https://openrouter.ai/api/${operation === "decisions" ? "alpha/decisions" : "v1/chat/completions"}`, {
190
+ method: "POST",
191
+ redirect: "error",
192
+ signal: AbortSignal.timeout(10 * 60 * 1000),
193
+ headers: { Authorization: `Bearer ${key}`, "Content-Type": "application/json" },
194
+ body: payload,
195
+ });
196
+ if (!response.ok) {
197
+ await response.body?.cancel();
198
+ throw requestFailure(response.status);
199
+ }
200
+ const value = parseMediaJson(decodeOpenRouterText(await readMediaResponse(response, 8_000_000)), "OpenRouter response");
201
+ if (value && typeof value === "object" && "error" in value) {
202
+ const error = z.object({ code: z.number().int() }).safeParse(value.error);
203
+ if (error.success)
204
+ throw requestFailure(error.data.code);
205
+ throw new ToolCliError("OpenRouter returned a provider error; no automatic retry");
206
+ }
207
+ return value;
208
+ }
209
+ export async function runOpenRouterCommand(argv, options) {
210
+ const [operation, ...flags] = argv;
211
+ const log = options.stdout ??
212
+ ((line) => new Promise((resolve, reject) => {
213
+ process.stdout.write(`${line}\n`, (error) => {
214
+ if (error)
215
+ reject(error);
216
+ else
217
+ resolve();
218
+ });
219
+ }));
220
+ if ((operation === "--help" || operation === "-h") && !flags.length) {
221
+ await printHelp(undefined, log);
222
+ return;
223
+ }
224
+ if (operation !== "decisions" && operation !== "chat")
225
+ throw new ToolCliError("use tau tool openrouter <decisions|chat> --help");
226
+ const { values, attachments } = parseOptions(flags, operation);
227
+ if (values.help) {
228
+ await printHelp(operation, log);
229
+ return;
230
+ }
231
+ if (values["list-models"]) {
232
+ if (Object.keys(values).length !== 1)
233
+ throw new ToolCliError("--list-models cannot be combined with request flags");
234
+ await log(JSON.stringify({ models: models[operation] }));
235
+ return;
236
+ }
237
+ const requestedModel = requiredArg(values.model, "model");
238
+ const spec = models[operation].find((model) => model.id === requestedModel);
239
+ if (!spec)
240
+ throw new ToolCliError(`unsupported ${operation} model; use ${operation} --list-models`);
241
+ const cwd = options.cwd ?? process.cwd();
242
+ if (operation === "decisions") {
243
+ const path = requiredArg(values.input, "input");
244
+ const bytes = path === "-"
245
+ ? await readOpenRouterStdin(options.stdin ?? process.stdin)
246
+ : await readOpenRouterFile(resolve(cwd, path), OPENROUTER_TEXT_BYTES);
247
+ const input = parseDecisionInput(parseMediaJson(decodeOpenRouterText(bytes), "decisions input"));
248
+ const result = decisionResponse.safeParse(await request(operation, { model: requestedModel, ...input }, options));
249
+ if (!result.success)
250
+ throw new ToolCliError("OpenRouter returned an invalid decisions response");
251
+ validateDecisionAnswers(input, result.data);
252
+ await log(JSON.stringify({ requested_model: requestedModel, ...result.data }));
253
+ return;
254
+ }
255
+ if (values.reasoning !== undefined &&
256
+ !spec.reasoning.includes(requiredArg(values.reasoning, "reasoning")))
257
+ throw new ToolCliError(`unsupported reasoning effort for ${requestedModel}; use chat --list-models`);
258
+ if (attachments.some((item) => !spec.inputs.includes(item.kind)))
259
+ throw new ToolCliError("audio and video require google/gemini-3.8-flash; no model substitution is performed");
260
+ const prompt = await textInput(values.prompt, values["prompt-file"], "prompt", cwd);
261
+ const system = values.system === undefined && values["system-file"] === undefined
262
+ ? undefined
263
+ : await textInput(values.system, values["system-file"], "system", cwd);
264
+ const media = await prepareOpenRouterAttachments(attachments.map((item) => ({ ...item, path: resolve(cwd, item.path) })), options.spawnImpl ?? spawnWithCapture);
265
+ const messages = [];
266
+ if (system !== undefined)
267
+ messages.push({ role: "system", content: system });
268
+ messages.push({ role: "user", content: [{ type: "text", text: prompt }, ...media] });
269
+ const result = chatResponse.safeParse(await request(operation, {
270
+ model: requestedModel,
271
+ messages,
272
+ stream: false,
273
+ ...(values.reasoning === undefined ? {} : { reasoning: { effort: values.reasoning } }),
274
+ provider: { require_parameters: true },
275
+ }, options));
276
+ if (!result.success)
277
+ throw new ToolCliError("OpenRouter returned an invalid or unsupported chat response");
278
+ const { choices, ...metadata } = result.data;
279
+ const { message, finish_reason, native_finish_reason } = choices[0];
280
+ if (finish_reason === "stop" && !message.content?.trim() && !message.refusal)
281
+ throw new ToolCliError("OpenRouter returned no answer or refusal");
282
+ await log(JSON.stringify({
283
+ requested_model: requestedModel,
284
+ ...metadata,
285
+ answer: message.content,
286
+ finish_reason,
287
+ native_finish_reason,
288
+ refusal: message.refusal,
289
+ }));
290
+ }
291
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../../src/core/tool/openrouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { z } from "zod";
2
+ import { ToolCliError } from "./errors.js";
3
+ import { mediaValidationConstraint } from "./media.js";
4
+ // Nested content is already parsed JSON; preserve its arbitrary property names verbatim.
5
+ const guidance = z.custom((value) => typeof value === "string" || (typeof value === "object" && value !== null));
6
+ const namedObject = z.custom((value) => typeof value === "object" &&
7
+ value !== null &&
8
+ !Array.isArray(value) &&
9
+ !Object.hasOwn(value, "__proto__"), { message: "expected an object without the reserved name __proto__" });
10
+ const probability = z.number().min(0).max(1);
11
+ const probabilities = namedObject.pipe(z.record(z.string(), probability));
12
+ const question = z.discriminatedUnion("type", [
13
+ z.strictObject({
14
+ type: z.literal("noul"),
15
+ instructions: guidance,
16
+ criteria: z.strictObject({ true: guidance, false: guidance }).optional(),
17
+ }),
18
+ z.strictObject({
19
+ type: z.literal("choice"),
20
+ instructions: guidance,
21
+ criteria: namedObject
22
+ .pipe(z.record(z.string().min(1), guidance.nullable()))
23
+ .refine((value) => Object.keys(value).length > 0),
24
+ }),
25
+ z.strictObject({
26
+ type: z.literal("score"),
27
+ instructions: guidance,
28
+ criteria: z.array(guidance).min(1),
29
+ }),
30
+ ]);
31
+ const decisionInput = z.strictObject({
32
+ state: guidance,
33
+ questions: namedObject
34
+ .pipe(z.record(z.string().min(1), question))
35
+ .refine((value) => Object.keys(value).length > 0),
36
+ });
37
+ const answer = z.discriminatedUnion("type", [
38
+ z.object({ type: z.literal("noul"), noul: probability }),
39
+ z.object({
40
+ type: z.literal("choice"),
41
+ choice: z.string(),
42
+ confidence: probability.optional(),
43
+ probabilities: probabilities.optional(),
44
+ }),
45
+ z.object({
46
+ type: z.literal("score"),
47
+ score: z.number().nonnegative(),
48
+ confidence: probability.optional(),
49
+ probabilities: probabilities.optional(),
50
+ legend: namedObject.pipe(z.record(z.string(), guidance)).optional(),
51
+ }),
52
+ ]);
53
+ export const decisionResponse = z.object({
54
+ model: z.string().min(1),
55
+ id: z.string().optional(),
56
+ provider: z.string().optional(),
57
+ answers: namedObject.pipe(z.record(z.string(), answer)),
58
+ usage: z.looseObject({
59
+ input_tokens: z.number().int().nonnegative(),
60
+ output_tokens: z.number().int().nonnegative(),
61
+ cost: z.number().nonnegative().optional(),
62
+ }),
63
+ });
64
+ export function parseDecisionInput(value) {
65
+ const parsed = decisionInput.safeParse(value);
66
+ if (!parsed.success) {
67
+ throw new ToolCliError(`invalid decisions input: ${parsed.error.issues.map((issue) => `${issue.path.join(".") || "document"}: ${mediaValidationConstraint(issue)}`).join("; ")}`);
68
+ }
69
+ return parsed.data;
70
+ }
71
+ export function validateDecisionAnswers(input, response) {
72
+ const names = Object.keys(input.questions);
73
+ if (names.length !== Object.keys(response.answers).length) {
74
+ throw new ToolCliError("OpenRouter returned mismatched decision answers");
75
+ }
76
+ for (const [name, question] of Object.entries(input.questions)) {
77
+ const answer = Object.hasOwn(response.answers, name) ? response.answers[name] : undefined;
78
+ if (!answer || answer.type !== question.type) {
79
+ throw new ToolCliError("OpenRouter returned a missing or mistyped decision answer");
80
+ }
81
+ if (answer.type === "choice" && question.type === "choice") {
82
+ if (!Object.hasOwn(question.criteria, answer.choice) ||
83
+ (answer.probabilities &&
84
+ Object.keys(answer.probabilities).some((key) => !Object.hasOwn(question.criteria, key)))) {
85
+ throw new ToolCliError("OpenRouter returned an unknown decision category");
86
+ }
87
+ }
88
+ if (answer.type === "score" && question.type === "score") {
89
+ const indices = new Set(question.criteria.map((_, index) => String(index)));
90
+ if (answer.score > question.criteria.length - 1 ||
91
+ [answer.probabilities, answer.legend].some((value) => value && Object.keys(value).some((key) => !indices.has(key)))) {
92
+ throw new ToolCliError("OpenRouter returned a score outside the supplied rubric");
93
+ }
94
+ }
95
+ }
96
+ }
97
+ //# sourceMappingURL=openrouter_decisions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter_decisions.js","sourceRoot":"","sources":["../../../src/core/tool/openrouter_decisions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAEvD,yFAAyF;AACzF,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CACvB,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CACtF,CAAC;AACF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAC1B,CAAC,KAAK,EAAE,EAAE,CACR,OAAO,KAAK,KAAK,QAAQ;IACzB,KAAK,KAAK,IAAI;IACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;IACrB,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,EACpC,EAAE,OAAO,EAAE,wDAAwD,EAAE,CACtE,CAAC;AACF,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC7C,MAAM,aAAa,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAC;AAC1E,MAAM,QAAQ,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC5C,CAAC,CAAC,YAAY,CAAC;QACb,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACvB,YAAY,EAAE,QAAQ;QACtB,QAAQ,EAAE,CAAC,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE;KACzE,CAAC;IACF,CAAC,CAAC,YAAY,CAAC;QACb,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACzB,YAAY,EAAE,QAAQ;QACtB,QAAQ,EAAE,WAAW;aAClB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;aACtD,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;KACpD,CAAC;IACF,CAAC,CAAC,YAAY,CAAC;QACb,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QACxB,YAAY,EAAE,QAAQ;QACtB,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;KACnC,CAAC;CACH,CAAC,CAAC;AACH,MAAM,aAAa,GAAG,CAAC,CAAC,YAAY,CAAC;IACnC,KAAK,EAAE,QAAQ;IACf,SAAS,EAAE,WAAW;SACnB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;SAC3C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;CACpD,CAAC,CAAC;AACH,MAAM,MAAM,GAAG,CAAC,CAAC,kBAAkB,CAAC,MAAM,EAAE;IAC1C,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACxD,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;QACzB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;QAClB,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE;QAClC,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE;KACxC,CAAC;IACF,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QACxB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;QAC/B,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE;QAClC,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE;QACvC,MAAM,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;KACpE,CAAC;CACH,CAAC,CAAC;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACxB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;IACvD,KAAK,EAAE,CAAC,CAAC,WAAW,CAAC;QACnB,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QAC5C,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;QAC7C,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;KAC1C,CAAC;CACH,CAAC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,KAAc;IAC/C,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,YAAY,CACpB,4BAA4B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,UAAU,KAAK,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC1J,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,KAAoC,EACpC,QAA0C;IAE1C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;QAC1D,MAAM,IAAI,YAAY,CAAC,iDAAiD,CAAC,CAAC;IAC5E,CAAC;IACD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1F,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7C,MAAM,IAAI,YAAY,CAAC,2DAA2D,CAAC,CAAC;QACtF,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC3D,IACE,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC;gBAChD,CAAC,MAAM,CAAC,aAAa;oBACnB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,EAC1F,CAAC;gBACD,MAAM,IAAI,YAAY,CAAC,kDAAkD,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YAC5E,IACE,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAC3C,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CACxC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CACxE,EACD,CAAC;gBACD,MAAM,IAAI,YAAY,CAAC,yDAAyD,CAAC,CAAC;YACpF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC"}
@@ -0,0 +1,180 @@
1
+ import { constants } from "node:fs";
2
+ import { mkdtemp, open, rm, writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { fileTypeFromBuffer } from "file-type";
6
+ import sharp from "sharp";
7
+ import { z } from "zod";
8
+ import { ToolCliError } from "./errors.js";
9
+ import { parseMediaJson } from "./media.js";
10
+ export const OPENROUTER_TEXT_BYTES = 1_000_000;
11
+ export const OPENROUTER_REQUEST_BYTES = 20_000_000;
12
+ async function readBounded(stream, limit) {
13
+ const chunks = [];
14
+ let size = 0;
15
+ for await (const chunk of stream) {
16
+ const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
17
+ size += bytes.length;
18
+ if (size > limit)
19
+ throw new ToolCliError(`input exceeds ${limit} bytes; reduce its size`);
20
+ chunks.push(bytes);
21
+ }
22
+ return Buffer.concat(chunks);
23
+ }
24
+ export async function readOpenRouterFile(path, limit) {
25
+ const file = await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
26
+ try {
27
+ const stat = await file.stat();
28
+ if (!stat.isFile())
29
+ throw new ToolCliError(`expected a regular local file: ${path}`);
30
+ if (stat.size > limit)
31
+ throw new ToolCliError(`input exceeds ${limit} bytes: ${path}`);
32
+ return await readBounded(file.createReadStream({ autoClose: false }), limit);
33
+ }
34
+ finally {
35
+ await file.close();
36
+ }
37
+ }
38
+ export async function readOpenRouterStdin(stdin) {
39
+ if (stdin.isTTY)
40
+ throw new ToolCliError("--input - requires piped or redirected JSON, not a terminal");
41
+ const timer = setTimeout(() => stdin.destroy(new ToolCliError("stdin did not reach EOF within 30 seconds")), 30_000);
42
+ try {
43
+ return await readBounded(stdin, OPENROUTER_TEXT_BYTES);
44
+ }
45
+ finally {
46
+ clearTimeout(timer);
47
+ }
48
+ }
49
+ export function decodeOpenRouterText(bytes) {
50
+ try {
51
+ return new TextDecoder("utf-8", { fatal: true }).decode(bytes);
52
+ }
53
+ catch {
54
+ throw new ToolCliError("input must be valid UTF-8");
55
+ }
56
+ }
57
+ const mediaProbe = z.object({
58
+ format: z.object({ duration: z.string().transform(Number).pipe(z.number().positive().max(600)) }),
59
+ streams: z
60
+ .array(z.object({
61
+ codec_type: z.string(),
62
+ codec_name: z.string(),
63
+ width: z.number().optional(),
64
+ height: z.number().optional(),
65
+ }))
66
+ .min(1),
67
+ });
68
+ async function probeMedia(bytes, kind, format, spawnImpl) {
69
+ const directory = await mkdtemp(join(tmpdir(), "tau-openrouter-"));
70
+ try {
71
+ const path = join(directory, "input");
72
+ await writeFile(path, bytes, { mode: 0o600 });
73
+ const result = await spawnImpl("ffprobe", [
74
+ "-v",
75
+ "error",
76
+ "-protocol_whitelist",
77
+ "file",
78
+ "-f",
79
+ format,
80
+ "-show_entries",
81
+ "format=duration:stream=codec_type,codec_name,width,height",
82
+ "-of",
83
+ "json",
84
+ path,
85
+ ], { timeoutMs: 15_000, maxCaptureBytes: 1_000_000, detached: true, killProcessGroup: true });
86
+ if (result.exitCode !== 0 || result.timedOut || result.captureLimitExceeded || result.aborted) {
87
+ throw new ToolCliError("ffprobe could not validate media; use a valid WAV, MP3, or MP4 file");
88
+ }
89
+ const parsed = mediaProbe.safeParse(parseMediaJson(result.stdout, "ffprobe output"));
90
+ if (!parsed.success)
91
+ throw new ToolCliError("media must have a known duration of at most 600 seconds");
92
+ const { streams, format: metadata } = parsed.data;
93
+ if (kind === "audio") {
94
+ if (streams.length !== 1 ||
95
+ streams.some((stream) => stream.codec_type !== "audio" ||
96
+ stream.codec_name !== (format === "wav" ? "pcm_s16le" : "mp3"))) {
97
+ throw new ToolCliError("audio requires a single PCM 16-bit WAV or MP3 audio stream");
98
+ }
99
+ }
100
+ else if (!streams.some((stream) => stream.codec_type === "video") ||
101
+ streams.some((stream) => {
102
+ if (stream.codec_type === "audio")
103
+ return stream.codec_name !== "aac";
104
+ return (stream.codec_type !== "video" ||
105
+ stream.codec_name !== "h264" ||
106
+ !stream.width ||
107
+ !stream.height ||
108
+ stream.width > 3840 ||
109
+ stream.height > 2160);
110
+ })) {
111
+ throw new ToolCliError("video requires H.264 MP4 up to 3840x2160, with optional AAC audio");
112
+ }
113
+ return metadata.duration;
114
+ }
115
+ catch (error) {
116
+ if (error.code === "ENOENT") {
117
+ throw new ToolCliError("ffprobe not found; install FFmpeg (brew install ffmpeg or apt install ffmpeg) and ensure ffprobe is on PATH");
118
+ }
119
+ throw error;
120
+ }
121
+ finally {
122
+ await rm(directory, { recursive: true, force: true });
123
+ }
124
+ }
125
+ export async function prepareOpenRouterAttachments(attachments, spawnImpl) {
126
+ if (attachments.length > 16 ||
127
+ attachments.filter((item) => item.kind === "audio").length > 4 ||
128
+ attachments.filter((item) => item.kind === "video").length > 1) {
129
+ throw new ToolCliError("at most 16 attachments, including at most 4 audio files and 1 video, are supported");
130
+ }
131
+ const parts = [];
132
+ let duration = 0;
133
+ let encodedBytes = 0;
134
+ for (const { kind, path } of attachments) {
135
+ const bytes = await readOpenRouterFile(path, kind === "image" ? 5_000_000 : 12_000_000);
136
+ encodedBytes += 4 * Math.ceil(bytes.length / 3);
137
+ if (encodedBytes > OPENROUTER_REQUEST_BYTES)
138
+ throw new ToolCliError("attachments exceed the 20 MB encoded request limit");
139
+ const type = await fileTypeFromBuffer(bytes);
140
+ if (kind === "image") {
141
+ if (!type || !["image/png", "image/jpeg", "image/webp"].includes(type.mime)) {
142
+ throw new ToolCliError(`unsupported image: ${path}; use PNG, JPEG, or WebP`);
143
+ }
144
+ const image = sharp(bytes, { limitInputPixels: 32_000_000 });
145
+ const metadata = await image.metadata();
146
+ if (!metadata.width ||
147
+ !metadata.height ||
148
+ metadata.width > 8000 ||
149
+ metadata.height > 8000 ||
150
+ (metadata.pages ?? 1) > 1) {
151
+ throw new ToolCliError("images must be single-frame, at most 8000 pixels per edge and 32 megapixels");
152
+ }
153
+ await image.stats();
154
+ parts.push({
155
+ type: "image_url",
156
+ image_url: { url: `data:${type.mime};base64,${bytes.toString("base64")}` },
157
+ });
158
+ }
159
+ else {
160
+ const format = kind === "audio"
161
+ ? { "audio/wav": "wav", "audio/mpeg": "mp3" }[type?.mime ?? ""]
162
+ : type?.mime === "video/mp4"
163
+ ? "mov"
164
+ : undefined;
165
+ if (!format)
166
+ throw new ToolCliError(`unsupported ${kind}: ${path}; use WAV/MP3 audio or MP4 video`);
167
+ duration += await probeMedia(bytes, kind, format, spawnImpl);
168
+ if (duration > 600)
169
+ throw new ToolCliError("combined audio/video duration exceeds 600 seconds");
170
+ parts.push(kind === "audio"
171
+ ? { type: "input_audio", input_audio: { data: bytes.toString("base64"), format } }
172
+ : {
173
+ type: "video_url",
174
+ video_url: { url: `data:video/mp4;base64,${bytes.toString("base64")}` },
175
+ });
176
+ }
177
+ }
178
+ return parts;
179
+ }
180
+ //# sourceMappingURL=openrouter_media.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter_media.js","sourceRoot":"","sources":["../../../src/core/tool/openrouter_media.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,7 @@ const TAU_DOCS_DESCRIPTION = [
24
24
  "- PDF unpacking: extract OCR text, tables, and page-image patches from a PDF. Documentation: pdf-unpacking.md.",
25
25
  "- Image generation: generate images from prompts or edit images using local references. Documentation: image-generation.md.",
26
26
  "- Speech generation: turn narration or multi-speaker dialogue scripts into an audio file. Documentation: speech-generation.md.",
27
+ "- OpenRouter: call a selection of AI models for tasks such as analysis, writing, and typed decisions, with support for text, image, audio, and video inputs depending on the model. Documentation: openrouter.md.",
27
28
  "",
28
29
  "Guidelines:",
29
30
  "- Selection: Consider these tools when their capabilities match the task, even if the user has not explicitly named them. Their use is optional; choose the approach that best fits the request.",