@theoremjs/agents 0.3.0 → 0.3.1

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 (568) hide show
  1. package/README.md +276 -995
  2. package/esm/mod.d.ts +33 -19
  3. package/esm/mod.js +18 -11
  4. package/esm/src/cli/commands/bench.js +36 -14
  5. package/esm/src/cli/commands/detect-compile.d.ts +17 -0
  6. package/esm/src/cli/commands/detect-compile.js +22 -0
  7. package/esm/src/cli/commands/eval.d.ts +3 -3
  8. package/esm/src/cli/commands/fuzz-canary.js +55 -16
  9. package/esm/src/cli/commands/profile.js +4 -4
  10. package/esm/src/cli/commands/run.d.ts +2 -2
  11. package/esm/src/cli/commands/run.js +1 -1
  12. package/esm/src/cli/commands/test.d.ts +4 -3
  13. package/esm/src/cli/commands/test.js +2 -2
  14. package/esm/src/cli/index.js +9 -9
  15. package/esm/src/cli/matrix/fixtures.js +25 -30
  16. package/esm/src/evals/attachments.d.ts +1 -0
  17. package/esm/src/evals/attachments.js +4 -2
  18. package/esm/src/evals/breakdown.d.ts +2 -0
  19. package/esm/src/evals/breakdown.js +1 -0
  20. package/esm/src/evals/graders/answer.d.ts +3 -0
  21. package/esm/src/evals/graders/answer.js +1 -0
  22. package/esm/src/evals/graders/code.d.ts +7 -31
  23. package/esm/src/evals/graders/code.js +4 -25
  24. package/esm/src/evals/graders/judge.d.ts +4 -0
  25. package/esm/src/evals/graders/judge.js +7 -5
  26. package/esm/src/evals/graders/latency.d.ts +1 -0
  27. package/esm/src/evals/graders/latency.js +3 -2
  28. package/esm/src/evals/graders/live.d.ts +3 -0
  29. package/esm/src/evals/graders/live.js +2 -0
  30. package/esm/src/evals/graders/media.js +1 -2
  31. package/esm/src/evals/graders/shared.js +1 -1
  32. package/esm/src/evals/graders/transcript.d.ts +2 -0
  33. package/esm/src/evals/graders/transcript.js +5 -3
  34. package/esm/src/evals/mod.d.ts +1 -9
  35. package/esm/src/evals/mod.js +1 -9
  36. package/esm/src/evals/record.d.ts +6 -0
  37. package/esm/src/evals/record.js +4 -2
  38. package/esm/src/evals/rubrics/mod.d.ts +1 -1
  39. package/esm/src/evals/rubrics/mod.js +1 -1
  40. package/esm/src/evals/rubrics/mustache.js +1 -1
  41. package/esm/src/evals/rubrics/types.js +1 -1
  42. package/esm/src/evals/run.d.ts +9 -52
  43. package/esm/src/evals/run.js +12 -46
  44. package/esm/src/evals/suite.d.ts +12 -3
  45. package/esm/src/evals/suite.js +9 -4
  46. package/esm/src/evals/summary.d.ts +3 -0
  47. package/esm/src/evals/summary.js +1 -0
  48. package/esm/src/evals/trial.d.ts +3 -16
  49. package/esm/src/evals/trial.js +7 -30
  50. package/esm/src/evals/types.d.ts +30 -121
  51. package/esm/src/evals/types.js +3 -16
  52. package/esm/src/evals/verdict.d.ts +5 -0
  53. package/esm/src/evals/verdict.js +4 -1
  54. package/esm/src/guardrails/boundaries.d.ts +41 -0
  55. package/esm/src/guardrails/boundaries.js +103 -0
  56. package/esm/src/guardrails/canary-gate.d.ts +1 -0
  57. package/esm/src/guardrails/canary.d.ts +49 -15
  58. package/esm/src/guardrails/canary.js +103 -30
  59. package/esm/src/guardrails/compile-egress.d.ts +6 -5
  60. package/esm/src/guardrails/compile-egress.js +6 -5
  61. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +3 -1
  62. package/esm/src/guardrails/corpus/canary-egress-attacks.js +4 -2
  63. package/esm/src/guardrails/corpus/fuzz-inbound.js +14 -17
  64. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +2 -0
  65. package/esm/src/guardrails/corpus/inbound-payloads.js +4 -2
  66. package/esm/src/guardrails/corpus/live-attacks.d.ts +2 -0
  67. package/esm/src/guardrails/corpus/live-attacks.js +6 -1
  68. package/esm/src/guardrails/corpus/mod.d.ts +1 -1
  69. package/esm/src/guardrails/corpus/secrets.d.ts +3 -3
  70. package/esm/src/guardrails/corpus/secrets.js +2 -2
  71. package/esm/src/guardrails/corpus/strings.d.ts +1 -1
  72. package/esm/src/guardrails/corpus/strings.js +1 -1
  73. package/esm/src/guardrails/corpus/types.d.ts +5 -1
  74. package/esm/src/guardrails/credential-rules.d.ts +36 -0
  75. package/esm/src/guardrails/credential-rules.js +3001 -0
  76. package/esm/src/guardrails/credential-scan.d.ts +45 -0
  77. package/esm/src/guardrails/credential-scan.js +172 -0
  78. package/esm/src/guardrails/destinations.d.ts +45 -0
  79. package/esm/src/guardrails/destinations.js +234 -0
  80. package/esm/src/guardrails/detect-at.d.ts +107 -0
  81. package/esm/src/guardrails/detect-at.js +434 -0
  82. package/esm/src/guardrails/detect-reply.d.ts +61 -0
  83. package/esm/src/guardrails/detect-reply.js +95 -0
  84. package/esm/src/guardrails/detect-stream.d.ts +33 -0
  85. package/esm/src/guardrails/detect-stream.js +77 -0
  86. package/esm/src/guardrails/detectors.d.ts +216 -0
  87. package/esm/src/guardrails/detectors.js +503 -0
  88. package/esm/src/guardrails/egress-automata.d.ts +4 -6
  89. package/esm/src/guardrails/egress-automata.js +24095 -4572
  90. package/esm/src/guardrails/egress-compiler.d.ts +38 -16
  91. package/esm/src/guardrails/egress-compiler.js +254 -60
  92. package/esm/src/guardrails/egress-patterns.d.ts +4 -2
  93. package/esm/src/guardrails/egress-patterns.js +6 -2
  94. package/esm/src/guardrails/egress-stream.d.ts +54 -36
  95. package/esm/src/guardrails/egress-stream.js +253 -124
  96. package/esm/src/guardrails/egress-urls.d.ts +6 -3
  97. package/esm/src/guardrails/egress-urls.js +14 -22
  98. package/esm/src/guardrails/egress.d.ts +26 -86
  99. package/esm/src/guardrails/egress.js +59 -309
  100. package/esm/src/guardrails/error.d.ts +13 -8
  101. package/esm/src/guardrails/error.js +23 -18
  102. package/esm/src/guardrails/event-schemas.d.ts +46 -3
  103. package/esm/src/guardrails/event-schemas.js +12 -5
  104. package/esm/src/guardrails/events.d.ts +5 -1
  105. package/esm/src/guardrails/events.js +4 -1
  106. package/esm/src/guardrails/hints.d.ts +14 -0
  107. package/esm/src/guardrails/hints.js +57 -0
  108. package/esm/src/guardrails/hits.d.ts +7 -1
  109. package/esm/src/guardrails/hits.js +12 -1
  110. package/esm/src/guardrails/host-patterns.d.ts +85 -0
  111. package/esm/src/guardrails/host-patterns.js +173 -0
  112. package/esm/src/guardrails/injection-patterns.d.ts +6 -1
  113. package/esm/src/guardrails/injection-patterns.js +33 -1
  114. package/esm/src/guardrails/injection-reversed.d.ts +9 -0
  115. package/esm/src/guardrails/injection-reversed.js +49 -0
  116. package/esm/src/guardrails/injection.d.ts +17 -1
  117. package/esm/src/guardrails/injection.js +259 -36
  118. package/esm/src/guardrails/labels.d.ts +40 -0
  119. package/esm/src/guardrails/labels.js +874 -0
  120. package/esm/src/guardrails/live-outbound-gate.d.ts +9 -8
  121. package/esm/src/guardrails/live-outbound-gate.js +100 -107
  122. package/esm/src/guardrails/mod.d.ts +29 -21
  123. package/esm/src/guardrails/mod.js +18 -13
  124. package/esm/src/guardrails/network.d.ts +4 -0
  125. package/esm/src/guardrails/network.js +21 -19
  126. package/esm/src/guardrails/normalize.d.ts +15 -1
  127. package/esm/src/guardrails/normalize.js +34 -1
  128. package/esm/src/guardrails/policy.d.ts +2 -17
  129. package/esm/src/guardrails/policy.js +12 -41
  130. package/esm/src/guardrails/progressive-yield.d.ts +65 -24
  131. package/esm/src/guardrails/progressive-yield.js +191 -147
  132. package/esm/src/guardrails/prompt-echo.d.ts +4 -2
  133. package/esm/src/guardrails/prompt-echo.js +87 -6
  134. package/esm/src/guardrails/quota.d.ts +1 -0
  135. package/esm/src/guardrails/quota.js +1 -1
  136. package/esm/src/guardrails/rules.d.ts +20 -29
  137. package/esm/src/guardrails/rules.js +23 -30
  138. package/esm/src/guardrails/sanitize.d.ts +32 -15
  139. package/esm/src/guardrails/sanitize.js +100 -124
  140. package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
  141. package/esm/src/guardrails/sensitive-groups.js +12 -0
  142. package/esm/src/guardrails/sensitive.d.ts +16 -23
  143. package/esm/src/guardrails/sensitive.js +168 -47
  144. package/esm/src/guardrails/serialize.d.ts +1 -0
  145. package/esm/src/guardrails/testing.d.ts +4 -2
  146. package/esm/src/guardrails/testing.js +4 -2
  147. package/esm/src/guardrails/theorem-error.d.ts +4 -1
  148. package/esm/src/guardrails/theorem-error.js +3 -2
  149. package/esm/src/guardrails/thought-guard.d.ts +34 -13
  150. package/esm/src/guardrails/thought-guard.js +264 -64
  151. package/esm/src/guardrails/tool-directives.d.ts +29 -10
  152. package/esm/src/guardrails/tool-directives.js +133 -47
  153. package/esm/src/guardrails/tool-leak.d.ts +26 -0
  154. package/esm/src/guardrails/tool-leak.js +45 -0
  155. package/esm/src/guardrails/tool-result.d.ts +45 -14
  156. package/esm/src/guardrails/tool-result.js +94 -70
  157. package/esm/src/guardrails/types.d.ts +79 -71
  158. package/esm/src/guardrails/types.js +11 -7
  159. package/esm/src/host/client-turn.d.ts +29 -2
  160. package/esm/src/host/client-turn.js +46 -4
  161. package/esm/src/host/mint-trace.d.ts +1 -0
  162. package/esm/src/host/mint-trace.js +3 -2
  163. package/esm/src/host/mod.d.ts +2 -2
  164. package/esm/src/host/mod.js +1 -1
  165. package/esm/src/host/readStreamingJsonStringField.js +2 -43
  166. package/esm/src/host/reply.d.ts +6 -0
  167. package/esm/src/host/reply.js +7 -1
  168. package/esm/src/interface/blocks.d.ts +3 -0
  169. package/esm/src/interface/blocks.js +84 -14
  170. package/esm/src/interface/composer-actions.d.ts +4 -0
  171. package/esm/src/interface/composer-actions.js +5 -3
  172. package/esm/src/interface/draft.d.ts +6 -0
  173. package/esm/src/interface/draft.js +22 -11
  174. package/esm/src/interface/from-profile.d.ts +13 -1
  175. package/esm/src/interface/from-profile.js +66 -31
  176. package/esm/src/interface/history.d.ts +9 -3
  177. package/esm/src/interface/history.js +33 -24
  178. package/esm/src/interface/inputs.d.ts +1 -0
  179. package/esm/src/interface/inputs.js +3 -0
  180. package/esm/src/interface/mod.d.ts +4 -2
  181. package/esm/src/interface/mod.js +3 -2
  182. package/esm/src/interface/models.d.ts +7 -0
  183. package/esm/src/interface/models.js +5 -0
  184. package/esm/src/interface/pending.d.ts +9 -0
  185. package/esm/src/interface/pending.js +9 -3
  186. package/esm/src/interface/profile-interface.js +54 -40
  187. package/esm/src/interface/session.d.ts +12 -5
  188. package/esm/src/interface/session.js +17 -10
  189. package/esm/src/interface/stop.d.ts +13 -0
  190. package/esm/src/interface/stop.js +28 -0
  191. package/esm/src/interface/tool-calls.d.ts +14 -2
  192. package/esm/src/interface/tool-calls.js +64 -10
  193. package/esm/src/interface/tool-invoke.d.ts +2 -0
  194. package/esm/src/interface/tool-invoke.js +3 -1
  195. package/esm/src/interface/tool-media.d.ts +2 -0
  196. package/esm/src/interface/tool-media.js +2 -1
  197. package/esm/src/interface/types.d.ts +105 -40
  198. package/esm/src/interface/types.js +1 -0
  199. package/esm/src/kernel/api-catalog.d.ts +85 -0
  200. package/esm/src/kernel/api-catalog.js +229 -0
  201. package/esm/src/kernel/auth/crypto.d.ts +7 -2
  202. package/esm/src/kernel/auth/crypto.js +12 -10
  203. package/esm/src/kernel/auth/oauth.d.ts +2 -1
  204. package/esm/src/kernel/auth/oauth.js +23 -22
  205. package/esm/src/kernel/auth/typed-secret.js +2 -2
  206. package/esm/src/kernel/auth/types.d.ts +13 -0
  207. package/esm/src/kernel/checkpoint.d.ts +43 -0
  208. package/esm/src/kernel/checkpoint.js +58 -0
  209. package/esm/src/kernel/default-scope.d.ts +43 -5
  210. package/esm/src/kernel/default-scope.js +54 -5
  211. package/esm/src/kernel/engine/call-trace.d.ts +19 -0
  212. package/esm/src/kernel/engine/call-trace.js +29 -0
  213. package/esm/src/kernel/engine/compaction.d.ts +6 -5
  214. package/esm/src/kernel/engine/compaction.js +12 -11
  215. package/esm/src/kernel/engine/decision.d.ts +10 -8
  216. package/esm/src/kernel/engine/decision.js +173 -146
  217. package/esm/src/kernel/engine/embedding.d.ts +8 -0
  218. package/esm/src/kernel/engine/embedding.js +118 -0
  219. package/esm/src/kernel/engine/live-inbound.d.ts +14 -4
  220. package/esm/src/kernel/engine/live-inbound.js +36 -11
  221. package/esm/src/kernel/engine/live-ingress.d.ts +6 -0
  222. package/esm/src/kernel/engine/live-ingress.js +6 -1
  223. package/esm/src/kernel/engine/repair.js +12 -12
  224. package/esm/src/kernel/engine/runner/gates.d.ts +2 -2
  225. package/esm/src/kernel/engine/runner/gates.js +287 -101
  226. package/esm/src/kernel/engine/runner/mod.d.ts +19 -5
  227. package/esm/src/kernel/engine/runner/mod.js +107 -56
  228. package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
  229. package/esm/src/kernel/engine/runner/nested.js +134 -0
  230. package/esm/src/kernel/engine/runner/schema-validation.d.ts +24 -3
  231. package/esm/src/kernel/engine/runner/schema-validation.js +78 -4
  232. package/esm/src/kernel/engine/runner/stages.d.ts +1 -1
  233. package/esm/src/kernel/engine/runner/stages.js +1 -8
  234. package/esm/src/kernel/engine/runner/state.d.ts +33 -12
  235. package/esm/src/kernel/engine/runner/state.js +11 -1
  236. package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
  237. package/esm/src/kernel/engine/runner/step-order.js +165 -0
  238. package/esm/src/kernel/engine/runner/steps.d.ts +2 -2
  239. package/esm/src/kernel/engine/runner/steps.js +328 -169
  240. package/esm/src/kernel/engine/runner/stream.d.ts +42 -11
  241. package/esm/src/kernel/engine/runner/stream.js +197 -46
  242. package/esm/src/kernel/engine/runner/usage.d.ts +5 -5
  243. package/esm/src/kernel/engine/runner/usage.js +12 -14
  244. package/esm/src/kernel/engine/session/mod.d.ts +8 -6
  245. package/esm/src/kernel/engine/session/mod.js +360 -129
  246. package/esm/src/kernel/engine/session/session-trace.d.ts +10 -10
  247. package/esm/src/kernel/engine/session/session-trace.js +41 -30
  248. package/esm/src/kernel/engine/token-estimate.d.ts +10 -64
  249. package/esm/src/kernel/engine/token-estimate.js +14 -194
  250. package/esm/src/kernel/engine/tool-trace.d.ts +3 -3
  251. package/esm/src/kernel/engine/tool-trace.js +2 -1
  252. package/esm/src/kernel/engine/turn-trace.d.ts +8 -7
  253. package/esm/src/kernel/engine/turn-trace.js +28 -36
  254. package/esm/src/kernel/engine/usage.d.ts +6 -0
  255. package/esm/src/kernel/engine/usage.js +17 -0
  256. package/esm/src/kernel/interaction-parts.d.ts +3 -0
  257. package/esm/src/kernel/interaction-parts.js +18 -0
  258. package/esm/src/kernel/json.d.ts +10 -0
  259. package/esm/src/kernel/json.js +3 -0
  260. package/esm/src/kernel/mod.d.ts +38 -11
  261. package/esm/src/kernel/mod.js +22 -7
  262. package/esm/src/kernel/profile-graph.d.ts +11 -6
  263. package/esm/src/kernel/profile-graph.js +14 -7
  264. package/esm/src/kernel/profile-presence.d.ts +10 -1
  265. package/esm/src/kernel/profile-presence.js +90 -75
  266. package/esm/src/kernel/profile-scope.d.ts +7 -3
  267. package/esm/src/kernel/profile-scope.js +67 -55
  268. package/esm/src/kernel/protocols/binding.d.ts +65 -0
  269. package/esm/src/kernel/protocols/binding.js +125 -0
  270. package/esm/src/kernel/protocols/limits.d.ts +15 -0
  271. package/esm/src/kernel/protocols/limits.js +28 -0
  272. package/esm/src/kernel/protocols/mod.d.ts +5 -0
  273. package/esm/src/kernel/protocols/mod.js +5 -0
  274. package/esm/src/kernel/protocols/prices.d.ts +36 -0
  275. package/esm/src/kernel/protocols/prices.js +37 -0
  276. package/esm/src/kernel/protocols/protocol.d.ts +253 -0
  277. package/esm/src/kernel/protocols/protocol.js +253 -0
  278. package/esm/src/kernel/protocols/provider.d.ts +108 -0
  279. package/esm/src/kernel/protocols/provider.js +143 -0
  280. package/esm/src/kernel/protocols/runtime.d.ts +55 -0
  281. package/esm/src/kernel/protocols/runtime.js +534 -0
  282. package/esm/src/kernel/provider-budget.d.ts +32 -0
  283. package/esm/src/kernel/provider-budget.js +262 -0
  284. package/esm/src/kernel/provider-dispatch.d.ts +13 -0
  285. package/esm/src/kernel/provider-dispatch.js +36 -0
  286. package/esm/src/kernel/provider-live.d.ts +7 -0
  287. package/esm/src/kernel/provider-live.js +189 -0
  288. package/esm/src/kernel/provider-runtime.d.ts +57 -0
  289. package/esm/src/kernel/provider-runtime.js +524 -0
  290. package/esm/src/kernel/registry/attachments.d.ts +15 -4
  291. package/esm/src/kernel/registry/attachments.js +31 -22
  292. package/esm/src/kernel/registry/catalog.d.ts +6 -0
  293. package/esm/src/kernel/registry/catalog.js +9 -2
  294. package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
  295. package/esm/src/kernel/registry/embedding-rules.js +66 -0
  296. package/esm/src/kernel/registry/ingress.d.ts +6 -2
  297. package/esm/src/kernel/registry/ingress.js +55 -10
  298. package/esm/src/kernel/registry/kernel-registry.d.ts +3 -0
  299. package/esm/src/kernel/registry/kernel-registry.js +9 -2
  300. package/esm/src/kernel/registry/profile-outputs.js +4 -1
  301. package/esm/src/kernel/registry/profiles.d.ts +38 -14
  302. package/esm/src/kernel/registry/profiles.js +280 -205
  303. package/esm/src/kernel/registry/provider-request.d.ts +3 -3
  304. package/esm/src/kernel/registry/provider-request.js +5 -13
  305. package/esm/src/kernel/registry/resolve.d.ts +4 -1
  306. package/esm/src/kernel/registry/resolve.js +59 -58
  307. package/esm/src/kernel/registry/schemas.d.ts +3 -0
  308. package/esm/src/kernel/registry/schemas.js +3 -1
  309. package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
  310. package/esm/src/kernel/registry/slot-fill.js +22 -0
  311. package/esm/src/kernel/registry/system-prompt.js +7 -8
  312. package/esm/src/kernel/registry/vault.d.ts +14 -13
  313. package/esm/src/kernel/registry/vault.js +1 -14
  314. package/esm/src/kernel/schema.d.ts +100 -46
  315. package/esm/src/kernel/schema.js +499 -257
  316. package/esm/src/kernel/scope.d.ts +12 -5
  317. package/esm/src/kernel/scope.js +23 -3
  318. package/esm/src/kernel/stages.d.ts +38 -3
  319. package/esm/src/kernel/stages.js +82 -39
  320. package/esm/src/kernel/stop.d.ts +29 -6
  321. package/esm/src/kernel/stop.js +16 -4
  322. package/esm/src/kernel/system-parts.js +6 -6
  323. package/esm/src/kernel/tools/activity-label.d.ts +12 -6
  324. package/esm/src/kernel/tools/activity-label.js +258 -32
  325. package/esm/src/kernel/tools/agent.d.ts +66 -0
  326. package/esm/src/kernel/tools/agent.js +212 -0
  327. package/esm/src/kernel/tools/coordinate.d.ts +4 -0
  328. package/esm/src/kernel/tools/coordinate.js +165 -0
  329. package/esm/src/kernel/tools/events.d.ts +21 -6
  330. package/esm/src/kernel/tools/events.js +53 -18
  331. package/esm/src/kernel/tools/execute.d.ts +47 -11
  332. package/esm/src/kernel/tools/execute.js +508 -136
  333. package/esm/src/kernel/tools/gate-answer.d.ts +12 -2
  334. package/esm/src/kernel/tools/gate-answer.js +17 -6
  335. package/esm/src/kernel/tools/handler-events.d.ts +45 -0
  336. package/esm/src/kernel/tools/handler-events.js +106 -0
  337. package/esm/src/kernel/tools/harness.d.ts +1 -0
  338. package/esm/src/kernel/tools/harness.js +2 -1
  339. package/esm/src/kernel/tools/http-limit.d.ts +27 -0
  340. package/esm/src/kernel/tools/http-limit.js +85 -0
  341. package/esm/src/kernel/tools/invoke.d.ts +27 -5
  342. package/esm/src/kernel/tools/invoke.js +223 -70
  343. package/esm/src/kernel/tools/mcp-sessions.d.ts +4 -1
  344. package/esm/src/kernel/tools/mcp-sessions.js +13 -8
  345. package/esm/src/kernel/tools/mod.d.ts +4 -3
  346. package/esm/src/kernel/tools/mod.js +3 -2
  347. package/esm/src/kernel/tools/model-text.d.ts +10 -5
  348. package/esm/src/kernel/tools/model-text.js +18 -12
  349. package/esm/src/kernel/tools/operation.d.ts +76 -0
  350. package/esm/src/kernel/tools/operation.js +100 -0
  351. package/esm/src/kernel/tools/page-answer.d.ts +8 -0
  352. package/esm/src/kernel/tools/page-answer.js +19 -0
  353. package/esm/src/kernel/tools/permission.d.ts +11 -2
  354. package/esm/src/kernel/tools/permission.js +12 -12
  355. package/esm/src/kernel/tools/project.d.ts +4 -1
  356. package/esm/src/kernel/tools/project.js +32 -2
  357. package/esm/src/kernel/tools/registry.d.ts +9 -2
  358. package/esm/src/kernel/tools/registry.js +69 -10
  359. package/esm/src/kernel/tools/remote.d.ts +40 -6
  360. package/esm/src/kernel/tools/remote.js +219 -92
  361. package/esm/src/kernel/tools/resolve.d.ts +3 -0
  362. package/esm/src/kernel/tools/resolve.js +12 -4
  363. package/esm/src/kernel/tools/run.d.ts +28 -0
  364. package/esm/src/kernel/tools/run.js +86 -0
  365. package/esm/src/kernel/tools/schema.d.ts +3 -3
  366. package/esm/src/kernel/tools/schema.js +21 -100
  367. package/esm/src/kernel/tools/signed-in-fetch.d.ts +2 -1
  368. package/esm/src/kernel/tools/signed-in-fetch.js +3 -3
  369. package/esm/src/kernel/tools/stage-run.d.ts +27 -4
  370. package/esm/src/kernel/tools/stage-run.js +75 -17
  371. package/esm/src/kernel/tools/types.d.ts +235 -25
  372. package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
  373. package/esm/src/kernel/tools/unchecked-output.js +18 -0
  374. package/esm/src/kernel/turn-events.d.ts +208 -31
  375. package/esm/src/kernel/turn-events.js +127 -9
  376. package/esm/src/kernel/types.d.ts +302 -161
  377. package/esm/src/kernel/util/base64.d.ts +2 -0
  378. package/esm/src/kernel/util/base64.js +2 -0
  379. package/esm/src/kernel/util/partial-json.d.ts +23 -0
  380. package/esm/src/kernel/util/partial-json.js +128 -0
  381. package/esm/src/kernel/util/record.d.ts +1 -0
  382. package/esm/src/kernel/util/record.js +1 -0
  383. package/esm/src/observability/destinations.d.ts +5 -0
  384. package/esm/src/observability/destinations.js +7 -2
  385. package/esm/src/observability/jsonl.d.ts +2 -2
  386. package/esm/src/observability/jsonl.js +15 -22
  387. package/esm/src/observability/mod.d.ts +3 -3
  388. package/esm/src/observability/mod.js +2 -2
  389. package/esm/src/observability/openinference.d.ts +1 -1
  390. package/esm/src/observability/openinference.js +3 -3
  391. package/esm/src/observability/otlp.d.ts +3 -0
  392. package/esm/src/observability/otlp.js +3 -3
  393. package/esm/src/observability/phoenix.d.ts +1 -0
  394. package/esm/src/observability/policy.d.ts +3 -0
  395. package/esm/src/observability/policy.js +5 -1
  396. package/esm/src/observability/resolve-policy.js +11 -5
  397. package/esm/src/observability/spans.d.ts +8 -2
  398. package/esm/src/observability/spans.js +21 -5
  399. package/esm/src/observability/trace-catalog.d.ts +19 -2
  400. package/esm/src/observability/trace-catalog.js +128 -87
  401. package/esm/src/observability/trace-record.js +22 -17
  402. package/esm/src/observability/trace-schema.d.ts +3 -0
  403. package/esm/src/observability/trace-schema.js +1 -1
  404. package/esm/src/observability/trace-sink.d.ts +1 -0
  405. package/esm/src/observability/trace-sink.js +1 -1
  406. package/esm/src/observability/trace-span.d.ts +7 -1
  407. package/esm/src/observability/trace-span.js +3 -1
  408. package/esm/src/observability/trace.d.ts +2 -0
  409. package/esm/src/observability/trace.js +4 -2
  410. package/esm/src/observability/types.d.ts +35 -11
  411. package/esm/src/observability/types.js +1 -1
  412. package/esm/src/presets/google/speech-voices.d.ts +1 -0
  413. package/esm/src/presets/google-limits.d.ts +1 -0
  414. package/esm/src/presets/google.d.ts +27 -12
  415. package/esm/src/presets/google.js +34 -25
  416. package/esm/src/presets/local.d.ts +26 -0
  417. package/esm/src/presets/local.js +30 -0
  418. package/esm/src/presets/mod.d.ts +5 -4
  419. package/esm/src/presets/mod.js +4 -4
  420. package/esm/src/presets/openrouter.d.ts +14 -1
  421. package/esm/src/presets/openrouter.js +19 -1
  422. package/esm/src/providers/embedding-limits.d.ts +7 -0
  423. package/esm/src/providers/embedding-limits.js +12 -0
  424. package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
  425. package/esm/src/providers/gemini/embedding-protocol.js +125 -0
  426. package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
  427. package/esm/src/providers/gemini/interactions-protocol.js +105 -0
  428. package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
  429. package/esm/src/providers/gemini/live-protocol.js +191 -0
  430. package/esm/src/providers/gemini/prices.d.ts +3 -0
  431. package/esm/src/providers/gemini/prices.js +63 -0
  432. package/esm/src/providers/gemini/provider.d.ts +7 -0
  433. package/esm/src/providers/gemini/provider.js +39 -0
  434. package/esm/src/providers/google/builtins.d.ts +14 -0
  435. package/esm/src/providers/google/builtins.js +57 -0
  436. package/esm/src/providers/google/grounding.d.ts +4 -4
  437. package/esm/src/providers/google/interactions/framing.d.ts +20 -8
  438. package/esm/src/providers/google/interactions/framing.js +85 -44
  439. package/esm/src/providers/google/interactions/steps.d.ts +5 -5
  440. package/esm/src/providers/google/interactions/steps.js +4 -4
  441. package/esm/src/providers/google/interactions/stream.d.ts +10 -11
  442. package/esm/src/providers/google/interactions/stream.js +33 -100
  443. package/esm/src/providers/google/live/framing.d.ts +15 -5
  444. package/esm/src/providers/google/live/framing.js +25 -25
  445. package/esm/src/providers/google/live/stream.d.ts +6 -44
  446. package/esm/src/providers/google/live/stream.js +3 -209
  447. package/esm/src/providers/google/urls.d.ts +1 -3
  448. package/esm/src/providers/google/urls.js +1 -3
  449. package/esm/src/providers/google/usage.js +2 -2
  450. package/esm/src/providers/live.d.ts +6 -0
  451. package/esm/src/providers/live.js +6 -0
  452. package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
  453. package/esm/src/providers/local/embedding-protocol.js +60 -0
  454. package/esm/src/providers/local/provider.d.ts +7 -0
  455. package/esm/src/providers/local/provider.js +28 -0
  456. package/esm/src/providers/mod.d.ts +28 -7
  457. package/esm/src/providers/mod.js +19 -3
  458. package/esm/src/providers/open-ai/protocol.d.ts +3 -0
  459. package/esm/src/providers/open-ai/protocol.js +189 -0
  460. package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
  461. package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
  462. package/esm/src/providers/openrouter/image.d.ts +0 -9
  463. package/esm/src/providers/openrouter/image.js +0 -153
  464. package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
  465. package/esm/src/providers/openrouter/images-protocol.js +82 -0
  466. package/esm/src/providers/openrouter/openai/compat.d.ts +2 -2
  467. package/esm/src/providers/openrouter/openai/compat.js +6 -6
  468. package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
  469. package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
  470. package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
  471. package/esm/src/providers/openrouter/protocol.d.ts +8 -0
  472. package/esm/src/providers/openrouter/protocol.js +171 -0
  473. package/esm/src/providers/openrouter/provider.d.ts +10 -0
  474. package/esm/src/providers/openrouter/provider.js +50 -0
  475. package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
  476. package/esm/src/providers/shared/carried-tool-files.js +43 -0
  477. package/esm/src/providers/shared/pcm.js +2 -2
  478. package/esm/src/providers/shared/protocol-events.d.ts +8 -0
  479. package/esm/src/providers/shared/protocol-events.js +20 -0
  480. package/esm/src/providers/shared/response-identity.d.ts +2 -2
  481. package/esm/src/providers/shared/retry.d.ts +17 -0
  482. package/esm/src/providers/shared/retry.js +90 -0
  483. package/esm/src/providers/shared/sse.d.ts +0 -4
  484. package/esm/src/providers/shared/sse.js +50 -36
  485. package/esm/src/providers/shared/tool-args.d.ts +6 -7
  486. package/esm/src/providers/shared/tool-args.js +10 -6
  487. package/esm/src/providers/shared/tool-draft.d.ts +16 -0
  488. package/esm/src/providers/shared/tool-draft.js +14 -0
  489. package/esm/src/providers/shared/upstream-tap.d.ts +2 -2
  490. package/esm/src/providers/shared/upstream-tape.js +1 -1
  491. package/esm/src/providers/system-one/protocol.d.ts +8 -0
  492. package/esm/src/providers/system-one/protocol.js +93 -0
  493. package/esm/src/providers/types.d.ts +48 -16
  494. package/esm/src/providers/types.js +2 -1
  495. package/esm/src/providers/typesafe/provider.d.ts +7 -0
  496. package/esm/src/providers/typesafe/provider.js +24 -0
  497. package/esm/src/surface/formats.d.ts +19 -1
  498. package/esm/src/surface/formats.js +68 -29
  499. package/esm/src/surface/mod.d.ts +4 -2
  500. package/esm/src/surface/mod.js +4 -2
  501. package/esm/src/surface/runtime.d.ts +4 -0
  502. package/esm/src/surface/runtime.js +2 -0
  503. package/esm/src/surface/tools.d.ts +2 -8
  504. package/esm/src/surface/tools.js +4 -22
  505. package/esm/src/surface/types.d.ts +6 -0
  506. package/package.json +5 -13
  507. package/esm/src/cli/commands/egress-compile.d.ts +0 -17
  508. package/esm/src/cli/commands/egress-compile.js +0 -25
  509. package/esm/src/guardrails/egress-policy.d.ts +0 -27
  510. package/esm/src/guardrails/egress-policy.js +0 -76
  511. package/esm/src/guardrails/egress-rules.d.ts +0 -54
  512. package/esm/src/guardrails/egress-rules.js +0 -49
  513. package/esm/src/guardrails/lexicon.d.ts +0 -30
  514. package/esm/src/guardrails/lexicon.js +0 -478
  515. package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
  516. package/esm/src/kernel/engine/media-probe/audio.js +0 -342
  517. package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
  518. package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
  519. package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
  520. package/esm/src/kernel/engine/media-probe/image.js +0 -171
  521. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
  522. package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
  523. package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
  524. package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
  525. package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
  526. package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
  527. package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
  528. package/esm/src/kernel/engine/media-probe/opus.js +0 -23
  529. package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
  530. package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
  531. package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
  532. package/esm/src/kernel/engine/media-probe/video.js +0 -49
  533. package/esm/src/presets/typesafe.d.ts +0 -2
  534. package/esm/src/presets/typesafe.js +0 -2
  535. package/esm/src/providers/create-provider.d.ts +0 -21
  536. package/esm/src/providers/create-provider.js +0 -90
  537. package/esm/src/providers/decision/usage.d.ts +0 -3
  538. package/esm/src/providers/decision/usage.js +0 -25
  539. package/esm/src/providers/google/interactions/mod.d.ts +0 -2
  540. package/esm/src/providers/google/interactions/mod.js +0 -2
  541. package/esm/src/providers/google/keys.d.ts +0 -20
  542. package/esm/src/providers/google/keys.js +0 -87
  543. package/esm/src/providers/google/live/mod.d.ts +0 -7
  544. package/esm/src/providers/google/live/mod.js +0 -7
  545. package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
  546. package/esm/src/providers/google/live/openapi-schema.js +0 -42
  547. package/esm/src/providers/google/live/session.d.ts +0 -14
  548. package/esm/src/providers/google/live/session.js +0 -150
  549. package/esm/src/providers/local/local.d.ts +0 -12
  550. package/esm/src/providers/local/local.js +0 -186
  551. package/esm/src/providers/local/mod.d.ts +0 -8
  552. package/esm/src/providers/local/mod.js +0 -8
  553. package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
  554. package/esm/src/providers/openrouter/cache-control.js +0 -4
  555. package/esm/src/providers/openrouter/chat.d.ts +0 -64
  556. package/esm/src/providers/openrouter/chat.js +0 -490
  557. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
  558. package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
  559. package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
  560. package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
  561. package/esm/src/providers/openrouter/speech.d.ts +0 -18
  562. package/esm/src/providers/openrouter/speech.js +0 -109
  563. package/esm/src/providers/probe.d.ts +0 -5
  564. package/esm/src/providers/probe.js +0 -15
  565. package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
  566. package/esm/src/providers/shared/builtin-wire.js +0 -9
  567. package/esm/src/providers/shared/vault.d.ts +0 -13
  568. package/esm/src/providers/shared/vault.js +0 -41
@@ -0,0 +1,3 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ /** OpenAI Chat Completions: the shape most compatible servers speak. */
3
+ export declare const openAi: Protocol<Record<string, never>>;
@@ -0,0 +1,189 @@
1
+ import { z } from 'zod';
2
+ import { kindOfHttpStatus, TheoremError } from '../../guardrails/error.js';
3
+ import { asRecord } from '../../kernel/engine/record.js';
4
+ import { defineProtocol, } from '../../kernel/protocols/mod.js';
5
+ import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
6
+ import { base64ToBytes, bytesToBase64 } from '../../kernel/util/base64.js';
7
+ import { mimeEssence } from '../../kernel/util/mime.js';
8
+ import { buildChatMessages, resolveResponseFormat, wireTools, } from '../openrouter/openai/compat.js';
9
+ import { openAiResponse, openAiUsageTokens } from '../openrouter/openai/usage.js';
10
+ import { pcmFormatFromMime, wrapPcmAsWav } from '../shared/pcm.js';
11
+ import { asProtocolEvent } from '../shared/protocol-events.js';
12
+ import { foldResponse } from '../shared/response-identity.js';
13
+ import { structuredEvent } from '../shared/structured-output.js';
14
+ import { toolCallEvents } from '../shared/tool-args.js';
15
+ import { toolDraftEvents } from '../shared/tool-draft.js';
16
+ /** Old-shape events from the shared helpers, as protocol events. */
17
+ function asProtocolEvents(events) {
18
+ return events.flatMap((event) => asProtocolEvent(event) ?? []);
19
+ }
20
+ function requestBody(context, request) {
21
+ const stream = request.stream !== false;
22
+ const tools = wireTools(request.wireTools);
23
+ const format = resolveResponseFormat(request.structured);
24
+ const body = {
25
+ model: context.apiId,
26
+ // why: replayed reasoning belongs to the protocol that wrote it, never to plain Chat Completions.
27
+ messages: buildChatMessages(request),
28
+ stream,
29
+ ...(stream ? { stream_options: { include_usage: true } } : {}),
30
+ ...(request.temperature === undefined ? {} : { temperature: request.temperature }),
31
+ ...(request.maxOutputTokens === undefined ? {} : { max_tokens: request.maxOutputTokens }),
32
+ ...(request.thinking ? { reasoning_effort: request.thinking } : {}),
33
+ ...(format ? { response_format: format } : {}),
34
+ // probed 2026-10-09: an empty `tools` list counts as a parameter the model must support, so OpenRouter refuses models without tool calling.
35
+ ...(tools ? { tools } : {}),
36
+ };
37
+ return JSON.parse(JSON.stringify(body));
38
+ }
39
+ /** An error row inside a 200 reply: thrown, so a quota refusal before any output can still fall back. */
40
+ function errorRow(row) {
41
+ const error = asRecord(row.error);
42
+ if (!error)
43
+ return;
44
+ const status = typeof error.code === 'number' ? error.code : 502;
45
+ const message = typeof error.message === 'string' ? error.message : JSON.stringify(error);
46
+ throw new TheoremError(kindOfHttpStatus(status), message);
47
+ }
48
+ function citations(part, reply) {
49
+ const sources = (Array.isArray(part.annotations) ? part.annotations : []).flatMap((item) => {
50
+ const cited = asRecord(asRecord(item)?.url_citation);
51
+ if (typeof cited?.url !== 'string' || reply.cited.has(cited.url))
52
+ return [];
53
+ reply.cited.add(cited.url);
54
+ const title = typeof cited.title === 'string' && cited.title ? cited.title : cited.url;
55
+ return [{ title, uri: cited.url, type: 'web' }];
56
+ });
57
+ return sources.length ? [{ type: 'citation', sources }] : [];
58
+ }
59
+ function mergeCalls(part, reply) {
60
+ for (const [position, value] of (Array.isArray(part.tool_calls)
61
+ ? part.tool_calls
62
+ : []).entries()) {
63
+ const call = asRecord(value);
64
+ const fn = asRecord(call?.function);
65
+ const index = typeof call?.index === 'number' ? call.index : position;
66
+ const current = reply.calls.get(index) ?? { name: '', args: '' };
67
+ if (typeof call?.id === 'string' && call.id)
68
+ current.id = call.id;
69
+ if (typeof fn?.name === 'string')
70
+ current.name += fn.name;
71
+ if (typeof fn?.arguments === 'string')
72
+ current.args += fn.arguments;
73
+ reply.calls.set(index, current);
74
+ }
75
+ }
76
+ /** One choice's delta (streamed) or message (whole). */
77
+ function partEvents(part, reply, request) {
78
+ const events = [];
79
+ const thought = part.reasoning ?? part.reasoning_content;
80
+ if (typeof thought === 'string' && thought && request.summaries !== 'none')
81
+ events.push({ type: 'thought', text: thought });
82
+ if (typeof part.content === 'string' && part.content) {
83
+ reply.text += part.content;
84
+ events.push({ type: 'text', text: part.content });
85
+ }
86
+ events.push(...citations(part, reply));
87
+ mergeCalls(part, reply);
88
+ return events;
89
+ }
90
+ function rowEvents(row, reply, request, stream) {
91
+ errorRow(row);
92
+ const events = [];
93
+ const identity = foldResponse(reply.response, openAiResponse(row));
94
+ reply.response = identity.known;
95
+ if (identity.event)
96
+ events.push(identity.event);
97
+ const tokens = reply.tokens ? undefined : openAiUsageTokens(row.usage);
98
+ if (tokens) {
99
+ reply.tokens = true;
100
+ events.push({ type: 'tokens', tokens });
101
+ }
102
+ for (const item of Array.isArray(row.choices) ? row.choices : []) {
103
+ const choice = asRecord(item);
104
+ const part = asRecord(stream ? choice?.delta : choice?.message);
105
+ if (part)
106
+ events.push(...partEvents(part, reply, request));
107
+ if (typeof choice?.finish_reason === 'string')
108
+ reply.finish = choice.finish_reason;
109
+ // why: gateways add the upstream's own reason beside it; it tells a provider failure from a stop.
110
+ if (typeof choice?.native_finish_reason === 'string')
111
+ reply.native = choice.native_finish_reason;
112
+ }
113
+ // why: a whole reply carries each call complete; only a streamed one has a draft to show.
114
+ if (stream)
115
+ for (const call of reply.calls.values())
116
+ events.push(...asProtocolEvents(toolDraftEvents(call)));
117
+ return events;
118
+ }
119
+ /** The calls, the structured reply, and the stop, once the rows are done. */
120
+ function endEvents(reply, request) {
121
+ const events = [];
122
+ // why: some compatible servers end a tool-calling reply with `stop`, so the calls go out whatever the finish.
123
+ for (const [index, call] of reply.calls)
124
+ events.push(...asProtocolEvents(toolCallEvents({ ...call, id: call.id ?? `call_${index}` }, call.args)));
125
+ const stop = turnStopFromOpenAiFinishReason(reply.finish, reply.native);
126
+ if (request.structured && reply.text && stop.kind === 'completed') {
127
+ const structured = asProtocolEvents([structuredEvent(reply.text)]);
128
+ events.push(...structured);
129
+ if (structured[0]?.type === 'error')
130
+ return events;
131
+ }
132
+ events.push({ type: 'done', stop });
133
+ return events;
134
+ }
135
+ /** `/audio/speech`: the input's text read aloud, answered whole. Raw PCM with a stated rate becomes WAV. */
136
+ async function* speech(context, request) {
137
+ const text = request.input
138
+ .flatMap((part) => (part.type === 'text' ? [part.text] : []))
139
+ .join(' ')
140
+ .trim();
141
+ if (!text)
142
+ throw new TheoremError('request', 'empty text for speech');
143
+ const spec = request.speech;
144
+ const body = {
145
+ model: context.apiId,
146
+ input: text,
147
+ ...(spec?.format ? { response_format: spec.format } : {}),
148
+ ...(spec?.voice ? { voice: spec.voice } : {}),
149
+ ...(spec?.speed === undefined ? {} : { speed: spec.speed }),
150
+ // why: `instructions` is the endpoint's own field for delivery, never read aloud (probe 07/10/2026: Gemini 3.8 slowed and sped by it).
151
+ ...(spec?.style ? { instructions: spec.style } : {}),
152
+ };
153
+ for await (const row of context.send(body, { stream: false })) {
154
+ const type = typeof row.mime_type === 'string' ? row.mime_type : '';
155
+ const bytes = typeof row.data === 'string' ? base64ToBytes(row.data) : new Uint8Array();
156
+ if (!bytes.length)
157
+ throw new TheoremError('bad_response', 'no audio returned from speech');
158
+ const pcm = pcmFormatFromMime(type);
159
+ const media = pcm
160
+ ? { mimeType: 'audio/wav', data: bytesToBase64(wrapPcmAsWav(bytes, pcm)) }
161
+ : { mimeType: mimeEssence(type) || 'application/octet-stream', data: row.data };
162
+ yield { type: 'media', media };
163
+ // why: the endpoint answers whole or not at all: a body with audio completed.
164
+ yield { type: 'done', stop: { kind: 'completed' } };
165
+ }
166
+ }
167
+ /** OpenAI Chat Completions: the shape most compatible servers speak. */
168
+ export const openAi = defineProtocol({
169
+ id: 'openAi',
170
+ name: 'OpenAI Chat Completions',
171
+ description: 'The Chat Completions shape that OpenAI and most compatible servers speak.', // labels-exempt: builder field description, read by the studio and docs
172
+ endpoints: { text: '/chat/completions', speech: '/audio/speech' },
173
+ options: z.strictObject({}),
174
+ create(context) {
175
+ return {
176
+ async *complete(request) {
177
+ if (context.profileType === 'speech') {
178
+ yield* speech(context, request);
179
+ return;
180
+ }
181
+ const stream = request.stream !== false;
182
+ const reply = { text: '', tokens: false, cited: new Set(), calls: new Map() };
183
+ for await (const row of context.send(requestBody(context, request), { stream }))
184
+ yield* rowEvents(row, reply, request, stream);
185
+ yield* endEvents(reply, request);
186
+ },
187
+ };
188
+ },
189
+ });
@@ -0,0 +1,6 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ /** What an `openRouterEmbedding` binding sets in `options`. */
3
+ export interface OpenRouterEmbeddingOptions {
4
+ encodingFormat?: 'float' | 'base64';
5
+ }
6
+ export declare const openRouterEmbedding: Protocol<OpenRouterEmbeddingOptions>;
@@ -0,0 +1,86 @@
1
+ import { z } from 'zod';
2
+ import { defineProtocol, } from '../../kernel/protocols/mod.js';
3
+ import { base64ToBytes } from '../../kernel/util/base64.js';
4
+ const options = z.strictObject({
5
+ encodingFormat: z
6
+ .enum(['float', 'base64'])
7
+ .optional()
8
+ .describe('How OpenRouter sends each vector back: as a list of numbers (`float`) or packed into a base64 string (`base64`, smaller on the wire). Theorem decodes both to the same numbers. Absent: `float`.'),
9
+ });
10
+ // why: OpenRouter's embeddings reference takes images only and caps neither inputs nor images per input; a text-only model refuses an image itself.
11
+ const LIMITS = { media: [{ accept: ['image/*'] }] };
12
+ /** A string stays a string; a multimodal input is one `{ content }` item, as OpenRouter documents. */
13
+ function inputValue(input) {
14
+ if (typeof input === 'string')
15
+ return input;
16
+ return {
17
+ content: input.parts.map((part) => {
18
+ if (part.type === 'text')
19
+ return { type: 'text', text: part.text };
20
+ const url = part.type === 'media' ? `data:${part.mimeType};base64,${part.data}` : part.uri;
21
+ return { type: 'image_url', image_url: { url } };
22
+ }),
23
+ };
24
+ }
25
+ function embeddingValues(value) {
26
+ if (Array.isArray(value)) {
27
+ if (!value.every((entry) => typeof entry === 'number' && Number.isFinite(entry))) {
28
+ throw new Error('OpenRouter returned an embedding with a non-finite value');
29
+ }
30
+ return value;
31
+ }
32
+ if (typeof value !== 'string') {
33
+ throw new Error('OpenRouter returned an embedding in an unsupported format');
34
+ }
35
+ const bytes = base64ToBytes(value);
36
+ if (bytes.byteLength % Float32Array.BYTES_PER_ELEMENT !== 0) {
37
+ throw new Error('OpenRouter returned an invalid base64 embedding length');
38
+ }
39
+ return Array.from(new Float32Array(bytes.buffer, bytes.byteOffset, bytes.byteLength / Float32Array.BYTES_PER_ELEMENT));
40
+ }
41
+ export const openRouterEmbedding = defineProtocol({
42
+ id: 'openRouterEmbedding',
43
+ name: 'OpenRouter Embeddings',
44
+ description: 'OpenRouter embedding models, including supported multimodal models.',
45
+ endpoints: { embedding: '/embeddings' },
46
+ options,
47
+ embeddingLimits: () => LIMITS,
48
+ create(context) {
49
+ return {
50
+ async embed(request) {
51
+ const parsed = options.parse(request.options ?? {});
52
+ const inputs = Array.isArray(request.input) ? request.input : [request.input];
53
+ const body = {
54
+ model: context.apiId,
55
+ input: inputs.length === 1 && typeof inputs[0] === 'string'
56
+ ? inputs[0]
57
+ : inputs.map(inputValue),
58
+ };
59
+ if (parsed.encodingFormat)
60
+ body.encoding_format = parsed.encodingFormat;
61
+ let row;
62
+ for await (const current of context.send(body, { stream: false }))
63
+ row = current;
64
+ const data = Array.isArray(row?.data) ? row.data : [];
65
+ const usage = row?.usage && typeof row.usage === 'object'
66
+ ? row.usage
67
+ : undefined;
68
+ return {
69
+ model: typeof row?.model === 'string' ? row.model : context.apiId,
70
+ embeddings: data.map((item, position) => {
71
+ const record = item && typeof item === 'object' ? item : {};
72
+ const values = embeddingValues(record.embedding);
73
+ return {
74
+ index: typeof record.index === 'number' ? record.index : position,
75
+ values,
76
+ dimensions: values.length,
77
+ };
78
+ }),
79
+ ...(typeof usage?.prompt_tokens === 'number'
80
+ ? { usage: { inputTokens: usage.prompt_tokens } }
81
+ : {}),
82
+ };
83
+ },
84
+ };
85
+ },
86
+ });
@@ -1,8 +1,4 @@
1
- import type { ModelProvider, ProviderCompleteRequest, ProviderEvent } from '../../kernel/types.js';
2
- import type { OpenAiGatewayTransport } from '../types.js';
3
1
  export declare const OPENROUTER_IMAGE_TOOL = "openrouter:image_generation";
4
- export type ImageProviderConfig = OpenAiGatewayTransport;
5
- export declare function buildImageHeaders(apiKey: string, config: ImageProviderConfig): Record<string, string>;
6
2
  /** `/images` answers `data[]` of `b64_json` + `media_type` (probe 23/09/2026, bytedance-seed/seedream-4.5). */
7
3
  export declare function imagesFromImagesBody(body: Record<string, unknown>): {
8
4
  mimeType: string;
@@ -17,8 +13,3 @@ export declare function imagesFromChatMessage(message: Record<string, unknown>):
17
13
  mimeType: string;
18
14
  data: string;
19
15
  }[];
20
- export declare function buildInterleavedChatPayload(req: ProviderCompleteRequest): Record<string, unknown>;
21
- export declare function yieldInterleavedChat(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<ProviderEvent>;
22
- export declare function yieldImagesEndpoint(req: ProviderCompleteRequest, config: ImageProviderConfig, apiKey: string): AsyncGenerator<ProviderEvent>;
23
- export declare function streamImage(req: ProviderCompleteRequest, config?: ImageProviderConfig): AsyncGenerator<ProviderEvent>;
24
- export declare function createImageProvider(config?: ImageProviderConfig): ModelProvider;
@@ -1,35 +1,5 @@
1
- import { TheoremError, toErrorEvent } from '../../guardrails/error.js';
2
1
  import { asRecord, nonEmptyString } from '../../kernel/engine/record.js';
3
- import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
4
- import { networkFetch } from '../shared/upstream-tap.js';
5
- import { bearerFetch } from '../shared/vault.js';
6
- import { buildChatMessages, httpErrorEvent, openAiGatewayHeaders } from './openai/compat.js';
7
- import { buildImagesPayload, extractPromptText, imageToolParameters, } from './openai/image-payload.js';
8
- import { openAiUsageTokens } from './openai/usage.js';
9
- import { resolveOpenAiGatewayApiKey } from './resolve-api-key.js';
10
- const HTTP_OK = 200;
11
2
  export const OPENROUTER_IMAGE_TOOL = 'openrouter:image_generation';
12
- export function buildImageHeaders(apiKey, config) {
13
- const headers = {
14
- Authorization: `Bearer ${apiKey}`,
15
- 'Content-Type': 'application/json',
16
- };
17
- const gateway = openAiGatewayHeaders(config);
18
- if (gateway) {
19
- Object.assign(headers, gateway);
20
- }
21
- return headers;
22
- }
23
- function baseUrl(config) {
24
- return config.baseUrl?.replace(/\/+$/, '') ?? 'https://openrouter.ai/api/v1';
25
- }
26
- function* yieldUsage(raw) {
27
- const tokens = openAiUsageTokens(raw);
28
- if (!tokens) {
29
- return;
30
- }
31
- yield { type: 'tokens', tokens };
32
- }
33
3
  /** `/images` answers `data[]` of `b64_json` + `media_type` (probe 23/09/2026, bytedance-seed/seedream-4.5). */
34
4
  export function imagesFromImagesBody(body) {
35
5
  const entries = Array.isArray(body.data) ? body.data : [];
@@ -62,126 +32,3 @@ export function imagesFromChatMessage(message) {
62
32
  return media ? [media] : [];
63
33
  });
64
34
  }
65
- async function postJson(req, config, apiKey, path, body) {
66
- const fetchFn = bearerFetch(req, networkFetch(config.fetch ?? fetch), config.vault, apiKey);
67
- return await fetchFn(`${baseUrl(config)}${path}`, {
68
- method: 'POST',
69
- headers: buildImageHeaders(apiKey, config),
70
- body: JSON.stringify(body),
71
- signal: req.signal,
72
- });
73
- }
74
- async function readTapedJson(req, res) {
75
- const body = (await res.json());
76
- req.tapUpstream?.(body);
77
- return body;
78
- }
79
- async function requestImages(req, config, apiKey) {
80
- return await postJson(req, config, apiKey, '/images', buildImagesPayload(req));
81
- }
82
- export function buildInterleavedChatPayload(req) {
83
- if (!req.image) {
84
- throw new Error('buildInterleavedChatPayload requires req.image');
85
- }
86
- return {
87
- model: req.apiId,
88
- stream: false,
89
- messages: buildChatMessages(req),
90
- temperature: req.temperature,
91
- max_tokens: req.maxOutputTokens,
92
- ...(req.thinking ? { reasoning: { effort: req.thinking } } : {}),
93
- tools: [
94
- {
95
- type: OPENROUTER_IMAGE_TOOL,
96
- parameters: imageToolParameters(req.image),
97
- },
98
- ],
99
- };
100
- }
101
- async function requestInterleavedChat(req, config, apiKey) {
102
- return await postJson(req, config, apiKey, '/chat/completions', buildInterleavedChatPayload(req));
103
- }
104
- export async function* yieldInterleavedChat(req, config, apiKey) {
105
- const res = await requestInterleavedChat(req, config, apiKey);
106
- if (res.status !== HTTP_OK) {
107
- yield await httpErrorEvent(res, 'Image chat');
108
- return;
109
- }
110
- const body = await readTapedJson(req, res);
111
- const choices = body.choices;
112
- if (!Array.isArray(choices) || choices.length === 0) {
113
- yield toErrorEvent(new TheoremError('bad_response', 'no chat choices returned for image generation'));
114
- return;
115
- }
116
- const choice = asRecord(choices[0]);
117
- const message = asRecord(choice?.message);
118
- if (!message) {
119
- yield toErrorEvent(new TheoremError('bad_response', 'no assistant message returned for image generation'));
120
- return;
121
- }
122
- const text = nonEmptyString(message.content);
123
- if (text) {
124
- yield { type: 'text', text };
125
- }
126
- const images = imagesFromChatMessage(message);
127
- if (images.length === 0) {
128
- yield toErrorEvent(new TheoremError('bad_response', 'no image returned from chat image generation'));
129
- return;
130
- }
131
- for (const media of images) {
132
- yield { type: 'media', media };
133
- }
134
- yield* yieldUsage(body.usage);
135
- yield {
136
- type: 'done',
137
- stop: turnStopFromOpenAiFinishReason(typeof choice?.finish_reason === 'string' ? choice.finish_reason : undefined, typeof choice?.native_finish_reason === 'string' ? choice.native_finish_reason : undefined),
138
- };
139
- }
140
- export async function* yieldImagesEndpoint(req, config, apiKey) {
141
- const res = await requestImages(req, config, apiKey);
142
- if (res.status !== HTTP_OK) {
143
- yield await httpErrorEvent(res, 'Image');
144
- return;
145
- }
146
- const body = await readTapedJson(req, res);
147
- const images = imagesFromImagesBody(body);
148
- if (images.length === 0) {
149
- yield toErrorEvent(new TheoremError('bad_response', 'no image returned from image generation'));
150
- return;
151
- }
152
- for (const media of images) {
153
- yield { type: 'media', media };
154
- }
155
- yield* yieldUsage(body.usage);
156
- // The endpoint answers whole or not at all: a body with images completed.
157
- yield { type: 'done', stop: { kind: 'completed' } };
158
- }
159
- export async function* streamImage(req, config = {}) {
160
- let apiKey;
161
- try {
162
- apiKey = resolveOpenAiGatewayApiKey(config, req.keySlot);
163
- }
164
- catch (err) {
165
- yield toErrorEvent(err);
166
- return;
167
- }
168
- if (!req.image) {
169
- yield toErrorEvent(new TheoremError('request', 'missing image response format'));
170
- return;
171
- }
172
- const prompt = extractPromptText(req.input);
173
- if (!prompt) {
174
- yield toErrorEvent(new TheoremError('request', 'empty text for image generation'));
175
- return;
176
- }
177
- if (req.image.includeText) {
178
- yield* yieldInterleavedChat(req, config, apiKey);
179
- return;
180
- }
181
- yield* yieldImagesEndpoint(req, config, apiKey);
182
- }
183
- export function createImageProvider(config = {}) {
184
- return {
185
- complete: (req) => streamImage(req, config),
186
- };
187
- }
@@ -0,0 +1,3 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ /** OpenRouter's image generation: `/images`, or the chat path with its image tool when text is wanted too. */
3
+ export declare const openRouterImages: Protocol<Record<string, never>>;
@@ -0,0 +1,82 @@
1
+ import { z } from 'zod';
2
+ import { TheoremError } from '../../guardrails/error.js';
3
+ import { asRecord, nonEmptyString } from '../../kernel/engine/record.js';
4
+ import { defineProtocol, } from '../../kernel/protocols/mod.js';
5
+ import { turnStopFromOpenAiFinishReason } from '../../kernel/stop.js';
6
+ import { imagesFromChatMessage, imagesFromImagesBody, OPENROUTER_IMAGE_TOOL } from './image.js';
7
+ import { buildChatMessages } from './openai/compat.js';
8
+ import { buildImagesPayload, extractPromptText, imageToolParameters, } from './openai/image-payload.js';
9
+ import { openAiUsageTokens } from './openai/usage.js';
10
+ function json(value) {
11
+ return JSON.parse(JSON.stringify(value));
12
+ }
13
+ function tokens(row) {
14
+ const counted = openAiUsageTokens(row.usage);
15
+ return counted ? [{ type: 'tokens', tokens: counted }] : [];
16
+ }
17
+ function noImage() {
18
+ return new TheoremError('bad_response', 'no image returned from image generation');
19
+ }
20
+ /** `/images`: the picture alone, answered whole. */
21
+ async function* images(context, request) {
22
+ const body = json(buildImagesPayload({ ...request, apiId: context.apiId }));
23
+ for await (const row of context.send(body, { stream: false })) {
24
+ const media = imagesFromImagesBody(row);
25
+ if (!media.length)
26
+ throw noImage();
27
+ for (const item of media)
28
+ yield { type: 'media', media: item };
29
+ yield* tokens(row);
30
+ // why: the endpoint answers whole or not at all: a body with images completed.
31
+ yield { type: 'done', stop: { kind: 'completed' } };
32
+ }
33
+ }
34
+ /** Text with the picture: Chat Completions with OpenRouter's image tool, on the chat path. */
35
+ async function* withText(context, request, image) {
36
+ const body = json({
37
+ model: context.apiId,
38
+ stream: false,
39
+ provider: { require_parameters: true },
40
+ messages: buildChatMessages(request),
41
+ temperature: request.temperature,
42
+ max_tokens: request.maxOutputTokens,
43
+ ...(request.thinking ? { reasoning: { effort: request.thinking } } : {}),
44
+ tools: [{ type: OPENROUTER_IMAGE_TOOL, parameters: imageToolParameters(image) }],
45
+ });
46
+ for await (const row of context.send(body, { stream: false, path: '/chat/completions' })) {
47
+ const choice = asRecord(Array.isArray(row.choices) ? row.choices[0] : undefined);
48
+ const message = asRecord(choice?.message);
49
+ const text = nonEmptyString(message?.content);
50
+ if (text)
51
+ yield { type: 'text', text };
52
+ const media = message ? imagesFromChatMessage(message) : [];
53
+ if (!media.length)
54
+ throw noImage();
55
+ for (const item of media)
56
+ yield { type: 'media', media: item };
57
+ yield* tokens(row);
58
+ const finish = typeof choice?.finish_reason === 'string' ? choice.finish_reason : undefined;
59
+ const native = typeof choice?.native_finish_reason === 'string' ? choice.native_finish_reason : undefined;
60
+ yield { type: 'done', stop: turnStopFromOpenAiFinishReason(finish, native) };
61
+ }
62
+ }
63
+ /** OpenRouter's image generation: `/images`, or the chat path with its image tool when text is wanted too. */
64
+ export const openRouterImages = defineProtocol({
65
+ id: 'openRouterImages',
66
+ name: 'OpenRouter Images',
67
+ description: "OpenRouter's image generation, with or without text beside the picture.", // labels-exempt: builder field description, read by the studio and docs
68
+ endpoints: { image: '/images' },
69
+ options: z.strictObject({}),
70
+ create(context) {
71
+ return {
72
+ complete(request) {
73
+ const image = request.image;
74
+ if (!image)
75
+ throw new TheoremError('request', 'missing image response format');
76
+ if (!extractPromptText(request.input))
77
+ throw new TheoremError('request', 'empty text for image generation');
78
+ return image.includeText ? withText(context, request, image) : images(context, request);
79
+ },
80
+ };
81
+ },
82
+ });
@@ -1,5 +1,5 @@
1
1
  import { type ProducedError } from '../../../guardrails/error.js';
2
- import type { InteractionPart, ProviderCompleteRequest, ResolvedStructured, WireFunctionTool } from '../../../kernel/types.js';
2
+ import type { InteractionPart, ModelRequest, ResolvedStructured, WireFunctionTool } from '../../../kernel/types.js';
3
3
  /** The detail is the body's `error.message` (or raw text), so the upstream reason reaches traces. */
4
4
  declare function httpErrorEvent(res: Response, label: string): Promise<ProducedError>;
5
5
  interface GatewayHeaderConfig {
@@ -9,7 +9,7 @@ interface GatewayHeaderConfig {
9
9
  /** Text-only input collapses to one string; mixed input is a content-part array. */
10
10
  export declare function wireMessageContent(parts: InteractionPart[]): unknown;
11
11
  /** `includeSystem: false` when the caller passes system text separately (AI SDK `instructions`). */
12
- declare function buildChatMessages(req: ProviderCompleteRequest, options?: {
12
+ declare function buildChatMessages(req: Pick<ModelRequest, 'system' | 'history' | 'input'>, options?: {
13
13
  includeSystem?: boolean;
14
14
  }): Record<string, unknown>[];
15
15
  declare function wireTools(wireTools?: WireFunctionTool[]): Record<string, unknown>[] | undefined;
@@ -1,6 +1,7 @@
1
1
  import { kindOfHttpStatus, TheoremError, toErrorEvent, } from '../../../guardrails/error.js';
2
2
  import { asRecord } from '../../../kernel/engine/record.js';
3
3
  import { historyMessageParts, isMediaRefPart } from '../../../kernel/interaction-parts.js';
4
+ import { withCarriedToolFiles } from '../../shared/carried-tool-files.js';
4
5
  import { historyToolIdentity } from '../../shared/tool-args.js';
5
6
  /** The detail is the body's `error.message` (or raw text), so the upstream reason reaches traces. */
6
7
  async function httpErrorEvent(res, label) {
@@ -12,7 +13,7 @@ async function httpErrorEvent(res, label) {
12
13
  detail = message;
13
14
  }
14
15
  catch {
15
- // Not JSON: the raw body is the detail.
16
+ // why: Not JSON: the raw body is the detail.
16
17
  }
17
18
  const head = `${label} HTTP ${String(res.status)}`;
18
19
  return toErrorEvent(new TheoremError(kindOfHttpStatus(res.status), detail ? `${head}: ${detail}` : head));
@@ -63,7 +64,6 @@ export function wireMessageContent(parts) {
63
64
  if (part.type === 'audio') {
64
65
  return wireAudioPart(part);
65
66
  }
66
- // video and document ride as a `file` part.
67
67
  return {
68
68
  type: 'file',
69
69
  file: {
@@ -99,6 +99,8 @@ function wireHistoryMessage(msg) {
99
99
  }
100
100
  return wired;
101
101
  }
102
+ // why: A PDF inside a `role: 'tool'` message was accepted and never read, and was read from the user message after it; a photo inside one was read (live, 13/10/2026, google/gemini-3.5-flash-lite).
103
+ const TOOL_MESSAGE_PART_TYPES = new Set(['text', 'image']);
102
104
  /** `includeSystem: false` when the caller passes system text separately (AI SDK `instructions`). */
103
105
  function buildChatMessages(req, options) {
104
106
  const includeSystem = options?.includeSystem !== false;
@@ -106,10 +108,8 @@ function buildChatMessages(req, options) {
106
108
  if (includeSystem && req.system) {
107
109
  messages.push({ role: 'system', content: req.system });
108
110
  }
109
- if (req.history && req.history.length > 0) {
110
- for (const h of req.history) {
111
- messages.push(wireHistoryMessage(h));
112
- }
111
+ for (const h of withCarriedToolFiles(req.history ?? [], TOOL_MESSAGE_PART_TYPES)) {
112
+ messages.push(wireHistoryMessage(h));
113
113
  }
114
114
  if (req.input.length > 0) {
115
115
  messages.push({
@@ -1,9 +1,9 @@
1
- import type { ImageResponseFormat, InteractionMediaPart, InteractionMediaRefPart, InteractionPart, ProviderCompleteRequest } from '../../../kernel/types.js';
1
+ import type { ImageResponseFormat, InteractionMediaPart, InteractionMediaRefPart, InteractionPart, ModelRequest } from '../../../kernel/types.js';
2
2
  export declare function extractPromptText(input: InteractionPart[]): string;
3
3
  export declare function outputFormatFromMime(mimeType: string): string;
4
4
  export declare function wireInputReference(part: InteractionMediaPart | InteractionMediaRefPart): Record<string, unknown>;
5
5
  /** Non-image media is refused, not dropped: a dropped file would leave the user believing the model saw it. */
6
6
  export declare function wireInputReferences(input: InteractionPart[]): Record<string, unknown>[];
7
7
  export declare function attachImagePins(payload: Record<string, unknown>, image: ImageResponseFormat): void;
8
- export declare function buildImagesPayload(req: ProviderCompleteRequest): Record<string, unknown>;
8
+ export declare function buildImagesPayload(req: ModelRequest): Record<string, unknown>;
9
9
  export declare function imageToolParameters(image: ImageResponseFormat): Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ import { type JsonObject } from '../../../kernel/json.js';
2
+ export declare function collectReasoning(row: Record<string, unknown>, details: Map<string, JsonObject>): string;