@theoremjs/agents 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (568) hide show
  1. package/README.md +276 -995
  2. package/esm/mod.d.ts +33 -19
  3. package/esm/mod.js +18 -11
  4. package/esm/src/cli/commands/bench.js +36 -14
  5. package/esm/src/cli/commands/detect-compile.d.ts +17 -0
  6. package/esm/src/cli/commands/detect-compile.js +22 -0
  7. package/esm/src/cli/commands/eval.d.ts +3 -3
  8. package/esm/src/cli/commands/fuzz-canary.js +55 -16
  9. package/esm/src/cli/commands/profile.js +4 -4
  10. package/esm/src/cli/commands/run.d.ts +2 -2
  11. package/esm/src/cli/commands/run.js +1 -1
  12. package/esm/src/cli/commands/test.d.ts +4 -3
  13. package/esm/src/cli/commands/test.js +2 -2
  14. package/esm/src/cli/index.js +9 -9
  15. package/esm/src/cli/matrix/fixtures.js +25 -30
  16. package/esm/src/evals/attachments.d.ts +1 -0
  17. package/esm/src/evals/attachments.js +4 -2
  18. package/esm/src/evals/breakdown.d.ts +2 -0
  19. package/esm/src/evals/breakdown.js +1 -0
  20. package/esm/src/evals/graders/answer.d.ts +3 -0
  21. package/esm/src/evals/graders/answer.js +1 -0
  22. package/esm/src/evals/graders/code.d.ts +7 -31
  23. package/esm/src/evals/graders/code.js +4 -25
  24. package/esm/src/evals/graders/judge.d.ts +4 -0
  25. package/esm/src/evals/graders/judge.js +7 -5
  26. package/esm/src/evals/graders/latency.d.ts +1 -0
  27. package/esm/src/evals/graders/latency.js +3 -2
  28. package/esm/src/evals/graders/live.d.ts +3 -0
  29. package/esm/src/evals/graders/live.js +2 -0
  30. package/esm/src/evals/graders/media.js +1 -2
  31. package/esm/src/evals/graders/shared.js +1 -1
  32. package/esm/src/evals/graders/transcript.d.ts +2 -0
  33. package/esm/src/evals/graders/transcript.js +5 -3
  34. package/esm/src/evals/mod.d.ts +1 -9
  35. package/esm/src/evals/mod.js +1 -9
  36. package/esm/src/evals/record.d.ts +6 -0
  37. package/esm/src/evals/record.js +4 -2
  38. package/esm/src/evals/rubrics/mod.d.ts +1 -1
  39. package/esm/src/evals/rubrics/mod.js +1 -1
  40. package/esm/src/evals/rubrics/mustache.js +1 -1
  41. package/esm/src/evals/rubrics/types.js +1 -1
  42. package/esm/src/evals/run.d.ts +9 -52
  43. package/esm/src/evals/run.js +12 -46
  44. package/esm/src/evals/suite.d.ts +12 -3
  45. package/esm/src/evals/suite.js +9 -4
  46. package/esm/src/evals/summary.d.ts +3 -0
  47. package/esm/src/evals/summary.js +1 -0
  48. package/esm/src/evals/trial.d.ts +3 -16
  49. package/esm/src/evals/trial.js +7 -30
  50. package/esm/src/evals/types.d.ts +30 -121
  51. package/esm/src/evals/types.js +3 -16
  52. package/esm/src/evals/verdict.d.ts +5 -0
  53. package/esm/src/evals/verdict.js +4 -1
  54. package/esm/src/guardrails/boundaries.d.ts +41 -0
  55. package/esm/src/guardrails/boundaries.js +103 -0
  56. package/esm/src/guardrails/canary-gate.d.ts +1 -0
  57. package/esm/src/guardrails/canary.d.ts +49 -15
  58. package/esm/src/guardrails/canary.js +103 -30
  59. package/esm/src/guardrails/compile-egress.d.ts +6 -5
  60. package/esm/src/guardrails/compile-egress.js +6 -5
  61. package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +3 -1
  62. package/esm/src/guardrails/corpus/canary-egress-attacks.js +4 -2
  63. package/esm/src/guardrails/corpus/fuzz-inbound.js +14 -17
  64. package/esm/src/guardrails/corpus/inbound-payloads.d.ts +2 -0
  65. package/esm/src/guardrails/corpus/inbound-payloads.js +4 -2
  66. package/esm/src/guardrails/corpus/live-attacks.d.ts +2 -0
  67. package/esm/src/guardrails/corpus/live-attacks.js +6 -1
  68. package/esm/src/guardrails/corpus/mod.d.ts +1 -1
  69. package/esm/src/guardrails/corpus/secrets.d.ts +3 -3
  70. package/esm/src/guardrails/corpus/secrets.js +2 -2
  71. package/esm/src/guardrails/corpus/strings.d.ts +1 -1
  72. package/esm/src/guardrails/corpus/strings.js +1 -1
  73. package/esm/src/guardrails/corpus/types.d.ts +5 -1
  74. package/esm/src/guardrails/credential-rules.d.ts +36 -0
  75. package/esm/src/guardrails/credential-rules.js +3001 -0
  76. package/esm/src/guardrails/credential-scan.d.ts +45 -0
  77. package/esm/src/guardrails/credential-scan.js +172 -0
  78. package/esm/src/guardrails/destinations.d.ts +45 -0
  79. package/esm/src/guardrails/destinations.js +234 -0
  80. package/esm/src/guardrails/detect-at.d.ts +107 -0
  81. package/esm/src/guardrails/detect-at.js +434 -0
  82. package/esm/src/guardrails/detect-reply.d.ts +61 -0
  83. package/esm/src/guardrails/detect-reply.js +95 -0
  84. package/esm/src/guardrails/detect-stream.d.ts +33 -0
  85. package/esm/src/guardrails/detect-stream.js +77 -0
  86. package/esm/src/guardrails/detectors.d.ts +216 -0
  87. package/esm/src/guardrails/detectors.js +503 -0
  88. package/esm/src/guardrails/egress-automata.d.ts +4 -6
  89. package/esm/src/guardrails/egress-automata.js +24095 -4572
  90. package/esm/src/guardrails/egress-compiler.d.ts +38 -16
  91. package/esm/src/guardrails/egress-compiler.js +254 -60
  92. package/esm/src/guardrails/egress-patterns.d.ts +4 -2
  93. package/esm/src/guardrails/egress-patterns.js +6 -2
  94. package/esm/src/guardrails/egress-stream.d.ts +54 -36
  95. package/esm/src/guardrails/egress-stream.js +253 -124
  96. package/esm/src/guardrails/egress-urls.d.ts +6 -3
  97. package/esm/src/guardrails/egress-urls.js +14 -22
  98. package/esm/src/guardrails/egress.d.ts +26 -86
  99. package/esm/src/guardrails/egress.js +59 -309
  100. package/esm/src/guardrails/error.d.ts +13 -8
  101. package/esm/src/guardrails/error.js +23 -18
  102. package/esm/src/guardrails/event-schemas.d.ts +46 -3
  103. package/esm/src/guardrails/event-schemas.js +12 -5
  104. package/esm/src/guardrails/events.d.ts +5 -1
  105. package/esm/src/guardrails/events.js +4 -1
  106. package/esm/src/guardrails/hints.d.ts +14 -0
  107. package/esm/src/guardrails/hints.js +57 -0
  108. package/esm/src/guardrails/hits.d.ts +7 -1
  109. package/esm/src/guardrails/hits.js +12 -1
  110. package/esm/src/guardrails/host-patterns.d.ts +85 -0
  111. package/esm/src/guardrails/host-patterns.js +173 -0
  112. package/esm/src/guardrails/injection-patterns.d.ts +6 -1
  113. package/esm/src/guardrails/injection-patterns.js +33 -1
  114. package/esm/src/guardrails/injection-reversed.d.ts +9 -0
  115. package/esm/src/guardrails/injection-reversed.js +49 -0
  116. package/esm/src/guardrails/injection.d.ts +17 -1
  117. package/esm/src/guardrails/injection.js +259 -36
  118. package/esm/src/guardrails/labels.d.ts +40 -0
  119. package/esm/src/guardrails/labels.js +874 -0
  120. package/esm/src/guardrails/live-outbound-gate.d.ts +9 -8
  121. package/esm/src/guardrails/live-outbound-gate.js +100 -107
  122. package/esm/src/guardrails/mod.d.ts +29 -21
  123. package/esm/src/guardrails/mod.js +18 -13
  124. package/esm/src/guardrails/network.d.ts +4 -0
  125. package/esm/src/guardrails/network.js +21 -19
  126. package/esm/src/guardrails/normalize.d.ts +15 -1
  127. package/esm/src/guardrails/normalize.js +34 -1
  128. package/esm/src/guardrails/policy.d.ts +2 -17
  129. package/esm/src/guardrails/policy.js +12 -41
  130. package/esm/src/guardrails/progressive-yield.d.ts +65 -24
  131. package/esm/src/guardrails/progressive-yield.js +191 -147
  132. package/esm/src/guardrails/prompt-echo.d.ts +4 -2
  133. package/esm/src/guardrails/prompt-echo.js +87 -6
  134. package/esm/src/guardrails/quota.d.ts +1 -0
  135. package/esm/src/guardrails/quota.js +1 -1
  136. package/esm/src/guardrails/rules.d.ts +20 -29
  137. package/esm/src/guardrails/rules.js +23 -30
  138. package/esm/src/guardrails/sanitize.d.ts +32 -15
  139. package/esm/src/guardrails/sanitize.js +100 -124
  140. package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
  141. package/esm/src/guardrails/sensitive-groups.js +12 -0
  142. package/esm/src/guardrails/sensitive.d.ts +16 -23
  143. package/esm/src/guardrails/sensitive.js +168 -47
  144. package/esm/src/guardrails/serialize.d.ts +1 -0
  145. package/esm/src/guardrails/testing.d.ts +4 -2
  146. package/esm/src/guardrails/testing.js +4 -2
  147. package/esm/src/guardrails/theorem-error.d.ts +4 -1
  148. package/esm/src/guardrails/theorem-error.js +3 -2
  149. package/esm/src/guardrails/thought-guard.d.ts +34 -13
  150. package/esm/src/guardrails/thought-guard.js +264 -64
  151. package/esm/src/guardrails/tool-directives.d.ts +29 -10
  152. package/esm/src/guardrails/tool-directives.js +133 -47
  153. package/esm/src/guardrails/tool-leak.d.ts +26 -0
  154. package/esm/src/guardrails/tool-leak.js +45 -0
  155. package/esm/src/guardrails/tool-result.d.ts +45 -14
  156. package/esm/src/guardrails/tool-result.js +94 -70
  157. package/esm/src/guardrails/types.d.ts +79 -71
  158. package/esm/src/guardrails/types.js +11 -7
  159. package/esm/src/host/client-turn.d.ts +29 -2
  160. package/esm/src/host/client-turn.js +46 -4
  161. package/esm/src/host/mint-trace.d.ts +1 -0
  162. package/esm/src/host/mint-trace.js +3 -2
  163. package/esm/src/host/mod.d.ts +2 -2
  164. package/esm/src/host/mod.js +1 -1
  165. package/esm/src/host/readStreamingJsonStringField.js +2 -43
  166. package/esm/src/host/reply.d.ts +6 -0
  167. package/esm/src/host/reply.js +7 -1
  168. package/esm/src/interface/blocks.d.ts +3 -0
  169. package/esm/src/interface/blocks.js +84 -14
  170. package/esm/src/interface/composer-actions.d.ts +4 -0
  171. package/esm/src/interface/composer-actions.js +5 -3
  172. package/esm/src/interface/draft.d.ts +6 -0
  173. package/esm/src/interface/draft.js +22 -11
  174. package/esm/src/interface/from-profile.d.ts +13 -1
  175. package/esm/src/interface/from-profile.js +66 -31
  176. package/esm/src/interface/history.d.ts +9 -3
  177. package/esm/src/interface/history.js +33 -24
  178. package/esm/src/interface/inputs.d.ts +1 -0
  179. package/esm/src/interface/inputs.js +3 -0
  180. package/esm/src/interface/mod.d.ts +4 -2
  181. package/esm/src/interface/mod.js +3 -2
  182. package/esm/src/interface/models.d.ts +7 -0
  183. package/esm/src/interface/models.js +5 -0
  184. package/esm/src/interface/pending.d.ts +9 -0
  185. package/esm/src/interface/pending.js +9 -3
  186. package/esm/src/interface/profile-interface.js +54 -40
  187. package/esm/src/interface/session.d.ts +12 -5
  188. package/esm/src/interface/session.js +17 -10
  189. package/esm/src/interface/stop.d.ts +13 -0
  190. package/esm/src/interface/stop.js +28 -0
  191. package/esm/src/interface/tool-calls.d.ts +14 -2
  192. package/esm/src/interface/tool-calls.js +64 -10
  193. package/esm/src/interface/tool-invoke.d.ts +2 -0
  194. package/esm/src/interface/tool-invoke.js +3 -1
  195. package/esm/src/interface/tool-media.d.ts +2 -0
  196. package/esm/src/interface/tool-media.js +2 -1
  197. package/esm/src/interface/types.d.ts +105 -40
  198. package/esm/src/interface/types.js +1 -0
  199. package/esm/src/kernel/api-catalog.d.ts +85 -0
  200. package/esm/src/kernel/api-catalog.js +229 -0
  201. package/esm/src/kernel/auth/crypto.d.ts +7 -2
  202. package/esm/src/kernel/auth/crypto.js +12 -10
  203. package/esm/src/kernel/auth/oauth.d.ts +2 -1
  204. package/esm/src/kernel/auth/oauth.js +23 -22
  205. package/esm/src/kernel/auth/typed-secret.js +2 -2
  206. package/esm/src/kernel/auth/types.d.ts +13 -0
  207. package/esm/src/kernel/checkpoint.d.ts +43 -0
  208. package/esm/src/kernel/checkpoint.js +58 -0
  209. package/esm/src/kernel/default-scope.d.ts +43 -5
  210. package/esm/src/kernel/default-scope.js +54 -5
  211. package/esm/src/kernel/engine/call-trace.d.ts +19 -0
  212. package/esm/src/kernel/engine/call-trace.js +29 -0
  213. package/esm/src/kernel/engine/compaction.d.ts +6 -5
  214. package/esm/src/kernel/engine/compaction.js +12 -11
  215. package/esm/src/kernel/engine/decision.d.ts +10 -8
  216. package/esm/src/kernel/engine/decision.js +173 -146
  217. package/esm/src/kernel/engine/embedding.d.ts +8 -0
  218. package/esm/src/kernel/engine/embedding.js +118 -0
  219. package/esm/src/kernel/engine/live-inbound.d.ts +14 -4
  220. package/esm/src/kernel/engine/live-inbound.js +36 -11
  221. package/esm/src/kernel/engine/live-ingress.d.ts +6 -0
  222. package/esm/src/kernel/engine/live-ingress.js +6 -1
  223. package/esm/src/kernel/engine/repair.js +12 -12
  224. package/esm/src/kernel/engine/runner/gates.d.ts +2 -2
  225. package/esm/src/kernel/engine/runner/gates.js +287 -101
  226. package/esm/src/kernel/engine/runner/mod.d.ts +19 -5
  227. package/esm/src/kernel/engine/runner/mod.js +107 -56
  228. package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
  229. package/esm/src/kernel/engine/runner/nested.js +134 -0
  230. package/esm/src/kernel/engine/runner/schema-validation.d.ts +24 -3
  231. package/esm/src/kernel/engine/runner/schema-validation.js +78 -4
  232. package/esm/src/kernel/engine/runner/stages.d.ts +1 -1
  233. package/esm/src/kernel/engine/runner/stages.js +1 -8
  234. package/esm/src/kernel/engine/runner/state.d.ts +33 -12
  235. package/esm/src/kernel/engine/runner/state.js +11 -1
  236. package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
  237. package/esm/src/kernel/engine/runner/step-order.js +165 -0
  238. package/esm/src/kernel/engine/runner/steps.d.ts +2 -2
  239. package/esm/src/kernel/engine/runner/steps.js +328 -169
  240. package/esm/src/kernel/engine/runner/stream.d.ts +42 -11
  241. package/esm/src/kernel/engine/runner/stream.js +197 -46
  242. package/esm/src/kernel/engine/runner/usage.d.ts +5 -5
  243. package/esm/src/kernel/engine/runner/usage.js +12 -14
  244. package/esm/src/kernel/engine/session/mod.d.ts +8 -6
  245. package/esm/src/kernel/engine/session/mod.js +360 -129
  246. package/esm/src/kernel/engine/session/session-trace.d.ts +10 -10
  247. package/esm/src/kernel/engine/session/session-trace.js +41 -30
  248. package/esm/src/kernel/engine/token-estimate.d.ts +10 -64
  249. package/esm/src/kernel/engine/token-estimate.js +14 -194
  250. package/esm/src/kernel/engine/tool-trace.d.ts +3 -3
  251. package/esm/src/kernel/engine/tool-trace.js +2 -1
  252. package/esm/src/kernel/engine/turn-trace.d.ts +8 -7
  253. package/esm/src/kernel/engine/turn-trace.js +28 -36
  254. package/esm/src/kernel/engine/usage.d.ts +6 -0
  255. package/esm/src/kernel/engine/usage.js +17 -0
  256. package/esm/src/kernel/interaction-parts.d.ts +3 -0
  257. package/esm/src/kernel/interaction-parts.js +18 -0
  258. package/esm/src/kernel/json.d.ts +10 -0
  259. package/esm/src/kernel/json.js +3 -0
  260. package/esm/src/kernel/mod.d.ts +38 -11
  261. package/esm/src/kernel/mod.js +22 -7
  262. package/esm/src/kernel/profile-graph.d.ts +11 -6
  263. package/esm/src/kernel/profile-graph.js +14 -7
  264. package/esm/src/kernel/profile-presence.d.ts +10 -1
  265. package/esm/src/kernel/profile-presence.js +90 -75
  266. package/esm/src/kernel/profile-scope.d.ts +7 -3
  267. package/esm/src/kernel/profile-scope.js +67 -55
  268. package/esm/src/kernel/protocols/binding.d.ts +65 -0
  269. package/esm/src/kernel/protocols/binding.js +125 -0
  270. package/esm/src/kernel/protocols/limits.d.ts +15 -0
  271. package/esm/src/kernel/protocols/limits.js +28 -0
  272. package/esm/src/kernel/protocols/mod.d.ts +5 -0
  273. package/esm/src/kernel/protocols/mod.js +5 -0
  274. package/esm/src/kernel/protocols/prices.d.ts +36 -0
  275. package/esm/src/kernel/protocols/prices.js +37 -0
  276. package/esm/src/kernel/protocols/protocol.d.ts +253 -0
  277. package/esm/src/kernel/protocols/protocol.js +253 -0
  278. package/esm/src/kernel/protocols/provider.d.ts +108 -0
  279. package/esm/src/kernel/protocols/provider.js +143 -0
  280. package/esm/src/kernel/protocols/runtime.d.ts +55 -0
  281. package/esm/src/kernel/protocols/runtime.js +534 -0
  282. package/esm/src/kernel/provider-budget.d.ts +32 -0
  283. package/esm/src/kernel/provider-budget.js +262 -0
  284. package/esm/src/kernel/provider-dispatch.d.ts +13 -0
  285. package/esm/src/kernel/provider-dispatch.js +36 -0
  286. package/esm/src/kernel/provider-live.d.ts +7 -0
  287. package/esm/src/kernel/provider-live.js +189 -0
  288. package/esm/src/kernel/provider-runtime.d.ts +57 -0
  289. package/esm/src/kernel/provider-runtime.js +524 -0
  290. package/esm/src/kernel/registry/attachments.d.ts +15 -4
  291. package/esm/src/kernel/registry/attachments.js +31 -22
  292. package/esm/src/kernel/registry/catalog.d.ts +6 -0
  293. package/esm/src/kernel/registry/catalog.js +9 -2
  294. package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
  295. package/esm/src/kernel/registry/embedding-rules.js +66 -0
  296. package/esm/src/kernel/registry/ingress.d.ts +6 -2
  297. package/esm/src/kernel/registry/ingress.js +55 -10
  298. package/esm/src/kernel/registry/kernel-registry.d.ts +3 -0
  299. package/esm/src/kernel/registry/kernel-registry.js +9 -2
  300. package/esm/src/kernel/registry/profile-outputs.js +4 -1
  301. package/esm/src/kernel/registry/profiles.d.ts +38 -14
  302. package/esm/src/kernel/registry/profiles.js +280 -205
  303. package/esm/src/kernel/registry/provider-request.d.ts +3 -3
  304. package/esm/src/kernel/registry/provider-request.js +5 -13
  305. package/esm/src/kernel/registry/resolve.d.ts +4 -1
  306. package/esm/src/kernel/registry/resolve.js +59 -58
  307. package/esm/src/kernel/registry/schemas.d.ts +3 -0
  308. package/esm/src/kernel/registry/schemas.js +3 -1
  309. package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
  310. package/esm/src/kernel/registry/slot-fill.js +22 -0
  311. package/esm/src/kernel/registry/system-prompt.js +7 -8
  312. package/esm/src/kernel/registry/vault.d.ts +14 -13
  313. package/esm/src/kernel/registry/vault.js +1 -14
  314. package/esm/src/kernel/schema.d.ts +100 -46
  315. package/esm/src/kernel/schema.js +499 -257
  316. package/esm/src/kernel/scope.d.ts +12 -5
  317. package/esm/src/kernel/scope.js +23 -3
  318. package/esm/src/kernel/stages.d.ts +38 -3
  319. package/esm/src/kernel/stages.js +82 -39
  320. package/esm/src/kernel/stop.d.ts +29 -6
  321. package/esm/src/kernel/stop.js +16 -4
  322. package/esm/src/kernel/system-parts.js +6 -6
  323. package/esm/src/kernel/tools/activity-label.d.ts +12 -6
  324. package/esm/src/kernel/tools/activity-label.js +258 -32
  325. package/esm/src/kernel/tools/agent.d.ts +66 -0
  326. package/esm/src/kernel/tools/agent.js +212 -0
  327. package/esm/src/kernel/tools/coordinate.d.ts +4 -0
  328. package/esm/src/kernel/tools/coordinate.js +165 -0
  329. package/esm/src/kernel/tools/events.d.ts +21 -6
  330. package/esm/src/kernel/tools/events.js +53 -18
  331. package/esm/src/kernel/tools/execute.d.ts +47 -11
  332. package/esm/src/kernel/tools/execute.js +508 -136
  333. package/esm/src/kernel/tools/gate-answer.d.ts +12 -2
  334. package/esm/src/kernel/tools/gate-answer.js +17 -6
  335. package/esm/src/kernel/tools/handler-events.d.ts +45 -0
  336. package/esm/src/kernel/tools/handler-events.js +106 -0
  337. package/esm/src/kernel/tools/harness.d.ts +1 -0
  338. package/esm/src/kernel/tools/harness.js +2 -1
  339. package/esm/src/kernel/tools/http-limit.d.ts +27 -0
  340. package/esm/src/kernel/tools/http-limit.js +85 -0
  341. package/esm/src/kernel/tools/invoke.d.ts +27 -5
  342. package/esm/src/kernel/tools/invoke.js +223 -70
  343. package/esm/src/kernel/tools/mcp-sessions.d.ts +4 -1
  344. package/esm/src/kernel/tools/mcp-sessions.js +13 -8
  345. package/esm/src/kernel/tools/mod.d.ts +4 -3
  346. package/esm/src/kernel/tools/mod.js +3 -2
  347. package/esm/src/kernel/tools/model-text.d.ts +10 -5
  348. package/esm/src/kernel/tools/model-text.js +18 -12
  349. package/esm/src/kernel/tools/operation.d.ts +76 -0
  350. package/esm/src/kernel/tools/operation.js +100 -0
  351. package/esm/src/kernel/tools/page-answer.d.ts +8 -0
  352. package/esm/src/kernel/tools/page-answer.js +19 -0
  353. package/esm/src/kernel/tools/permission.d.ts +11 -2
  354. package/esm/src/kernel/tools/permission.js +12 -12
  355. package/esm/src/kernel/tools/project.d.ts +4 -1
  356. package/esm/src/kernel/tools/project.js +32 -2
  357. package/esm/src/kernel/tools/registry.d.ts +9 -2
  358. package/esm/src/kernel/tools/registry.js +69 -10
  359. package/esm/src/kernel/tools/remote.d.ts +40 -6
  360. package/esm/src/kernel/tools/remote.js +219 -92
  361. package/esm/src/kernel/tools/resolve.d.ts +3 -0
  362. package/esm/src/kernel/tools/resolve.js +12 -4
  363. package/esm/src/kernel/tools/run.d.ts +28 -0
  364. package/esm/src/kernel/tools/run.js +86 -0
  365. package/esm/src/kernel/tools/schema.d.ts +3 -3
  366. package/esm/src/kernel/tools/schema.js +21 -100
  367. package/esm/src/kernel/tools/signed-in-fetch.d.ts +2 -1
  368. package/esm/src/kernel/tools/signed-in-fetch.js +3 -3
  369. package/esm/src/kernel/tools/stage-run.d.ts +27 -4
  370. package/esm/src/kernel/tools/stage-run.js +75 -17
  371. package/esm/src/kernel/tools/types.d.ts +235 -25
  372. package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
  373. package/esm/src/kernel/tools/unchecked-output.js +18 -0
  374. package/esm/src/kernel/turn-events.d.ts +208 -31
  375. package/esm/src/kernel/turn-events.js +127 -9
  376. package/esm/src/kernel/types.d.ts +302 -161
  377. package/esm/src/kernel/util/base64.d.ts +2 -0
  378. package/esm/src/kernel/util/base64.js +2 -0
  379. package/esm/src/kernel/util/partial-json.d.ts +23 -0
  380. package/esm/src/kernel/util/partial-json.js +128 -0
  381. package/esm/src/kernel/util/record.d.ts +1 -0
  382. package/esm/src/kernel/util/record.js +1 -0
  383. package/esm/src/observability/destinations.d.ts +5 -0
  384. package/esm/src/observability/destinations.js +7 -2
  385. package/esm/src/observability/jsonl.d.ts +2 -2
  386. package/esm/src/observability/jsonl.js +15 -22
  387. package/esm/src/observability/mod.d.ts +3 -3
  388. package/esm/src/observability/mod.js +2 -2
  389. package/esm/src/observability/openinference.d.ts +1 -1
  390. package/esm/src/observability/openinference.js +3 -3
  391. package/esm/src/observability/otlp.d.ts +3 -0
  392. package/esm/src/observability/otlp.js +3 -3
  393. package/esm/src/observability/phoenix.d.ts +1 -0
  394. package/esm/src/observability/policy.d.ts +3 -0
  395. package/esm/src/observability/policy.js +5 -1
  396. package/esm/src/observability/resolve-policy.js +11 -5
  397. package/esm/src/observability/spans.d.ts +8 -2
  398. package/esm/src/observability/spans.js +21 -5
  399. package/esm/src/observability/trace-catalog.d.ts +19 -2
  400. package/esm/src/observability/trace-catalog.js +128 -87
  401. package/esm/src/observability/trace-record.js +22 -17
  402. package/esm/src/observability/trace-schema.d.ts +3 -0
  403. package/esm/src/observability/trace-schema.js +1 -1
  404. package/esm/src/observability/trace-sink.d.ts +1 -0
  405. package/esm/src/observability/trace-sink.js +1 -1
  406. package/esm/src/observability/trace-span.d.ts +7 -1
  407. package/esm/src/observability/trace-span.js +3 -1
  408. package/esm/src/observability/trace.d.ts +2 -0
  409. package/esm/src/observability/trace.js +4 -2
  410. package/esm/src/observability/types.d.ts +35 -11
  411. package/esm/src/observability/types.js +1 -1
  412. package/esm/src/presets/google/speech-voices.d.ts +1 -0
  413. package/esm/src/presets/google-limits.d.ts +1 -0
  414. package/esm/src/presets/google.d.ts +27 -12
  415. package/esm/src/presets/google.js +34 -25
  416. package/esm/src/presets/local.d.ts +26 -0
  417. package/esm/src/presets/local.js +30 -0
  418. package/esm/src/presets/mod.d.ts +5 -4
  419. package/esm/src/presets/mod.js +4 -4
  420. package/esm/src/presets/openrouter.d.ts +14 -1
  421. package/esm/src/presets/openrouter.js +19 -1
  422. package/esm/src/providers/embedding-limits.d.ts +7 -0
  423. package/esm/src/providers/embedding-limits.js +12 -0
  424. package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
  425. package/esm/src/providers/gemini/embedding-protocol.js +125 -0
  426. package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
  427. package/esm/src/providers/gemini/interactions-protocol.js +105 -0
  428. package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
  429. package/esm/src/providers/gemini/live-protocol.js +191 -0
  430. package/esm/src/providers/gemini/prices.d.ts +3 -0
  431. package/esm/src/providers/gemini/prices.js +63 -0
  432. package/esm/src/providers/gemini/provider.d.ts +7 -0
  433. package/esm/src/providers/gemini/provider.js +39 -0
  434. package/esm/src/providers/google/builtins.d.ts +14 -0
  435. package/esm/src/providers/google/builtins.js +57 -0
  436. package/esm/src/providers/google/grounding.d.ts +4 -4
  437. package/esm/src/providers/google/interactions/framing.d.ts +20 -8
  438. package/esm/src/providers/google/interactions/framing.js +85 -44
  439. package/esm/src/providers/google/interactions/steps.d.ts +5 -5
  440. package/esm/src/providers/google/interactions/steps.js +4 -4
  441. package/esm/src/providers/google/interactions/stream.d.ts +10 -11
  442. package/esm/src/providers/google/interactions/stream.js +33 -100
  443. package/esm/src/providers/google/live/framing.d.ts +15 -5
  444. package/esm/src/providers/google/live/framing.js +25 -25
  445. package/esm/src/providers/google/live/stream.d.ts +6 -44
  446. package/esm/src/providers/google/live/stream.js +3 -209
  447. package/esm/src/providers/google/urls.d.ts +1 -3
  448. package/esm/src/providers/google/urls.js +1 -3
  449. package/esm/src/providers/google/usage.js +2 -2
  450. package/esm/src/providers/live.d.ts +6 -0
  451. package/esm/src/providers/live.js +6 -0
  452. package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
  453. package/esm/src/providers/local/embedding-protocol.js +60 -0
  454. package/esm/src/providers/local/provider.d.ts +7 -0
  455. package/esm/src/providers/local/provider.js +28 -0
  456. package/esm/src/providers/mod.d.ts +28 -7
  457. package/esm/src/providers/mod.js +19 -3
  458. package/esm/src/providers/open-ai/protocol.d.ts +3 -0
  459. package/esm/src/providers/open-ai/protocol.js +189 -0
  460. package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
  461. package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
  462. package/esm/src/providers/openrouter/image.d.ts +0 -9
  463. package/esm/src/providers/openrouter/image.js +0 -153
  464. package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
  465. package/esm/src/providers/openrouter/images-protocol.js +82 -0
  466. package/esm/src/providers/openrouter/openai/compat.d.ts +2 -2
  467. package/esm/src/providers/openrouter/openai/compat.js +6 -6
  468. package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
  469. package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
  470. package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
  471. package/esm/src/providers/openrouter/protocol.d.ts +8 -0
  472. package/esm/src/providers/openrouter/protocol.js +171 -0
  473. package/esm/src/providers/openrouter/provider.d.ts +10 -0
  474. package/esm/src/providers/openrouter/provider.js +50 -0
  475. package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
  476. package/esm/src/providers/shared/carried-tool-files.js +43 -0
  477. package/esm/src/providers/shared/pcm.js +2 -2
  478. package/esm/src/providers/shared/protocol-events.d.ts +8 -0
  479. package/esm/src/providers/shared/protocol-events.js +20 -0
  480. package/esm/src/providers/shared/response-identity.d.ts +2 -2
  481. package/esm/src/providers/shared/retry.d.ts +17 -0
  482. package/esm/src/providers/shared/retry.js +90 -0
  483. package/esm/src/providers/shared/sse.d.ts +0 -4
  484. package/esm/src/providers/shared/sse.js +50 -36
  485. package/esm/src/providers/shared/tool-args.d.ts +6 -7
  486. package/esm/src/providers/shared/tool-args.js +10 -6
  487. package/esm/src/providers/shared/tool-draft.d.ts +16 -0
  488. package/esm/src/providers/shared/tool-draft.js +14 -0
  489. package/esm/src/providers/shared/upstream-tap.d.ts +2 -2
  490. package/esm/src/providers/shared/upstream-tape.js +1 -1
  491. package/esm/src/providers/system-one/protocol.d.ts +8 -0
  492. package/esm/src/providers/system-one/protocol.js +93 -0
  493. package/esm/src/providers/types.d.ts +48 -16
  494. package/esm/src/providers/types.js +2 -1
  495. package/esm/src/providers/typesafe/provider.d.ts +7 -0
  496. package/esm/src/providers/typesafe/provider.js +24 -0
  497. package/esm/src/surface/formats.d.ts +19 -1
  498. package/esm/src/surface/formats.js +68 -29
  499. package/esm/src/surface/mod.d.ts +4 -2
  500. package/esm/src/surface/mod.js +4 -2
  501. package/esm/src/surface/runtime.d.ts +4 -0
  502. package/esm/src/surface/runtime.js +2 -0
  503. package/esm/src/surface/tools.d.ts +2 -8
  504. package/esm/src/surface/tools.js +4 -22
  505. package/esm/src/surface/types.d.ts +6 -0
  506. package/package.json +5 -13
  507. package/esm/src/cli/commands/egress-compile.d.ts +0 -17
  508. package/esm/src/cli/commands/egress-compile.js +0 -25
  509. package/esm/src/guardrails/egress-policy.d.ts +0 -27
  510. package/esm/src/guardrails/egress-policy.js +0 -76
  511. package/esm/src/guardrails/egress-rules.d.ts +0 -54
  512. package/esm/src/guardrails/egress-rules.js +0 -49
  513. package/esm/src/guardrails/lexicon.d.ts +0 -30
  514. package/esm/src/guardrails/lexicon.js +0 -478
  515. package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
  516. package/esm/src/kernel/engine/media-probe/audio.js +0 -342
  517. package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
  518. package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
  519. package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
  520. package/esm/src/kernel/engine/media-probe/image.js +0 -171
  521. package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
  522. package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
  523. package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
  524. package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
  525. package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
  526. package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
  527. package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
  528. package/esm/src/kernel/engine/media-probe/opus.js +0 -23
  529. package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
  530. package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
  531. package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
  532. package/esm/src/kernel/engine/media-probe/video.js +0 -49
  533. package/esm/src/presets/typesafe.d.ts +0 -2
  534. package/esm/src/presets/typesafe.js +0 -2
  535. package/esm/src/providers/create-provider.d.ts +0 -21
  536. package/esm/src/providers/create-provider.js +0 -90
  537. package/esm/src/providers/decision/usage.d.ts +0 -3
  538. package/esm/src/providers/decision/usage.js +0 -25
  539. package/esm/src/providers/google/interactions/mod.d.ts +0 -2
  540. package/esm/src/providers/google/interactions/mod.js +0 -2
  541. package/esm/src/providers/google/keys.d.ts +0 -20
  542. package/esm/src/providers/google/keys.js +0 -87
  543. package/esm/src/providers/google/live/mod.d.ts +0 -7
  544. package/esm/src/providers/google/live/mod.js +0 -7
  545. package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
  546. package/esm/src/providers/google/live/openapi-schema.js +0 -42
  547. package/esm/src/providers/google/live/session.d.ts +0 -14
  548. package/esm/src/providers/google/live/session.js +0 -150
  549. package/esm/src/providers/local/local.d.ts +0 -12
  550. package/esm/src/providers/local/local.js +0 -186
  551. package/esm/src/providers/local/mod.d.ts +0 -8
  552. package/esm/src/providers/local/mod.js +0 -8
  553. package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
  554. package/esm/src/providers/openrouter/cache-control.js +0 -4
  555. package/esm/src/providers/openrouter/chat.d.ts +0 -64
  556. package/esm/src/providers/openrouter/chat.js +0 -490
  557. package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
  558. package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
  559. package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
  560. package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
  561. package/esm/src/providers/openrouter/speech.d.ts +0 -18
  562. package/esm/src/providers/openrouter/speech.js +0 -109
  563. package/esm/src/providers/probe.d.ts +0 -5
  564. package/esm/src/providers/probe.js +0 -15
  565. package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
  566. package/esm/src/providers/shared/builtin-wire.js +0 -9
  567. package/esm/src/providers/shared/vault.d.ts +0 -13
  568. package/esm/src/providers/shared/vault.js +0 -41
@@ -1,29 +1,32 @@
1
1
  /**
2
- * Thought guarding. A host that renders `thought` events shows the user what
2
+ * Thought guarding, under `guardrails.detect` at `thought`. A host that renders `thought` events shows the user what
3
3
  * they say and loads what they link, as it does a reply: the canary, the
4
4
  * system prompt and the user-data markers leak through a thought, and a URL
5
5
  * the model was not given carries data out. Nothing in a thought stops a turn
6
6
  * (`isGuardedOutput`); each leak is omitted and the rest of the thought
7
- * released.
7
+ * released, or under `block` omitted with the rest of the thought.
8
8
  *
9
9
  * @module
10
10
  */
11
11
  import { CANARY_LEAK_REACH, canaryHoldFrom, canaryLeakRanges, canaryOpeningFrom, createCanaryScanner, promptLeakCarry, RELEASED_LOOKBACK, wordStartAcross, } from './canary.js';
12
- import { CANARY_HIT, egressChecksOf, NO_CHECKS, PROMPT_ECHO_HIT, } from './egress.js';
13
- import { SYSTEM_BOUNDARY } from './egress-patterns.js';
14
- import { createEgressStream } from './egress-stream.js';
12
+ import { detectReads, scopeOf, stronger, } from './detect-at.js';
13
+ import { createDetectStream } from './detect-stream.js';
14
+ import { boundaryNote } from './egress.js';
15
+ import { notePattern, SYSTEM_BOUNDARY } from './egress-patterns.js';
16
+ import { createEgressStream, loadEgressAutomata } from './egress-stream.js';
15
17
  import { imageLeakSpans, linkLeakSpans } from './egress-urls.js';
16
- import { lexiconText } from './lexicon.js';
18
+ import { CANARY_HIT, PROMPT_ECHO_HIT } from './hits.js';
19
+ import { labelText } from './labels.js';
17
20
  import { promptEchoHoldFrom, promptEchoRanges, promptEchoScanFrom } from './prompt-echo.js';
18
- import { EGRESS_RULES } from './rules.js';
21
+ import { DETECT_RULES } from './rules.js';
19
22
  const OMIT_KEYS = {
20
23
  image: 'thought.omitted_image',
21
24
  link: 'thought.omitted_link',
22
25
  instructions: 'thought.omitted_instructions',
23
26
  };
24
- const IMAGE_HIT = { rule: EGRESS_RULES.image, severity: 'high' };
25
- const LINK_HIT = { rule: EGRESS_RULES.link, severity: 'high' };
26
- const BOUNDARY_HIT = { rule: EGRESS_RULES.boundary, severity: 'medium' };
27
+ const IMAGE_HIT = { rule: DETECT_RULES.ungiven_images, severity: 'high' };
28
+ const LINK_HIT = { rule: DETECT_RULES.ungiven_links, severity: 'high' };
29
+ const MARKER_HIT = { rule: DETECT_RULES.marker_leak, severity: 'high' };
27
30
  /** Where `raw`, an offset into `view.text`, stands in the thought: a placeholder's start, or with `end` its end. */
28
31
  function shownAt(view, raw, end = false) {
29
32
  let piece = view.pieces[0];
@@ -38,17 +41,6 @@ function shownAt(view, raw, end = false) {
38
41
  return end ? piece.mark.end : piece.mark.start;
39
42
  return piece.shown + raw - piece.raw;
40
43
  }
41
- /** The checks of `checks` a thought runs: what it would load, and the markers it would show. */
42
- function thoughtChecks(checks) {
43
- if (!(checks.images || checks.links || checks.boundary))
44
- return undefined;
45
- return {
46
- ...NO_CHECKS,
47
- boundary: checks.boundary,
48
- ...(checks.images ? { images: checks.images } : {}),
49
- ...(checks.links ? { links: checks.links } : {}),
50
- };
51
- }
52
44
  /** Sorted, with overlapping leaks as one: an image's URL is a bare link too. */
53
45
  function merged(spans) {
54
46
  const out = [];
@@ -73,15 +65,24 @@ const MAX_LEAKS = 16;
73
65
  * text, is omitted too.
74
66
  */
75
67
  function createThoughtGuard(options) {
76
- const { checks, canary, given, lexicon } = options;
77
- const privateSystem = canary ? options.privateSystem : undefined;
68
+ const { omit = {}, canary, privateSystem, ends, given, labels } = options;
69
+ /** The detectors whose matches the guard omits as the thought streams. */
70
+ const streamed = [
71
+ ...(omit.markers ? ['marker_leak'] : []),
72
+ ...(omit.images ? ['ungiven_images'] : []),
73
+ ...(omit.links ? ['ungiven_links'] : []),
74
+ ];
75
+ const skipImages = omit.imagesRead ?? omit.images !== undefined;
76
+ /** The canary as the echo and the note read it: planted, whether or not a thought is read for it. */
77
+ const slot = canary ?? options.planted;
78
+ const note = boundaryNote({ canary: slot, labels });
78
79
  const scope = (check) => ({ ...check, ...(given ? { given } : {}) });
79
80
  /** The placeholder for `kind` after `before`, without a second space. */
80
81
  function placeholder(kind, before) {
81
- const text = lexiconText(OMIT_KEYS[kind], {}, lexicon);
82
+ const text = labelText(OMIT_KEYS[kind], {}, labels);
82
83
  return /\s$/.test(before) ? text.trimStart() : text;
83
84
  }
84
- let out = canary ? (options.carry ?? '') : '';
85
+ let out = canary || privateSystem ? (options.carry ?? '') : '';
85
86
  let held = '';
86
87
  let stream;
87
88
  let scanner;
@@ -106,7 +107,16 @@ function createThoughtGuard(options) {
106
107
  let hits = new Map();
107
108
  /** Fresh readers over `text`, as if it had streamed: true when it already holds a leak. */
108
109
  function restart(text) {
109
- stream = checks ? createEgressStream({ checks, ...(given ? { given } : {}) }) : undefined;
110
+ stream =
111
+ streamed.length > 0
112
+ ? createEgressStream({
113
+ detect: streamed,
114
+ allow: { ungiven_images: omit.images ?? {}, ungiven_links: omit.links ?? {} },
115
+ skipImages,
116
+ ...(given ? { given } : {}),
117
+ ...(note ? { note } : {}),
118
+ })
119
+ : undefined;
110
120
  scanner = canary ? createCanaryScanner(canary) : undefined;
111
121
  echoed = 0;
112
122
  readTo = 0;
@@ -115,37 +125,41 @@ function createThoughtGuard(options) {
115
125
  /** Read `text`, what follows the read part of `out + held`; true when a leak has settled. */
116
126
  function read(text) {
117
127
  readTo += text.length;
118
- const urlHit = stream?.push(text) !== undefined;
128
+ const urlHit = (stream?.push(text).length ?? 0) > 0;
119
129
  const canaryHit = scanner?.push(text) ?? false;
120
130
  let echoHit = false;
121
131
  if (privateSystem) {
122
132
  const whole = (out + held).slice(0, readTo);
123
133
  const from = promptEchoScanFrom(whole, echoed);
124
- echoHit = promptEchoRanges(whole.slice(from), privateSystem, canary).length > 0;
134
+ echoHit = promptEchoRanges(whole.slice(from), privateSystem, slot).length > 0;
125
135
  echoed = whole.length;
126
136
  }
127
137
  return urlHit || canaryHit || echoHit;
128
138
  }
129
139
  function leakSpans(text) {
130
140
  const spans = [];
131
- if (checks?.images) {
132
- for (const span of imageLeakSpans(text, scope(checks.images))) {
141
+ if (omit.images) {
142
+ for (const span of imageLeakSpans(text, scope(omit.images))) {
133
143
  spans.push({ ...span, kind: 'image', hit: IMAGE_HIT });
134
144
  }
135
145
  }
136
- if (checks?.links) {
137
- for (const span of linkLeakSpans(text, scope(checks.links), checks.images !== undefined)) {
146
+ if (omit.links) {
147
+ for (const span of linkLeakSpans(text, scope(omit.links), skipImages)) {
138
148
  spans.push({ ...span, kind: 'link', hit: LINK_HIT });
139
149
  }
140
150
  }
141
- if (checks?.boundary) {
142
- for (const match of text.matchAll(new RegExp(SYSTEM_BOUNDARY.source, 'gi'))) {
151
+ if (omit.markers) {
152
+ const patterns = [
153
+ new RegExp(SYSTEM_BOUNDARY.source, 'gi'),
154
+ ...(note ? [notePattern(note)] : []),
155
+ ];
156
+ for (const match of patterns.flatMap((pattern) => [...text.matchAll(pattern)])) {
143
157
  const start = match.index;
144
158
  spans.push({
145
159
  start,
146
160
  end: start + match[0].length,
147
161
  kind: 'instructions',
148
- hit: BOUNDARY_HIT,
162
+ hit: MARKER_HIT,
149
163
  });
150
164
  }
151
165
  }
@@ -155,7 +169,7 @@ function createThoughtGuard(options) {
155
169
  }
156
170
  }
157
171
  if (privateSystem) {
158
- for (const [start, end] of promptEchoRanges(text, privateSystem, canary)) {
172
+ for (const [start, end] of promptEchoRanges(text, privateSystem, slot)) {
159
173
  spans.push({ start, end, kind: 'instructions', hit: PROMPT_ECHO_HIT });
160
174
  }
161
175
  }
@@ -222,7 +236,7 @@ function createThoughtGuard(options) {
222
236
  view.text += mark.raw;
223
237
  at = mark.end;
224
238
  }
225
- // An echo run is counted in words: read back until it fits, or the thought starts.
239
+ // why: An echo run is counted in words: read back until it fits, or the thought starts.
226
240
  if (!privateSystem || from === 0 || promptEchoScanFrom(view.text, view.held) > 0)
227
241
  return view;
228
242
  }
@@ -239,7 +253,7 @@ function createThoughtGuard(options) {
239
253
  }
240
254
  }
241
255
  if (privateSystem) {
242
- for (const [start, end] of promptEchoRanges(view.text, privateSystem, canary)) {
256
+ for (const [start, end] of promptEchoRanges(view.text, privateSystem, slot)) {
243
257
  ranges.push([start, end, PROMPT_ECHO_HIT]);
244
258
  }
245
259
  }
@@ -298,16 +312,20 @@ function createThoughtGuard(options) {
298
312
  };
299
313
  for (const { start, end, kind, hit } of closed) {
300
314
  copy(offMark(start));
301
- const to = Math.max(at, offMark(end, true));
315
+ // why: A leak set to `block` takes the rest of the thought with it.
316
+ cut = ends?.has(hit.rule) ?? false;
317
+ const to = cut ? whole.length : Math.max(at, offMark(end, true));
302
318
  const text = placeholder(kind, out + next);
303
319
  const begin = out.length + next.length;
304
320
  kept.push({ start: begin, end: begin + text.length, raw: rawOf(at, to) });
305
321
  next += text;
306
322
  hits.set(hit.rule, hit);
307
323
  at = to;
324
+ if (cut)
325
+ break;
308
326
  }
309
327
  open = undefined;
310
- if (growing) {
328
+ if (growing && !cut) {
311
329
  copy(offMark(growing.start));
312
330
  open = out.length + next.length;
313
331
  }
@@ -346,12 +364,14 @@ function createThoughtGuard(options) {
346
364
  break;
347
365
  const before = new Set(marks.map((mark) => mark.start));
348
366
  if (!omitHeld(false)) {
349
- // A leak the readers settled that no span covers is cut, not shown.
367
+ // why: A leak the readers settled that no span covers is cut, not shown.
350
368
  if (open === undefined)
351
369
  break;
352
370
  return;
353
371
  }
354
- // A leak running on past its placeholder only grows it.
372
+ if (cut)
373
+ return;
374
+ // why: A leak running on past its placeholder only grows it.
355
375
  if (marks.some((mark) => !before.has(mark.start)))
356
376
  leaks++;
357
377
  if (!restart(readable()))
@@ -364,7 +384,7 @@ function createThoughtGuard(options) {
364
384
  const end = out.length + held.length;
365
385
  const url = stream ? stream.holdFrom() : end;
366
386
  const leak = canary ? canaryFrom(canary) : end;
367
- const echo = privateSystem ? out.length + promptEchoHoldFrom(held, privateSystem, canary) : end;
387
+ const echo = privateSystem ? out.length + promptEchoHoldFrom(held, privateSystem, slot) : end;
368
388
  const from = Math.min(url, leak, echo, rawHoldFrom() ?? end, open ?? end);
369
389
  return offMark(from < out.length ? from : out.length + wordStartAcross(held, from - out.length));
370
390
  }
@@ -374,7 +394,6 @@ function createThoughtGuard(options) {
374
394
  const lead = Math.max(0, from - RELEASED_LOOKBACK);
375
395
  let at = lead + canaryOpeningFrom(textFrom(lead), canary);
376
396
  if (at < from && from > out.length) {
377
- // An opening the bound rules out: read the held text whole.
378
397
  const whole = Math.max(0, out.length - RELEASED_LOOKBACK);
379
398
  at = whole + canaryOpeningFrom(textFrom(whole), canary);
380
399
  }
@@ -392,7 +411,7 @@ function createThoughtGuard(options) {
392
411
  return undefined;
393
412
  const rest = view.text.slice(view.held);
394
413
  const leak = canary ? canaryHoldFrom(rest, canary, view.text.slice(0, view.held)) : rest.length;
395
- const echo = privateSystem ? promptEchoHoldFrom(rest, privateSystem, canary) : rest.length;
414
+ const echo = privateSystem ? promptEchoHoldFrom(rest, privateSystem, slot) : rest.length;
396
415
  return shownAt(view, view.held + Math.min(leak, echo));
397
416
  }
398
417
  function release(text) {
@@ -418,15 +437,15 @@ function createThoughtGuard(options) {
418
437
  },
419
438
  flush() {
420
439
  if (!cut) {
421
- for (let round = 0; round < MAX_ROUNDS && omitHeld(true); round++)
440
+ for (let round = 0; round < MAX_ROUNDS && !cut && omitHeld(true); round++)
422
441
  ;
423
- // A leak left is one the text shown already takes part in, such as a definition an image opener held here could use.
424
- if (held && (leakSpans(out + held).length > 0 || rawLeaks().length > 0))
442
+ // why: A leak left is one the text shown already takes part in, such as a definition an image opener held here could use.
443
+ if (!cut && held && (leakSpans(out + held).length > 0 || rawLeaks().length > 0))
425
444
  cutRest();
426
445
  }
427
446
  const shown = held;
428
447
  const whole = out + held;
429
- out = canary ? promptLeakCarry(whole, canary, privateSystem) : '';
448
+ out = canary || privateSystem ? promptLeakCarry(whole, canary, privateSystem) : '';
430
449
  const shift = out.length - whole.length;
431
450
  marks = marks
432
451
  .filter((mark) => mark.start + shift >= 0)
@@ -442,23 +461,204 @@ function createThoughtGuard(options) {
442
461
  carryOut: () => out,
443
462
  };
444
463
  }
464
+ /** What several readers of one stretch of a thought found: every hit, once a rule, at the strongest action. */
465
+ function foundBy(...founds) {
466
+ const all = founds.filter((found) => found !== undefined);
467
+ if (all.length === 0)
468
+ return {};
469
+ return {
470
+ found: {
471
+ action: all.reduce((action, found) => stronger(action, found.action), 'allow'),
472
+ hits: [...new Map(all.flatMap(({ hits }) => hits).map((hit) => [hit.rule, hit])).values()],
473
+ },
474
+ };
475
+ }
445
476
  /**
446
- * A guard for a turn's thoughts: the canary and prompt echo whenever the turn
447
- * binds a canary, and the URL and boundary checks `enforce` runs.
477
+ * `guard` with `guardrails.detect` read at `thought` in front of it: the guard
478
+ * reads the thought as the detectors let it through. A match set to `block`
479
+ * ends what is shown of the thought there. The detectors in `leave` are the
480
+ * guard's own. `guard` unchanged when no other detector reads a thought.
448
481
  */
449
- function thoughtGuardFor(enforce, context, carry) {
450
- const known = egressChecksOf(enforce);
451
- const checks = known ? thoughtChecks(known) : undefined;
452
- const { canary, privateSystem, givenUrls, lexicon } = context;
453
- if (!(checks || canary))
454
- return undefined;
455
- return createThoughtGuard({
456
- ...(checks ? { checks } : {}),
457
- ...(canary ? { canary } : {}),
458
- ...(privateSystem ? { privateSystem } : {}),
482
+ function detectingThoughts(guard, detect, scope, leave) {
483
+ const open = () => createDetectStream('thought', detect, scope, leave);
484
+ let reader = open();
485
+ if (!reader)
486
+ return guard;
487
+ /** How much of the thought has been written, and how much of that released. */
488
+ let written = 0;
489
+ let read = 0;
490
+ let stopped = false;
491
+ /** The text now through the detectors, and what they found in it. */
492
+ function through(ended) {
493
+ if (stopped || !reader)
494
+ return { text: '' };
495
+ const to = ended ? written : Math.max(read, reader.holdFrom());
496
+ const { action, text = '', hits, taken } = reader.take(read, to, ended);
497
+ stopped = action === 'block';
498
+ read += taken;
499
+ return { text, ...(action === 'allow' ? {} : { found: { action, hits } }) };
500
+ }
501
+ return {
502
+ push(text) {
503
+ written += text.length;
504
+ reader?.push(text);
505
+ const { text: clear, found } = through(false);
506
+ const shown = guard ? guard.push(clear) : { text: clear, hits: [] };
507
+ return { text: shown.text, hits: shown.hits, ...foundBy(found, shown.found) };
508
+ },
509
+ flush() {
510
+ const { text: clear, found } = through(true);
511
+ const last = guard?.push(clear);
512
+ const rest = guard ? guard.flush() : { text: clear, hits: [] };
513
+ reader = open();
514
+ written = 0;
515
+ read = 0;
516
+ stopped = false;
517
+ return {
518
+ text: (last?.text ?? '') + rest.text,
519
+ hits: [
520
+ ...new Map([...(last?.hits ?? []), ...rest.hits].map((hit) => [hit.rule, hit])).values(),
521
+ ],
522
+ ...foundBy(found, last?.found, rest.found),
523
+ };
524
+ },
525
+ carryOut: () => guard?.carryOut() ?? '',
526
+ };
527
+ }
528
+ /** The detectors a thought guard omits a match of, and the hit it reports for each. */
529
+ const LEAK_DETECTORS = {
530
+ canary_leak: CANARY_HIT,
531
+ prompt_leak: PROMPT_ECHO_HIT,
532
+ marker_leak: MARKER_HIT,
533
+ ungiven_images: IMAGE_HIT,
534
+ ungiven_links: LINK_HIT,
535
+ };
536
+ /** The detectors among them the guard reads a thought's own text for; the gate has the other two. */
537
+ const TEXT_LEAKS = ['marker_leak', 'ungiven_images', 'ungiven_links'];
538
+ /**
539
+ * Reads a thought for the leaks set to `flag`: each is reported once a thought
540
+ * and the thought shown as written, so nothing is held for it.
541
+ */
542
+ function flaggedLeaks(scope, planted) {
543
+ const { canary, privateSystem } = scope;
544
+ let scanner = canary ? createCanaryScanner(canary) : undefined;
545
+ let seen = '';
546
+ let reported = new Set();
547
+ return {
548
+ read(text) {
549
+ const from = promptEchoScanFrom(seen + text, seen.length);
550
+ seen += text;
551
+ const hits = [];
552
+ if (scanner?.push(text))
553
+ hits.push(CANARY_HIT);
554
+ if (privateSystem && promptEchoRanges(seen.slice(from), privateSystem, planted).length > 0) {
555
+ hits.push(PROMPT_ECHO_HIT);
556
+ }
557
+ const fresh = hits.filter((hit) => !reported.has(hit.rule));
558
+ for (const hit of fresh)
559
+ reported.add(hit.rule);
560
+ return fresh;
561
+ },
562
+ reset() {
563
+ scanner = canary ? createCanaryScanner(canary) : undefined;
564
+ seen = '';
565
+ reported = new Set();
566
+ },
567
+ };
568
+ }
569
+ /**
570
+ * `guard` with what it omitted reported as its detector's finding at `thought`,
571
+ * beside the leaks `flagged` reads for.
572
+ */
573
+ function reportingLeaks(guard, detect, flagged, planted) {
574
+ const flags = flaggedLeaks(flagged, planted);
575
+ const actions = new Map(Object.entries(LEAK_DETECTORS).map(([detector, hit]) => [
576
+ hit.rule,
577
+ detect[detector].thought,
578
+ ]));
579
+ function report(release, noted) {
580
+ const ours = [...noted, ...release.hits.filter((hit) => actions.has(hit.rule))];
581
+ if (ours.length === 0)
582
+ return release;
583
+ const action = ours.reduce((found, hit) => stronger(found, actions.get(hit.rule) ?? 'ignore'), release.found?.action ?? 'allow');
584
+ return {
585
+ text: release.text,
586
+ hits: release.hits.filter((hit) => !actions.has(hit.rule)),
587
+ found: { action, hits: [...(release.found?.hits ?? []), ...ours] },
588
+ };
589
+ }
590
+ return {
591
+ push: (text) => report(guard.push(text), flags.read(text)),
592
+ flush() {
593
+ flags.reset();
594
+ return report(guard.flush(), []);
595
+ },
596
+ carryOut: () => guard.carryOut(),
597
+ };
598
+ }
599
+ /**
600
+ * A guard for a turn's thoughts: the detectors `guardrails.detect` sets at
601
+ * `thought`. `context` carries the canary and the system instruction only
602
+ * while their detectors read somewhere (`leakScopeOf`); at `thought`, `redact`
603
+ * omits a match, `block` ends what is shown of the thought there, and `flag`
604
+ * reports it and shows it.
605
+ */
606
+ async function thoughtGuardFor(policy, context, carry) {
607
+ const { detect } = policy;
608
+ const own = TEXT_LEAKS.filter((detector) => omitsThought(detect, detector));
609
+ const omitted = leakScopeAt(detect, context, omitsThought);
610
+ const flagged = leakScopeAt(detect, context, (set, detector) => set[detector].thought === 'flag');
611
+ const guarded = own.length > 0 || scoped(omitted) || scoped(flagged);
612
+ const scope = scopeOf(policy, context);
613
+ if (guarded || detectReads(['thought'], detect, scope))
614
+ await loadEgressAutomata();
615
+ const guard = guarded
616
+ ? createThoughtGuard({
617
+ omit: thoughtOmits(policy),
618
+ ...omitted,
619
+ ...thoughtEnds(detect),
620
+ ...thoughtTurn(context),
621
+ ...(carry ? { carry } : {}),
622
+ })
623
+ : undefined;
624
+ const leaks = guard && reportingLeaks(guard, detect, flagged, context.canary);
625
+ return detectingThoughts(leaks, detect, scope, own);
626
+ }
627
+ /** Whether `detector` takes its matches out of a thought. */
628
+ function omitsThought(detect, detector) {
629
+ return detect[detector].thought === 'redact' || detect[detector].thought === 'block';
630
+ }
631
+ /** What `guardrails.detect` omits from a thought by its marker, image, and link detectors. */
632
+ function thoughtOmits({ detect, allow, }) {
633
+ return {
634
+ ...(omitsThought(detect, 'marker_leak') ? { markers: true } : {}),
635
+ ...(omitsThought(detect, 'ungiven_images') ? { images: allow.ungiven_images } : {}),
636
+ ...(omitsThought(detect, 'ungiven_links') ? { links: allow.ungiven_links } : {}),
637
+ imagesRead: detect.ungiven_images.thought !== 'ignore',
638
+ };
639
+ }
640
+ /** The canary and the system instruction, each while `applies` to its detector and the turn has it to read. */
641
+ function leakScopeAt(detect, context, applies) {
642
+ const canary = applies(detect, 'canary_leak') && !context.canaryGiven && context.canary;
643
+ const privateSystem = applies(detect, 'prompt_leak') && context.privateSystem;
644
+ return { ...(canary ? { canary } : {}), ...(privateSystem ? { privateSystem } : {}) };
645
+ }
646
+ function scoped(scope) {
647
+ return scope.canary !== undefined || scope.privateSystem !== undefined;
648
+ }
649
+ /** The rules whose match ends what is shown of a thought. */
650
+ function thoughtEnds(detect) {
651
+ const ends = new Set(Object.entries(LEAK_DETECTORS)
652
+ .filter(([detector]) => detect[detector].thought === 'block')
653
+ .map(([, hit]) => hit.rule));
654
+ return ends.size > 0 ? { ends } : {};
655
+ }
656
+ /** What the turn gives a thought guard to read against. */
657
+ function thoughtTurn({ canary, givenUrls, labels, }) {
658
+ return {
659
+ ...(canary ? { planted: canary } : {}),
459
660
  ...(givenUrls ? { given: givenUrls } : {}),
460
- ...(lexicon ? { lexicon } : {}),
461
- ...(carry ? { carry } : {}),
462
- });
661
+ ...(labels ? { labels } : {}),
662
+ };
463
663
  }
464
664
  export { createThoughtGuard, thoughtGuardFor };
@@ -1,19 +1,38 @@
1
- import type { AdvisoryLevel, GuardrailHit } from './types.js';
1
+ import type { AdvisoryLevel } from './types.js';
2
+ /**
3
+ * What of a tool's text reads as an instruction to the agent: an order to set its instructions
4
+ * aside, the name of a tool it can call, an order, or a claim of authority. The last three count
5
+ * only beside a destination.
6
+ */
7
+ declare const DIRECTIVE_SIGNALS: readonly ["override", "tool_name", "order", "authority"];
8
+ /** One of {@linkcode DIRECTIVE_SIGNALS}. */
9
+ type DirectiveSignal = (typeof DIRECTIVE_SIGNALS)[number];
10
+ /** A stretch of a tool's text that instructs the agent, and what about it does. */
11
+ interface Directive {
12
+ signal: DirectiveSignal;
13
+ start: number;
14
+ end: number;
15
+ }
16
+ /** One range for each run of overlapping `ranges`, in order. */
17
+ declare function mergedRanges(ranges: readonly [number, number][]): [number, number][];
2
18
  /**
3
19
  * Real indirect injection rarely names what it attacks, so this looks for content that behaves
4
- * like an instruction. Hits raise the turn's taint rather than rewriting the text: a page
5
- * documenting an email API legitimately says "call send_email", and being wrong should cost a
6
- * refused write, not silently damaged input.
20
+ * like an instruction: each order, claim of authority, tool name, and destination, where it sits
21
+ * in `text`. A page documenting an email API legitimately says "call send_email", so the
22
+ * detector that reads with this (`tool_instructions`) starts at `flag`.
7
23
  *
8
24
  * `callableTools` is the set the model can invoke this turn. A result naming one is the
9
25
  * highest-precision signal: ordinary data has no reason to, and no generic filter can check it
10
26
  * without the turn's registry.
27
+ *
28
+ * The text is read normalized. Where that changes it, each signal found is placed on the
29
+ * stretch of `text` it was read from (`normalizedView`).
11
30
  */
12
- declare function directiveHits(text: string, callableTools?: readonly string[]): GuardrailHit[];
13
- declare function looksDirective(hits: GuardrailHit[]): boolean;
31
+ declare function directives(text: string, callableTools?: readonly string[]): Directive[];
14
32
  /**
15
- * Naming a tool the model can call is the sharpest signal available, so it alone
16
- * reaches `high`; so does agreement between two different signal kinds.
33
+ * How strongly a tool's text reads as instructions, by the `signals` found in it: `high` for an
34
+ * order to drop instructions, a callable tool's name, or two signals together.
17
35
  */
18
- declare function advisoryLevel(hits: GuardrailHit[]): AdvisoryLevel;
19
- export { advisoryLevel, directiveHits, looksDirective };
36
+ declare function advisoryLevel(signals: readonly (string | undefined)[]): AdvisoryLevel;
37
+ export type { Directive, DirectiveSignal };
38
+ export { advisoryLevel, DIRECTIVE_SIGNALS, directives, mergedRanges };