@theoremjs/agents 0.3.0 → 0.3.2

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 (570) hide show
  1. package/README.md +277 -995
  2. package/esm/mod.d.ts +34 -20
  3. package/esm/mod.js +19 -12
  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 +25 -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 +881 -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 +30 -22
  123. package/esm/src/guardrails/mod.js +19 -14
  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 +4 -1
  135. package/esm/src/guardrails/quota.js +7 -2
  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 +5 -2
  148. package/esm/src/guardrails/theorem-error.js +6 -3
  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 +8 -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 +174 -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 +329 -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 +130 -88
  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 +102 -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/api-error.d.ts +2 -0
  435. package/esm/src/providers/google/api-error.js +26 -18
  436. package/esm/src/providers/google/builtins.d.ts +14 -0
  437. package/esm/src/providers/google/builtins.js +57 -0
  438. package/esm/src/providers/google/grounding.d.ts +4 -4
  439. package/esm/src/providers/google/interactions/framing.d.ts +20 -8
  440. package/esm/src/providers/google/interactions/framing.js +85 -44
  441. package/esm/src/providers/google/interactions/steps.d.ts +5 -5
  442. package/esm/src/providers/google/interactions/steps.js +4 -4
  443. package/esm/src/providers/google/interactions/stream.d.ts +10 -11
  444. package/esm/src/providers/google/interactions/stream.js +33 -100
  445. package/esm/src/providers/google/live/framing.d.ts +15 -5
  446. package/esm/src/providers/google/live/framing.js +25 -25
  447. package/esm/src/providers/google/live/stream.d.ts +6 -44
  448. package/esm/src/providers/google/live/stream.js +4 -210
  449. package/esm/src/providers/google/urls.d.ts +1 -3
  450. package/esm/src/providers/google/urls.js +1 -3
  451. package/esm/src/providers/google/usage.js +2 -2
  452. package/esm/src/providers/live.d.ts +6 -0
  453. package/esm/src/providers/live.js +6 -0
  454. package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
  455. package/esm/src/providers/local/embedding-protocol.js +60 -0
  456. package/esm/src/providers/local/provider.d.ts +7 -0
  457. package/esm/src/providers/local/provider.js +28 -0
  458. package/esm/src/providers/mod.d.ts +28 -7
  459. package/esm/src/providers/mod.js +19 -3
  460. package/esm/src/providers/open-ai/protocol.d.ts +3 -0
  461. package/esm/src/providers/open-ai/protocol.js +189 -0
  462. package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
  463. package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
  464. package/esm/src/providers/openrouter/image.d.ts +0 -9
  465. package/esm/src/providers/openrouter/image.js +0 -153
  466. package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
  467. package/esm/src/providers/openrouter/images-protocol.js +82 -0
  468. package/esm/src/providers/openrouter/openai/compat.d.ts +2 -2
  469. package/esm/src/providers/openrouter/openai/compat.js +6 -6
  470. package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
  471. package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
  472. package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
  473. package/esm/src/providers/openrouter/protocol.d.ts +8 -0
  474. package/esm/src/providers/openrouter/protocol.js +171 -0
  475. package/esm/src/providers/openrouter/provider.d.ts +10 -0
  476. package/esm/src/providers/openrouter/provider.js +50 -0
  477. package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
  478. package/esm/src/providers/shared/carried-tool-files.js +43 -0
  479. package/esm/src/providers/shared/pcm.js +2 -2
  480. package/esm/src/providers/shared/protocol-events.d.ts +8 -0
  481. package/esm/src/providers/shared/protocol-events.js +20 -0
  482. package/esm/src/providers/shared/response-identity.d.ts +2 -2
  483. package/esm/src/providers/shared/retry.d.ts +18 -0
  484. package/esm/src/providers/shared/retry.js +89 -0
  485. package/esm/src/providers/shared/sse.d.ts +0 -4
  486. package/esm/src/providers/shared/sse.js +50 -36
  487. package/esm/src/providers/shared/tool-args.d.ts +6 -7
  488. package/esm/src/providers/shared/tool-args.js +10 -6
  489. package/esm/src/providers/shared/tool-draft.d.ts +16 -0
  490. package/esm/src/providers/shared/tool-draft.js +14 -0
  491. package/esm/src/providers/shared/upstream-tap.d.ts +2 -2
  492. package/esm/src/providers/shared/upstream-tape.js +1 -1
  493. package/esm/src/providers/system-one/protocol.d.ts +8 -0
  494. package/esm/src/providers/system-one/protocol.js +93 -0
  495. package/esm/src/providers/types.d.ts +48 -16
  496. package/esm/src/providers/types.js +2 -1
  497. package/esm/src/providers/typesafe/provider.d.ts +7 -0
  498. package/esm/src/providers/typesafe/provider.js +24 -0
  499. package/esm/src/surface/formats.d.ts +19 -1
  500. package/esm/src/surface/formats.js +68 -29
  501. package/esm/src/surface/mod.d.ts +4 -2
  502. package/esm/src/surface/mod.js +4 -2
  503. package/esm/src/surface/runtime.d.ts +4 -0
  504. package/esm/src/surface/runtime.js +2 -0
  505. package/esm/src/surface/tools.d.ts +2 -8
  506. package/esm/src/surface/tools.js +4 -22
  507. package/esm/src/surface/types.d.ts +6 -0
  508. package/package.json +5 -13
  509. package/esm/src/cli/commands/egress-compile.d.ts +0 -17
  510. package/esm/src/cli/commands/egress-compile.js +0 -25
  511. package/esm/src/guardrails/egress-policy.d.ts +0 -27
  512. package/esm/src/guardrails/egress-policy.js +0 -76
  513. package/esm/src/guardrails/egress-rules.d.ts +0 -54
  514. package/esm/src/guardrails/egress-rules.js +0 -49
  515. package/esm/src/guardrails/lexicon.d.ts +0 -30
  516. package/esm/src/guardrails/lexicon.js +0 -478
  517. package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
  518. package/esm/src/kernel/engine/media-probe/audio.js +0 -342
  519. package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
  520. package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
  521. package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
  522. package/esm/src/kernel/engine/media-probe/image.js +0 -171
  523. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
  524. package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
  525. package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
  526. package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
  527. package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
  528. package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
  529. package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
  530. package/esm/src/kernel/engine/media-probe/opus.js +0 -23
  531. package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
  532. package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
  533. package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
  534. package/esm/src/kernel/engine/media-probe/video.js +0 -49
  535. package/esm/src/presets/typesafe.d.ts +0 -2
  536. package/esm/src/presets/typesafe.js +0 -2
  537. package/esm/src/providers/create-provider.d.ts +0 -21
  538. package/esm/src/providers/create-provider.js +0 -90
  539. package/esm/src/providers/decision/usage.d.ts +0 -3
  540. package/esm/src/providers/decision/usage.js +0 -25
  541. package/esm/src/providers/google/interactions/mod.d.ts +0 -2
  542. package/esm/src/providers/google/interactions/mod.js +0 -2
  543. package/esm/src/providers/google/keys.d.ts +0 -20
  544. package/esm/src/providers/google/keys.js +0 -87
  545. package/esm/src/providers/google/live/mod.d.ts +0 -7
  546. package/esm/src/providers/google/live/mod.js +0 -7
  547. package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
  548. package/esm/src/providers/google/live/openapi-schema.js +0 -42
  549. package/esm/src/providers/google/live/session.d.ts +0 -14
  550. package/esm/src/providers/google/live/session.js +0 -150
  551. package/esm/src/providers/local/local.d.ts +0 -12
  552. package/esm/src/providers/local/local.js +0 -186
  553. package/esm/src/providers/local/mod.d.ts +0 -8
  554. package/esm/src/providers/local/mod.js +0 -8
  555. package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
  556. package/esm/src/providers/openrouter/cache-control.js +0 -4
  557. package/esm/src/providers/openrouter/chat.d.ts +0 -64
  558. package/esm/src/providers/openrouter/chat.js +0 -490
  559. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
  560. package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
  561. package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
  562. package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
  563. package/esm/src/providers/openrouter/speech.d.ts +0 -18
  564. package/esm/src/providers/openrouter/speech.js +0 -109
  565. package/esm/src/providers/probe.d.ts +0 -5
  566. package/esm/src/providers/probe.js +0 -15
  567. package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
  568. package/esm/src/providers/shared/builtin-wire.js +0 -9
  569. package/esm/src/providers/shared/vault.d.ts +0 -13
  570. package/esm/src/providers/shared/vault.js +0 -41
@@ -0,0 +1,125 @@
1
+ import { z } from 'zod';
2
+ import { defineProtocol, modelOptions } from '../../kernel/protocols/mod.js';
3
+ function task(value, title, description) {
4
+ return z.literal(value).meta({ title, description });
5
+ }
6
+ const options = z.strictObject({
7
+ // why: Labels and descriptions are Google's own task-type table (ai.google.dev/gemini-api/docs/embeddings), so a studio can show them.
8
+ taskType: z
9
+ .union([
10
+ task('RETRIEVAL_QUERY', 'Retrieval query', 'Embeddings optimized for general search queries. Pair with Retrieval document for the documents searched.'),
11
+ task('RETRIEVAL_DOCUMENT', 'Retrieval document', 'Embeddings optimized for document search, such as indexing articles, books or web pages.'),
12
+ task('SEMANTIC_SIMILARITY', 'Semantic similarity', 'Embeddings optimized to assess text similarity, such as for recommendations or duplicate detection.'),
13
+ task('CLASSIFICATION', 'Classification', 'Embeddings optimized to classify texts according to preset labels, such as sentiment or spam.'),
14
+ task('CLUSTERING', 'Clustering', 'Embeddings optimized to cluster texts based on their similarities.'),
15
+ task('QUESTION_ANSWERING', 'Question answering', 'Embeddings for questions, optimized for finding documents that answer them. Pair with Retrieval document.'),
16
+ task('FACT_VERIFICATION', 'Fact verification', 'Embeddings for statements to verify, optimized for retrieving evidence that supports or refutes them. Pair with Retrieval document.'),
17
+ task('CODE_RETRIEVAL_QUERY', 'Code retrieval query', 'Embeddings optimized for finding code blocks from natural language queries. Pair with Retrieval document for the code.'),
18
+ ])
19
+ .optional()
20
+ .describe("What the vectors will be used for, so Google tunes them to it. Only gemini-embedding-001 takes it; later models read the request's task from the text. Absent: no tuning."),
21
+ outputDimensionality: z
22
+ .union([z.literal(768), z.literal(1536), z.literal(3072)])
23
+ .optional()
24
+ .describe('How many numbers each vector holds. A shorter vector is cheaper to store and compare and a little less precise. Absent: the 3072 the model returns.'),
25
+ });
26
+ /** Models that take the task as `taskType`. Later ones (Gemini Embedding 2 on) refuse the field and read the task from the text. */
27
+ const TASK_FIELD_MODELS = /^(gemini-embedding-001|text-embedding-|embedding-)/;
28
+ // why: ai.google.dev/gemini-api/docs/embeddings gives 6 images and 1 PDF per input, and duration caps (not counts) for audio and video; a batch of 101 inputs is refused (checked 2026-10-19).
29
+ const MULTIMODAL = {
30
+ maxInputs: 100,
31
+ media: [
32
+ { accept: ['image/png', 'image/jpeg'], maxPerInput: 6 },
33
+ { accept: ['application/pdf'], maxPerInput: 1 },
34
+ { accept: ['audio/mpeg', 'audio/mp3', 'audio/wav', 'audio/x-wav'] },
35
+ { accept: ['video/mp4', 'video/quicktime'] },
36
+ ],
37
+ };
38
+ const TEXT_ONLY = { maxInputs: 100, media: [] };
39
+ const TASK_TYPES = {
40
+ query: 'RETRIEVAL_QUERY',
41
+ document: 'RETRIEVAL_DOCUMENT',
42
+ };
43
+ // why: The formats Google gives for Gemini Embedding 2 search (ai.google.dev/gemini-api/docs/embeddings); it advises leaving input with media unprefixed.
44
+ function withTask(text, task) {
45
+ return task === 'query' ? `task: search result | query: ${text}` : `title: none | text: ${text}`;
46
+ }
47
+ function parts(input, task) {
48
+ const list = typeof input === 'string' ? [{ type: 'text', text: input }] : input.parts;
49
+ const textOnly = list.every((part) => part.type === 'text');
50
+ return list.map((part, at) => {
51
+ if (part.type === 'text')
52
+ return { text: task && textOnly && at === 0 ? withTask(part.text, task) : part.text };
53
+ if (part.type === 'media') {
54
+ return { inlineData: { mimeType: part.mimeType, data: part.data } };
55
+ }
56
+ return { fileData: { mimeType: part.mimeType, fileUri: part.uri } };
57
+ });
58
+ }
59
+ function values(row) {
60
+ const embedding = row.embedding;
61
+ const values = embedding && typeof embedding === 'object'
62
+ ? embedding.values
63
+ : undefined;
64
+ return Array.isArray(values)
65
+ ? values.filter((value) => typeof value === 'number')
66
+ : [];
67
+ }
68
+ function requestBody(input, parsed, shape) {
69
+ const body = {
70
+ content: { parts: parts(input, shape.taskField ? undefined : shape.task) },
71
+ };
72
+ const taskType = shape.taskField && shape.task ? TASK_TYPES[shape.task] : parsed.taskType;
73
+ if (taskType)
74
+ body.taskType = taskType;
75
+ if (parsed.outputDimensionality)
76
+ body.outputDimensionality = parsed.outputDimensionality;
77
+ return body;
78
+ }
79
+ export const geminiEmbedding = defineProtocol({
80
+ id: 'geminiEmbedding',
81
+ name: 'Gemini Embeddings',
82
+ description: "Google's embedding API for text and supported media.",
83
+ endpoints: { embedding: '/models/{apiId}:embedContent' },
84
+ options,
85
+ embeddingLimits: (apiId) => (TASK_FIELD_MODELS.test(apiId) ? TEXT_ONLY : MULTIMODAL),
86
+ // why: Gemini Embedding 2 reads the task from the text and refuses the field; the request's `task` says it.
87
+ refusedOptions: (apiId) => (TASK_FIELD_MODELS.test(apiId) ? [] : ['taskType']),
88
+ create(context) {
89
+ return {
90
+ async embed(request) {
91
+ const parsed = modelOptions(geminiEmbedding, context.apiId, request.options);
92
+ const taskField = TASK_FIELD_MODELS.test(context.apiId);
93
+ const shape = { taskField, ...(request.task ? { task: request.task } : {}) };
94
+ const inputs = Array.isArray(request.input) ? request.input : [request.input];
95
+ const body = inputs.length === 1
96
+ ? requestBody(inputs[0], parsed, shape)
97
+ : {
98
+ requests: inputs.map((input) => ({
99
+ model: `models/${context.apiId}`,
100
+ ...requestBody(input, parsed, shape),
101
+ })),
102
+ };
103
+ const path = inputs.length === 1
104
+ ? `/models/${encodeURIComponent(context.apiId)}:embedContent`
105
+ : `/models/${encodeURIComponent(context.apiId)}:batchEmbedContents`;
106
+ let row;
107
+ for await (const current of context.send(body, { stream: false, path }))
108
+ row = current;
109
+ const raw = Array.isArray(row?.embeddings)
110
+ ? row.embeddings
111
+ : row?.embedding
112
+ ? [row.embedding]
113
+ : [];
114
+ return {
115
+ model: context.apiId,
116
+ embeddings: raw.map((item, index) => ({
117
+ index,
118
+ values: item && typeof item === 'object' ? values({ embedding: item }) : [],
119
+ dimensions: item && typeof item === 'object' ? values({ embedding: item }).length : 0,
120
+ })),
121
+ };
122
+ },
123
+ };
124
+ },
125
+ });
@@ -0,0 +1,8 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ /** What a `geminiInteractions` binding sets in `options`. */
3
+ export interface GeminiInteractionsOptions {
4
+ store?: boolean;
5
+ persistViaInteractionId?: boolean;
6
+ }
7
+ /** Gemini's Interactions API: text, images, and speech, all at `/interactions`. */
8
+ export declare const geminiInteractions: Protocol<GeminiInteractionsOptions>;
@@ -0,0 +1,102 @@
1
+ import { z } from 'zod';
2
+ import { asRecord } from '../../kernel/engine/record.js';
3
+ import { jsonObjectSchema } from '../../kernel/json.js';
4
+ import { defineProtocol, } from '../../kernel/protocols/mod.js';
5
+ import { readGeminiApiError, statedOrStatusError } from '../google/api-error.js';
6
+ import { googleBuiltins } from '../google/builtins.js';
7
+ import { thoughtSignature, toInteractionsBody, } from '../google/interactions/framing.js';
8
+ import { finalizeStructured, foldBody, foldPayload, missingMediaError, newStreamFold, openStepEvents, } from '../google/interactions/stream.js';
9
+ import { asProtocolEvent } from '../shared/protocol-events.js';
10
+ const state = z.strictObject({ interactionId: z.string().min(1) });
11
+ const options = z
12
+ .strictObject({
13
+ store: z
14
+ .boolean()
15
+ .optional()
16
+ .describe('Whether Google keeps the interaction. Off, nothing is stored server-side.'), // labels-exempt: builder field description, read by the studio and docs
17
+ persistViaInteractionId: z.boolean().optional().describe('Continue from the stored interaction instead of sending the conversation again. Needs store.'),
18
+ })
19
+ .refine((value) => !value.persistViaInteractionId || value.store !== false, 'persistViaInteractionId needs store');
20
+ function wireRequest(context, request) {
21
+ const history = request.history ?? [];
22
+ const previous = context.options.persistViaInteractionId
23
+ ? request.state?.interactionId
24
+ : undefined;
25
+ const builtins = googleBuiltins(request.builtins);
26
+ const wire = {
27
+ ...request,
28
+ apiId: context.apiId,
29
+ history,
30
+ builtins,
31
+ state: undefined,
32
+ tapUpstream: undefined,
33
+ store: context.options.store,
34
+ previousInteractionId: previous,
35
+ continuation: previous
36
+ ? [
37
+ ...history.slice(request.stateHistoryLength ?? 0),
38
+ ...request.input.map((part) => ({ role: 'user', parts: [part] })),
39
+ ]
40
+ : undefined,
41
+ };
42
+ const body = jsonObjectSchema.parse(JSON.parse(JSON.stringify(toInteractionsBody(wire))));
43
+ return { wire, body, wroteTools: builtins.map((builtin) => builtin.id) };
44
+ }
45
+ /** The shared reader's events as protocol events; the `done` waits for the end, with the state to keep. */
46
+ function asProtocolEvents(events, reply, persist) {
47
+ return events.flatMap((event) => {
48
+ if (event.type !== 'done') {
49
+ const converted = asProtocolEvent(event);
50
+ return converted ? [converted] : [];
51
+ }
52
+ const { interactionId, ...done } = event;
53
+ reply.done = {
54
+ ...done,
55
+ ...(persist && interactionId ? { state: { interactionId } } : {}),
56
+ };
57
+ return [];
58
+ });
59
+ }
60
+ /** Gemini's Interactions API: text, images, and speech, all at `/interactions`. */
61
+ export const geminiInteractions = defineProtocol({
62
+ id: 'geminiInteractions',
63
+ name: 'Gemini Interactions',
64
+ description: "Google's Interactions API for Gemini: text, images and speech at one endpoint.", // labels-exempt: builder field description, read by the studio and docs
65
+ endpoints: { text: '/interactions', image: '/interactions', speech: '/interactions' },
66
+ options,
67
+ continuation: { version: 1, schema: state, keyOptions: ['store', 'persistViaInteractionId'] },
68
+ reasoning: thoughtSignature,
69
+ error(failure) {
70
+ const record = asRecord(failure.body);
71
+ return statedOrStatusError(record ? readGeminiApiError(record) : null, failure.status, `Gemini HTTP ${failure.status}`);
72
+ },
73
+ create(context) {
74
+ return {
75
+ async *complete(request) {
76
+ const { wire, body, wroteTools } = wireRequest(context, request);
77
+ const stream = request.stream !== false;
78
+ const persist = Boolean(context.options.persistViaInteractionId);
79
+ const reply = { fold: newStreamFold() };
80
+ const init = { stream, wroteTools, ...(stream ? { path: '/interactions?alt=sse' } : {}) };
81
+ for await (const row of context.send(body, init)) {
82
+ // why: an error row before any output is thrown, so the kernel can fall back to the other key.
83
+ const failed = readGeminiApiError(row);
84
+ if (failed)
85
+ throw failed;
86
+ const events = stream ? foldPayload(row, reply.fold) : foldBody(row, reply.fold);
87
+ yield* asProtocolEvents(events, reply, persist);
88
+ if (events.some((event) => event.type === 'error')) {
89
+ yield* asProtocolEvents(openStepEvents(reply.fold), reply, persist);
90
+ return;
91
+ }
92
+ }
93
+ yield* asProtocolEvents(openStepEvents(reply.fold), reply, persist);
94
+ yield* asProtocolEvents([...finalizeStructured(wire, reply.fold)], reply, persist);
95
+ const missing = missingMediaError(wire, reply.fold);
96
+ if (missing)
97
+ yield* asProtocolEvents([missing], reply, persist);
98
+ yield reply.done ?? { type: 'done', stop: { kind: 'stream_incomplete' } };
99
+ },
100
+ };
101
+ },
102
+ });
@@ -0,0 +1,3 @@
1
+ import { type Protocol } from '../../kernel/protocols/mod.js';
2
+ /** Gemini Live: a spoken session over one WebSocket. */
3
+ export declare const geminiLive: Protocol<Record<string, never>>;
@@ -0,0 +1,191 @@
1
+ import { z } from 'zod';
2
+ import { TheoremError } from '../../guardrails/error.js';
3
+ import { jsonObjectSchema } from '../../kernel/json.js';
4
+ import { defineProtocol, } from '../../kernel/protocols/mod.js';
5
+ import { readGeminiApiError } from '../google/api-error.js';
6
+ import { googleBuiltins } from '../google/builtins.js';
7
+ import { buildGeminiLiveClientContent, buildGeminiLiveContext, buildGeminiLiveRealtimeInput, buildGeminiLiveSetupMessage, buildGeminiLiveToolResponse, foldGeminiLiveServerMessage, liveFrameInput, newLiveFold, } from '../google/live/framing.js';
8
+ import { closeError, goAwayIn, turnPhaseFromMessage } from '../google/live/stream.js';
9
+ import { asProtocolEvent } from '../shared/protocol-events.js';
10
+ const state = z.strictObject({ liveHandle: z.string().min(1) });
11
+ const NORMAL_CLOSE = 1000;
12
+ /** What a frame that is not the model's says: a close, a socket error, or bytes that are not JSON. */
13
+ function socketTrouble(frame, during) {
14
+ if (frame.eventType === 'ws_error')
15
+ return new TheoremError('network', `Gemini Live WebSocket error during ${during}`); // labels-exempt: developer diagnostic
16
+ if (frame.eventType === 'ws_unparsed')
17
+ return new TheoremError('bad_response', 'malformed Gemini Live message'); // labels-exempt: developer diagnostic
18
+ return readGeminiApiError(frame) ?? undefined;
19
+ }
20
+ /** Waits for `setupComplete`; a refusal here comes before any event, so the kernel can try the other key. */
21
+ async function setupComplete(frames, context) {
22
+ let timer;
23
+ const late = new Promise((_, reject) => {
24
+ timer = setTimeout(() => reject(new TheoremError('timeout', `Gemini Live setup timed out after ${context.limits.connectTimeoutMs}ms`)), context.limits.connectTimeoutMs);
25
+ });
26
+ try {
27
+ for (;;) {
28
+ const next = await Promise.race([frames.next(), late]);
29
+ if (next.done)
30
+ throw closeError(1006, '', 'setup');
31
+ const frame = next.value;
32
+ if (frame.eventType === 'ws_close')
33
+ throw closeError(Number(frame.code), String(frame.reason ?? ''), 'setup');
34
+ const trouble = socketTrouble(frame, 'setup');
35
+ if (trouble)
36
+ throw trouble;
37
+ if (frame.setupComplete)
38
+ return;
39
+ }
40
+ }
41
+ finally {
42
+ clearTimeout(timer);
43
+ }
44
+ }
45
+ function wireRequest(context, request) {
46
+ const handle = request.state?.liveHandle;
47
+ const history = request.history ?? [];
48
+ const builtins = googleBuiltins(request.builtins);
49
+ const wire = {
50
+ ...request,
51
+ apiId: context.apiId,
52
+ builtins,
53
+ state: undefined,
54
+ tapUpstream: undefined,
55
+ sessionResumptionHandle: handle,
56
+ // why: a resumed session already holds what came before its handle.
57
+ history: handle ? history.slice(request.stateHistoryLength ?? 0) : history,
58
+ live: {
59
+ ...request.live,
60
+ transcription: { ...request.live?.transcription, input: true, output: true },
61
+ },
62
+ };
63
+ const setup = jsonObjectSchema.parse(JSON.parse(JSON.stringify(buildGeminiLiveSetupMessage(wire))));
64
+ return { wire, setup, wroteTools: builtins.map((builtin) => builtin.id) };
65
+ }
66
+ /** One server message's events, then the stop its turn phase calls for. */
67
+ function* batch(events, phase, handle) {
68
+ // why: usage first, so a turn's tokens are counted before its stop.
69
+ const ordered = [
70
+ ...events.filter((event) => event.type === 'tokens'),
71
+ ...events.filter((event) => event.type !== 'tokens'),
72
+ ];
73
+ for (const event of ordered) {
74
+ const converted = asProtocolEvent(event);
75
+ if (converted)
76
+ yield converted;
77
+ }
78
+ if (phase === 'abort')
79
+ return;
80
+ const saved = handle ? { state: { liveHandle: handle } } : {};
81
+ if (events.some((event) => event.type === 'tool' && event.tool.phase === undefined))
82
+ yield { type: 'done', stop: { kind: 'tool' }, ...saved };
83
+ if (phase === 'complete')
84
+ yield { type: 'done', stop: { kind: 'completed' }, ...saved };
85
+ }
86
+ function session(socket, frames, context, resumedFrom) {
87
+ const send = (frame) => sendFrame(socket, frame);
88
+ const fold = newLiveFold();
89
+ let handle = resumedFrom;
90
+ let goAway;
91
+ let closed;
92
+ return {
93
+ closeInfo: () => closed,
94
+ async *events() {
95
+ for (;;) {
96
+ const next = await frames.next();
97
+ if (next.done)
98
+ return;
99
+ const frame = next.value;
100
+ if (frame.eventType === 'ws_close') {
101
+ context.signal?.throwIfAborted();
102
+ const code = Number(frame.code);
103
+ const reason = String(frame.reason ?? '');
104
+ closed = {
105
+ code,
106
+ reason,
107
+ ...(code === NORMAL_CLOSE ? {} : { error: closeError(code, reason, 'session') }),
108
+ ...(goAway
109
+ ? {
110
+ warning: {
111
+ ...(goAway.timeLeftMs === undefined ? {} : { timeLeftMs: goAway.timeLeftMs }),
112
+ closedAfterMs: Math.round(performance.now() - goAway.atMs),
113
+ },
114
+ }
115
+ : {}),
116
+ };
117
+ return;
118
+ }
119
+ const trouble = socketTrouble(frame, 'session');
120
+ if (trouble)
121
+ throw trouble;
122
+ if (frame.setupComplete)
123
+ continue;
124
+ const events = foldGeminiLiveServerMessage(frame, fold);
125
+ const warning = goAwayIn(events);
126
+ if (warning)
127
+ goAway = { ...warning, atMs: performance.now() };
128
+ for (const event of events)
129
+ if (event.type === 'evidence' && event.sessionResumptionHandle)
130
+ handle = event.sessionResumptionHandle;
131
+ yield* batch(events, turnPhaseFromMessage(frame, events), handle);
132
+ }
133
+ },
134
+ sendText: (text) => settled(() => send(buildGeminiLiveRealtimeInput({ type: 'text', text }))),
135
+ sendAudio: (media) => settled(() => send(buildGeminiLiveRealtimeInput({ type: 'audio', ...media }))),
136
+ sendVideo: (media) => settled(() => send(buildGeminiLiveRealtimeInput({ type: 'video', ...media }))),
137
+ sendContext: (value) => settled(() => send(buildGeminiLiveContext(typeof value.server === 'string' ? value.server : JSON.stringify(value)))),
138
+ sendToolResult: (result) => settled(() => send(buildGeminiLiveToolResponse(result.callId, result.name, result.text, result.parts))),
139
+ close: (reason) => settled(() => socket.close(NORMAL_CLOSE, reason ?? 'session-closed')),
140
+ };
141
+ }
142
+ /** Gemini Live: a spoken session over one WebSocket. */
143
+ export const geminiLive = defineProtocol({
144
+ id: 'geminiLive',
145
+ name: 'Gemini Live',
146
+ description: "Google's Live API for Gemini: a spoken session over one WebSocket.", // labels-exempt: builder field description, read by the studio and docs
147
+ endpoints: { live: '/google.ai.generativelanguage.v1beta.GenerativeService.BidiGenerateContent' },
148
+ options: z.strictObject({}),
149
+ continuation: { version: 1, schema: state },
150
+ create(context) {
151
+ return {
152
+ async openSession(request) {
153
+ const { wire, setup, wroteTools } = wireRequest(context, request);
154
+ const socket = await context.connect(setup, { wroteTools });
155
+ const frames = socket.frames()[Symbol.asyncIterator]();
156
+ const abort = () => socket.close(NORMAL_CLOSE, 'aborted');
157
+ context.signal?.addEventListener('abort', abort, { once: true });
158
+ try {
159
+ context.signal?.throwIfAborted();
160
+ await setupComplete(frames, context);
161
+ }
162
+ catch (error) {
163
+ context.signal?.removeEventListener('abort', abort);
164
+ socket.close(NORMAL_CLOSE, 'setup-failed');
165
+ throw error;
166
+ }
167
+ const history = wire.history?.length
168
+ ? buildGeminiLiveClientContent(wire.history)
169
+ : undefined;
170
+ if (history)
171
+ sendFrame(socket, history);
172
+ for (const part of wire.input)
173
+ sendFrame(socket, buildGeminiLiveRealtimeInput(part));
174
+ return session(socket, frames, context, wire.sessionResumptionHandle);
175
+ },
176
+ };
177
+ },
178
+ });
179
+ /** A send that throws becomes a rejected promise, as the session's callers expect. */
180
+ function settled(act) {
181
+ try {
182
+ act();
183
+ return Promise.resolve();
184
+ }
185
+ catch (error) {
186
+ return Promise.reject(error);
187
+ }
188
+ }
189
+ function sendFrame(socket, frame) {
190
+ socket.send(frame, liveFrameInput(frame));
191
+ }
@@ -0,0 +1,3 @@
1
+ import type { PriceTable } from '../../kernel/protocols/prices.js';
2
+ /** What the Gemini API charges per model. */
3
+ export declare const geminiPrices: PriceTable;
@@ -0,0 +1,63 @@
1
+ /* probed 2026-10-15: https://ai.google.dev/gemini-api/docs/pricing, paid tier, US dollars per
2
+ * million tokens. The Gemini API reports no cost. gemini-3.8-flash rises to $1.50 input and $7.50
3
+ * output on 2027-01-01. Cached input is one rate here, so gemini-3.1-flash-lite's cached audio
4
+ * ($0.05) is billed at its cached text rate. Gemma, gemini-3.7-flash and gemini-3.5-flash list no paid price;
5
+ * gemini-2.5-flash-image's output is all image, $30 per million tokens.
6
+ */
7
+ const live = {
8
+ input: 0.75,
9
+ output: 4.5,
10
+ byModality: { input: { audio: 3, image: 1, video: 1 }, output: { audio: 12 } },
11
+ };
12
+ /** What the Gemini API charges per model. */
13
+ export const geminiPrices = {
14
+ checked: '2026-10-15',
15
+ models: {
16
+ 'gemini-3.8-flash': { input: 0.75, output: 3.75, cachedInput: 0.075 },
17
+ 'gemini-3.6-flash': { input: 0.75, output: 3.75, cachedInput: 0.075 },
18
+ 'gemini-3.8-live': live,
19
+ 'gemini-3.8-live-extended-thinking': live,
20
+ 'gemini-3.1-flash-live-preview': live,
21
+ 'gemini-3.5-flash-lite': { input: 0.3, output: 2.5, cachedInput: 0.03 },
22
+ 'gemini-3.1-flash-lite': {
23
+ input: 0.25,
24
+ output: 1.5,
25
+ cachedInput: 0.025,
26
+ byModality: { input: { audio: 0.5 } },
27
+ },
28
+ 'gemini-3.1-pro-preview': {
29
+ input: 2,
30
+ output: 12,
31
+ cachedInput: 0.2,
32
+ longContext: { above: 200_000, input: 4, output: 18, cachedInput: 0.4 },
33
+ },
34
+ 'gemini-3.1-flash-lite-image': {
35
+ input: 0.25,
36
+ output: 1.5,
37
+ byModality: { output: { image: 30 } },
38
+ },
39
+ 'gemini-3.8-flash-tts': { input: 0.5, output: 9 },
40
+ 'gemini-3.8-flash-lite-tts': { input: 0.5, output: 6 },
41
+ 'gemini-3.1-flash-tts-preview': { input: 1, output: 20 },
42
+ 'gemini-3-flash-preview': {
43
+ input: 0.5,
44
+ output: 3,
45
+ cachedInput: 0.05,
46
+ byModality: { input: { audio: 1 } },
47
+ },
48
+ 'gemini-2.5-flash': {
49
+ input: 0.3,
50
+ output: 2.5,
51
+ cachedInput: 0.03,
52
+ byModality: { input: { audio: 1 } },
53
+ },
54
+ 'gemini-2.5-flash-lite': {
55
+ input: 0.1,
56
+ output: 0.4,
57
+ cachedInput: 0.01,
58
+ byModality: { input: { audio: 0.3 } },
59
+ },
60
+ 'gemini-2.5-flash-preview-tts': { input: 0.5, output: 10 },
61
+ 'gemini-2.5-flash-image': { input: 0.3, output: 30 },
62
+ },
63
+ };
@@ -0,0 +1,7 @@
1
+ import { type Provider } from '../../kernel/protocols/provider.js';
2
+ /** What registering `geminiProvider` takes as `connection`. */
3
+ export interface GeminiConnection {
4
+ host?: string;
5
+ }
6
+ /** Gemini: Google's models with an API key. Text, images, and speech, and Live voice. */
7
+ export declare const geminiProvider: Provider<GeminiConnection, string>;
@@ -0,0 +1,39 @@
1
+ import { z } from 'zod';
2
+ import { labelText } from '../../guardrails/labels.js';
3
+ import { defineProvider, endpointUrlSchema, header, query, } from '../../kernel/protocols/provider.js';
4
+ import { geminiEmbedding } from './embedding-protocol.js';
5
+ import { geminiInteractions } from './interactions-protocol.js';
6
+ import { geminiLive } from './live-protocol.js';
7
+ import { geminiPrices } from './prices.js';
8
+ /** Gemini: Google's models with an API key. Text, images, and speech, and Live voice. */
9
+ export const geminiProvider = defineProvider({
10
+ id: 'gemini',
11
+ name: 'Gemini',
12
+ description: "Google's models with an API key, from Google AI Studio.", // labels-exempt: builder field description, read by the studio and docs
13
+ traceName: 'gcp.gemini',
14
+ connection: z
15
+ .strictObject({
16
+ host: endpointUrlSchema
17
+ .refine((value) => {
18
+ const url = new URL(value);
19
+ return url.pathname === '/' && !url.search && !url.hash;
20
+ }, labelText('protocol.endpoint_host'))
21
+ .optional()
22
+ .describe('The API host, by default https://generativelanguage.googleapis.com. Live connects to the same host over wss.'),
23
+ })
24
+ .default({}),
25
+ key: z.string().trim().min(1),
26
+ authorize: header('x-goog-api-key'),
27
+ prices: geminiPrices,
28
+ serves(at) {
29
+ const host = new URL(at.host ?? 'https://generativelanguage.googleapis.com');
30
+ const origin = host.origin;
31
+ const liveOrigin = `${host.protocol === 'http:' ? 'ws:' : 'wss:'}//${host.host}`;
32
+ return [
33
+ { protocol: geminiInteractions, baseUrl: `${origin}/v1beta` },
34
+ { protocol: geminiEmbedding, baseUrl: `${origin}/v1beta` },
35
+ // probed 2026-09-23: Live's WebSocket takes the key only in the URL's query.
36
+ { protocol: geminiLive, baseUrl: `${liveOrigin}/ws`, authorize: query('key') },
37
+ ];
38
+ },
39
+ });
@@ -6,3 +6,5 @@ import { TheoremError } from '../../guardrails/error.js';
6
6
  export declare function readGeminiApiError(record: Record<string, unknown>): TheoremError | null;
7
7
  /** The kind is the HTTP status's, unless the body names a refused key. */
8
8
  export declare function readNonOkError(response: Response): Promise<TheoremError>;
9
+ /** A non-OK reply's error: the body's own when it names a refused key, else the status's with the body's message. */
10
+ export declare function statedOrStatusError(stated: TheoremError | null, status: number, fallback: string): TheoremError;
@@ -72,13 +72,15 @@ const BLOCKED_CODES = new Set([
72
72
  * codes (`malformed_function_call`, `no_image`, …) and any code Google adds later
73
73
  * are `bad_response`.
74
74
  */
75
- function kindOfNamedCode(code) {
75
+ function namedCodeError(code, message) {
76
76
  if (code === 'cancelled')
77
- return 'cancelled';
77
+ return new TheoremError('cancelled', message);
78
78
  if (BLOCKED_CODES.has(code))
79
- return 'safety';
79
+ return new TheoremError('safety', message);
80
80
  const status = NAMED_CODE_STATUS[code];
81
- return status === undefined ? 'bad_response' : kindOfHttpStatus(status);
81
+ return status === undefined
82
+ ? new TheoremError('bad_response', message)
83
+ : new TheoremError(kindOfHttpStatus(status), message);
82
84
  }
83
85
  /**
84
86
  * Interactions (SSE `error` rows, non-OK bodies) and Live (error frames) both send
@@ -90,28 +92,34 @@ export function readGeminiApiError(record) {
90
92
  return null;
91
93
  }
92
94
  const { code, message, status, details } = error;
93
- const kind = refusesKey(details)
94
- ? 'auth'
95
- : typeof code === 'number' && code >= HTTP_STATUS_MIN && code <= HTTP_STATUS_MAX
96
- ? kindOfHttpStatus(code)
97
- : typeof code === 'string'
98
- ? kindOfNamedCode(code)
99
- : 'bad_response';
100
- if (typeof message !== 'string' || message.length === 0) {
101
- return new TheoremError(kind, 'Gemini returned an error.');
95
+ const text = typeof message !== 'string' || message.length === 0
96
+ ? 'Gemini returned an error.'
97
+ : typeof status === 'string'
98
+ ? `${status}: ${message}`
99
+ : message;
100
+ if (refusesKey(details))
101
+ return new TheoremError('auth', text);
102
+ if (typeof code === 'number' && code >= HTTP_STATUS_MIN && code <= HTTP_STATUS_MAX) {
103
+ return new TheoremError(kindOfHttpStatus(code), text);
102
104
  }
103
- return new TheoremError(kind, typeof status === 'string' ? `${status}: ${message}` : message);
105
+ return typeof code === 'string'
106
+ ? namedCodeError(code, text)
107
+ : new TheoremError('bad_response', text);
104
108
  }
105
109
  /** The kind is the HTTP status's, unless the body names a refused key. */
106
110
  export async function readNonOkError(response) {
107
- const kind = kindOfHttpStatus(response.status);
108
111
  const text = await response.text().catch(() => '');
109
112
  if (!text.trim()) {
110
- return new TheoremError(kind, `HTTP ${response.status}`);
113
+ return new TheoremError(kindOfHttpStatus(response.status), `HTTP ${response.status}`);
111
114
  }
112
115
  const parsed = parseRecord(text);
113
- const stated = parsed ? readGeminiApiError(parsed) : null;
114
- return new TheoremError(stated?.kind === 'auth' ? 'auth' : kind, stated?.message ?? `Gemini HTTP ${response.status}: ${text}`);
116
+ return statedOrStatusError(parsed ? readGeminiApiError(parsed) : null, response.status, `Gemini HTTP ${response.status}: ${text}`);
117
+ }
118
+ /** A non-OK reply's error: the body's own when it names a refused key, else the status's with the body's message. */
119
+ export function statedOrStatusError(stated, status, fallback) {
120
+ if (stated?.kind === 'auth')
121
+ return stated;
122
+ return new TheoremError(kindOfHttpStatus(status), stated?.message ?? fallback);
115
123
  }
116
124
  function parseRecord(text) {
117
125
  try {
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The tools Gemini runs itself, and how each is sent on Interactions and on Live, with what it
3
+ * takes from a request's `builtInArgs`.
4
+ *
5
+ * @module
6
+ */
7
+ import type { ProviderBuiltin } from '../../kernel/types.js';
8
+ /** The request's builtins that are Google's own tools; the wire takes no others. */
9
+ declare function googleBuiltins<B extends ProviderBuiltin>(builtins: readonly B[]): B[];
10
+ /** One builtin as an Interactions `tools` entry. */
11
+ declare function interactionsBuiltinTool(builtin: ProviderBuiltin): Record<string, unknown>;
12
+ /** One builtin as a Live setup `tools` entry. Live takes no args for any of them. */
13
+ declare function liveBuiltinTool(builtin: ProviderBuiltin): Record<string, unknown>;
14
+ export { googleBuiltins, interactionsBuiltinTool, liveBuiltinTool };