@theoremjs/agents 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/README.md +276 -995
  2. package/esm/mod.d.ts +33 -19
  3. package/esm/mod.js +18 -11
  4. package/esm/src/cli/commands/bench.js +36 -14
  5. package/esm/src/cli/commands/detect-compile.d.ts +17 -0
  6. package/esm/src/cli/commands/detect-compile.js +22 -0
  7. package/esm/src/cli/commands/eval.d.ts +3 -3
  8. package/esm/src/cli/commands/fuzz-canary.js +55 -16
  9. package/esm/src/cli/commands/profile.js +4 -4
  10. package/esm/src/cli/commands/run.d.ts +2 -2
  11. package/esm/src/cli/commands/run.js +1 -1
  12. package/esm/src/cli/commands/test.d.ts +4 -3
  13. package/esm/src/cli/commands/test.js +2 -2
  14. package/esm/src/cli/index.js +9 -9
  15. package/esm/src/cli/matrix/fixtures.js +25 -30
  16. package/esm/src/evals/attachments.d.ts +1 -0
  17. package/esm/src/evals/attachments.js +4 -2
  18. package/esm/src/evals/breakdown.d.ts +2 -0
  19. package/esm/src/evals/breakdown.js +1 -0
  20. package/esm/src/evals/graders/answer.d.ts +3 -0
  21. package/esm/src/evals/graders/answer.js +1 -0
  22. package/esm/src/evals/graders/code.d.ts +7 -31
  23. package/esm/src/evals/graders/code.js +4 -25
  24. package/esm/src/evals/graders/judge.d.ts +4 -0
  25. package/esm/src/evals/graders/judge.js +7 -5
  26. package/esm/src/evals/graders/latency.d.ts +1 -0
  27. package/esm/src/evals/graders/latency.js +3 -2
  28. package/esm/src/evals/graders/live.d.ts +3 -0
  29. package/esm/src/evals/graders/live.js +2 -0
  30. package/esm/src/evals/graders/media.js +1 -2
  31. package/esm/src/evals/graders/shared.js +1 -1
  32. package/esm/src/evals/graders/transcript.d.ts +2 -0
  33. package/esm/src/evals/graders/transcript.js +5 -3
  34. package/esm/src/evals/mod.d.ts +1 -9
  35. package/esm/src/evals/mod.js +1 -9
  36. package/esm/src/evals/record.d.ts +6 -0
  37. package/esm/src/evals/record.js +4 -2
  38. package/esm/src/evals/rubrics/mod.d.ts +1 -1
  39. package/esm/src/evals/rubrics/mod.js +1 -1
  40. package/esm/src/evals/rubrics/mustache.js +1 -1
  41. package/esm/src/evals/rubrics/types.js +1 -1
  42. package/esm/src/evals/run.d.ts +9 -52
  43. package/esm/src/evals/run.js +12 -46
  44. package/esm/src/evals/suite.d.ts +12 -3
  45. package/esm/src/evals/suite.js +9 -4
  46. package/esm/src/evals/summary.d.ts +3 -0
  47. package/esm/src/evals/summary.js +1 -0
  48. package/esm/src/evals/trial.d.ts +3 -16
  49. package/esm/src/evals/trial.js +7 -30
  50. package/esm/src/evals/types.d.ts +30 -121
  51. package/esm/src/evals/types.js +3 -16
  52. package/esm/src/evals/verdict.d.ts +5 -0
  53. package/esm/src/evals/verdict.js +4 -1
  54. package/esm/src/guardrails/boundaries.d.ts +41 -0
  55. package/esm/src/guardrails/boundaries.js +103 -0
  56. package/esm/src/guardrails/canary-gate.d.ts +1 -0
  57. package/esm/src/guardrails/canary.d.ts +49 -15
  58. package/esm/src/guardrails/canary.js +103 -30
  59. package/esm/src/guardrails/compile-egress.d.ts +6 -5
  60. package/esm/src/guardrails/compile-egress.js +6 -5
  61. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +3 -1
  62. package/esm/src/guardrails/corpus/canary-egress-attacks.js +4 -2
  63. package/esm/src/guardrails/corpus/fuzz-inbound.js +14 -17
  64. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +2 -0
  65. package/esm/src/guardrails/corpus/inbound-payloads.js +4 -2
  66. package/esm/src/guardrails/corpus/live-attacks.d.ts +2 -0
  67. package/esm/src/guardrails/corpus/live-attacks.js +6 -1
  68. package/esm/src/guardrails/corpus/mod.d.ts +1 -1
  69. package/esm/src/guardrails/corpus/secrets.d.ts +3 -3
  70. package/esm/src/guardrails/corpus/secrets.js +2 -2
  71. package/esm/src/guardrails/corpus/strings.d.ts +1 -1
  72. package/esm/src/guardrails/corpus/strings.js +1 -1
  73. package/esm/src/guardrails/corpus/types.d.ts +5 -1
  74. package/esm/src/guardrails/credential-rules.d.ts +36 -0
  75. package/esm/src/guardrails/credential-rules.js +3001 -0
  76. package/esm/src/guardrails/credential-scan.d.ts +45 -0
  77. package/esm/src/guardrails/credential-scan.js +172 -0
  78. package/esm/src/guardrails/destinations.d.ts +45 -0
  79. package/esm/src/guardrails/destinations.js +234 -0
  80. package/esm/src/guardrails/detect-at.d.ts +107 -0
  81. package/esm/src/guardrails/detect-at.js +434 -0
  82. package/esm/src/guardrails/detect-reply.d.ts +61 -0
  83. package/esm/src/guardrails/detect-reply.js +95 -0
  84. package/esm/src/guardrails/detect-stream.d.ts +33 -0
  85. package/esm/src/guardrails/detect-stream.js +77 -0
  86. package/esm/src/guardrails/detectors.d.ts +216 -0
  87. package/esm/src/guardrails/detectors.js +503 -0
  88. package/esm/src/guardrails/egress-automata.d.ts +4 -6
  89. package/esm/src/guardrails/egress-automata.js +24095 -4572
  90. package/esm/src/guardrails/egress-compiler.d.ts +38 -16
  91. package/esm/src/guardrails/egress-compiler.js +254 -60
  92. package/esm/src/guardrails/egress-patterns.d.ts +4 -2
  93. package/esm/src/guardrails/egress-patterns.js +6 -2
  94. package/esm/src/guardrails/egress-stream.d.ts +54 -36
  95. package/esm/src/guardrails/egress-stream.js +253 -124
  96. package/esm/src/guardrails/egress-urls.d.ts +6 -3
  97. package/esm/src/guardrails/egress-urls.js +14 -22
  98. package/esm/src/guardrails/egress.d.ts +26 -86
  99. package/esm/src/guardrails/egress.js +59 -309
  100. package/esm/src/guardrails/error.d.ts +13 -8
  101. package/esm/src/guardrails/error.js +23 -18
  102. package/esm/src/guardrails/event-schemas.d.ts +46 -3
  103. package/esm/src/guardrails/event-schemas.js +12 -5
  104. package/esm/src/guardrails/events.d.ts +5 -1
  105. package/esm/src/guardrails/events.js +4 -1
  106. package/esm/src/guardrails/hints.d.ts +14 -0
  107. package/esm/src/guardrails/hints.js +57 -0
  108. package/esm/src/guardrails/hits.d.ts +7 -1
  109. package/esm/src/guardrails/hits.js +12 -1
  110. package/esm/src/guardrails/host-patterns.d.ts +85 -0
  111. package/esm/src/guardrails/host-patterns.js +173 -0
  112. package/esm/src/guardrails/injection-patterns.d.ts +6 -1
  113. package/esm/src/guardrails/injection-patterns.js +33 -1
  114. package/esm/src/guardrails/injection-reversed.d.ts +9 -0
  115. package/esm/src/guardrails/injection-reversed.js +49 -0
  116. package/esm/src/guardrails/injection.d.ts +17 -1
  117. package/esm/src/guardrails/injection.js +259 -36
  118. package/esm/src/guardrails/labels.d.ts +40 -0
  119. package/esm/src/guardrails/labels.js +874 -0
  120. package/esm/src/guardrails/live-outbound-gate.d.ts +9 -8
  121. package/esm/src/guardrails/live-outbound-gate.js +100 -107
  122. package/esm/src/guardrails/mod.d.ts +29 -21
  123. package/esm/src/guardrails/mod.js +18 -13
  124. package/esm/src/guardrails/network.d.ts +4 -0
  125. package/esm/src/guardrails/network.js +21 -19
  126. package/esm/src/guardrails/normalize.d.ts +15 -1
  127. package/esm/src/guardrails/normalize.js +34 -1
  128. package/esm/src/guardrails/policy.d.ts +2 -17
  129. package/esm/src/guardrails/policy.js +12 -41
  130. package/esm/src/guardrails/progressive-yield.d.ts +65 -24
  131. package/esm/src/guardrails/progressive-yield.js +191 -147
  132. package/esm/src/guardrails/prompt-echo.d.ts +4 -2
  133. package/esm/src/guardrails/prompt-echo.js +87 -6
  134. package/esm/src/guardrails/quota.d.ts +1 -0
  135. package/esm/src/guardrails/quota.js +1 -1
  136. package/esm/src/guardrails/rules.d.ts +20 -29
  137. package/esm/src/guardrails/rules.js +23 -30
  138. package/esm/src/guardrails/sanitize.d.ts +32 -15
  139. package/esm/src/guardrails/sanitize.js +100 -124
  140. package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
  141. package/esm/src/guardrails/sensitive-groups.js +12 -0
  142. package/esm/src/guardrails/sensitive.d.ts +16 -23
  143. package/esm/src/guardrails/sensitive.js +168 -47
  144. package/esm/src/guardrails/serialize.d.ts +1 -0
  145. package/esm/src/guardrails/testing.d.ts +4 -2
  146. package/esm/src/guardrails/testing.js +4 -2
  147. package/esm/src/guardrails/theorem-error.d.ts +4 -1
  148. package/esm/src/guardrails/theorem-error.js +3 -2
  149. package/esm/src/guardrails/thought-guard.d.ts +34 -13
  150. package/esm/src/guardrails/thought-guard.js +264 -64
  151. package/esm/src/guardrails/tool-directives.d.ts +29 -10
  152. package/esm/src/guardrails/tool-directives.js +133 -47
  153. package/esm/src/guardrails/tool-leak.d.ts +26 -0
  154. package/esm/src/guardrails/tool-leak.js +45 -0
  155. package/esm/src/guardrails/tool-result.d.ts +45 -14
  156. package/esm/src/guardrails/tool-result.js +94 -70
  157. package/esm/src/guardrails/types.d.ts +79 -71
  158. package/esm/src/guardrails/types.js +11 -7
  159. package/esm/src/host/client-turn.d.ts +29 -2
  160. package/esm/src/host/client-turn.js +46 -4
  161. package/esm/src/host/mint-trace.d.ts +1 -0
  162. package/esm/src/host/mint-trace.js +3 -2
  163. package/esm/src/host/mod.d.ts +2 -2
  164. package/esm/src/host/mod.js +1 -1
  165. package/esm/src/host/readStreamingJsonStringField.js +2 -43
  166. package/esm/src/host/reply.d.ts +6 -0
  167. package/esm/src/host/reply.js +7 -1
  168. package/esm/src/interface/blocks.d.ts +3 -0
  169. package/esm/src/interface/blocks.js +84 -14
  170. package/esm/src/interface/composer-actions.d.ts +4 -0
  171. package/esm/src/interface/composer-actions.js +5 -3
  172. package/esm/src/interface/draft.d.ts +6 -0
  173. package/esm/src/interface/draft.js +22 -11
  174. package/esm/src/interface/from-profile.d.ts +13 -1
  175. package/esm/src/interface/from-profile.js +66 -31
  176. package/esm/src/interface/history.d.ts +9 -3
  177. package/esm/src/interface/history.js +33 -24
  178. package/esm/src/interface/inputs.d.ts +1 -0
  179. package/esm/src/interface/inputs.js +3 -0
  180. package/esm/src/interface/mod.d.ts +4 -2
  181. package/esm/src/interface/mod.js +3 -2
  182. package/esm/src/interface/models.d.ts +7 -0
  183. package/esm/src/interface/models.js +5 -0
  184. package/esm/src/interface/pending.d.ts +9 -0
  185. package/esm/src/interface/pending.js +9 -3
  186. package/esm/src/interface/profile-interface.js +54 -40
  187. package/esm/src/interface/session.d.ts +12 -5
  188. package/esm/src/interface/session.js +17 -10
  189. package/esm/src/interface/stop.d.ts +13 -0
  190. package/esm/src/interface/stop.js +28 -0
  191. package/esm/src/interface/tool-calls.d.ts +14 -2
  192. package/esm/src/interface/tool-calls.js +64 -10
  193. package/esm/src/interface/tool-invoke.d.ts +2 -0
  194. package/esm/src/interface/tool-invoke.js +3 -1
  195. package/esm/src/interface/tool-media.d.ts +2 -0
  196. package/esm/src/interface/tool-media.js +2 -1
  197. package/esm/src/interface/types.d.ts +105 -40
  198. package/esm/src/interface/types.js +1 -0
  199. package/esm/src/kernel/api-catalog.d.ts +85 -0
  200. package/esm/src/kernel/api-catalog.js +229 -0
  201. package/esm/src/kernel/auth/crypto.d.ts +7 -2
  202. package/esm/src/kernel/auth/crypto.js +12 -10
  203. package/esm/src/kernel/auth/oauth.d.ts +2 -1
  204. package/esm/src/kernel/auth/oauth.js +23 -22
  205. package/esm/src/kernel/auth/typed-secret.js +2 -2
  206. package/esm/src/kernel/auth/types.d.ts +13 -0
  207. package/esm/src/kernel/checkpoint.d.ts +43 -0
  208. package/esm/src/kernel/checkpoint.js +58 -0
  209. package/esm/src/kernel/default-scope.d.ts +43 -5
  210. package/esm/src/kernel/default-scope.js +54 -5
  211. package/esm/src/kernel/engine/call-trace.d.ts +19 -0
  212. package/esm/src/kernel/engine/call-trace.js +29 -0
  213. package/esm/src/kernel/engine/compaction.d.ts +6 -5
  214. package/esm/src/kernel/engine/compaction.js +12 -11
  215. package/esm/src/kernel/engine/decision.d.ts +10 -8
  216. package/esm/src/kernel/engine/decision.js +173 -146
  217. package/esm/src/kernel/engine/embedding.d.ts +8 -0
  218. package/esm/src/kernel/engine/embedding.js +118 -0
  219. package/esm/src/kernel/engine/live-inbound.d.ts +14 -4
  220. package/esm/src/kernel/engine/live-inbound.js +36 -11
  221. package/esm/src/kernel/engine/live-ingress.d.ts +6 -0
  222. package/esm/src/kernel/engine/live-ingress.js +6 -1
  223. package/esm/src/kernel/engine/repair.js +12 -12
  224. package/esm/src/kernel/engine/runner/gates.d.ts +2 -2
  225. package/esm/src/kernel/engine/runner/gates.js +287 -101
  226. package/esm/src/kernel/engine/runner/mod.d.ts +19 -5
  227. package/esm/src/kernel/engine/runner/mod.js +107 -56
  228. package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
  229. package/esm/src/kernel/engine/runner/nested.js +134 -0
  230. package/esm/src/kernel/engine/runner/schema-validation.d.ts +24 -3
  231. package/esm/src/kernel/engine/runner/schema-validation.js +78 -4
  232. package/esm/src/kernel/engine/runner/stages.d.ts +1 -1
  233. package/esm/src/kernel/engine/runner/stages.js +1 -8
  234. package/esm/src/kernel/engine/runner/state.d.ts +33 -12
  235. package/esm/src/kernel/engine/runner/state.js +11 -1
  236. package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
  237. package/esm/src/kernel/engine/runner/step-order.js +165 -0
  238. package/esm/src/kernel/engine/runner/steps.d.ts +2 -2
  239. package/esm/src/kernel/engine/runner/steps.js +328 -169
  240. package/esm/src/kernel/engine/runner/stream.d.ts +42 -11
  241. package/esm/src/kernel/engine/runner/stream.js +197 -46
  242. package/esm/src/kernel/engine/runner/usage.d.ts +5 -5
  243. package/esm/src/kernel/engine/runner/usage.js +12 -14
  244. package/esm/src/kernel/engine/session/mod.d.ts +8 -6
  245. package/esm/src/kernel/engine/session/mod.js +360 -129
  246. package/esm/src/kernel/engine/session/session-trace.d.ts +10 -10
  247. package/esm/src/kernel/engine/session/session-trace.js +41 -30
  248. package/esm/src/kernel/engine/token-estimate.d.ts +10 -64
  249. package/esm/src/kernel/engine/token-estimate.js +14 -194
  250. package/esm/src/kernel/engine/tool-trace.d.ts +3 -3
  251. package/esm/src/kernel/engine/tool-trace.js +2 -1
  252. package/esm/src/kernel/engine/turn-trace.d.ts +8 -7
  253. package/esm/src/kernel/engine/turn-trace.js +28 -36
  254. package/esm/src/kernel/engine/usage.d.ts +6 -0
  255. package/esm/src/kernel/engine/usage.js +17 -0
  256. package/esm/src/kernel/interaction-parts.d.ts +3 -0
  257. package/esm/src/kernel/interaction-parts.js +18 -0
  258. package/esm/src/kernel/json.d.ts +10 -0
  259. package/esm/src/kernel/json.js +3 -0
  260. package/esm/src/kernel/mod.d.ts +38 -11
  261. package/esm/src/kernel/mod.js +22 -7
  262. package/esm/src/kernel/profile-graph.d.ts +11 -6
  263. package/esm/src/kernel/profile-graph.js +14 -7
  264. package/esm/src/kernel/profile-presence.d.ts +10 -1
  265. package/esm/src/kernel/profile-presence.js +90 -75
  266. package/esm/src/kernel/profile-scope.d.ts +7 -3
  267. package/esm/src/kernel/profile-scope.js +67 -55
  268. package/esm/src/kernel/protocols/binding.d.ts +65 -0
  269. package/esm/src/kernel/protocols/binding.js +125 -0
  270. package/esm/src/kernel/protocols/limits.d.ts +15 -0
  271. package/esm/src/kernel/protocols/limits.js +28 -0
  272. package/esm/src/kernel/protocols/mod.d.ts +5 -0
  273. package/esm/src/kernel/protocols/mod.js +5 -0
  274. package/esm/src/kernel/protocols/prices.d.ts +36 -0
  275. package/esm/src/kernel/protocols/prices.js +37 -0
  276. package/esm/src/kernel/protocols/protocol.d.ts +253 -0
  277. package/esm/src/kernel/protocols/protocol.js +253 -0
  278. package/esm/src/kernel/protocols/provider.d.ts +108 -0
  279. package/esm/src/kernel/protocols/provider.js +143 -0
  280. package/esm/src/kernel/protocols/runtime.d.ts +55 -0
  281. package/esm/src/kernel/protocols/runtime.js +534 -0
  282. package/esm/src/kernel/provider-budget.d.ts +32 -0
  283. package/esm/src/kernel/provider-budget.js +262 -0
  284. package/esm/src/kernel/provider-dispatch.d.ts +13 -0
  285. package/esm/src/kernel/provider-dispatch.js +36 -0
  286. package/esm/src/kernel/provider-live.d.ts +7 -0
  287. package/esm/src/kernel/provider-live.js +189 -0
  288. package/esm/src/kernel/provider-runtime.d.ts +57 -0
  289. package/esm/src/kernel/provider-runtime.js +524 -0
  290. package/esm/src/kernel/registry/attachments.d.ts +15 -4
  291. package/esm/src/kernel/registry/attachments.js +31 -22
  292. package/esm/src/kernel/registry/catalog.d.ts +6 -0
  293. package/esm/src/kernel/registry/catalog.js +9 -2
  294. package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
  295. package/esm/src/kernel/registry/embedding-rules.js +66 -0
  296. package/esm/src/kernel/registry/ingress.d.ts +6 -2
  297. package/esm/src/kernel/registry/ingress.js +55 -10
  298. package/esm/src/kernel/registry/kernel-registry.d.ts +3 -0
  299. package/esm/src/kernel/registry/kernel-registry.js +9 -2
  300. package/esm/src/kernel/registry/profile-outputs.js +4 -1
  301. package/esm/src/kernel/registry/profiles.d.ts +38 -14
  302. package/esm/src/kernel/registry/profiles.js +280 -205
  303. package/esm/src/kernel/registry/provider-request.d.ts +3 -3
  304. package/esm/src/kernel/registry/provider-request.js +5 -13
  305. package/esm/src/kernel/registry/resolve.d.ts +4 -1
  306. package/esm/src/kernel/registry/resolve.js +59 -58
  307. package/esm/src/kernel/registry/schemas.d.ts +3 -0
  308. package/esm/src/kernel/registry/schemas.js +3 -1
  309. package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
  310. package/esm/src/kernel/registry/slot-fill.js +22 -0
  311. package/esm/src/kernel/registry/system-prompt.js +7 -8
  312. package/esm/src/kernel/registry/vault.d.ts +14 -13
  313. package/esm/src/kernel/registry/vault.js +1 -14
  314. package/esm/src/kernel/schema.d.ts +100 -46
  315. package/esm/src/kernel/schema.js +499 -257
  316. package/esm/src/kernel/scope.d.ts +12 -5
  317. package/esm/src/kernel/scope.js +23 -3
  318. package/esm/src/kernel/stages.d.ts +38 -3
  319. package/esm/src/kernel/stages.js +82 -39
  320. package/esm/src/kernel/stop.d.ts +29 -6
  321. package/esm/src/kernel/stop.js +16 -4
  322. package/esm/src/kernel/system-parts.js +6 -6
  323. package/esm/src/kernel/tools/activity-label.d.ts +12 -6
  324. package/esm/src/kernel/tools/activity-label.js +258 -32
  325. package/esm/src/kernel/tools/agent.d.ts +66 -0
  326. package/esm/src/kernel/tools/agent.js +212 -0
  327. package/esm/src/kernel/tools/coordinate.d.ts +4 -0
  328. package/esm/src/kernel/tools/coordinate.js +165 -0
  329. package/esm/src/kernel/tools/events.d.ts +21 -6
  330. package/esm/src/kernel/tools/events.js +53 -18
  331. package/esm/src/kernel/tools/execute.d.ts +47 -11
  332. package/esm/src/kernel/tools/execute.js +508 -136
  333. package/esm/src/kernel/tools/gate-answer.d.ts +12 -2
  334. package/esm/src/kernel/tools/gate-answer.js +17 -6
  335. package/esm/src/kernel/tools/handler-events.d.ts +45 -0
  336. package/esm/src/kernel/tools/handler-events.js +106 -0
  337. package/esm/src/kernel/tools/harness.d.ts +1 -0
  338. package/esm/src/kernel/tools/harness.js +2 -1
  339. package/esm/src/kernel/tools/http-limit.d.ts +27 -0
  340. package/esm/src/kernel/tools/http-limit.js +85 -0
  341. package/esm/src/kernel/tools/invoke.d.ts +27 -5
  342. package/esm/src/kernel/tools/invoke.js +223 -70
  343. package/esm/src/kernel/tools/mcp-sessions.d.ts +4 -1
  344. package/esm/src/kernel/tools/mcp-sessions.js +13 -8
  345. package/esm/src/kernel/tools/mod.d.ts +4 -3
  346. package/esm/src/kernel/tools/mod.js +3 -2
  347. package/esm/src/kernel/tools/model-text.d.ts +10 -5
  348. package/esm/src/kernel/tools/model-text.js +18 -12
  349. package/esm/src/kernel/tools/operation.d.ts +76 -0
  350. package/esm/src/kernel/tools/operation.js +100 -0
  351. package/esm/src/kernel/tools/page-answer.d.ts +8 -0
  352. package/esm/src/kernel/tools/page-answer.js +19 -0
  353. package/esm/src/kernel/tools/permission.d.ts +11 -2
  354. package/esm/src/kernel/tools/permission.js +12 -12
  355. package/esm/src/kernel/tools/project.d.ts +4 -1
  356. package/esm/src/kernel/tools/project.js +32 -2
  357. package/esm/src/kernel/tools/registry.d.ts +9 -2
  358. package/esm/src/kernel/tools/registry.js +69 -10
  359. package/esm/src/kernel/tools/remote.d.ts +40 -6
  360. package/esm/src/kernel/tools/remote.js +219 -92
  361. package/esm/src/kernel/tools/resolve.d.ts +3 -0
  362. package/esm/src/kernel/tools/resolve.js +12 -4
  363. package/esm/src/kernel/tools/run.d.ts +28 -0
  364. package/esm/src/kernel/tools/run.js +86 -0
  365. package/esm/src/kernel/tools/schema.d.ts +3 -3
  366. package/esm/src/kernel/tools/schema.js +21 -100
  367. package/esm/src/kernel/tools/signed-in-fetch.d.ts +2 -1
  368. package/esm/src/kernel/tools/signed-in-fetch.js +3 -3
  369. package/esm/src/kernel/tools/stage-run.d.ts +27 -4
  370. package/esm/src/kernel/tools/stage-run.js +75 -17
  371. package/esm/src/kernel/tools/types.d.ts +235 -25
  372. package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
  373. package/esm/src/kernel/tools/unchecked-output.js +18 -0
  374. package/esm/src/kernel/turn-events.d.ts +208 -31
  375. package/esm/src/kernel/turn-events.js +127 -9
  376. package/esm/src/kernel/types.d.ts +302 -161
  377. package/esm/src/kernel/util/base64.d.ts +2 -0
  378. package/esm/src/kernel/util/base64.js +2 -0
  379. package/esm/src/kernel/util/partial-json.d.ts +23 -0
  380. package/esm/src/kernel/util/partial-json.js +128 -0
  381. package/esm/src/kernel/util/record.d.ts +1 -0
  382. package/esm/src/kernel/util/record.js +1 -0
  383. package/esm/src/observability/destinations.d.ts +5 -0
  384. package/esm/src/observability/destinations.js +7 -2
  385. package/esm/src/observability/jsonl.d.ts +2 -2
  386. package/esm/src/observability/jsonl.js +15 -22
  387. package/esm/src/observability/mod.d.ts +3 -3
  388. package/esm/src/observability/mod.js +2 -2
  389. package/esm/src/observability/openinference.d.ts +1 -1
  390. package/esm/src/observability/openinference.js +3 -3
  391. package/esm/src/observability/otlp.d.ts +3 -0
  392. package/esm/src/observability/otlp.js +3 -3
  393. package/esm/src/observability/phoenix.d.ts +1 -0
  394. package/esm/src/observability/policy.d.ts +3 -0
  395. package/esm/src/observability/policy.js +5 -1
  396. package/esm/src/observability/resolve-policy.js +11 -5
  397. package/esm/src/observability/spans.d.ts +8 -2
  398. package/esm/src/observability/spans.js +21 -5
  399. package/esm/src/observability/trace-catalog.d.ts +19 -2
  400. package/esm/src/observability/trace-catalog.js +128 -87
  401. package/esm/src/observability/trace-record.js +22 -17
  402. package/esm/src/observability/trace-schema.d.ts +3 -0
  403. package/esm/src/observability/trace-schema.js +1 -1
  404. package/esm/src/observability/trace-sink.d.ts +1 -0
  405. package/esm/src/observability/trace-sink.js +1 -1
  406. package/esm/src/observability/trace-span.d.ts +7 -1
  407. package/esm/src/observability/trace-span.js +3 -1
  408. package/esm/src/observability/trace.d.ts +2 -0
  409. package/esm/src/observability/trace.js +4 -2
  410. package/esm/src/observability/types.d.ts +35 -11
  411. package/esm/src/observability/types.js +1 -1
  412. package/esm/src/presets/google/speech-voices.d.ts +1 -0
  413. package/esm/src/presets/google-limits.d.ts +1 -0
  414. package/esm/src/presets/google.d.ts +27 -12
  415. package/esm/src/presets/google.js +34 -25
  416. package/esm/src/presets/local.d.ts +26 -0
  417. package/esm/src/presets/local.js +30 -0
  418. package/esm/src/presets/mod.d.ts +5 -4
  419. package/esm/src/presets/mod.js +4 -4
  420. package/esm/src/presets/openrouter.d.ts +14 -1
  421. package/esm/src/presets/openrouter.js +19 -1
  422. package/esm/src/providers/embedding-limits.d.ts +7 -0
  423. package/esm/src/providers/embedding-limits.js +12 -0
  424. package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
  425. package/esm/src/providers/gemini/embedding-protocol.js +125 -0
  426. package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
  427. package/esm/src/providers/gemini/interactions-protocol.js +105 -0
  428. package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
  429. package/esm/src/providers/gemini/live-protocol.js +191 -0
  430. package/esm/src/providers/gemini/prices.d.ts +3 -0
  431. package/esm/src/providers/gemini/prices.js +63 -0
  432. package/esm/src/providers/gemini/provider.d.ts +7 -0
  433. package/esm/src/providers/gemini/provider.js +39 -0
  434. package/esm/src/providers/google/builtins.d.ts +14 -0
  435. package/esm/src/providers/google/builtins.js +57 -0
  436. package/esm/src/providers/google/grounding.d.ts +4 -4
  437. package/esm/src/providers/google/interactions/framing.d.ts +20 -8
  438. package/esm/src/providers/google/interactions/framing.js +85 -44
  439. package/esm/src/providers/google/interactions/steps.d.ts +5 -5
  440. package/esm/src/providers/google/interactions/steps.js +4 -4
  441. package/esm/src/providers/google/interactions/stream.d.ts +10 -11
  442. package/esm/src/providers/google/interactions/stream.js +33 -100
  443. package/esm/src/providers/google/live/framing.d.ts +15 -5
  444. package/esm/src/providers/google/live/framing.js +25 -25
  445. package/esm/src/providers/google/live/stream.d.ts +6 -44
  446. package/esm/src/providers/google/live/stream.js +3 -209
  447. package/esm/src/providers/google/urls.d.ts +1 -3
  448. package/esm/src/providers/google/urls.js +1 -3
  449. package/esm/src/providers/google/usage.js +2 -2
  450. package/esm/src/providers/live.d.ts +6 -0
  451. package/esm/src/providers/live.js +6 -0
  452. package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
  453. package/esm/src/providers/local/embedding-protocol.js +60 -0
  454. package/esm/src/providers/local/provider.d.ts +7 -0
  455. package/esm/src/providers/local/provider.js +28 -0
  456. package/esm/src/providers/mod.d.ts +28 -7
  457. package/esm/src/providers/mod.js +19 -3
  458. package/esm/src/providers/open-ai/protocol.d.ts +3 -0
  459. package/esm/src/providers/open-ai/protocol.js +189 -0
  460. package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
  461. package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
  462. package/esm/src/providers/openrouter/image.d.ts +0 -9
  463. package/esm/src/providers/openrouter/image.js +0 -153
  464. package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
  465. package/esm/src/providers/openrouter/images-protocol.js +82 -0
  466. package/esm/src/providers/openrouter/openai/compat.d.ts +2 -2
  467. package/esm/src/providers/openrouter/openai/compat.js +6 -6
  468. package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
  469. package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
  470. package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
  471. package/esm/src/providers/openrouter/protocol.d.ts +8 -0
  472. package/esm/src/providers/openrouter/protocol.js +171 -0
  473. package/esm/src/providers/openrouter/provider.d.ts +10 -0
  474. package/esm/src/providers/openrouter/provider.js +50 -0
  475. package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
  476. package/esm/src/providers/shared/carried-tool-files.js +43 -0
  477. package/esm/src/providers/shared/pcm.js +2 -2
  478. package/esm/src/providers/shared/protocol-events.d.ts +8 -0
  479. package/esm/src/providers/shared/protocol-events.js +20 -0
  480. package/esm/src/providers/shared/response-identity.d.ts +2 -2
  481. package/esm/src/providers/shared/retry.d.ts +17 -0
  482. package/esm/src/providers/shared/retry.js +90 -0
  483. package/esm/src/providers/shared/sse.d.ts +0 -4
  484. package/esm/src/providers/shared/sse.js +50 -36
  485. package/esm/src/providers/shared/tool-args.d.ts +6 -7
  486. package/esm/src/providers/shared/tool-args.js +10 -6
  487. package/esm/src/providers/shared/tool-draft.d.ts +16 -0
  488. package/esm/src/providers/shared/tool-draft.js +14 -0
  489. package/esm/src/providers/shared/upstream-tap.d.ts +2 -2
  490. package/esm/src/providers/shared/upstream-tape.js +1 -1
  491. package/esm/src/providers/system-one/protocol.d.ts +8 -0
  492. package/esm/src/providers/system-one/protocol.js +93 -0
  493. package/esm/src/providers/types.d.ts +48 -16
  494. package/esm/src/providers/types.js +2 -1
  495. package/esm/src/providers/typesafe/provider.d.ts +7 -0
  496. package/esm/src/providers/typesafe/provider.js +24 -0
  497. package/esm/src/surface/formats.d.ts +19 -1
  498. package/esm/src/surface/formats.js +68 -29
  499. package/esm/src/surface/mod.d.ts +4 -2
  500. package/esm/src/surface/mod.js +4 -2
  501. package/esm/src/surface/runtime.d.ts +4 -0
  502. package/esm/src/surface/runtime.js +2 -0
  503. package/esm/src/surface/tools.d.ts +2 -8
  504. package/esm/src/surface/tools.js +4 -22
  505. package/esm/src/surface/types.d.ts +6 -0
  506. package/package.json +5 -13
  507. package/esm/src/cli/commands/egress-compile.d.ts +0 -17
  508. package/esm/src/cli/commands/egress-compile.js +0 -25
  509. package/esm/src/guardrails/egress-policy.d.ts +0 -27
  510. package/esm/src/guardrails/egress-policy.js +0 -76
  511. package/esm/src/guardrails/egress-rules.d.ts +0 -54
  512. package/esm/src/guardrails/egress-rules.js +0 -49
  513. package/esm/src/guardrails/lexicon.d.ts +0 -30
  514. package/esm/src/guardrails/lexicon.js +0 -478
  515. package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
  516. package/esm/src/kernel/engine/media-probe/audio.js +0 -342
  517. package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
  518. package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
  519. package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
  520. package/esm/src/kernel/engine/media-probe/image.js +0 -171
  521. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
  522. package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
  523. package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
  524. package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
  525. package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
  526. package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
  527. package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
  528. package/esm/src/kernel/engine/media-probe/opus.js +0 -23
  529. package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
  530. package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
  531. package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
  532. package/esm/src/kernel/engine/media-probe/video.js +0 -49
  533. package/esm/src/presets/typesafe.d.ts +0 -2
  534. package/esm/src/presets/typesafe.js +0 -2
  535. package/esm/src/providers/create-provider.d.ts +0 -21
  536. package/esm/src/providers/create-provider.js +0 -90
  537. package/esm/src/providers/decision/usage.d.ts +0 -3
  538. package/esm/src/providers/decision/usage.js +0 -25
  539. package/esm/src/providers/google/interactions/mod.d.ts +0 -2
  540. package/esm/src/providers/google/interactions/mod.js +0 -2
  541. package/esm/src/providers/google/keys.d.ts +0 -20
  542. package/esm/src/providers/google/keys.js +0 -87
  543. package/esm/src/providers/google/live/mod.d.ts +0 -7
  544. package/esm/src/providers/google/live/mod.js +0 -7
  545. package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
  546. package/esm/src/providers/google/live/openapi-schema.js +0 -42
  547. package/esm/src/providers/google/live/session.d.ts +0 -14
  548. package/esm/src/providers/google/live/session.js +0 -150
  549. package/esm/src/providers/local/local.d.ts +0 -12
  550. package/esm/src/providers/local/local.js +0 -186
  551. package/esm/src/providers/local/mod.d.ts +0 -8
  552. package/esm/src/providers/local/mod.js +0 -8
  553. package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
  554. package/esm/src/providers/openrouter/cache-control.js +0 -4
  555. package/esm/src/providers/openrouter/chat.d.ts +0 -64
  556. package/esm/src/providers/openrouter/chat.js +0 -490
  557. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
  558. package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
  559. package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
  560. package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
  561. package/esm/src/providers/openrouter/speech.d.ts +0 -18
  562. package/esm/src/providers/openrouter/speech.js +0 -109
  563. package/esm/src/providers/probe.d.ts +0 -5
  564. package/esm/src/providers/probe.js +0 -15
  565. package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
  566. package/esm/src/providers/shared/builtin-wire.js +0 -9
  567. package/esm/src/providers/shared/vault.d.ts +0 -13
  568. package/esm/src/providers/shared/vault.js +0 -41
@@ -1,13 +1,11 @@
1
- import { kindOfHttpStatus, TheoremError, throwIfAborted, } from '../../guardrails/error.js';
2
- import { resolveTraceWriter } from '../../observability/policy.js';
3
- import { writeSpans } from '../../observability/trace.js';
4
- import { startTrace, traceJson } from '../../observability/trace-span.js';
5
- import { decisionUsage } from '../../providers/decision/usage.js';
1
+ import { TheoremError, throwIfAborted } from '../../guardrails/error.js';
2
+ import { labelText } from '../../guardrails/labels.js';
3
+ import { traceJson } from '../../observability/trace-span.js';
4
+ import { guardedCall } from '../provider-runtime.js';
6
5
  import { soleModelId } from '../registry/sole-model.js';
7
6
  import { isRecord } from '../util/record.js';
8
- import { endThrownSpan } from './turn-trace.js';
9
- const TYPESAFE_SYSTEM_ONE_URL = 'https://api.typesafe.ai/v1/systemone';
10
- const OPENROUTER_DECISIONS_URL = 'https://openrouter.ai/api/alpha/decisions';
7
+ import { tracedCall } from './call-trace.js';
8
+ /** Where the provider takes decision requests, as its preset states. */
11
9
  const DECISION_ERROR_KINDS = {
12
10
  invalid_request: 'request',
13
11
  authentication: 'auth',
@@ -20,12 +18,15 @@ const DECISION_ERROR_KINDS = {
20
18
  malformed_response: 'bad_response',
21
19
  disclosure_blocked: 'blocked',
22
20
  };
23
- /** A normalized native-decision failure; response bodies are deliberately omitted. */
21
+ /**
22
+ * A normalized native-decision failure; response bodies are deliberately omitted. What the
23
+ * provider path threw is its `cause`, and a failure the framework named reads as that failure.
24
+ */
24
25
  export class DecisionError extends TheoremError {
25
26
  code;
26
27
  status;
27
- constructor(code, message, status) {
28
- super(DECISION_ERROR_KINDS[code], message);
28
+ constructor(code, message, status, options) {
29
+ super(DECISION_ERROR_KINDS[code], message, options);
29
30
  this.code = code;
30
31
  this.status = status;
31
32
  }
@@ -34,7 +35,7 @@ function requireDecisionProfile(registry, id) {
34
35
  const profile = registry.profiles.get(id);
35
36
  if (profile.type !== 'decision') {
36
37
  throw new TheoremError('request',
37
- // lexicon-exempt: developer contract error
38
+ // labels-exempt: developer contract error
38
39
  `runDecision requires profile.type 'decision' (got '${profile.type}' for ${profile.id})`);
39
40
  }
40
41
  return profile;
@@ -50,7 +51,7 @@ function decisionModel(profile) {
50
51
  }
51
52
  function finite(value, path, min = 0, max = 1) {
52
53
  if (typeof value !== 'number' || !Number.isFinite(value) || value < min || value > max) {
53
- throw new DecisionError('malformed_response', `${path} is outside its valid range`); // lexicon-exempt: upstream contract error
54
+ throw new DecisionError('malformed_response', `${path} is outside its valid range`); // labels-exempt: upstream contract error
54
55
  }
55
56
  return value;
56
57
  }
@@ -58,31 +59,45 @@ function distribution(value, labels, path) {
58
59
  if (!isRecord(value) ||
59
60
  Object.keys(value).length !== labels.length ||
60
61
  labels.some((key) => !Object.hasOwn(value, key))) {
61
- throw new DecisionError('malformed_response', `${path} does not match declared labels`); // lexicon-exempt: upstream contract error
62
+ throw new DecisionError('malformed_response', `${path} does not match declared labels`); // labels-exempt: upstream contract error
62
63
  }
63
64
  const out = Object.create(null);
64
65
  for (const label of labels)
65
66
  out[label] = finite(value[label], `${path}.${label}`);
66
67
  const total = Object.values(out).reduce((sum, item) => sum + item, 0);
67
68
  if (Math.abs(total - 1) > 0.001) {
68
- throw new DecisionError('malformed_response', `${path} must sum to one`); // lexicon-exempt: upstream contract error
69
+ throw new DecisionError('malformed_response', `${path} must sum to one`); // labels-exempt: upstream contract error
69
70
  }
70
71
  return out;
71
72
  }
73
+ /** A box's four edges, each a fraction of the image, with the low edge before the high one. */
74
+ function box(value, path) {
75
+ if (!isRecord(value))
76
+ throw new DecisionError('malformed_response', `${path} is invalid`); // labels-exempt: upstream contract error
77
+ const edges = {
78
+ top: finite(value.top, `${path}.top`),
79
+ bottom: finite(value.bottom, `${path}.bottom`),
80
+ left: finite(value.left, `${path}.left`),
81
+ right: finite(value.right, `${path}.right`),
82
+ };
83
+ if (edges.left >= edges.right || edges.top >= edges.bottom)
84
+ throw new DecisionError('malformed_response', `${path} has an edge out of order`); // labels-exempt: upstream contract error
85
+ return edges;
86
+ }
72
87
  /** A score's legend: text for every declared level. */
73
88
  function legend(value, labels, path) {
74
89
  if (!isRecord(value) ||
75
90
  Object.keys(value).length !== labels.length ||
76
91
  labels.some((label) => !Object.hasOwn(value, label)) ||
77
92
  Object.values(value).some((text) => typeof text !== 'string' || !text.trim())) {
78
- throw new DecisionError('malformed_response', `${path} is invalid`); // lexicon-exempt: upstream contract error
93
+ throw new DecisionError('malformed_response', `${path} is invalid`); // labels-exempt: upstream contract error
79
94
  }
80
95
  return value;
81
96
  }
82
97
  function validateAnswers(raw, questions) {
83
98
  if (!isRecord(raw) || Object.keys(raw).length !== Object.keys(questions).length) {
84
99
  throw new DecisionError('malformed_response',
85
- // lexicon-exempt: upstream contract error
100
+ // labels-exempt: upstream contract error
86
101
  'Decision provider returned an incomplete answer set');
87
102
  }
88
103
  const answers = Object.create(null);
@@ -90,14 +105,14 @@ function validateAnswers(raw, questions) {
90
105
  const answer = raw[id];
91
106
  if (!isRecord(answer) || answer.type !== question.type) {
92
107
  throw new DecisionError('malformed_response',
93
- // lexicon-exempt: upstream contract error
108
+ // labels-exempt: upstream contract error
94
109
  `Decision provider returned an invalid answer for '${id}'`);
95
110
  }
96
111
  if (question.type === 'choice') {
97
112
  const labels = Object.keys(question.criteria);
98
113
  if (typeof answer.choice !== 'string' || !labels.includes(answer.choice)) {
99
114
  throw new DecisionError('malformed_response',
100
- // lexicon-exempt: upstream contract error
115
+ // labels-exempt: upstream contract error
101
116
  `Decision provider returned an undeclared choice for '${id}'`);
102
117
  }
103
118
  answers[id] = {
@@ -110,6 +125,13 @@ function validateAnswers(raw, questions) {
110
125
  else if (question.type === 'noul') {
111
126
  answers[id] = { type: 'noul', noul: finite(answer.noul, `${id}.noul`) };
112
127
  }
128
+ else if (question.type === 'box') {
129
+ answers[id] = {
130
+ type: 'box',
131
+ box: box(answer.box, `${id}.box`),
132
+ confidence: finite(answer.confidence, `${id}.confidence`),
133
+ };
134
+ }
113
135
  else {
114
136
  const labels = question.criteria.map((_, index) => String(index));
115
137
  answers[id] = {
@@ -161,22 +183,22 @@ function isJson(value) {
161
183
  function validateQuestion(id, question) {
162
184
  if (!isRecord(question) || !id.trim() || !isDecisionEntry(question.instructions)) {
163
185
  throw new DecisionError('invalid_request',
164
- // lexicon-exempt: developer contract error
186
+ // labels-exempt: developer contract error
165
187
  `Decision question '${id}' must include instructions`);
166
188
  }
167
- if (question.type === 'noul' && question.criteria === undefined)
189
+ if ((question.type === 'noul' || question.type === 'box') && question.criteria === undefined)
168
190
  return;
169
191
  if (typeof question.type !== 'string' ||
170
192
  !['choice', 'noul', 'score'].includes(question.type) ||
171
193
  (question.type === 'score' ? !Array.isArray(question.criteria) : !isRecord(question.criteria))) {
172
- throw new DecisionError('invalid_request', `Decision question '${id}' has invalid criteria`); // lexicon-exempt: developer contract error
194
+ throw new DecisionError('invalid_request', `Decision question '${id}' has invalid criteria`); // labels-exempt: developer contract error
173
195
  }
174
196
  const criteria = Array.isArray(question.criteria)
175
197
  ? question.criteria
176
198
  : Object.values(question.criteria);
177
199
  if (!criteria.length || !criteria.every(isDecisionEntry)) {
178
200
  throw new DecisionError('invalid_request',
179
- // lexicon-exempt: developer contract error
201
+ // labels-exempt: developer contract error
180
202
  `Decision ${question.type} '${id}' must declare criteria`);
181
203
  }
182
204
  }
@@ -185,35 +207,89 @@ export function validateDecisionRequest(request, profile) {
185
207
  throwIfAborted(request.signal);
186
208
  if (request.model !== undefined) {
187
209
  throw new DecisionError('invalid_request',
188
- // lexicon-exempt: developer contract error
210
+ // labels-exempt: developer contract error
189
211
  'Decision requests do not select a model; the profile runs its one model');
190
212
  }
191
213
  if (request.state === null || !isJson(request.state)) {
192
- throw new DecisionError('invalid_request', 'Decision state must be non-null JSON'); // lexicon-exempt: developer contract error
214
+ throw new DecisionError('invalid_request', 'Decision state must be non-null JSON'); // labels-exempt: developer contract error
193
215
  }
194
216
  let serialized;
195
217
  try {
196
218
  serialized = JSON.stringify(request.state);
197
219
  }
198
220
  catch {
199
- // lexicon-exempt: developer contract error
221
+ // labels-exempt: developer contract error
200
222
  throw new DecisionError('invalid_request', 'Decision state cannot be serialized as JSON');
201
223
  }
202
224
  const bytes = new TextEncoder().encode(serialized).byteLength;
203
225
  if (profile.inputs.maxStateBytes !== undefined && bytes > profile.inputs.maxStateBytes) {
204
226
  throw new DecisionError('invalid_request',
205
- // lexicon-exempt: developer contract error
227
+ // labels-exempt: developer contract error
206
228
  `Decision state exceeds ${profile.inputs.maxStateBytes} bytes`);
207
229
  }
208
230
  if (!isRecord(request.questions) ||
209
231
  !isJson(request.questions) ||
210
232
  Object.keys(request.questions).length === 0) {
211
233
  throw new DecisionError('invalid_request',
212
- // lexicon-exempt: developer contract error
234
+ // labels-exempt: developer contract error
213
235
  'Decision request must declare at least one question');
214
236
  }
215
237
  for (const [id, question] of Object.entries(request.questions))
216
238
  validateQuestion(id, question);
239
+ if (request.assets !== undefined)
240
+ validateAssets(request.assets);
241
+ for (const [id, question] of Object.entries(request.questions))
242
+ validateBoxImage(id, question, request.state, request.assets);
243
+ }
244
+ function stateAt(state, path) {
245
+ let value = state;
246
+ for (const step of path.split('.')) {
247
+ if (!isRecord(value) && !Array.isArray(value))
248
+ return undefined;
249
+ value = Array.isArray(value) ? value[Number(step)] : value[step];
250
+ }
251
+ return value;
252
+ }
253
+ /** A box's image names an image the request holds, itself or through the state field it gives. */
254
+ function validateBoxImage(id, question, state, assets) {
255
+ if (!isRecord(question) || question.image === undefined)
256
+ return;
257
+ const image = question.image;
258
+ const reference = typeof image === 'string' && !assets?.[image] ? stateAt(state, image) : image;
259
+ if (question.type !== 'box' || typeof reference !== 'string' || assets?.[reference] === undefined)
260
+ throw new DecisionError('invalid_request',
261
+ // labels-exempt: developer contract error
262
+ `Decision question '${id}' has an image that is neither a held image nor a state field holding one`);
263
+ }
264
+ /** The question as a provider reads it: a box's image said in its instructions, not as a field. */
265
+ function providerQuestion(question, assets) {
266
+ if (question.type !== 'box' || question.image === undefined)
267
+ return question;
268
+ const { image, instructions } = question;
269
+ const hint = labelText('decision.box_image', {
270
+ image: assets?.[image] ? image : `\`${image}\``,
271
+ });
272
+ return {
273
+ type: 'box',
274
+ instructions: typeof instructions === 'string' ? `${instructions} ${hint}` : [instructions, hint],
275
+ };
276
+ }
277
+ const BASE64 = /^[A-Za-z0-9+/]+={0,2}$/;
278
+ /** Only what any provider needs: a known image type and bare, padded base64. The provider holds its own limits. */
279
+ function validateAssets(assets) {
280
+ if (!isRecord(assets) || Object.keys(assets).length === 0)
281
+ throw new DecisionError('invalid_request', 'Decision assets must name at least one image'); // labels-exempt: developer contract error
282
+ for (const [reference, asset] of Object.entries(assets)) {
283
+ if (!reference.trim() ||
284
+ !isRecord(asset) ||
285
+ (asset.mimeType !== 'image/png' && asset.mimeType !== 'image/jpeg') ||
286
+ typeof asset.data !== 'string' ||
287
+ asset.data.length % 4 !== 0 ||
288
+ !BASE64.test(asset.data))
289
+ throw new DecisionError('invalid_request',
290
+ // labels-exempt: developer contract error
291
+ `Decision asset '${reference}' must be PNG or JPEG bytes as padded base64`);
292
+ }
217
293
  }
218
294
  function isDecisionEntry(value) {
219
295
  const pending = [value];
@@ -234,95 +310,18 @@ function isDecisionEntry(value) {
234
310
  }
235
311
  return true;
236
312
  }
237
- function errorForStatus(status) {
238
- if (status === 400 || status === 409 || status === 413 || status === 422)
239
- return new DecisionError('invalid_request', 'Provider rejected the decision request', status); // lexicon-exempt: upstream contract error
240
- if (status === 401)
241
- return new DecisionError('authentication', 'Decision provider authentication failed', status); // lexicon-exempt: upstream contract error
242
- if (status === 402 || status === 403)
243
- return new DecisionError('permission', 'Decision provider refused the request', status); // lexicon-exempt: upstream contract error
244
- if (status === 429)
245
- return new DecisionError('rate_limited', 'Decision provider rate limited the request', status); // lexicon-exempt: upstream contract error
246
- if (kindOfHttpStatus(status) === 'timeout')
247
- return new DecisionError('timeout', 'Decision provider request timed out', status); // lexicon-exempt: upstream contract error
248
- return new DecisionError('unavailable', 'Decision provider is unavailable', status); // lexicon-exempt: upstream contract error
249
- }
250
313
  async function enforceDisclosure(profile, model, provider, request) {
251
314
  const verdict = await profile.guardrails?.disclosure?.enforce(request.state, {
252
315
  destination: provider,
253
316
  profileId: profile.id,
254
317
  model,
255
318
  questionIds: Object.keys(request.questions),
319
+ ...(request.assets ? { assets: request.assets } : {}),
256
320
  });
257
321
  if (verdict?.action === 'block') {
258
- throw new DecisionError('disclosure_blocked', 'Decision disclosure was blocked'); // lexicon-exempt: developer contract error
259
- }
260
- }
261
- function requireApiKey(profile, binding, options) {
262
- const keySlot = binding.key ?? profile.key;
263
- const apiKey = keySlot ? options.vault?.[keySlot]?.trim() : undefined;
264
- if (!apiKey)
265
- throw new DecisionError('authentication', `the vault has no key in slot '${keySlot}'`); // lexicon-exempt: developer contract error
266
- return apiKey;
267
- }
268
- async function sendDecisionRequest(args) {
269
- try {
270
- const response = await (args.options.fetch ?? globalThis.fetch)(args.options.endpoint ??
271
- (args.provider === 'openrouter' ? OPENROUTER_DECISIONS_URL : TYPESAFE_SYSTEM_ONE_URL), {
272
- method: 'POST',
273
- headers: {
274
- Authorization: `Bearer ${args.apiKey}`,
275
- 'Content-Type': 'application/json',
276
- Accept: 'application/json',
277
- },
278
- body: JSON.stringify({
279
- model: args.apiId,
280
- state: args.request.state,
281
- questions: args.request.questions,
282
- }),
283
- signal: args.signal,
284
- });
285
- if (!response.ok)
286
- throw errorForStatus(response.status);
287
- return response;
288
- }
289
- catch (error) {
290
- if (error instanceof DecisionError)
291
- throw error;
292
- if (args.request.signal?.aborted)
293
- throw new DecisionError('cancelled', 'Decision request was cancelled'); // lexicon-exempt: developer contract error
294
- if (args.signal.aborted)
295
- throw new DecisionError('timeout', 'Decision request timed out'); // lexicon-exempt: developer contract error
296
- throw new DecisionError('network', 'Decision provider network request failed'); // lexicon-exempt: upstream contract error
322
+ throw new DecisionError('disclosure_blocked', 'Decision disclosure was blocked'); // labels-exempt: developer contract error
297
323
  }
298
324
  }
299
- async function resultFromResponse(response, questions, binding, signal, requestSignal) {
300
- let body;
301
- try {
302
- body = await response.json();
303
- }
304
- catch (error) {
305
- if (requestSignal?.aborted)
306
- throw new DecisionError('cancelled', 'Decision request was cancelled'); // lexicon-exempt: developer contract error
307
- if (signal.aborted)
308
- throw new DecisionError('timeout', 'Decision request timed out'); // lexicon-exempt: developer contract error
309
- if (!(error instanceof SyntaxError))
310
- throw new DecisionError('network', 'Decision response body could not be read'); // lexicon-exempt: upstream contract error
311
- throw new DecisionError('malformed_response', 'Decision provider returned non-JSON output'); // lexicon-exempt: upstream contract error
312
- }
313
- if (!isRecord(body) ||
314
- typeof body.model !== 'string' ||
315
- !body.model.trim() ||
316
- !isRecord(body.answers)) {
317
- throw new DecisionError('malformed_response', 'Decision response has an invalid shape'); // lexicon-exempt: upstream contract error
318
- }
319
- const usage = decisionUsage(body.usage, binding, body.model);
320
- return {
321
- model: body.model,
322
- answers: validateAnswers(body.answers, questions),
323
- ...(usage ? { usage } : {}),
324
- };
325
- }
326
325
  function decisionSpanAttributes(profile, modelId, binding, request) {
327
326
  return {
328
327
  'gen_ai.operation.name': 'decide',
@@ -333,6 +332,15 @@ function decisionSpanAttributes(profile, modelId, binding, request) {
333
332
  'theorem.decision.contract': profile.decision.contract,
334
333
  'theorem.decision.state': traceJson(request.state),
335
334
  'theorem.decision.questions': traceJson(request.questions),
335
+ ...(request.assets
336
+ ? {
337
+ // invariant: Image bytes never reach a trace; it keeps each image's type and size.
338
+ 'theorem.decision.assets': traceJson(Object.fromEntries(Object.entries(request.assets).map(([reference, { mimeType, data }]) => [
339
+ reference,
340
+ { mimeType, bytes: data.length },
341
+ ]))),
342
+ }
343
+ : {}),
336
344
  };
337
345
  }
338
346
  function recordResult(root, result) {
@@ -350,32 +358,58 @@ function recordResult(root, result) {
350
358
  : {}),
351
359
  });
352
360
  }
353
- async function decide(profile, [modelId, binding], request, options) {
361
+ function decisionProviderError(error) {
362
+ if (error instanceof DecisionError)
363
+ return error;
364
+ const kind = error instanceof TheoremError
365
+ ? error.kind
366
+ : error instanceof TypeError
367
+ ? 'network'
368
+ : 'bad_response';
369
+ const codes = {
370
+ auth: 'authentication',
371
+ rate_limit: 'rate_limited',
372
+ network: 'network',
373
+ unavailable: 'unavailable',
374
+ timeout: 'timeout',
375
+ cancelled: 'cancelled',
376
+ request: 'invalid_request',
377
+ unsupported: 'invalid_request',
378
+ };
379
+ const code = kind === 'auth' && isRecord(error) && error.status === 403
380
+ ? 'permission'
381
+ : (codes[kind] ?? 'malformed_response');
382
+ return new DecisionError(code,
383
+ // why: A framework failure's message holds no response body, and says what stopped the decision.
384
+ error instanceof TheoremError ? error.message : labelText('provider.decision_failed'), isRecord(error) && typeof error.status === 'number' ? error.status : undefined, { cause: error });
385
+ }
386
+ async function decide(registry, profile, [modelId, binding], request, options) {
354
387
  throwIfAborted(request.signal);
388
+ const provider = registry.providers.require(binding.provider, binding.apiId);
355
389
  await enforceDisclosure(profile, modelId, binding.provider, request);
356
390
  throwIfAborted(request.signal);
357
- const apiKey = requireApiKey(profile, binding, options);
358
- const controller = new AbortController();
359
- const timeout = binding.timeoutMs
360
- ? setTimeout(() => controller.abort(), binding.timeoutMs)
361
- : undefined;
362
- const abort = () => controller.abort();
363
- request.signal?.addEventListener('abort', abort, { once: true });
364
391
  try {
365
- const response = await sendDecisionRequest({
366
- request,
392
+ const call = guardedCall(provider, binding, 'decision', options, {
393
+ ...(request.signal ? { signal: request.signal } : {}),
394
+ ...(binding.timeoutMs ? { timeoutMs: binding.timeoutMs } : {}),
395
+ });
396
+ const result = await call.decide({
367
397
  apiId: binding.apiId,
368
- provider: binding.provider,
369
- apiKey,
370
- options,
371
- signal: controller.signal,
398
+ state: request.state,
399
+ questions: Object.fromEntries(Object.entries(request.questions).map(([id, question]) => [
400
+ id,
401
+ providerQuestion(question, request.assets),
402
+ ])),
403
+ ...(request.assets ? { assets: request.assets } : {}),
372
404
  });
373
- return await resultFromResponse(response, request.questions, binding, controller.signal, request.signal);
405
+ if (typeof result.model !== 'string' || !result.model.trim())
406
+ throw new DecisionError('malformed_response', labelText('provider.decision_model_missing'));
407
+ return { ...result, answers: validateAnswers(result.answers, request.questions) };
374
408
  }
375
- finally {
376
- if (timeout !== undefined)
377
- clearTimeout(timeout);
378
- request.signal?.removeEventListener('abort', abort);
409
+ catch (error) {
410
+ if (request.signal?.aborted)
411
+ throw new DecisionError('cancelled', labelText('provider.decision_ended'));
412
+ throw decisionProviderError(error);
379
413
  }
380
414
  }
381
415
  /**
@@ -387,26 +421,19 @@ export async function runDecisionInRegistry(registry, request, options) {
387
421
  validateDecisionRequest(request, profile);
388
422
  const model = decisionModel(profile);
389
423
  const [modelId, binding] = model;
390
- const tree = startTrace(`decide ${binding.apiId}`, {
391
- kind: 'CLIENT',
424
+ return await tracedCall({
425
+ name: `decide ${binding.apiId}`,
392
426
  attributes: decisionSpanAttributes(profile, modelId, binding, request),
393
- ...(request.traceparent ? { traceparent: request.traceparent } : {}),
394
- });
395
- const { sink, policy } = resolveTraceWriter({
396
- override: options.sink,
397
- observability: profile.observability,
398
- });
399
- try {
400
- const result = await decide(profile, model, request, options);
401
- recordResult(tree.root, result);
402
- tree.root.end({ code: 'OK' });
427
+ traceparent: request.traceparent,
428
+ metadata: request.metadata,
429
+ writer: {
430
+ override: options.sink,
431
+ observability: profile.observability,
432
+ guardrails: profile.guardrails,
433
+ },
434
+ }, async (root) => {
435
+ const result = await decide(registry, profile, model, request, options);
436
+ recordResult(root, result);
403
437
  return result;
404
- }
405
- catch (error) {
406
- endThrownSpan(tree.root, error);
407
- throw error;
408
- }
409
- finally {
410
- await writeSpans(sink, tree.collect(), policy, request.metadata);
411
- }
438
+ });
412
439
  }
@@ -0,0 +1,8 @@
1
+ import type { TraceSink } from '../../observability/trace-sink.js';
2
+ import type { ProviderHostOptions } from '../protocols/runtime.js';
3
+ import type { KernelRegistry } from '../registry/kernel-registry.js';
4
+ import type { EmbeddingRequest, EmbeddingResult } from '../types.js';
5
+ export interface RunEmbeddingOptions extends ProviderHostOptions {
6
+ sink?: TraceSink;
7
+ }
8
+ export declare function runEmbeddingInRegistry(registry: KernelRegistry, request: EmbeddingRequest, options?: RunEmbeddingOptions): Promise<EmbeddingResult>;
@@ -0,0 +1,118 @@
1
+ import { refuseOverlong } from '../../guardrails/detect-at.js';
2
+ import { TheoremError, throwIfAborted } from '../../guardrails/error.js';
3
+ import { protocolOf } from '../protocols/binding.js';
4
+ import { guardedCall } from '../provider-runtime.js';
5
+ import { attachmentsRefused, base64Bytes } from '../registry/attachments.js';
6
+ import { embeddingMediaIssues, embeddingRules } from '../registry/embedding-rules.js';
7
+ import { tracedCall } from './call-trace.js';
8
+ function requireEmbeddingProfile(registry, id) {
9
+ const profile = registry.profiles.get(id);
10
+ if (profile.type !== 'embedding')
11
+ throw new TheoremError('request', `runEmbedding requires profile.type 'embedding' (got '${profile.type}' for ${id})`);
12
+ return profile;
13
+ }
14
+ function chooseModel(profile, requested) {
15
+ const modelId = requested ?? profile.defaultModel;
16
+ if (requested && !profile.allowModelSelect)
17
+ throw new TheoremError('request', `Profile ${profile.id} does not allow model selection`); // labels-exempt: developer contract error
18
+ const binding = profile.models[modelId];
19
+ if (!binding)
20
+ throw new TheoremError('request', `Unknown model '${modelId}' for ${profile.id}`); // labels-exempt: developer contract error
21
+ return [modelId, binding];
22
+ }
23
+ const TASKS = ['query', 'document'];
24
+ function checkTask(task) {
25
+ if (task !== undefined && !TASKS.includes(task))
26
+ throw new TheoremError('request', `Embedding task must be 'query' or 'document'`); // labels-exempt: developer contract error
27
+ }
28
+ function inputsOf(input) {
29
+ return Array.isArray(input) ? input : [input];
30
+ }
31
+ /** An input's parts; a bare string is one text part. */
32
+ function partsOf(input) {
33
+ if (typeof input === 'string')
34
+ return [{ type: 'text', text: input }];
35
+ return input && Array.isArray(input.parts) ? input.parts : [];
36
+ }
37
+ /** Text is checked per part; media per input, held to the profile and to what the model takes. */
38
+ function validateInputs(profile, modelId, inputs, model) {
39
+ const rules = embeddingRules(profile.inputs, model);
40
+ if (rules.maxInputs !== undefined && inputs.length > rules.maxInputs)
41
+ throw new TheoremError('request', `Model '${modelId}' of ${profile.id} takes at most ${rules.maxInputs} inputs per request`);
42
+ const media = [];
43
+ for (const input of inputs) {
44
+ const parts = partsOf(input);
45
+ if (parts.length === 0)
46
+ throw new TheoremError('request', `Profile ${profile.id} received an empty embedding input`); // labels-exempt: developer contract error
47
+ const files = [];
48
+ for (const part of parts) {
49
+ if (part.type === 'text') {
50
+ refuseOverlong(part.text, 'embedding input');
51
+ if (!rules.text)
52
+ throw new TheoremError('unsupported', `Profile ${profile.id} does not accept text embedding input`);
53
+ continue;
54
+ }
55
+ files.push(part.type === 'media'
56
+ ? { mimeType: part.mimeType, sizeBytes: base64Bytes(part.data) }
57
+ : { mimeType: part.mimeType });
58
+ }
59
+ media.push(files);
60
+ }
61
+ const issues = embeddingMediaIssues(rules, media);
62
+ if (issues.length > 0)
63
+ throw attachmentsRefused(issues);
64
+ }
65
+ function validateResult(result, count) {
66
+ if (!result.model.trim() || result.embeddings.length !== count)
67
+ throw new TheoremError('bad_response', 'Embedding provider returned an invalid vector count'); // labels-exempt: upstream contract error
68
+ const embeddings = result.embeddings.map((vector, index) => {
69
+ if (vector.index !== index ||
70
+ vector.dimensions !== vector.values.length ||
71
+ vector.dimensions === 0)
72
+ throw new TheoremError('bad_response', 'Embedding provider returned invalid vector metadata'); // labels-exempt: upstream contract error
73
+ if (vector.values.some((value) => !Number.isFinite(value)))
74
+ throw new TheoremError('bad_response', 'Embedding provider returned a non-finite vector value');
75
+ return vector;
76
+ });
77
+ return { ...result, embeddings };
78
+ }
79
+ export async function runEmbeddingInRegistry(registry, request, options = {}) {
80
+ throwIfAborted(request.signal);
81
+ const profile = requireEmbeddingProfile(registry, request.profile);
82
+ const [modelId, binding] = chooseModel(profile, request.model);
83
+ const inputs = inputsOf(request.input);
84
+ checkTask(request.task);
85
+ const provider = registry.providers.require(binding.provider, binding.apiId);
86
+ validateInputs(profile, modelId, inputs, protocolOf(provider, binding).embeddingLimits?.(binding.apiId));
87
+ const call = guardedCall(provider, binding, 'embedding', options, {
88
+ ...(request.signal ? { signal: request.signal } : {}),
89
+ });
90
+ return await tracedCall({
91
+ name: `embed ${binding.apiId}`,
92
+ attributes: {
93
+ 'gen_ai.operation.name': 'embeddings',
94
+ 'gen_ai.provider.name': binding.provider,
95
+ 'gen_ai.agent.name': profile.id,
96
+ 'gen_ai.request.model': binding.apiId,
97
+ 'theorem.model.id': modelId,
98
+ 'theorem.embedding.inputs': inputs.length,
99
+ ...(request.task ? { 'theorem.embedding.task': request.task } : {}),
100
+ },
101
+ traceparent: request.traceparent,
102
+ metadata: request.metadata,
103
+ writer: {
104
+ override: options.sink,
105
+ observability: profile.observability,
106
+ guardrails: profile.guardrails,
107
+ },
108
+ }, async () => {
109
+ const result = await call.embed({
110
+ apiId: binding.apiId,
111
+ input: request.input,
112
+ ...(request.task ? { task: request.task } : {}),
113
+ ...(binding.options ? { options: binding.options } : {}),
114
+ ...(request.signal ? { signal: request.signal } : {}),
115
+ });
116
+ return validateResult(result, inputs.length);
117
+ });
118
+ }
@@ -1,9 +1,19 @@
1
1
  import type { TurnEventOf } from '../turn-events.js';
2
- import type { Profile } from '../types.js';
2
+ import type { Profile, TurnContext } from '../types.js';
3
3
  export interface LiveInboundPrepareResult {
4
- text: string;
5
- /** Present when inbound sanitize redacted spans. */
4
+ /** The message to send, wrapped as user data. Absent when a match blocks: it does not reach the model. */
5
+ text?: string;
6
+ /** Present when a detector matched. */
6
7
  guardrail?: TurnEventOf<'guardrail'>;
7
8
  }
9
+ /** Reads text a live session receives from the user at the `live_user` boundary, wraps what crosses as user data, and returns the guardrail event when something matched. */
8
10
  declare function prepareLiveInboundText(profile: Profile, text: string): LiveInboundPrepareResult;
9
- export { prepareLiveInboundText };
11
+ export interface LiveContextPrepareResult {
12
+ /** Each package that crossed, in its sender's fence, the host's first. */
13
+ texts: string[];
14
+ /** One per package a detector matched in. */
15
+ guardrails: TurnEventOf<'guardrail'>[];
16
+ }
17
+ /** Reads each sender's context at the `context` boundary, as a turn does. A package a match blocks does not reach the model. */
18
+ declare function prepareLiveContext(profile: Profile, context: TurnContext): LiveContextPrepareResult;
19
+ export { prepareLiveContext, prepareLiveInboundText };