@theoremjs/agents 0.0.0-stage → 0.3.0

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 (514) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1264 -2
  3. package/esm/_dnt.polyfills.d.ts +66 -0
  4. package/esm/_dnt.polyfills.js +51 -0
  5. package/esm/mod.d.ts +65 -0
  6. package/esm/mod.js +42 -0
  7. package/esm/package.json +3 -0
  8. package/esm/src/cli/bin.d.ts +7 -0
  9. package/esm/src/cli/bin.js +9 -0
  10. package/esm/src/cli/commands/bench.d.ts +6 -0
  11. package/esm/src/cli/commands/bench.js +458 -0
  12. package/esm/src/cli/commands/egress-compile.d.ts +17 -0
  13. package/esm/src/cli/commands/egress-compile.js +25 -0
  14. package/esm/src/cli/commands/eval.d.ts +37 -0
  15. package/esm/src/cli/commands/eval.js +190 -0
  16. package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
  17. package/esm/src/cli/commands/fuzz-canary.js +202 -0
  18. package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
  19. package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
  20. package/esm/src/cli/commands/profile.d.ts +2 -0
  21. package/esm/src/cli/commands/profile.js +80 -0
  22. package/esm/src/cli/commands/run.d.ts +13 -0
  23. package/esm/src/cli/commands/run.js +45 -0
  24. package/esm/src/cli/commands/test.d.ts +25 -0
  25. package/esm/src/cli/commands/test.js +143 -0
  26. package/esm/src/cli/event-log.d.ts +15 -0
  27. package/esm/src/cli/event-log.js +136 -0
  28. package/esm/src/cli/index.d.ts +10 -0
  29. package/esm/src/cli/index.js +267 -0
  30. package/esm/src/cli/matrix/fixtures.d.ts +10 -0
  31. package/esm/src/cli/matrix/fixtures.js +72 -0
  32. package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
  33. package/esm/src/cli/matrix/synthesizer.js +103 -0
  34. package/esm/src/evals/attachments.d.ts +4 -0
  35. package/esm/src/evals/attachments.js +53 -0
  36. package/esm/src/evals/breakdown.d.ts +28 -0
  37. package/esm/src/evals/breakdown.js +68 -0
  38. package/esm/src/evals/graders/answer.d.ts +13 -0
  39. package/esm/src/evals/graders/answer.js +133 -0
  40. package/esm/src/evals/graders/code.d.ts +64 -0
  41. package/esm/src/evals/graders/code.js +205 -0
  42. package/esm/src/evals/graders/judge.d.ts +20 -0
  43. package/esm/src/evals/graders/judge.js +365 -0
  44. package/esm/src/evals/graders/latency.d.ts +5 -0
  45. package/esm/src/evals/graders/latency.js +81 -0
  46. package/esm/src/evals/graders/live.d.ts +11 -0
  47. package/esm/src/evals/graders/live.js +40 -0
  48. package/esm/src/evals/graders/media.d.ts +18 -0
  49. package/esm/src/evals/graders/media.js +92 -0
  50. package/esm/src/evals/graders/shared.d.ts +11 -0
  51. package/esm/src/evals/graders/shared.js +62 -0
  52. package/esm/src/evals/graders/transcript.d.ts +17 -0
  53. package/esm/src/evals/graders/transcript.js +200 -0
  54. package/esm/src/evals/mod.d.ts +42 -0
  55. package/esm/src/evals/mod.js +30 -0
  56. package/esm/src/evals/record.d.ts +35 -0
  57. package/esm/src/evals/record.js +105 -0
  58. package/esm/src/evals/rubrics/catalog.d.ts +148 -0
  59. package/esm/src/evals/rubrics/catalog.js +846 -0
  60. package/esm/src/evals/rubrics/mod.d.ts +24 -0
  61. package/esm/src/evals/rubrics/mod.js +55 -0
  62. package/esm/src/evals/rubrics/mustache.d.ts +23 -0
  63. package/esm/src/evals/rubrics/mustache.js +154 -0
  64. package/esm/src/evals/rubrics/types.d.ts +54 -0
  65. package/esm/src/evals/rubrics/types.js +74 -0
  66. package/esm/src/evals/run.d.ts +118 -0
  67. package/esm/src/evals/run.js +452 -0
  68. package/esm/src/evals/suite.d.ts +19 -0
  69. package/esm/src/evals/suite.js +92 -0
  70. package/esm/src/evals/summary.d.ts +32 -0
  71. package/esm/src/evals/summary.js +30 -0
  72. package/esm/src/evals/trial.d.ts +27 -0
  73. package/esm/src/evals/trial.js +158 -0
  74. package/esm/src/evals/types.d.ts +260 -0
  75. package/esm/src/evals/types.js +126 -0
  76. package/esm/src/evals/verdict.d.ts +18 -0
  77. package/esm/src/evals/verdict.js +45 -0
  78. package/esm/src/guardrails/canary-gate.d.ts +21 -0
  79. package/esm/src/guardrails/canary-gate.js +40 -0
  80. package/esm/src/guardrails/canary.d.ts +112 -0
  81. package/esm/src/guardrails/canary.js +901 -0
  82. package/esm/src/guardrails/compile-egress.d.ts +11 -0
  83. package/esm/src/guardrails/compile-egress.js +11 -0
  84. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +22 -0
  85. package/esm/src/guardrails/corpus/canary-egress-attacks.js +303 -0
  86. package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
  87. package/esm/src/guardrails/corpus/fuzz-inbound.js +202 -0
  88. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +3 -0
  89. package/esm/src/guardrails/corpus/inbound-payloads.js +118 -0
  90. package/esm/src/guardrails/corpus/live-attacks.d.ts +13 -0
  91. package/esm/src/guardrails/corpus/live-attacks.js +224 -0
  92. package/esm/src/guardrails/corpus/mod.d.ts +7 -0
  93. package/esm/src/guardrails/corpus/mod.js +4 -0
  94. package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
  95. package/esm/src/guardrails/corpus/secrets.js +16 -0
  96. package/esm/src/guardrails/corpus/strings.d.ts +23 -0
  97. package/esm/src/guardrails/corpus/strings.js +29 -0
  98. package/esm/src/guardrails/corpus/types.d.ts +32 -0
  99. package/esm/src/guardrails/corpus/types.js +1 -0
  100. package/esm/src/guardrails/egress-automata.d.ts +14 -0
  101. package/esm/src/guardrails/egress-automata.js +6059 -0
  102. package/esm/src/guardrails/egress-compiler.d.ts +33 -0
  103. package/esm/src/guardrails/egress-compiler.js +237 -0
  104. package/esm/src/guardrails/egress-patterns.d.ts +24 -0
  105. package/esm/src/guardrails/egress-patterns.js +32 -0
  106. package/esm/src/guardrails/egress-policy.d.ts +27 -0
  107. package/esm/src/guardrails/egress-policy.js +76 -0
  108. package/esm/src/guardrails/egress-rules.d.ts +54 -0
  109. package/esm/src/guardrails/egress-rules.js +49 -0
  110. package/esm/src/guardrails/egress-stream.d.ts +105 -0
  111. package/esm/src/guardrails/egress-stream.js +645 -0
  112. package/esm/src/guardrails/egress-urls.d.ts +83 -0
  113. package/esm/src/guardrails/egress-urls.js +917 -0
  114. package/esm/src/guardrails/egress.d.ts +106 -0
  115. package/esm/src/guardrails/egress.js +374 -0
  116. package/esm/src/guardrails/error.d.ts +26 -0
  117. package/esm/src/guardrails/error.js +91 -0
  118. package/esm/src/guardrails/event-schemas.d.ts +57 -0
  119. package/esm/src/guardrails/event-schemas.js +41 -0
  120. package/esm/src/guardrails/events.d.ts +9 -0
  121. package/esm/src/guardrails/events.js +42 -0
  122. package/esm/src/guardrails/hits.d.ts +8 -0
  123. package/esm/src/guardrails/hits.js +19 -0
  124. package/esm/src/guardrails/injection-patterns.d.ts +15 -0
  125. package/esm/src/guardrails/injection-patterns.js +94 -0
  126. package/esm/src/guardrails/injection.d.ts +14 -0
  127. package/esm/src/guardrails/injection.js +237 -0
  128. package/esm/src/guardrails/lexicon.d.ts +30 -0
  129. package/esm/src/guardrails/lexicon.js +478 -0
  130. package/esm/src/guardrails/live-outbound-gate.d.ts +54 -0
  131. package/esm/src/guardrails/live-outbound-gate.js +305 -0
  132. package/esm/src/guardrails/mod.d.ts +46 -0
  133. package/esm/src/guardrails/mod.js +29 -0
  134. package/esm/src/guardrails/network.d.ts +42 -0
  135. package/esm/src/guardrails/network.js +328 -0
  136. package/esm/src/guardrails/normalize.d.ts +6 -0
  137. package/esm/src/guardrails/normalize.js +132 -0
  138. package/esm/src/guardrails/policy.d.ts +19 -0
  139. package/esm/src/guardrails/policy.js +50 -0
  140. package/esm/src/guardrails/progressive-yield.d.ts +69 -0
  141. package/esm/src/guardrails/progressive-yield.js +237 -0
  142. package/esm/src/guardrails/prompt-echo.d.ts +38 -0
  143. package/esm/src/guardrails/prompt-echo.js +225 -0
  144. package/esm/src/guardrails/quota.d.ts +20 -0
  145. package/esm/src/guardrails/quota.js +80 -0
  146. package/esm/src/guardrails/rules.d.ts +56 -0
  147. package/esm/src/guardrails/rules.js +54 -0
  148. package/esm/src/guardrails/sanitize.d.ts +23 -0
  149. package/esm/src/guardrails/sanitize.js +184 -0
  150. package/esm/src/guardrails/sensitive.d.ts +29 -0
  151. package/esm/src/guardrails/sensitive.js +113 -0
  152. package/esm/src/guardrails/serialize.d.ts +14 -0
  153. package/esm/src/guardrails/serialize.js +37 -0
  154. package/esm/src/guardrails/testing.d.ts +9 -0
  155. package/esm/src/guardrails/testing.js +8 -0
  156. package/esm/src/guardrails/theorem-error.d.ts +18 -0
  157. package/esm/src/guardrails/theorem-error.js +53 -0
  158. package/esm/src/guardrails/thought-guard.d.ts +55 -0
  159. package/esm/src/guardrails/thought-guard.js +464 -0
  160. package/esm/src/guardrails/tool-directives.d.ts +19 -0
  161. package/esm/src/guardrails/tool-directives.js +109 -0
  162. package/esm/src/guardrails/tool-result.d.ts +61 -0
  163. package/esm/src/guardrails/tool-result.js +248 -0
  164. package/esm/src/guardrails/types.d.ts +242 -0
  165. package/esm/src/guardrails/types.js +54 -0
  166. package/esm/src/host/client-turn.d.ts +9 -0
  167. package/esm/src/host/client-turn.js +38 -0
  168. package/esm/src/host/mint-trace.d.ts +28 -0
  169. package/esm/src/host/mint-trace.js +59 -0
  170. package/esm/src/host/mod.d.ts +13 -0
  171. package/esm/src/host/mod.js +11 -0
  172. package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
  173. package/esm/src/host/readStreamingJsonStringField.js +68 -0
  174. package/esm/src/host/reply.d.ts +7 -0
  175. package/esm/src/host/reply.js +35 -0
  176. package/esm/src/interface/blocks.d.ts +8 -0
  177. package/esm/src/interface/blocks.js +213 -0
  178. package/esm/src/interface/composer-actions.d.ts +20 -0
  179. package/esm/src/interface/composer-actions.js +31 -0
  180. package/esm/src/interface/draft.d.ts +14 -0
  181. package/esm/src/interface/draft.js +28 -0
  182. package/esm/src/interface/from-profile.d.ts +12 -0
  183. package/esm/src/interface/from-profile.js +144 -0
  184. package/esm/src/interface/history.d.ts +40 -0
  185. package/esm/src/interface/history.js +269 -0
  186. package/esm/src/interface/inputs.d.ts +10 -0
  187. package/esm/src/interface/inputs.js +64 -0
  188. package/esm/src/interface/mod.d.ts +31 -0
  189. package/esm/src/interface/mod.js +21 -0
  190. package/esm/src/interface/models.d.ts +19 -0
  191. package/esm/src/interface/models.js +45 -0
  192. package/esm/src/interface/pending.d.ts +48 -0
  193. package/esm/src/interface/pending.js +146 -0
  194. package/esm/src/interface/profile-interface.d.ts +4 -0
  195. package/esm/src/interface/profile-interface.js +223 -0
  196. package/esm/src/interface/session.d.ts +64 -0
  197. package/esm/src/interface/session.js +121 -0
  198. package/esm/src/interface/tool-calls.d.ts +20 -0
  199. package/esm/src/interface/tool-calls.js +73 -0
  200. package/esm/src/interface/tool-invoke.d.ts +4 -0
  201. package/esm/src/interface/tool-invoke.js +20 -0
  202. package/esm/src/interface/tool-media.d.ts +9 -0
  203. package/esm/src/interface/tool-media.js +112 -0
  204. package/esm/src/interface/types.d.ts +213 -0
  205. package/esm/src/interface/types.js +4 -0
  206. package/esm/src/kernel/auth/credential-source.d.ts +23 -0
  207. package/esm/src/kernel/auth/credential-source.js +11 -0
  208. package/esm/src/kernel/auth/crypto.d.ts +51 -0
  209. package/esm/src/kernel/auth/crypto.js +161 -0
  210. package/esm/src/kernel/auth/mod.d.ts +5 -0
  211. package/esm/src/kernel/auth/mod.js +5 -0
  212. package/esm/src/kernel/auth/oauth.d.ts +17 -0
  213. package/esm/src/kernel/auth/oauth.js +438 -0
  214. package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
  215. package/esm/src/kernel/auth/scope-refusal.js +8 -0
  216. package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
  217. package/esm/src/kernel/auth/typed-secret.js +23 -0
  218. package/esm/src/kernel/auth/types.d.ts +139 -0
  219. package/esm/src/kernel/auth/types.js +1 -0
  220. package/esm/src/kernel/default-scope.d.ts +34 -0
  221. package/esm/src/kernel/default-scope.js +72 -0
  222. package/esm/src/kernel/engine/compaction.d.ts +70 -0
  223. package/esm/src/kernel/engine/compaction.js +202 -0
  224. package/esm/src/kernel/engine/decision.d.ts +41 -0
  225. package/esm/src/kernel/engine/decision.js +412 -0
  226. package/esm/src/kernel/engine/hash.d.ts +6 -0
  227. package/esm/src/kernel/engine/hash.js +22 -0
  228. package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
  229. package/esm/src/kernel/engine/live-inbound.js +19 -0
  230. package/esm/src/kernel/engine/live-ingress.d.ts +9 -0
  231. package/esm/src/kernel/engine/live-ingress.js +37 -0
  232. package/esm/src/kernel/engine/media-probe/audio.d.ts +7 -0
  233. package/esm/src/kernel/engine/media-probe/audio.js +342 -0
  234. package/esm/src/kernel/engine/media-probe/bytes.d.ts +6 -0
  235. package/esm/src/kernel/engine/media-probe/bytes.js +26 -0
  236. package/esm/src/kernel/engine/media-probe/image.d.ts +5 -0
  237. package/esm/src/kernel/engine/media-probe/image.js +171 -0
  238. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +19 -0
  239. package/esm/src/kernel/engine/media-probe/iso-bmff.js +48 -0
  240. package/esm/src/kernel/engine/media-probe/matroska.d.ts +35 -0
  241. package/esm/src/kernel/engine/media-probe/matroska.js +226 -0
  242. package/esm/src/kernel/engine/media-probe/mp4.d.ts +22 -0
  243. package/esm/src/kernel/engine/media-probe/mp4.js +279 -0
  244. package/esm/src/kernel/engine/media-probe/opus.d.ts +4 -0
  245. package/esm/src/kernel/engine/media-probe/opus.js +23 -0
  246. package/esm/src/kernel/engine/media-probe/pdf.d.ts +5 -0
  247. package/esm/src/kernel/engine/media-probe/pdf.js +117 -0
  248. package/esm/src/kernel/engine/media-probe/video.d.ts +15 -0
  249. package/esm/src/kernel/engine/media-probe/video.js +49 -0
  250. package/esm/src/kernel/engine/record.d.ts +3 -0
  251. package/esm/src/kernel/engine/record.js +11 -0
  252. package/esm/src/kernel/engine/repair.d.ts +7 -0
  253. package/esm/src/kernel/engine/repair.js +36 -0
  254. package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
  255. package/esm/src/kernel/engine/runner/gates.js +322 -0
  256. package/esm/src/kernel/engine/runner/mod.d.ts +15 -0
  257. package/esm/src/kernel/engine/runner/mod.js +574 -0
  258. package/esm/src/kernel/engine/runner/schema-validation.d.ts +14 -0
  259. package/esm/src/kernel/engine/runner/schema-validation.js +105 -0
  260. package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
  261. package/esm/src/kernel/engine/runner/stages.js +48 -0
  262. package/esm/src/kernel/engine/runner/state.d.ts +76 -0
  263. package/esm/src/kernel/engine/runner/state.js +40 -0
  264. package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
  265. package/esm/src/kernel/engine/runner/steps.js +360 -0
  266. package/esm/src/kernel/engine/runner/stream.d.ts +40 -0
  267. package/esm/src/kernel/engine/runner/stream.js +225 -0
  268. package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
  269. package/esm/src/kernel/engine/runner/usage.js +150 -0
  270. package/esm/src/kernel/engine/session/mod.d.ts +31 -0
  271. package/esm/src/kernel/engine/session/mod.js +951 -0
  272. package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
  273. package/esm/src/kernel/engine/session/session-trace.js +489 -0
  274. package/esm/src/kernel/engine/token-estimate.d.ts +77 -0
  275. package/esm/src/kernel/engine/token-estimate.js +218 -0
  276. package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
  277. package/esm/src/kernel/engine/tool-trace.js +131 -0
  278. package/esm/src/kernel/engine/tree.d.ts +2 -0
  279. package/esm/src/kernel/engine/tree.js +17 -0
  280. package/esm/src/kernel/engine/turn-trace.d.ts +118 -0
  281. package/esm/src/kernel/engine/turn-trace.js +863 -0
  282. package/esm/src/kernel/engine/usage.d.ts +30 -0
  283. package/esm/src/kernel/engine/usage.js +134 -0
  284. package/esm/src/kernel/interaction-parts.d.ts +10 -0
  285. package/esm/src/kernel/interaction-parts.js +22 -0
  286. package/esm/src/kernel/mod.d.ts +47 -0
  287. package/esm/src/kernel/mod.js +30 -0
  288. package/esm/src/kernel/profile-graph.d.ts +140 -0
  289. package/esm/src/kernel/profile-graph.js +151 -0
  290. package/esm/src/kernel/profile-presence.d.ts +9 -0
  291. package/esm/src/kernel/profile-presence.js +143 -0
  292. package/esm/src/kernel/profile-scope.d.ts +36 -0
  293. package/esm/src/kernel/profile-scope.js +262 -0
  294. package/esm/src/kernel/registry/attachments.d.ts +35 -0
  295. package/esm/src/kernel/registry/attachments.js +211 -0
  296. package/esm/src/kernel/registry/catalog.d.ts +19 -0
  297. package/esm/src/kernel/registry/catalog.js +78 -0
  298. package/esm/src/kernel/registry/ingress.d.ts +8 -0
  299. package/esm/src/kernel/registry/ingress.js +134 -0
  300. package/esm/src/kernel/registry/kernel-registry.d.ts +12 -0
  301. package/esm/src/kernel/registry/kernel-registry.js +8 -0
  302. package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
  303. package/esm/src/kernel/registry/profile-outputs.js +7 -0
  304. package/esm/src/kernel/registry/profiles.d.ts +92 -0
  305. package/esm/src/kernel/registry/profiles.js +698 -0
  306. package/esm/src/kernel/registry/provider-request.d.ts +6 -0
  307. package/esm/src/kernel/registry/provider-request.js +42 -0
  308. package/esm/src/kernel/registry/resolve.d.ts +14 -0
  309. package/esm/src/kernel/registry/resolve.js +237 -0
  310. package/esm/src/kernel/registry/schemas.d.ts +9 -0
  311. package/esm/src/kernel/registry/schemas.js +25 -0
  312. package/esm/src/kernel/registry/sole-model.d.ts +2 -0
  313. package/esm/src/kernel/registry/sole-model.js +4 -0
  314. package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
  315. package/esm/src/kernel/registry/system-prompt.js +33 -0
  316. package/esm/src/kernel/registry/system-role.d.ts +3 -0
  317. package/esm/src/kernel/registry/system-role.js +9 -0
  318. package/esm/src/kernel/registry/vault.d.ts +13 -0
  319. package/esm/src/kernel/registry/vault.js +14 -0
  320. package/esm/src/kernel/schema.d.ts +172 -0
  321. package/esm/src/kernel/schema.js +653 -0
  322. package/esm/src/kernel/scope.d.ts +22 -0
  323. package/esm/src/kernel/scope.js +25 -0
  324. package/esm/src/kernel/stages.d.ts +141 -0
  325. package/esm/src/kernel/stages.js +388 -0
  326. package/esm/src/kernel/stop.d.ts +93 -0
  327. package/esm/src/kernel/stop.js +125 -0
  328. package/esm/src/kernel/system-parts.d.ts +26 -0
  329. package/esm/src/kernel/system-parts.js +98 -0
  330. package/esm/src/kernel/tools/activity-label.d.ts +16 -0
  331. package/esm/src/kernel/tools/activity-label.js +209 -0
  332. package/esm/src/kernel/tools/events.d.ts +51 -0
  333. package/esm/src/kernel/tools/events.js +149 -0
  334. package/esm/src/kernel/tools/execute.d.ts +64 -0
  335. package/esm/src/kernel/tools/execute.js +801 -0
  336. package/esm/src/kernel/tools/gate-answer.d.ts +50 -0
  337. package/esm/src/kernel/tools/gate-answer.js +54 -0
  338. package/esm/src/kernel/tools/harness.d.ts +16 -0
  339. package/esm/src/kernel/tools/harness.js +42 -0
  340. package/esm/src/kernel/tools/invoke.d.ts +10 -0
  341. package/esm/src/kernel/tools/invoke.js +129 -0
  342. package/esm/src/kernel/tools/mcp-sessions.d.ts +20 -0
  343. package/esm/src/kernel/tools/mcp-sessions.js +64 -0
  344. package/esm/src/kernel/tools/mod.d.ts +9 -0
  345. package/esm/src/kernel/tools/mod.js +6 -0
  346. package/esm/src/kernel/tools/model-text.d.ts +11 -0
  347. package/esm/src/kernel/tools/model-text.js +25 -0
  348. package/esm/src/kernel/tools/permission.d.ts +6 -0
  349. package/esm/src/kernel/tools/permission.js +38 -0
  350. package/esm/src/kernel/tools/project.d.ts +8 -0
  351. package/esm/src/kernel/tools/project.js +25 -0
  352. package/esm/src/kernel/tools/registry.d.ts +20 -0
  353. package/esm/src/kernel/tools/registry.js +84 -0
  354. package/esm/src/kernel/tools/remote.d.ts +110 -0
  355. package/esm/src/kernel/tools/remote.js +998 -0
  356. package/esm/src/kernel/tools/resolve.d.ts +28 -0
  357. package/esm/src/kernel/tools/resolve.js +259 -0
  358. package/esm/src/kernel/tools/schema.d.ts +10 -0
  359. package/esm/src/kernel/tools/schema.js +174 -0
  360. package/esm/src/kernel/tools/signed-in-fetch.d.ts +18 -0
  361. package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
  362. package/esm/src/kernel/tools/stage-run.d.ts +93 -0
  363. package/esm/src/kernel/tools/stage-run.js +140 -0
  364. package/esm/src/kernel/tools/types.d.ts +287 -0
  365. package/esm/src/kernel/tools/types.js +1 -0
  366. package/esm/src/kernel/turn-events.d.ts +599 -0
  367. package/esm/src/kernel/turn-events.js +425 -0
  368. package/esm/src/kernel/types.d.ts +884 -0
  369. package/esm/src/kernel/types.js +1 -0
  370. package/esm/src/kernel/util/base64.d.ts +2 -0
  371. package/esm/src/kernel/util/base64.js +13 -0
  372. package/esm/src/kernel/util/exact-type.d.ts +31 -0
  373. package/esm/src/kernel/util/exact-type.js +1 -0
  374. package/esm/src/kernel/util/find-last.d.ts +3 -0
  375. package/esm/src/kernel/util/find-last.js +9 -0
  376. package/esm/src/kernel/util/mime.d.ts +2 -0
  377. package/esm/src/kernel/util/mime.js +4 -0
  378. package/esm/src/kernel/util/record.d.ts +1 -0
  379. package/esm/src/kernel/util/record.js +3 -0
  380. package/esm/src/observability/destinations.d.ts +9 -0
  381. package/esm/src/observability/destinations.js +38 -0
  382. package/esm/src/observability/jsonl.d.ts +18 -0
  383. package/esm/src/observability/jsonl.js +117 -0
  384. package/esm/src/observability/mod.d.ts +22 -0
  385. package/esm/src/observability/mod.js +16 -0
  386. package/esm/src/observability/openinference.d.ts +11 -0
  387. package/esm/src/observability/openinference.js +205 -0
  388. package/esm/src/observability/otlp.d.ts +68 -0
  389. package/esm/src/observability/otlp.js +98 -0
  390. package/esm/src/observability/phoenix.d.ts +29 -0
  391. package/esm/src/observability/phoenix.js +71 -0
  392. package/esm/src/observability/policy.d.ts +14 -0
  393. package/esm/src/observability/policy.js +69 -0
  394. package/esm/src/observability/resolve-policy.d.ts +8 -0
  395. package/esm/src/observability/resolve-policy.js +58 -0
  396. package/esm/src/observability/spans.d.ts +16 -0
  397. package/esm/src/observability/spans.js +56 -0
  398. package/esm/src/observability/trace-catalog.d.ts +111 -0
  399. package/esm/src/observability/trace-catalog.js +865 -0
  400. package/esm/src/observability/trace-record.d.ts +23 -0
  401. package/esm/src/observability/trace-record.js +223 -0
  402. package/esm/src/observability/trace-schema.d.ts +54 -0
  403. package/esm/src/observability/trace-schema.js +59 -0
  404. package/esm/src/observability/trace-sink.d.ts +13 -0
  405. package/esm/src/observability/trace-sink.js +3 -0
  406. package/esm/src/observability/trace-span.d.ts +92 -0
  407. package/esm/src/observability/trace-span.js +199 -0
  408. package/esm/src/observability/trace.d.ts +11 -0
  409. package/esm/src/observability/trace.js +35 -0
  410. package/esm/src/observability/types.d.ts +85 -0
  411. package/esm/src/observability/types.js +3 -0
  412. package/esm/src/presets/google/speech-voices.d.ts +8 -0
  413. package/esm/src/presets/google/speech-voices.js +38 -0
  414. package/esm/src/presets/google-limits.d.ts +12 -0
  415. package/esm/src/presets/google-limits.js +18 -0
  416. package/esm/src/presets/google.d.ts +104 -0
  417. package/esm/src/presets/google.js +188 -0
  418. package/esm/src/presets/mod.d.ts +10 -0
  419. package/esm/src/presets/mod.js +9 -0
  420. package/esm/src/presets/openrouter.d.ts +13 -0
  421. package/esm/src/presets/openrouter.js +13 -0
  422. package/esm/src/presets/typesafe.d.ts +2 -0
  423. package/esm/src/presets/typesafe.js +2 -0
  424. package/esm/src/providers/create-provider.d.ts +21 -0
  425. package/esm/src/providers/create-provider.js +90 -0
  426. package/esm/src/providers/decision/usage.d.ts +3 -0
  427. package/esm/src/providers/decision/usage.js +25 -0
  428. package/esm/src/providers/google/api-error.d.ts +8 -0
  429. package/esm/src/providers/google/api-error.js +123 -0
  430. package/esm/src/providers/google/grounding.d.ts +5 -0
  431. package/esm/src/providers/google/grounding.js +226 -0
  432. package/esm/src/providers/google/interactions/framing.d.ts +15 -0
  433. package/esm/src/providers/google/interactions/framing.js +263 -0
  434. package/esm/src/providers/google/interactions/mod.d.ts +2 -0
  435. package/esm/src/providers/google/interactions/mod.js +2 -0
  436. package/esm/src/providers/google/interactions/steps.d.ts +12 -0
  437. package/esm/src/providers/google/interactions/steps.js +200 -0
  438. package/esm/src/providers/google/interactions/stream.d.ts +24 -0
  439. package/esm/src/providers/google/interactions/stream.js +297 -0
  440. package/esm/src/providers/google/keys.d.ts +20 -0
  441. package/esm/src/providers/google/keys.js +87 -0
  442. package/esm/src/providers/google/live/framing.d.ts +51 -0
  443. package/esm/src/providers/google/live/framing.js +597 -0
  444. package/esm/src/providers/google/live/mod.d.ts +7 -0
  445. package/esm/src/providers/google/live/mod.js +7 -0
  446. package/esm/src/providers/google/live/openapi-schema.d.ts +1 -0
  447. package/esm/src/providers/google/live/openapi-schema.js +42 -0
  448. package/esm/src/providers/google/live/session.d.ts +14 -0
  449. package/esm/src/providers/google/live/session.js +150 -0
  450. package/esm/src/providers/google/live/stream.d.ts +51 -0
  451. package/esm/src/providers/google/live/stream.js +263 -0
  452. package/esm/src/providers/google/thinking.d.ts +3 -0
  453. package/esm/src/providers/google/thinking.js +8 -0
  454. package/esm/src/providers/google/urls.d.ts +6 -0
  455. package/esm/src/providers/google/urls.js +6 -0
  456. package/esm/src/providers/google/usage.d.ts +7 -0
  457. package/esm/src/providers/google/usage.js +49 -0
  458. package/esm/src/providers/local/local.d.ts +12 -0
  459. package/esm/src/providers/local/local.js +186 -0
  460. package/esm/src/providers/local/mod.d.ts +8 -0
  461. package/esm/src/providers/local/mod.js +8 -0
  462. package/esm/src/providers/mod.d.ts +11 -0
  463. package/esm/src/providers/mod.js +7 -0
  464. package/esm/src/providers/openrouter/cache-control.d.ts +5 -0
  465. package/esm/src/providers/openrouter/cache-control.js +4 -0
  466. package/esm/src/providers/openrouter/chat.d.ts +64 -0
  467. package/esm/src/providers/openrouter/chat.js +490 -0
  468. package/esm/src/providers/openrouter/image.d.ts +24 -0
  469. package/esm/src/providers/openrouter/image.js +187 -0
  470. package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
  471. package/esm/src/providers/openrouter/openai/compat.js +162 -0
  472. package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
  473. package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
  474. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +10 -0
  475. package/esm/src/providers/openrouter/openai/sdk-messages.js +99 -0
  476. package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
  477. package/esm/src/providers/openrouter/openai/usage.js +56 -0
  478. package/esm/src/providers/openrouter/resolve-api-key.d.ts +3 -0
  479. package/esm/src/providers/openrouter/resolve-api-key.js +8 -0
  480. package/esm/src/providers/openrouter/speech.d.ts +18 -0
  481. package/esm/src/providers/openrouter/speech.js +109 -0
  482. package/esm/src/providers/probe.d.ts +5 -0
  483. package/esm/src/providers/probe.js +15 -0
  484. package/esm/src/providers/shared/builtin-wire.d.ts +4 -0
  485. package/esm/src/providers/shared/builtin-wire.js +9 -0
  486. package/esm/src/providers/shared/pcm.d.ts +14 -0
  487. package/esm/src/providers/shared/pcm.js +78 -0
  488. package/esm/src/providers/shared/response-identity.d.ts +11 -0
  489. package/esm/src/providers/shared/response-identity.js +12 -0
  490. package/esm/src/providers/shared/sse.d.ts +10 -0
  491. package/esm/src/providers/shared/sse.js +79 -0
  492. package/esm/src/providers/shared/structured-output.d.ts +4 -0
  493. package/esm/src/providers/shared/structured-output.js +11 -0
  494. package/esm/src/providers/shared/tool-args.d.ts +25 -0
  495. package/esm/src/providers/shared/tool-args.js +84 -0
  496. package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
  497. package/esm/src/providers/shared/upstream-tap.js +85 -0
  498. package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
  499. package/esm/src/providers/shared/upstream-tape.js +88 -0
  500. package/esm/src/providers/shared/vault.d.ts +13 -0
  501. package/esm/src/providers/shared/vault.js +41 -0
  502. package/esm/src/providers/types.d.ts +19 -0
  503. package/esm/src/providers/types.js +1 -0
  504. package/esm/src/surface/formats.d.ts +28 -0
  505. package/esm/src/surface/formats.js +139 -0
  506. package/esm/src/surface/mod.d.ts +14 -0
  507. package/esm/src/surface/mod.js +10 -0
  508. package/esm/src/surface/runtime.d.ts +40 -0
  509. package/esm/src/surface/runtime.js +439 -0
  510. package/esm/src/surface/tools.d.ts +15 -0
  511. package/esm/src/surface/tools.js +80 -0
  512. package/esm/src/surface/types.d.ts +104 -0
  513. package/esm/src/surface/types.js +4 -0
  514. package/package.json +108 -4
@@ -0,0 +1,951 @@
1
+ import { canaryNote, userDataNote } from '../../../guardrails/canary.js';
2
+ import { addHistoryUrls, addRequestUrls, addSeenUrls, givenUrlSets, } from '../../../guardrails/egress-urls.js';
3
+ import { describeError, errorKind, TheoremError, throwIfAborted, toErrorEvent, withPublicWording, } from '../../../guardrails/error.js';
4
+ import { projectGuardrailTurnEvent } from '../../../guardrails/events.js';
5
+ import { lexiconText } from '../../../guardrails/lexicon.js';
6
+ import { abortLiveOutboundTurn, createLiveOutboundGateSession, finalizeLiveOutboundTurn, processLiveOutboundBatch, } from '../../../guardrails/live-outbound-gate.js';
7
+ import { sanitizeTurnRequest } from '../../../guardrails/sanitize.js';
8
+ import { resolveObservabilityPolicy } from '../../../observability/resolve-policy.js';
9
+ import { buildGeminiLiveContext, buildGeminiLiveRealtimeInput, buildGeminiLiveToolResponse, liveFunctionResponsePayload, } from '../../../providers/google/live/framing.js';
10
+ import { openGoogleLiveSession } from '../../../providers/google/live/session.js';
11
+ import { memoryCredentialSource } from '../../auth/credential-source.js';
12
+ import { providerCompleteRequest } from '../../registry/provider-request.js';
13
+ import { resolveTurnInRegistry } from '../../registry/resolve.js';
14
+ import { injectedStageEvent, runStage, stageEventFields, } from '../../stages.js';
15
+ import { profileAllowsInject, stageAbortStop } from '../../stop.js';
16
+ import { bindSystem } from '../../system-parts.js';
17
+ import { failureEvent } from '../../tools/events.js';
18
+ import { executeRegisteredTool, lapsedGateFailure, } from '../../tools/execute.js';
19
+ import { answerGatedCall, gateExpired, resolveGateTtlMs, resumeForAnswer, } from '../../tools/gate-answer.js';
20
+ import { formatToolFailureForModel, formatToolResult } from '../../tools/model-text.js';
21
+ import { cloneTurnToolSnapshot } from '../../tools/resolve.js';
22
+ import { turnDoneOf } from '../../turn-events.js';
23
+ import { prepareLiveInboundText } from '../live-inbound.js';
24
+ import { assertLiveIngress } from '../live-ingress.js';
25
+ import { mediaTokenFamily } from '../token-estimate.js';
26
+ import { startLiveTrace } from './session-trace.js';
27
+ function isReleased(held) {
28
+ return typeof held.state === 'object' && held.state.released === true;
29
+ }
30
+ function isSettledPhase(tool) {
31
+ return tool.phase === 'complete' || tool.phase === 'error' || tool.phase === 'gate';
32
+ }
33
+ /**
34
+ * The provider's close after it warned of it (`goAway`): the session's last
35
+ * event, not a failure. Every close fact rides along for the builder; the raw
36
+ * close text is `errorInternal`, which `forClient` strips.
37
+ */
38
+ function sessionEndedEvent(closed, goAway, lexicon) {
39
+ const internal = closed.error ? describeError(closed.error) : closed.reason;
40
+ return {
41
+ type: 'session',
42
+ session: {
43
+ kind: 'ended',
44
+ ...(goAway.timeLeftMs !== undefined ? { timeLeftMs: goAway.timeLeftMs } : {}),
45
+ message: lexiconText('live.session_ended', {}, lexicon),
46
+ ended: {
47
+ cause: 'go_away',
48
+ code: closed.code,
49
+ closedAfterMs: goAway.closedAfterMs,
50
+ ...(closed.error ? { errorKind: errorKind(closed.error) } : {}),
51
+ },
52
+ },
53
+ ...(internal ? { errorInternal: internal } : {}),
54
+ };
55
+ }
56
+ /** Live ingress takes text: an inject's texts, or `undefined` when any message is not plain text. */
57
+ function liveInjectTexts(messages) {
58
+ const texts = [];
59
+ for (const msg of messages) {
60
+ const text = msg.role === 'tool' || msg.parts?.length ? undefined : msg.content?.trim();
61
+ if (!text)
62
+ return undefined;
63
+ texts.push(text);
64
+ }
65
+ return texts;
66
+ }
67
+ function assertLiveProfile(profile) {
68
+ if (profile.type !== 'live') {
69
+ throw new TheoremError('request', `runSession requires profile.type 'live' (got '${profile.type}' for ${profile.id})`);
70
+ }
71
+ }
72
+ /**
73
+ * Accept a registry-resolved snapshot from the process that owns the tool
74
+ * registry. The profile's `tools.allow` stays the ceiling: a custom tool id
75
+ * outside it is refused rather than declared.
76
+ */
77
+ function sessionSnapshotWithinAllow(profile, snapshot) {
78
+ const allow = new Set(profile.tools.allow);
79
+ const builtins = new Set(snapshot.builtins);
80
+ const outside = new Set();
81
+ for (const id of [...snapshot.gated, ...snapshot.visible, ...snapshot.executable]) {
82
+ if (!allow.has(id) && !builtins.has(id)) {
83
+ outside.add(id);
84
+ }
85
+ }
86
+ if (outside.size > 0) {
87
+ // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
88
+ const detail = `session snapshot declares tools outside tools.allow: ${[...outside].join(', ')}`;
89
+ throw new TheoremError('config', `Profile ${profile.id}: ${detail}`);
90
+ }
91
+ return cloneTurnToolSnapshot(snapshot);
92
+ }
93
+ function toTurnRequest(req) {
94
+ return {
95
+ profile: req.profile,
96
+ system: req.system,
97
+ path: req.path,
98
+ sessionPermissions: req.sessionPermissions,
99
+ sessionResumptionHandle: req.sessionResumptionHandle,
100
+ signal: req.signal,
101
+ metadata: req.metadata,
102
+ host: req.host,
103
+ input: {
104
+ text: '',
105
+ history: req.history,
106
+ sessionResumptionHandle: req.sessionResumptionHandle,
107
+ },
108
+ };
109
+ }
110
+ function applyVoiceOverride(generation, voice) {
111
+ if (!voice || !generation.live) {
112
+ return generation;
113
+ }
114
+ return {
115
+ ...generation,
116
+ live: {
117
+ ...generation.live,
118
+ voice,
119
+ },
120
+ };
121
+ }
122
+ function applyInitialInput(generation, input) {
123
+ if (!input || input.length === 0) {
124
+ return generation;
125
+ }
126
+ return { ...generation, input };
127
+ }
128
+ async function applyOutbound(gate, events, turnPhase, onWithhold) {
129
+ if (turnPhase === 'abort') {
130
+ abortLiveOutboundTurn(gate);
131
+ // Keep tool calls + interrupted marker; drop buffered speech via abortLiveOutboundTurn.
132
+ return events.filter((ev) => ev.type === 'tool' ||
133
+ ev.type === 'session' ||
134
+ (ev.type === 'done' && ev.interrupted === true));
135
+ }
136
+ const batch = await processLiveOutboundBatch(gate, events);
137
+ const out = [];
138
+ if (batch.action === 'withhold') {
139
+ onWithhold();
140
+ return [...(batch.events ?? []), toErrorEvent(batch.error)];
141
+ }
142
+ if (batch.action === 'emit') {
143
+ out.push(...batch.events);
144
+ }
145
+ if (turnPhase === 'complete') {
146
+ const finalized = await finalizeLiveOutboundTurn(gate);
147
+ if (finalized.action === 'withhold') {
148
+ onWithhold();
149
+ return [...out, toErrorEvent(finalized.error)];
150
+ }
151
+ if (finalized.action === 'emit') {
152
+ out.push(...finalized.events);
153
+ }
154
+ // Conversational turn boundary — session stays open.
155
+ out.push({ type: 'done', stop: { kind: 'completed' } });
156
+ }
157
+ return out;
158
+ }
159
+ /**
160
+ * The output a settled Live call sends upstream, or `undefined` when nothing
161
+ * is sent (a held gate, or no result). The model reads it as the `functionResponse`:
162
+ * the same guarded text a turn sends, never the tool's raw output.
163
+ */
164
+ function liveToolOutput(s) {
165
+ if (s.gated)
166
+ return undefined;
167
+ const result = s.modelResult ?? (s.failure ? formatToolFailureForModel(s.failure) : undefined);
168
+ return result ? formatToolResult(result) : undefined;
169
+ }
170
+ /** What the model reads back from a Live call: the `functionResponse.response` sent. */
171
+ function liveReadBack(s) {
172
+ const output = liveToolOutput(s);
173
+ return output === undefined
174
+ ? undefined
175
+ : { text: JSON.stringify(liveFunctionResponsePayload(output)) };
176
+ }
177
+ /**
178
+ * A provider batch as the host receives it: a call's `done` becomes the
179
+ * host's (`turnDoneOf`); `response` stays with the trace, which read the batch.
180
+ */
181
+ function hostEventsOf(events, snapshot) {
182
+ return events.flatMap((ev) => {
183
+ if (ev.type === 'response')
184
+ return [];
185
+ if (ev.type !== 'done')
186
+ return [ev];
187
+ const { type: _done, ...done } = ev;
188
+ return [turnDoneOf(done, snapshot)];
189
+ });
190
+ }
191
+ function* drainPendingHostEvents(pendingHostEvents) {
192
+ while (pendingHostEvents.length > 0) {
193
+ const pending = pendingHostEvents.shift();
194
+ if (pending)
195
+ yield pending;
196
+ }
197
+ }
198
+ function boundaryDoneEvents(doneBatch, turnPhase, interrupted) {
199
+ if (doneBatch.length > 0)
200
+ return doneBatch;
201
+ if (turnPhase === 'abort' || interrupted) {
202
+ return [{ type: 'done', stop: { kind: 'interrupted' }, interrupted: true }];
203
+ }
204
+ return [{ type: 'done', stop: { kind: 'completed' } }];
205
+ }
206
+ function* yieldLiveNonDoneEvents(gated, includeMatch, recordAssistantText) {
207
+ const doneBatch = gated.filter((ev) => ev.type === 'done');
208
+ for (const ev of gated) {
209
+ if (ev.type === 'done')
210
+ continue;
211
+ if (ev.type === 'text' && typeof ev.text === 'string') {
212
+ recordAssistantText(ev.text);
213
+ }
214
+ yield projectGuardrailTurnEvent(ev, includeMatch ?? false);
215
+ }
216
+ return doneBatch;
217
+ }
218
+ function buildLiveSession(args) {
219
+ const { profile, canary, connection, gate, givenUrls, signal, onStage, host: sessionHost, resolveHost, path, snapshot, trace, gateTtlMs, signInGate, } = args;
220
+ /** Grows as the user approves `session_consent` tools. */
221
+ let sessionPermissions = args.sessionPermissions;
222
+ /** Where keys typed at sign-in gates go when a call brings no source of its own. */
223
+ const sessionCredentials = args.credentials ?? memoryCredentialSource();
224
+ const calls = new Map();
225
+ let closed = false;
226
+ let withholdClose = false;
227
+ const pendingHostEvents = [];
228
+ /** Wakes the host's stream when the session queues an event while Gemini is silent. */
229
+ let wakeHost;
230
+ const includeMatch = resolveObservabilityPolicy(profile.observability).include
231
+ .guardrailMatchPreview;
232
+ let cycle = 'idle';
233
+ let cycleStep = 0;
234
+ const history = args.historySeed?.length
235
+ ? structuredClone(args.historySeed)
236
+ : [];
237
+ /** Serialize stage + ingress so concurrent send* cannot interleave cycles. */
238
+ let ingressChain = Promise.resolve();
239
+ const recordUserText = (text) => {
240
+ const trimmed = text.trim();
241
+ if (!trimmed)
242
+ return;
243
+ history.push({ role: 'user', content: trimmed });
244
+ addSeenUrls(givenUrls.request, trimmed);
245
+ };
246
+ const recordAssistantText = (text) => {
247
+ const trimmed = text.trim();
248
+ if (!trimmed)
249
+ return;
250
+ const last = history.at(-1);
251
+ if (last?.role === 'assistant' && typeof last.content === 'string' && !last.tool_calls) {
252
+ last.content = `${last.content}${trimmed}`;
253
+ return;
254
+ }
255
+ history.push({ role: 'assistant', content: trimmed });
256
+ };
257
+ const recordToolSettle = (tool, readBack) => {
258
+ history.push({
259
+ role: 'assistant',
260
+ tool_calls: [
261
+ {
262
+ id: tool.callId,
263
+ type: 'function',
264
+ function: {
265
+ name: tool.name,
266
+ arguments: JSON.stringify(tool.arguments),
267
+ },
268
+ },
269
+ ],
270
+ }, {
271
+ role: 'tool',
272
+ tool_call_id: tool.callId,
273
+ name: tool.name,
274
+ content: readBack,
275
+ });
276
+ addSeenUrls(givenUrls.tools, readBack);
277
+ };
278
+ const enqueuePending = (ev) => {
279
+ pendingHostEvents.push(projectGuardrailTurnEvent(ev, includeMatch));
280
+ const wake = wakeHost;
281
+ wakeHost = undefined;
282
+ wake?.();
283
+ };
284
+ const hostEventQueued = () => pendingHostEvents.length > 0
285
+ ? Promise.resolve('queued')
286
+ : new Promise((resolve) => {
287
+ wakeHost = () => resolve('queued');
288
+ });
289
+ const assertOpen = () => {
290
+ if (closed) {
291
+ throw new TheoremError('request', 'Live session is closed'); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
292
+ }
293
+ };
294
+ const sendJson = (payload) => {
295
+ assertOpen();
296
+ connection.send(payload);
297
+ };
298
+ const answerModel = (callId, held, readBack) => {
299
+ recordToolSettle({ name: held.name, callId, arguments: held.arguments }, readBack);
300
+ sendJson(buildGeminiLiveToolResponse(callId, held.name, readBack));
301
+ };
302
+ const settleHeld = (callId, held, readBack) => {
303
+ clearTimeout(held.lapse);
304
+ calls.delete(callId);
305
+ answerModel(callId, held, readBack);
306
+ };
307
+ /** A released call nobody answered in time: the model reads that its sign-in expired. */
308
+ const lapseReleased = (callId, held) => {
309
+ if (closed || calls.get(callId) !== held || typeof held.state !== 'object')
310
+ return;
311
+ const { gate } = held.state;
312
+ const failure = lapsedGateFailure(held.name, gate.kind === 'auth' ? gate.authChallenge.service : undefined, profile.lexicon);
313
+ const readBack = formatToolResult(formatToolFailureForModel(failure));
314
+ enqueuePending(failureEvent({ name: held.name, callId }, failure, readBack));
315
+ settleHeld(callId, held, readBack);
316
+ };
317
+ /** A closed session answers nothing more. */
318
+ const stopLapses = () => {
319
+ for (const held of calls.values())
320
+ clearTimeout(held.lapse);
321
+ };
322
+ /**
323
+ * A call that ran into `gate`. A sign-in gate this session answers at once tells the model its
324
+ * pending note and releases the call; a call already released stays released. Either waits
325
+ * `gateTtlMs` for its outcome. False: the call is not released, and the caller holds it.
326
+ */
327
+ const releaseGated = (callId, held, wasReleased, gate, readBack) => {
328
+ const answersNow = signInGate === 'answer' && gate.kind === 'auth' && readBack !== undefined;
329
+ if (!answersNow && !wasReleased)
330
+ return false;
331
+ if (answersNow)
332
+ answerModel(callId, held, readBack);
333
+ clearTimeout(held.lapse);
334
+ held.state = { gate, createdAt: Date.now(), released: true };
335
+ held.lapse = setTimeout(() => lapseReleased(callId, held), gateTtlMs);
336
+ return true;
337
+ };
338
+ /**
339
+ * Hold each call the model makes. A call the provider already failed
340
+ * (malformed arguments) is settled here: the model reads its failure. A
341
+ * provider cancel lets go of a call that is not running.
342
+ */
343
+ const holdCalls = (events) => {
344
+ for (const ev of events) {
345
+ if (ev.type !== 'tool')
346
+ continue;
347
+ const tool = ev.tool;
348
+ if (tool.phase === undefined) {
349
+ calls.set(tool.callId, { name: tool.name, arguments: tool.arguments, state: 'open' });
350
+ continue;
351
+ }
352
+ const held = calls.get(tool.callId);
353
+ if (!held)
354
+ continue;
355
+ if (tool.phase === 'error' && tool.readBack !== undefined) {
356
+ settleHeld(tool.callId, held, tool.readBack);
357
+ }
358
+ else if (tool.phase === 'cancel' && held.state !== 'running') {
359
+ calls.delete(tool.callId);
360
+ }
361
+ }
362
+ };
363
+ const closeSocket = (code, reason, initiator) => {
364
+ trace.socketClosed(code, reason, initiator);
365
+ connection.close(code, reason);
366
+ };
367
+ /** A `done` names the response span it ends. */
368
+ const stampDone = (ev) => {
369
+ if (ev.type !== 'done')
370
+ return ev;
371
+ const traceparent = trace.responseTraceparent();
372
+ return traceparent ? { ...ev, traceparent } : ev;
373
+ };
374
+ const runCycleStage = async (stage, extra) => {
375
+ const gen = runStage({
376
+ ...extra,
377
+ stage,
378
+ step: Math.max(1, cycleStep),
379
+ history,
380
+ handlers: onStage ? [onStage] : [],
381
+ guardrails: profile.guardrails,
382
+ injectAllowed: profileAllowsInject(profile),
383
+ host: sessionHost,
384
+ signal,
385
+ span: trace.root,
386
+ });
387
+ let result = await gen.next();
388
+ while (!result.done) {
389
+ enqueuePending(result.value);
390
+ result = await gen.next();
391
+ }
392
+ return {
393
+ abort: result.value.abort,
394
+ inject: result.value.inject,
395
+ };
396
+ };
397
+ const ingestPreparedLiveText = (text) => {
398
+ const start = performance.now();
399
+ const prepared = prepareLiveInboundText(profile, text);
400
+ trace.inboundCheck(performance.now() - start, prepared.guardrail);
401
+ if (prepared.guardrail)
402
+ enqueuePending(prepared.guardrail);
403
+ recordUserText(prepared.text);
404
+ sendJson(buildGeminiLiveRealtimeInput({ type: 'text', text: prepared.text }));
405
+ };
406
+ /**
407
+ * Write each inject whole into the open cycle (no re-entry into pre_turn),
408
+ * then record the named ones that landed. An inject live cannot write as
409
+ * text is refused whole with a stage warning, never written in part.
410
+ */
411
+ const landInject = (stage, units, extra) => {
412
+ const landed = [];
413
+ for (const unit of units) {
414
+ const texts = liveInjectTexts(unit.messages);
415
+ if (!texts) {
416
+ enqueuePending({
417
+ ...stageEventFields(stage, extra),
418
+ stageWarnings: [
419
+ {
420
+ code: 'inject_invalid_messages',
421
+ field: 'inject',
422
+ message: 'live ingress takes plain-text inject messages only; inject refused', // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
423
+ },
424
+ ],
425
+ });
426
+ continue;
427
+ }
428
+ for (const text of texts) {
429
+ assertLiveIngress(profile, 'text');
430
+ ingestPreparedLiveText(text);
431
+ }
432
+ landed.push(unit);
433
+ }
434
+ const event = injectedStageEvent(stage, landed, extra);
435
+ if (event)
436
+ enqueuePending(event);
437
+ };
438
+ /** A stage's `abort` ends the open cycle: a cancelled `done`, then `post_turn`. */
439
+ const cancelCycle = async (abort) => {
440
+ const stop = stageAbortStop(abort);
441
+ // Idle first, so a boundary Gemini sends meanwhile does not end the cycle again.
442
+ cycle = 'idle';
443
+ enqueuePending({ type: 'done', stop, interrupted: true });
444
+ await runCycleStage('post_turn', { stop });
445
+ };
446
+ const openCycleIfNeeded = async () => {
447
+ if (cycle === 'open')
448
+ return { aborted: false };
449
+ cycle = 'open';
450
+ cycleStep += 1;
451
+ const pre = await runCycleStage('pre_turn');
452
+ if (pre.abort) {
453
+ await cancelCycle(pre.abort);
454
+ return { aborted: true };
455
+ }
456
+ landInject('pre_turn', pre.inject);
457
+ return { aborted: false };
458
+ };
459
+ const endCycleAroundDone = async function* (doneEvents) {
460
+ if (cycle !== 'open') {
461
+ for (const ev of doneEvents)
462
+ yield ev;
463
+ return;
464
+ }
465
+ const before = await runCycleStage('before_end', {
466
+ stop: doneEvents.find((e) => e.type === 'done')?.stop,
467
+ });
468
+ if (before.abort) {
469
+ yield { type: 'done', stop: { kind: 'cancelled' }, interrupted: true };
470
+ await runCycleStage('post_turn', { stop: { kind: 'cancelled' } });
471
+ cycle = 'idle';
472
+ return;
473
+ }
474
+ landInject('before_end', before.inject);
475
+ for (const ev of doneEvents) {
476
+ yield ev;
477
+ }
478
+ const terminal = doneEvents.find((e) => e.type === 'done');
479
+ await runCycleStage('post_turn', { stop: terminal?.stop });
480
+ cycle = 'idle';
481
+ };
482
+ const withIngress = (fn) => {
483
+ const next = ingressChain.then(fn, fn);
484
+ ingressChain = next.then(() => undefined, () => undefined);
485
+ return next;
486
+ };
487
+ /**
488
+ * Run a held call through the registry, with stages. A gate holds it for its
489
+ * decision; any other settlement answers the model and lets it go.
490
+ */
491
+ const runHeld = async (callId, held, input, resume, per) => {
492
+ const waiting = held.state;
493
+ const wasReleased = isReleased(held);
494
+ held.state = 'running';
495
+ const host = per.host ?? sessionHost;
496
+ const record = trace.toolRecord(callId);
497
+ const exec = executeRegisteredTool({
498
+ tools: args.tools,
499
+ profile,
500
+ name: held.name,
501
+ input,
502
+ callId,
503
+ ctx: {
504
+ sessionPermissions,
505
+ credentials: per.credentials ?? sessionCredentials,
506
+ resolveHost,
507
+ path,
508
+ signal,
509
+ resume,
510
+ host,
511
+ turn: { step: Math.max(1, cycleStep) },
512
+ },
513
+ snapshot,
514
+ stages: {
515
+ handlers: onStage ? [onStage] : [],
516
+ profile,
517
+ step: Math.max(1, cycleStep),
518
+ history: () => history,
519
+ injectAllowed: profileAllowsInject(profile),
520
+ host,
521
+ signal,
522
+ },
523
+ openSpan: record.open,
524
+ readBack: liveReadBack,
525
+ });
526
+ let s;
527
+ try {
528
+ while (true) {
529
+ const next = await exec.next();
530
+ if (next.done) {
531
+ s = next.value;
532
+ break;
533
+ }
534
+ enqueuePending(next.value);
535
+ }
536
+ }
537
+ catch (err) {
538
+ // It did not settle: it waits as it did, to be run again.
539
+ held.state = waiting;
540
+ throw err;
541
+ }
542
+ finally {
543
+ record.finish();
544
+ }
545
+ if (s.gated) {
546
+ if (!releaseGated(callId, held, wasReleased, s.gated, s.gateReadBack)) {
547
+ held.state = { gate: s.gated, createdAt: Date.now() };
548
+ }
549
+ return { gated: s.gated };
550
+ }
551
+ if (s.aborted) {
552
+ // A stage stopped the call. The model still reads an answer, or it
553
+ // waits for one; then the open cycle ends cancelled, as a turn does.
554
+ const failure = s.callNotStarted
555
+ ? {
556
+ code: 'cancelled',
557
+ kind: 'cancelled',
558
+ message: lexiconText('session.tool_aborted', { tool: held.name }, profile.lexicon),
559
+ }
560
+ : s.failure;
561
+ if (s.callNotStarted && failure) {
562
+ const readBack = formatToolResult(formatToolFailureForModel(failure));
563
+ enqueuePending(failureEvent({ name: held.name, callId }, failure, readBack));
564
+ settleHeld(callId, held, readBack);
565
+ }
566
+ else {
567
+ const output = liveToolOutput(s);
568
+ if (output === undefined)
569
+ calls.delete(callId);
570
+ else
571
+ settleHeld(callId, held, output);
572
+ }
573
+ const { aborted } = s;
574
+ await withIngress(async () => {
575
+ if (cycle === 'open')
576
+ await cancelCycle(aborted);
577
+ });
578
+ return {
579
+ outputRaw: s.outputRaw,
580
+ outputModel: s.modelResult,
581
+ failure,
582
+ awaiting: s.awaiting,
583
+ };
584
+ }
585
+ const { pendingInject } = s;
586
+ if (pendingInject) {
587
+ await withIngress(async () => {
588
+ const opened = await openCycleIfNeeded();
589
+ if (opened.aborted)
590
+ return;
591
+ landInject('post_tool', pendingInject, { callId, toolName: held.name });
592
+ });
593
+ }
594
+ const output = liveToolOutput(s);
595
+ if (output === undefined)
596
+ calls.delete(callId);
597
+ else
598
+ settleHeld(callId, held, output);
599
+ return {
600
+ outputRaw: s.outputRaw,
601
+ outputModel: s.modelResult,
602
+ failure: s.failure,
603
+ awaiting: s.awaiting,
604
+ };
605
+ };
606
+ const gateExpiredError = (callId) =>
607
+ // lexicon-exempt: developer contract / internal diagnostic — the user reads session.gate_expired
608
+ new TheoremError('request', `gate ${callId} expired`, {
609
+ copy: { key: 'session.gate_expired' },
610
+ });
611
+ const gateLapsed = (held) => typeof held.state === 'object' && gateExpired(held.state.createdAt, Date.now(), gateTtlMs);
612
+ /**
613
+ * The held call `callId`, when it can run now. A gate that waited past
614
+ * `gateTtlMs` is settled (a held one as abandoned, a released one as lapsed;
615
+ * the model reads that), then refused.
616
+ */
617
+ const takeHeld = async (callId) => {
618
+ const held = calls.get(callId);
619
+ if (!held || held.state === 'running') {
620
+ throw new TheoremError('request', `call ${callId} is not waiting to run`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
621
+ }
622
+ if (gateLapsed(held)) {
623
+ if (isReleased(held))
624
+ lapseReleased(callId, held);
625
+ else
626
+ await runHeld(callId, held, held.arguments, resumeForAnswer({ decision: 'abandon' }), {});
627
+ throw gateExpiredError(callId);
628
+ }
629
+ return held;
630
+ };
631
+ const deliverBatch = async function* (item) {
632
+ holdCalls(item.events);
633
+ // Usage is held per response and emitted once, reported or estimated, by `settle`.
634
+ const hostEvents = hostEventsOf(item.events.filter((ev) => ev.type !== 'tokens'), snapshot);
635
+ const gateStart = performance.now();
636
+ const gated = await applyOutbound(gate, hostEvents, item.turnPhase, () => {
637
+ withholdClose = true;
638
+ });
639
+ // An abort only drops what the gate held; there is no check to time.
640
+ if (item.turnPhase !== 'abort')
641
+ trace.outboundTime(performance.now() - gateStart);
642
+ for (const ev of gated) {
643
+ if (ev.type === 'guardrail')
644
+ trace.outbound(ev);
645
+ }
646
+ const doneBatch = yield* yieldLiveNonDoneEvents(gated, includeMatch, recordAssistantText);
647
+ const tokens = await trace.settle();
648
+ if (tokens)
649
+ yield tokens;
650
+ const interrupted = doneBatch.some((ev) => ev.type === 'done' && ev.interrupted);
651
+ const completeBoundary = item.turnPhase === 'complete' || item.turnPhase === 'abort' || doneBatch.length > 0;
652
+ // Boundary batches (`interactionStatus: IDLE`, or bare `turnComplete` when the
653
+ // provider sends no status) often have no folded `done` — still end the cycle.
654
+ if (completeBoundary && cycle === 'open') {
655
+ const boundaryDone = boundaryDoneEvents(doneBatch, item.turnPhase, interrupted);
656
+ for await (const ev of endCycleAroundDone(boundaryDone)) {
657
+ yield projectGuardrailTurnEvent(stampDone(ev), includeMatch);
658
+ }
659
+ yield* drainPendingHostEvents(pendingHostEvents);
660
+ }
661
+ else if (doneBatch.length > 0) {
662
+ for (const ev of doneBatch) {
663
+ yield projectGuardrailTurnEvent(stampDone(ev), includeMatch);
664
+ }
665
+ }
666
+ };
667
+ const streamToHost = async function* () {
668
+ // Who closes the socket when the loop ends: the host, unless THEOREM stops it.
669
+ let closer = 'host';
670
+ let thrown;
671
+ const provider = connection.batches();
672
+ // The batch being awaited; it stays pending across wakes, so no frame is read twice.
673
+ let nextBatch;
674
+ try {
675
+ while (true) {
676
+ nextBatch ??= provider.next();
677
+ // A tool the host ran, or a stage the session fired, reaches the host
678
+ // now: a model waiting on a call's result sends nothing meanwhile.
679
+ const woke = await Promise.race([nextBatch, hostEventQueued()]);
680
+ throwIfAborted(signal);
681
+ if (woke === 'queued') {
682
+ yield* drainPendingHostEvents(pendingHostEvents);
683
+ continue;
684
+ }
685
+ nextBatch = undefined;
686
+ if (woke.done)
687
+ break;
688
+ const item = woke.value;
689
+ trace.receive(item);
690
+ yield* drainPendingHostEvents(pendingHostEvents);
691
+ if (item.type === 'closed') {
692
+ if (item.goAway)
693
+ yield sessionEndedEvent(item, item.goAway, profile.lexicon);
694
+ else if (item.error)
695
+ yield toErrorEvent(item.error);
696
+ break;
697
+ }
698
+ if (item.type === 'error') {
699
+ closer = 'theorem';
700
+ yield toErrorEvent(item.error);
701
+ break;
702
+ }
703
+ if (item.type === 'row') {
704
+ continue;
705
+ }
706
+ yield* deliverBatch(item);
707
+ if (withholdClose) {
708
+ closer = 'theorem';
709
+ break;
710
+ }
711
+ }
712
+ yield* drainPendingHostEvents(pendingHostEvents);
713
+ }
714
+ catch (err) {
715
+ thrown = err;
716
+ throw err;
717
+ }
718
+ finally {
719
+ closed = true;
720
+ stopLapses();
721
+ if (withholdClose)
722
+ closeSocket(1011, 'guardrail withheld', closer);
723
+ else
724
+ closeSocket(1000, 'session-closed', closer);
725
+ // The socket is closed, so a batch still awaited resolves and the provider can finish.
726
+ await provider.return(undefined);
727
+ await trace.close({ thrown });
728
+ }
729
+ };
730
+ const session = {
731
+ profileId: profile.id,
732
+ canary,
733
+ async *events() {
734
+ for await (const raw of streamToHost()) {
735
+ const event = withPublicWording(raw, profile.lexicon);
736
+ trace.delivered(event);
737
+ yield event;
738
+ }
739
+ },
740
+ sendAudio(audio) {
741
+ return withIngress(async () => {
742
+ if (!audio.data)
743
+ return;
744
+ assertLiveIngress(profile, 'audio');
745
+ const opened = await openCycleIfNeeded();
746
+ if (opened.aborted)
747
+ return;
748
+ sendJson(buildGeminiLiveRealtimeInput({
749
+ type: 'audio',
750
+ mimeType: audio.mimeType,
751
+ data: audio.data,
752
+ }));
753
+ });
754
+ },
755
+ sendVideo(video) {
756
+ return withIngress(async () => {
757
+ assertLiveIngress(profile, 'video');
758
+ const opened = await openCycleIfNeeded();
759
+ if (opened.aborted)
760
+ return;
761
+ sendJson(buildGeminiLiveRealtimeInput({
762
+ type: 'video',
763
+ mimeType: video.mimeType,
764
+ data: video.data,
765
+ }));
766
+ });
767
+ },
768
+ sendText(text) {
769
+ return withIngress(async () => {
770
+ assertLiveIngress(profile, 'text');
771
+ const opened = await openCycleIfNeeded();
772
+ if (opened.aborted)
773
+ return;
774
+ ingestPreparedLiveText(text);
775
+ });
776
+ },
777
+ sendContext(text) {
778
+ return withIngress(() => {
779
+ assertLiveIngress(profile, 'text');
780
+ const start = performance.now();
781
+ const prepared = prepareLiveInboundText(profile, text);
782
+ trace.inboundCheck(performance.now() - start, prepared.guardrail);
783
+ if (prepared.guardrail)
784
+ enqueuePending(prepared.guardrail);
785
+ sendJson(buildGeminiLiveContext(prepared.text));
786
+ return Promise.resolve();
787
+ });
788
+ },
789
+ async executeTool({ callId, decision, input, secret, credentials, host, }) {
790
+ assertOpen();
791
+ const held = await takeHeld(callId);
792
+ const gate = typeof held.state === 'object' ? held.state.gate : undefined;
793
+ if (!gate) {
794
+ if (decision !== undefined || input !== undefined || secret !== undefined) {
795
+ throw new TheoremError('request', `call ${callId} is not waiting on a gate; it takes no decision, input or secret`);
796
+ }
797
+ return await runHeld(callId, held, held.arguments, undefined, { credentials, host });
798
+ }
799
+ if (decision === undefined) {
800
+ throw new TheoremError('request', `call ${callId} is waiting on a gate; answer it with a decision`);
801
+ }
802
+ const answered = answerGatedCall({ callId, decision, input, secret }, {
803
+ name: held.name,
804
+ arguments: held.arguments,
805
+ permission: gate.permission,
806
+ ...(gate.kind === 'auth' ? { auth: gate.authChallenge } : {}),
807
+ }, sessionPermissions ?? []);
808
+ if (answered.typed) {
809
+ await (credentials ?? sessionCredentials).set(answered.typed.slot, answered.typed.credential);
810
+ }
811
+ sessionPermissions = answered.sessionPermissions;
812
+ return await runHeld(callId, held, answered.input, answered.resume, {
813
+ credentials,
814
+ host,
815
+ });
816
+ },
817
+ answerToolCall({ callId, events }) {
818
+ assertOpen();
819
+ const held = calls.get(callId);
820
+ if (!held || (held.state !== 'open' && !isReleased(held))) {
821
+ throw new TheoremError('request', `call ${callId} is not waiting for an answer`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
822
+ }
823
+ if (gateLapsed(held)) {
824
+ lapseReleased(callId, held);
825
+ throw gateExpiredError(callId);
826
+ }
827
+ let settled;
828
+ for (const ev of events) {
829
+ if (ev.type !== 'tool')
830
+ continue;
831
+ if (ev.tool.phase === undefined || ev.tool.callId !== callId) {
832
+ throw new TheoremError('request', `the run answering call ${callId} carries a call of its own (${ev.tool.callId})`);
833
+ }
834
+ if (isSettledPhase(ev.tool))
835
+ settled = ev.tool;
836
+ }
837
+ if (!settled) {
838
+ throw new TheoremError('request', `the run answering call ${callId} settled nothing`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
839
+ }
840
+ const forward = () => {
841
+ for (const ev of events) {
842
+ if (ev.type !== 'done')
843
+ enqueuePending(ev);
844
+ }
845
+ };
846
+ if (settled.phase === 'gate') {
847
+ forward();
848
+ releaseGated(callId, held, isReleased(held), settled.gate, settled.readBack);
849
+ return { gated: settled.gate };
850
+ }
851
+ const { readBack } = settled;
852
+ if (readBack === undefined) {
853
+ throw new TheoremError('request', `the run answering call ${callId} carries no readBack`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
854
+ }
855
+ forward();
856
+ settleHeld(callId, held, readBack);
857
+ return settled.phase === 'complete'
858
+ ? { outputRaw: settled.output, ...(settled.awaiting ? { awaiting: true } : {}) }
859
+ : { failure: settled.failure };
860
+ },
861
+ close(reason = 'session-closed') {
862
+ if (!closed) {
863
+ closed = true;
864
+ stopLapses();
865
+ closeSocket(1000, reason, 'host');
866
+ }
867
+ // The session record is sealed here; frames the host reads after closing are not in it.
868
+ return trace.close({});
869
+ },
870
+ };
871
+ if (args.openInitialCycle) {
872
+ void withIngress(async () => {
873
+ await openCycleIfNeeded();
874
+ });
875
+ }
876
+ return session;
877
+ }
878
+ /**
879
+ * The session record is written however the session ends, including when opening fails. An unknown
880
+ * profile fails to open and is recorded under the standard observability policy.
881
+ */
882
+ export async function runSessionInRegistry(registry, req, options, sinkOverride) {
883
+ const trace = startLiveTrace(req, registry.profiles.find(req.profile)?.observability, sinkOverride);
884
+ try {
885
+ return await openTracedSession(registry, req, options, trace);
886
+ }
887
+ catch (err) {
888
+ await trace.close({ thrown: err });
889
+ throw err;
890
+ }
891
+ }
892
+ async function openTracedSession(registry, req, options, trace) {
893
+ const gateTtlMs = resolveGateTtlMs('runSession', options.gateTtlMs);
894
+ const turnReq = toTurnRequest(req);
895
+ const safe = sanitizeTurnRequest(turnReq, registry.profiles.get(turnReq.profile));
896
+ throwIfAborted(safe.signal);
897
+ const { profile, generation: gen0 } = resolveTurnInRegistry(registry, safe);
898
+ assertLiveProfile(profile);
899
+ if (req.snapshot) {
900
+ gen0.tools = sessionSnapshotWithinAllow(profile, req.snapshot);
901
+ }
902
+ gen0.builtins = gen0.tools.builtins;
903
+ let generation = applyVoiceOverride(gen0, req.voice);
904
+ const hasInitialInput = Boolean(req.input && req.input.length > 0);
905
+ generation = applyInitialInput(generation, req.input);
906
+ const system = bindSystem(generation.resolvedSystem, [
907
+ canaryNote(generation.canary, profile.lexicon),
908
+ userDataNote(profile.lexicon),
909
+ ]);
910
+ const completeReq = {
911
+ ...providerCompleteRequest(registry.tools, generation, system.text),
912
+ signal: safe.signal,
913
+ tapUpstream: trace.sent,
914
+ };
915
+ const binding = profile.models[generation.model];
916
+ trace.bind({
917
+ request: completeReq,
918
+ generation,
919
+ binding,
920
+ family: binding ? mediaTokenFamily(binding) : undefined,
921
+ system: system.text,
922
+ canary: generation.canary,
923
+ });
924
+ const givenUrls = givenUrlSets();
925
+ addRequestUrls(givenUrls, completeReq);
926
+ addHistoryUrls(givenUrls, req.history ?? []);
927
+ const gate = createLiveOutboundGateSession(profile, generation.canary || undefined, system.private, givenUrls);
928
+ const connection = await openGoogleLiveSession(completeReq, { ...options.gemini, vault: options.vault }, options.openWebSocket);
929
+ trace.setup(connection.setup);
930
+ return buildLiveSession({
931
+ tools: registry.tools,
932
+ profile,
933
+ canary: generation.canary,
934
+ connection,
935
+ gate,
936
+ givenUrls,
937
+ signal: safe.signal,
938
+ onStage: req.onStage,
939
+ host: req.host,
940
+ credentials: req.credentials,
941
+ resolveHost: req.resolveHost,
942
+ sessionPermissions: req.sessionPermissions,
943
+ path: req.path,
944
+ snapshot: gen0.tools,
945
+ historySeed: req.history,
946
+ openInitialCycle: hasInitialInput,
947
+ trace,
948
+ gateTtlMs,
949
+ signInGate: options.signInGate ?? 'hold',
950
+ });
951
+ }