@theoremjs/agents 0.0.0-stage → 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.
- package/LICENSE +21 -0
- package/README.md +545 -2
- package/esm/_dnt.polyfills.d.ts +66 -0
- package/esm/_dnt.polyfills.js +51 -0
- package/esm/mod.d.ts +79 -0
- package/esm/mod.js +49 -0
- package/esm/package.json +3 -0
- package/esm/src/cli/bin.d.ts +7 -0
- package/esm/src/cli/bin.js +9 -0
- package/esm/src/cli/commands/bench.d.ts +6 -0
- package/esm/src/cli/commands/bench.js +480 -0
- package/esm/src/cli/commands/detect-compile.d.ts +17 -0
- package/esm/src/cli/commands/detect-compile.js +22 -0
- package/esm/src/cli/commands/eval.d.ts +37 -0
- package/esm/src/cli/commands/eval.js +190 -0
- package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
- package/esm/src/cli/commands/fuzz-canary.js +241 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
- package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
- package/esm/src/cli/commands/profile.d.ts +2 -0
- package/esm/src/cli/commands/profile.js +80 -0
- package/esm/src/cli/commands/run.d.ts +13 -0
- package/esm/src/cli/commands/run.js +45 -0
- package/esm/src/cli/commands/test.d.ts +26 -0
- package/esm/src/cli/commands/test.js +143 -0
- package/esm/src/cli/event-log.d.ts +15 -0
- package/esm/src/cli/event-log.js +136 -0
- package/esm/src/cli/index.d.ts +10 -0
- package/esm/src/cli/index.js +267 -0
- package/esm/src/cli/matrix/fixtures.d.ts +10 -0
- package/esm/src/cli/matrix/fixtures.js +67 -0
- package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
- package/esm/src/cli/matrix/synthesizer.js +103 -0
- package/esm/src/evals/attachments.d.ts +5 -0
- package/esm/src/evals/attachments.js +55 -0
- package/esm/src/evals/breakdown.d.ts +30 -0
- package/esm/src/evals/breakdown.js +69 -0
- package/esm/src/evals/graders/answer.d.ts +16 -0
- package/esm/src/evals/graders/answer.js +134 -0
- package/esm/src/evals/graders/code.d.ts +40 -0
- package/esm/src/evals/graders/code.js +184 -0
- package/esm/src/evals/graders/judge.d.ts +24 -0
- package/esm/src/evals/graders/judge.js +367 -0
- package/esm/src/evals/graders/latency.d.ts +6 -0
- package/esm/src/evals/graders/latency.js +82 -0
- package/esm/src/evals/graders/live.d.ts +14 -0
- package/esm/src/evals/graders/live.js +42 -0
- package/esm/src/evals/graders/media.d.ts +18 -0
- package/esm/src/evals/graders/media.js +91 -0
- package/esm/src/evals/graders/shared.d.ts +11 -0
- package/esm/src/evals/graders/shared.js +62 -0
- package/esm/src/evals/graders/transcript.d.ts +19 -0
- package/esm/src/evals/graders/transcript.js +202 -0
- package/esm/src/evals/mod.d.ts +34 -0
- package/esm/src/evals/mod.js +22 -0
- package/esm/src/evals/record.d.ts +41 -0
- package/esm/src/evals/record.js +107 -0
- package/esm/src/evals/rubrics/catalog.d.ts +148 -0
- package/esm/src/evals/rubrics/catalog.js +846 -0
- package/esm/src/evals/rubrics/mod.d.ts +24 -0
- package/esm/src/evals/rubrics/mod.js +55 -0
- package/esm/src/evals/rubrics/mustache.d.ts +23 -0
- package/esm/src/evals/rubrics/mustache.js +154 -0
- package/esm/src/evals/rubrics/types.d.ts +54 -0
- package/esm/src/evals/rubrics/types.js +74 -0
- package/esm/src/evals/run.d.ts +75 -0
- package/esm/src/evals/run.js +418 -0
- package/esm/src/evals/suite.d.ts +28 -0
- package/esm/src/evals/suite.js +97 -0
- package/esm/src/evals/summary.d.ts +35 -0
- package/esm/src/evals/summary.js +31 -0
- package/esm/src/evals/trial.d.ts +14 -0
- package/esm/src/evals/trial.js +135 -0
- package/esm/src/evals/types.d.ts +169 -0
- package/esm/src/evals/types.js +113 -0
- package/esm/src/evals/verdict.d.ts +23 -0
- package/esm/src/evals/verdict.js +48 -0
- package/esm/src/guardrails/boundaries.d.ts +41 -0
- package/esm/src/guardrails/boundaries.js +103 -0
- package/esm/src/guardrails/canary-gate.d.ts +22 -0
- package/esm/src/guardrails/canary-gate.js +40 -0
- package/esm/src/guardrails/canary.d.ts +146 -0
- package/esm/src/guardrails/canary.js +974 -0
- package/esm/src/guardrails/compile-egress.d.ts +12 -0
- package/esm/src/guardrails/compile-egress.js +12 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +24 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +305 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +199 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +5 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +120 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +15 -0
- package/esm/src/guardrails/corpus/live-attacks.js +229 -0
- package/esm/src/guardrails/corpus/mod.d.ts +7 -0
- package/esm/src/guardrails/corpus/mod.js +4 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +23 -0
- package/esm/src/guardrails/corpus/strings.js +29 -0
- package/esm/src/guardrails/corpus/types.d.ts +36 -0
- package/esm/src/guardrails/corpus/types.js +1 -0
- package/esm/src/guardrails/credential-rules.d.ts +36 -0
- package/esm/src/guardrails/credential-rules.js +3001 -0
- package/esm/src/guardrails/credential-scan.d.ts +45 -0
- package/esm/src/guardrails/credential-scan.js +172 -0
- package/esm/src/guardrails/destinations.d.ts +45 -0
- package/esm/src/guardrails/destinations.js +234 -0
- package/esm/src/guardrails/detect-at.d.ts +107 -0
- package/esm/src/guardrails/detect-at.js +434 -0
- package/esm/src/guardrails/detect-reply.d.ts +61 -0
- package/esm/src/guardrails/detect-reply.js +95 -0
- package/esm/src/guardrails/detect-stream.d.ts +33 -0
- package/esm/src/guardrails/detect-stream.js +77 -0
- package/esm/src/guardrails/detectors.d.ts +216 -0
- package/esm/src/guardrails/detectors.js +503 -0
- package/esm/src/guardrails/egress-automata.d.ts +12 -0
- package/esm/src/guardrails/egress-automata.js +25582 -0
- package/esm/src/guardrails/egress-compiler.d.ts +55 -0
- package/esm/src/guardrails/egress-compiler.js +431 -0
- package/esm/src/guardrails/egress-patterns.d.ts +26 -0
- package/esm/src/guardrails/egress-patterns.js +36 -0
- package/esm/src/guardrails/egress-stream.d.ts +123 -0
- package/esm/src/guardrails/egress-stream.js +774 -0
- package/esm/src/guardrails/egress-urls.d.ts +86 -0
- package/esm/src/guardrails/egress-urls.js +909 -0
- package/esm/src/guardrails/egress.d.ts +46 -0
- package/esm/src/guardrails/egress.js +124 -0
- package/esm/src/guardrails/error.d.ts +31 -0
- package/esm/src/guardrails/error.js +96 -0
- package/esm/src/guardrails/event-schemas.d.ts +100 -0
- package/esm/src/guardrails/event-schemas.js +48 -0
- package/esm/src/guardrails/events.d.ts +13 -0
- package/esm/src/guardrails/events.js +45 -0
- package/esm/src/guardrails/hints.d.ts +14 -0
- package/esm/src/guardrails/hints.js +57 -0
- package/esm/src/guardrails/hits.d.ts +14 -0
- package/esm/src/guardrails/hits.js +30 -0
- package/esm/src/guardrails/host-patterns.d.ts +85 -0
- package/esm/src/guardrails/host-patterns.js +173 -0
- package/esm/src/guardrails/injection-patterns.d.ts +20 -0
- package/esm/src/guardrails/injection-patterns.js +126 -0
- package/esm/src/guardrails/injection-reversed.d.ts +9 -0
- package/esm/src/guardrails/injection-reversed.js +49 -0
- package/esm/src/guardrails/injection.d.ts +30 -0
- package/esm/src/guardrails/injection.js +460 -0
- package/esm/src/guardrails/labels.d.ts +40 -0
- package/esm/src/guardrails/labels.js +874 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +55 -0
- package/esm/src/guardrails/live-outbound-gate.js +298 -0
- package/esm/src/guardrails/mod.d.ts +54 -0
- package/esm/src/guardrails/mod.js +34 -0
- package/esm/src/guardrails/network.d.ts +46 -0
- package/esm/src/guardrails/network.js +330 -0
- package/esm/src/guardrails/normalize.d.ts +20 -0
- package/esm/src/guardrails/normalize.js +165 -0
- package/esm/src/guardrails/policy.d.ts +4 -0
- package/esm/src/guardrails/policy.js +21 -0
- package/esm/src/guardrails/progressive-yield.d.ts +110 -0
- package/esm/src/guardrails/progressive-yield.js +281 -0
- package/esm/src/guardrails/prompt-echo.d.ts +40 -0
- package/esm/src/guardrails/prompt-echo.js +306 -0
- package/esm/src/guardrails/quota.d.ts +21 -0
- package/esm/src/guardrails/quota.js +80 -0
- package/esm/src/guardrails/rules.d.ts +47 -0
- package/esm/src/guardrails/rules.js +47 -0
- package/esm/src/guardrails/sanitize.d.ts +40 -0
- package/esm/src/guardrails/sanitize.js +160 -0
- package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
- package/esm/src/guardrails/sensitive-groups.js +12 -0
- package/esm/src/guardrails/sensitive.d.ts +22 -0
- package/esm/src/guardrails/sensitive.js +234 -0
- package/esm/src/guardrails/serialize.d.ts +15 -0
- package/esm/src/guardrails/serialize.js +37 -0
- package/esm/src/guardrails/testing.d.ts +11 -0
- package/esm/src/guardrails/testing.js +10 -0
- package/esm/src/guardrails/theorem-error.d.ts +21 -0
- package/esm/src/guardrails/theorem-error.js +54 -0
- package/esm/src/guardrails/thought-guard.d.ts +76 -0
- package/esm/src/guardrails/thought-guard.js +664 -0
- package/esm/src/guardrails/tool-directives.d.ts +38 -0
- package/esm/src/guardrails/tool-directives.js +195 -0
- package/esm/src/guardrails/tool-leak.d.ts +26 -0
- package/esm/src/guardrails/tool-leak.js +45 -0
- package/esm/src/guardrails/tool-result.d.ts +92 -0
- package/esm/src/guardrails/tool-result.js +272 -0
- package/esm/src/guardrails/types.d.ts +250 -0
- package/esm/src/guardrails/types.js +58 -0
- package/esm/src/host/client-turn.d.ts +36 -0
- package/esm/src/host/client-turn.js +80 -0
- package/esm/src/host/mint-trace.d.ts +29 -0
- package/esm/src/host/mint-trace.js +60 -0
- package/esm/src/host/mod.d.ts +13 -0
- package/esm/src/host/mod.js +11 -0
- package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
- package/esm/src/host/readStreamingJsonStringField.js +27 -0
- package/esm/src/host/reply.d.ts +13 -0
- package/esm/src/host/reply.js +41 -0
- package/esm/src/interface/blocks.d.ts +11 -0
- package/esm/src/interface/blocks.js +283 -0
- package/esm/src/interface/composer-actions.d.ts +24 -0
- package/esm/src/interface/composer-actions.js +33 -0
- package/esm/src/interface/draft.d.ts +20 -0
- package/esm/src/interface/draft.js +39 -0
- package/esm/src/interface/from-profile.d.ts +24 -0
- package/esm/src/interface/from-profile.js +179 -0
- package/esm/src/interface/history.d.ts +46 -0
- package/esm/src/interface/history.js +278 -0
- package/esm/src/interface/inputs.d.ts +11 -0
- package/esm/src/interface/inputs.js +67 -0
- package/esm/src/interface/mod.d.ts +33 -0
- package/esm/src/interface/mod.js +22 -0
- package/esm/src/interface/models.d.ts +26 -0
- package/esm/src/interface/models.js +50 -0
- package/esm/src/interface/pending.d.ts +57 -0
- package/esm/src/interface/pending.js +152 -0
- package/esm/src/interface/profile-interface.d.ts +4 -0
- package/esm/src/interface/profile-interface.js +237 -0
- package/esm/src/interface/session.d.ts +71 -0
- package/esm/src/interface/session.js +128 -0
- package/esm/src/interface/stop.d.ts +13 -0
- package/esm/src/interface/stop.js +28 -0
- package/esm/src/interface/tool-calls.d.ts +32 -0
- package/esm/src/interface/tool-calls.js +127 -0
- package/esm/src/interface/tool-invoke.d.ts +6 -0
- package/esm/src/interface/tool-invoke.js +22 -0
- package/esm/src/interface/tool-media.d.ts +11 -0
- package/esm/src/interface/tool-media.js +113 -0
- package/esm/src/interface/types.d.ts +278 -0
- package/esm/src/interface/types.js +5 -0
- package/esm/src/kernel/api-catalog.d.ts +85 -0
- package/esm/src/kernel/api-catalog.js +229 -0
- package/esm/src/kernel/auth/credential-source.d.ts +23 -0
- package/esm/src/kernel/auth/credential-source.js +11 -0
- package/esm/src/kernel/auth/crypto.d.ts +56 -0
- package/esm/src/kernel/auth/crypto.js +163 -0
- package/esm/src/kernel/auth/mod.d.ts +5 -0
- package/esm/src/kernel/auth/mod.js +5 -0
- package/esm/src/kernel/auth/oauth.d.ts +18 -0
- package/esm/src/kernel/auth/oauth.js +439 -0
- package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
- package/esm/src/kernel/auth/scope-refusal.js +8 -0
- package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
- package/esm/src/kernel/auth/typed-secret.js +23 -0
- package/esm/src/kernel/auth/types.d.ts +152 -0
- package/esm/src/kernel/auth/types.js +1 -0
- package/esm/src/kernel/checkpoint.d.ts +43 -0
- package/esm/src/kernel/checkpoint.js +58 -0
- package/esm/src/kernel/default-scope.d.ts +72 -0
- package/esm/src/kernel/default-scope.js +121 -0
- package/esm/src/kernel/engine/call-trace.d.ts +19 -0
- package/esm/src/kernel/engine/call-trace.js +29 -0
- package/esm/src/kernel/engine/compaction.d.ts +71 -0
- package/esm/src/kernel/engine/compaction.js +203 -0
- package/esm/src/kernel/engine/decision.d.ts +43 -0
- package/esm/src/kernel/engine/decision.js +439 -0
- package/esm/src/kernel/engine/embedding.d.ts +8 -0
- package/esm/src/kernel/engine/embedding.js +118 -0
- package/esm/src/kernel/engine/hash.d.ts +6 -0
- package/esm/src/kernel/engine/hash.js +22 -0
- package/esm/src/kernel/engine/live-inbound.d.ts +19 -0
- package/esm/src/kernel/engine/live-inbound.js +44 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +15 -0
- package/esm/src/kernel/engine/live-ingress.js +42 -0
- package/esm/src/kernel/engine/record.d.ts +3 -0
- package/esm/src/kernel/engine/record.js +11 -0
- package/esm/src/kernel/engine/repair.d.ts +7 -0
- package/esm/src/kernel/engine/repair.js +36 -0
- package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
- package/esm/src/kernel/engine/runner/gates.js +508 -0
- package/esm/src/kernel/engine/runner/mod.d.ts +29 -0
- package/esm/src/kernel/engine/runner/mod.js +625 -0
- package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
- package/esm/src/kernel/engine/runner/nested.js +134 -0
- package/esm/src/kernel/engine/runner/schema-validation.d.ts +35 -0
- package/esm/src/kernel/engine/runner/schema-validation.js +179 -0
- package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
- package/esm/src/kernel/engine/runner/stages.js +41 -0
- package/esm/src/kernel/engine/runner/state.d.ts +97 -0
- package/esm/src/kernel/engine/runner/state.js +50 -0
- package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
- package/esm/src/kernel/engine/runner/step-order.js +165 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
- package/esm/src/kernel/engine/runner/steps.js +519 -0
- package/esm/src/kernel/engine/runner/stream.d.ts +71 -0
- package/esm/src/kernel/engine/runner/stream.js +376 -0
- package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
- package/esm/src/kernel/engine/runner/usage.js +148 -0
- package/esm/src/kernel/engine/session/mod.d.ts +33 -0
- package/esm/src/kernel/engine/session/mod.js +1182 -0
- package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
- package/esm/src/kernel/engine/session/session-trace.js +500 -0
- package/esm/src/kernel/engine/token-estimate.d.ts +23 -0
- package/esm/src/kernel/engine/token-estimate.js +38 -0
- package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
- package/esm/src/kernel/engine/tool-trace.js +132 -0
- package/esm/src/kernel/engine/tree.d.ts +2 -0
- package/esm/src/kernel/engine/tree.js +17 -0
- package/esm/src/kernel/engine/turn-trace.d.ts +119 -0
- package/esm/src/kernel/engine/turn-trace.js +855 -0
- package/esm/src/kernel/engine/usage.d.ts +36 -0
- package/esm/src/kernel/engine/usage.js +151 -0
- package/esm/src/kernel/interaction-parts.d.ts +13 -0
- package/esm/src/kernel/interaction-parts.js +40 -0
- package/esm/src/kernel/json.d.ts +10 -0
- package/esm/src/kernel/json.js +3 -0
- package/esm/src/kernel/mod.d.ts +74 -0
- package/esm/src/kernel/mod.js +45 -0
- package/esm/src/kernel/profile-graph.d.ts +145 -0
- package/esm/src/kernel/profile-graph.js +158 -0
- package/esm/src/kernel/profile-presence.d.ts +18 -0
- package/esm/src/kernel/profile-presence.js +158 -0
- package/esm/src/kernel/profile-scope.d.ts +40 -0
- package/esm/src/kernel/profile-scope.js +274 -0
- package/esm/src/kernel/protocols/binding.d.ts +65 -0
- package/esm/src/kernel/protocols/binding.js +125 -0
- package/esm/src/kernel/protocols/limits.d.ts +15 -0
- package/esm/src/kernel/protocols/limits.js +28 -0
- package/esm/src/kernel/protocols/mod.d.ts +5 -0
- package/esm/src/kernel/protocols/mod.js +5 -0
- package/esm/src/kernel/protocols/prices.d.ts +36 -0
- package/esm/src/kernel/protocols/prices.js +37 -0
- package/esm/src/kernel/protocols/protocol.d.ts +253 -0
- package/esm/src/kernel/protocols/protocol.js +253 -0
- package/esm/src/kernel/protocols/provider.d.ts +108 -0
- package/esm/src/kernel/protocols/provider.js +143 -0
- package/esm/src/kernel/protocols/runtime.d.ts +55 -0
- package/esm/src/kernel/protocols/runtime.js +534 -0
- package/esm/src/kernel/provider-budget.d.ts +32 -0
- package/esm/src/kernel/provider-budget.js +262 -0
- package/esm/src/kernel/provider-dispatch.d.ts +13 -0
- package/esm/src/kernel/provider-dispatch.js +36 -0
- package/esm/src/kernel/provider-live.d.ts +7 -0
- package/esm/src/kernel/provider-live.js +189 -0
- package/esm/src/kernel/provider-runtime.d.ts +57 -0
- package/esm/src/kernel/provider-runtime.js +524 -0
- package/esm/src/kernel/registry/attachments.d.ts +46 -0
- package/esm/src/kernel/registry/attachments.js +220 -0
- package/esm/src/kernel/registry/catalog.d.ts +25 -0
- package/esm/src/kernel/registry/catalog.js +85 -0
- package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
- package/esm/src/kernel/registry/embedding-rules.js +66 -0
- package/esm/src/kernel/registry/ingress.d.ts +12 -0
- package/esm/src/kernel/registry/ingress.js +179 -0
- package/esm/src/kernel/registry/kernel-registry.d.ts +15 -0
- package/esm/src/kernel/registry/kernel-registry.js +15 -0
- package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
- package/esm/src/kernel/registry/profile-outputs.js +10 -0
- package/esm/src/kernel/registry/profiles.d.ts +116 -0
- package/esm/src/kernel/registry/profiles.js +773 -0
- package/esm/src/kernel/registry/provider-request.d.ts +6 -0
- package/esm/src/kernel/registry/provider-request.js +34 -0
- package/esm/src/kernel/registry/resolve.d.ts +17 -0
- package/esm/src/kernel/registry/resolve.js +238 -0
- package/esm/src/kernel/registry/schemas.d.ts +12 -0
- package/esm/src/kernel/registry/schemas.js +27 -0
- package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
- package/esm/src/kernel/registry/slot-fill.js +22 -0
- package/esm/src/kernel/registry/sole-model.d.ts +2 -0
- package/esm/src/kernel/registry/sole-model.js +4 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
- package/esm/src/kernel/registry/system-prompt.js +32 -0
- package/esm/src/kernel/registry/system-role.d.ts +3 -0
- package/esm/src/kernel/registry/system-role.js +9 -0
- package/esm/src/kernel/registry/vault.d.ts +14 -0
- package/esm/src/kernel/registry/vault.js +1 -0
- package/esm/src/kernel/schema.d.ts +226 -0
- package/esm/src/kernel/schema.js +895 -0
- package/esm/src/kernel/scope.d.ts +29 -0
- package/esm/src/kernel/scope.js +45 -0
- package/esm/src/kernel/stages.d.ts +176 -0
- package/esm/src/kernel/stages.js +431 -0
- package/esm/src/kernel/stop.d.ts +116 -0
- package/esm/src/kernel/stop.js +137 -0
- package/esm/src/kernel/system-parts.d.ts +26 -0
- package/esm/src/kernel/system-parts.js +98 -0
- package/esm/src/kernel/tools/activity-label.d.ts +22 -0
- package/esm/src/kernel/tools/activity-label.js +435 -0
- package/esm/src/kernel/tools/agent.d.ts +66 -0
- package/esm/src/kernel/tools/agent.js +212 -0
- package/esm/src/kernel/tools/coordinate.d.ts +4 -0
- package/esm/src/kernel/tools/coordinate.js +165 -0
- package/esm/src/kernel/tools/events.d.ts +66 -0
- package/esm/src/kernel/tools/events.js +184 -0
- package/esm/src/kernel/tools/execute.d.ts +100 -0
- package/esm/src/kernel/tools/execute.js +1173 -0
- package/esm/src/kernel/tools/gate-answer.d.ts +60 -0
- package/esm/src/kernel/tools/gate-answer.js +65 -0
- package/esm/src/kernel/tools/handler-events.d.ts +45 -0
- package/esm/src/kernel/tools/handler-events.js +106 -0
- package/esm/src/kernel/tools/harness.d.ts +17 -0
- package/esm/src/kernel/tools/harness.js +43 -0
- package/esm/src/kernel/tools/http-limit.d.ts +27 -0
- package/esm/src/kernel/tools/http-limit.js +85 -0
- package/esm/src/kernel/tools/invoke.d.ts +32 -0
- package/esm/src/kernel/tools/invoke.js +282 -0
- package/esm/src/kernel/tools/mcp-sessions.d.ts +23 -0
- package/esm/src/kernel/tools/mcp-sessions.js +69 -0
- package/esm/src/kernel/tools/mod.d.ts +10 -0
- package/esm/src/kernel/tools/mod.js +7 -0
- package/esm/src/kernel/tools/model-text.d.ts +16 -0
- package/esm/src/kernel/tools/model-text.js +31 -0
- package/esm/src/kernel/tools/operation.d.ts +76 -0
- package/esm/src/kernel/tools/operation.js +100 -0
- package/esm/src/kernel/tools/page-answer.d.ts +8 -0
- package/esm/src/kernel/tools/page-answer.js +19 -0
- package/esm/src/kernel/tools/permission.d.ts +15 -0
- package/esm/src/kernel/tools/permission.js +38 -0
- package/esm/src/kernel/tools/project.d.ts +11 -0
- package/esm/src/kernel/tools/project.js +55 -0
- package/esm/src/kernel/tools/registry.d.ts +27 -0
- package/esm/src/kernel/tools/registry.js +143 -0
- package/esm/src/kernel/tools/remote.d.ts +144 -0
- package/esm/src/kernel/tools/remote.js +1125 -0
- package/esm/src/kernel/tools/resolve.d.ts +31 -0
- package/esm/src/kernel/tools/resolve.js +267 -0
- package/esm/src/kernel/tools/run.d.ts +28 -0
- package/esm/src/kernel/tools/run.js +86 -0
- package/esm/src/kernel/tools/schema.d.ts +10 -0
- package/esm/src/kernel/tools/schema.js +95 -0
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +19 -0
- package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
- package/esm/src/kernel/tools/stage-run.d.ts +116 -0
- package/esm/src/kernel/tools/stage-run.js +198 -0
- package/esm/src/kernel/tools/types.d.ts +497 -0
- package/esm/src/kernel/tools/types.js +1 -0
- package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
- package/esm/src/kernel/tools/unchecked-output.js +18 -0
- package/esm/src/kernel/turn-events.d.ts +776 -0
- package/esm/src/kernel/turn-events.js +543 -0
- package/esm/src/kernel/types.d.ts +1025 -0
- package/esm/src/kernel/types.js +1 -0
- package/esm/src/kernel/util/base64.d.ts +4 -0
- package/esm/src/kernel/util/base64.js +15 -0
- package/esm/src/kernel/util/exact-type.d.ts +31 -0
- package/esm/src/kernel/util/exact-type.js +1 -0
- package/esm/src/kernel/util/find-last.d.ts +3 -0
- package/esm/src/kernel/util/find-last.js +9 -0
- package/esm/src/kernel/util/mime.d.ts +2 -0
- package/esm/src/kernel/util/mime.js +4 -0
- package/esm/src/kernel/util/partial-json.d.ts +23 -0
- package/esm/src/kernel/util/partial-json.js +128 -0
- package/esm/src/kernel/util/record.d.ts +2 -0
- package/esm/src/kernel/util/record.js +4 -0
- package/esm/src/observability/destinations.d.ts +14 -0
- package/esm/src/observability/destinations.js +43 -0
- package/esm/src/observability/jsonl.d.ts +18 -0
- package/esm/src/observability/jsonl.js +110 -0
- package/esm/src/observability/mod.d.ts +22 -0
- package/esm/src/observability/mod.js +16 -0
- package/esm/src/observability/openinference.d.ts +11 -0
- package/esm/src/observability/openinference.js +205 -0
- package/esm/src/observability/otlp.d.ts +71 -0
- package/esm/src/observability/otlp.js +98 -0
- package/esm/src/observability/phoenix.d.ts +30 -0
- package/esm/src/observability/phoenix.js +71 -0
- package/esm/src/observability/policy.d.ts +17 -0
- package/esm/src/observability/policy.js +73 -0
- package/esm/src/observability/resolve-policy.d.ts +8 -0
- package/esm/src/observability/resolve-policy.js +64 -0
- package/esm/src/observability/spans.d.ts +22 -0
- package/esm/src/observability/spans.js +72 -0
- package/esm/src/observability/trace-catalog.d.ts +128 -0
- package/esm/src/observability/trace-catalog.js +906 -0
- package/esm/src/observability/trace-record.d.ts +23 -0
- package/esm/src/observability/trace-record.js +228 -0
- package/esm/src/observability/trace-schema.d.ts +57 -0
- package/esm/src/observability/trace-schema.js +59 -0
- package/esm/src/observability/trace-sink.d.ts +14 -0
- package/esm/src/observability/trace-sink.js +3 -0
- package/esm/src/observability/trace-span.d.ts +98 -0
- package/esm/src/observability/trace-span.js +201 -0
- package/esm/src/observability/trace.d.ts +13 -0
- package/esm/src/observability/trace.js +37 -0
- package/esm/src/observability/types.d.ts +109 -0
- package/esm/src/observability/types.js +3 -0
- package/esm/src/presets/google/speech-voices.d.ts +9 -0
- package/esm/src/presets/google/speech-voices.js +38 -0
- package/esm/src/presets/google-limits.d.ts +13 -0
- package/esm/src/presets/google-limits.js +18 -0
- package/esm/src/presets/google.d.ts +119 -0
- package/esm/src/presets/google.js +197 -0
- package/esm/src/presets/local.d.ts +26 -0
- package/esm/src/presets/local.js +30 -0
- package/esm/src/presets/mod.d.ts +11 -0
- package/esm/src/presets/mod.js +9 -0
- package/esm/src/presets/openrouter.d.ts +26 -0
- package/esm/src/presets/openrouter.js +31 -0
- package/esm/src/providers/embedding-limits.d.ts +7 -0
- package/esm/src/providers/embedding-limits.js +12 -0
- package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
- package/esm/src/providers/gemini/embedding-protocol.js +125 -0
- package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
- package/esm/src/providers/gemini/interactions-protocol.js +105 -0
- package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
- package/esm/src/providers/gemini/live-protocol.js +191 -0
- package/esm/src/providers/gemini/prices.d.ts +3 -0
- package/esm/src/providers/gemini/prices.js +63 -0
- package/esm/src/providers/gemini/provider.d.ts +7 -0
- package/esm/src/providers/gemini/provider.js +39 -0
- package/esm/src/providers/google/api-error.d.ts +8 -0
- package/esm/src/providers/google/api-error.js +123 -0
- package/esm/src/providers/google/builtins.d.ts +14 -0
- package/esm/src/providers/google/builtins.js +57 -0
- package/esm/src/providers/google/grounding.d.ts +5 -0
- package/esm/src/providers/google/grounding.js +226 -0
- package/esm/src/providers/google/interactions/framing.d.ts +27 -0
- package/esm/src/providers/google/interactions/framing.js +304 -0
- package/esm/src/providers/google/interactions/steps.d.ts +12 -0
- package/esm/src/providers/google/interactions/steps.js +200 -0
- package/esm/src/providers/google/interactions/stream.d.ts +23 -0
- package/esm/src/providers/google/interactions/stream.js +230 -0
- package/esm/src/providers/google/live/framing.d.ts +61 -0
- package/esm/src/providers/google/live/framing.js +597 -0
- package/esm/src/providers/google/live/stream.d.ts +13 -0
- package/esm/src/providers/google/live/stream.js +57 -0
- package/esm/src/providers/google/thinking.d.ts +3 -0
- package/esm/src/providers/google/thinking.js +8 -0
- package/esm/src/providers/google/urls.d.ts +4 -0
- package/esm/src/providers/google/urls.js +4 -0
- package/esm/src/providers/google/usage.d.ts +7 -0
- package/esm/src/providers/google/usage.js +49 -0
- package/esm/src/providers/live.d.ts +6 -0
- package/esm/src/providers/live.js +6 -0
- package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
- package/esm/src/providers/local/embedding-protocol.js +60 -0
- package/esm/src/providers/local/provider.d.ts +7 -0
- package/esm/src/providers/local/provider.js +28 -0
- package/esm/src/providers/mod.d.ts +32 -0
- package/esm/src/providers/mod.js +23 -0
- package/esm/src/providers/open-ai/protocol.d.ts +3 -0
- package/esm/src/providers/open-ai/protocol.js +189 -0
- package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
- package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
- package/esm/src/providers/openrouter/image.d.ts +15 -0
- package/esm/src/providers/openrouter/image.js +34 -0
- package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
- package/esm/src/providers/openrouter/images-protocol.js +82 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
- package/esm/src/providers/openrouter/openai/compat.js +162 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
- package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
- package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
- package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
- package/esm/src/providers/openrouter/openai/usage.js +56 -0
- package/esm/src/providers/openrouter/protocol.d.ts +8 -0
- package/esm/src/providers/openrouter/protocol.js +171 -0
- package/esm/src/providers/openrouter/provider.d.ts +10 -0
- package/esm/src/providers/openrouter/provider.js +50 -0
- package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
- package/esm/src/providers/shared/carried-tool-files.js +43 -0
- package/esm/src/providers/shared/pcm.d.ts +14 -0
- package/esm/src/providers/shared/pcm.js +78 -0
- package/esm/src/providers/shared/protocol-events.d.ts +8 -0
- package/esm/src/providers/shared/protocol-events.js +20 -0
- package/esm/src/providers/shared/response-identity.d.ts +11 -0
- package/esm/src/providers/shared/response-identity.js +12 -0
- package/esm/src/providers/shared/retry.d.ts +17 -0
- package/esm/src/providers/shared/retry.js +90 -0
- package/esm/src/providers/shared/sse.d.ts +6 -0
- package/esm/src/providers/shared/sse.js +93 -0
- package/esm/src/providers/shared/structured-output.d.ts +4 -0
- package/esm/src/providers/shared/structured-output.js +11 -0
- package/esm/src/providers/shared/tool-args.d.ts +24 -0
- package/esm/src/providers/shared/tool-args.js +88 -0
- package/esm/src/providers/shared/tool-draft.d.ts +16 -0
- package/esm/src/providers/shared/tool-draft.js +14 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
- package/esm/src/providers/shared/upstream-tap.js +85 -0
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/shared/upstream-tape.js +88 -0
- package/esm/src/providers/system-one/protocol.d.ts +8 -0
- package/esm/src/providers/system-one/protocol.js +93 -0
- package/esm/src/providers/types.d.ts +51 -0
- package/esm/src/providers/types.js +2 -0
- package/esm/src/providers/typesafe/provider.d.ts +7 -0
- package/esm/src/providers/typesafe/provider.js +24 -0
- package/esm/src/surface/formats.d.ts +46 -0
- package/esm/src/surface/formats.js +178 -0
- package/esm/src/surface/mod.d.ts +16 -0
- package/esm/src/surface/mod.js +12 -0
- package/esm/src/surface/runtime.d.ts +44 -0
- package/esm/src/surface/runtime.js +441 -0
- package/esm/src/surface/tools.d.ts +9 -0
- package/esm/src/surface/tools.js +62 -0
- package/esm/src/surface/types.d.ts +110 -0
- package/esm/src/surface/types.js +4 -0
- package/package.json +100 -4
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
import { TheoremError } from './error.js';
|
|
2
|
+
/**
|
|
3
|
+
* IPv4 ranges refused outright:
|
|
4
|
+
* - Loopback: 127.0.0.0/8
|
|
5
|
+
* - RFC 1918: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16
|
|
6
|
+
* - Link-local / Cloud metadata: 169.254.0.0/16
|
|
7
|
+
* - Current network: 0.0.0.0/8
|
|
8
|
+
* - RFC 6598 Carrier-grade NAT: 100.64.0.0/10
|
|
9
|
+
* - RFC 5737 / RFC 6890 documentation / assignments: 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24
|
|
10
|
+
* - RFC 2544 benchmark testing: 198.18.0.0/15
|
|
11
|
+
* - Broadcast / multicast / reserved: 224.0.0.0/4, 240.0.0.0/4, 255.255.255.255
|
|
12
|
+
*/
|
|
13
|
+
/** Four dotted decimal octets and nothing else, so an IPv6 literal's dotted tail is never read as an IPv4 address. */
|
|
14
|
+
const IPV4_LITERAL = /^\d{1,3}(\.\d{1,3}){3}$/;
|
|
15
|
+
const PRIVATE_OR_LOCAL_IPV4_MATCHES = [
|
|
16
|
+
(b0) => b0 === 0,
|
|
17
|
+
(b0) => b0 === 127,
|
|
18
|
+
(b0) => b0 === 10,
|
|
19
|
+
(b0, b1) => b0 === 100 && b1 >= 64 && b1 <= 127,
|
|
20
|
+
(b0, b1) => b0 === 172 && b1 >= 16 && b1 <= 31,
|
|
21
|
+
(b0, b1) => b0 === 192 && b1 === 168,
|
|
22
|
+
(b0, b1) => b0 === 169 && b1 === 254,
|
|
23
|
+
(b0, b1, b2) => b0 === 192 && b1 === 0 && (b2 === 0 || b2 === 2),
|
|
24
|
+
(b0, b1) => b0 === 198 && (b1 === 18 || b1 === 19),
|
|
25
|
+
(b0, b1, b2) => b0 === 198 && b1 === 51 && b2 === 100,
|
|
26
|
+
(b0, b1, b2) => b0 === 203 && b1 === 0 && b2 === 113,
|
|
27
|
+
(b0) => b0 >= 224,
|
|
28
|
+
];
|
|
29
|
+
function isPrivateOrLocalIPv4Parts(b0, b1, b2, _b3) {
|
|
30
|
+
return PRIVATE_OR_LOCAL_IPV4_MATCHES.some((match) => match(b0, b1, b2));
|
|
31
|
+
}
|
|
32
|
+
function isPrivateOrLocalIPv4(ip) {
|
|
33
|
+
if (!IPV4_LITERAL.test(ip)) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
const [b0 = 0, b1 = 0, b2 = 0, b3 = 0] = ip.split('.').map(Number);
|
|
37
|
+
if (b0 > 255 || b1 > 255 || b2 > 255 || b3 > 255) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return isPrivateOrLocalIPv4Parts(b0, b1, b2, b3);
|
|
41
|
+
}
|
|
42
|
+
function parseIPv6Words(ip) {
|
|
43
|
+
const trimmed = ip.toLowerCase().trim();
|
|
44
|
+
const lastColon = trimmed.lastIndexOf(':');
|
|
45
|
+
let ipv4Words = [];
|
|
46
|
+
let v6Str = trimmed;
|
|
47
|
+
if (lastColon !== -1) {
|
|
48
|
+
const potentialV4 = trimmed.slice(lastColon + 1);
|
|
49
|
+
if (potentialV4.includes('.')) {
|
|
50
|
+
const v4Parts = potentialV4.split('.').map((p) => Number.parseInt(p, 10));
|
|
51
|
+
if (v4Parts.length !== 4 || v4Parts.some((p) => Number.isNaN(p) || p < 0 || p > 255)) {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
const b0 = v4Parts[0] ?? 0;
|
|
55
|
+
const b1 = v4Parts[1] ?? 0;
|
|
56
|
+
const b2 = v4Parts[2] ?? 0;
|
|
57
|
+
const b3 = v4Parts[3] ?? 0;
|
|
58
|
+
ipv4Words = [(b0 << 8) | b1, (b2 << 8) | b3];
|
|
59
|
+
const head = trimmed.slice(0, lastColon + 1);
|
|
60
|
+
v6Str = head.endsWith('::') ? head : head.slice(0, -1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const parts = v6Str.split('::');
|
|
64
|
+
if (parts.length > 2)
|
|
65
|
+
return null;
|
|
66
|
+
const left = parts[0] ? parts[0].split(':').filter(Boolean) : [];
|
|
67
|
+
const right = parts.length === 2 && parts[1] ? parts[1].split(':').filter(Boolean) : [];
|
|
68
|
+
const needed = 8 - ipv4Words.length;
|
|
69
|
+
if (parts.length === 1) {
|
|
70
|
+
if (left.length !== needed)
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (left.length + right.length >= needed)
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const zerosNeeded = needed - (left.length + right.length);
|
|
78
|
+
const mid = new Array(zerosNeeded).fill(0);
|
|
79
|
+
const parseHex = (s) => (/^[0-9a-f]{1,4}$/.test(s) ? Number.parseInt(s, 16) : null);
|
|
80
|
+
const leftWords = [];
|
|
81
|
+
for (const s of left) {
|
|
82
|
+
const w = parseHex(s);
|
|
83
|
+
if (w === null)
|
|
84
|
+
return null;
|
|
85
|
+
leftWords.push(w);
|
|
86
|
+
}
|
|
87
|
+
const rightWords = [];
|
|
88
|
+
for (const s of right) {
|
|
89
|
+
const w = parseHex(s);
|
|
90
|
+
if (w === null)
|
|
91
|
+
return null;
|
|
92
|
+
rightWords.push(w);
|
|
93
|
+
}
|
|
94
|
+
return [...leftWords, ...mid, ...rightWords, ...ipv4Words];
|
|
95
|
+
}
|
|
96
|
+
const zeros = (w, from, to) => w.slice(from, to).every((x) => x === 0);
|
|
97
|
+
/**
|
|
98
|
+
* IPv6 ranges refused outright:
|
|
99
|
+
* - Unspecified `::` and loopback `::1`
|
|
100
|
+
* - Link-local fe80::/10, deprecated site-local fec0::/10, unique local fc00::/7
|
|
101
|
+
* - Multicast ff00::/8, documentation 2001:db8::/32, discard 100::/64
|
|
102
|
+
* - Local-use NAT64 64:ff9b:1::/48 (RFC 8215), which translates to IPv4 behind
|
|
103
|
+
* the host's own gateway, and Teredo 2001::/32, whose client address is hidden
|
|
104
|
+
*/
|
|
105
|
+
const PRIVATE_OR_LOCAL_IPV6_MATCHES = [
|
|
106
|
+
(w) => zeros(w, 0, 8),
|
|
107
|
+
(w) => zeros(w, 0, 7) && w[7] === 1,
|
|
108
|
+
(w) => ((w[0] ?? 0) & 0xffc0) === 0xfe80,
|
|
109
|
+
(w) => ((w[0] ?? 0) & 0xffc0) === 0xfec0,
|
|
110
|
+
(w) => ((w[0] ?? 0) & 0xfe00) === 0xfc00,
|
|
111
|
+
(w) => ((w[0] ?? 0) & 0xff00) === 0xff00,
|
|
112
|
+
(w) => w[0] === 0x2001 && w[1] === 0x0db8,
|
|
113
|
+
(w) => w[0] === 0x0100 && zeros(w, 1, 4),
|
|
114
|
+
(w) => w[0] === 0x0064 && w[1] === 0xff9b && w[2] === 0x0001,
|
|
115
|
+
(w) => w[0] === 0x2001 && w[1] === 0x0000,
|
|
116
|
+
];
|
|
117
|
+
/**
|
|
118
|
+
* IPv6 ranges that carry an IPv4 address, judged by that address. `at` is the
|
|
119
|
+
* word where its two words start.
|
|
120
|
+
* - IPv4-mapped ::ffff:0:0/96 and IPv4-translated ::ffff:0:0:0/96
|
|
121
|
+
* - IPv4-compatible ::/96 and NAT64 64:ff9b::/96
|
|
122
|
+
* - 6to4 2002::/16, whose relay forwards to the embedded address
|
|
123
|
+
*/
|
|
124
|
+
const EMBEDDED_IPV4_RANGES = [
|
|
125
|
+
{ match: (w) => zeros(w, 0, 5) && w[5] === 0xffff, at: 6 },
|
|
126
|
+
{ match: (w) => zeros(w, 0, 4) && w[4] === 0xffff && w[5] === 0, at: 6 },
|
|
127
|
+
{ match: (w) => zeros(w, 0, 6), at: 6 },
|
|
128
|
+
{ match: (w) => w[0] === 0x0064 && w[1] === 0xff9b && zeros(w, 2, 6), at: 6 },
|
|
129
|
+
{ match: (w) => w[0] === 0x2002, at: 1 },
|
|
130
|
+
];
|
|
131
|
+
function isPrivateOrLocalIPv6(ip) {
|
|
132
|
+
const words = parseIPv6Words(ip);
|
|
133
|
+
if (words?.length !== 8) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (PRIVATE_OR_LOCAL_IPV6_MATCHES.some((match) => match(words)))
|
|
137
|
+
return true;
|
|
138
|
+
return EMBEDDED_IPV4_RANGES.some(({ match, at }) => {
|
|
139
|
+
if (!match(words))
|
|
140
|
+
return false;
|
|
141
|
+
const hi = words[at] ?? 0;
|
|
142
|
+
const lo = words[at + 1] ?? 0;
|
|
143
|
+
return isPrivateOrLocalIPv4Parts((hi >> 8) & 0xff, hi & 0xff, (lo >> 8) & 0xff, lo & 0xff);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/** True for loopback addresses and names reserved for local use: `localhost`, `.local`, `.internal`, `.lan`, `.home.arpa`, and `.localdomain`. */
|
|
147
|
+
export function isLocalhostName(hostname) {
|
|
148
|
+
let lower = hostname.toLowerCase();
|
|
149
|
+
while (lower.endsWith('.')) {
|
|
150
|
+
lower = lower.slice(0, -1);
|
|
151
|
+
}
|
|
152
|
+
return (lower === 'localhost' ||
|
|
153
|
+
lower.endsWith('.localhost') ||
|
|
154
|
+
lower === 'local' ||
|
|
155
|
+
lower.endsWith('.local') ||
|
|
156
|
+
lower === 'internal' ||
|
|
157
|
+
lower.endsWith('.internal') ||
|
|
158
|
+
lower === 'lan' ||
|
|
159
|
+
lower.endsWith('.lan') ||
|
|
160
|
+
lower === 'home.arpa' ||
|
|
161
|
+
lower.endsWith('.home.arpa') ||
|
|
162
|
+
lower === 'localdomain' ||
|
|
163
|
+
lower.endsWith('.localdomain') ||
|
|
164
|
+
lower === '127.0.0.1' ||
|
|
165
|
+
lower === '::1' ||
|
|
166
|
+
lower === '[::1]');
|
|
167
|
+
}
|
|
168
|
+
/** True when the IP address, or bracketed IPv6 host, is a private or local IPv4 or IPv6 address. */
|
|
169
|
+
export function isPrivateOrLocalAddress(ipOrHost) {
|
|
170
|
+
const stripped = ipOrHost.startsWith('[') && ipOrHost.endsWith(']') ? ipOrHost.slice(1, -1) : ipOrHost;
|
|
171
|
+
return isPrivateOrLocalIPv4(stripped) || isPrivateOrLocalIPv6(stripped);
|
|
172
|
+
}
|
|
173
|
+
/** Throws a `TheoremError` when the URL is blocked. */
|
|
174
|
+
export function assertSafeUrl(urlStr, policy) {
|
|
175
|
+
let parsed;
|
|
176
|
+
try {
|
|
177
|
+
parsed = new URL(urlStr);
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
throw new TheoremError('request', `Invalid URL provided: "${urlStr}"`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
181
|
+
}
|
|
182
|
+
const allowPrivate = policy?.allowPrivateNetworks ?? false;
|
|
183
|
+
const allowedHosts = policy?.allowedHosts?.map((h) => h.toLowerCase()) ?? [];
|
|
184
|
+
const hostname = parsed.hostname.toLowerCase();
|
|
185
|
+
// invariant: An allowed host is exempt from the address checks, never from the scheme.
|
|
186
|
+
const defaultSchemes = allowPrivate ? ['http:', 'https:'] : ['https:'];
|
|
187
|
+
const allowedSchemes = policy?.allowedSchemes
|
|
188
|
+
? policy.allowedSchemes.map((s) => (s.endsWith(':') ? s.toLowerCase() : `${s.toLowerCase()}:`))
|
|
189
|
+
: defaultSchemes;
|
|
190
|
+
if (!allowedSchemes.includes(parsed.protocol)) {
|
|
191
|
+
throw new TheoremError('blocked', `URL scheme "${parsed.protocol}" is not permitted by network policy. Allowed: ${allowedSchemes.join(', ')}`);
|
|
192
|
+
}
|
|
193
|
+
if (!allowPrivate && !allowedHosts.includes(hostname)) {
|
|
194
|
+
if (isLocalhostName(hostname)) {
|
|
195
|
+
throw new TheoremError('blocked', `Access to loopback target "${hostname}" blocked by network guardrail. Enable allowPrivateNetworks to permit local addresses.`);
|
|
196
|
+
}
|
|
197
|
+
if (isPrivateOrLocalIPv4(hostname)) {
|
|
198
|
+
throw new TheoremError('blocked', `Access to private IPv4 address "${hostname}" blocked by network guardrail.`);
|
|
199
|
+
}
|
|
200
|
+
const strippedV6 = hostname.startsWith('[') && hostname.endsWith(']') ? hostname.slice(1, -1) : hostname;
|
|
201
|
+
if (isPrivateOrLocalIPv6(strippedV6)) {
|
|
202
|
+
throw new TheoremError('blocked', `Access to private IPv6 address "${hostname}" blocked by network guardrail.`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return parsed;
|
|
206
|
+
}
|
|
207
|
+
/** The Fetch standard's redirect limit — the one `redirect: 'follow'` applies. */
|
|
208
|
+
const FETCH_REDIRECT_LIMIT = 20;
|
|
209
|
+
const REDIRECT_STATUSES = new Set([301, 302, 303, 307, 308]);
|
|
210
|
+
/**
|
|
211
|
+
* `assertSafeUrl` judges literal addresses and local names, so a public name whose DNS answers a
|
|
212
|
+
* private address passes it. This lookup is separate from the connection's own: it stops names that
|
|
213
|
+
* point inward, but not a DNS server that changes its answer between the two (rebinding); only the
|
|
214
|
+
* host's egress layer can.
|
|
215
|
+
*/
|
|
216
|
+
async function assertResolvesPublic(target, options, signal) {
|
|
217
|
+
const { resolveHost, policy } = options;
|
|
218
|
+
const hostname = target.hostname.toLowerCase();
|
|
219
|
+
if (resolveHost === undefined ||
|
|
220
|
+
policy?.allowPrivateNetworks === true ||
|
|
221
|
+
policy?.allowedHosts?.some((h) => h.toLowerCase() === hostname) === true ||
|
|
222
|
+
hostname.startsWith('[') ||
|
|
223
|
+
IPV4_LITERAL.test(hostname)) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const addresses = await resolveHost(hostname, signal ?? undefined);
|
|
227
|
+
if (addresses.length === 0) {
|
|
228
|
+
throw new TheoremError('blocked', `Host "${hostname}" did not resolve to an address.`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
229
|
+
}
|
|
230
|
+
const inward = addresses.find(isPrivateOrLocalAddress);
|
|
231
|
+
if (inward !== undefined) {
|
|
232
|
+
throw new TheoremError('blocked', `Host "${hostname}" resolves to private address "${inward}", blocked by network guardrail.`);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** A 301/302 turns a POST into a GET, and a 303 turns anything but HEAD into a GET (Fetch standard). */
|
|
236
|
+
function redirectsToGet(status, method) {
|
|
237
|
+
if (status === 303)
|
|
238
|
+
return method !== 'HEAD';
|
|
239
|
+
return (status === 301 || status === 302) && method === 'POST';
|
|
240
|
+
}
|
|
241
|
+
/** Every redirect hop must clear `policy`; throws a `TheoremError` (`blocked`) when one is refused. */
|
|
242
|
+
export async function fetchGuarded(url, init, options) {
|
|
243
|
+
const fetchFn = options.fetchFn ?? fetch;
|
|
244
|
+
const clearHop = async (href) => {
|
|
245
|
+
const start = performance.now();
|
|
246
|
+
try {
|
|
247
|
+
const safe = assertSafeUrl(href, options.policy);
|
|
248
|
+
await assertResolvesPublic(safe, options, init.signal);
|
|
249
|
+
return safe;
|
|
250
|
+
}
|
|
251
|
+
finally {
|
|
252
|
+
options.onCheck?.(performance.now() - start);
|
|
253
|
+
}
|
|
254
|
+
};
|
|
255
|
+
let target = await clearHop(url);
|
|
256
|
+
const origin = target.origin;
|
|
257
|
+
const headers = new Headers(init.headers);
|
|
258
|
+
let method = init.method ?? 'GET';
|
|
259
|
+
let body = init.body;
|
|
260
|
+
let onOrigin = true;
|
|
261
|
+
for (let hop = 0;; hop++) {
|
|
262
|
+
const sent = new Headers(headers);
|
|
263
|
+
if (onOrigin) {
|
|
264
|
+
for (const [name, value] of Object.entries(options.originBoundHeaders ?? {})) {
|
|
265
|
+
sent.set(name, value);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
const response = await fetchFn(target.href, {
|
|
269
|
+
...init,
|
|
270
|
+
method,
|
|
271
|
+
headers: sent,
|
|
272
|
+
body,
|
|
273
|
+
redirect: 'manual',
|
|
274
|
+
});
|
|
275
|
+
const redirect = response.headers.get('location');
|
|
276
|
+
if (!options.followRedirects || !REDIRECT_STATUSES.has(response.status) || redirect === null) {
|
|
277
|
+
return response;
|
|
278
|
+
}
|
|
279
|
+
await response.body?.cancel();
|
|
280
|
+
if (hop === FETCH_REDIRECT_LIMIT) {
|
|
281
|
+
throw new TheoremError('network', `Too many redirects from "${url}"`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
282
|
+
}
|
|
283
|
+
target = await clearHop(new URL(redirect, target).href);
|
|
284
|
+
onOrigin &&= target.origin === origin;
|
|
285
|
+
if (redirectsToGet(response.status, method)) {
|
|
286
|
+
method = 'GET';
|
|
287
|
+
body = undefined;
|
|
288
|
+
headers.delete('content-type');
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
const DNS_TYPE_A = 1;
|
|
293
|
+
const DNS_TYPE_AAAA = 28;
|
|
294
|
+
const DNS_NOERROR = 0;
|
|
295
|
+
const DNS_NXDOMAIN = 3;
|
|
296
|
+
/**
|
|
297
|
+
* A {@link ResolveHost} over DNS-over-HTTPS (the DNS JSON API), for runtimes
|
|
298
|
+
* with `fetch` but no DNS lookup, such as Cloudflare Workers. It asks the
|
|
299
|
+
* endpoint, not the machine's resolver, so names only an internal resolver
|
|
300
|
+
* knows are not seen; a server host should resolve through its own DNS.
|
|
301
|
+
*/
|
|
302
|
+
export function dnsOverHttpsResolver(options) {
|
|
303
|
+
const fetchFn = options.fetchFn ?? fetch;
|
|
304
|
+
const query = async (hostname, type, signal) => {
|
|
305
|
+
const url = new URL(options.endpoint);
|
|
306
|
+
url.searchParams.set('name', hostname);
|
|
307
|
+
url.searchParams.set('type', String(type));
|
|
308
|
+
const response = await fetchFn(url.href, {
|
|
309
|
+
headers: { accept: 'application/dns-json' },
|
|
310
|
+
...(signal ? { signal } : {}),
|
|
311
|
+
});
|
|
312
|
+
if (!response.ok) {
|
|
313
|
+
throw new TheoremError('network', `DNS lookup for "${hostname}" failed: HTTP ${response.status}`);
|
|
314
|
+
}
|
|
315
|
+
const answer = (await response.json());
|
|
316
|
+
if (answer.Status === DNS_NXDOMAIN)
|
|
317
|
+
return [];
|
|
318
|
+
if (answer.Status !== DNS_NOERROR) {
|
|
319
|
+
throw new TheoremError('network', `DNS lookup for "${hostname}" failed: status ${answer.Status}`);
|
|
320
|
+
}
|
|
321
|
+
return (answer.Answer ?? []).flatMap((record) => record.type === type && typeof record.data === 'string' ? [record.data] : []);
|
|
322
|
+
};
|
|
323
|
+
return async (hostname, signal) => {
|
|
324
|
+
const [v4, v6] = await Promise.all([
|
|
325
|
+
query(hostname, DNS_TYPE_A, signal),
|
|
326
|
+
query(hostname, DNS_TYPE_AAAA, signal),
|
|
327
|
+
]);
|
|
328
|
+
return [...v4, ...v6];
|
|
329
|
+
};
|
|
330
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** What one code point reads as: stripped, folded to ASCII, or itself. */
|
|
2
|
+
declare function normalizeCodePoint(ch: string): string;
|
|
3
|
+
/** Whether a code point is one `EMOJI_BETWEEN` drops between letters. */
|
|
4
|
+
declare function isEmoji(ch: string): boolean;
|
|
5
|
+
declare function normalizeForDetection(text: string): string;
|
|
6
|
+
/** `normalizeForDetection` of a text, and for each index of it the stretch of the text it stands for. */
|
|
7
|
+
interface NormalizedView {
|
|
8
|
+
text: string;
|
|
9
|
+
/** Where in the text as written the character at each index starts. */
|
|
10
|
+
start: number[];
|
|
11
|
+
/** Where in the text as written the character at each index ends. */
|
|
12
|
+
end: number[];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* `normalizeForDetection(text)` with its way back: a match in the normalized
|
|
16
|
+
* text is placed on the characters of `text` it was read from.
|
|
17
|
+
*/
|
|
18
|
+
declare function normalizedView(text: string): NormalizedView;
|
|
19
|
+
export type { NormalizedView };
|
|
20
|
+
export { isEmoji, normalizeCodePoint, normalizedView, normalizeForDetection };
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
const STRIP_CODES = [
|
|
2
|
+
0x200b, 0x200c, 0x200d, 0xfeff, 0x00ad, 0x200e, 0x200f, 0x202a, 0x202b, 0x202c, 0x202d, 0x202e,
|
|
3
|
+
0x2060, 0x2061, 0x2062, 0x2063, 0x2064, 0x034f, 0x061c, 0x180e, 0x2066, 0x2067, 0x2068, 0x2069,
|
|
4
|
+
];
|
|
5
|
+
const STRIP_SET = new Set(STRIP_CODES);
|
|
6
|
+
const SPACE_CODES = [
|
|
7
|
+
0x00a0, 0x1680, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009,
|
|
8
|
+
0x200a, 0x202f, 0x205f, 0x3000,
|
|
9
|
+
];
|
|
10
|
+
const SPACE_SET = new Set(SPACE_CODES);
|
|
11
|
+
const HOMOGLYPH_MAP = new Map([
|
|
12
|
+
[0x0430, 'a'],
|
|
13
|
+
[0x0441, 'c'],
|
|
14
|
+
[0x0435, 'e'],
|
|
15
|
+
[0x0456, 'i'],
|
|
16
|
+
[0x043e, 'o'],
|
|
17
|
+
[0x0440, 'p'],
|
|
18
|
+
[0x0455, 's'],
|
|
19
|
+
[0x0443, 'y'],
|
|
20
|
+
[0x0445, 'x'],
|
|
21
|
+
[0x043a, 'k'],
|
|
22
|
+
[0x043d, 'h'],
|
|
23
|
+
[0x0410, 'A'],
|
|
24
|
+
[0x0412, 'B'],
|
|
25
|
+
[0x0415, 'E'],
|
|
26
|
+
[0x041d, 'H'],
|
|
27
|
+
[0x041e, 'O'],
|
|
28
|
+
[0x041a, 'K'],
|
|
29
|
+
[0x041c, 'M'],
|
|
30
|
+
[0x0420, 'P'],
|
|
31
|
+
[0x0421, 'C'],
|
|
32
|
+
[0x0422, 'T'],
|
|
33
|
+
[0x0425, 'X'],
|
|
34
|
+
[0x03b1, 'a'],
|
|
35
|
+
[0x03b5, 'e'],
|
|
36
|
+
[0x03b9, 'i'],
|
|
37
|
+
[0x03bf, 'o'],
|
|
38
|
+
[0x03c1, 'p'],
|
|
39
|
+
[0x2071, 'i'],
|
|
40
|
+
[0x207f, 'n'],
|
|
41
|
+
[0x1d43, 'a'],
|
|
42
|
+
[0x1d47, 'b'],
|
|
43
|
+
[0x1d48, 'd'],
|
|
44
|
+
[0x1d49, 'e'],
|
|
45
|
+
[0x1d4d, 'g'],
|
|
46
|
+
[0x1d4f, 'k'],
|
|
47
|
+
[0x1d50, 'm'],
|
|
48
|
+
[0x1d52, 'o'],
|
|
49
|
+
[0x1d56, 'p'],
|
|
50
|
+
[0x1d57, 't'],
|
|
51
|
+
[0x1d58, 'u'],
|
|
52
|
+
[0x1d5b, 'v'],
|
|
53
|
+
]);
|
|
54
|
+
const FULLWIDTH_LO = 0xff01;
|
|
55
|
+
const FULLWIDTH_HI = 0xff5e;
|
|
56
|
+
const FULLWIDTH_OFFSET = 0xfee0;
|
|
57
|
+
const COMBINING_LO = 0x0300;
|
|
58
|
+
const COMBINING_HI = 0x036f;
|
|
59
|
+
const MATH_ALPHA = [
|
|
60
|
+
[0x1d400, 0x1d41a],
|
|
61
|
+
[0x1d434, 0x1d44e],
|
|
62
|
+
[0x1d468, 0x1d482],
|
|
63
|
+
[0x1d49c, 0x1d4b6],
|
|
64
|
+
[0x1d4d0, 0x1d4ea],
|
|
65
|
+
[0x1d504, 0x1d51e],
|
|
66
|
+
[0x1d538, 0x1d552],
|
|
67
|
+
[0x1d56c, 0x1d586],
|
|
68
|
+
[0x1d5a0, 0x1d5ba],
|
|
69
|
+
[0x1d5d4, 0x1d5ee],
|
|
70
|
+
[0x1d608, 0x1d622],
|
|
71
|
+
[0x1d63c, 0x1d656],
|
|
72
|
+
[0x1d670, 0x1d68a],
|
|
73
|
+
];
|
|
74
|
+
const MATH_DIGIT = [0x1d7ce, 0x1d7d8, 0x1d7e2, 0x1d7ec, 0x1d7f6];
|
|
75
|
+
const ALPHA_SIZE = 26;
|
|
76
|
+
const DIGIT_SIZE = 10;
|
|
77
|
+
const UPPER_A = 0x41;
|
|
78
|
+
const LOWER_A = 0x61;
|
|
79
|
+
const DIGIT_0 = 0x30;
|
|
80
|
+
function mapMath(code) {
|
|
81
|
+
for (const [upper, lower] of MATH_ALPHA) {
|
|
82
|
+
if (code >= upper && code < upper + ALPHA_SIZE) {
|
|
83
|
+
return String.fromCodePoint(UPPER_A + code - upper);
|
|
84
|
+
}
|
|
85
|
+
if (code >= lower && code < lower + ALPHA_SIZE) {
|
|
86
|
+
return String.fromCodePoint(LOWER_A + code - lower);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
for (const start of MATH_DIGIT) {
|
|
90
|
+
if (code >= start && code < start + DIGIT_SIZE) {
|
|
91
|
+
return String.fromCodePoint(DIGIT_0 + code - start);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
const EMOJI = String.raw `(?:[\u{1F300}-\u{1FFFF}]|[\u{2600}-\u{27BF}]|[\u{FE00}-\u{FE0F}]|[\u{231A}-\u{23FF}])`;
|
|
97
|
+
/** Emoji runs between two letters are dropped: `ig😀nore` reads `ignore`. */
|
|
98
|
+
const EMOJI_BETWEEN = new RegExp(`(?<=[a-zA-Z])${EMOJI}+(?=[a-zA-Z])`, 'gu');
|
|
99
|
+
const EMOJI_CHAR = new RegExp(`^${EMOJI}$`, 'u');
|
|
100
|
+
const BACKSLASH_BEFORE_ALPHA = /\\(?=[a-zA-Z])/g;
|
|
101
|
+
/** What one code point reads as: stripped, folded to ASCII, or itself. */
|
|
102
|
+
function normalizeCodePoint(ch) {
|
|
103
|
+
const code = ch.codePointAt(0) ?? 0;
|
|
104
|
+
if (STRIP_SET.has(code))
|
|
105
|
+
return '';
|
|
106
|
+
if (code >= COMBINING_LO && code <= COMBINING_HI)
|
|
107
|
+
return '';
|
|
108
|
+
if (code >= FULLWIDTH_LO && code <= FULLWIDTH_HI) {
|
|
109
|
+
return String.fromCodePoint(code - FULLWIDTH_OFFSET);
|
|
110
|
+
}
|
|
111
|
+
const math = mapMath(code);
|
|
112
|
+
if (math !== undefined)
|
|
113
|
+
return math;
|
|
114
|
+
const homo = HOMOGLYPH_MAP.get(code);
|
|
115
|
+
if (homo !== undefined)
|
|
116
|
+
return homo;
|
|
117
|
+
if (SPACE_SET.has(code))
|
|
118
|
+
return ' ';
|
|
119
|
+
return ch;
|
|
120
|
+
}
|
|
121
|
+
/** Whether a code point is one `EMOJI_BETWEEN` drops between letters. */
|
|
122
|
+
function isEmoji(ch) {
|
|
123
|
+
return EMOJI_CHAR.test(ch);
|
|
124
|
+
}
|
|
125
|
+
function normalizeForDetection(text) {
|
|
126
|
+
let out = '';
|
|
127
|
+
for (const ch of text) {
|
|
128
|
+
out += normalizeCodePoint(ch);
|
|
129
|
+
}
|
|
130
|
+
return out.replace(EMOJI_BETWEEN, '').replace(BACKSLASH_BEFORE_ALPHA, '');
|
|
131
|
+
}
|
|
132
|
+
function withoutMatches(view, pattern) {
|
|
133
|
+
const kept = { text: '', start: [], end: [] };
|
|
134
|
+
let last = 0;
|
|
135
|
+
const keep = (to) => {
|
|
136
|
+
kept.text += view.text.slice(last, to);
|
|
137
|
+
kept.start.push(...view.start.slice(last, to));
|
|
138
|
+
kept.end.push(...view.end.slice(last, to));
|
|
139
|
+
};
|
|
140
|
+
for (const match of view.text.matchAll(pattern)) {
|
|
141
|
+
keep(match.index);
|
|
142
|
+
last = match.index + match[0].length;
|
|
143
|
+
}
|
|
144
|
+
keep(view.text.length);
|
|
145
|
+
return kept;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* `normalizeForDetection(text)` with its way back: a match in the normalized
|
|
149
|
+
* text is placed on the characters of `text` it was read from.
|
|
150
|
+
*/
|
|
151
|
+
function normalizedView(text) {
|
|
152
|
+
const view = { text: '', start: [], end: [] };
|
|
153
|
+
let at = 0;
|
|
154
|
+
for (const ch of text) {
|
|
155
|
+
const folded = normalizeCodePoint(ch);
|
|
156
|
+
for (let i = 0; i < folded.length; i += 1) {
|
|
157
|
+
view.start.push(at);
|
|
158
|
+
view.end.push(at + ch.length);
|
|
159
|
+
}
|
|
160
|
+
view.text += folded;
|
|
161
|
+
at += ch.length;
|
|
162
|
+
}
|
|
163
|
+
return withoutMatches(withoutMatches(view, EMOJI_BETWEEN), BACKSLASH_BEFORE_ALPHA);
|
|
164
|
+
}
|
|
165
|
+
export { isEmoji, normalizeCodePoint, normalizedView, normalizeForDetection };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { ProfileGuardrailsSpec, ResolvedGuardrailPolicy } from './types.js';
|
|
2
|
+
/** Every ingress and egress path resolves through here so none can drift on what "unset" means. */
|
|
3
|
+
declare function resolveGuardrailPolicy(spec: ProfileGuardrailsSpec | undefined): ResolvedGuardrailPolicy;
|
|
4
|
+
export { resolveGuardrailPolicy };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { resolveAllow, resolveDetect } from './detectors.js';
|
|
2
|
+
/** A blocked reply is rewritten once unless the profile says otherwise. */
|
|
3
|
+
const BLOCKED_REPLY = { onBlock: 'retry', maxRetries: 1 };
|
|
4
|
+
function resolveBlockedReply(spec) {
|
|
5
|
+
return {
|
|
6
|
+
onBlock: spec?.onBlock ?? BLOCKED_REPLY.onBlock,
|
|
7
|
+
maxRetries: spec?.maxRetries ?? BLOCKED_REPLY.maxRetries,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
/** Every ingress and egress path resolves through here so none can drift on what "unset" means. */
|
|
11
|
+
function resolveGuardrailPolicy(spec) {
|
|
12
|
+
return {
|
|
13
|
+
detect: resolveDetect(spec?.detect),
|
|
14
|
+
allow: resolveAllow(spec?.detect),
|
|
15
|
+
blockedReply: resolveBlockedReply(spec?.blockedReply),
|
|
16
|
+
network: spec?.network,
|
|
17
|
+
quota: spec?.quota,
|
|
18
|
+
taint: spec?.taint,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export { resolveGuardrailPolicy };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { Boundary, ToolBoundary } from './boundaries.js';
|
|
2
|
+
import { type Detection, type DetectScope } from './detect-at.js';
|
|
3
|
+
import type { ResolvedDetect } from './detectors.js';
|
|
4
|
+
import type { GuardrailContext, GuardrailHit, ResolvedGuardrailPolicy } from './types.js';
|
|
5
|
+
/** A reply boundary the gate reads as the reply streams. */
|
|
6
|
+
export type ReplyBoundary = Extract<Boundary, 'reply' | 'live_reply'>;
|
|
7
|
+
/** Where a draft is read: where the whole it previews is (a tool call, a tool's output, a structured reply). */
|
|
8
|
+
export type DraftBoundary = ToolBoundary | Extract<Boundary, 'reply_structured'>;
|
|
9
|
+
/** Where a gate stands: a reply boundary, or a draft's. */
|
|
10
|
+
export type GateBoundary = ReplyBoundary | DraftBoundary;
|
|
11
|
+
export type ProgressiveYieldOk = {
|
|
12
|
+
blocked: false;
|
|
13
|
+
emit: string;
|
|
14
|
+
/** What `guardrails.detect` reported or replaced in `emit`. */
|
|
15
|
+
found?: Pick<Detection, 'action' | 'hits'>;
|
|
16
|
+
};
|
|
17
|
+
export type ProgressiveYieldBlocked = {
|
|
18
|
+
blocked: true;
|
|
19
|
+
hits: GuardrailHit[];
|
|
20
|
+
/** Set when a detector stopped the reply: the boundary it was read at. */
|
|
21
|
+
boundary?: GateBoundary;
|
|
22
|
+
};
|
|
23
|
+
/** What one step of the progressive gate returns: the text to emit, or the hits that block the reply. */
|
|
24
|
+
export type ProgressiveYieldResult = ProgressiveYieldOk | ProgressiveYieldBlocked;
|
|
25
|
+
/** Settings for the progressive gate: the guardrail context, the detectors it reads with, and the carry from the window before. */
|
|
26
|
+
export interface ProgressiveYieldGateOptions {
|
|
27
|
+
/** Also carries the turn canary. */
|
|
28
|
+
context: GuardrailContext;
|
|
29
|
+
/**
|
|
30
|
+
* `guardrails.detect` and the reply boundary this gate stands at. With
|
|
31
|
+
* `rewrite`, a match set to `redact` is replaced as the text is released;
|
|
32
|
+
* without it (Live, where the text is the transcript of audio already held)
|
|
33
|
+
* the gate stops there and the cycle's verdict replaces the reply.
|
|
34
|
+
*/
|
|
35
|
+
detect?: {
|
|
36
|
+
matrix: ResolvedDetect;
|
|
37
|
+
boundary: GateBoundary;
|
|
38
|
+
rewrite: boolean;
|
|
39
|
+
/** What the detectors read against (`scopeOf`). Left out, the URL and marker detectors read with none. */
|
|
40
|
+
scope?: DetectScope;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Text an earlier window of the same canary ended on that could still open a
|
|
44
|
+
* leak (`promptLeakCarry`). It is scanned in front of this window, never released
|
|
45
|
+
* again, so a token split across steps or cycles is still one match.
|
|
46
|
+
*/
|
|
47
|
+
carry?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Incremental outbound gate that scans accumulated output and releases only
|
|
51
|
+
* prefixes outside its retained lookback window.
|
|
52
|
+
*/
|
|
53
|
+
interface ProgressiveYieldGate {
|
|
54
|
+
process: (fragment: string) => ProgressiveYieldResult;
|
|
55
|
+
flush: () => ProgressiveYieldResult;
|
|
56
|
+
/** Full window inspected so far (for end-of-attempt egress / repair). */
|
|
57
|
+
accumulated: () => string;
|
|
58
|
+
/** Lookback tail not yet released to the host. Peek only. */
|
|
59
|
+
unreleased: () => string;
|
|
60
|
+
/**
|
|
61
|
+
* Take the tail not yet released and mark it released.
|
|
62
|
+
*
|
|
63
|
+
* Used when the runner records withheld text for the egress window: without
|
|
64
|
+
* advancing the cursor a later `flush` re-releases the same range and the
|
|
65
|
+
* attempt buffer ends up holding the text twice.
|
|
66
|
+
*/
|
|
67
|
+
drainUnreleased: () => string;
|
|
68
|
+
/** The tail the next window of the same canary must scan in front of its own. */
|
|
69
|
+
carryOut: () => string;
|
|
70
|
+
}
|
|
71
|
+
/** Call `flush` when the stream ends to release the held tail. */
|
|
72
|
+
declare function createProgressiveYieldGate(options: ProgressiveYieldGateOptions): Promise<ProgressiveYieldGate>;
|
|
73
|
+
/**
|
|
74
|
+
* Whether a reply read at `boundaries` gets a verdict once it has ended: a
|
|
75
|
+
* detector reads one of them. A gate that stops such a reply withholds it for
|
|
76
|
+
* that verdict.
|
|
77
|
+
*/
|
|
78
|
+
declare function replyIsJudged(policy: ResolvedGuardrailPolicy, boundaries: readonly Boundary[], scope?: DetectScope): boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Shared constructor for runTurn + Live: a gate when a detector reads
|
|
81
|
+
* `boundary`. `context.canary` is set only while `canary_leak` is above
|
|
82
|
+
* `ignore` somewhere, and `context.privateSystem` while `prompt_leak` is.
|
|
83
|
+
*/
|
|
84
|
+
declare function createOutboundProgressiveGate(policy: ResolvedGuardrailPolicy, context: GuardrailContext, boundary: ReplyBoundary, carry?: string): Promise<ProgressiveYieldGate | null>;
|
|
85
|
+
/** `createOutboundProgressiveGate`, once the automata are loaded. */
|
|
86
|
+
declare function outboundProgressiveGate(policy: ResolvedGuardrailPolicy, context: GuardrailContext, boundary: ReplyBoundary, carry?: string): ProgressiveYieldGate | null;
|
|
87
|
+
/**
|
|
88
|
+
* A gate for a draft read at `boundary`, where the whole it previews is read before the host sees
|
|
89
|
+
* it: a tool call the model is still writing, a tool's output as the tool writes it, or a
|
|
90
|
+
* structured reply's JSON as the model writes it. It never
|
|
91
|
+
* rewrites: a match the whole's check would replace or stop stops the draft instead, because the
|
|
92
|
+
* host gets the whole only as that check leaves it. `scope` is what that check reads against;
|
|
93
|
+
* left out, the turn's (`scopeOf`).
|
|
94
|
+
*/
|
|
95
|
+
declare function createDraftGate(policy: ResolvedGuardrailPolicy, context: GuardrailContext, boundary: DraftBoundary, scope?: DetectScope): Promise<ProgressiveYieldGate | null>;
|
|
96
|
+
/**
|
|
97
|
+
* One stream of drafts read through one draft gate, opened on the first draft. A match stops
|
|
98
|
+
* the rest of the stream; with no gate (nothing is judged there), every draft passes as is.
|
|
99
|
+
*/
|
|
100
|
+
declare class DraftReader {
|
|
101
|
+
private readonly open;
|
|
102
|
+
private gate;
|
|
103
|
+
constructor(open: () => Promise<ProgressiveYieldGate | null>);
|
|
104
|
+
/** What of `text` may be shown now: empty while the gate holds it, or once a match stopped the stream. */
|
|
105
|
+
read(text: string): Promise<string>;
|
|
106
|
+
/** The tail the gate still holds, once the stream has ended. */
|
|
107
|
+
end(): string;
|
|
108
|
+
}
|
|
109
|
+
export type { ProgressiveYieldGate };
|
|
110
|
+
export { createDraftGate, createOutboundProgressiveGate, createProgressiveYieldGate, DraftReader, outboundProgressiveGate, replyIsJudged, };
|