@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,32 +1,57 @@
1
- import { errorKind, isAbortError, throwIfAborted } from '../../guardrails/error.js';
2
- import { lexiconText } from '../../guardrails/lexicon.js';
1
+ import { toolBoundary } from '../../guardrails/boundaries.js';
2
+ import { checkDestinationGate } from '../../guardrails/destinations.js';
3
+ import { scopeOf } from '../../guardrails/detect-at.js';
4
+ import { errorKind, isAbortError, TheoremError, throwIfAborted } from '../../guardrails/error.js';
5
+ import { labelText } from '../../guardrails/labels.js';
3
6
  import { resolveGuardrailPolicy } from '../../guardrails/policy.js';
4
- import { resolveSensitive } from '../../guardrails/sensitive.js';
5
- import { checkTaintGate, guardToolFailureText, guardToolResult, inspectToolArguments, toolCallEvent, } from '../../guardrails/tool-result.js';
7
+ import { checkTaintGate, guardShownValue, guardToolFailureText, guardToolResult, inspectToolArguments, toolCallEvent, } from '../../guardrails/tool-result.js';
6
8
  import { recordToolCheck, startToolTrace, } from '../engine/tool-trace.js';
7
- import { isAwaitingUserInput } from '../stages.js';
9
+ import { jsonObjectSchema } from '../json.js';
10
+ import { isAwaitingUserInput } from '../turn-events.js';
8
11
  import { isRecord } from '../util/record.js';
9
12
  import { fillActivityLabel } from './activity-label.js';
10
- import { failureEvent, messageOf, networkBlocked, networkBlockedEvent, requestChecks, sourceEvents, startToolExecution, toolCallArguments, toolEvent, } from './events.js';
11
- import { formatToolFailureForModel, formatToolResult } from './model-text.js';
12
- import { checkPermission, isGateResumeDenied, isGateResumeGranted, isResumeContinuation, } from './permission.js';
13
+ import { AgentCallFailed, agentToolOrigin } from './agent.js';
14
+ import { coordinateTool } from './coordinate.js';
15
+ import { dispatchToolBody, failedActivity, failedActivityOf, failureEvent, messageOf, networkBlocked, networkBlockedEvent, requestChecks, sourceEvents, startToolExecution, toolCallArguments, toolEvent, } from './events.js';
16
+ import { HandlerEvents } from './handler-events.js';
17
+ import { formatToolFailureForModel, formatToolResult, frameToolFailure } from './model-text.js';
18
+ import { operationUnavailable, operationWireValue } from './operation.js';
19
+ import { checkPermission, gateDetails, isGateResumeDenied, isGateResumeGranted, isResumeContinuation, } from './permission.js';
13
20
  import { executeHttpTool, executeMcpTool, failureWithoutSecret, modelResultFromOutput, omitSecret, outcomeFromUnauth, parseToolOutput, refusedCredentialOutcome, resolveToolAuth, withMedia, } from './remote.js';
14
21
  import { extractLoadedIds, profileToolAllow, profileToolsSpec, promoteLoadedTools, } from './resolve.js';
15
22
  import { plainToolInput } from './schema.js';
16
23
  import { CredentialRefusedError, signedInFetch } from './signed-in-fetch.js';
17
24
  import { emitGateSettlement, runPostToolStages, runPreToolPipeline, } from './stage-run.js';
18
25
  export { checkPermission, isGateResumeGranted, isResumeContinuation, permissionGranted, } from './permission.js';
19
- function originOfTool(type) {
20
- if (type === 'http')
26
+ import { UncheckedOutput } from './unchecked-output.js';
27
+ function originOfTool(tool, tools) {
28
+ if (tool.type === 'agent')
29
+ return agentToolOrigin(tools.findProfile(tool.profile));
30
+ if (tool.type === 'http')
21
31
  return 'http';
22
- if (type === 'mcp')
32
+ if (tool.type === 'mcp')
23
33
  return 'mcp';
24
- if (type === 'builtin')
34
+ if (tool.type === 'builtin')
25
35
  return 'builtin';
26
36
  return 'local';
27
37
  }
28
- function provenanceFor(tool, depth = 1) {
29
- return { origin: originOfTool(tool.type), tool: tool.name, depth };
38
+ /** The kind whose boundaries a tool's calls cross. A provider builtin crosses none. */
39
+ function toolKindOf(tool) {
40
+ return tool.type === 'builtin' ? undefined : tool.type;
41
+ }
42
+ /**
43
+ * The boundary a call of `name` is read at before its tool gets it: none for a provider builtin,
44
+ * whose text the kernel never reads. A call no tool takes is read as a function tool's.
45
+ */
46
+ export function toolArgumentsBoundary(tools, name) {
47
+ const tool = tools.get(name);
48
+ const kind = tool ? toolKindOf(tool) : 'function';
49
+ return kind && toolBoundary('tool_arguments', kind);
50
+ }
51
+ /** A delegated reply is one hop past the called agent's own tools. */
52
+ function provenanceFor(tool, tools) {
53
+ const origin = originOfTool(tool, tools);
54
+ return { origin, tool: tool.name, depth: origin === 'delegated' ? 2 : 1 };
30
55
  }
31
56
  function isStreamHandler(handler) {
32
57
  return (typeof handler === 'function' &&
@@ -59,27 +84,14 @@ export function coerceToolResultParts(raw) {
59
84
  }
60
85
  return parts.length > 0 ? parts : undefined;
61
86
  }
87
+ /** A tool's output without its `parts` key, which carries media the model receives separately; any other value is returned as it is. */
62
88
  export function leanToolResultData(output) {
63
89
  if (!isRecord(output))
64
90
  return output;
65
91
  const { parts: _parts, ...rest } = output;
66
92
  return rest;
67
93
  }
68
- export function* yieldHandlerSideEvent(base, event) {
69
- if (event.kind === 'progress') {
70
- yield toolEvent(base, { phase: 'progress', data: event.data });
71
- }
72
- else if (event.kind === 'trace') {
73
- yield toolEvent(base, { phase: 'trace', step: event.step });
74
- }
75
- else if (event.kind === 'artifact') {
76
- yield toolEvent(base, { phase: 'artifact', artifact: event.artifact });
77
- }
78
- else if (event.kind === 'warning') {
79
- yield toolEvent(base, { phase: 'warning', warning: event.warning });
80
- }
81
- }
82
- async function* runHandler(handler, input, ctx, base) {
94
+ async function* runHandler(handler, input, ctx, shown) {
83
95
  if (isStreamHandler(handler)) {
84
96
  let output;
85
97
  const gen = handler(input, ctx);
@@ -89,20 +101,22 @@ async function* runHandler(handler, input, ctx, base) {
89
101
  output = event.output;
90
102
  continue;
91
103
  }
92
- yield* yieldHandlerSideEvent(base, event);
104
+ yield* shown.show(event);
93
105
  }
106
+ yield* shown.end();
94
107
  return output;
95
108
  }
96
109
  const output = await handler(input, ctx);
97
- return output;
110
+ return output instanceof UncheckedOutput ? output.value : output;
98
111
  }
99
- export function projectForModel(tool, output, lexicon) {
112
+ /** What the model is told of a function tool's output: a fixed finding for a hidden tool, a finding plus the output for an awaiting-user result, otherwise the tool's own summary or finding and its data. */
113
+ export function projectForModel(tool, output, labels) {
100
114
  if (tool.exposeToModel === false) {
101
- return { finding: lexiconText('tool.completed_hidden', {}, lexicon) };
115
+ return { finding: labelText('tool.completed_hidden', {}, labels) };
102
116
  }
103
117
  if (isAwaitingUserInput(output)) {
104
118
  return {
105
- finding: lexiconText('tool.awaiting_user', { kind: output.kind, prompt: output.prompt }, lexicon),
119
+ finding: labelText('tool.awaiting_user', { kind: output.kind, prompt: output.prompt }, labels),
106
120
  data: leanToolResultData(output),
107
121
  };
108
122
  }
@@ -131,7 +145,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
131
145
  failure: {
132
146
  code: 'invalid_output',
133
147
  kind: 'bad_response',
134
- message: lexiconText('tool.t2_loader_needs_snapshot', { tool: tool.name }, ctx.profile.lexicon),
148
+ message: labelText('tool.t2_loader_needs_snapshot', { tool: tool.name }, ctx.profile.labels),
135
149
  },
136
150
  };
137
151
  }
@@ -142,7 +156,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
142
156
  failure: {
143
157
  code: 'invalid_output',
144
158
  kind: 'bad_response',
145
- message: lexiconText('tool.t2_loader_shape', { tool: tool.name }, ctx.profile.lexicon),
159
+ message: labelText('tool.t2_loader_shape', { tool: tool.name }, ctx.profile.labels),
146
160
  },
147
161
  };
148
162
  }
@@ -158,7 +172,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
158
172
  failure: {
159
173
  code: 'invalid_output',
160
174
  kind: 'bad_response',
161
- message: lexiconText('tool.t2_loader_output_invalid', {}, ctx.profile.lexicon),
175
+ message: labelText('tool.t2_loader_output_invalid', {}, ctx.profile.labels),
162
176
  details: rechecked.error.flatten(),
163
177
  },
164
178
  };
@@ -176,7 +190,7 @@ function* reviseAfterStages(post, guard, reproject) {
176
190
  return {
177
191
  failure,
178
192
  outputRaw: undefined,
179
- modelResult: yield* guard.failure(failure),
193
+ modelResult: (yield* guard.failure(failure)).modelResult,
180
194
  awaiting: false,
181
195
  };
182
196
  }
@@ -187,22 +201,33 @@ function* reviseAfterStages(post, guard, reproject) {
187
201
  return {
188
202
  failure: next.failure,
189
203
  outputRaw: undefined,
190
- modelResult: yield* guard.failure(next.failure),
204
+ modelResult: (yield* guard.failure(next.failure)).modelResult,
205
+ awaiting: false,
206
+ };
207
+ }
208
+ const guarded = yield* guard.result(next.modelResult);
209
+ if (guarded.withheld) {
210
+ return {
211
+ failure: guarded.withheld,
212
+ outputRaw: undefined,
213
+ modelResult: guarded.modelResult,
191
214
  awaiting: false,
192
215
  };
193
216
  }
194
217
  return {
195
218
  outputRaw: next.outputRaw,
196
- modelResult: yield* guard.result(next.modelResult),
219
+ modelResult: guarded.modelResult,
197
220
  awaiting: isAwaitingUserInput(next.outputRaw),
198
221
  };
199
222
  }
223
+ function pastActivity(labels, input, output) {
224
+ return fillActivityLabel(labels?.activityPast, { input, output });
225
+ }
200
226
  function completeEvent(base, settled) {
201
227
  const { input, outputRaw, modelResult } = settled;
202
- const activityPast = fillActivityLabel(settled.labels?.activityPast, {
203
- input,
204
- output: outputRaw,
205
- });
228
+ const activityPast = settled.labelFailed
229
+ ? failedActivityOf(base)
230
+ : pastActivity(settled.labels, input, outputRaw);
206
231
  return toolEvent(base, {
207
232
  phase: 'complete',
208
233
  output: outputRaw,
@@ -217,16 +242,18 @@ function completeEvent(base, settled) {
217
242
  */
218
243
  async function* settleToolCall(args) {
219
244
  const { base, toolName, callId, input, stages, provisional, guard, reproject, sources } = args;
220
- let modelResult = yield* 'failure' in provisional
245
+ const guarded = yield* 'failure' in provisional
221
246
  ? guard.failure(provisional.failure)
222
247
  : guard.result(provisional.modelResult);
223
- let failure = 'failure' in provisional ? provisional.failure : undefined;
224
- let outputRaw = 'outputRaw' in provisional ? provisional.outputRaw : undefined;
248
+ let modelResult = guarded.modelResult;
249
+ let failure = 'failure' in provisional ? provisional.failure : guarded.withheld;
250
+ let outputRaw = 'outputRaw' in provisional && !failure ? provisional.outputRaw : undefined;
225
251
  const callNotStarted = 'callNotStarted' in provisional ? provisional.callNotStarted : undefined;
226
252
  let denied = 'denied' in provisional ? provisional.denied : undefined;
227
253
  let awaiting = !failure && isAwaitingUserInput(outputRaw);
228
254
  let post;
229
255
  if (stages) {
256
+ const activityPast = failure ? undefined : pastActivity(args.labels, input, outputRaw);
230
257
  post = yield* runPostToolStages({
231
258
  stages,
232
259
  toolName,
@@ -235,6 +262,8 @@ async function* settleToolCall(args) {
235
262
  callNotStarted,
236
263
  outputRaw,
237
264
  outputModel: modelResult,
265
+ ...(activityPast ? { activityPast } : {}),
266
+ activityFailed: failedActivityOf(base),
238
267
  failure,
239
268
  awaiting: awaiting || undefined,
240
269
  mutable: !failure && reproject !== undefined,
@@ -249,14 +278,26 @@ async function* settleToolCall(args) {
249
278
  if (!failure && sources)
250
279
  yield* sourceEvents(base, sources, outputRaw);
251
280
  yield failure
252
- ? failureEvent(base, failure, formatToolResult(modelResult))
253
- : completeEvent(base, { input, outputRaw, modelResult, labels: args.labels });
281
+ ? failureEvent(base, { ...failure, message: String(yield* guard.shown(failure.message)) }, formatToolResult(modelResult))
282
+ : completeEvent(base, {
283
+ input,
284
+ outputRaw: yield* guard.shown(outputRaw),
285
+ modelResult,
286
+ labels: args.labels,
287
+ ...(post?.labelFailed ? { labelFailed: true } : {}),
288
+ });
254
289
  return {
255
290
  modelResult,
256
291
  ...(failure ? { failure } : { outputRaw }),
257
292
  ...(denied ? { denied } : {}),
258
293
  ...(callNotStarted ? { callNotStarted: true } : {}),
259
294
  ...(awaiting ? { awaiting: true } : {}),
295
+ ...stageSettlement(post),
296
+ };
297
+ }
298
+ /** What the after-call stages add to a settlement: a turn to stop, input to hand the model. */
299
+ function stageSettlement(post) {
300
+ return {
260
301
  ...(post?.abort !== undefined ? { aborted: post.abort } : {}),
261
302
  ...(post?.inject.length ? { pendingInject: post.inject } : {}),
262
303
  };
@@ -276,16 +317,52 @@ function settleToolFailure(guard, base, failure, stages, args) {
276
317
  },
277
318
  });
278
319
  }
279
- function resultGuard(tool, ctx, snapshot, span) {
280
- const provenance = provenanceFor(tool);
320
+ function resultGuard(tools, tool, ctx, snapshot, span) {
321
+ const provenance = provenanceFor(tool, tools);
281
322
  const policy = resolveGuardrailPolicy(ctx.profile.guardrails);
282
323
  const callableTools = snapshot?.executable ?? [];
283
- const inputs = { provenance, policy, callableTools, lexicon: ctx.profile.lexicon, span };
324
+ const inputs = {
325
+ provenance,
326
+ policy,
327
+ kind: toolKindOf(tool),
328
+ callableTools,
329
+ labels: ctx.profile.labels,
330
+ span,
331
+ };
332
+ const { kind } = inputs;
333
+ const handlerEvents = (drafts) => kind && {
334
+ profileId: ctx.profile.id,
335
+ provenance,
336
+ policy,
337
+ boundary: toolBoundary('tool_output', kind),
338
+ shown: toolBoundary('tool_shown', kind),
339
+ callableTools,
340
+ drafts,
341
+ };
342
+ const shown = (value) => showValue(value, inputs);
343
+ const service = isGateResumeGranted(ctx.resume) ? signInService(tool, ctx.resume) : undefined;
344
+ if (!service) {
345
+ return {
346
+ result: (result) => guardResult(result, inputs),
347
+ failure: (failure) => guardFailure(failure, inputs),
348
+ handlerEvents,
349
+ shown,
350
+ };
351
+ }
352
+ const note = labelText('sign_in.done', { service }, ctx.profile.labels);
284
353
  return {
285
- result: (result) => guardResult(result, inputs),
286
- failure: (failure) => guardFailure(failure, inputs),
354
+ result: (result) => afterSignIn(note, guardResult(result, inputs)),
355
+ failure: (failure) => afterSignIn(note, guardFailure(failure, inputs)),
356
+ handlerEvents,
357
+ shown,
287
358
  };
288
359
  }
360
+ /** A call the person signed in for tells the model so before what it read back. */
361
+ function* afterSignIn(note, guarded) {
362
+ const read = yield* guarded;
363
+ const modelText = `${note}\n\n${formatToolResult(read.modelResult)}`;
364
+ return { ...read, modelResult: { ...read.modelResult, modelText } };
365
+ }
289
366
  async function* runFunctionPreBodyStages(args) {
290
367
  const { tool, base, stages, guard } = args;
291
368
  const pre = yield* runPreToolPipeline(args);
@@ -305,7 +382,7 @@ async function* runFunctionPreBodyStages(args) {
305
382
  ...(pre.denied ? { denied: true } : {}),
306
383
  });
307
384
  }
308
- function makeReproject(parse, project, lexicon) {
385
+ function makeReproject(parse, project, labels) {
309
386
  return (output) => {
310
387
  const checked = parse(output);
311
388
  if (!checked.success) {
@@ -314,7 +391,7 @@ function makeReproject(parse, project, lexicon) {
314
391
  failure: {
315
392
  code: 'invalid_output',
316
393
  kind: 'bad_response',
317
- message: lexiconText('tool.output_invalid_after_mutate', {}, lexicon),
394
+ message: labelText('tool.output_invalid_after_mutate', {}, labels),
318
395
  details: checked.error.flatten(),
319
396
  },
320
397
  };
@@ -333,31 +410,64 @@ async function* resolveFunctionSignIn(tool, ctx, base) {
333
410
  return {
334
411
  prepared: {
335
412
  authHeaders: resolved.headers,
413
+ ...(resolved.query ? { query: resolved.query } : {}),
336
414
  ...(resolved.audience ? { audience: resolved.audience } : {}),
337
415
  },
338
416
  ...(resolved.secret ? { secret: resolved.secret } : {}),
339
417
  };
340
418
  }
341
- export async function* executeFunction(tools, tool, rawInput, ctx, base, snapshot, stages) {
342
- const guard = resultGuard(tool, ctx, snapshot, stages?.span);
419
+ function functionHandlerFailure(error) {
420
+ return {
421
+ code: 'handler_error',
422
+ kind: error instanceof TheoremError ? error.kind : 'failed',
423
+ message: messageOf(error),
424
+ };
425
+ }
426
+ function waitsForPage(tool, ctx) {
427
+ return tool.answeredBy === 'page' && ctx.page === undefined && !ctx.pageExecution;
428
+ }
429
+ async function* receivePageAnswer(tool, ctx, claim, base) {
430
+ const execution = ctx.pageExecution;
431
+ if (tool.answeredBy !== 'page' || !execution)
432
+ return ctx;
433
+ if (!claim?.invocation)
434
+ throw operationUnavailable();
435
+ const argumentsForPage = jsonObjectSchema.parse(operationWireValue(claim.invocation.preparedInput));
436
+ const dispatch = await execution.dispatch(claim, ctx.signal);
437
+ throwIfAborted(ctx.signal);
438
+ if (!dispatch.grantId)
439
+ throw operationUnavailable();
440
+ yield toolEvent(base, {
441
+ phase: 'dispatch',
442
+ grantId: dispatch.grantId,
443
+ arguments: argumentsForPage,
444
+ });
445
+ ctx = { ...ctx, page: await dispatch.result };
446
+ throwIfAborted(ctx.signal);
447
+ return ctx;
448
+ }
449
+ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapshot, stages,
450
+ /** Set when `tool` runs an agent tool: its trust, and its handler's failures and faults. */
451
+ agent, beginBody) {
452
+ const guard = resultGuard(tools, agent ?? tool, ctx, snapshot, stages?.span);
343
453
  const callId = base.callId;
344
- const parsed = yield* startToolExecution(tool, rawInput, ctx, base);
454
+ const parsed = startToolExecution(tool, rawInput, ctx);
345
455
  if (!parsed.ok) {
346
- return yield* settleToolFailure(guard, base, {
347
- code: 'invalid_input',
348
- kind: 'bad_response',
349
- message: lexiconText('tool.input_invalid', {}, ctx.profile.lexicon),
350
- }, stages, { toolName: tool.name, callId, callNotStarted: true });
456
+ return yield* settleToolFailure(guard, base, parsed.failure, stages, {
457
+ toolName: tool.name,
458
+ callId,
459
+ callNotStarted: true,
460
+ });
351
461
  }
352
462
  let input = parsed.data;
353
- const permissionGate = checkPermission(tool.name, tool.permission, ctx.sessionPermissions, ctx.resume);
463
+ const permissionGate = checkPermission(tool.name, tool.permission, ctx.sessionPermissions, ctx.resume, gateDetails(tool, input));
354
464
  if (permissionGate) {
355
465
  yield* emitGateSettlement({
356
466
  base,
357
467
  gate: permissionGate,
358
468
  callId,
359
469
  toolName: tool.name,
360
- lexicon: ctx.profile.lexicon,
470
+ labels: ctx.profile.labels,
361
471
  });
362
472
  return { gated: permissionGate, callNotStarted: true };
363
473
  }
@@ -370,7 +480,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
370
480
  safeInput: input,
371
481
  stages,
372
482
  guard,
373
- lexicon: ctx.profile.lexicon,
483
+ labels: ctx.profile.labels,
374
484
  });
375
485
  const signedIn = yield* resolveFunctionSignIn(tool, ctx, base);
376
486
  if (signedIn.outcome)
@@ -380,7 +490,21 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
380
490
  return preBody;
381
491
  }
382
492
  input = preBody.input;
493
+ if (waitsForPage(tool, ctx)) {
494
+ // why: Last of the checks, so the page is asked only for a call every guardrail and gate let through.
495
+ const gate = { kind: 'page', tool: tool.name, ...gateDetails(tool, input) };
496
+ yield* emitGateSettlement({
497
+ base,
498
+ gate,
499
+ callId,
500
+ toolName: tool.name,
501
+ labels: ctx.profile.labels,
502
+ });
503
+ return { gated: gate, callNotStarted: true };
504
+ }
383
505
  throwIfAborted(ctx.signal);
506
+ const claim = yield* dispatchToolBody(tool, input, ctx, base, beginBody);
507
+ ctx = yield* receivePageAnswer(tool, ctx, claim, base);
384
508
  const { secret } = signedIn;
385
509
  const fail = (failure) => settleToolFailure(guard, base, secret ? failureWithoutSecret(failure, secret) : failure, stages, { toolName: tool.name, callId, input });
386
510
  const checks = requestChecks(stages?.span);
@@ -389,13 +513,20 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
389
513
  : ctx;
390
514
  let output;
391
515
  try {
392
- output = yield* runHandler(tool.handler, input, handlerCtx, base);
516
+ const shown = new HandlerEvents(base, guard.handlerEvents(stages?.drafts === true));
517
+ output = yield* runHandler(tool.handler, input, handlerCtx, shown);
393
518
  checks.record();
394
519
  }
395
520
  catch (err) {
521
+ if (agent) {
522
+ // why: Anything but a settled failure is the host's to fix, as a compactor's is.
523
+ if (err instanceof AgentCallFailed)
524
+ return yield* fail(err.failure);
525
+ throw err;
526
+ }
396
527
  if (signedIn.prepared && err instanceof CredentialRefusedError) {
397
528
  checks.record();
398
- const refused = yield* refusedCredentialOutcome(tool, err.refusal, signedIn.prepared.authHeaders, ctx, base);
529
+ const refused = yield* refusedCredentialOutcome(tool, err.refusal, signedIn.secret !== undefined, ctx, base);
399
530
  if (refused)
400
531
  return yield* settleOutcome(refused);
401
532
  }
@@ -404,7 +535,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
404
535
  checks.record(blocked);
405
536
  return yield* fail(yield* networkBlocked(err, blocked));
406
537
  }
407
- return yield* fail({ code: 'handler_error', kind: 'failed', message: messageOf(err) });
538
+ return yield* fail(functionHandlerFailure(err));
408
539
  }
409
540
  if (secret)
410
541
  output = omitSecret(output, secret);
@@ -412,7 +543,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
412
543
  return yield* fail({
413
544
  code: 'invalid_output',
414
545
  kind: 'bad_response',
415
- message: lexiconText('tool.handler_no_output', {}, ctx.profile.lexicon),
546
+ message: labelText('tool.handler_no_output', {}, ctx.profile.labels),
416
547
  });
417
548
  }
418
549
  const checked = tool.output.safeParse(output);
@@ -420,7 +551,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
420
551
  return yield* fail({
421
552
  code: 'invalid_output',
422
553
  kind: 'bad_response',
423
- message: lexiconText('tool.output_invalid', {}, ctx.profile.lexicon),
554
+ message: labelText('tool.output_invalid', {}, ctx.profile.labels),
424
555
  details: checked.error.flatten(),
425
556
  });
426
557
  }
@@ -428,7 +559,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
428
559
  if (!promoted.ok) {
429
560
  return yield* fail(promoted.failure);
430
561
  }
431
- // The T2 loader's output drives the snapshot, so the host may not mutate it.
562
+ // why: The T2 loader's output drives the snapshot, so the host may not mutate it.
432
563
  const ownsOutput = loadsT2(tool, ctx);
433
564
  return yield* settleToolCall({
434
565
  base,
@@ -439,25 +570,24 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
439
570
  guard,
440
571
  provisional: {
441
572
  outputRaw: promoted.output,
442
- modelResult: projectForModel(tool, promoted.output, ctx.profile.lexicon),
573
+ modelResult: projectForModel(tool, promoted.output, ctx.profile.labels),
443
574
  },
444
575
  sources: tool.sources,
445
576
  labels: tool.labels,
446
577
  ...(ownsOutput
447
578
  ? {}
448
579
  : {
449
- reproject: makeReproject((v) => tool.output.safeParse(v), (data) => projectForModel(tool, data, ctx.profile.lexicon), ctx.profile.lexicon),
580
+ reproject: makeReproject((v) => tool.output.safeParse(v), (data) => projectForModel(tool, data, ctx.profile.labels), ctx.profile.labels),
450
581
  }),
451
582
  });
452
583
  }
453
- export function notLoadedMessage(tool, lexicon) {
454
- if (tool.loadTier === 'T1') {
455
- return lexiconText('tool.not_wired_t1', { tool: tool.name }, lexicon);
456
- }
457
- if (tool.loadTier === 'T2') {
458
- return lexiconText('tool.not_loaded_t2', { tool: tool.name }, lexicon);
584
+ /** Names the profile's loader when it can load the tool, so the model knows which call comes first. */
585
+ export function notLoadedMessage(tool, profile) {
586
+ const loader = profileToolsSpec(profile)?.t2Loader;
587
+ if (tool.loadTier === 'T2' && loader) {
588
+ return labelText('tool.not_loaded_t2', { tool: tool.name, loader }, profile.labels);
459
589
  }
460
- return lexiconText('tool.not_visible', { tool: tool.name }, lexicon);
590
+ return labelText('tool.not_visible', { tool: tool.name }, profile.labels);
461
591
  }
462
592
  function earlyFailure(failure) {
463
593
  return { failure, callNotStarted: true, modelResult: formatToolFailureForModel(failure) };
@@ -469,7 +599,7 @@ export async function* executeBuiltin(tool, ctx, base, snapshot) {
469
599
  const failure = {
470
600
  code: 'not_loaded',
471
601
  kind: 'request',
472
- message: lexiconText('tool.builtin_not_enabled', { tool: tool.name }, ctx.profile.lexicon),
602
+ message: labelText('tool.builtin_not_enabled', { tool: tool.name }, ctx.profile.labels),
473
603
  };
474
604
  yield failureEvent(base, failure);
475
605
  return earlyFailure(failure);
@@ -477,7 +607,7 @@ export async function* executeBuiltin(tool, ctx, base, snapshot) {
477
607
  const failure = {
478
608
  code: 'provider_native',
479
609
  kind: 'request',
480
- message: lexiconText('tool.provider_native', { tool: tool.name }, ctx.profile.lexicon),
610
+ message: labelText('tool.provider_native', { tool: tool.name }, ctx.profile.labels),
481
611
  };
482
612
  yield failureEvent(base, failure);
483
613
  return earlyFailure(failure);
@@ -488,7 +618,7 @@ function registeredEligibilityFailure(args) {
488
618
  return {
489
619
  code: 'not_allowed',
490
620
  kind: 'blocked',
491
- message: lexiconText('tool.not_allowed', { tool: name, profile: profile.id }, profile.lexicon),
621
+ message: labelText('tool.not_allowed', { tool: name, profile: profile.id }, profile.labels),
492
622
  };
493
623
  }
494
624
  if (!snapshot)
@@ -498,24 +628,46 @@ function registeredEligibilityFailure(args) {
498
628
  return {
499
629
  code: 'not_gated',
500
630
  kind: 'request',
501
- message: lexiconText('tool.not_eligible', { tool: name }, profile.lexicon),
631
+ message: labelText('tool.not_eligible', { tool: name }, profile.labels),
502
632
  };
503
633
  }
504
- if (!snapshot.visible.includes(name)) {
634
+ if (!(args.visible ?? snapshot.visible).includes(name)) {
505
635
  const skipLoadCheck = continuing && tool.loadTier === 'T0';
506
636
  if (!skipLoadCheck) {
507
637
  return {
508
638
  code: 'not_loaded',
509
639
  kind: 'request',
510
- message: notLoadedMessage(tool, profile.lexicon),
640
+ message: notLoadedMessage(tool, profile),
511
641
  };
512
642
  }
513
643
  }
514
644
  return undefined;
515
645
  }
646
+ export function authorizeToolReplay(args) {
647
+ const tool = args.tools.get(args.name);
648
+ if (!tool || tool.type === 'builtin') {
649
+ throw new TheoremError('blocked', labelText('error.blocked'));
650
+ }
651
+ const failure = registeredEligibilityFailure({ ...args, tool });
652
+ if (failure)
653
+ throw new TheoremError(failure.kind, failure.message);
654
+ if (args.outcome)
655
+ authorizeSavedDisclosure(args, tool, args.outcome);
656
+ }
657
+ function authorizeSavedDisclosure(args, tool, outcome) {
658
+ const blocked = () => new TheoremError('blocked', labelText('detect.output_blocked', {}, args.profile.labels));
659
+ const result = outcome.replay.modelResult;
660
+ if (tool.type === 'function' &&
661
+ tool.exposeToModel === false &&
662
+ result?.finding !== labelText('tool.completed_hidden', {}, args.profile.labels))
663
+ throw blocked();
664
+ const guard = guardToolResult(outcome.event.tool.readBack ?? '', { event: outcome.event, output: outcome.replay.outputRaw }, provenanceFor(tool, args.tools), resolveGuardrailPolicy(args.profile.guardrails), tool.type === 'builtin' ? undefined : toolBoundary('tool_output', tool.type), args.snapshot?.executable ?? [], args.profile.labels);
665
+ if (guard.event?.action === 'block' || guard.event?.action === 'redact')
666
+ throw blocked();
667
+ }
516
668
  /** Settles an outcome the kernel reached without a handler's own result: a remote body, or a sign-in. */
517
669
  async function* settleBodyOutcome(args) {
518
- const { outcome, tool, base, callId, safeInput, stages, guard, lexicon } = args;
670
+ const { outcome, tool, base, callId, safeInput, stages, guard, labels } = args;
519
671
  const name = tool.name;
520
672
  if (outcome.kind === 'gated') {
521
673
  if (outcome.gate.kind === 'confirmation') {
@@ -526,7 +678,7 @@ async function* settleBodyOutcome(args) {
526
678
  gate: outcome.gate,
527
679
  callId,
528
680
  toolName: name,
529
- lexicon,
681
+ labels,
530
682
  });
531
683
  return { gated: outcome.gate, callNotStarted: true, ...(gateReadBack ? { gateReadBack } : {}) };
532
684
  }
@@ -553,8 +705,8 @@ async function* settleBodyOutcome(args) {
553
705
  sources: tool.sources,
554
706
  labels: tool.labels,
555
707
  reproject: makeReproject((v) => parseToolOutput(tool.output, v),
556
- // A hook's edit replaces the value; the media the tool returned stays.
557
- (data) => withMedia(modelResultFromOutput(data), outcome.modelResult.parts), lexicon),
708
+ // why: A hook's edit replaces the value; the media the tool returned stays.
709
+ (data) => withMedia(modelResultFromOutput(data), outcome.modelResult.parts), labels),
558
710
  });
559
711
  }
560
712
  function turnReadBack({ modelResult }) {
@@ -562,9 +714,9 @@ function turnReadBack({ modelResult }) {
562
714
  ? { text: formatToolResult(modelResult), parts: modelResult.parts }
563
715
  : undefined;
564
716
  }
565
- /** The service a refused sign-in names, from the tool's own auth config. */
566
- function refusedSignInService(tool, resume) {
567
- if (!resume?.signIn || tool.type === 'builtin')
717
+ /** The service a sign-in gate's answer names, from the tool's own auth config. */
718
+ function signInService(tool, resume) {
719
+ if (!resume?.signIn || tool.type === 'builtin' || tool.type === 'agent')
568
720
  return undefined;
569
721
  return tool.auth?.service;
570
722
  }
@@ -572,34 +724,34 @@ function refusedSignInService(tool, resume) {
572
724
  * A gate nobody answered: a sign-in for `expiredService` whose link expired, or any other gate
573
725
  * left behind. Both settle as `cancelled`.
574
726
  */
575
- export function lapsedGateFailure(toolName, expiredService, lexicon) {
727
+ export function lapsedGateFailure(toolName, expiredService, labels) {
576
728
  if (expiredService) {
577
729
  return {
578
730
  code: 'expired',
579
731
  kind: 'cancelled',
580
- message: lexiconText('sign_in.expired', { service: expiredService }, lexicon),
732
+ message: labelText('sign_in.expired', { service: expiredService }, labels),
581
733
  };
582
734
  }
583
735
  return {
584
736
  code: 'cancelled',
585
737
  kind: 'cancelled',
586
- message: lexiconText('session.abandon_gated', { tool: toolName }, lexicon),
738
+ message: labelText('session.abandon_gated', { tool: toolName }, labels),
587
739
  };
588
740
  }
589
741
  /** `abandoned` and `expired` settle as `cancelled`. */
590
- function refusalFailure(tool, resume, lexicon) {
591
- const service = refusedSignInService(tool, resume);
742
+ function refusalFailure(tool, resume, labels) {
743
+ const service = signInService(tool, resume);
592
744
  const cause = resume?.cause ?? 'declined';
593
745
  if (cause === 'declined') {
594
746
  return {
595
747
  code: 'denied',
596
748
  kind: 'declined',
597
749
  message: service
598
- ? lexiconText('sign_in.declined', { service }, lexicon)
599
- : lexiconText('session.tool_denied', { tool: tool.name }, lexicon),
750
+ ? labelText('sign_in.declined', { service }, labels)
751
+ : labelText('session.tool_denied', { tool: tool.name }, labels),
600
752
  };
601
753
  }
602
- return lapsedGateFailure(tool.name, cause === 'expired' ? service : undefined, lexicon);
754
+ return lapsedGateFailure(tool.name, cause === 'expired' ? service : undefined, labels);
603
755
  }
604
756
  function resumeApproval(resume) {
605
757
  if (isGateResumeGranted(resume))
@@ -629,7 +781,53 @@ function toolCallEnd(settlement, readBack) {
629
781
  ...(failure ? { failure } : {}),
630
782
  };
631
783
  }
784
+ /** Runs one registered tool call as a stream of turn events and returns how it settled; when `openSpan` is given the call is recorded as a tool span that ends with the outcome. */
785
+ /**
786
+ * A call's arguments as its tool gets them, which is what the call's first
787
+ * event shows the host: a detector's placeholder where it redacts, and none
788
+ * when the call is stopped. A call no tool takes is read as a function tool's.
789
+ */
790
+ export function shownToolArguments(call) {
791
+ const tool = call.tools.get(call.name);
792
+ const policy = resolveGuardrailPolicy(call.profile.guardrails);
793
+ const inspected = inspectToolArguments(plainToolInput(call.input), tool ? provenanceFor(tool, call.tools) : { origin: 'local', tool: call.name, depth: 1 }, policy, toolArgumentsBoundary(call.tools, call.name), scopeOf(policy, call.scope ?? {}));
794
+ const { args } = inspected;
795
+ return args !== null && typeof args === 'object' && !Array.isArray(args)
796
+ ? args
797
+ : {};
798
+ }
632
799
  export async function* executeRegisteredTool(args) {
800
+ args = {
801
+ ...args,
802
+ ctx: { ...args.ctx, operationId: args.ctx.operationId ?? crypto.randomUUID() },
803
+ };
804
+ return yield* coordinateTool(args.execution, {
805
+ operationId: args.ctx.operationId ?? crypto.randomUUID(),
806
+ callId: args.callId,
807
+ profileId: args.profile.id,
808
+ toolId: args.name,
809
+ }, {
810
+ input: args.input,
811
+ resume: args.ctx.resume,
812
+ snapshot: args.snapshot,
813
+ context: args.invocation,
814
+ }, args.ctx.signal, (beginBody) => executeTracedTool({
815
+ ...args,
816
+ beginBody: async (input) => {
817
+ const claim = (await beginBody?.(input)) ?? (await args.beginBody?.(input));
818
+ args.onDispatch?.();
819
+ return claim;
820
+ },
821
+ }), (outcome) => authorizeToolReplay({
822
+ outcome,
823
+ tools: args.tools,
824
+ profile: args.profile,
825
+ name: args.name,
826
+ resume: args.ctx.resume,
827
+ snapshot: args.snapshot,
828
+ }));
829
+ }
830
+ async function* executeTracedTool(args) {
633
831
  const tool = args.tools.get(args.name);
634
832
  if (!args.openSpan) {
635
833
  return yield* runRegisteredTool(args, tool);
@@ -638,7 +836,7 @@ export async function* executeRegisteredTool(args) {
638
836
  name: args.name,
639
837
  callId: args.callId,
640
838
  call: { arguments: toolCallArguments(plainToolInput(args.input)) },
641
- origin: tool ? originOfTool(tool.type) : undefined,
839
+ origin: tool ? originOfTool(tool, args.tools) : undefined,
642
840
  permission: tool && 'permission' in tool ? tool.permission : undefined,
643
841
  approved: resumeApproval(args.ctx.resume),
644
842
  step: args.ctx.turn?.step,
@@ -664,7 +862,7 @@ export async function* executeRegisteredTool(args) {
664
862
  throw err;
665
863
  }
666
864
  finally {
667
- // The host stopped reading mid-call.
865
+ // why: The host stopped reading mid-call.
668
866
  if (!trace.span.ended) {
669
867
  trace.end({ outcome: 'cancelled' });
670
868
  await exec.return({});
@@ -674,12 +872,18 @@ export async function* executeRegisteredTool(args) {
674
872
  async function* runRegisteredTool(args, tool) {
675
873
  const { profile, name, input, callId, ctx, snapshot, stages } = args;
676
874
  const safeInput = plainToolInput(input);
677
- const base = { name, callId };
875
+ const operationId = ctx.operationId ?? crypto.randomUUID();
876
+ const base = {
877
+ name,
878
+ callId,
879
+ operationId,
880
+ activityFailed: failedActivity(name, profile.labels, tool?.labels, safeInput),
881
+ };
678
882
  if (!tool) {
679
883
  const failure = {
680
884
  code: 'unknown_tool',
681
885
  kind: 'request',
682
- message: lexiconText('tool.not_registered', { tool: name }, profile.lexicon),
886
+ message: labelText('tool.not_registered', { tool: name }, profile.labels),
683
887
  };
684
888
  yield failureEvent(base, failure);
685
889
  return earlyFailure(failure);
@@ -689,12 +893,12 @@ async function* runRegisteredTool(args, tool) {
689
893
  const failure = {
690
894
  code: 'provider_native',
691
895
  kind: 'request',
692
- message: lexiconText('tool.builtin_needs_snapshot', { tool: name }, profile.lexicon),
896
+ message: labelText('tool.builtin_needs_snapshot', { tool: name }, profile.labels),
693
897
  };
694
898
  yield failureEvent(base, failure);
695
899
  return earlyFailure(failure);
696
900
  }
697
- const fullCtx = { ...ctx, callId, profile };
901
+ const fullCtx = { ...ctx, callId, profile, operationId };
698
902
  return yield* executeBuiltin(tool, fullCtx, base, snapshot);
699
903
  }
700
904
  const eligibility = registeredEligibilityFailure({
@@ -703,25 +907,36 @@ async function* runRegisteredTool(args, tool) {
703
907
  name,
704
908
  resume: ctx.resume,
705
909
  snapshot,
910
+ visible: ctx.turn?.visible,
706
911
  });
707
912
  if (eligibility) {
708
913
  yield failureEvent(base, eligibility);
709
914
  return earlyFailure(eligibility);
710
915
  }
711
916
  if (isGateResumeDenied(ctx.resume)) {
712
- return yield* settleToolFailure(resultGuard(tool, { ...ctx, callId, profile }, snapshot, stages?.span), base, refusalFailure(tool, ctx.resume, profile.lexicon), stages, { toolName: name, callId, input: safeInput, callNotStarted: true, denied: true });
917
+ return yield* settleToolFailure(resultGuard(args.tools, tool, { ...ctx, callId, profile, operationId }, snapshot, stages?.span), base, refusalFailure(tool, ctx.resume, profile.labels), stages, { toolName: name, callId, input: safeInput, callNotStarted: true, denied: true });
713
918
  }
714
- const fullCtx = { ...ctx, callId, profile };
919
+ const fullCtx = { ...ctx, callId, profile, operationId };
715
920
  const policy = resolveGuardrailPolicy(profile.guardrails);
716
- const provenance = provenanceFor(tool);
921
+ const provenance = provenanceFor(tool, args.tools);
717
922
  const argsStart = performance.now();
718
- const argEvent = toolCallEvent(inspectToolArguments(safeInput, policy), provenance);
719
- recordToolCheck(stages?.span, 'tool_arguments', performance.now() - argsStart, argEvent);
720
- if (argEvent) {
721
- yield { type: 'guardrail', guardrail: argEvent };
923
+ const kind = toolKindOf(tool);
924
+ const inspected = inspectToolArguments(safeInput, provenance, policy, kind && toolBoundary('tool_arguments', kind), scopeOf(policy, args.scope ?? {}));
925
+ recordToolCheck(stages?.span, 'tool_arguments', performance.now() - argsStart, inspected.event);
926
+ if (inspected.event) {
927
+ yield { type: 'guardrail', guardrail: inspected.event };
928
+ }
929
+ if (!('args' in inspected)) {
930
+ const failure = {
931
+ code: 'arguments_blocked',
932
+ kind: 'blocked',
933
+ message: labelText('detect.call_blocked', {}, profile.labels),
934
+ };
935
+ yield failureEvent(base, failure);
936
+ return { ...earlyFailure(failure), denied: true };
722
937
  }
723
938
  const taintStart = performance.now();
724
- const taintVerdict = checkTaintGate(ctx.turn?.taint, tool.access, policy, profile.lexicon);
939
+ const taintVerdict = checkTaintGate(ctx.turn?.taint, tool.access, policy, profile.labels);
725
940
  const taintEvent = toolCallEvent(taintVerdict, provenance);
726
941
  recordToolCheck(stages?.span, 'taint', performance.now() - taintStart, taintEvent);
727
942
  if (taintEvent) {
@@ -736,23 +951,155 @@ async function* runRegisteredTool(args, tool) {
736
951
  yield failureEvent(base, failure);
737
952
  return { ...earlyFailure(failure), denied: true };
738
953
  }
739
- return yield* settleByType(args.tools, tool, safeInput, fullCtx, base, snapshot, stages);
954
+ const stopped = yield* settleRemoteDestination({
955
+ tool,
956
+ input: inspected.args,
957
+ ctx: fullCtx,
958
+ base,
959
+ provenance,
960
+ policy,
961
+ span: stages?.span,
962
+ });
963
+ if (stopped)
964
+ return stopped;
965
+ return yield* settleByType(args.tools, tool, inspected.args, fullCtx, base, snapshot, stages, args.agents, args.beginBody);
966
+ }
967
+ /** The call's settlement when a destination in its arguments stops it: refused, or held for the user's answer. */
968
+ async function* settleRemoteDestination(args) {
969
+ const { tool, input, ctx, base } = args;
970
+ const { labels } = ctx.profile;
971
+ const start = performance.now();
972
+ const { verdict, confirm } = checkDestinationGate(ctx.turn?.destinations, input, args.policy, labels);
973
+ const event = toolCallEvent(verdict, args.provenance);
974
+ recordToolCheck(args.span, 'destination', performance.now() - start, event);
975
+ if (event) {
976
+ yield { type: 'guardrail', guardrail: event };
977
+ }
978
+ if (verdict.action === 'block') {
979
+ const failure = {
980
+ code: 'remote_destination',
981
+ kind: 'blocked',
982
+ message: verdict.rejection,
983
+ };
984
+ yield failureEvent(base, failure);
985
+ return { ...earlyFailure(failure), denied: true };
986
+ }
987
+ if (!confirm || isGateResumeGranted(ctx.resume))
988
+ return undefined;
989
+ const gate = {
990
+ kind: 'confirmation',
991
+ tool: tool.name,
992
+ summary: confirm,
993
+ ...gateDetails(tool, input),
994
+ };
995
+ yield* emitGateSettlement({
996
+ base,
997
+ gate,
998
+ callId: ctx.callId,
999
+ toolName: tool.name,
1000
+ labels,
1001
+ });
1002
+ return { gated: gate, callNotStarted: true };
1003
+ }
1004
+ /**
1005
+ * An agent tool runs as a function tool whose handler is the called agent's
1006
+ * turn, so input checks, gates, stages, and the result guard are the same. The
1007
+ * agent's reply streams as the call's drafts and its other events as its
1008
+ * `progress`, and its usage rides on the call's last phase.
1009
+ */
1010
+ async function* executeAgentTool(args) {
1011
+ const { tool, ctx, base, agents } = args;
1012
+ if (!agents) {
1013
+ const failure = {
1014
+ code: 'unknown_tool',
1015
+ kind: 'unsupported',
1016
+ message: labelText('tool.unsupported_type', { tool: tool.name }, ctx.profile.labels),
1017
+ };
1018
+ yield failureEvent(base, failure);
1019
+ return earlyFailure(failure);
1020
+ }
1021
+ let tokens;
1022
+ const span = args.stages?.span;
1023
+ const handler = async function* (input, handlerCtx) {
1024
+ const run = agents.run({
1025
+ tool,
1026
+ callId: handlerCtx.callId,
1027
+ // why: Checked against the tool's input schema before the handler runs.
1028
+ input: input,
1029
+ caller: handlerCtx.profile,
1030
+ ...(span ? { span } : {}),
1031
+ ...(handlerCtx.signal ? { signal: handlerCtx.signal } : {}),
1032
+ });
1033
+ // why: A retry throws away the reply drafted so far; the drafts stop there, and the output arrives whole.
1034
+ let retried = false;
1035
+ for (;;) {
1036
+ const next = await run.next();
1037
+ if (next.done) {
1038
+ tokens = next.value.tokens;
1039
+ if ('failure' in next.value)
1040
+ throw new AgentCallFailed(next.value.failure);
1041
+ yield { kind: 'complete', output: next.value.output };
1042
+ return;
1043
+ }
1044
+ const event = next.value;
1045
+ if (event.type === 'attempt')
1046
+ retried = true;
1047
+ if (event.type === 'text' || event.type === 'structured_draft') {
1048
+ if (!retried)
1049
+ yield { kind: 'draft', text: event.text };
1050
+ continue;
1051
+ }
1052
+ yield { kind: 'progress', data: { agent: tool.profile, event } };
1053
+ }
1054
+ };
1055
+ // why: Its hooks take `AgentToolInput`, which the input schema has already checked.
1056
+ const asFunction = { ...tool, type: 'function', handler };
1057
+ const exec = executeFunction(args.tools, asFunction, args.safeInput, ctx, base, args.snapshot, args.stages, tool, args.beginBody);
1058
+ for (;;) {
1059
+ const next = await exec.next();
1060
+ if (next.done)
1061
+ return next.value;
1062
+ yield withAgentTokens(next.value, base.callId, tokens);
1063
+ }
1064
+ }
1065
+ /** The called agent's usage on the call's `complete` or `error` phase. */
1066
+ function withAgentTokens(event, callId, tokens) {
1067
+ if (!tokens || event.type !== 'tool' || event.tool.callId !== callId)
1068
+ return event;
1069
+ const { tool } = event;
1070
+ if (tool.phase !== 'complete' && tool.phase !== 'error')
1071
+ return event;
1072
+ return { ...event, tool: { ...tool, tokens } };
740
1073
  }
741
- async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, stages) {
1074
+ async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, stages, agents, beginBody) {
742
1075
  const { name } = tool;
743
1076
  if (tool.type === 'function') {
744
- return yield* executeFunction(tools, tool, safeInput, fullCtx, base, snapshot, stages);
1077
+ return yield* executeFunction(tools, tool, safeInput, fullCtx, base, snapshot, stages, undefined, beginBody);
1078
+ }
1079
+ if (tool.type === 'agent') {
1080
+ return yield* executeAgentTool({
1081
+ tools,
1082
+ tool,
1083
+ safeInput,
1084
+ ctx: fullCtx,
1085
+ base,
1086
+ snapshot,
1087
+ stages,
1088
+ agents,
1089
+ beginBody,
1090
+ });
745
1091
  }
746
1092
  if (tool.type !== 'http' && tool.type !== 'mcp') {
747
1093
  return earlyFailure({
748
1094
  code: 'unknown_tool',
749
1095
  kind: 'request',
750
- message: lexiconText('tool.unsupported_type', { tool: name }, fullCtx.profile.lexicon),
1096
+ message: labelText('tool.unsupported_type', { tool: name }, fullCtx.profile.labels),
751
1097
  });
752
1098
  }
1099
+ const guard = resultGuard(tools, tool, fullCtx, snapshot, stages?.span);
753
1100
  const remoteOutcome = tool.type === 'http'
754
- ? yield* executeHttpTool(tool, safeInput, fullCtx, base, stages)
755
- : yield* executeMcpTool(tool, safeInput, fullCtx, base, stages, tools.mcpSessions);
1101
+ ? yield* executeHttpTool(tool, safeInput, fullCtx, base, stages, beginBody, new HandlerEvents(base, guard.handlerEvents(stages?.drafts === true)))
1102
+ : yield* executeMcpTool(tool, safeInput, fullCtx, base, stages, tools.mcpSessions, beginBody);
756
1103
  return yield* settleBodyOutcome({
757
1104
  outcome: remoteOutcome,
758
1105
  tool,
@@ -760,37 +1107,62 @@ async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, st
760
1107
  callId: base.callId,
761
1108
  safeInput,
762
1109
  stages,
763
- guard: resultGuard(tool, fullCtx, snapshot, stages?.span),
764
- lexicon: fullCtx.profile.lexicon,
1110
+ guard,
1111
+ labels: fullCtx.profile.labels,
765
1112
  });
766
1113
  }
767
1114
  /**
768
- * A failure's message is redacted under full detection, whatever the profile
769
- * enables: the kernel frames it for the model as a system report, and a remote
770
- * server writes its own error strings. What it changed is a decision like any
771
- * other, reported and timed; the framed message is then guarded as a result.
1115
+ * A remote server writes its own error strings, so a failure's message is read
1116
+ * at `tool_failure_<kind>` before the kernel frames it for the model as a system
1117
+ * report. A blocked message is replaced by the labels' words. The framed
1118
+ * report is the kernel's own text and is not read again.
772
1119
  */
773
1120
  function* guardFailure(failure, guard) {
774
1121
  const start = performance.now();
775
- const checked = guardToolFailureText(failure.message, guard.provenance, {
776
- ...guard.policy,
777
- sanitizeInput: true,
778
- redactSensitive: resolveSensitive(true),
779
- });
1122
+ const checked = guardToolFailureText(failure.message, guard.provenance, guard.policy, guard.kind && toolBoundary('tool_failure', guard.kind));
780
1123
  recordToolCheck(guard.span, 'tool_failure', performance.now() - start, checked.event);
781
1124
  if (checked.event) {
782
1125
  yield { type: 'guardrail', guardrail: checked.event };
783
1126
  }
784
- return yield* guardResult(formatToolFailureForModel({ ...failure, message: checked.text }), guard);
1127
+ const message = checked.text ?? labelText('detect.output_blocked', {}, guard.labels);
1128
+ return { modelResult: yield* reportFailure({ ...failure, message }, guard) };
785
1129
  }
1130
+ /** A failure framed for the model in the kernel's own words, fenced and labelled like any result. */
1131
+ function* reportFailure(failure, guard) {
1132
+ const framed = frameToolFailure(failure);
1133
+ return (yield* readBack(framed, guard, undefined)) ?? framed;
1134
+ }
1135
+ /** A result read at `tool_output_<kind>`. A blocked one settles as a failed call the model is told about. */
786
1136
  function* guardResult(result, guard) {
1137
+ const read = yield* readBack(result, guard, guard.kind && toolBoundary('tool_output', guard.kind));
1138
+ if (read)
1139
+ return { modelResult: read };
1140
+ const withheld = {
1141
+ code: 'output_blocked',
1142
+ kind: 'blocked',
1143
+ message: labelText('detect.output_blocked', {}, guard.labels),
1144
+ };
1145
+ return { modelResult: yield* reportFailure(withheld, guard), withheld };
1146
+ }
1147
+ /** What the person is shown of `value`, read at `tool_shown_<kind>`; a blocked one is the labels' words. */
1148
+ function* showValue(value, guard) {
1149
+ const boundary = guard.kind && toolBoundary('tool_shown', guard.kind);
1150
+ const shown = guardShownValue(value, guard.provenance, guard.policy, boundary);
1151
+ if (shown.event)
1152
+ yield { type: 'guardrail', guardrail: shown.event };
1153
+ return 'value' in shown ? shown.value : labelText('detect.shown_blocked', {}, guard.labels);
1154
+ }
1155
+ /** What the model reads of `result`, or `undefined` when a match at `boundary` blocks it. */
1156
+ function* readBack(result, guard, boundary) {
787
1157
  const { provenance, span } = guard;
788
1158
  const start = performance.now();
789
- const guarded = guardToolResult(result.finding, result.data, provenance, guard.policy, guard.callableTools, guard.lexicon);
1159
+ const guarded = guardToolResult(result.finding, result.data, provenance, guard.policy, boundary, guard.callableTools, guard.labels);
790
1160
  recordToolCheck(span, 'tool_result', performance.now() - start, guarded.event);
791
1161
  if (guarded.event) {
792
1162
  yield { type: 'guardrail', guardrail: guarded.event };
793
1163
  }
1164
+ if (guarded.text === undefined)
1165
+ return undefined;
794
1166
  return {
795
1167
  ...result,
796
1168
  modelText: guarded.text,