@theoremjs/agents 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) hide show
  1. package/README.md +277 -995
  2. package/esm/mod.d.ts +34 -20
  3. package/esm/mod.js +19 -12
  4. package/esm/src/cli/commands/bench.js +36 -14
  5. package/esm/src/cli/commands/detect-compile.d.ts +17 -0
  6. package/esm/src/cli/commands/detect-compile.js +22 -0
  7. package/esm/src/cli/commands/eval.d.ts +3 -3
  8. package/esm/src/cli/commands/fuzz-canary.js +55 -16
  9. package/esm/src/cli/commands/profile.js +4 -4
  10. package/esm/src/cli/commands/run.d.ts +2 -2
  11. package/esm/src/cli/commands/run.js +1 -1
  12. package/esm/src/cli/commands/test.d.ts +4 -3
  13. package/esm/src/cli/commands/test.js +2 -2
  14. package/esm/src/cli/index.js +9 -9
  15. package/esm/src/cli/matrix/fixtures.js +25 -30
  16. package/esm/src/evals/attachments.d.ts +1 -0
  17. package/esm/src/evals/attachments.js +4 -2
  18. package/esm/src/evals/breakdown.d.ts +2 -0
  19. package/esm/src/evals/breakdown.js +1 -0
  20. package/esm/src/evals/graders/answer.d.ts +3 -0
  21. package/esm/src/evals/graders/answer.js +1 -0
  22. package/esm/src/evals/graders/code.d.ts +7 -31
  23. package/esm/src/evals/graders/code.js +4 -25
  24. package/esm/src/evals/graders/judge.d.ts +4 -0
  25. package/esm/src/evals/graders/judge.js +7 -5
  26. package/esm/src/evals/graders/latency.d.ts +1 -0
  27. package/esm/src/evals/graders/latency.js +3 -2
  28. package/esm/src/evals/graders/live.d.ts +3 -0
  29. package/esm/src/evals/graders/live.js +2 -0
  30. package/esm/src/evals/graders/media.js +1 -2
  31. package/esm/src/evals/graders/shared.js +1 -1
  32. package/esm/src/evals/graders/transcript.d.ts +2 -0
  33. package/esm/src/evals/graders/transcript.js +5 -3
  34. package/esm/src/evals/mod.d.ts +1 -9
  35. package/esm/src/evals/mod.js +1 -9
  36. package/esm/src/evals/record.d.ts +6 -0
  37. package/esm/src/evals/record.js +4 -2
  38. package/esm/src/evals/rubrics/mod.d.ts +1 -1
  39. package/esm/src/evals/rubrics/mod.js +1 -1
  40. package/esm/src/evals/rubrics/mustache.js +1 -1
  41. package/esm/src/evals/rubrics/types.js +1 -1
  42. package/esm/src/evals/run.d.ts +9 -52
  43. package/esm/src/evals/run.js +12 -46
  44. package/esm/src/evals/suite.d.ts +12 -3
  45. package/esm/src/evals/suite.js +9 -4
  46. package/esm/src/evals/summary.d.ts +3 -0
  47. package/esm/src/evals/summary.js +1 -0
  48. package/esm/src/evals/trial.d.ts +3 -16
  49. package/esm/src/evals/trial.js +7 -30
  50. package/esm/src/evals/types.d.ts +30 -121
  51. package/esm/src/evals/types.js +3 -16
  52. package/esm/src/evals/verdict.d.ts +5 -0
  53. package/esm/src/evals/verdict.js +4 -1
  54. package/esm/src/guardrails/boundaries.d.ts +41 -0
  55. package/esm/src/guardrails/boundaries.js +103 -0
  56. package/esm/src/guardrails/canary-gate.d.ts +1 -0
  57. package/esm/src/guardrails/canary.d.ts +49 -15
  58. package/esm/src/guardrails/canary.js +103 -30
  59. package/esm/src/guardrails/compile-egress.d.ts +6 -5
  60. package/esm/src/guardrails/compile-egress.js +6 -5
  61. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +3 -1
  62. package/esm/src/guardrails/corpus/canary-egress-attacks.js +4 -2
  63. package/esm/src/guardrails/corpus/fuzz-inbound.js +14 -17
  64. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +2 -0
  65. package/esm/src/guardrails/corpus/inbound-payloads.js +4 -2
  66. package/esm/src/guardrails/corpus/live-attacks.d.ts +2 -0
  67. package/esm/src/guardrails/corpus/live-attacks.js +6 -1
  68. package/esm/src/guardrails/corpus/mod.d.ts +1 -1
  69. package/esm/src/guardrails/corpus/secrets.d.ts +3 -3
  70. package/esm/src/guardrails/corpus/secrets.js +2 -2
  71. package/esm/src/guardrails/corpus/strings.d.ts +1 -1
  72. package/esm/src/guardrails/corpus/strings.js +1 -1
  73. package/esm/src/guardrails/corpus/types.d.ts +5 -1
  74. package/esm/src/guardrails/credential-rules.d.ts +36 -0
  75. package/esm/src/guardrails/credential-rules.js +3001 -0
  76. package/esm/src/guardrails/credential-scan.d.ts +45 -0
  77. package/esm/src/guardrails/credential-scan.js +172 -0
  78. package/esm/src/guardrails/destinations.d.ts +45 -0
  79. package/esm/src/guardrails/destinations.js +234 -0
  80. package/esm/src/guardrails/detect-at.d.ts +107 -0
  81. package/esm/src/guardrails/detect-at.js +434 -0
  82. package/esm/src/guardrails/detect-reply.d.ts +61 -0
  83. package/esm/src/guardrails/detect-reply.js +95 -0
  84. package/esm/src/guardrails/detect-stream.d.ts +33 -0
  85. package/esm/src/guardrails/detect-stream.js +77 -0
  86. package/esm/src/guardrails/detectors.d.ts +216 -0
  87. package/esm/src/guardrails/detectors.js +503 -0
  88. package/esm/src/guardrails/egress-automata.d.ts +4 -6
  89. package/esm/src/guardrails/egress-automata.js +24095 -4572
  90. package/esm/src/guardrails/egress-compiler.d.ts +38 -16
  91. package/esm/src/guardrails/egress-compiler.js +254 -60
  92. package/esm/src/guardrails/egress-patterns.d.ts +4 -2
  93. package/esm/src/guardrails/egress-patterns.js +6 -2
  94. package/esm/src/guardrails/egress-stream.d.ts +54 -36
  95. package/esm/src/guardrails/egress-stream.js +253 -124
  96. package/esm/src/guardrails/egress-urls.d.ts +6 -3
  97. package/esm/src/guardrails/egress-urls.js +14 -22
  98. package/esm/src/guardrails/egress.d.ts +26 -86
  99. package/esm/src/guardrails/egress.js +59 -309
  100. package/esm/src/guardrails/error.d.ts +13 -8
  101. package/esm/src/guardrails/error.js +25 -18
  102. package/esm/src/guardrails/event-schemas.d.ts +46 -3
  103. package/esm/src/guardrails/event-schemas.js +12 -5
  104. package/esm/src/guardrails/events.d.ts +5 -1
  105. package/esm/src/guardrails/events.js +4 -1
  106. package/esm/src/guardrails/hints.d.ts +14 -0
  107. package/esm/src/guardrails/hints.js +57 -0
  108. package/esm/src/guardrails/hits.d.ts +7 -1
  109. package/esm/src/guardrails/hits.js +12 -1
  110. package/esm/src/guardrails/host-patterns.d.ts +85 -0
  111. package/esm/src/guardrails/host-patterns.js +173 -0
  112. package/esm/src/guardrails/injection-patterns.d.ts +6 -1
  113. package/esm/src/guardrails/injection-patterns.js +33 -1
  114. package/esm/src/guardrails/injection-reversed.d.ts +9 -0
  115. package/esm/src/guardrails/injection-reversed.js +49 -0
  116. package/esm/src/guardrails/injection.d.ts +17 -1
  117. package/esm/src/guardrails/injection.js +259 -36
  118. package/esm/src/guardrails/labels.d.ts +40 -0
  119. package/esm/src/guardrails/labels.js +881 -0
  120. package/esm/src/guardrails/live-outbound-gate.d.ts +9 -8
  121. package/esm/src/guardrails/live-outbound-gate.js +100 -107
  122. package/esm/src/guardrails/mod.d.ts +30 -22
  123. package/esm/src/guardrails/mod.js +19 -14
  124. package/esm/src/guardrails/network.d.ts +4 -0
  125. package/esm/src/guardrails/network.js +21 -19
  126. package/esm/src/guardrails/normalize.d.ts +15 -1
  127. package/esm/src/guardrails/normalize.js +34 -1
  128. package/esm/src/guardrails/policy.d.ts +2 -17
  129. package/esm/src/guardrails/policy.js +12 -41
  130. package/esm/src/guardrails/progressive-yield.d.ts +65 -24
  131. package/esm/src/guardrails/progressive-yield.js +191 -147
  132. package/esm/src/guardrails/prompt-echo.d.ts +4 -2
  133. package/esm/src/guardrails/prompt-echo.js +87 -6
  134. package/esm/src/guardrails/quota.d.ts +4 -1
  135. package/esm/src/guardrails/quota.js +7 -2
  136. package/esm/src/guardrails/rules.d.ts +20 -29
  137. package/esm/src/guardrails/rules.js +23 -30
  138. package/esm/src/guardrails/sanitize.d.ts +32 -15
  139. package/esm/src/guardrails/sanitize.js +100 -124
  140. package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
  141. package/esm/src/guardrails/sensitive-groups.js +12 -0
  142. package/esm/src/guardrails/sensitive.d.ts +16 -23
  143. package/esm/src/guardrails/sensitive.js +168 -47
  144. package/esm/src/guardrails/serialize.d.ts +1 -0
  145. package/esm/src/guardrails/testing.d.ts +4 -2
  146. package/esm/src/guardrails/testing.js +4 -2
  147. package/esm/src/guardrails/theorem-error.d.ts +5 -2
  148. package/esm/src/guardrails/theorem-error.js +6 -3
  149. package/esm/src/guardrails/thought-guard.d.ts +34 -13
  150. package/esm/src/guardrails/thought-guard.js +264 -64
  151. package/esm/src/guardrails/tool-directives.d.ts +29 -10
  152. package/esm/src/guardrails/tool-directives.js +133 -47
  153. package/esm/src/guardrails/tool-leak.d.ts +26 -0
  154. package/esm/src/guardrails/tool-leak.js +45 -0
  155. package/esm/src/guardrails/tool-result.d.ts +45 -14
  156. package/esm/src/guardrails/tool-result.js +94 -70
  157. package/esm/src/guardrails/types.d.ts +79 -71
  158. package/esm/src/guardrails/types.js +11 -7
  159. package/esm/src/host/client-turn.d.ts +29 -2
  160. package/esm/src/host/client-turn.js +46 -4
  161. package/esm/src/host/mint-trace.d.ts +1 -0
  162. package/esm/src/host/mint-trace.js +3 -2
  163. package/esm/src/host/mod.d.ts +2 -2
  164. package/esm/src/host/mod.js +1 -1
  165. package/esm/src/host/readStreamingJsonStringField.js +2 -43
  166. package/esm/src/host/reply.d.ts +6 -0
  167. package/esm/src/host/reply.js +8 -1
  168. package/esm/src/interface/blocks.d.ts +3 -0
  169. package/esm/src/interface/blocks.js +84 -14
  170. package/esm/src/interface/composer-actions.d.ts +4 -0
  171. package/esm/src/interface/composer-actions.js +5 -3
  172. package/esm/src/interface/draft.d.ts +6 -0
  173. package/esm/src/interface/draft.js +22 -11
  174. package/esm/src/interface/from-profile.d.ts +13 -1
  175. package/esm/src/interface/from-profile.js +66 -31
  176. package/esm/src/interface/history.d.ts +9 -3
  177. package/esm/src/interface/history.js +33 -24
  178. package/esm/src/interface/inputs.d.ts +1 -0
  179. package/esm/src/interface/inputs.js +3 -0
  180. package/esm/src/interface/mod.d.ts +4 -2
  181. package/esm/src/interface/mod.js +3 -2
  182. package/esm/src/interface/models.d.ts +7 -0
  183. package/esm/src/interface/models.js +5 -0
  184. package/esm/src/interface/pending.d.ts +9 -0
  185. package/esm/src/interface/pending.js +9 -3
  186. package/esm/src/interface/profile-interface.js +54 -40
  187. package/esm/src/interface/session.d.ts +12 -5
  188. package/esm/src/interface/session.js +17 -10
  189. package/esm/src/interface/stop.d.ts +13 -0
  190. package/esm/src/interface/stop.js +28 -0
  191. package/esm/src/interface/tool-calls.d.ts +14 -2
  192. package/esm/src/interface/tool-calls.js +64 -10
  193. package/esm/src/interface/tool-invoke.d.ts +2 -0
  194. package/esm/src/interface/tool-invoke.js +3 -1
  195. package/esm/src/interface/tool-media.d.ts +2 -0
  196. package/esm/src/interface/tool-media.js +2 -1
  197. package/esm/src/interface/types.d.ts +105 -40
  198. package/esm/src/interface/types.js +1 -0
  199. package/esm/src/kernel/api-catalog.d.ts +85 -0
  200. package/esm/src/kernel/api-catalog.js +229 -0
  201. package/esm/src/kernel/auth/crypto.d.ts +7 -2
  202. package/esm/src/kernel/auth/crypto.js +12 -10
  203. package/esm/src/kernel/auth/oauth.d.ts +2 -1
  204. package/esm/src/kernel/auth/oauth.js +23 -22
  205. package/esm/src/kernel/auth/typed-secret.js +2 -2
  206. package/esm/src/kernel/auth/types.d.ts +13 -0
  207. package/esm/src/kernel/checkpoint.d.ts +43 -0
  208. package/esm/src/kernel/checkpoint.js +58 -0
  209. package/esm/src/kernel/default-scope.d.ts +43 -5
  210. package/esm/src/kernel/default-scope.js +54 -5
  211. package/esm/src/kernel/engine/call-trace.d.ts +19 -0
  212. package/esm/src/kernel/engine/call-trace.js +29 -0
  213. package/esm/src/kernel/engine/compaction.d.ts +6 -5
  214. package/esm/src/kernel/engine/compaction.js +12 -11
  215. package/esm/src/kernel/engine/decision.d.ts +10 -8
  216. package/esm/src/kernel/engine/decision.js +174 -146
  217. package/esm/src/kernel/engine/embedding.d.ts +8 -0
  218. package/esm/src/kernel/engine/embedding.js +118 -0
  219. package/esm/src/kernel/engine/live-inbound.d.ts +14 -4
  220. package/esm/src/kernel/engine/live-inbound.js +36 -11
  221. package/esm/src/kernel/engine/live-ingress.d.ts +6 -0
  222. package/esm/src/kernel/engine/live-ingress.js +6 -1
  223. package/esm/src/kernel/engine/repair.js +12 -12
  224. package/esm/src/kernel/engine/runner/gates.d.ts +2 -2
  225. package/esm/src/kernel/engine/runner/gates.js +287 -101
  226. package/esm/src/kernel/engine/runner/mod.d.ts +19 -5
  227. package/esm/src/kernel/engine/runner/mod.js +107 -56
  228. package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
  229. package/esm/src/kernel/engine/runner/nested.js +134 -0
  230. package/esm/src/kernel/engine/runner/schema-validation.d.ts +24 -3
  231. package/esm/src/kernel/engine/runner/schema-validation.js +78 -4
  232. package/esm/src/kernel/engine/runner/stages.d.ts +1 -1
  233. package/esm/src/kernel/engine/runner/stages.js +1 -8
  234. package/esm/src/kernel/engine/runner/state.d.ts +33 -12
  235. package/esm/src/kernel/engine/runner/state.js +11 -1
  236. package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
  237. package/esm/src/kernel/engine/runner/step-order.js +165 -0
  238. package/esm/src/kernel/engine/runner/steps.d.ts +2 -2
  239. package/esm/src/kernel/engine/runner/steps.js +329 -169
  240. package/esm/src/kernel/engine/runner/stream.d.ts +42 -11
  241. package/esm/src/kernel/engine/runner/stream.js +197 -46
  242. package/esm/src/kernel/engine/runner/usage.d.ts +5 -5
  243. package/esm/src/kernel/engine/runner/usage.js +12 -14
  244. package/esm/src/kernel/engine/session/mod.d.ts +8 -6
  245. package/esm/src/kernel/engine/session/mod.js +360 -129
  246. package/esm/src/kernel/engine/session/session-trace.d.ts +10 -10
  247. package/esm/src/kernel/engine/session/session-trace.js +41 -30
  248. package/esm/src/kernel/engine/token-estimate.d.ts +10 -64
  249. package/esm/src/kernel/engine/token-estimate.js +14 -194
  250. package/esm/src/kernel/engine/tool-trace.d.ts +3 -3
  251. package/esm/src/kernel/engine/tool-trace.js +2 -1
  252. package/esm/src/kernel/engine/turn-trace.d.ts +8 -7
  253. package/esm/src/kernel/engine/turn-trace.js +28 -36
  254. package/esm/src/kernel/engine/usage.d.ts +6 -0
  255. package/esm/src/kernel/engine/usage.js +17 -0
  256. package/esm/src/kernel/interaction-parts.d.ts +3 -0
  257. package/esm/src/kernel/interaction-parts.js +18 -0
  258. package/esm/src/kernel/json.d.ts +10 -0
  259. package/esm/src/kernel/json.js +3 -0
  260. package/esm/src/kernel/mod.d.ts +38 -11
  261. package/esm/src/kernel/mod.js +22 -7
  262. package/esm/src/kernel/profile-graph.d.ts +11 -6
  263. package/esm/src/kernel/profile-graph.js +14 -7
  264. package/esm/src/kernel/profile-presence.d.ts +10 -1
  265. package/esm/src/kernel/profile-presence.js +90 -75
  266. package/esm/src/kernel/profile-scope.d.ts +7 -3
  267. package/esm/src/kernel/profile-scope.js +67 -55
  268. package/esm/src/kernel/protocols/binding.d.ts +65 -0
  269. package/esm/src/kernel/protocols/binding.js +125 -0
  270. package/esm/src/kernel/protocols/limits.d.ts +15 -0
  271. package/esm/src/kernel/protocols/limits.js +28 -0
  272. package/esm/src/kernel/protocols/mod.d.ts +5 -0
  273. package/esm/src/kernel/protocols/mod.js +5 -0
  274. package/esm/src/kernel/protocols/prices.d.ts +36 -0
  275. package/esm/src/kernel/protocols/prices.js +37 -0
  276. package/esm/src/kernel/protocols/protocol.d.ts +253 -0
  277. package/esm/src/kernel/protocols/protocol.js +253 -0
  278. package/esm/src/kernel/protocols/provider.d.ts +108 -0
  279. package/esm/src/kernel/protocols/provider.js +143 -0
  280. package/esm/src/kernel/protocols/runtime.d.ts +55 -0
  281. package/esm/src/kernel/protocols/runtime.js +534 -0
  282. package/esm/src/kernel/provider-budget.d.ts +32 -0
  283. package/esm/src/kernel/provider-budget.js +262 -0
  284. package/esm/src/kernel/provider-dispatch.d.ts +13 -0
  285. package/esm/src/kernel/provider-dispatch.js +36 -0
  286. package/esm/src/kernel/provider-live.d.ts +7 -0
  287. package/esm/src/kernel/provider-live.js +189 -0
  288. package/esm/src/kernel/provider-runtime.d.ts +57 -0
  289. package/esm/src/kernel/provider-runtime.js +524 -0
  290. package/esm/src/kernel/registry/attachments.d.ts +15 -4
  291. package/esm/src/kernel/registry/attachments.js +31 -22
  292. package/esm/src/kernel/registry/catalog.d.ts +6 -0
  293. package/esm/src/kernel/registry/catalog.js +9 -2
  294. package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
  295. package/esm/src/kernel/registry/embedding-rules.js +66 -0
  296. package/esm/src/kernel/registry/ingress.d.ts +6 -2
  297. package/esm/src/kernel/registry/ingress.js +55 -10
  298. package/esm/src/kernel/registry/kernel-registry.d.ts +3 -0
  299. package/esm/src/kernel/registry/kernel-registry.js +9 -2
  300. package/esm/src/kernel/registry/profile-outputs.js +4 -1
  301. package/esm/src/kernel/registry/profiles.d.ts +38 -14
  302. package/esm/src/kernel/registry/profiles.js +280 -205
  303. package/esm/src/kernel/registry/provider-request.d.ts +3 -3
  304. package/esm/src/kernel/registry/provider-request.js +5 -13
  305. package/esm/src/kernel/registry/resolve.d.ts +4 -1
  306. package/esm/src/kernel/registry/resolve.js +59 -58
  307. package/esm/src/kernel/registry/schemas.d.ts +3 -0
  308. package/esm/src/kernel/registry/schemas.js +3 -1
  309. package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
  310. package/esm/src/kernel/registry/slot-fill.js +22 -0
  311. package/esm/src/kernel/registry/system-prompt.js +7 -8
  312. package/esm/src/kernel/registry/vault.d.ts +14 -13
  313. package/esm/src/kernel/registry/vault.js +1 -14
  314. package/esm/src/kernel/schema.d.ts +100 -46
  315. package/esm/src/kernel/schema.js +499 -257
  316. package/esm/src/kernel/scope.d.ts +12 -5
  317. package/esm/src/kernel/scope.js +23 -3
  318. package/esm/src/kernel/stages.d.ts +38 -3
  319. package/esm/src/kernel/stages.js +82 -39
  320. package/esm/src/kernel/stop.d.ts +29 -6
  321. package/esm/src/kernel/stop.js +16 -4
  322. package/esm/src/kernel/system-parts.js +6 -6
  323. package/esm/src/kernel/tools/activity-label.d.ts +12 -6
  324. package/esm/src/kernel/tools/activity-label.js +258 -32
  325. package/esm/src/kernel/tools/agent.d.ts +66 -0
  326. package/esm/src/kernel/tools/agent.js +212 -0
  327. package/esm/src/kernel/tools/coordinate.d.ts +4 -0
  328. package/esm/src/kernel/tools/coordinate.js +165 -0
  329. package/esm/src/kernel/tools/events.d.ts +21 -6
  330. package/esm/src/kernel/tools/events.js +53 -18
  331. package/esm/src/kernel/tools/execute.d.ts +47 -11
  332. package/esm/src/kernel/tools/execute.js +508 -136
  333. package/esm/src/kernel/tools/gate-answer.d.ts +12 -2
  334. package/esm/src/kernel/tools/gate-answer.js +17 -6
  335. package/esm/src/kernel/tools/handler-events.d.ts +45 -0
  336. package/esm/src/kernel/tools/handler-events.js +106 -0
  337. package/esm/src/kernel/tools/harness.d.ts +1 -0
  338. package/esm/src/kernel/tools/harness.js +2 -1
  339. package/esm/src/kernel/tools/http-limit.d.ts +27 -0
  340. package/esm/src/kernel/tools/http-limit.js +85 -0
  341. package/esm/src/kernel/tools/invoke.d.ts +27 -5
  342. package/esm/src/kernel/tools/invoke.js +223 -70
  343. package/esm/src/kernel/tools/mcp-sessions.d.ts +4 -1
  344. package/esm/src/kernel/tools/mcp-sessions.js +13 -8
  345. package/esm/src/kernel/tools/mod.d.ts +4 -3
  346. package/esm/src/kernel/tools/mod.js +3 -2
  347. package/esm/src/kernel/tools/model-text.d.ts +10 -5
  348. package/esm/src/kernel/tools/model-text.js +18 -12
  349. package/esm/src/kernel/tools/operation.d.ts +76 -0
  350. package/esm/src/kernel/tools/operation.js +100 -0
  351. package/esm/src/kernel/tools/page-answer.d.ts +8 -0
  352. package/esm/src/kernel/tools/page-answer.js +19 -0
  353. package/esm/src/kernel/tools/permission.d.ts +11 -2
  354. package/esm/src/kernel/tools/permission.js +12 -12
  355. package/esm/src/kernel/tools/project.d.ts +4 -1
  356. package/esm/src/kernel/tools/project.js +32 -2
  357. package/esm/src/kernel/tools/registry.d.ts +9 -2
  358. package/esm/src/kernel/tools/registry.js +69 -10
  359. package/esm/src/kernel/tools/remote.d.ts +40 -6
  360. package/esm/src/kernel/tools/remote.js +219 -92
  361. package/esm/src/kernel/tools/resolve.d.ts +3 -0
  362. package/esm/src/kernel/tools/resolve.js +12 -4
  363. package/esm/src/kernel/tools/run.d.ts +28 -0
  364. package/esm/src/kernel/tools/run.js +86 -0
  365. package/esm/src/kernel/tools/schema.d.ts +3 -3
  366. package/esm/src/kernel/tools/schema.js +21 -100
  367. package/esm/src/kernel/tools/signed-in-fetch.d.ts +2 -1
  368. package/esm/src/kernel/tools/signed-in-fetch.js +3 -3
  369. package/esm/src/kernel/tools/stage-run.d.ts +27 -4
  370. package/esm/src/kernel/tools/stage-run.js +75 -17
  371. package/esm/src/kernel/tools/types.d.ts +235 -25
  372. package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
  373. package/esm/src/kernel/tools/unchecked-output.js +18 -0
  374. package/esm/src/kernel/turn-events.d.ts +208 -31
  375. package/esm/src/kernel/turn-events.js +127 -9
  376. package/esm/src/kernel/types.d.ts +302 -161
  377. package/esm/src/kernel/util/base64.d.ts +2 -0
  378. package/esm/src/kernel/util/base64.js +2 -0
  379. package/esm/src/kernel/util/partial-json.d.ts +23 -0
  380. package/esm/src/kernel/util/partial-json.js +128 -0
  381. package/esm/src/kernel/util/record.d.ts +1 -0
  382. package/esm/src/kernel/util/record.js +1 -0
  383. package/esm/src/observability/destinations.d.ts +5 -0
  384. package/esm/src/observability/destinations.js +7 -2
  385. package/esm/src/observability/jsonl.d.ts +2 -2
  386. package/esm/src/observability/jsonl.js +15 -22
  387. package/esm/src/observability/mod.d.ts +3 -3
  388. package/esm/src/observability/mod.js +2 -2
  389. package/esm/src/observability/openinference.d.ts +1 -1
  390. package/esm/src/observability/openinference.js +3 -3
  391. package/esm/src/observability/otlp.d.ts +3 -0
  392. package/esm/src/observability/otlp.js +3 -3
  393. package/esm/src/observability/phoenix.d.ts +1 -0
  394. package/esm/src/observability/policy.d.ts +3 -0
  395. package/esm/src/observability/policy.js +5 -1
  396. package/esm/src/observability/resolve-policy.js +11 -5
  397. package/esm/src/observability/spans.d.ts +8 -2
  398. package/esm/src/observability/spans.js +21 -5
  399. package/esm/src/observability/trace-catalog.d.ts +19 -2
  400. package/esm/src/observability/trace-catalog.js +130 -88
  401. package/esm/src/observability/trace-record.js +22 -17
  402. package/esm/src/observability/trace-schema.d.ts +3 -0
  403. package/esm/src/observability/trace-schema.js +1 -1
  404. package/esm/src/observability/trace-sink.d.ts +1 -0
  405. package/esm/src/observability/trace-sink.js +1 -1
  406. package/esm/src/observability/trace-span.d.ts +7 -1
  407. package/esm/src/observability/trace-span.js +3 -1
  408. package/esm/src/observability/trace.d.ts +2 -0
  409. package/esm/src/observability/trace.js +4 -2
  410. package/esm/src/observability/types.d.ts +35 -11
  411. package/esm/src/observability/types.js +1 -1
  412. package/esm/src/presets/google/speech-voices.d.ts +1 -0
  413. package/esm/src/presets/google-limits.d.ts +1 -0
  414. package/esm/src/presets/google.d.ts +27 -12
  415. package/esm/src/presets/google.js +34 -25
  416. package/esm/src/presets/local.d.ts +26 -0
  417. package/esm/src/presets/local.js +30 -0
  418. package/esm/src/presets/mod.d.ts +5 -4
  419. package/esm/src/presets/mod.js +4 -4
  420. package/esm/src/presets/openrouter.d.ts +14 -1
  421. package/esm/src/presets/openrouter.js +19 -1
  422. package/esm/src/providers/embedding-limits.d.ts +7 -0
  423. package/esm/src/providers/embedding-limits.js +12 -0
  424. package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
  425. package/esm/src/providers/gemini/embedding-protocol.js +125 -0
  426. package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
  427. package/esm/src/providers/gemini/interactions-protocol.js +102 -0
  428. package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
  429. package/esm/src/providers/gemini/live-protocol.js +191 -0
  430. package/esm/src/providers/gemini/prices.d.ts +3 -0
  431. package/esm/src/providers/gemini/prices.js +63 -0
  432. package/esm/src/providers/gemini/provider.d.ts +7 -0
  433. package/esm/src/providers/gemini/provider.js +39 -0
  434. package/esm/src/providers/google/api-error.d.ts +2 -0
  435. package/esm/src/providers/google/api-error.js +26 -18
  436. package/esm/src/providers/google/builtins.d.ts +14 -0
  437. package/esm/src/providers/google/builtins.js +57 -0
  438. package/esm/src/providers/google/grounding.d.ts +4 -4
  439. package/esm/src/providers/google/interactions/framing.d.ts +20 -8
  440. package/esm/src/providers/google/interactions/framing.js +85 -44
  441. package/esm/src/providers/google/interactions/steps.d.ts +5 -5
  442. package/esm/src/providers/google/interactions/steps.js +4 -4
  443. package/esm/src/providers/google/interactions/stream.d.ts +10 -11
  444. package/esm/src/providers/google/interactions/stream.js +33 -100
  445. package/esm/src/providers/google/live/framing.d.ts +15 -5
  446. package/esm/src/providers/google/live/framing.js +25 -25
  447. package/esm/src/providers/google/live/stream.d.ts +6 -44
  448. package/esm/src/providers/google/live/stream.js +4 -210
  449. package/esm/src/providers/google/urls.d.ts +1 -3
  450. package/esm/src/providers/google/urls.js +1 -3
  451. package/esm/src/providers/google/usage.js +2 -2
  452. package/esm/src/providers/live.d.ts +6 -0
  453. package/esm/src/providers/live.js +6 -0
  454. package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
  455. package/esm/src/providers/local/embedding-protocol.js +60 -0
  456. package/esm/src/providers/local/provider.d.ts +7 -0
  457. package/esm/src/providers/local/provider.js +28 -0
  458. package/esm/src/providers/mod.d.ts +28 -7
  459. package/esm/src/providers/mod.js +19 -3
  460. package/esm/src/providers/open-ai/protocol.d.ts +3 -0
  461. package/esm/src/providers/open-ai/protocol.js +189 -0
  462. package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
  463. package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
  464. package/esm/src/providers/openrouter/image.d.ts +0 -9
  465. package/esm/src/providers/openrouter/image.js +0 -153
  466. package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
  467. package/esm/src/providers/openrouter/images-protocol.js +82 -0
  468. package/esm/src/providers/openrouter/openai/compat.d.ts +2 -2
  469. package/esm/src/providers/openrouter/openai/compat.js +6 -6
  470. package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
  471. package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
  472. package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
  473. package/esm/src/providers/openrouter/protocol.d.ts +8 -0
  474. package/esm/src/providers/openrouter/protocol.js +171 -0
  475. package/esm/src/providers/openrouter/provider.d.ts +10 -0
  476. package/esm/src/providers/openrouter/provider.js +50 -0
  477. package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
  478. package/esm/src/providers/shared/carried-tool-files.js +43 -0
  479. package/esm/src/providers/shared/pcm.js +2 -2
  480. package/esm/src/providers/shared/protocol-events.d.ts +8 -0
  481. package/esm/src/providers/shared/protocol-events.js +20 -0
  482. package/esm/src/providers/shared/response-identity.d.ts +2 -2
  483. package/esm/src/providers/shared/retry.d.ts +18 -0
  484. package/esm/src/providers/shared/retry.js +89 -0
  485. package/esm/src/providers/shared/sse.d.ts +0 -4
  486. package/esm/src/providers/shared/sse.js +50 -36
  487. package/esm/src/providers/shared/tool-args.d.ts +6 -7
  488. package/esm/src/providers/shared/tool-args.js +10 -6
  489. package/esm/src/providers/shared/tool-draft.d.ts +16 -0
  490. package/esm/src/providers/shared/tool-draft.js +14 -0
  491. package/esm/src/providers/shared/upstream-tap.d.ts +2 -2
  492. package/esm/src/providers/shared/upstream-tape.js +1 -1
  493. package/esm/src/providers/system-one/protocol.d.ts +8 -0
  494. package/esm/src/providers/system-one/protocol.js +93 -0
  495. package/esm/src/providers/types.d.ts +48 -16
  496. package/esm/src/providers/types.js +2 -1
  497. package/esm/src/providers/typesafe/provider.d.ts +7 -0
  498. package/esm/src/providers/typesafe/provider.js +24 -0
  499. package/esm/src/surface/formats.d.ts +19 -1
  500. package/esm/src/surface/formats.js +68 -29
  501. package/esm/src/surface/mod.d.ts +4 -2
  502. package/esm/src/surface/mod.js +4 -2
  503. package/esm/src/surface/runtime.d.ts +4 -0
  504. package/esm/src/surface/runtime.js +2 -0
  505. package/esm/src/surface/tools.d.ts +2 -8
  506. package/esm/src/surface/tools.js +4 -22
  507. package/esm/src/surface/types.d.ts +6 -0
  508. package/package.json +5 -13
  509. package/esm/src/cli/commands/egress-compile.d.ts +0 -17
  510. package/esm/src/cli/commands/egress-compile.js +0 -25
  511. package/esm/src/guardrails/egress-policy.d.ts +0 -27
  512. package/esm/src/guardrails/egress-policy.js +0 -76
  513. package/esm/src/guardrails/egress-rules.d.ts +0 -54
  514. package/esm/src/guardrails/egress-rules.js +0 -49
  515. package/esm/src/guardrails/lexicon.d.ts +0 -30
  516. package/esm/src/guardrails/lexicon.js +0 -478
  517. package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
  518. package/esm/src/kernel/engine/media-probe/audio.js +0 -342
  519. package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
  520. package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
  521. package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
  522. package/esm/src/kernel/engine/media-probe/image.js +0 -171
  523. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
  524. package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
  525. package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
  526. package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
  527. package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
  528. package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
  529. package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
  530. package/esm/src/kernel/engine/media-probe/opus.js +0 -23
  531. package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
  532. package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
  533. package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
  534. package/esm/src/kernel/engine/media-probe/video.js +0 -49
  535. package/esm/src/presets/typesafe.d.ts +0 -2
  536. package/esm/src/presets/typesafe.js +0 -2
  537. package/esm/src/providers/create-provider.d.ts +0 -21
  538. package/esm/src/providers/create-provider.js +0 -90
  539. package/esm/src/providers/decision/usage.d.ts +0 -3
  540. package/esm/src/providers/decision/usage.js +0 -25
  541. package/esm/src/providers/google/interactions/mod.d.ts +0 -2
  542. package/esm/src/providers/google/interactions/mod.js +0 -2
  543. package/esm/src/providers/google/keys.d.ts +0 -20
  544. package/esm/src/providers/google/keys.js +0 -87
  545. package/esm/src/providers/google/live/mod.d.ts +0 -7
  546. package/esm/src/providers/google/live/mod.js +0 -7
  547. package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
  548. package/esm/src/providers/google/live/openapi-schema.js +0 -42
  549. package/esm/src/providers/google/live/session.d.ts +0 -14
  550. package/esm/src/providers/google/live/session.js +0 -150
  551. package/esm/src/providers/local/local.d.ts +0 -12
  552. package/esm/src/providers/local/local.js +0 -186
  553. package/esm/src/providers/local/mod.d.ts +0 -8
  554. package/esm/src/providers/local/mod.js +0 -8
  555. package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
  556. package/esm/src/providers/openrouter/cache-control.js +0 -4
  557. package/esm/src/providers/openrouter/chat.d.ts +0 -64
  558. package/esm/src/providers/openrouter/chat.js +0 -490
  559. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
  560. package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
  561. package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
  562. package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
  563. package/esm/src/providers/openrouter/speech.d.ts +0 -18
  564. package/esm/src/providers/openrouter/speech.js +0 -109
  565. package/esm/src/providers/probe.d.ts +0 -5
  566. package/esm/src/providers/probe.js +0 -15
  567. package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
  568. package/esm/src/providers/shared/builtin-wire.js +0 -9
  569. package/esm/src/providers/shared/vault.d.ts +0 -13
  570. package/esm/src/providers/shared/vault.js +0 -41
@@ -1,19 +1,23 @@
1
- import { hitRules, runEnforcer, WITHHELD_REASON } from '../../../guardrails/egress.js';
1
+ import { scopeOf } from '../../../guardrails/detect-at.js';
2
+ import { readReply, refusalAfter, replyAfter, standingBlock, TURN_REPLY, } from '../../../guardrails/detect-reply.js';
3
+ import { WITHHELD_REASON } from '../../../guardrails/egress.js';
2
4
  import { TheoremError, throwIfAborted, toErrorEvent } from '../../../guardrails/error.js';
3
- import { guardrailFromVerdict } from '../../../guardrails/events.js';
4
- import { lexiconText } from '../../../guardrails/lexicon.js';
5
+ import { guardrailFromHits, guardrailTurnEvent } from '../../../guardrails/events.js';
6
+ import { retryRejection } from '../../../guardrails/hints.js';
7
+ import { labelText } from '../../../guardrails/labels.js';
5
8
  import { resolveGuardrailPolicy } from '../../../guardrails/policy.js';
9
+ import { replyIsJudged } from '../../../guardrails/progressive-yield.js';
6
10
  import { sanitizeTurnRequest } from '../../../guardrails/sanitize.js';
7
11
  import { resolveInputParts } from '../../registry/ingress.js';
8
12
  import { profileTurnOutputs } from '../../registry/profile-outputs.js';
9
13
  import { injectWouldExceedMaxSteps } from '../../stages.js';
10
14
  import { findLast } from '../../util/find-last.js';
11
15
  import { guardrailCheckAttributes } from '../turn-trace.js';
12
- import { collectValidationFailures, formatValidationFailures } from './schema-validation.js';
16
+ import { collectItemFailures, collectValidationFailures, formatValidationFailures, itemSchemaAt, valueAt, withListAt, } from './schema-validation.js';
13
17
  import { applyTurnStage } from './stages.js';
14
- import { appendUserInput } from './state.js';
18
+ import { appendUserInput, } from './state.js';
15
19
  import { executeAttempt } from './steps.js';
16
- import { isWithheldOnBlock } from './stream.js';
20
+ import { isWithheldOnBlock, shownToHost } from './stream.js';
17
21
  /** A turn whose final output the egress check blocked (withheld or replaced by policy copy). */
18
22
  const EGRESS_FILTERED_STOP = { kind: 'filtered', native: 'egress' };
19
23
  /** Reply text only: thoughts are not guarded output (`isGuardedOutput`). */
@@ -26,7 +30,7 @@ function collectAttemptText(events) {
26
30
  }
27
31
  return parts.join('');
28
32
  }
29
- // Structured output travels with the text so `outputs.structured` meets egress rather than passing unexamined.
33
+ // why: Structured output travels with the text so `outputs.structured` meets egress rather than passing unexamined.
30
34
  function projectOutbound(events) {
31
35
  const structured = findLast(events, (e) => e.type === 'structured')?.structured;
32
36
  return {
@@ -47,56 +51,61 @@ function buildRepairRequest(safe, previousOutput, rejection, repairGuidance) {
47
51
  },
48
52
  };
49
53
  }
50
- async function evaluateEgressOutcome(args) {
51
- const { egress, attemptEvents, generation, request, profile, canRetry, promptLeaks, givenUrls } = args;
52
- const payload = projectOutbound(attemptEvents);
53
- const context = {
54
- stage: 'output_final',
55
- trust: 'untrusted',
56
- profileId: profile.id,
57
- ...(profile.lexicon ? { lexicon: profile.lexicon } : {}),
58
- ...(generation.canary ? { canary: generation.canary } : {}),
59
- ...(request.input?.slots ? { slots: request.input.slots } : {}),
60
- ...(request.input?.role ? { role: request.input.role } : {}),
61
- givenUrls,
62
- };
63
- // The host policy adds checks; it never releases a system-prompt leak.
64
- const verdict = promptLeaks?.length
65
- ? {
66
- action: 'block',
67
- hits: promptLeaks,
68
- rejection: lexiconText('egress.rejection', { rules: hitRules(promptLeaks).join(', ') }, profile.lexicon),
54
+ /** The verdict on an attempt's reply, as `guardrails.detect` reads it whole. */
55
+ function evaluateEgressOutcome(args) {
56
+ const { attemptEvents, request, profile, canRetry, promptLeaks } = args;
57
+ const { detect, blockedReply } = args.policy;
58
+ const written = projectOutbound(attemptEvents);
59
+ const scope = scopeOf(args.policy, {
60
+ canary: args.generation.canary,
61
+ canaryGiven: args.canaryGiven,
62
+ privateSystem: args.privateSystem,
63
+ givenUrls: args.givenUrls,
64
+ ...(args.ownTools ? { ownTools: args.ownTools } : {}),
65
+ ...(profile.labels ? { labels: profile.labels } : {}),
66
+ });
67
+ const read = readReply(written, detect, {
68
+ boundary: 'reply',
69
+ ...(args.withheld ? { reportedTo: args.released.length } : {}),
70
+ scope,
71
+ });
72
+ const { payload } = read;
73
+ /** Text that takes the written reply's place, as the host receives it. */
74
+ const replacement = (text) => ({
75
+ action: 'refusal',
76
+ event: { type: 'text', text },
77
+ });
78
+ const stopped = standingBlock(read, promptLeaks);
79
+ // why: A detector's block is reported by its own event, which names the boundary.
80
+ const judged = stopped && stopped !== read.blocked
81
+ ? guardrailFromHits('output_final', 'untrusted', stopped, 'block')
82
+ : undefined;
83
+ const guardrails = [...read.events.map(guardrailTurnEvent), ...(judged ? [judged] : [])];
84
+ if (!stopped) {
85
+ if (read.rewritten) {
86
+ // why: Text the stream could not replace as it went: the reply goes out replaced, whole.
87
+ return { outcome: replacement(replyAfter(args.shown, payload.text)), guardrails };
69
88
  }
70
- : await runEnforcer(egress.enforce, payload, context);
71
- const guardrail = guardrailFromVerdict('output_final', 'untrusted', verdict);
72
- // `flag` is advisory: the hit is recorded, the turn still releases.
73
- if (verdict.action === 'allow' || verdict.action === 'flag') {
74
- return { outcome: { action: 'pass' }, guardrail };
75
- }
76
- // The policy supplied safe replacement prose — release that instead.
77
- if (verdict.action === 'redact') {
89
+ const replaced = payload.structured !== written.structured;
78
90
  return {
79
- outcome: {
80
- action: 'refusal',
81
- event: { type: 'text', text: verdict.text },
82
- },
83
- guardrail,
91
+ outcome: { action: 'pass' },
92
+ guardrails,
93
+ ...(replaced ? { structured: payload.structured } : {}),
84
94
  };
85
95
  }
86
- if (egress.onBlock === 'refuse_to_user') {
87
- const text = lexiconText('egress.refusal', {}, profile.lexicon);
88
- return { outcome: { action: 'refusal', event: { type: 'text', text } }, guardrail };
96
+ if (blockedReply.onBlock === 'refuse') {
97
+ return { outcome: replacement(refusalAfter(args.shown, profile.labels)), guardrails };
89
98
  }
90
99
  if (canRetry) {
91
- const nextRequest = buildRepairRequest(request, payload.text, verdict.rejection, lexiconText('egress.default_repair_guidance', {}, profile.lexicon));
92
- return { outcome: { action: 'retry', nextRequest }, guardrail };
100
+ const nextRequest = buildRepairRequest(request, payload.text, retryRejection(stopped, detect, profile.labels), labelText('egress.default_repair_guidance', {}, profile.labels));
101
+ return { outcome: { action: 'retry', nextRequest }, guardrails };
93
102
  }
94
103
  return {
95
104
  outcome: {
96
105
  action: 'withhold',
97
106
  event: toErrorEvent(new TheoremError('safety', WITHHELD_REASON.egress)),
98
107
  },
99
- guardrail,
108
+ guardrails,
100
109
  };
101
110
  }
102
111
  async function evaluateValidationOutcome(args) {
@@ -109,34 +118,31 @@ async function evaluateValidationOutcome(args) {
109
118
  throw new TheoremError('config', 'outputs.validation requires outputs.structured with a JSON Schema');
110
119
  }
111
120
  const failures = await collectValidationFailures(structured.jsonSchema, latestStructured, validation.fields, request.input?.slots);
112
- if (failures.length === 0) {
121
+ if (failures.length === 0)
113
122
  return { action: 'pass' };
114
- }
115
- const error = formatValidationFailures(failures);
116
- if (canRetry) {
117
- const nextRequest = buildRepairRequest(request, latestStructured, error);
118
- return { action: 'retry', nextRequest };
119
- }
120
- return {
121
- action: 'accept',
122
- event: { type: 'structured', structured: latestStructured },
123
- };
123
+ if (!canRetry)
124
+ return { action: 'pass', failed: failures };
125
+ const nextRequest = buildRepairRequest(request, latestStructured, formatValidationFailures(failures));
126
+ return { action: 'retry', nextRequest };
124
127
  }
125
- function* yieldBufferedAttemptEvents(events, alreadyStreamedUserVisible) {
128
+ function* yieldBufferedAttemptEvents(events, alreadyStreamedUserVisible, generation) {
126
129
  for (const ev of events) {
127
130
  if (ev.type === 'tokens') {
128
131
  continue;
129
132
  }
130
- // Thoughts always streamed live; text and media did unless the attempt withheld them.
133
+ // why: Thoughts always streamed live; text and media did unless the attempt withheld them.
131
134
  if (ev.type === 'thought' || (alreadyStreamedUserVisible && isWithheldOnBlock(ev))) {
132
135
  continue;
133
136
  }
134
- yield ev;
137
+ // why: A held structured reply was judged whole; its drafts are the JSON before that check, so the `structured` event alone shows it.
138
+ const shown = shownToHost(ev, { ...generation, stream: false });
139
+ if (shown)
140
+ yield shown;
135
141
  }
136
142
  }
137
143
  /**
138
144
  * Start the next attempt with the repair added. The turn is not resolved again:
139
- * the retry keeps attempt 1's canary, tools and system prompt, and only the
145
+ * the retry keeps attempt 1's canary, tools, and system prompt, and only the
140
146
  * repair prompt is new.
141
147
  */
142
148
  function updateFlowForRetry(flow, state, profile, nextReq, reason) {
@@ -146,34 +152,68 @@ function updateFlowForRetry(flow, state, profile, nextReq, reason) {
146
152
  flow.currentReq = nextReq;
147
153
  const safe = sanitizeTurnRequest(nextReq, profile);
148
154
  if (profile.type === 'text') {
149
- // The conversation is already in turn history: the repair is its next user message.
155
+ // why: The conversation is already in turn history: the repair is its next user message.
156
+ const before = state.currentHistory.length;
150
157
  appendUserInput(state, resolveInputParts(profile, { ...safe, input: { repair: safe.input?.repair } }));
151
- return;
158
+ for (const message of state.currentHistory.slice(before))
159
+ quotesOwnReply(state, message);
152
160
  }
153
- // An image or speech call reads only its input: the repair replaces the prompt.
154
- flow.currentGen = { ...flow.currentGen, input: resolveInputParts(profile, safe) };
161
+ else {
162
+ // why: An image or speech call reads only its input: the repair replaces the prompt.
163
+ const input = resolveInputParts(profile, safe);
164
+ quotesOwnReply(state, input);
165
+ flow.currentGen = { ...flow.currentGen, input };
166
+ }
167
+ const event = { type: 'attempt', attempt: flow.currentAttempt, reason };
168
+ state.allEmittedEvents.push(event);
169
+ return event;
170
+ }
171
+ /**
172
+ * A repair hands the stopped reply back, and the model wrote that reply. What
173
+ * carries it gives the model nothing: a canary or a URL in it is still a leak
174
+ * on the next attempt.
175
+ */
176
+ function quotesOwnReply(state, carrier) {
177
+ state.canaryScanned.add(carrier);
178
+ state.givenUrls.own.add(carrier);
179
+ }
180
+ /** Whether an attempt holds its reply text to its end: one validated and not streamed. */
181
+ function holdsVisible(profile, generation) {
182
+ return profileTurnOutputs(profile)?.validation !== undefined && generation.stream === false;
155
183
  }
156
- async function* handleEgressGate(egress, flow, state, profile, maxRetries) {
157
- const canRetry = flow.currentAttempt < maxRetries;
184
+ async function* handleEgressGate(policy, flow, state, profile, privateSystem) {
185
+ const canRetry = flow.currentAttempt < policy.blockedReply.maxRetries;
158
186
  const checkStart = performance.now();
159
- const { outcome, guardrail } = await evaluateEgressOutcome({
160
- egress,
187
+ const { outcome, guardrails, structured } = await evaluateEgressOutcome({
188
+ policy,
161
189
  attemptEvents: state.attemptEvents,
190
+ withheld: state.withheldVisible === true,
191
+ released: state.released,
192
+ shown: holdsVisible(profile, flow.currentGen) ? '' : state.released,
162
193
  generation: flow.currentGen,
163
194
  request: flow.currentReq,
164
195
  profile,
165
196
  canRetry,
166
197
  ...(state.promptLeaks ? { promptLeaks: state.promptLeaks } : {}),
167
198
  givenUrls: state.givenUrls,
199
+ canaryGiven: state.canaryGiven,
200
+ privateSystem,
201
+ ...(state.ownTools ? { ownTools: state.ownTools } : {}),
168
202
  });
169
- state.trace.root.event('theorem.guardrail', guardrailCheckAttributes('egress', performance.now() - checkStart, guardrail?.guardrail, {
203
+ state.trace.root.event('theorem.guardrail', guardrailCheckAttributes('egress', performance.now() - checkStart, guardrails.at(-1)?.guardrail, {
170
204
  stage: 'output_final',
171
205
  trust: 'untrusted',
172
206
  }));
173
- if (guardrail) {
207
+ for (const guardrail of guardrails) {
174
208
  state.allEmittedEvents.push(guardrail);
175
209
  yield guardrail;
176
210
  }
211
+ if (structured !== undefined) {
212
+ // why: What validation reads and the host receives is the structured output as replaced.
213
+ const held = findLast(state.attemptEvents, (event) => event.type === 'structured');
214
+ if (held)
215
+ state.attemptEvents[state.attemptEvents.indexOf(held)] = { ...held, structured };
216
+ }
177
217
  if (outcome.action === 'refusal') {
178
218
  state.lastStop = EGRESS_FILTERED_STOP;
179
219
  state.allEmittedEvents.push(outcome.event);
@@ -186,34 +226,175 @@ async function* handleEgressGate(egress, flow, state, profile, maxRetries) {
186
226
  return 'terminal';
187
227
  }
188
228
  if (outcome.action === 'retry') {
189
- updateFlowForRetry(flow, state, profile, outcome.nextRequest, 'egress');
229
+ yield updateFlowForRetry(flow, state, profile, outcome.nextRequest, 'egress');
190
230
  return 'continue';
191
231
  }
192
232
  return 'pass';
193
233
  }
194
- async function* handleValidationGate(validation, flow, state, profile, latestStructured, maxRetries) {
195
- const canRetry = flow.currentAttempt < maxRetries;
234
+ /** The refused items of each list, in the reply's own shape and order. */
235
+ function refusedLists(refused) {
236
+ let lists = {};
237
+ for (const path of new Set(refused.map((failure) => failure.path))) {
238
+ const items = refused.filter((failure) => failure.path === path).map(({ item }) => item);
239
+ lists = withListAt(lists, path, items);
240
+ }
241
+ return lists;
242
+ }
243
+ /**
244
+ * The schema a rewrite of refused items answers under: the reply's shape, holding
245
+ * only the lists that had a refused item.
246
+ *
247
+ * why: Under the reply's own schema the model would write the whole reply again to change one item.
248
+ */
249
+ function fixSchemaFor(jsonSchema, paths) {
250
+ const root = { type: 'object', properties: {}, required: [] };
251
+ // why: An item schema may point into the reply schema's definitions.
252
+ if (jsonSchema.$defs !== undefined)
253
+ root.$defs = jsonSchema.$defs;
254
+ for (const path of paths) {
255
+ const items = itemSchemaAt(jsonSchema, path);
256
+ if (!items)
257
+ continue;
258
+ const keys = path.split('.');
259
+ let node = root;
260
+ for (const [depth, key] of keys.entries()) {
261
+ if (!node.required.includes(key))
262
+ node.required.push(key);
263
+ if (depth === keys.length - 1) {
264
+ node.properties[key] = { type: 'array', items };
265
+ break;
266
+ }
267
+ const next = node.properties[key];
268
+ const child = next?.type === 'object' ? next : { type: 'object', properties: {}, required: [] };
269
+ node.properties[key] = child;
270
+ node = child;
271
+ }
272
+ }
273
+ return root;
274
+ }
275
+ /** `fix.reply` with each refused item replaced by its rewrite, matched by position; one with no rewrite stays as it was. */
276
+ function withRewrittenItems(fix, rewrite) {
277
+ let reply = fix.reply;
278
+ for (const path of new Set(fix.refused.map((failure) => failure.path))) {
279
+ const list = valueAt(reply, path);
280
+ const rewritten = valueAt(rewrite, path);
281
+ if (!Array.isArray(list) || !Array.isArray(rewritten))
282
+ continue;
283
+ const next = [...list];
284
+ const refusedHere = fix.refused.filter((failure) => failure.path === path);
285
+ for (const [position, failure] of refusedHere.entries()) {
286
+ if (position < rewritten.length)
287
+ next[failure.index] = rewritten[position];
288
+ }
289
+ reply = withListAt(reply, path, next);
290
+ }
291
+ return reply;
292
+ }
293
+ /** `reply` without its refused items. */
294
+ function withoutItems(reply, refused) {
295
+ let next = reply;
296
+ for (const path of new Set(refused.map((failure) => failure.path))) {
297
+ const list = valueAt(next, path);
298
+ if (!Array.isArray(list))
299
+ continue;
300
+ const gone = new Set(refused.filter((failure) => failure.path === path).map(({ index }) => index));
301
+ next = withListAt(next, path, list.filter((_, index) => !gone.has(index)));
302
+ }
303
+ return next;
304
+ }
305
+ /**
306
+ * Makes `reply` the attempt's structured output, with what the item rules removed.
307
+ *
308
+ * why: The buffered text is the model's own JSON, which no longer matches; held text goes out as the reply that is kept, and streamed text is skipped at release as it always is.
309
+ */
310
+ function holdReply(state, reply, removed, failed) {
311
+ const event = {
312
+ type: 'structured',
313
+ structured: reply,
314
+ ...(removed.length
315
+ ? { removed: removed.map(({ path, reason, item }) => ({ path, reason, item })) }
316
+ : {}),
317
+ ...(failed ? { failed } : {}),
318
+ };
319
+ state.attemptEvents = [
320
+ ...state.attemptEvents.filter((held) => held.type !== 'structured' && held.type !== 'text'),
321
+ { type: 'text', text: JSON.stringify(reply) },
322
+ event,
323
+ ];
324
+ }
325
+ /** The next attempt rewrites only the refused items, under a schema that holds only their lists. */
326
+ function startItemFix(args) {
327
+ const { flow, state, profile, reply, refused, structured } = args;
328
+ const positions = new Map();
329
+ const rejection = refused
330
+ .map(({ path, reason }) => {
331
+ const position = positions.get(path) ?? 0;
332
+ positions.set(path, position + 1);
333
+ return `${path}[${position}]: ${reason}`;
334
+ })
335
+ .join('\n');
336
+ const nextRequest = buildRepairRequest(flow.currentReq, refusedLists(refused), rejection, labelText('repair.items_guidance', {}, profile.labels));
337
+ flow.pendingItemFix = { reply, refused, structured };
338
+ const attempt = updateFlowForRetry(flow, state, profile, nextRequest, 'validation');
339
+ flow.currentGen = {
340
+ ...flow.currentGen,
341
+ structured: {
342
+ id: structured.id,
343
+ jsonSchema: fixSchemaFor(structured.jsonSchema, refused.map(({ path }) => path)),
344
+ },
345
+ };
346
+ return attempt;
347
+ }
348
+ async function handleValidationGate(validation, flow, state, profile, latestStructured) {
349
+ const canRetry = flow.currentAttempt < (validation.maxRetries ?? 0);
350
+ const fix = flow.pendingItemFix;
351
+ let reply = latestStructured;
352
+ if (fix) {
353
+ // why: The attempt that just ended answered under the fix schema; the reply is the one the items were refused in, with the rewrites put back.
354
+ flow.pendingItemFix = undefined;
355
+ flow.currentGen = { ...flow.currentGen, structured: fix.structured };
356
+ reply = withRewrittenItems(fix, latestStructured);
357
+ holdReply(state, reply, []);
358
+ }
196
359
  const outcome = await evaluateValidationOutcome({
197
360
  validation,
198
361
  generation: flow.currentGen,
199
- latestStructured,
362
+ latestStructured: reply,
200
363
  request: flow.currentReq,
201
364
  canRetry,
202
365
  });
203
366
  if (outcome.action === 'retry') {
204
- updateFlowForRetry(flow, state, profile, outcome.nextRequest, 'validation');
205
- return 'continue';
367
+ return updateFlowForRetry(flow, state, profile, outcome.nextRequest, 'validation');
206
368
  }
207
- if (outcome.action === 'accept') {
208
- state.allEmittedEvents.push(outcome.event);
209
- yield outcome.event;
210
- return 'terminal';
369
+ if (reply === undefined)
370
+ return 'pass';
371
+ if (outcome.failed)
372
+ markFailed(state, outcome.failed);
373
+ const slots = flow.currentReq.input?.slots;
374
+ const refused = await collectItemFailures(reply, validation.items, {
375
+ ...(slots ? { slots } : {}),
376
+ toolResults: state.toolResults,
377
+ });
378
+ if (refused.length === 0)
379
+ return 'pass';
380
+ const fixable = refused.filter((failure) => failure.onFail === 'fix');
381
+ const structured = flow.currentGen.structured;
382
+ // invariant: Refused items get one rewrite. Refused again, they are removed.
383
+ if (fixable.length > 0 && canRetry && !fix && structured) {
384
+ return startItemFix({ flow, state, profile, reply, refused: fixable, structured });
211
385
  }
386
+ holdReply(state, withoutItems(reply, refused), refused, outcome.failed);
212
387
  return 'pass';
213
388
  }
214
- function gateStatusToAction(status, terminalStatus = 'terminal') {
389
+ /** Puts on the attempt's structured output the fields that still failed. */
390
+ function markFailed(state, failed) {
391
+ const held = findLast(state.attemptEvents, (event) => event.type === 'structured');
392
+ if (held)
393
+ state.attemptEvents[state.attemptEvents.indexOf(held)] = { ...held, failed };
394
+ }
395
+ function gateStatusToAction(status) {
215
396
  if (status === 'terminal') {
216
- return { status: terminalStatus };
397
+ return { status: 'terminal' };
217
398
  }
218
399
  if (status === 'continue') {
219
400
  return { status: 'continue' };
@@ -221,16 +402,17 @@ function gateStatusToAction(status, terminalStatus = 'terminal') {
221
402
  return null;
222
403
  }
223
404
  async function* executeSingleAttemptCycle(args) {
224
- const { flow, state, profile, system, provider, maxRetries } = args;
405
+ const { flow, state, profile, system, provider } = args;
225
406
  const validation = profileTurnOutputs(profile)?.validation;
226
- const egress = resolveGuardrailPolicy(profile.guardrails).egress;
227
- // Fresh maxSteps budget per validation/egress attempt. before_end inject
407
+ const policy = resolveGuardrailPolicy(profile.guardrails);
408
+ const judged = replyIsJudged(policy, TURN_REPLY);
409
+ // invariant: Fresh maxSteps budget per validation/egress attempt. before_end inject
228
410
  // re-entry inside this cycle still accumulates stepCount (do not reset there).
229
411
  state.stepCount = 0;
230
412
  let latestStructured;
231
- // before_end may inject and re-enter the step loop under maxSteps.
232
413
  for (;;) {
233
414
  state.attemptEvents = [];
415
+ state.released = '';
234
416
  state.withheldVisible = false;
235
417
  state.promptLeaks = undefined;
236
418
  const attempt = yield* executeAttempt({
@@ -242,8 +424,10 @@ async function* executeSingleAttemptCycle(args) {
242
424
  state,
243
425
  });
244
426
  latestStructured = attempt.latestStructured;
245
- // Tool / gate suspension — do not before_end; finalize with that stop.
246
- if (state.lastStop?.kind === 'tool' || state.lastStop?.kind === 'gate') {
427
+ // why: Tool / gate suspension, or no answer to check — do not before_end; finalize with that stop.
428
+ if (state.lastStop?.kind === 'tool' ||
429
+ state.lastStop?.kind === 'gate' ||
430
+ state.lastStop?.kind === 'step_limit') {
247
431
  break;
248
432
  }
249
433
  if (state.lastStop?.kind === 'cancelled') {
@@ -270,35 +454,38 @@ async function* executeSingleAttemptCycle(args) {
270
454
  return { status: 'terminal' };
271
455
  }
272
456
  if (beforeEnd.injectCount > 0) {
273
- // Host extended the turn — another provider step under maxSteps.
274
457
  continue;
275
458
  }
276
459
  break;
277
460
  }
278
- if (egress?.enforce) {
279
- const status = yield* handleEgressGate(egress, flow, state, profile, maxRetries);
280
- const action = gateStatusToAction(status, 'terminal');
461
+ if (judged) {
462
+ const status = yield* handleEgressGate(policy, flow, state, profile, system.private);
463
+ const action = gateStatusToAction(status);
281
464
  if (action) {
282
465
  return action;
283
466
  }
467
+ latestStructured = projectOutbound(state.attemptEvents).structured ?? latestStructured;
284
468
  }
285
469
  if (validation) {
286
- const status = yield* handleValidationGate(validation, flow, state, profile, latestStructured, maxRetries);
287
- const action = gateStatusToAction(status, 'success');
288
- if (action) {
289
- return action;
470
+ const status = await handleValidationGate(validation, flow, state, profile, latestStructured);
471
+ if (status !== 'pass') {
472
+ yield status;
473
+ return { status: 'continue' };
290
474
  }
291
475
  }
292
- if (validation || egress?.enforce) {
293
- // Progressive-yield already released text and media live under egress — unless it
476
+ if (validation || judged) {
477
+ // why: Progressive-yield already released text and media live under egress — unless it
294
478
  // withheld them mid-stream. A passing final verdict on the full text supersedes
295
479
  // that partial-window decision, so the buffer is released instead of dropped.
296
- yield* yieldBufferedAttemptEvents(state.attemptEvents, !state.withheldVisible);
480
+ const heldVisible = state.withheldVisible || holdsVisible(profile, flow.currentGen);
481
+ yield* yieldBufferedAttemptEvents(state.attemptEvents, !heldVisible, flow.currentGen);
297
482
  }
298
483
  return { status: 'success' };
299
484
  }
300
485
  async function* runAttemptsWithValidation(safe, profile, generation, system, provider, state) {
301
- const maxRetries = Math.max(profileTurnOutputs(profile)?.validation?.maxRetries ?? 0, resolveGuardrailPolicy(profile.guardrails).egress?.maxRetries ?? 0);
486
+ const { blockedReply } = resolveGuardrailPolicy(profile.guardrails);
487
+ // why: Each gate counts the attempts against its own cap; the turn runs while either has one left.
488
+ const maxRetries = Math.max(profileTurnOutputs(profile)?.validation?.maxRetries ?? 0, blockedReply.onBlock === 'retry' ? blockedReply.maxRetries : 0);
302
489
  const flow = {
303
490
  currentAttempt: 0,
304
491
  currentGen: generation,
@@ -312,7 +499,6 @@ async function* runAttemptsWithValidation(safe, profile, generation, system, pro
312
499
  profile,
313
500
  system,
314
501
  provider,
315
- maxRetries,
316
502
  });
317
503
  if (step.status === 'terminal' || step.status === 'success') {
318
504
  break;
@@ -1,15 +1,29 @@
1
1
  import type { TraceSink } from '../../../observability/trace-sink.js';
2
+ import type { ProviderHostOptions } from '../../protocols/runtime.js';
2
3
  import type { KernelRegistry } from '../../registry/kernel-registry.js';
3
- import type { CompactHistoryRequest, CompactionResult, ModelProvider, TurnEvent, TurnRequest } from '../../types.js';
4
+ import type { AgentCaller } from '../../tools/agent.js';
5
+ import type { InvokeToolRequest } from '../../tools/types.js';
6
+ import type { CompactHistoryRequest, CompactionResult, SessionRequest, TurnEvent, TurnModel, TurnRequest } from '../../types.js';
4
7
  /**
5
8
  * The trace record is written however the turn ends, including when the host stops reading early;
6
9
  * spans still open then close as `ERROR` / `unclosed`.
7
10
  */
8
- declare function runTurnInRegistry(registry: KernelRegistry, req: TurnRequest, provider: ModelProvider, sinkOverride?: TraceSink): AsyncGenerator<TurnEvent>;
11
+ declare function runTurnInRegistry(registry: KernelRegistry, req: TurnRequest, provider: TurnModel, sinkOverride?: TraceSink): AsyncGenerator<TurnEvent>;
12
+ /**
13
+ * A host's own call's agent tools: the host's provider, or the one `onAgentCall`
14
+ * returns, runs each. Its nested turns bind their canaries into `canaries`.
15
+ */
16
+ declare function invokeAgentCaller(registry: KernelRegistry, request: InvokeToolRequest, canaries: string[]): AgentCaller;
17
+ /**
18
+ * A live session's agent tools: the session's own provider options, or those
19
+ * `onAgentCall` returns, run each. Its nested turns bind their canaries into
20
+ * `canaries`.
21
+ */
22
+ declare function sessionAgentCaller(registry: KernelRegistry, req: Pick<SessionRequest, 'onAgentCall' | 'metadata'>, options: ProviderHostOptions & Pick<TurnRequest, 'execution'>, canaries: string[]): AgentCaller;
9
23
  /**
10
24
  * `timing: 'after'`: run the compactor on the history `done.compaction` carried,
11
- * with the same split, failure rules and trace as `before`. `provider` runs the
25
+ * with the same split, failure rules, and trace as `before`. `provider` runs the
12
26
  * compactor. `undefined` when the split leaves nothing to compact.
13
27
  */
14
- declare function compactHistoryInRegistry(registry: KernelRegistry, req: CompactHistoryRequest, provider: ModelProvider, sinkOverride?: TraceSink): Promise<CompactionResult | undefined>;
15
- export { compactHistoryInRegistry, runTurnInRegistry };
28
+ declare function compactHistoryInRegistry(registry: KernelRegistry, req: CompactHistoryRequest, provider: TurnModel, sinkOverride?: TraceSink): Promise<CompactionResult | undefined>;
29
+ export { compactHistoryInRegistry, invokeAgentCaller, runTurnInRegistry, sessionAgentCaller };