@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,115 @@
1
+ import type { TraceSink } from '../../../observability/trace-sink.js';
2
+ import { type SpanHandle, type TraceAttributes, type TraceTree } from '../../../observability/trace-span.js';
3
+ import type { ProfileObservabilitySpec, ResolvedObservabilityPolicy } from '../../../observability/types.js';
4
+ import type { SessionQueueItem } from '../../../providers/google/live/stream.js';
5
+ import type { TurnEventOf } from '../../turn-events.js';
6
+ import type { ModelBinding, ProviderCompleteRequest, ResolvedGeneration, SessionRequest, TurnEvent } from '../../types.js';
7
+ import type { MediaTokenFamily } from '../token-estimate.js';
8
+ type LiveCloser = 'host' | 'provider' | 'theorem';
9
+ interface LiveTraceBinding {
10
+ request: ProviderCompleteRequest;
11
+ generation: ResolvedGeneration;
12
+ binding: ModelBinding | undefined;
13
+ family: MediaTokenFamily | undefined;
14
+ /** The system prompt as sent, canary bound. */
15
+ system: string;
16
+ canary: string;
17
+ }
18
+ interface LiveTraceEnd {
19
+ /** Thrown out of the session (an abort is recorded as cancelled). */
20
+ thrown?: unknown;
21
+ }
22
+ declare class LiveTrace {
23
+ private readonly tree;
24
+ private readonly out;
25
+ private readonly identity;
26
+ readonly root: SpanHandle;
27
+ private bound?;
28
+ private response?;
29
+ private lastResponse?;
30
+ private pendingFrames;
31
+ private pendingInput;
32
+ private pendingHeard;
33
+ /** What the provider holds from answered responses, for estimating unreported usage. */
34
+ private held?;
35
+ private readonly tokens;
36
+ private responses;
37
+ private readonly callParents;
38
+ private writes;
39
+ private failure?;
40
+ /** The provider closed the session after warning it would (`goAway`). */
41
+ private endedByGoAway;
42
+ private socketHasClosed;
43
+ private closing?;
44
+ constructor(tree: TraceTree, out: {
45
+ sink: TraceSink;
46
+ policy: ResolvedObservabilityPolicy;
47
+ metadata?: Record<string, unknown>;
48
+ }, identity: TraceAttributes);
49
+ /** Attach the resolved request; frames are recorded from here on. */
50
+ bind(binding: LiveTraceBinding): void;
51
+ /** The adapter's `tapUpstream`: every frame sent, as it is sent. */
52
+ readonly sent: (row: Record<string, unknown>) => void;
53
+ /** The pinned key was refused for quota at setup; the session reopens on the fallback slot, which its responses name. */
54
+ private keyFallback;
55
+ setup(frame: Record<string, unknown>): void;
56
+ /** One received queue item, before guardrails. */
57
+ receive(item: SessionQueueItem): void;
58
+ /**
59
+ * One event as the host received it. Output reaches the host only after
60
+ * `receive` opened its response, so every output part lands on the open one;
61
+ * a transcript of the user's speech is input, recorded where it was heard.
62
+ */
63
+ delivered(event: TurnEvent): void;
64
+ /** A guardrail decision on the model's output: on the open response. */
65
+ outbound(event: TurnEventOf<'guardrail'>): void;
66
+ /** A guardrail decision on the session (inbound text): on the session span. */
67
+ inbound(event: TurnEventOf<'guardrail'>): void;
68
+ /** One run of the gate on the model's output, on the open response: a decision after it is its. */
69
+ outboundTime(ms: number): void;
70
+ /** The check on text the host sent into the session, pass or decision, with its time. */
71
+ inboundCheck(ms: number, event: TurnEventOf<'guardrail'> | undefined): void;
72
+ /**
73
+ * Record the socket closing; the first close is the one that ended the
74
+ * session. A provider close carries its warning (`goAway`) and what the code
75
+ * means as a failure, so a warned close stays fully diagnosable.
76
+ */
77
+ socketClosed(code: number, reason: string, initiator: LiveCloser, provider?: Extract<SessionQueueItem, {
78
+ type: 'closed';
79
+ }>): void;
80
+ /**
81
+ * Close the response whose `turnComplete` arrived and write its record.
82
+ * Returns its one `tokens` event, reported or estimated.
83
+ */
84
+ settle(): Promise<TurnEvent | undefined>;
85
+ /** The span a `done` ends: the open response, else the last one. */
86
+ responseTraceparent(): string | undefined;
87
+ /**
88
+ * Open the record for one `executeTool` call, under the response that asked
89
+ * for it (the session when the call id is unknown). `finish` writes it.
90
+ */
91
+ toolRecord(callId: string): {
92
+ open: (name: string, attributes: TraceAttributes) => SpanHandle;
93
+ finish: () => void;
94
+ };
95
+ /** End the session: close what is open, write the session record, wait for every write. */
96
+ close(end: LiveTraceEnd): Promise<void>;
97
+ private finish;
98
+ private route;
99
+ private row;
100
+ private open;
101
+ /**
102
+ * Close the open response and write its record. A response ended by the
103
+ * session closing has no usage event: what was billed is unknown.
104
+ */
105
+ private endResponse;
106
+ /** Build and write one record, after every earlier write. */
107
+ private write;
108
+ }
109
+ /**
110
+ * Open a session's trace: its `invoke_agent` span under the host's `traceparent`,
111
+ * written under `observability`, the session's profile's block.
112
+ */
113
+ declare function startLiveTrace(req: SessionRequest, observability: ProfileObservabilitySpec | undefined, sinkOverride?: TraceSink): LiveTrace;
114
+ export type { LiveCloser, LiveTrace, LiveTraceBinding, LiveTraceEnd };
115
+ export { startLiveTrace };
@@ -0,0 +1,489 @@
1
+ import { errorKind, isAbortError, TheoremError } from '../../../guardrails/error.js';
2
+ import { resolveTraceWriter } from '../../../observability/policy.js';
3
+ import { writeTrace } from '../../../observability/trace.js';
4
+ import { buildRecord } from '../../../observability/trace-record.js';
5
+ import { startTrace, traceJson, } from '../../../observability/trace-span.js';
6
+ import { liveFrameInput } from '../../../providers/google/live/framing.js';
7
+ import { LIVE_FALLBACK_ROW } from '../../../providers/google/live/session.js';
8
+ import { base64ToBytes, bytesToBase64 } from '../../util/base64.js';
9
+ import { asRecord } from '../record.js';
10
+ import { callTokensEvent, heldAfter, observeCallEvent, startCallUsage, } from '../runner/usage.js';
11
+ import { endThrownSpan, guardrailAttributes, guardrailCheckAttributes, OutputFold, optional, startCallTrace, traceLinks, usageAttributes, } from '../turn-trace.js';
12
+ import { sumTokens } from '../usage.js';
13
+ /** Events that are the model's output: they mark a response as answering. */
14
+ const OUTPUT_EVENTS = new Set(['text', 'thought', 'media', 'tool']);
15
+ const MS_PER_S = 1000;
16
+ /** One user message holding exactly one inline audio part: a realtime audio chunk. */
17
+ function audioChunk(msg) {
18
+ const [part, ...rest] = msg.parts ?? [];
19
+ if (msg.role !== 'user' || msg.content || rest.length > 0)
20
+ return undefined;
21
+ return part?.type === 'audio' && 'data' in part ? part : undefined;
22
+ }
23
+ /** A run's chunks as one part over their concatenated bytes; one part each when any is not base64. */
24
+ function audioRunParts(run) {
25
+ try {
26
+ const decoded = run.chunks.map(base64ToBytes);
27
+ const merged = new Uint8Array(decoded.reduce((size, bytes) => size + bytes.byteLength, 0));
28
+ let offset = 0;
29
+ for (const bytes of decoded) {
30
+ merged.set(bytes, offset);
31
+ offset += bytes.byteLength;
32
+ }
33
+ return [{ type: 'audio', mimeType: run.mimeType, data: bytesToBase64(merged) }];
34
+ }
35
+ catch {
36
+ // Not base64: keep each chunk as sent, so the record labels what it holds.
37
+ return run.chunks.map((data) => ({ type: 'audio', mimeType: run.mimeType, data }));
38
+ }
39
+ }
40
+ /**
41
+ * Input sent since the previous response opened; a tool response is input to the response after the
42
+ * one that asked. Never the whole session: under sliding-window compression what the model read of
43
+ * it is unknowable. Contiguous audio of one format is one message.
44
+ */
45
+ class LiveInput {
46
+ items = [];
47
+ run;
48
+ add(messages) {
49
+ for (const msg of messages) {
50
+ const chunk = audioChunk(msg);
51
+ if (chunk && this.run?.mimeType === chunk.mimeType) {
52
+ this.run.chunks.push(chunk.data);
53
+ continue;
54
+ }
55
+ this.run = chunk ? { mimeType: chunk.mimeType, chunks: [chunk.data] } : undefined;
56
+ this.items.push(this.run ?? msg);
57
+ }
58
+ }
59
+ messages() {
60
+ return this.items.map((item) => 'chunks' in item ? { role: 'user', parts: audioRunParts(item) } : item);
61
+ }
62
+ }
63
+ /** A frame without its resumption handle: the handle is a credential. */
64
+ function withoutHandle(frame) {
65
+ const setup = asRecord(frame.setup);
66
+ const resumption = asRecord(setup?.sessionResumption);
67
+ if (setup && resumption && 'handle' in resumption) {
68
+ const { handle: _handle, ...rest } = resumption;
69
+ return { ...frame, setup: { ...setup, sessionResumption: rest } };
70
+ }
71
+ const update = asRecord(frame.sessionResumptionUpdate);
72
+ if (update && 'newHandle' in update) {
73
+ const { newHandle: _newHandle, ...rest } = update;
74
+ return { ...frame, sessionResumptionUpdate: rest };
75
+ }
76
+ return frame;
77
+ }
78
+ function stringAttribute(key, value) {
79
+ return typeof value === 'string' ? { [key]: value } : {};
80
+ }
81
+ /** A provider session signal as `theorem.session` attributes, or `undefined` for a response event. */
82
+ function sessionSignal(event) {
83
+ if (event.type === 'session') {
84
+ const { session } = event;
85
+ if (session.kind === 'turn_complete')
86
+ return undefined;
87
+ return {
88
+ kind: session.kind,
89
+ ...('timeLeftMs' in session ? optional('time_left_ms', session.timeLeftMs) : {}),
90
+ };
91
+ }
92
+ if (event.type !== 'evidence')
93
+ return undefined;
94
+ const { evidence } = event;
95
+ if (evidence.kind === 'voice_activity') {
96
+ const raw = asRecord(evidence.raw);
97
+ return {
98
+ kind: 'voice_activity',
99
+ ...stringAttribute('activity', raw?.type),
100
+ ...stringAttribute('audio_offset', raw?.audioOffset),
101
+ };
102
+ }
103
+ if (evidence.kind === 'session_resumption') {
104
+ return {
105
+ kind: 'session_resumption',
106
+ ...optional('resumable', evidence.resumable),
107
+ handle_issued: Boolean(event.sessionResumptionHandle),
108
+ };
109
+ }
110
+ return undefined;
111
+ }
112
+ // Each record is written as soon as it is complete, so a long session never holds its whole trace.
113
+ class LiveTrace {
114
+ tree;
115
+ out;
116
+ identity;
117
+ root;
118
+ bound;
119
+ response;
120
+ lastResponse;
121
+ pendingFrames = [];
122
+ pendingInput = new LiveInput();
123
+ pendingHeard = [];
124
+ /** What the provider holds from answered responses, for estimating unreported usage. */
125
+ held;
126
+ tokens = [];
127
+ responses = 0;
128
+ callParents = new Map();
129
+ writes = Promise.resolve();
130
+ failure;
131
+ /** The provider closed the session after warning it would (`goAway`). */
132
+ endedByGoAway = false;
133
+ socketHasClosed = false;
134
+ closing;
135
+ constructor(tree, out, identity) {
136
+ this.tree = tree;
137
+ this.out = out;
138
+ this.identity = identity;
139
+ this.root = tree.root;
140
+ }
141
+ /** Attach the resolved request; frames are recorded from here on. */
142
+ bind(binding) {
143
+ this.bound = binding;
144
+ }
145
+ /** The adapter's `tapUpstream`: every frame sent, as it is sent. */
146
+ sent = (row) => {
147
+ if (row.eventType === LIVE_FALLBACK_ROW) {
148
+ this.keyFallback(row);
149
+ return;
150
+ }
151
+ const frame = asRecord(row.body);
152
+ if (!frame)
153
+ return;
154
+ const body = withoutHandle(frame);
155
+ if ('setup' in frame) {
156
+ this.root.event('theorem.wire.request', { body: traceJson(body) });
157
+ return;
158
+ }
159
+ this.pendingInput.add(liveFrameInput(frame));
160
+ this.pendingFrames.push({ timeUnixNano: this.root.nowUnixNano(), body });
161
+ };
162
+ /** The pinned key was refused for quota at setup; the session reopens on the fallback slot, which its responses name. */
163
+ keyFallback(row) {
164
+ const to = String(row.keySlot);
165
+ this.root.event('theorem.session', {
166
+ kind: 'key_fallback',
167
+ key_slot: String(row.from),
168
+ to_key_slot: to,
169
+ 'error.type': String(row.errorKind),
170
+ error: String(row.error),
171
+ });
172
+ const bound = this.bound;
173
+ if (bound)
174
+ this.bound = { ...bound, request: { ...bound.request, keySlot: to } };
175
+ }
176
+ setup(frame) {
177
+ this.root.event('theorem.upstream.row', { row: traceJson(frame) });
178
+ this.root.event('theorem.session', { kind: 'setup_complete' });
179
+ }
180
+ /** One received queue item, before guardrails. */
181
+ receive(item) {
182
+ switch (item.type) {
183
+ case 'batch':
184
+ for (const event of item.events)
185
+ this.route(event);
186
+ this.row(item.row);
187
+ return;
188
+ case 'row':
189
+ this.row(item.row);
190
+ return;
191
+ case 'error':
192
+ if (item.row)
193
+ this.row(item.row);
194
+ this.failure ??= item.error;
195
+ return;
196
+ case 'closed':
197
+ this.socketClosed(item.code, item.reason, 'provider', item);
198
+ // A close the provider warned of ends the session; it is not the session's failure.
199
+ if (item.goAway)
200
+ this.endedByGoAway = true;
201
+ else
202
+ this.failure ??= item.error;
203
+ return;
204
+ }
205
+ }
206
+ /**
207
+ * One event as the host received it. Output reaches the host only after
208
+ * `receive` opened its response, so every output part lands on the open one;
209
+ * a transcript of the user's speech is input, recorded where it was heard.
210
+ */
211
+ delivered(event) {
212
+ if (event.type === 'evidence' && event.evidence.kind === 'input_transcription')
213
+ return;
214
+ this.response?.delivered.add(event, this.root.nowUnixNano());
215
+ }
216
+ /** A guardrail decision on the model's output: on the open response. */
217
+ outbound(event) {
218
+ if (this.response)
219
+ this.response.call.guardrail(event.guardrail);
220
+ else
221
+ this.inbound(event);
222
+ }
223
+ /** A guardrail decision on the session (inbound text): on the session span. */
224
+ inbound(event) {
225
+ this.root.event('theorem.guardrail', guardrailAttributes(event.guardrail));
226
+ }
227
+ /** One run of the gate on the model's output, on the open response: a decision after it is its. */
228
+ outboundTime(ms) {
229
+ this.response?.call.guardTime('live_output', ms);
230
+ }
231
+ /** The check on text the host sent into the session, pass or decision, with its time. */
232
+ inboundCheck(ms, event) {
233
+ this.root.event('theorem.guardrail', guardrailCheckAttributes('live_input', ms, event?.guardrail, {
234
+ stage: 'live_inbound',
235
+ trust: 'untrusted',
236
+ }));
237
+ }
238
+ /**
239
+ * Record the socket closing; the first close is the one that ended the
240
+ * session. A provider close carries its warning (`goAway`) and what the code
241
+ * means as a failure, so a warned close stays fully diagnosable.
242
+ */
243
+ socketClosed(code, reason, initiator, provider) {
244
+ if (this.socketHasClosed)
245
+ return;
246
+ this.socketHasClosed = true;
247
+ const goAway = provider?.goAway;
248
+ this.root.event('theorem.session', {
249
+ kind: 'closed',
250
+ code,
251
+ reason,
252
+ initiator,
253
+ ...(provider?.error ? { 'error.type': errorKind(provider.error) } : {}),
254
+ ...(goAway
255
+ ? {
256
+ cause: 'go_away',
257
+ ...optional('time_left_ms', goAway.timeLeftMs),
258
+ closed_after_ms: goAway.closedAfterMs,
259
+ }
260
+ : {}),
261
+ });
262
+ }
263
+ /**
264
+ * Close the response whose `turnComplete` arrived and write its record.
265
+ * Returns its one `tokens` event, reported or estimated.
266
+ */
267
+ async settle() {
268
+ return this.response?.complete ? await this.endResponse({}) : undefined;
269
+ }
270
+ /** The span a `done` ends: the open response, else the last one. */
271
+ responseTraceparent() {
272
+ return (this.response?.call.span ?? this.lastResponse)?.traceparent();
273
+ }
274
+ /**
275
+ * Open the record for one `executeTool` call, under the response that asked
276
+ * for it (the session when the call id is unknown). `finish` writes it.
277
+ */
278
+ toolRecord(callId) {
279
+ let tree;
280
+ return {
281
+ open: (name, attributes) => {
282
+ tree = startTrace(name, {
283
+ attributes: { ...this.identity, ...attributes },
284
+ traceparent: this.callParents.get(callId) ?? this.root.traceparent(),
285
+ clock: this.tree.clock,
286
+ });
287
+ return tree.root;
288
+ },
289
+ finish: () => {
290
+ if (tree)
291
+ this.write(tree.collect());
292
+ },
293
+ };
294
+ }
295
+ /** End the session: close what is open, write the session record, wait for every write. */
296
+ close(end) {
297
+ this.closing ??= this.finish(end);
298
+ return this.closing;
299
+ }
300
+ async finish(end) {
301
+ const aborted = end.thrown !== undefined && isAbortError(end.thrown);
302
+ const thrown = aborted ? undefined : (end.thrown ?? this.failure);
303
+ if (this.response) {
304
+ await this.endResponse(thrown === undefined ? { cancelled: true } : { thrown });
305
+ }
306
+ // Sent after the last response: no response read it.
307
+ for (const frame of this.pendingFrames) {
308
+ this.root.event('theorem.wire.request', { body: traceJson(frame.body) }, frame.timeUnixNano);
309
+ }
310
+ this.pendingFrames = [];
311
+ const tokens = sumTokens(this.tokens);
312
+ this.root.set({
313
+ ...(tokens ? usageAttributes(tokens) : {}),
314
+ 'theorem.steps': this.responses,
315
+ ...(aborted ? { 'theorem.stop.kind': 'cancelled' } : {}),
316
+ ...(!aborted && this.endedByGoAway ? { 'theorem.stop.kind': 'go_away' } : {}),
317
+ });
318
+ if (thrown !== undefined) {
319
+ endThrownSpan(this.root, thrown);
320
+ }
321
+ else {
322
+ // A warned close is no verdict: neither failed nor known to be fine.
323
+ this.root.end(aborted || this.endedByGoAway ? { code: 'UNSET' } : { code: 'OK' });
324
+ }
325
+ this.write(this.tree.collect());
326
+ await this.writes;
327
+ }
328
+ route(event) {
329
+ const signal = sessionSignal(event);
330
+ if (signal) {
331
+ this.root.event('theorem.session', signal);
332
+ return;
333
+ }
334
+ if (event.type === 'tool' && event.tool.phase === 'cancel') {
335
+ (this.response?.call.span ?? this.root).event('theorem.tool.cancel', {
336
+ 'gen_ai.tool.call.id': event.tool.callId,
337
+ 'gen_ai.tool.name': event.tool.name,
338
+ });
339
+ return;
340
+ }
341
+ const kind = event.type === 'evidence' ? event.evidence.kind : undefined;
342
+ if (kind === 'input_transcription' && !(this.response && !this.response.answering)) {
343
+ // Heard after the model began answering: input for the next response.
344
+ this.pendingHeard.push(event);
345
+ return;
346
+ }
347
+ const response = this.open();
348
+ if (event.type === 'session') {
349
+ response.complete = true;
350
+ return;
351
+ }
352
+ observeCallEvent(response.usage, event);
353
+ response.call.observe(event);
354
+ if (!response.answering && (OUTPUT_EVENTS.has(event.type) || kind === 'output_transcription')) {
355
+ // The reply's first chunk, from the response's first input frame: what a person waited.
356
+ response.call.span.set({
357
+ 'gen_ai.response.time_to_first_chunk': response.call.span.msSinceStart() / MS_PER_S,
358
+ });
359
+ response.answering = true;
360
+ }
361
+ if (event.type === 'tool' && event.tool.phase === undefined) {
362
+ this.callParents.set(event.tool.callId, response.call.span.traceparent());
363
+ }
364
+ if (event.type === 'done' && response.stop?.kind !== 'interrupted') {
365
+ response.stop = event.stop;
366
+ }
367
+ }
368
+ row(row) {
369
+ const span = this.response?.call.span ?? this.root;
370
+ span.event('theorem.upstream.row', { row: traceJson(withoutHandle(row)) });
371
+ }
372
+ open() {
373
+ if (this.response)
374
+ return this.response;
375
+ const bound = this.bound;
376
+ if (!bound) {
377
+ // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
378
+ throw new TheoremError('internal', 'Live trace received a response before it was bound');
379
+ }
380
+ const usage = startCallUsage(bound.system, { history: [], input: [] }, this.held);
381
+ // A response starts at its first input frame, so its duration includes the model's listening time.
382
+ const startTimeUnixNano = this.pendingFrames[0]?.timeUnixNano;
383
+ let tree;
384
+ const call = startCallTrace((name, options) => {
385
+ tree = startTrace(name, {
386
+ ...options,
387
+ // Each record stands alone (the session record may never be written): it names its agent.
388
+ attributes: { ...this.identity, ...options.attributes },
389
+ traceparent: this.root.traceparent(),
390
+ clock: this.tree.clock,
391
+ ...(startTimeUnixNano ? { startTimeUnixNano } : {}),
392
+ });
393
+ return tree.root;
394
+ }, {
395
+ req: bound.request,
396
+ usage,
397
+ binding: bound.binding,
398
+ transport: bound.generation.transport,
399
+ step: this.responses + 1,
400
+ });
401
+ if (!tree) {
402
+ // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
403
+ throw new TheoremError('internal', 'Live response span was not opened');
404
+ }
405
+ // A Live response streams over the session socket; no HTTP try says so.
406
+ call.span.set({ 'gen_ai.request.stream': true });
407
+ for (const frame of this.pendingFrames) {
408
+ call.span.event('theorem.wire.request', { body: traceJson(frame.body) }, frame.timeUnixNano);
409
+ }
410
+ const response = {
411
+ tree,
412
+ call,
413
+ usage,
414
+ input: this.pendingInput,
415
+ delivered: new OutputFold(),
416
+ answering: false,
417
+ complete: false,
418
+ };
419
+ for (const heard of this.pendingHeard)
420
+ call.observe(heard);
421
+ this.pendingFrames = [];
422
+ this.pendingInput = new LiveInput();
423
+ this.pendingHeard = [];
424
+ this.response = response;
425
+ return response;
426
+ }
427
+ /**
428
+ * Close the open response and write its record. A response ended by the
429
+ * session closing has no usage event: what was billed is unknown.
430
+ */
431
+ async endResponse(end) {
432
+ const response = this.response;
433
+ const bound = this.bound;
434
+ if (!(response && bound))
435
+ return undefined;
436
+ this.response = undefined;
437
+ this.responses += 1;
438
+ response.usage.conversation = { history: response.input.messages(), input: [] };
439
+ const answered = end.thrown === undefined && !end.cancelled;
440
+ const tokens = answered
441
+ ? await callTokensEvent(response.usage, bound.generation, bound.family)
442
+ : undefined;
443
+ if (answered)
444
+ this.held = await heldAfter(response.usage, bound.family);
445
+ // Beside `output.messages` (what the model produced): what the host received of it.
446
+ response.call.span.set({
447
+ 'theorem.output.delivered': [{ role: 'assistant', parts: response.delivered.parts }],
448
+ });
449
+ response.call.end({
450
+ ...(tokens?.tokens ? { tokens: tokens.tokens } : {}),
451
+ stop: end.cancelled ? { kind: 'cancelled' } : response.stop,
452
+ ...(end.thrown === undefined ? {} : { thrown: end.thrown }),
453
+ });
454
+ if (tokens?.tokens)
455
+ this.tokens.push(tokens.tokens);
456
+ this.lastResponse = response.call.span;
457
+ this.write(response.tree.collect());
458
+ return tokens;
459
+ }
460
+ /** Build and write one record, after every earlier write. */
461
+ write(spans) {
462
+ const record = buildRecord({
463
+ spans,
464
+ policy: this.out.policy,
465
+ canaries: this.bound ? [this.bound.canary] : [],
466
+ ...(this.out.metadata ? { metadata: this.out.metadata } : {}),
467
+ });
468
+ this.writes = this.writes.then(() => writeTrace(this.out.sink, record, this.out.policy));
469
+ }
470
+ }
471
+ /**
472
+ * Open a session's trace: its `invoke_agent` span under the host's `traceparent`,
473
+ * written under `observability`, the session's profile's block.
474
+ */
475
+ function startLiveTrace(req, observability, sinkOverride) {
476
+ const { sink, policy } = resolveTraceWriter({ override: sinkOverride, observability });
477
+ const identity = {
478
+ 'gen_ai.agent.name': req.profile,
479
+ ...optional('gen_ai.conversation.id', req.conversationId),
480
+ };
481
+ const tree = startTrace(`invoke_agent ${req.profile}`, {
482
+ kind: 'INTERNAL',
483
+ attributes: { 'gen_ai.operation.name': 'invoke_agent', ...identity },
484
+ links: traceLinks(req.links),
485
+ ...(req.traceparent ? { traceparent: req.traceparent } : {}),
486
+ });
487
+ return new LiveTrace(tree, { sink, policy, ...(req.metadata ? { metadata: req.metadata } : {}) }, identity);
488
+ }
489
+ export { startLiveTrace };
@@ -0,0 +1,77 @@
1
+ /**
2
+ * o200k is not every model's tokenizer, so text counts are an estimate for all families. Media is
3
+ * counted only by a rule the family's billed usage was measured to follow; a family without one
4
+ * reports media as `unknownMedia`, never a borrowed rate.
5
+ *
6
+ * Gemini 3 (`gemini-3*` flash / pro text models, direct or via OpenRouter).
7
+ * Measured 22/09/2026 against the usage Gemini bills — Interactions `usage`
8
+ * and `generateContent` `usageMetadata` agree exactly — on gemini-3.8-flash
9
+ * at the default media resolution (THEOREM never sets `media_resolution`).
10
+ * `countTokens` is not the oracle: it reports 560 per PDF page and 32 tokens
11
+ * per audio second, and neither is what is billed.
12
+ * - image: a patch grid inside a 1120-token budget that keeps the aspect
13
+ * ratio — `⌊√(1120·w/h)⌋ × ⌊√(1120·h/w)⌋` (1024×1024 → 1089, 1920×1080 →
14
+ * 1100, 4032×3024 HEIC → 1064). Needs the pixel size from the image header.
15
+ * - audio: `⌈seconds × 25⌉`, seconds being decoded samples ÷ rate
16
+ * (`audioSeconds`): 2.2 s → 56, 0.5 s → 13. Sample rate, channels and
17
+ * silence do not matter. Raw PCM: bare `audio/pcm` is 16 kHz mono 16-bit;
18
+ * `audio/L16` needs both `rate` and `channels`. `audio/pcm` with parameters,
19
+ * `audio/alaw`, and `audio/mulaw` are refused by Interactions — unknown.
20
+ * Mono `audio/L16` is unknown: Gemini converts it first and adds text tokens
21
+ * no rule reproduces (about 31–33, plus 2 per second, plus 1 audio token
22
+ * away from 16 kHz).
23
+ * - video: `frames × ⌊√(70·w/h)⌋ × ⌊√(70·h/w)⌋ + ⌈min(audio, frames) × 25⌉`,
24
+ * `frames` = the video track's seconds rounded half up (66 per frame at
25
+ * 16:9, 63 at 4:3; fps, codec and container do not matter). Under half a
26
+ * second rounds to no frames, which Gemini refuses — unknown. MP4 / MOV /
27
+ * 3GP and WebM only (`videoInfo`); other containers are unknown.
28
+ * - PDF: 520 tokens per page. Text on the page adds nothing.
29
+ * - text documents (plain, Markdown, CSV, JSON, HTML, CSS, XML, RTF,
30
+ * JavaScript, Python) as their UTF-8 text. `text/md` and
31
+ * `application/x-python` are unknown: Gemini converts them first, adding
32
+ * about 30 text tokens no rule reproduces.
33
+ * - Provider file references (`uri`): unknown — the bytes are not here.
34
+ *
35
+ * Known gap: ADTS AAC. Gemini estimates its length from the bitrate; the
36
+ * decoded length here runs 2–3 tokens over at 10 s.
37
+ *
38
+ * Not yet checked against billed usage: video in WebM / MOV / 3GP, anamorphic
39
+ * video, and Gemini 3 models other than gemini-3.8-flash. The full probe and
40
+ * open decisions: https://github.com/masudl-hub/theoremai/issues/18
41
+ */
42
+ import { type Provider } from '../schema.js';
43
+ import type { InteractionPart, TurnHistoryMessage } from '../types.js';
44
+ export declare const TOKEN_TEXT_ENCODING = "o200k_base";
45
+ /** Model families with a verified media rule. */
46
+ export type MediaTokenFamily = 'gemini-3';
47
+ export type MediaPayload = {
48
+ mimeType: string;
49
+ data: string;
50
+ } | {
51
+ mimeType: string;
52
+ uri: string;
53
+ };
54
+ export interface TokenCount {
55
+ tokens: number;
56
+ /** Media parts left out of `tokens` because their count is unknown. */
57
+ unknownMedia: number;
58
+ }
59
+ /** Loaded estimator. Text counting is synchronous; anything with media is not. */
60
+ export interface TokenEstimator {
61
+ /** o200k token count of `text`. */
62
+ text: (text: string) => number;
63
+ /** Token count of one media payload, or `undefined` when unknown. */
64
+ media: (payload: MediaPayload, family: MediaTokenFamily | undefined) => Promise<number | undefined>;
65
+ parts: (parts: InteractionPart[], family: MediaTokenFamily | undefined) => Promise<TokenCount>;
66
+ /** Content, parts, and tool-call arguments across history messages. */
67
+ messages: (messages: TurnHistoryMessage[], family: MediaTokenFamily | undefined) => Promise<TokenCount>;
68
+ }
69
+ /**
70
+ * Media family for a model binding — `undefined` when no verified rule covers
71
+ * it. OpenRouter uses the routed model's family (`google/gemini-3…`).
72
+ */
73
+ export declare function mediaTokenFamily(binding: {
74
+ provider: Provider;
75
+ apiId: string;
76
+ }): MediaTokenFamily | undefined;
77
+ export declare function loadTokenEstimator(): Promise<TokenEstimator>;