@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,14 +1,16 @@
1
- import { lexiconText } from './lexicon.js';
2
- import { detectionForTrust } from './policy.js';
3
- import { TOOL_RULES } from './rules.js';
4
- import { sanitizeText } from './sanitize.js';
5
- import { anySensitive } from './sensitive.js';
1
+ import { mapStrings } from '../kernel/engine/tree.js';
2
+ import { detectAt, detectEvent, detectReads, } from './detect-at.js';
3
+ import { readValue } from './detect-reply.js';
4
+ import { labelText } from './labels.js';
5
+ import { DETECT_RULES, EGRESS_RULES, TOOL_RULES } from './rules.js';
6
6
  import { textForScan } from './serialize.js';
7
- import { advisoryLevel, directiveHits } from './tool-directives.js';
7
+ import { advisoryLevel } from './tool-directives.js';
8
+ /** The closing tag of the fence a tool result is wrapped in. */
8
9
  const TOOL_CLOSE = '</tool_data>';
9
10
  const TOOL_OPEN = '<tool_data';
10
11
  /** Origins whose bytes the host does not author and cannot vouch for. */
11
12
  const REMOTE_ORIGINS = new Set(['http', 'mcp', 'delegated']);
13
+ /** True when the tool's bytes come from outside the host. */
12
14
  function isRemoteOrigin(origin) {
13
15
  return REMOTE_ORIGINS.has(origin);
14
16
  }
@@ -55,24 +57,24 @@ function stripToolFences(text) {
55
57
  * The origin is on the tag rather than in prose so a result cannot claim a
56
58
  * friendlier provenance than it has by writing one into its own body.
57
59
  */
58
- function wrapToolData(text, provenance, advisory = 'none', lexicon) {
59
- const guidance = lexiconText('advisory.guidance', {}, lexicon).trim();
60
+ function wrapToolData(text, provenance, advisory = 'none', labels) {
61
+ const guidance = labelText('advisory.guidance', {}, labels).trim();
60
62
  const attrs = `tool="${provenance.tool}" origin="${provenance.origin}"` +
61
63
  (advisory === 'none' ? '' : ` advisory="${advisory}"`);
62
64
  const notice = advisory === 'none'
63
65
  ? ''
64
- : `${advisoryNotice(advisory, lexicon)}${guidance ? ` ${guidance}` : ''}\n`;
66
+ : `${advisoryNotice(advisory, labels)}${guidance ? ` ${guidance}` : ''}\n`;
65
67
  return `<${'tool_data'} ${attrs}>\n${notice}${stripToolFences(text)}\n${TOOL_CLOSE}`;
66
68
  }
67
69
  /**
68
70
  * Deliberately an observation, not an instruction: what the agent should do about
69
- * it is product behaviour, supplied by the host as lexicon `advisory.guidance`. Emitted
71
+ * it is product behaviour, supplied by the host as labels `advisory.guidance`. Emitted
70
72
  * only when signals fired, so it stays rare enough to carry weight — a warning on
71
73
  * every fetch is one the model learns to skip.
72
74
  */
73
- function advisoryNotice(advisory, lexicon) {
75
+ function advisoryNotice(advisory, labels) {
74
76
  const key = advisory === 'high' ? 'advisory.notice_high' : 'advisory.notice_elevated';
75
- return lexiconText(key, {}, lexicon);
77
+ return labelText(key, {}, labels);
76
78
  }
77
79
  /**
78
80
  * `finding` is the tool's summary and `data` its structured payload; both reach
@@ -88,88 +90,108 @@ function composeToolText(finding, data) {
88
90
  }
89
91
  return `${finding}\n${rendered.text}`;
90
92
  }
93
+ const NOTHING_FOUND = { action: 'allow', hits: [] };
94
+ /** `text` read at `boundary`, or passed as it is when the text crosses none. */
95
+ function readAt(text, boundary, detect, scope) {
96
+ return boundary ? detectAt(text, boundary, detect, scope) : { ...NOTHING_FOUND, text };
97
+ }
91
98
  /**
92
99
  * Local host tools are still detected — a host tool reading a database returns
93
100
  * data the host did not write — but only remote origins are fenced, because
94
101
  * fencing a local tool's output would change prompts hosts have already tuned.
102
+ * `boundary` is absent for text that crosses none: a provider builtin's, or a
103
+ * failure already read at its own boundary.
95
104
  */
96
- function guardToolResult(finding, data, provenance, policy, callableTools = [], lexicon) {
105
+ function guardToolResult(finding, data, provenance, policy, boundary, callableTools = [], labels) {
97
106
  const composed = composeToolText(finding, data);
98
- const options = detectionForTrust(policy, 'untrusted');
99
- const redacted = sanitizeText(composed, options);
100
- const changed = redacted !== composed;
101
- // Directive detection runs on remote content only: a local tool's output is
102
- // bytes the host's own code produced.
107
+ const detected = readAt(composed, boundary, policy.detect, { callable: callableTools });
108
+ const suspicious = detected.hits.filter(({ rule }) => rule === DETECT_RULES.tool_instructions);
103
109
  const remote = isRemoteOrigin(provenance.origin);
104
- const suspicious = remote ? directiveHits(composed, callableTools) : [];
105
- const advisory = advisoryLevel(suspicious);
106
- const fenced = remote ? wrapToolData(redacted, provenance, advisory, lexicon) : redacted;
107
- const hits = [
108
- ...(changed ? [{ rule: TOOL_RULES.resultRedacted, severity: 'medium' }] : []),
109
- ...suspicious,
110
- ];
111
- if (hits.length === 0) {
112
- return { text: fenced };
113
- }
114
- return {
115
- text: fenced,
116
- ...(suspicious.length > 0 ? { suspicious } : {}),
117
- event: {
110
+ const event = detected.action === 'allow'
111
+ ? undefined
112
+ : {
118
113
  stage: 'tool_result',
114
+ ...(boundary ? { boundary } : {}),
119
115
  trust: 'untrusted',
120
- // Redaction changed the text; directive signals only annotate it.
121
- action: changed ? 'redact' : 'flag',
122
- hits,
116
+ action: detected.action,
117
+ hits: detected.hits,
123
118
  provenance,
124
- },
119
+ };
120
+ const found = {
121
+ ...(suspicious.length > 0 ? { suspicious } : {}),
122
+ ...(event ? { event } : {}),
125
123
  };
124
+ if (detected.text === undefined)
125
+ return found;
126
+ const fenced = remote
127
+ ? wrapToolData(detected.text, provenance, advisoryLevel(suspicious.map(({ signal }) => signal)), labels)
128
+ : detected.text;
129
+ return { text: fenced, ...found };
126
130
  }
127
131
  /**
128
132
  * A remote server authors its own error strings, so an unguarded failure message
129
133
  * is the cleanest injection path across this boundary: it reaches the model
130
134
  * verbatim and is framed by the kernel as a system report.
131
135
  */
132
- function guardToolFailureText(message, provenance, policy) {
133
- const options = detectionForTrust(policy, 'untrusted');
134
- const redacted = sanitizeText(stripToolFences(message), options);
135
- if (redacted === message) {
136
- return { text: redacted };
137
- }
136
+ function guardToolFailureText(message, provenance, policy, boundary) {
137
+ const detected = readAt(stripToolFences(message), boundary, policy.detect);
138
+ const event = boundary ? detectEvent(boundary, detected, provenance) : undefined;
138
139
  return {
139
- text: redacted,
140
- event: {
141
- stage: 'tool_result',
142
- trust: 'untrusted',
143
- action: 'redact',
144
- hits: [{ rule: TOOL_RULES.failureRedacted, severity: 'medium' }],
145
- provenance,
146
- },
140
+ ...(detected.text === undefined ? {} : { text: detected.text }),
141
+ ...(event ? { event } : {}),
142
+ };
143
+ }
144
+ /**
145
+ * A call's output, error, artifacts, and trace reach the person on the turn's events, apart from
146
+ * what the model read back: the host's server forwards them to the browser as they are. Each is
147
+ * read here at `tool_shown_<kind>`, so a key a tool returned is not shown. `readBack` is
148
+ * untouched: what the model read is settled at `tool_output_<kind>`.
149
+ */
150
+ function guardShownValue(value, provenance, policy, boundary) {
151
+ if (!boundary || value === undefined)
152
+ return { value };
153
+ const found = readValue(value, boundary, policy.detect);
154
+ const event = detectEvent(boundary, found, provenance);
155
+ return {
156
+ ...(found.action === 'block' ? {} : { value: found.value }),
157
+ ...(event ? { event } : {}),
147
158
  };
148
159
  }
149
160
  /**
150
161
  * Arguments are model-authored, so the risk is not instruction smuggling but
151
162
  * exfiltration: a credential lifted from context and posted outward as a
152
- * parameter. Detection reports rather than rewrites — silently altering a tool
153
- * argument would make the call succeed against something the model did not ask
154
- * for.
163
+ * parameter. The whole call is read as it will be sent; `redact` then replaces
164
+ * the match inside each string it sits in, so the tool is called with the
165
+ * placeholder. `scope` is what the detectors of what is the profile's own
166
+ * read of the turn: the canary, and its system instruction.
155
167
  */
156
- function inspectToolArguments(args, policy) {
157
- if (!anySensitive(policy.redactSensitive)) {
158
- return { action: 'allow' };
168
+ function inspectToolArguments(args, provenance, policy, boundary, scope = {}) {
169
+ if (!(boundary && detectReads([boundary], policy.detect))) {
170
+ return { args };
159
171
  }
172
+ const stopped = (hits) => {
173
+ const event = detectEvent(boundary, { action: 'block', hits }, provenance);
174
+ return event ? { event } : {};
175
+ };
160
176
  const rendered = textForScan(args);
161
177
  if (rendered.unscannable) {
162
- return { action: 'allow' };
163
- }
164
- const options = { sanitizeInput: false, redactSensitive: policy.redactSensitive };
165
- if (sanitizeText(rendered.text, options) === rendered.text) {
166
- return { action: 'allow' };
178
+ // why: Cannot inspect it, so cannot vouch for it. Fail closed.
179
+ return stopped([{ rule: EGRESS_RULES.unscannable, severity: 'high' }]);
167
180
  }
168
- return {
169
- action: 'flag',
170
- hits: [{ rule: TOOL_RULES.sensitiveArgument, severity: 'high' }],
171
- };
181
+ const detected = detectAt(rendered.text, boundary, policy.detect, scope);
182
+ if (detected.action === 'block')
183
+ return stopped(detected.hits);
184
+ const event = detectEvent(boundary, detected, provenance);
185
+ if (detected.action !== 'redact')
186
+ return { args, ...(event ? { event } : {}) };
187
+ const safe = mapStrings(args, (text) => detectAt(text, boundary, policy.detect, scope).text ?? '');
188
+ const left = detectAt(textForScan(safe).text, boundary, policy.detect, scope).action;
189
+ // why: A match in a key, or one that runs across values, has no string to replace: the tool is not called.
190
+ if (left === 'redact' || left === 'block')
191
+ return stopped(detected.hits);
192
+ return { args: safe, ...(event ? { event } : {}) };
172
193
  }
194
+ /** The guardrail event for a tool call verdict, or `undefined` when it was allowed. */
173
195
  function toolCallEvent(verdict, provenance) {
174
196
  if (verdict.action === 'allow') {
175
197
  return undefined;
@@ -195,9 +217,11 @@ function recordTaint(taint, provenance, suspicious = []) {
195
217
  }
196
218
  return { sources: [...sources, provenance], suspicious: [...prior, ...suspicious] };
197
219
  }
220
+ /** True when the turn has read content from outside the host. */
198
221
  function isTainted(taint) {
199
222
  return (taint?.sources.length ?? 0) > 0;
200
223
  }
224
+ /** True when something the turn read looked like instructions. */
201
225
  function isSuspicious(taint) {
202
226
  return (taint?.suspicious.length ?? 0) > 0;
203
227
  }
@@ -217,7 +241,7 @@ const GATE_RANK = {
217
241
  * `block` says the profile asked for it to be refused. Reporting happens whether
218
242
  * or not enforcement is configured, so the risk is visible before a host opts in.
219
243
  */
220
- function checkTaintGate(taint, access, policy, lexicon) {
244
+ function checkTaintGate(taint, access, policy, labels) {
221
245
  if (!isTainted(taint)) {
222
246
  return { action: 'allow' };
223
247
  }
@@ -232,17 +256,17 @@ function checkTaintGate(taint, access, policy, lexicon) {
232
256
  severity: 'high',
233
257
  },
234
258
  ];
235
- // Gated on origin alone. Whether the content looked directive changes the rule
259
+ // why: Gated on origin alone. Whether the content looked directive changes the rule
236
260
  // reported, never whether the call is refused.
237
261
  if (rank < GATE_RANK[policy.taint?.afterRemoteRead ?? 'off']) {
238
262
  return { action: 'flag', hits };
239
263
  }
240
264
  const read = taint?.sources.map((s) => s.tool).join(', ') ?? '';
241
- const reason = lexiconText(suspicious ? 'taint.reason_steered' : 'taint.reason_tainted', {}, lexicon);
265
+ const reason = labelText(suspicious ? 'taint.reason_steered' : 'taint.reason_tainted', {}, labels);
242
266
  return {
243
267
  action: 'block',
244
268
  hits,
245
- rejection: lexiconText('taint.blocked', { access, sources: read, reason }, lexicon),
269
+ rejection: labelText('taint.blocked', { access, sources: read, reason }, labels),
246
270
  };
247
271
  }
248
- export { checkTaintGate, composeToolText, guardToolFailureText, guardToolResult, inspectToolArguments, isRemoteOrigin, isSuspicious, isTainted, recordTaint, TOOL_CLOSE, toolCallEvent, wrapToolData, };
272
+ export { checkTaintGate, composeToolText, guardShownValue, guardToolFailureText, guardToolResult, inspectToolArguments, isRemoteOrigin, isSuspicious, isTainted, recordTaint, TOOL_CLOSE, toolCallEvent, wrapToolData, };
@@ -1,25 +1,47 @@
1
- import type { EgressChecks } from './egress.js';
1
+ import type { DetectSpec, ResolvedAllow, ResolvedDetect } from './detectors.js';
2
2
  import type { GivenUrls } from './egress-urls.js';
3
3
  import type { GuardrailEvent, GuardrailHit, Provenance } from './event-schemas.js';
4
- import type { LexiconOverrides } from './lexicon.js';
5
- import type { SensitiveGroups, SensitiveSelection } from './sensitive.js';
4
+ import type { LabelOverrides } from './labels.js';
5
+ import type { OwnTools } from './tool-leak.js';
6
6
  export type { GuardrailEvent, GuardrailHit, Provenance };
7
7
  /**
8
- * - `trusted` — author-time profile text (`identity.system`). Sensitive redaction
9
- * only; injection redaction would mangle the host's own instructions.
8
+ * - `trusted` — author-time profile text (`identity.system`). Left verbatim: no
9
+ * injection or sensitive redaction, which would mangle the host's own instructions.
10
10
  * - `assembled` — host-built per turn (`req.system`). Interpolates retrieval and
11
11
  * user data, so it is permeable and takes full detection.
12
12
  * - `untrusted` — user input, tool results, attachments, delegated agents.
13
13
  */
14
14
  export declare const TRUST_LEVELS: readonly ["trusted", "assembled", "untrusted"];
15
+ /** One of {@linkcode TRUST_LEVELS}. */
15
16
  export type TrustLevel = (typeof TRUST_LEVELS)[number];
17
+ /** The points a guardrail can run: input, history, system, attachments, tool calls, and results, output, thoughts, network, live audio, and traces. */
16
18
  export declare const GUARDRAIL_STAGES: readonly ["input", "history", "system", "attachment", "tool_call", "tool_result", "output_delta", "output_final", "thought", "network", "live_inbound", "live_outbound", "trace"];
19
+ /** One of {@linkcode GUARDRAIL_STAGES}. */
17
20
  export type GuardrailStage = (typeof GUARDRAIL_STAGES)[number];
18
- /** Does not decide what happens next; that is `onBlock`. */
21
+ /** Does not decide what happens next; that is `blockedReply`. */
19
22
  export declare const SEVERITIES: readonly ["info", "low", "medium", "high"];
23
+ /** One of {@linkcode SEVERITIES}. */
20
24
  export type Severity = (typeof SEVERITIES)[number];
21
- export declare const EGRESS_ON_BLOCK: readonly ["reject_to_agent", "refuse_to_user"];
22
- export type EgressOnBlock = (typeof EGRESS_ON_BLOCK)[number];
25
+ /** What follows a blocked reply: the model rewrites it, or the user reads a refusal. */
26
+ export declare const BLOCKED_REPLY_ON_BLOCK: readonly ["retry", "refuse"];
27
+ /** One of {@linkcode BLOCKED_REPLY_ON_BLOCK}. */
28
+ export type BlockedReplyOnBlock = (typeof BLOCKED_REPLY_ON_BLOCK)[number];
29
+ /** What happens once a detector blocks a reply. */
30
+ export interface BlockedReplySpec {
31
+ /**
32
+ * `retry` (the default) tells the model what blocked the reply and has it write another;
33
+ * `refuse` sends the user the labels' `egress.refusal` in its place, or ends the part
34
+ * they already have with `egress.refusal_cut`.
35
+ */
36
+ onBlock?: BlockedReplyOnBlock;
37
+ /**
38
+ * Under `retry`, how many times the model may rewrite a blocked reply (default 1). Once they
39
+ * are spent the reply is withheld and the turn ends in a `safety` error.
40
+ */
41
+ maxRetries?: number;
42
+ }
43
+ /** {@linkcode BlockedReplySpec} with its defaults applied. */
44
+ export type ResolvedBlockedReply = Required<BlockedReplySpec>;
23
45
  /**
24
46
  * A discriminated union so a new variant fails every unhandled `switch` at
25
47
  * compile time rather than falling through at runtime.
@@ -37,8 +59,8 @@ export type Verdict = {
37
59
  action: 'block';
38
60
  hits: GuardrailHit[];
39
61
  /**
40
- * Sent to the model on a repair turn when `onBlock` is `reject_to_agent`.
41
- * With `refuse_to_user` the user reads the lexicon's `egress.refusal`.
62
+ * Sent to the model on a repair turn when `blockedReply.onBlock` is `retry`.
63
+ * With `refuse` the user reads the labels' `egress.refusal`.
42
64
  */
43
65
  rejection: string;
44
66
  /**
@@ -48,6 +70,7 @@ export type Verdict = {
48
70
  errorInternal?: string;
49
71
  };
50
72
  export declare const GUARDRAIL_ACTIONS: readonly ["allow", "redact", "flag", "block"];
73
+ /** One of {@linkcode GUARDRAIL_ACTIONS}. */
51
74
  export type GuardrailAction = (typeof GUARDRAIL_ACTIONS)[number];
52
75
  /**
53
76
  * `local` is host TypeScript the profile registered; `http` and `mcp` are remote
@@ -56,6 +79,7 @@ export type GuardrailAction = (typeof GUARDRAIL_ACTIONS)[number];
56
79
  * reads as authoritative, which is why depth is tracked separately.
57
80
  */
58
81
  export declare const TOOL_ORIGINS: readonly ["local", "builtin", "http", "mcp", "delegated"];
82
+ /** One of {@linkcode TOOL_ORIGINS}. */
59
83
  export type ToolOrigin = (typeof TOOL_ORIGINS)[number];
60
84
  /**
61
85
  * Once a turn has read attacker-influenceable bytes, a later tool call is a
@@ -78,9 +102,16 @@ export interface TurnTaint {
78
102
  * named a tool the model can call, or several signals agreed.
79
103
  */
80
104
  export declare const ADVISORY_LEVELS: readonly ["none", "elevated", "high"];
105
+ /** One of {@linkcode ADVISORY_LEVELS}. */
81
106
  export type AdvisoryLevel = (typeof ADVISORY_LEVELS)[number];
107
+ /** Which tool access levels refuse to run once a turn has read untrusted content. */
82
108
  export declare const TAINT_GATES: readonly ["off", "destructive", "write"];
109
+ /** One of {@linkcode TAINT_GATES}. */
83
110
  export type TaintGate = (typeof TAINT_GATES)[number];
111
+ /** What happens to a tool call that sends to a destination only remote content named. */
112
+ export declare const DESTINATION_GATES: readonly ["off", "confirm", "block"];
113
+ /** One of {@linkcode DESTINATION_GATES}. */
114
+ export type DestinationGate = (typeof DESTINATION_GATES)[number];
84
115
  /**
85
116
  * Enforcement is opt-in: every remote read is reported, but refusing tool calls
86
117
  * changes what working agents may do, so the host declares which access levels
@@ -95,15 +126,12 @@ export type TaintGate = (typeof TAINT_GATES)[number];
95
126
  */
96
127
  export interface TaintGuardrailSpec {
97
128
  /**
98
- * - `off` (default) — report only.
99
- * - `destructive` — refuse hard-to-undo calls.
100
- * - `write` — refuse those and any state-changing call.
101
- *
102
129
  * Stated as a capability threshold rather than a list of tool `access` values so
103
130
  * the guardrail vocabulary stays independent of the tool registry; the kernel
104
131
  * maps a tool's declared access onto it.
105
132
  */
106
133
  afterRemoteRead?: TaintGate;
134
+ remoteDestination?: DestinationGate;
107
135
  }
108
136
  /** Facts a check may read. Deliberately excludes the full profile. */
109
137
  export interface GuardrailContext {
@@ -111,10 +139,16 @@ export interface GuardrailContext {
111
139
  trust: TrustLevel;
112
140
  profileId: string;
113
141
  canary?: string;
142
+ /**
143
+ * The canary was in what the model was given besides the system prompt (its
144
+ * input, the user's and tools' history): a reply repeating it is not a
145
+ * leak. It still binds prompt echo.
146
+ */
147
+ canaryGiven?: boolean;
114
148
  /**
115
149
  * The private stretches of the system prompt as sent (`BoundSystem.private`),
116
- * when the profile guards it against echo (`guardrails.promptEcho`): a reply
117
- * repeating one is a leak.
150
+ * while the `prompt_leak` detector reads somewhere: text repeating one is a
151
+ * leak.
118
152
  */
119
153
  privateSystem?: readonly string[];
120
154
  role?: string;
@@ -128,41 +162,23 @@ export interface GuardrailContext {
128
162
  * server. The kernel adds to them as the model is given more. Unset: none.
129
163
  */
130
164
  givenUrls?: GivenUrls;
131
- /** The profile's lexicon, so a policy's rejection reads in the host's wording. */
132
- lexicon?: LexiconOverrides;
165
+ /** The names of the profile's tools and of their parameters, for `tool_leak`. Unset: none. */
166
+ ownTools?: OwnTools;
167
+ /** The profile's labels, so a rejection reads in the host's wording. */
168
+ labels?: LabelOverrides;
133
169
  }
134
170
  /**
135
171
  * Structured output travels alongside text so a profile with `outputs.structured`
136
- * is not invisible to its own egress policy.
172
+ * has it read by the detectors too.
137
173
  */
138
174
  export interface OutboundPayload {
139
175
  /** Concatenated user-visible text for this attempt. */
140
176
  text: string;
141
177
  structured?: unknown;
142
178
  }
143
- export type EgressEnforcer = (payload: OutboundPayload, context: GuardrailContext) => Verdict | Promise<Verdict>;
144
- /** `enforce` or `checks`, never both. */
145
- export interface ProfileEgressSpec {
146
- /** The host's own check. */
147
- enforce?: EgressEnforcer;
148
- /**
149
- * The bundled policy's checks: `true` runs each at its default, `false` none
150
- * but the system-prompt leak checks, and an object switches the ones it names.
151
- */
152
- checks?: boolean | EgressChecks;
153
- onBlock?: EgressOnBlock;
154
- maxRetries?: number;
155
- /**
156
- * For a host `enforce` only: characters the progressive gate holds back so
157
- * `enforce` sees a match split across stream chunks before any of it is
158
- * released (default `DEFAULT_HOLDBACK`, 256; on Live `LIVE_DEFAULT_HOLDBACK`,
159
- * 96). The bundled `standardEgressEnforce` holds exactly what could still
160
- * become a match, and setting this with it is a profile error.
161
- */
162
- holdback?: number;
163
- }
179
+ /** Which hosts and networks a tool's requests may reach. */
164
180
  export interface NetworkGuardrailSpec {
165
- /** Allows localhost, loopback and private subnets (local dev and testing). Default false. */
181
+ /** Allows localhost, loopback, and private subnets (local dev and testing). Default false. */
166
182
  allowPrivateNetworks?: boolean;
167
183
  /** Hostnames or IP addresses permitted regardless of private subnet status. */
168
184
  allowedHosts?: string[];
@@ -176,30 +192,20 @@ export interface NetworkGuardrailSpec {
176
192
  export interface QuotaGuardrailSpec {
177
193
  perDay: number;
178
194
  }
195
+ /** The guardrails a profile turns on, each with its own settings. */
179
196
  export interface ProfileGuardrailsSpec {
180
197
  /** Omitted means quota enforcement is not configured. */
181
198
  quota?: QuotaGuardrailSpec;
182
199
  /**
183
- * Mint a per-turn canary into the system prompt. Default true. The note
184
- * that binds it is the lexicon's `canary.bind_note` (the profile's `lexicon`
185
- * may replace it).
200
+ * What the kernel does when a detector finds a match, per boundary: one action
201
+ * for everything, or a rule for the detectors it names. Anything left out keeps
202
+ * its default (`DETECT_DEFAULTS`). A canary is bound into the system prompt
203
+ * while `canary_leak` is above `ignore` somewhere; the note that binds it is
204
+ * the labels' `canary.bind_note` (the profile's `labels` may replace it).
186
205
  */
187
- canary?: boolean;
188
- /**
189
- * With the canary on, also treat a reply that repeats `PROMPT_ECHO_WORDS`
190
- * (12) consecutive words of the system prompt as a leak: the dump the token
191
- * alone cannot see. Default true; set false when the prompt holds text the
192
- * agent is meant to quote word for word.
193
- */
194
- promptEcho?: boolean;
195
- sanitizeInput?: boolean;
196
- /**
197
- * Redact sensitive data from untrusted text before the model reads it:
198
- * `true` (the default) every group, `false` none, an object the groups it
199
- * switches, the rest on (`ids`, `financial`, `network`, `credentials`).
200
- */
201
- redactSensitive?: SensitiveSelection;
202
- egress?: ProfileEgressSpec;
206
+ detect?: DetectSpec;
207
+ /** What happens once a reply is blocked. Left out, the model rewrites it once. */
208
+ blockedReply?: BlockedReplySpec;
203
209
  network?: NetworkGuardrailSpec;
204
210
  taint?: TaintGuardrailSpec;
205
211
  }
@@ -208,10 +214,15 @@ export type DecisionDisclosureVerdict = Extract<Verdict, {
208
214
  action: 'allow' | 'block';
209
215
  }>;
210
216
  export type DecisionDisclosureEnforcer = (state: unknown, context: {
211
- destination: 'typesafe' | 'openrouter';
217
+ destination: string;
212
218
  profileId: string;
213
219
  model: string;
214
220
  questionIds: string[];
221
+ /** The images the call sends with the state, by reference. Absent: none. */
222
+ assets?: Record<string, {
223
+ mimeType: 'image/png' | 'image/jpeg';
224
+ data: string;
225
+ }>;
215
226
  }) => DecisionDisclosureVerdict | Promise<DecisionDisclosureVerdict>;
216
227
  /**
217
228
  * Keeps the shared guardrail vocabulary structurally compatible while the
@@ -223,20 +234,17 @@ export interface DecisionGuardrailsSpec extends Partial<ProfileGuardrailsSpec> {
223
234
  };
224
235
  }
225
236
  /** The guardrail field names a `host` profile may set. */
226
- export declare const HOST_GUARDRAIL_FIELDS: readonly ["sanitizeInput", "redactSensitive", "network"];
237
+ export declare const HOST_GUARDRAIL_FIELDS: readonly ["detect", "network"];
227
238
  /** The guardrails that fire on the `invokeTool` path; the rest guard a model turn. */
228
239
  export type HostGuardrailsSpec = Pick<ProfileGuardrailsSpec, (typeof HOST_GUARDRAIL_FIELDS)[number]>;
240
+ /** A profile's guardrails after defaults are applied. */
229
241
  export interface ResolvedGuardrailPolicy {
230
- sanitizeInput: boolean;
231
- redactSensitive: SensitiveGroups;
232
- canary: boolean;
233
- promptEcho: boolean;
234
- /** `checks` resolved to the bundled policy's `enforce`. */
235
- egress?: ResolvedEgressSpec;
242
+ /** Every detector's action at every boundary. */
243
+ detect: ResolvedDetect;
244
+ /** What `ungiven_images` and `ungiven_links` let through besides the given URLs. */
245
+ allow: ResolvedAllow;
246
+ blockedReply: ResolvedBlockedReply;
236
247
  network?: NetworkGuardrailSpec;
237
248
  quota?: QuotaGuardrailSpec;
238
249
  taint?: TaintGuardrailSpec;
239
250
  }
240
- export type ResolvedEgressSpec = Omit<ProfileEgressSpec, 'enforce' | 'checks'> & {
241
- enforce: EgressEnforcer;
242
- };
@@ -1,13 +1,14 @@
1
- // Must not import from `src/kernel/`: the kernel type-imports `ProfileGuardrailsSpec`, and that edge
1
+ // invariant: Must not import from `src/kernel/`: the kernel type-imports `ProfileGuardrailsSpec`, and that edge
2
2
  // stays one-directional. Other modules under `src/guardrails/` may import kernel types.
3
3
  /**
4
- * - `trusted` — author-time profile text (`identity.system`). Sensitive redaction
5
- * only; injection redaction would mangle the host's own instructions.
4
+ * - `trusted` — author-time profile text (`identity.system`). Left verbatim: no
5
+ * injection or sensitive redaction, which would mangle the host's own instructions.
6
6
  * - `assembled` — host-built per turn (`req.system`). Interpolates retrieval and
7
7
  * user data, so it is permeable and takes full detection.
8
8
  * - `untrusted` — user input, tool results, attachments, delegated agents.
9
9
  */
10
10
  export const TRUST_LEVELS = ['trusted', 'assembled', 'untrusted'];
11
+ /** The points a guardrail can run: input, history, system, attachments, tool calls, and results, output, thoughts, network, live audio, and traces. */
11
12
  export const GUARDRAIL_STAGES = [
12
13
  'input',
13
14
  'history',
@@ -23,9 +24,10 @@ export const GUARDRAIL_STAGES = [
23
24
  'live_outbound',
24
25
  'trace',
25
26
  ];
26
- /** Does not decide what happens next; that is `onBlock`. */
27
+ /** Does not decide what happens next; that is `blockedReply`. */
27
28
  export const SEVERITIES = ['info', 'low', 'medium', 'high'];
28
- export const EGRESS_ON_BLOCK = ['reject_to_agent', 'refuse_to_user'];
29
+ /** What follows a blocked reply: the model rewrites it, or the user reads a refusal. */
30
+ export const BLOCKED_REPLY_ON_BLOCK = ['retry', 'refuse'];
29
31
  export const GUARDRAIL_ACTIONS = [
30
32
  'allow',
31
33
  'redact',
@@ -45,10 +47,12 @@ export const TOOL_ORIGINS = ['local', 'builtin', 'http', 'mcp', 'delegated'];
45
47
  * named a tool the model can call, or several signals agreed.
46
48
  */
47
49
  export const ADVISORY_LEVELS = ['none', 'elevated', 'high'];
50
+ /** Which tool access levels refuse to run once a turn has read untrusted content. */
48
51
  export const TAINT_GATES = ['off', 'destructive', 'write'];
52
+ /** What happens to a tool call that sends to a destination only remote content named. */
53
+ export const DESTINATION_GATES = ['off', 'confirm', 'block'];
49
54
  /** The guardrail field names a `host` profile may set. */
50
55
  export const HOST_GUARDRAIL_FIELDS = [
51
- 'sanitizeInput',
52
- 'redactSensitive',
56
+ 'detect',
53
57
  'network',
54
58
  ];
@@ -1,9 +1,36 @@
1
+ import { type ErrorCopies, type ErrorKind } from '../guardrails/error.js';
2
+ import type { LabelOverrides } from '../guardrails/labels.js';
1
3
  import type { TurnEvent } from '../kernel/types.js';
4
+ /** Options for `forClient` and `clientError`: who reads the copy, and whether evidence keeps its provider-native payload. */
2
5
  export interface ClientTurnOptions {
3
6
  /** Keep provider-native payloads on `evidence` events. Default: false; parsed fields remain. */
4
7
  includeEvidenceRaw?: boolean;
8
+ /**
9
+ * Who reads the copy. A `'visitor'` (the default) reads the profile's wording, and every
10
+ * builder-only diagnostic is stripped. A `'builder'` is whoever builds the app, on their own
11
+ * machine and keys, as in a local development tool: a failed turn, an ended session, and a tool
12
+ * call's failure read their raw reason in place of the profile's wording, and builder-only
13
+ * diagnostics stay. Never for a page visitors reach.
14
+ */
15
+ reader?: 'visitor' | 'builder';
5
16
  }
6
- /** Strips host-only diagnostics, so the copy is safe to forward to browsers or end-user SSE. */
17
+ /**
18
+ * The copy of an event its reader may have. For a visitor (the default) host-only diagnostics are
19
+ * stripped, so the copy is safe to forward to browsers or end-user SSE.
20
+ */
7
21
  declare function forClient(event: TurnEvent, options?: ClientTurnOptions): TurnEvent;
22
+ /** `forClient` over a list of events. */
8
23
  declare function forClientEvents(events: TurnEvent[], options?: ClientTurnOptions): TurnEvent[];
9
- export { forClient, forClientEvents };
24
+ /** A failure's wording and kind as a client reads them: the body of an error reply or line. */
25
+ type ClientError = {
26
+ error: string;
27
+ errorKind: ErrorKind;
28
+ errorCopy?: ErrorCopies;
29
+ };
30
+ /**
31
+ * A caught failure as its reader may have it, by the same rule as `forClient`: the profile's
32
+ * wording (pass its `labels`) for a visitor, the raw diagnostic for a builder.
33
+ */
34
+ declare function clientError(err: unknown, labels?: LabelOverrides, options?: ClientTurnOptions): ClientError;
35
+ export type { ClientError };
36
+ export { clientError, forClient, forClientEvents };