@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,33 +1,55 @@
1
1
  /**
2
- * Build-time compiler for egress rules, behind `@theoremjs/agents/guardrails/compile`.
2
+ * Build-time compiler for a host's patterns, behind `@theoremjs/agents/guardrails/compile`.
3
3
  *
4
- * The streaming egress hold reads each pattern as an automaton that accepts
4
+ * The streaming hold reads each pattern as an automaton that accepts
5
5
  * every match of it and more, so it can hold exactly the text a match could
6
6
  * still be under way in. Building those automata takes a regex engine (refa)
7
7
  * and time a Worker cold start cannot spare, so it runs here, at build time:
8
- * `agents egress-compile` writes the table, and `egressPolicy` loads it.
8
+ * `agents detect-compile` writes the tables, and `guardrails.detect` loads them.
9
9
  *
10
- * An automaton drops its pattern's assertions: a lookbehind, `\b`, `^` and `$`
11
- * match nothing, and a lookahead may be read or skipped. A bounded repeat over
12
- * `COUNT_LIMIT` is unbounded. An inline modifier's flags are set on the whole
13
- * pattern. Each change only widens what it accepts, so the hold can only hold
14
- * more than it must. A backreference to text that varies has no automaton;
10
+ * An automaton drops its pattern's assertions: a lookbehind, `\b`, `^`, and `$`
11
+ * match nothing, and a lookahead is skipped, with its text read after what
12
+ * precedes it wherever the match may end before that text does. A bounded
13
+ * repeat over `COUNT_LIMIT` is unbounded. An optional repeat of one character
14
+ * class that opens the pattern is left out and its class named in `leads`:
15
+ * the stream reads a match as starting where the run of that class it is in
16
+ * started. An inline modifier's flags are set on the whole pattern. Each
17
+ * change only widens what it accepts, so the hold can only hold more than it
18
+ * must. A backreference to text that varies has no automaton;
15
19
  * compiling it fails.
16
20
  *
17
21
  * @module
18
22
  */
19
- import { type CompiledEgressRules, type EgressAutomatonData, type EgressRule } from './egress-rules.js';
20
- /** The table `egressPolicy` needs to hold exactly for `rules`. */
21
- declare function compileEgressRules(rules: readonly EgressRule[]): CompiledEgressRules;
22
- /** `compiled` as a module exporting it as `compiledEgressRules`. */
23
- declare function compiledEgressModule(compiled: CompiledEgressRules): string;
23
+ import type { DetectSpec } from './detectors.js';
24
+ import { type AutomatonData, type CompiledPatterns, type HostPattern } from './host-patterns.js';
25
+ /**
26
+ * What makes `source` slow on hostile text, or `undefined`. A source that does not parse is
27
+ * not this check's to report: whatever reads it says so.
28
+ */
29
+ declare function slowPatternProblem(source: string, flags?: string): string | undefined;
30
+ /**
31
+ * The table a detector needs for the host's `patterns`: each checked, and their automaton. A
32
+ * pattern is refused when it does not compile, matches the empty text, is sticky, could hang
33
+ * or get slow on long text (`slowProblem`), or has no automaton the stream can hold by (a
34
+ * backreference to text that varies).
35
+ */
36
+ declare function compilePatterns(patterns: readonly HostPattern[]): CompiledPatterns;
37
+ /**
38
+ * `detect` with the table compiled for every detector's `patterns`, for a host that compiles as
39
+ * it starts in place of `agents detect-compile` at build time. A table already set is replaced.
40
+ */
41
+ declare function compileDetect<Spec extends DetectSpec>(detect: Spec): Spec;
42
+ /** The table for each detector `detect` gives patterns, by detector. */
43
+ declare function compileDetectTables(detect: DetectSpec): Record<string, CompiledPatterns>;
44
+ /** `tables` as a module exporting them as `compiledDetect`, each to set as its detector's `compiled`. */
45
+ declare function compiledDetectModule(tables: Record<string, CompiledPatterns>): string;
24
46
  /**
25
47
  * Everything `egress-automata.ts` holds, from the bundled patterns as they are
26
48
  * now: the injection patterns reversed, and the forward and reversed automata.
27
49
  */
28
50
  declare function bundledEgressAutomata(): {
29
51
  reversedPatterns: RegExp[];
30
- forward: EgressAutomatonData;
31
- reversed: EgressAutomatonData;
52
+ forward: AutomatonData;
53
+ reversed: AutomatonData;
32
54
  };
33
- export { bundledEgressAutomata, compiledEgressModule, compileEgressRules };
55
+ export { bundledEgressAutomata, compileDetect, compileDetectTables, compiledDetectModule, compilePatterns, slowPatternProblem, };
@@ -1,26 +1,31 @@
1
1
  /**
2
- * Build-time compiler for egress rules, behind `@theoremjs/agents/guardrails/compile`.
2
+ * Build-time compiler for a host's patterns, behind `@theoremjs/agents/guardrails/compile`.
3
3
  *
4
- * The streaming egress hold reads each pattern as an automaton that accepts
4
+ * The streaming hold reads each pattern as an automaton that accepts
5
5
  * every match of it and more, so it can hold exactly the text a match could
6
6
  * still be under way in. Building those automata takes a regex engine (refa)
7
7
  * and time a Worker cold start cannot spare, so it runs here, at build time:
8
- * `agents egress-compile` writes the table, and `egressPolicy` loads it.
8
+ * `agents detect-compile` writes the tables, and `guardrails.detect` loads them.
9
9
  *
10
- * An automaton drops its pattern's assertions: a lookbehind, `\b`, `^` and `$`
11
- * match nothing, and a lookahead may be read or skipped. A bounded repeat over
12
- * `COUNT_LIMIT` is unbounded. An inline modifier's flags are set on the whole
13
- * pattern. Each change only widens what it accepts, so the hold can only hold
14
- * more than it must. A backreference to text that varies has no automaton;
10
+ * An automaton drops its pattern's assertions: a lookbehind, `\b`, `^`, and `$`
11
+ * match nothing, and a lookahead is skipped, with its text read after what
12
+ * precedes it wherever the match may end before that text does. A bounded
13
+ * repeat over `COUNT_LIMIT` is unbounded. An optional repeat of one character
14
+ * class that opens the pattern is left out and its class named in `leads`:
15
+ * the stream reads a match as starting where the run of that class it is in
16
+ * started. An inline modifier's flags are set on the whole pattern. Each
17
+ * change only widens what it accepts, so the hold can only hold more than it
18
+ * must. A backreference to text that varies has no automaton;
15
19
  * compiling it fails.
16
20
  *
17
21
  * @module
18
22
  */
19
23
  import { RegExpParser, visitRegExpAST } from '@eslint-community/regexpp';
20
24
  import { JS, NFA } from 'refa';
25
+ import { analyse } from 'scslre';
21
26
  import { EGRESS_PATTERNS } from './egress-patterns.js';
22
- import { assertEgressRules, EGRESS_COMPILER_VERSION, ruleFingerprint, } from './egress-rules.js';
23
27
  import { TheoremError } from './error.js';
28
+ import { MAX_PATTERNS, PATTERN_COMPILER_VERSION, patternProblem, patternSources, } from './host-patterns.js';
24
29
  const MAX_CHAR = 0xffff;
25
30
  /**
26
31
  * A bounded repeat longer than this is read as unbounded: the hold cannot
@@ -48,49 +53,96 @@ function reversedElement(element) {
48
53
  case 'CharacterClass':
49
54
  return element;
50
55
  default:
51
- // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
56
+ // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
52
57
  throw new Error(`cannot reverse a ${element.type} element`);
53
58
  }
54
59
  }
55
60
  /**
56
- * The pattern with its assertions loosened: a lookbehind (and `\b`, `^`, `$`,
57
- * which parse to lookarounds) matches the empty string, a lookahead is either
58
- * skipped or read as part of the match, and a long bounded repeat is unbounded.
61
+ * The pattern with its assertions loosened and a long bounded repeat
62
+ * unbounded. A lookbehind (and `\b`, `^`, `$`, which parse to lookarounds)
63
+ * matches the empty string. A lookahead:
64
+ *
65
+ * - no longer than what must follow it is skipped: the match has read its text;
66
+ * - with nothing after it is read or skipped;
67
+ * - otherwise is skipped, and what precedes it followed by its text is an
68
+ * alternative of the pattern (in `ends`), so the automaton is still under
69
+ * way, and then at a match, while the text that settles it arrives.
59
70
  */
60
- function loosened(alternatives) {
61
- return alternatives.map((concat) => ({
62
- type: 'Concatenation',
63
- elements: concat.elements.flatMap(loosenedElement),
64
- }));
71
+ function loosened(alternatives, after, ends) {
72
+ return alternatives.map((concat) => {
73
+ const elements = [];
74
+ concat.elements.forEach((element, i) => {
75
+ const rest = lengthOf(concat.elements.slice(i + 1));
76
+ elements.push(...loosenedElement(element, { min: after.min + rest.min, max: after.max + rest.max }, ends && { before: [...ends.before, ...elements], out: ends.out }));
77
+ });
78
+ return { type: 'Concatenation', elements };
79
+ });
65
80
  }
66
- function loosenedElement(element) {
81
+ /** The fewest and the most characters a match of the elements, one after another, reads. */
82
+ function lengthOf(elements) {
83
+ let min = 0;
84
+ let max = 0;
85
+ for (const element of elements) {
86
+ if (element.type === 'Assertion')
87
+ continue;
88
+ if (element.type === 'CharacterClass') {
89
+ min++;
90
+ max++;
91
+ continue;
92
+ }
93
+ if (element.type === 'Unknown') {
94
+ max = Number.POSITIVE_INFINITY;
95
+ continue;
96
+ }
97
+ const each = element.alternatives.map((concat) => lengthOf(concat.elements));
98
+ const times = element.type === 'Quantifier' ? element : { min: 1, max: 1 };
99
+ const most = Math.max(...each.map((length) => length.max));
100
+ min += times.min * Math.min(...each.map((length) => length.min));
101
+ max += most === 0 ? 0 : times.max * most;
102
+ }
103
+ return { min, max };
104
+ }
105
+ /** `element` loosened, where `after` characters follow it in a match. */
106
+ function loosenedElement(element, after, ends) {
67
107
  switch (element.type) {
68
108
  case 'Alternation':
69
- return [{ ...element, alternatives: loosened(element.alternatives) }];
70
- case 'Quantifier':
71
- return [
72
- {
73
- ...element,
74
- max: element.max > COUNT_LIMIT ? Number.POSITIVE_INFINITY : element.max,
75
- alternatives: loosened(element.alternatives),
76
- },
77
- ];
78
- case 'Assertion':
109
+ return [{ ...element, alternatives: loosened(element.alternatives, after, ends) }];
110
+ case 'Quantifier': {
111
+ const max = element.max > COUNT_LIMIT ? Number.POSITIVE_INFINITY : element.max;
112
+ const inside = max > 1 ? { min: after.min, max: Number.POSITIVE_INFINITY } : after;
113
+ const repeat = { ...element, max, alternatives: loosened(element.alternatives, inside) };
114
+ if (ends) {
115
+ const earlier = { ...repeat, min: 0, max: Number.POSITIVE_INFINITY };
116
+ loosened(element.alternatives, inside, {
117
+ before: max > 1 ? [...ends.before, earlier] : ends.before,
118
+ out: ends.out,
119
+ });
120
+ }
121
+ return [repeat];
122
+ }
123
+ case 'Assertion': {
79
124
  if (element.kind === 'behind')
80
125
  return [];
126
+ const text = loosened(element.alternatives, { min: 0, max: 0 }, ends);
127
+ const { max } = lengthOf([{ type: 'Alternation', alternatives: text }]);
128
+ if (max <= after.min)
129
+ return [];
130
+ const read = { type: 'Alternation', alternatives: text };
131
+ if (after.max > 0) {
132
+ ends?.out.push({ type: 'Concatenation', elements: [...ends.before, read] });
133
+ return [];
134
+ }
81
135
  return [
82
136
  {
83
137
  type: 'Alternation',
84
- alternatives: [
85
- { type: 'Concatenation', elements: [] },
86
- ...loosened(element.alternatives),
87
- ],
138
+ alternatives: [{ type: 'Concatenation', elements: [] }, ...text],
88
139
  },
89
140
  ];
141
+ }
90
142
  case 'CharacterClass':
91
143
  return [element];
92
144
  default:
93
- // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
145
+ // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
94
146
  throw new Error(`cannot loosen a ${element.type} element`);
95
147
  }
96
148
  }
@@ -122,30 +174,98 @@ function parsed(pattern) {
122
174
  const units = JS.toLiteral(expression, { flags: { unicode: false, unicodeSets: false } });
123
175
  return JS.Parser.fromLiteral(units).parse({ assertions: 'parse' }).expression.alternatives;
124
176
  }
177
+ /**
178
+ * The pattern's source spelled so no lint rule has anything to say about it: `[\s\S]` for any
179
+ * character (not `[^]`) and `\v` for the vertical tab (not `\x0b`). Each pair matches the same text.
180
+ */
181
+ function plainSource(source) {
182
+ let out = '';
183
+ let inClass = false;
184
+ for (let i = 0; i < source.length; i++) {
185
+ const char = source[i];
186
+ if (char === '\\') {
187
+ const next = source.slice(i, i + 4);
188
+ if (next === '\\x0b') {
189
+ out += '\\v';
190
+ i += 3;
191
+ }
192
+ else {
193
+ out += source.slice(i, i + 2);
194
+ i++;
195
+ }
196
+ }
197
+ else if (!inClass && source.startsWith('[^]', i)) {
198
+ out += '[\\s\\S]';
199
+ i += 2;
200
+ }
201
+ else {
202
+ if (char === '[')
203
+ inClass = true;
204
+ else if (char === ']')
205
+ inClass = false;
206
+ out += char;
207
+ }
208
+ }
209
+ return out;
210
+ }
125
211
  /** A regex literal for the reversed pattern, with the original's flags. */
126
212
  function reversedLiteral(pattern) {
127
213
  const literal = JS.toLiteral(reversed(parsed(pattern)), {
128
214
  flags: { global: true, unicode: false, sticky: false },
129
215
  });
130
- return new RegExp(literal.source, literal.flags);
216
+ return new RegExp(plainSource(literal.source), literal.flags);
217
+ }
218
+ /**
219
+ * The pattern split at an optional repeat of one character class that opens
220
+ * it: the class, and the rest. Counted in the automaton, the repeat would keep
221
+ * a state per repeat alive at every character of a run of the class.
222
+ */
223
+ function led(alternatives) {
224
+ const [concat] = alternatives;
225
+ if (alternatives.length !== 1 || !concat)
226
+ return { rest: alternatives };
227
+ const [first, ...after] = concat.elements;
228
+ if (first?.type === 'Alternation' && first.alternatives.length === 1) {
229
+ const [inner] = first.alternatives;
230
+ return led([{ type: 'Concatenation', elements: [...(inner?.elements ?? []), ...after] }]);
231
+ }
232
+ if (first?.type !== 'Quantifier' || first.min !== 0 || first.max < 2) {
233
+ return { rest: alternatives };
234
+ }
235
+ const [repeated] = first.alternatives;
236
+ const [only] = repeated?.elements ?? [];
237
+ if (first.alternatives.length !== 1 || repeated?.elements.length !== 1) {
238
+ return { rest: alternatives };
239
+ }
240
+ return only?.type === 'CharacterClass'
241
+ ? { lead: only.characters, rest: [{ type: 'Concatenation', elements: after }] }
242
+ : { rest: alternatives };
131
243
  }
132
244
  function nfaOf(alternatives) {
133
- const nfa = NFA.fromRegex(loosened(alternatives), { maxCharacter: MAX_CHAR });
134
- nfa.removeUnreachable();
135
- return { initial: nfa.initial, nodes: [...nfa.nodes()], finals: nfa.finals };
245
+ const ends = [];
246
+ const whole = [...loosened(alternatives, { min: 0, max: 0 }, { before: [], out: ends }), ...ends];
247
+ const { lead, rest } = led(whole);
248
+ const build = (from) => {
249
+ const nfa = NFA.fromRegex(from, { maxCharacter: MAX_CHAR });
250
+ nfa.removeUnreachable();
251
+ return { initial: nfa.initial, nodes: [...nfa.nodes()], finals: nfa.finals };
252
+ };
253
+ const nfa = build(rest);
254
+ if (!lead)
255
+ return nfa;
256
+ return nfa.finals.has(nfa.initial) ? build(whole) : { ...nfa, lead };
136
257
  }
137
258
  /** The union of the patterns' automata as tables, nodes tagged with their pattern. */
138
259
  function automatonData(patterns) {
139
260
  const nfas = patterns.map(nfaOf);
140
261
  const bounds = new Set([0]);
141
262
  for (const nfa of nfas) {
142
- for (const node of nfa.nodes) {
143
- for (const set of node.out.values()) {
144
- for (const range of set.ranges) {
145
- bounds.add(range.min);
146
- if (range.max < MAX_CHAR)
147
- bounds.add(range.max + 1);
148
- }
263
+ const sets = nfa.nodes.flatMap((node) => [...node.out.values()]);
264
+ for (const set of nfa.lead ? [...sets, nfa.lead] : sets) {
265
+ for (const range of set.ranges) {
266
+ bounds.add(range.min);
267
+ if (range.max < MAX_CHAR)
268
+ bounds.add(range.max + 1);
149
269
  }
150
270
  }
151
271
  }
@@ -194,32 +314,106 @@ function automatonData(patterns) {
194
314
  nodes.push(row);
195
315
  }
196
316
  });
197
- return { classStarts, charsets, initials, nodes };
317
+ const leads = nfas.map(({ lead }) => (lead ? charsetId(lead.ranges) : -1));
318
+ return { classStarts, charsets, initials, leads, nodes };
319
+ }
320
+ function patternError(message) {
321
+ return new TheoremError('config', `compilePatterns: ${message}`);
322
+ }
323
+ /**
324
+ * Why `pattern` could take far longer than the text is long, or `undefined`: a repeat that
325
+ * matches the same text in more than one way, or one the engine reads again from every position.
326
+ */
327
+ function slowProblem(pattern) {
328
+ const [report] = analyse(pattern, { maxReports: 1 }).reports;
329
+ if (!report)
330
+ return undefined;
331
+ const repeat = report.type === 'Trade' ? report.startQuant.raw : report.quant.raw;
332
+ // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
333
+ return report.type === 'Move'
334
+ ? `gets slow on long text: its time grows with the square of the text. Bound the repeat ${repeat} ({1,64} in place of + or *)`
335
+ : `can hang on text that nearly matches: the repeat ${repeat} matches the same text in more than one way. Bound it ({1,64} in place of + or *) or make its parts unable to overlap`;
336
+ }
337
+ /**
338
+ * What makes `source` slow on hostile text, or `undefined`. A source that does not parse is
339
+ * not this check's to report: whatever reads it says so.
340
+ */
341
+ function slowPatternProblem(source, flags = '') {
342
+ let regex;
343
+ try {
344
+ regex = new RegExp(source, flags);
345
+ }
346
+ catch {
347
+ return undefined;
348
+ }
349
+ return slowProblem(regex);
198
350
  }
199
- /** The table `egressPolicy` needs to hold exactly for `rules`. */
200
- function compileEgressRules(rules) {
201
- assertEgressRules(rules);
202
- const alternatives = rules.map(({ rule, pattern }) => {
351
+ /**
352
+ * The table a detector needs for the host's `patterns`: each checked, and their automaton. A
353
+ * pattern is refused when it does not compile, matches the empty text, is sticky, could hang
354
+ * or get slow on long text (`slowProblem`), or has no automaton the stream can hold by (a
355
+ * backreference to text that varies).
356
+ */
357
+ function compilePatterns(patterns) {
358
+ if (patterns.length > MAX_PATTERNS) {
359
+ throw patternError(`${patterns.length} patterns; a detector takes at most ${MAX_PATTERNS}`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
360
+ }
361
+ patterns.forEach((pattern, index) => {
362
+ const problem = patternProblem(`patterns[${index}]`, pattern);
363
+ if (problem !== undefined)
364
+ throw patternError(problem);
365
+ });
366
+ const sources = patternSources(patterns);
367
+ const alternatives = sources.map(({ name, source, flags }) => {
368
+ const slow = slowProblem(new RegExp(source, flags));
369
+ if (slow !== undefined)
370
+ throw patternError(`${name}: /${source}/${flags} ${slow}`);
203
371
  try {
204
- const units = parsed(pattern);
372
+ const units = parsed(new RegExp(source, flags));
205
373
  nfaOf(units);
206
374
  return units;
207
375
  }
208
376
  catch (err) {
209
- throw new TheoremError('config', `egress rule ${rule}: ${pattern} has no automaton the stream can hold for (${err instanceof Error ? err.message : String(err)})`);
377
+ throw patternError(`${name}: /${source}/${flags} has no automaton the stream can hold for (${err instanceof Error ? err.message : String(err)})`);
210
378
  }
211
379
  });
212
380
  return {
213
- compiler: EGRESS_COMPILER_VERSION,
214
- rules: ruleFingerprint(rules),
381
+ compiler: PATTERN_COMPILER_VERSION,
382
+ patterns: sources,
215
383
  automaton: automatonData(alternatives),
216
384
  };
217
385
  }
218
- /** `compiled` as a module exporting it as `compiledEgressRules`. */
219
- function compiledEgressModule(compiled) {
220
- // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
221
- return `// Generated by \`agents egress-compile\`. Do not edit: change the rules and compile again.
222
- export const compiledEgressRules = ${JSON.stringify(compiled)};
386
+ /**
387
+ * `detect` with the table compiled for every detector's `patterns`, for a host that compiles as
388
+ * it starts in place of `agents detect-compile` at build time. A table already set is replaced.
389
+ */
390
+ function compileDetect(detect) {
391
+ if (typeof detect === 'string')
392
+ return detect;
393
+ const tables = compileDetectTables(detect);
394
+ const rules = Object.entries(detect).map(([detector, rule]) => {
395
+ const compiled = tables[detector];
396
+ return [detector, compiled && typeof rule !== 'string' ? { ...rule, compiled } : rule];
397
+ });
398
+ return Object.fromEntries(rules);
399
+ }
400
+ /** The table for each detector `detect` gives patterns, by detector. */
401
+ function compileDetectTables(detect) {
402
+ if (typeof detect === 'string')
403
+ return {};
404
+ const tables = {};
405
+ for (const [detector, rule] of Object.entries(detect)) {
406
+ if (typeof rule === 'string' || !rule.patterns?.length)
407
+ continue;
408
+ tables[detector] = compilePatterns(rule.patterns);
409
+ }
410
+ return tables;
411
+ }
412
+ /** `tables` as a module exporting them as `compiledDetect`, each to set as its detector's `compiled`. */
413
+ function compiledDetectModule(tables) {
414
+ // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
415
+ return `// Generated by \`agents detect-compile\`. Do not edit: change the patterns and compile again.
416
+ export const compiledDetect = ${JSON.stringify(tables)};
223
417
  `;
224
418
  }
225
419
  /**
@@ -234,4 +428,4 @@ function bundledEgressAutomata() {
234
428
  reversed: automatonData(injection.map(({ pattern }) => reversed(parsed(pattern)))),
235
429
  };
236
430
  }
237
- export { bundledEgressAutomata, compiledEgressModule, compileEgressRules };
431
+ export { bundledEgressAutomata, compileDetect, compileDetectTables, compiledDetectModule, compilePatterns, slowPatternProblem, };
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @module
7
7
  */
8
- import { type SensitiveGroup } from './sensitive.js';
8
+ import type { SensitiveGroup } from './sensitive-groups.js';
9
9
  declare const SYSTEM_BOUNDARY: RegExp;
10
10
  /** What a match of the pattern means: the rule it trips, or the blob its filter decodes. */
11
11
  type EgressPatternKind = 'injection' | 'sensitive' | 'card' | 'boundary' | 'base64' | 'hex' | 'spaced' | 'pipe' | 'image' | 'link';
@@ -20,5 +20,7 @@ interface EgressPattern {
20
20
  * the rewritten views (typo, Unicode, rot13, leet, URL) match those alone.
21
21
  */
22
22
  declare const EGRESS_PATTERNS: readonly EgressPattern[];
23
+ /** A reply repeating `note`, a canary note's own words (`canaryNoteMarker`), as written, case aside. */
24
+ declare function notePattern(note: string): RegExp;
23
25
  export type { EgressPattern, EgressPatternKind };
24
- export { EGRESS_PATTERNS, SYSTEM_BOUNDARY };
26
+ export { EGRESS_PATTERNS, notePattern, SYSTEM_BOUNDARY };
@@ -8,7 +8,7 @@
8
8
  import { IMAGE_PATTERNS, LINK_PATTERNS } from './egress-urls.js';
9
9
  import { BASE64_BLOB, HEX_BLOB, INJECTION_PATTERNS, PIPE_SEPARATED, SPACED_LETTERS, } from './injection-patterns.js';
10
10
  import { CARD_CANDIDATE, SENSITIVE_PATTERNS } from './sensitive.js';
11
- const SYSTEM_BOUNDARY = /This turn\x27s canary is|<\s*(?:\/\s*)?user_data(?:\s*(?:\/\s*)?>)?/i; // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
11
+ const SYSTEM_BOUNDARY = /This turn\x27s canary is|Your canary token is|<\s*(?:\/\s*)?user_data(?:\s*(?:\/\s*)?>)?/i; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
12
12
  /**
13
13
  * Patterns matched on the reply as written. The injection patterns come first:
14
14
  * the rewritten views (typo, Unicode, rot13, leet, URL) match those alone.
@@ -29,4 +29,8 @@ const EGRESS_PATTERNS = [
29
29
  ...IMAGE_PATTERNS.map((pattern) => ({ kind: 'image', pattern })),
30
30
  ...LINK_PATTERNS.map((pattern) => ({ kind: 'link', pattern })),
31
31
  ];
32
- export { EGRESS_PATTERNS, SYSTEM_BOUNDARY };
32
+ /** A reply repeating `note`, a canary note's own words (`canaryNoteMarker`), as written, case aside. */
33
+ function notePattern(note) {
34
+ return new RegExp(note.replace(/[\\^$.*+?()[\]{}|/-]/g, '\\$&'), 'gi');
35
+ }
36
+ export { EGRESS_PATTERNS, notePattern, SYSTEM_BOUNDARY };
@@ -1,7 +1,7 @@
1
1
  /**
2
- * The bundled egress policy, run on a reply as it streams.
2
+ * The detectors, Theorem's and the host's own, run on a reply as it streams.
3
3
  *
4
- * The bundled checks match their patterns on the reply as written and, for
4
+ * Each matches its patterns on the reply as written and, for
5
5
  * injection phrasing, on
6
6
  * rewrites of it (typo-folded, Unicode-folded, rot13, leet, URL-decoded, read
7
7
  * backwards). The stream keeps each rewrite growing with the reply and, for
@@ -11,29 +11,40 @@
11
11
  * later starts at or after that place, so none of it has been released.
12
12
  *
13
13
  * A match whose outcome no later text can change is settled; a settled match
14
- * of the pattern itself (not the automaton) is a hit, and the reply is
15
- * blocked there. Each character is read a bounded number of times, so a long
16
- * reply costs time in proportion to its length.
14
+ * of the pattern itself (not the automaton) is a hit, and does what
15
+ * `guardrails.detect` sets (`detect-stream.ts`). Each character is read a bounded number of times, so a
16
+ * long reply costs time in proportion to its length.
17
17
  *
18
18
  * @module
19
19
  */
20
- import { type ResolvedEgressChecks } from './egress.js';
21
- import { type EgressAutomatonData } from './egress-rules.js';
20
+ import type { Detector, ResolvedAllow } from './detectors.js';
22
21
  import { type GivenUrls } from './egress-urls.js';
23
- import type { EgressEnforcer, GuardrailContext, Severity } from './types.js';
24
- /** A settled match the policy blocks on. */
22
+ import type { CompiledPatterns, HostMatcher } from './host-patterns.js';
23
+ import { type OwnTools } from './tool-leak.js';
24
+ import type { Severity } from './types.js';
25
+ /** A settled match. */
25
26
  interface EgressStreamHit {
26
27
  rule: string;
27
28
  severity: Severity;
28
29
  /** Where in the reply the match starts (the start of its rewrite's source). */
29
30
  start: number;
31
+ /** The detector whose match it is, or the id of the host's own. */
32
+ detector: string;
30
33
  }
31
34
  interface EgressStream {
32
- /** Read the next piece of the reply; a hit when a match has settled. */
33
- push: (chunk: string) => EgressStreamHit | undefined;
35
+ /**
36
+ * Read the next piece of the reply; the matches that settled, none when the reply is clear so
37
+ * far.
38
+ */
39
+ push: (chunk: string) => EgressStreamHit[];
34
40
  /** The earliest index of the reply a match could still start at. */
35
41
  holdFrom: () => number;
36
42
  }
43
+ /**
44
+ * Reads Theorem's automata, the most of the kernel's size, the first time a stream needs them.
45
+ * Every gate's constructor waits for this, so an app that never streams a reply never loads them.
46
+ */
47
+ declare function loadEgressAutomata(): Promise<void>;
37
48
  /**
38
49
  * Text grown at its end, with what its latest update added. Reading a grown
39
50
  * string copies the whole of it, so what reads each new character reads it
@@ -55,9 +66,11 @@ interface View extends Grown {
55
66
  update: () => void;
56
67
  }
57
68
  /**
58
- * `typoNormalize` of the source. It rewrites whole words (`\w` runs) of the
59
- * same length, so a word settles when a non-word character ends it, or as soon
60
- * as it can no longer fold to a target (then the rest of it passes as is).
69
+ * `typoNormalize` of the source. It rewrites whole words (`\w` runs), so a
70
+ * word settles when a non-word character ends it, or as soon as it can no
71
+ * longer fold to a target (then the rest of it passes as is). A corrected word
72
+ * may be a letter longer or shorter than the word as written, so each
73
+ * character keeps the source index it stands for.
61
74
  */
62
75
  declare function typoView(source: View): View;
63
76
  /** A rewrite whose characters keep their own reply index. */
@@ -71,7 +84,7 @@ interface MappedView extends View {
71
84
  * or in the mapped text), an emoji run after a letter until the character
72
85
  * after it, a backslash until the character after it.
73
86
  */
74
- declare function normalizedView(reply: Grown): MappedView;
87
+ declare function normalizedReplyView(reply: Grown): MappedView;
75
88
  /**
76
89
  * `decodeUrlRuns` of the reply: a run of `%XX` escapes is unsettled until the
77
90
  * character after it shows the run is over. Its decoded text holds from the
@@ -79,27 +92,32 @@ declare function normalizedView(reply: Grown): MappedView;
79
92
  */
80
93
  declare function urlView(reply: Grown): MappedView;
81
94
  interface EgressStreamOptions {
82
- /** The bundled checks to run. Default each at its default (`EgressChecks`). */
83
- checks?: ResolvedEgressChecks;
84
- /** Host rules, read on the reply as written, with their compiled automaton. */
85
- host?: {
86
- automaton: EgressAutomatonData;
87
- rules: readonly {
88
- rule: string;
89
- severity: Severity;
90
- pattern: RegExp;
91
- }[];
92
- };
93
- /** The URLs the model was given, for the image and link checks. */
95
+ /** The detectors whose matches the stream settles. Default none. */
96
+ detect?: readonly Detector[];
97
+ /** What `ungiven_images` and `ungiven_links` let through besides the given URLs. */
98
+ allow?: ResolvedAllow;
99
+ /**
100
+ * Whether `ungiven_links` leaves an image's own markup alone. Default: `ungiven_images` is
101
+ * among `detect`. Set when another reader has the images.
102
+ */
103
+ skipImages?: boolean;
104
+ /**
105
+ * The host's own patterns, read on the text as written, with their compiled table: those it
106
+ * adds to a detector, or those of a detector of its own, named by its id.
107
+ */
108
+ own?: readonly {
109
+ detector: string;
110
+ compiled: CompiledPatterns;
111
+ matchers: readonly HostMatcher[];
112
+ }[];
113
+ /** The URLs the model was given, for `ungiven_images` and `ungiven_links`. */
94
114
  given?: GivenUrls;
115
+ /** The words of the profile's own canary note, for `marker_leak` (`boundaryNote`). */
116
+ note?: string;
117
+ /** The names of the profile's tools and of their parameters, for `tool_leak`. */
118
+ tools?: OwnTools;
95
119
  }
96
- /** Scans the bundled egress policy's patterns, and any host rules, as a reply streams. */
120
+ /** Scans the detectors' patterns, Theorem's and the host's own, as a reply streams. */
97
121
  declare function createEgressStream(options?: EgressStreamOptions): EgressStream;
98
- /** A stream running a policy's checks, for the turn or session `context` describes. */
99
- type EgressStreamPlan = (context: GuardrailContext) => EgressStream;
100
- /** The streaming plan for `enforce`, when the stream knows its checks. */
101
- declare function streamPlanOf(enforce: EgressEnforcer): EgressStreamPlan | undefined;
102
- /** Tell the gate `enforce` runs exactly the checks `plan` streams. */
103
- declare function registerStreamPlan(enforce: EgressEnforcer, plan: EgressStreamPlan): void;
104
- export type { EgressStream, EgressStreamHit, EgressStreamOptions, EgressStreamPlan, Grown, MappedView, View, };
105
- export { createEgressStream, normalizedView, registerStreamPlan, streamPlanOf, typoView, urlView };
122
+ export type { EgressStream, EgressStreamHit, EgressStreamOptions, Grown, MappedView, View };
123
+ export { createEgressStream, loadEgressAutomata, normalizedReplyView, typoView, urlView };