@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,863 @@
1
+ import { errorKind } from '../../guardrails/error.js';
2
+ import { traceBytes, traceContent, traceJson, } from '../../observability/trace-span.js';
3
+ import { historyMessageParts } from '../interaction-parts.js';
4
+ import { findLast } from '../util/find-last.js';
5
+ import { asRecord } from './record.js';
6
+ import { sumEventTokens } from './usage.js';
7
+ const MS_PER_S = 1000;
8
+ const HTTP_ERROR = 400;
9
+ const HTTP_ROWS = new Set(['http_request', 'http_response', 'http_error_body', 'http_throw']);
10
+ /** Modalities semconv names under `gen_ai.usage.*`; others go under `theorem.usage.*`. */
11
+ const SEMCONV_MODALITIES = new Set(['text', 'image', 'audio']);
12
+ /** Stop kinds with a semconv `finish_reason` member; others keep the kernel's name. */
13
+ const FINISH_REASON = {
14
+ completed: 'stop',
15
+ length: 'length',
16
+ tool: 'tool_call',
17
+ filtered: 'content_filter',
18
+ provider_error: 'error',
19
+ };
20
+ function mediaModality(mimeType) {
21
+ const [kind] = mimeType.split('/');
22
+ return kind === 'application' || kind === 'text' || !kind ? 'document' : kind;
23
+ }
24
+ function tracePart(part) {
25
+ if (part.type === 'text') {
26
+ return { type: 'text', ...traceContent(part.text) };
27
+ }
28
+ if ('uri' in part) {
29
+ return { type: 'uri', modality: part.type, mime_type: part.mimeType, uri: part.uri };
30
+ }
31
+ return { type: 'blob', modality: part.type, mime_type: part.mimeType, ...traceBytes(part.data) };
32
+ }
33
+ function traceMessage(msg) {
34
+ const media = historyMessageParts(msg).map(tracePart);
35
+ if (msg.role === 'tool') {
36
+ // The tool's text is its response; media it returned follows as parts.
37
+ const response = {
38
+ type: 'tool_call_response',
39
+ ...(msg.tool_call_id ? { id: msg.tool_call_id } : {}),
40
+ response: traceContent(msg.content ?? ''),
41
+ };
42
+ const extra = (msg.parts ?? []).map(tracePart);
43
+ return { role: 'tool', parts: [response, ...extra] };
44
+ }
45
+ const calls = (msg.tool_calls ?? []).map((call) => ({
46
+ type: 'tool_call',
47
+ id: call.id,
48
+ name: call.function.name,
49
+ arguments: traceContent(call.function.arguments),
50
+ }));
51
+ return { role: msg.role, parts: [...media, ...calls] };
52
+ }
53
+ /** Keyed by the call's usage record, which continuations already chain. */
54
+ const callMessages = new WeakMap();
55
+ /** Everything the model reads on `usage`'s call, and where the wire payload starts. */
56
+ function inputMessages(usage) {
57
+ const { conversation } = usage;
58
+ if ('previous' in conversation) {
59
+ const previous = callMessages.get(conversation.previous);
60
+ const stored = [...(previous?.input ?? []), ...(previous?.output ? [previous.output] : [])];
61
+ return {
62
+ input: [...stored, ...conversation.continuation.map(traceMessage)],
63
+ sentFrom: stored.length,
64
+ };
65
+ }
66
+ const opening = conversation.input.length > 0
67
+ ? [{ role: 'user', parts: conversation.input.map(tracePart) }]
68
+ : [];
69
+ return { input: [...conversation.history.map(traceMessage), ...opening] };
70
+ }
71
+ /** Output parts folded from provider events: adjacent deltas of one kind merge. */
72
+ class OutputFold {
73
+ parts = [];
74
+ open;
75
+ /** Each call's `tool_call` part by `callId`, for the failure that follows a malformed one. */
76
+ calls = new Map();
77
+ add(event, nowUnixNano) {
78
+ switch (event.type) {
79
+ case 'text':
80
+ this.appendText('text', event.text);
81
+ return;
82
+ case 'thought':
83
+ this.appendText('reasoning', event.text);
84
+ return;
85
+ case 'tool':
86
+ this.addTool(event.tool);
87
+ return;
88
+ case 'structured':
89
+ this.push({ type: 'structured', content: traceJson(event.structured ?? null) });
90
+ return;
91
+ case 'media':
92
+ this.push(mediaPart(event.media));
93
+ return;
94
+ case 'evidence': {
95
+ const { evidence } = event;
96
+ // Live transcription: labelled, never taken for the model's own text.
97
+ if (evidence.kind === 'input_transcription' || evidence.kind === 'output_transcription') {
98
+ this.appendText('text', event.text ?? '', evidence.kind, evidence.interim);
99
+ return;
100
+ }
101
+ const part = serverToolPart(evidence, nowUnixNano);
102
+ if (part)
103
+ this.push(part);
104
+ return;
105
+ }
106
+ default:
107
+ return;
108
+ }
109
+ }
110
+ appendText(type, text,
111
+ /** A transcription kind, when the text is the provider's transcript. */
112
+ source, interim) {
113
+ if (!text)
114
+ return;
115
+ const key = `${type}:${source ?? ''}:${interim ? 'interim' : ''}`;
116
+ if (this.open?.key === key) {
117
+ this.open.text += text;
118
+ Object.assign(this.open.part, traceContent(this.open.text));
119
+ return;
120
+ }
121
+ const part = {
122
+ type,
123
+ ...traceContent(text),
124
+ ...optional('theorem.source', source),
125
+ ...(interim ? { 'theorem.interim': true } : {}),
126
+ };
127
+ this.parts.push(part);
128
+ this.open = { key, text, part };
129
+ }
130
+ /**
131
+ * The model's call as a `tool_call` part. A malformed call's failure follows
132
+ * it from the provider; the part then records the text the model sent.
133
+ */
134
+ addTool(tool) {
135
+ if (tool.phase === undefined) {
136
+ const part = toolCallPart(tool);
137
+ this.calls.set(tool.callId, part);
138
+ this.push(part);
139
+ return;
140
+ }
141
+ const call = this.calls.get(tool.callId);
142
+ const sent = tool.phase === 'error' ? sentArgumentsText(tool.failure) : undefined;
143
+ if (call && sent !== undefined)
144
+ Object.assign(call, { arguments: traceContent(sent) });
145
+ }
146
+ push(part) {
147
+ this.parts.push(part);
148
+ this.open = undefined;
149
+ }
150
+ }
151
+ /** The provider's raw text for arguments that did not parse (`details.raw`). */
152
+ function sentArgumentsText(failure) {
153
+ const raw = asRecord(failure?.details)?.raw;
154
+ return typeof raw === 'string' ? raw : undefined;
155
+ }
156
+ /**
157
+ * A tool call's arguments as the model sent them. Malformed arguments keep the
158
+ * provider's raw text; parsed ones are the same JSON the kernel sends back in
159
+ * history, so both hash alike.
160
+ */
161
+ function toolArgumentsText(call) {
162
+ return sentArgumentsText(call.failure) ?? JSON.stringify(call.arguments);
163
+ }
164
+ function toolCallPart(call) {
165
+ return {
166
+ type: 'tool_call',
167
+ id: call.callId,
168
+ name: call.name,
169
+ arguments: traceContent(toolArgumentsText(call)),
170
+ };
171
+ }
172
+ function mediaPart(media) {
173
+ return {
174
+ type: 'blob',
175
+ modality: mediaModality(media.mimeType),
176
+ mime_type: media.mimeType,
177
+ ...traceBytes(media.data),
178
+ };
179
+ }
180
+ const CALL_SUFFIX = '_call';
181
+ const RESULT_SUFFIX = '_result';
182
+ function serverToolStep(evidence) {
183
+ switch (evidence.kind) {
184
+ case 'code_execution_call':
185
+ return { side: 'call', name: 'code_execution', id: evidence.id };
186
+ case 'code_execution_result':
187
+ return { side: 'result', name: 'code_execution', id: evidence.callId };
188
+ case 'provider_step': {
189
+ const { step, raw } = evidence;
190
+ if (step.endsWith(CALL_SUFFIX)) {
191
+ const id = typeof raw?.id === 'string' ? raw.id : undefined;
192
+ return { side: 'call', name: step.slice(0, -CALL_SUFFIX.length), id };
193
+ }
194
+ if (step.endsWith(RESULT_SUFFIX)) {
195
+ const id = typeof raw?.call_id === 'string' ? raw.call_id : undefined;
196
+ return { side: 'result', name: step.slice(0, -RESULT_SUFFIX.length), id };
197
+ }
198
+ return undefined;
199
+ }
200
+ default:
201
+ return undefined;
202
+ }
203
+ }
204
+ /**
205
+ * A provider-run tool step as a semconv server tool part. The kernel sees a
206
+ * step only once it is whole, so its arrival is `theorem.observed_end`; the
207
+ * row events hold every earlier row's arrival.
208
+ */
209
+ function serverToolPart(evidence, nowUnixNano) {
210
+ const step = serverToolStep(evidence);
211
+ if (!step)
212
+ return undefined;
213
+ const observed = {
214
+ 'theorem.observed_end': nowUnixNano,
215
+ ...(evidence.partial ? { 'theorem.partial': true } : {}),
216
+ };
217
+ const payload = { ...traceJson(evidence.raw ?? {}), type: step.name };
218
+ if (step.side === 'call') {
219
+ return {
220
+ type: 'server_tool_call',
221
+ ...optional('id', step.id),
222
+ name: step.name,
223
+ server_tool_call: payload,
224
+ ...observed,
225
+ };
226
+ }
227
+ return {
228
+ type: 'server_tool_call_response',
229
+ ...optional('id', step.id),
230
+ server_tool_call_response: payload,
231
+ ...observed,
232
+ };
233
+ }
234
+ /** The raw evidence payload is recorded only with `evidenceRaw`. */
235
+ function groundingEvent(event) {
236
+ switch (event.type) {
237
+ case 'grounding': {
238
+ const { searchHtml, metadata, chunks } = event.grounding;
239
+ if (!searchHtml && !metadata && !chunks)
240
+ return undefined;
241
+ return {
242
+ ...(searchHtml ? { search_html: traceContent(searchHtml) } : {}),
243
+ ...(metadata || chunks ? { raw: traceJson({ metadata, chunks }) } : {}),
244
+ };
245
+ }
246
+ case 'citation':
247
+ return { sources: traceJson(event.sources) };
248
+ case 'evidence': {
249
+ const { evidence } = event;
250
+ if (serverToolStep(evidence))
251
+ return undefined;
252
+ if (evidence.kind === 'input_transcription' || evidence.kind === 'output_transcription') {
253
+ return undefined;
254
+ }
255
+ return {
256
+ provider: evidence.provider,
257
+ ...(evidence.raw ? { raw: traceJson(evidence.raw) } : {}),
258
+ };
259
+ }
260
+ default:
261
+ return undefined;
262
+ }
263
+ }
264
+ /**
265
+ * A guardrail decision as `theorem.guardrail` event attributes. The matched
266
+ * substring stays exact (not scrubbed: scrubbing it would erase what it shows);
267
+ * the record drops it unless the profile includes `guardrailMatchPreview`.
268
+ */
269
+ function guardrailAttributes(guardrail) {
270
+ return {
271
+ stage: guardrail.stage,
272
+ trust: guardrail.trust,
273
+ action: guardrail.action,
274
+ hits: guardrail.hits.map((hit) => ({
275
+ rule: hit.rule,
276
+ severity: hit.severity,
277
+ ...(hit.span ? { start: hit.span.start, end: hit.span.end } : {}),
278
+ ...optional('match', hit.match),
279
+ ...optional('label', hit.label),
280
+ ...optional('doc', hit.doc),
281
+ })),
282
+ ...(guardrail.provenance ? { provenance: { ...guardrail.provenance } } : {}),
283
+ ...(guardrail.errorInternal ? { error: traceContent(guardrail.errorInternal) } : {}),
284
+ };
285
+ }
286
+ /** What a stream check looked at, for its pass record. */
287
+ const STREAM_CHECK_STAGE = {
288
+ output_stream: 'output_delta',
289
+ stream_canary: 'output_delta',
290
+ live_output: 'live_outbound',
291
+ };
292
+ /**
293
+ * One timed guardrail check as `theorem.guardrail` attributes: its decision,
294
+ * or a pass (`allow`, no hits) when it let the text through. Trace only; the
295
+ * host still hears about hits alone.
296
+ */
297
+ function guardrailCheckAttributes(check, durationMs, guardrail, passed) {
298
+ return {
299
+ ...(guardrail
300
+ ? guardrailAttributes(guardrail)
301
+ : { stage: passed.stage, trust: passed.trust, action: 'allow', hits: [] }),
302
+ check,
303
+ duration_ms: durationMs,
304
+ };
305
+ }
306
+ function modalityAttributes(byModality) {
307
+ const out = {};
308
+ for (const side of ['input', 'output']) {
309
+ for (const [modality, count] of Object.entries(byModality?.[side] ?? {})) {
310
+ const family = SEMCONV_MODALITIES.has(modality) ? 'gen_ai' : 'theorem';
311
+ out[`${family}.usage.${modality}.${side}_tokens`] = count;
312
+ }
313
+ }
314
+ return out;
315
+ }
316
+ function optional(key, value) {
317
+ return value === undefined ? {} : { [key]: value };
318
+ }
319
+ function usageAttributes(tokens) {
320
+ return {
321
+ 'gen_ai.usage.input_tokens': tokens.input,
322
+ 'gen_ai.usage.output_tokens': tokens.output,
323
+ ...optional('gen_ai.usage.reasoning.output_tokens', tokens.thinking),
324
+ ...optional('gen_ai.usage.cache_read.input_tokens', tokens.cached),
325
+ ...optional('gen_ai.usage.cache_write.input_tokens', tokens.cacheWrite),
326
+ ...optional('theorem.usage.tool_use.input_tokens', tokens.toolUse),
327
+ ...modalityAttributes(tokens.byModality),
328
+ ...(tokens.grounding
329
+ ? {
330
+ 'theorem.usage.grounding': tokens.grounding.map((entry) => ({
331
+ type: entry.type,
332
+ count: entry.count,
333
+ ...optional('search_query_count', entry.searchQueryCount),
334
+ })),
335
+ }
336
+ : {}),
337
+ ...optional('theorem.usage.cost_usd', tokens.cost?.usd),
338
+ ...optional('theorem.usage.upstream_cost_usd', tokens.cost?.upstreamUsd),
339
+ ...(tokens.cost?.partial ? { 'theorem.usage.cost_partial': true } : {}),
340
+ ...(tokens.estimated?.length ? { 'theorem.usage.estimated': [...tokens.estimated] } : {}),
341
+ ...(tokens.unknownMedia ? { 'theorem.usage.unknown_media': { ...tokens.unknownMedia } } : {}),
342
+ };
343
+ }
344
+ function operationName(transport) {
345
+ return transport === 'openAiCompat' ? 'chat' : 'generate_content';
346
+ }
347
+ /** `gen_ai.provider.name`: semconv's name where one exists; a local server only when declared. */
348
+ function providerName(binding) {
349
+ switch (binding?.provider) {
350
+ case 'google':
351
+ return 'gcp.gemini';
352
+ case 'openrouter':
353
+ return 'openrouter';
354
+ default:
355
+ return binding?.server;
356
+ }
357
+ }
358
+ function outputType(req, transport) {
359
+ // Live answers in audio: its setup asks for `responseModalities: ['AUDIO']` (live/framing.ts).
360
+ if (transport === 'geminiLive')
361
+ return 'speech';
362
+ if (req.structured)
363
+ return 'json';
364
+ if (req.image)
365
+ return 'image';
366
+ if (req.speech)
367
+ return 'speech';
368
+ return 'text';
369
+ }
370
+ function requestAttributes(req, binding, transport) {
371
+ const provider = providerName(binding);
372
+ return {
373
+ 'gen_ai.operation.name': operationName(transport),
374
+ ...optional('gen_ai.provider.name', provider),
375
+ 'gen_ai.request.model': req.apiId,
376
+ 'theorem.model.id': req.model,
377
+ ...optional('gen_ai.request.temperature', req.temperature),
378
+ ...optional('gen_ai.request.max_tokens', req.maxOutputTokens),
379
+ ...optional('gen_ai.request.reasoning.level', req.thinking),
380
+ ...optional('gen_ai.request.previous_response.id', req.previousInteractionId),
381
+ 'gen_ai.system_instructions': [{ type: 'text', ...traceContent(req.system) }],
382
+ ...(req.wireTools?.length
383
+ ? { 'gen_ai.tool.definitions': traceContent(JSON.stringify(req.wireTools)) }
384
+ : {}),
385
+ 'gen_ai.output.type': outputType(req, transport),
386
+ ...optional('theorem.key_slot', req.keySlot),
387
+ ...controlAttributes(req),
388
+ };
389
+ }
390
+ /**
391
+ * Request controls semconv has no names for, as requested. The Maps location
392
+ * builtin's coordinates are left to the wire body (`outboundWire`): they locate
393
+ * the user.
394
+ */
395
+ function controlAttributes(req) {
396
+ const { cache, image, speech, live } = req;
397
+ return {
398
+ 'theorem.request.builtins': req.builtins.map((b) => b.id),
399
+ ...optional('theorem.request.store', req.store),
400
+ ...optional('theorem.request.summaries', req.summaries),
401
+ ...optional('theorem.request.structured', req.structured?.id),
402
+ ...optional('theorem.request.session_id', req.sessionId),
403
+ ...(cache
404
+ ? { 'theorem.request.cache': { mode: cache.mode, ...optional('ttl', cache.ttl) } }
405
+ : {}),
406
+ ...(image
407
+ ? {
408
+ 'theorem.request.image': {
409
+ ...optional('mime_type', image.mimeType),
410
+ ...optional('aspect_ratio', image.aspectRatio),
411
+ ...optional('resolution', image.resolution),
412
+ ...optional('quality', image.quality),
413
+ ...optional('background', image.background),
414
+ ...optional('n', image.n),
415
+ ...optional('seed', image.seed),
416
+ ...optional('output_compression', image.outputCompression),
417
+ include_text: image.includeText,
418
+ },
419
+ }
420
+ : {}),
421
+ ...(speech
422
+ ? {
423
+ 'theorem.request.speech': {
424
+ ...optional('voice', speech.voice),
425
+ ...optional('format', speech.format),
426
+ },
427
+ }
428
+ : {}),
429
+ ...(live ? { 'theorem.request.live': liveAttributes(live, req) } : {}),
430
+ };
431
+ }
432
+ /** Live session setup as sent. A resumption handle is a credential: only its presence is kept. */
433
+ function liveAttributes(live, req) {
434
+ const { vad, transcription } = live;
435
+ return {
436
+ ...optional('voice', live.voice),
437
+ ...(vad
438
+ ? {
439
+ vad: {
440
+ ...optional('activity_handling', vad.activityHandling),
441
+ ...optional('start_sensitivity', vad.startSensitivity),
442
+ ...optional('end_sensitivity', vad.endSensitivity),
443
+ ...optional('prefix_padding_ms', vad.prefixPaddingMs),
444
+ ...optional('silence_duration_ms', vad.silenceDurationMs),
445
+ },
446
+ }
447
+ : {}),
448
+ ...optional('session_resumption', live.sessionResumption),
449
+ ...(live.contextCompression
450
+ ? {
451
+ context_compression: {
452
+ mechanism: 'sliding_window',
453
+ ...optional('trigger_tokens', live.contextCompression.triggerTokens),
454
+ ...optional('target_tokens', live.contextCompression.slidingWindow.targetTokens),
455
+ },
456
+ }
457
+ : {}),
458
+ ...(transcription
459
+ ? {
460
+ transcription: {
461
+ ...optional('input', transcription.input),
462
+ ...optional('output', transcription.output),
463
+ },
464
+ }
465
+ : {}),
466
+ resumed: Boolean(req.sessionResumptionHandle),
467
+ };
468
+ }
469
+ function headerAttributes(prefix, headers) {
470
+ if (!headers || typeof headers !== 'object')
471
+ return {};
472
+ return Object.fromEntries(Object.entries(headers).map(([key, value]) => [`${prefix}.${key}`, [String(value)]]));
473
+ }
474
+ function urlAttributes(url) {
475
+ if (typeof url !== 'string')
476
+ return {};
477
+ const parsed = URL.canParse(url) ? new URL(url) : undefined;
478
+ // The path only: a query can carry credentials.
479
+ return parsed ? { 'server.address': parsed.hostname, 'url.path': parsed.pathname } : {};
480
+ }
481
+ /** POST spans of one call, opened and closed from the adapter's tap rows. */
482
+ class HttpTries {
483
+ call;
484
+ tries = 0;
485
+ current;
486
+ last;
487
+ /** Status of the latest response; how a try still open at call end ended. */
488
+ lastStatus;
489
+ awaitingFirstChunk = false;
490
+ streamed = false;
491
+ constructor(call) {
492
+ this.call = call;
493
+ }
494
+ /** Handle one tap row; returns false for a provider data row. */
495
+ row(row) {
496
+ const type = typeof row.eventType === 'string' ? row.eventType : undefined;
497
+ if (!type || !HTTP_ROWS.has(type)) {
498
+ this.firstChunk();
499
+ return false;
500
+ }
501
+ if (type === 'http_request')
502
+ this.open(row);
503
+ else if (type === 'http_response')
504
+ this.response(row);
505
+ else if (type === 'http_error_body')
506
+ this.errorBody(row);
507
+ else
508
+ this.thrown(row);
509
+ return true;
510
+ }
511
+ open(row) {
512
+ this.current?.end();
513
+ const backoff = this.last?.msSinceEnd();
514
+ this.current = this.call.child(String(row.method ?? 'GET'), {
515
+ kind: 'CLIENT',
516
+ attributes: {
517
+ 'http.request.method': String(row.method ?? 'GET'),
518
+ ...urlAttributes(row.url),
519
+ 'http.request.resend_count': this.tries,
520
+ ...(typeof row.keySlot === 'string' ? { 'theorem.key_slot': row.keySlot } : {}),
521
+ ...optional('theorem.retry.backoff_ms', backoff),
522
+ ...headerAttributes('http.request.header', row.headers),
523
+ },
524
+ });
525
+ this.tries += 1;
526
+ // The body sent decides, not the profile: an adapter may stream or buffer regardless.
527
+ this.streamed = asRecord(row.body)?.stream === true;
528
+ if (this.streamed)
529
+ this.call.set({ 'gen_ai.request.stream': true });
530
+ if ('body' in row) {
531
+ this.current.event('theorem.wire.request', { body: traceJson(row.body) });
532
+ }
533
+ else if (typeof row.bodyKind === 'string') {
534
+ this.current.event('theorem.wire.request', { body_kind: row.bodyKind });
535
+ }
536
+ if (typeof row.keySlot === 'string')
537
+ this.call.set({ 'theorem.key_slot': row.keySlot });
538
+ }
539
+ response(row) {
540
+ const status = typeof row.status === 'number' ? row.status : undefined;
541
+ this.lastStatus = status;
542
+ this.current?.set({
543
+ ...optional('http.response.status_code', status),
544
+ ...headerAttributes('http.response.header', row.headers),
545
+ });
546
+ if (status !== undefined && status >= HTTP_ERROR) {
547
+ this.current?.set({ 'error.type': String(status) });
548
+ }
549
+ else {
550
+ // Streamed or buffered, the first data row is the reply's first chunk: a buffered body is its one chunk.
551
+ this.awaitingFirstChunk = true;
552
+ }
553
+ }
554
+ errorBody(row) {
555
+ this.current?.event('theorem.upstream.row', { row: traceJson(row) });
556
+ this.close({ code: 'ERROR', message: String(this.lastStatus ?? 'error') });
557
+ }
558
+ thrown(row) {
559
+ const name = typeof row.name === 'string' ? row.name : 'Error';
560
+ this.current?.event('exception', {
561
+ 'exception.type': name,
562
+ 'exception.message': traceContent(String(row.message ?? '')),
563
+ });
564
+ this.current?.set({ 'error.type': name });
565
+ this.close({ code: 'ERROR', message: name });
566
+ }
567
+ firstChunk() {
568
+ if (!(this.awaitingFirstChunk && this.current))
569
+ return;
570
+ this.awaitingFirstChunk = false;
571
+ this.call.set({
572
+ 'gen_ai.response.time_to_first_chunk': this.current.msSinceStart() / MS_PER_S,
573
+ });
574
+ }
575
+ close(status) {
576
+ if (!this.current)
577
+ return;
578
+ this.current.end(status);
579
+ this.last = this.current;
580
+ this.current = undefined;
581
+ }
582
+ }
583
+ /**
584
+ * How a try still open at call end (a streamed body) ended: by its HTTP status
585
+ * and whether reading it threw. A provider error inside a 200 body is the
586
+ * call's failure, not the try's.
587
+ */
588
+ function httpStatus(status, cancelled, thrown) {
589
+ if (status !== undefined && status >= HTTP_ERROR) {
590
+ return { code: 'ERROR', message: String(status) };
591
+ }
592
+ if (thrown !== undefined) {
593
+ return { code: 'ERROR', message: errorKind(thrown) };
594
+ }
595
+ return cancelled ? { code: 'UNSET' } : { code: 'OK' };
596
+ }
597
+ /** The class a thrown value is recorded under (`exception.type`); `error.type` is its kind. */
598
+ function errorName(err) {
599
+ return err instanceof Error ? err.name : 'Error';
600
+ }
601
+ function recordException(span, err) {
602
+ span.event('exception', {
603
+ 'exception.type': errorName(err),
604
+ 'exception.message': traceContent(err instanceof Error ? err.message : String(err)),
605
+ ...(err instanceof Error && err.stack
606
+ ? { 'exception.stacktrace': traceContent(err.stack) }
607
+ : {}),
608
+ });
609
+ }
610
+ /** Close a root that a throw ended: the exception, its kind as `error.type`, and ERROR. */
611
+ function endThrownSpan(span, err) {
612
+ recordException(span, err);
613
+ const kind = errorKind(err);
614
+ span.set({ 'error.type': kind });
615
+ span.end({ code: 'ERROR', message: kind });
616
+ }
617
+ /** Each stream check that ran on a call and never acted, as one pass with its total time and runs. */
618
+ function recordStreamPasses(span, checks) {
619
+ for (const [check, timed] of checks) {
620
+ if (timed.decided)
621
+ continue;
622
+ span.event('theorem.guardrail', {
623
+ ...guardrailCheckAttributes(check, timed.ms, undefined, {
624
+ stage: STREAM_CHECK_STAGE[check],
625
+ trust: 'untrusted',
626
+ }),
627
+ runs: timed.runs,
628
+ });
629
+ }
630
+ }
631
+ /** Every stream check's time on a call, summed: `theorem.guardrail.stream_ms`, when any ran. */
632
+ function streamGuardMs(checks) {
633
+ let ms = 0;
634
+ for (const timed of checks.values())
635
+ ms += timed.ms;
636
+ return ms > 0 ? { 'theorem.guardrail.stream_ms': ms } : {};
637
+ }
638
+ /** Stops where the model did not finish its output: no finish reason, status `UNSET`. */
639
+ const STOPPED_CALLS = new Set(['cancelled', 'interrupted']);
640
+ function callOutcome(stop, failure) {
641
+ const stopped = stop !== undefined && STOPPED_CALLS.has(stop.kind);
642
+ const finish = stop && !stopped ? (FINISH_REASON[stop.kind] ?? stop.kind) : undefined;
643
+ if (failure) {
644
+ return {
645
+ stopped,
646
+ finish,
647
+ status: { code: 'ERROR', message: failure },
648
+ attributes: { 'error.type': failure },
649
+ };
650
+ }
651
+ return { stopped, finish, status: { code: stopped ? 'UNSET' : 'OK' }, attributes: {} };
652
+ }
653
+ function responseAttributes(response, native, transport) {
654
+ const reported = !native
655
+ ? {}
656
+ : transport === 'openAiCompat'
657
+ ? { 'gen_ai.response.finish_reasons': [native] }
658
+ : { 'gen_ai.response.status': native };
659
+ return {
660
+ ...optional('gen_ai.response.id', response?.id || undefined),
661
+ ...optional('gen_ai.response.model', response?.model || undefined),
662
+ ...reported,
663
+ };
664
+ }
665
+ /**
666
+ * `open` places the span: a child of the turn's root, or the root of a Live response's own record.
667
+ * `usage.conversation` is read again at the end, since a Live response sets it only when it closes.
668
+ */
669
+ function startCallTrace(open, args) {
670
+ const { req, usage, transport } = args;
671
+ const opening = inputMessages(usage);
672
+ const span = open(`${operationName(transport)} ${req.apiId}`, {
673
+ kind: 'CLIENT',
674
+ attributes: {
675
+ ...requestAttributes(req, args.binding, transport),
676
+ 'gen_ai.input.messages': opening.input,
677
+ ...optional('theorem.input.sent_from', opening.sentFrom),
678
+ 'theorem.step': args.step,
679
+ ...optional('theorem.attempt', args.attempt),
680
+ },
681
+ });
682
+ const http = new HttpTries(span);
683
+ const output = new OutputFold();
684
+ const heard = new OutputFold();
685
+ const errors = [];
686
+ let response;
687
+ let native;
688
+ let firstText = false;
689
+ const streamChecks = new Map();
690
+ /** The stream check that ran last: a decision right after it is that check's. */
691
+ let lastCheck;
692
+ return {
693
+ span,
694
+ tap: (row) => {
695
+ if (!http.row(row))
696
+ span.event('theorem.upstream.row', { row: traceJson(row) });
697
+ },
698
+ observe: (event) => {
699
+ if (event.type === 'evidence' && event.evidence.kind === 'input_transcription') {
700
+ // What the provider heard in the input: labelled, beside what the model read.
701
+ heard.add(event, span.nowUnixNano());
702
+ return;
703
+ }
704
+ output.add(event, span.nowUnixNano());
705
+ if (event.type === 'text' && !firstText) {
706
+ firstText = true;
707
+ span.set({ 'theorem.response.time_to_first_text': span.msSinceStart() / MS_PER_S });
708
+ }
709
+ const grounding = groundingEvent(event);
710
+ if (grounding)
711
+ span.event('theorem.grounding', grounding);
712
+ if (event.type === 'error')
713
+ errors.push(event);
714
+ if (event.type === 'response')
715
+ response = event.response;
716
+ if (event.type === 'done')
717
+ native = event.stop.native ?? native;
718
+ },
719
+ guardrail: (guardrail) => {
720
+ const timed = lastCheck ? streamChecks.get(lastCheck) : undefined;
721
+ if (!(lastCheck && timed) || timed.decided) {
722
+ span.event('theorem.guardrail', guardrailAttributes(guardrail));
723
+ return;
724
+ }
725
+ timed.decided = true;
726
+ span.event('theorem.guardrail', {
727
+ ...guardrailCheckAttributes(lastCheck, timed.ms, guardrail, {
728
+ stage: STREAM_CHECK_STAGE[lastCheck],
729
+ trust: 'untrusted',
730
+ }),
731
+ runs: timed.runs,
732
+ });
733
+ },
734
+ guardTime: (check, ms) => {
735
+ const timed = streamChecks.get(check) ?? { ms: 0, runs: 0, decided: false };
736
+ timed.ms += ms;
737
+ timed.runs += 1;
738
+ streamChecks.set(check, timed);
739
+ lastCheck = check;
740
+ },
741
+ end: (end) => {
742
+ for (const error of errors) {
743
+ span.event('exception', {
744
+ 'exception.type': error.errorKind,
745
+ 'exception.message': traceContent(error.errorInternal ?? error.error ?? ''),
746
+ });
747
+ }
748
+ if (end.thrown !== undefined)
749
+ recordException(span, end.thrown);
750
+ recordStreamPasses(span, streamChecks);
751
+ const lastError = errors.at(-1);
752
+ const failure = end.thrown !== undefined ? errorKind(end.thrown) : lastError?.errorKind;
753
+ const outcome = callOutcome(end.stop, failure);
754
+ const outputMessage = {
755
+ role: 'assistant',
756
+ parts: output.parts,
757
+ ...optional('finish_reason', outcome.finish),
758
+ };
759
+ const { input } = inputMessages(usage);
760
+ // A continuation replays what the model read, not the provider's transcript of it.
761
+ callMessages.set(usage, { input, output: outputMessage });
762
+ const transcript = heard.parts.length > 0 ? [{ role: 'user', parts: heard.parts }] : [];
763
+ http.close(httpStatus(http.lastStatus, outcome.stopped, end.thrown));
764
+ span.set({
765
+ 'gen_ai.input.messages': [...input, ...transcript],
766
+ 'gen_ai.output.messages': [outputMessage],
767
+ ...(end.tokens ? usageAttributes(end.tokens) : {}),
768
+ ...responseAttributes(response, outcome.stopped ? undefined : native, transport),
769
+ ...optional('theorem.stop.kind', end.stop?.kind),
770
+ ...streamGuardMs(streamChecks),
771
+ ...outcome.attributes,
772
+ });
773
+ span.end(outcome.status);
774
+ },
775
+ };
776
+ }
777
+ /** The host's new input as one user message, exactly as it arrived (before ingress). */
778
+ function turnInputMessages(input) {
779
+ const media = [...(input?.attachments ?? []), ...(input?.voice ?? [])].map((blob) => 'uri' in blob
780
+ ? {
781
+ type: 'uri',
782
+ modality: mediaModality(blob.mimeType),
783
+ mime_type: blob.mimeType,
784
+ uri: blob.uri,
785
+ }
786
+ : {
787
+ type: 'blob',
788
+ modality: mediaModality(blob.mimeType),
789
+ mime_type: blob.mimeType,
790
+ ...traceBytes(blob.data),
791
+ });
792
+ const parts = [...(input?.text ? [{ type: 'text', ...traceContent(input.text) }] : []), ...media];
793
+ return parts.length > 0 ? [{ role: 'user', parts }] : [];
794
+ }
795
+ function traceLinks(links) {
796
+ return (links ?? []).map((link) => ({
797
+ traceparent: link.traceparent,
798
+ attributes: {
799
+ 'theorem.link.kind': link.kind,
800
+ ...optional('theorem.stop.kind', link.stop),
801
+ },
802
+ }));
803
+ }
804
+ function turnSpanOptions(req) {
805
+ return {
806
+ kind: 'INTERNAL',
807
+ attributes: {
808
+ 'gen_ai.operation.name': 'invoke_agent',
809
+ 'gen_ai.agent.name': req.profile,
810
+ ...optional('gen_ai.conversation.id', req.conversationId),
811
+ 'gen_ai.input.messages': turnInputMessages(req.input),
812
+ ...optional('theorem.request.effort', req.effort),
813
+ ...optional('theorem.request.model_select', req.model),
814
+ ...optional('theorem.project.id', req.projectId),
815
+ },
816
+ links: traceLinks(req.links),
817
+ };
818
+ }
819
+ /** Stops where the turn failed; the rest either finished or were stopped on purpose. */
820
+ const FAILED_STOPS = new Set(['provider_error', 'stream_incomplete']);
821
+ const FINISHED_STOPS = new Set(['completed', 'length', 'generation_complete']);
822
+ /**
823
+ * Close a turn's `invoke_agent` span. Usage is the sum of this turn's own
824
+ * calls; a nested turn (compaction) carries its own.
825
+ */
826
+ function endTurnSpan(root, end) {
827
+ const tokens = sumEventTokens(end.seen);
828
+ const done = findLast(end.seen, (ev) => ev.type === 'done');
829
+ const stop = done?.stop.kind;
830
+ const errorEvent = findLast(end.seen, (ev) => ev.type === 'error');
831
+ const publicError = errorEvent?.error;
832
+ const threw = end.thrown !== undefined;
833
+ if (threw)
834
+ recordException(root, end.thrown);
835
+ const failed = threw || (stop !== undefined && FAILED_STOPS.has(stop));
836
+ // The builder's name for the failure: the thrown value's kind, else the error event's, else the stop.
837
+ const failure = threw ? errorKind(end.thrown) : (errorEvent?.errorKind ?? stop);
838
+ // What the host received, beside each call's `output.messages` (what the model produced).
839
+ const delivered = {
840
+ role: 'assistant',
841
+ parts: end.delivered.parts,
842
+ ...optional('finish_reason', callOutcome(done?.stop, undefined).finish),
843
+ };
844
+ root.set({
845
+ 'gen_ai.output.messages': [delivered],
846
+ ...(tokens ? usageAttributes(tokens) : {}),
847
+ ...(stop ? { 'theorem.stop.kind': stop } : {}),
848
+ 'theorem.attempts': end.attempts,
849
+ 'theorem.steps': end.calls,
850
+ ...(end.seen.some((ev) => ev.type === 'compaction' && ev.outcome === 'compacted')
851
+ ? { 'gen_ai.conversation.compacted': true }
852
+ : {}),
853
+ ...(failed && publicError ? { 'theorem.error.public': traceContent(publicError) } : {}),
854
+ ...(failed && failure ? { 'error.type': failure } : {}),
855
+ });
856
+ if (failed) {
857
+ root.end({ code: 'ERROR', ...(failure ? { message: failure } : {}) });
858
+ }
859
+ else {
860
+ root.end(stop && !FINISHED_STOPS.has(stop) ? { code: 'UNSET' } : { code: 'OK' });
861
+ }
862
+ }
863
+ export { endThrownSpan, endTurnSpan, guardrailAttributes, guardrailCheckAttributes, OutputFold, optional, recordException, startCallTrace, toolArgumentsText, traceLinks, tracePart, turnSpanOptions, urlAttributes, usageAttributes, };