@theoremjs/agents 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +276 -995
- package/esm/mod.d.ts +33 -19
- package/esm/mod.js +18 -11
- package/esm/src/cli/commands/bench.js +36 -14
- 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 +3 -3
- package/esm/src/cli/commands/fuzz-canary.js +55 -16
- package/esm/src/cli/commands/profile.js +4 -4
- package/esm/src/cli/commands/run.d.ts +2 -2
- package/esm/src/cli/commands/run.js +1 -1
- package/esm/src/cli/commands/test.d.ts +4 -3
- package/esm/src/cli/commands/test.js +2 -2
- package/esm/src/cli/index.js +9 -9
- package/esm/src/cli/matrix/fixtures.js +25 -30
- package/esm/src/evals/attachments.d.ts +1 -0
- package/esm/src/evals/attachments.js +4 -2
- package/esm/src/evals/breakdown.d.ts +2 -0
- package/esm/src/evals/breakdown.js +1 -0
- package/esm/src/evals/graders/answer.d.ts +3 -0
- package/esm/src/evals/graders/answer.js +1 -0
- package/esm/src/evals/graders/code.d.ts +7 -31
- package/esm/src/evals/graders/code.js +4 -25
- package/esm/src/evals/graders/judge.d.ts +4 -0
- package/esm/src/evals/graders/judge.js +7 -5
- package/esm/src/evals/graders/latency.d.ts +1 -0
- package/esm/src/evals/graders/latency.js +3 -2
- package/esm/src/evals/graders/live.d.ts +3 -0
- package/esm/src/evals/graders/live.js +2 -0
- package/esm/src/evals/graders/media.js +1 -2
- package/esm/src/evals/graders/shared.js +1 -1
- package/esm/src/evals/graders/transcript.d.ts +2 -0
- package/esm/src/evals/graders/transcript.js +5 -3
- package/esm/src/evals/mod.d.ts +1 -9
- package/esm/src/evals/mod.js +1 -9
- package/esm/src/evals/record.d.ts +6 -0
- package/esm/src/evals/record.js +4 -2
- package/esm/src/evals/rubrics/mod.d.ts +1 -1
- package/esm/src/evals/rubrics/mod.js +1 -1
- package/esm/src/evals/rubrics/mustache.js +1 -1
- package/esm/src/evals/rubrics/types.js +1 -1
- package/esm/src/evals/run.d.ts +9 -52
- package/esm/src/evals/run.js +12 -46
- package/esm/src/evals/suite.d.ts +12 -3
- package/esm/src/evals/suite.js +9 -4
- package/esm/src/evals/summary.d.ts +3 -0
- package/esm/src/evals/summary.js +1 -0
- package/esm/src/evals/trial.d.ts +3 -16
- package/esm/src/evals/trial.js +7 -30
- package/esm/src/evals/types.d.ts +30 -121
- package/esm/src/evals/types.js +3 -16
- package/esm/src/evals/verdict.d.ts +5 -0
- package/esm/src/evals/verdict.js +4 -1
- 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 +1 -0
- package/esm/src/guardrails/canary.d.ts +49 -15
- package/esm/src/guardrails/canary.js +103 -30
- package/esm/src/guardrails/compile-egress.d.ts +6 -5
- package/esm/src/guardrails/compile-egress.js +6 -5
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +3 -1
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +4 -2
- package/esm/src/guardrails/corpus/fuzz-inbound.js +14 -17
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +2 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +4 -2
- package/esm/src/guardrails/corpus/live-attacks.d.ts +2 -0
- package/esm/src/guardrails/corpus/live-attacks.js +6 -1
- package/esm/src/guardrails/corpus/mod.d.ts +1 -1
- package/esm/src/guardrails/corpus/secrets.d.ts +3 -3
- package/esm/src/guardrails/corpus/secrets.js +2 -2
- package/esm/src/guardrails/corpus/strings.d.ts +1 -1
- package/esm/src/guardrails/corpus/strings.js +1 -1
- package/esm/src/guardrails/corpus/types.d.ts +5 -1
- 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 +4 -6
- package/esm/src/guardrails/egress-automata.js +24095 -4572
- package/esm/src/guardrails/egress-compiler.d.ts +38 -16
- package/esm/src/guardrails/egress-compiler.js +254 -60
- package/esm/src/guardrails/egress-patterns.d.ts +4 -2
- package/esm/src/guardrails/egress-patterns.js +6 -2
- package/esm/src/guardrails/egress-stream.d.ts +54 -36
- package/esm/src/guardrails/egress-stream.js +253 -124
- package/esm/src/guardrails/egress-urls.d.ts +6 -3
- package/esm/src/guardrails/egress-urls.js +14 -22
- package/esm/src/guardrails/egress.d.ts +26 -86
- package/esm/src/guardrails/egress.js +59 -309
- package/esm/src/guardrails/error.d.ts +13 -8
- package/esm/src/guardrails/error.js +23 -18
- package/esm/src/guardrails/event-schemas.d.ts +46 -3
- package/esm/src/guardrails/event-schemas.js +12 -5
- package/esm/src/guardrails/events.d.ts +5 -1
- package/esm/src/guardrails/events.js +4 -1
- package/esm/src/guardrails/hints.d.ts +14 -0
- package/esm/src/guardrails/hints.js +57 -0
- package/esm/src/guardrails/hits.d.ts +7 -1
- package/esm/src/guardrails/hits.js +12 -1
- 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 +6 -1
- package/esm/src/guardrails/injection-patterns.js +33 -1
- 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 +17 -1
- package/esm/src/guardrails/injection.js +259 -36
- 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 +9 -8
- package/esm/src/guardrails/live-outbound-gate.js +100 -107
- package/esm/src/guardrails/mod.d.ts +29 -21
- package/esm/src/guardrails/mod.js +18 -13
- package/esm/src/guardrails/network.d.ts +4 -0
- package/esm/src/guardrails/network.js +21 -19
- package/esm/src/guardrails/normalize.d.ts +15 -1
- package/esm/src/guardrails/normalize.js +34 -1
- package/esm/src/guardrails/policy.d.ts +2 -17
- package/esm/src/guardrails/policy.js +12 -41
- package/esm/src/guardrails/progressive-yield.d.ts +65 -24
- package/esm/src/guardrails/progressive-yield.js +191 -147
- package/esm/src/guardrails/prompt-echo.d.ts +4 -2
- package/esm/src/guardrails/prompt-echo.js +87 -6
- package/esm/src/guardrails/quota.d.ts +1 -0
- package/esm/src/guardrails/quota.js +1 -1
- package/esm/src/guardrails/rules.d.ts +20 -29
- package/esm/src/guardrails/rules.js +23 -30
- package/esm/src/guardrails/sanitize.d.ts +32 -15
- package/esm/src/guardrails/sanitize.js +100 -124
- 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 +16 -23
- package/esm/src/guardrails/sensitive.js +168 -47
- package/esm/src/guardrails/serialize.d.ts +1 -0
- package/esm/src/guardrails/testing.d.ts +4 -2
- package/esm/src/guardrails/testing.js +4 -2
- package/esm/src/guardrails/theorem-error.d.ts +4 -1
- package/esm/src/guardrails/theorem-error.js +3 -2
- package/esm/src/guardrails/thought-guard.d.ts +34 -13
- package/esm/src/guardrails/thought-guard.js +264 -64
- package/esm/src/guardrails/tool-directives.d.ts +29 -10
- package/esm/src/guardrails/tool-directives.js +133 -47
- 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 +45 -14
- package/esm/src/guardrails/tool-result.js +94 -70
- package/esm/src/guardrails/types.d.ts +79 -71
- package/esm/src/guardrails/types.js +11 -7
- package/esm/src/host/client-turn.d.ts +29 -2
- package/esm/src/host/client-turn.js +46 -4
- package/esm/src/host/mint-trace.d.ts +1 -0
- package/esm/src/host/mint-trace.js +3 -2
- package/esm/src/host/mod.d.ts +2 -2
- package/esm/src/host/mod.js +1 -1
- package/esm/src/host/readStreamingJsonStringField.js +2 -43
- package/esm/src/host/reply.d.ts +6 -0
- package/esm/src/host/reply.js +7 -1
- package/esm/src/interface/blocks.d.ts +3 -0
- package/esm/src/interface/blocks.js +84 -14
- package/esm/src/interface/composer-actions.d.ts +4 -0
- package/esm/src/interface/composer-actions.js +5 -3
- package/esm/src/interface/draft.d.ts +6 -0
- package/esm/src/interface/draft.js +22 -11
- package/esm/src/interface/from-profile.d.ts +13 -1
- package/esm/src/interface/from-profile.js +66 -31
- package/esm/src/interface/history.d.ts +9 -3
- package/esm/src/interface/history.js +33 -24
- package/esm/src/interface/inputs.d.ts +1 -0
- package/esm/src/interface/inputs.js +3 -0
- package/esm/src/interface/mod.d.ts +4 -2
- package/esm/src/interface/mod.js +3 -2
- package/esm/src/interface/models.d.ts +7 -0
- package/esm/src/interface/models.js +5 -0
- package/esm/src/interface/pending.d.ts +9 -0
- package/esm/src/interface/pending.js +9 -3
- package/esm/src/interface/profile-interface.js +54 -40
- package/esm/src/interface/session.d.ts +12 -5
- package/esm/src/interface/session.js +17 -10
- 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 +14 -2
- package/esm/src/interface/tool-calls.js +64 -10
- package/esm/src/interface/tool-invoke.d.ts +2 -0
- package/esm/src/interface/tool-invoke.js +3 -1
- package/esm/src/interface/tool-media.d.ts +2 -0
- package/esm/src/interface/tool-media.js +2 -1
- package/esm/src/interface/types.d.ts +105 -40
- package/esm/src/interface/types.js +1 -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/crypto.d.ts +7 -2
- package/esm/src/kernel/auth/crypto.js +12 -10
- package/esm/src/kernel/auth/oauth.d.ts +2 -1
- package/esm/src/kernel/auth/oauth.js +23 -22
- package/esm/src/kernel/auth/typed-secret.js +2 -2
- package/esm/src/kernel/auth/types.d.ts +13 -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 +43 -5
- package/esm/src/kernel/default-scope.js +54 -5
- 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 +6 -5
- package/esm/src/kernel/engine/compaction.js +12 -11
- package/esm/src/kernel/engine/decision.d.ts +10 -8
- package/esm/src/kernel/engine/decision.js +173 -146
- package/esm/src/kernel/engine/embedding.d.ts +8 -0
- package/esm/src/kernel/engine/embedding.js +118 -0
- package/esm/src/kernel/engine/live-inbound.d.ts +14 -4
- package/esm/src/kernel/engine/live-inbound.js +36 -11
- package/esm/src/kernel/engine/live-ingress.d.ts +6 -0
- package/esm/src/kernel/engine/live-ingress.js +6 -1
- package/esm/src/kernel/engine/repair.js +12 -12
- package/esm/src/kernel/engine/runner/gates.d.ts +2 -2
- package/esm/src/kernel/engine/runner/gates.js +287 -101
- package/esm/src/kernel/engine/runner/mod.d.ts +19 -5
- package/esm/src/kernel/engine/runner/mod.js +107 -56
- 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 +24 -3
- package/esm/src/kernel/engine/runner/schema-validation.js +78 -4
- package/esm/src/kernel/engine/runner/stages.d.ts +1 -1
- package/esm/src/kernel/engine/runner/stages.js +1 -8
- package/esm/src/kernel/engine/runner/state.d.ts +33 -12
- package/esm/src/kernel/engine/runner/state.js +11 -1
- 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 +2 -2
- package/esm/src/kernel/engine/runner/steps.js +328 -169
- package/esm/src/kernel/engine/runner/stream.d.ts +42 -11
- package/esm/src/kernel/engine/runner/stream.js +197 -46
- package/esm/src/kernel/engine/runner/usage.d.ts +5 -5
- package/esm/src/kernel/engine/runner/usage.js +12 -14
- package/esm/src/kernel/engine/session/mod.d.ts +8 -6
- package/esm/src/kernel/engine/session/mod.js +360 -129
- package/esm/src/kernel/engine/session/session-trace.d.ts +10 -10
- package/esm/src/kernel/engine/session/session-trace.js +41 -30
- package/esm/src/kernel/engine/token-estimate.d.ts +10 -64
- package/esm/src/kernel/engine/token-estimate.js +14 -194
- package/esm/src/kernel/engine/tool-trace.d.ts +3 -3
- package/esm/src/kernel/engine/tool-trace.js +2 -1
- package/esm/src/kernel/engine/turn-trace.d.ts +8 -7
- package/esm/src/kernel/engine/turn-trace.js +28 -36
- package/esm/src/kernel/engine/usage.d.ts +6 -0
- package/esm/src/kernel/engine/usage.js +17 -0
- package/esm/src/kernel/interaction-parts.d.ts +3 -0
- package/esm/src/kernel/interaction-parts.js +18 -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 +38 -11
- package/esm/src/kernel/mod.js +22 -7
- package/esm/src/kernel/profile-graph.d.ts +11 -6
- package/esm/src/kernel/profile-graph.js +14 -7
- package/esm/src/kernel/profile-presence.d.ts +10 -1
- package/esm/src/kernel/profile-presence.js +90 -75
- package/esm/src/kernel/profile-scope.d.ts +7 -3
- package/esm/src/kernel/profile-scope.js +67 -55
- 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 +15 -4
- package/esm/src/kernel/registry/attachments.js +31 -22
- package/esm/src/kernel/registry/catalog.d.ts +6 -0
- package/esm/src/kernel/registry/catalog.js +9 -2
- 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 +6 -2
- package/esm/src/kernel/registry/ingress.js +55 -10
- package/esm/src/kernel/registry/kernel-registry.d.ts +3 -0
- package/esm/src/kernel/registry/kernel-registry.js +9 -2
- package/esm/src/kernel/registry/profile-outputs.js +4 -1
- package/esm/src/kernel/registry/profiles.d.ts +38 -14
- package/esm/src/kernel/registry/profiles.js +280 -205
- package/esm/src/kernel/registry/provider-request.d.ts +3 -3
- package/esm/src/kernel/registry/provider-request.js +5 -13
- package/esm/src/kernel/registry/resolve.d.ts +4 -1
- package/esm/src/kernel/registry/resolve.js +59 -58
- package/esm/src/kernel/registry/schemas.d.ts +3 -0
- package/esm/src/kernel/registry/schemas.js +3 -1
- 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/system-prompt.js +7 -8
- package/esm/src/kernel/registry/vault.d.ts +14 -13
- package/esm/src/kernel/registry/vault.js +1 -14
- package/esm/src/kernel/schema.d.ts +100 -46
- package/esm/src/kernel/schema.js +499 -257
- package/esm/src/kernel/scope.d.ts +12 -5
- package/esm/src/kernel/scope.js +23 -3
- package/esm/src/kernel/stages.d.ts +38 -3
- package/esm/src/kernel/stages.js +82 -39
- package/esm/src/kernel/stop.d.ts +29 -6
- package/esm/src/kernel/stop.js +16 -4
- package/esm/src/kernel/system-parts.js +6 -6
- package/esm/src/kernel/tools/activity-label.d.ts +12 -6
- package/esm/src/kernel/tools/activity-label.js +258 -32
- 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 +21 -6
- package/esm/src/kernel/tools/events.js +53 -18
- package/esm/src/kernel/tools/execute.d.ts +47 -11
- package/esm/src/kernel/tools/execute.js +508 -136
- package/esm/src/kernel/tools/gate-answer.d.ts +12 -2
- package/esm/src/kernel/tools/gate-answer.js +17 -6
- 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 +1 -0
- package/esm/src/kernel/tools/harness.js +2 -1
- 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 +27 -5
- package/esm/src/kernel/tools/invoke.js +223 -70
- package/esm/src/kernel/tools/mcp-sessions.d.ts +4 -1
- package/esm/src/kernel/tools/mcp-sessions.js +13 -8
- package/esm/src/kernel/tools/mod.d.ts +4 -3
- package/esm/src/kernel/tools/mod.js +3 -2
- package/esm/src/kernel/tools/model-text.d.ts +10 -5
- package/esm/src/kernel/tools/model-text.js +18 -12
- 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 +11 -2
- package/esm/src/kernel/tools/permission.js +12 -12
- package/esm/src/kernel/tools/project.d.ts +4 -1
- package/esm/src/kernel/tools/project.js +32 -2
- package/esm/src/kernel/tools/registry.d.ts +9 -2
- package/esm/src/kernel/tools/registry.js +69 -10
- package/esm/src/kernel/tools/remote.d.ts +40 -6
- package/esm/src/kernel/tools/remote.js +219 -92
- package/esm/src/kernel/tools/resolve.d.ts +3 -0
- package/esm/src/kernel/tools/resolve.js +12 -4
- 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 +3 -3
- package/esm/src/kernel/tools/schema.js +21 -100
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +2 -1
- package/esm/src/kernel/tools/signed-in-fetch.js +3 -3
- package/esm/src/kernel/tools/stage-run.d.ts +27 -4
- package/esm/src/kernel/tools/stage-run.js +75 -17
- package/esm/src/kernel/tools/types.d.ts +235 -25
- 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 +208 -31
- package/esm/src/kernel/turn-events.js +127 -9
- package/esm/src/kernel/types.d.ts +302 -161
- package/esm/src/kernel/util/base64.d.ts +2 -0
- package/esm/src/kernel/util/base64.js +2 -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 +1 -0
- package/esm/src/kernel/util/record.js +1 -0
- package/esm/src/observability/destinations.d.ts +5 -0
- package/esm/src/observability/destinations.js +7 -2
- package/esm/src/observability/jsonl.d.ts +2 -2
- package/esm/src/observability/jsonl.js +15 -22
- package/esm/src/observability/mod.d.ts +3 -3
- package/esm/src/observability/mod.js +2 -2
- package/esm/src/observability/openinference.d.ts +1 -1
- package/esm/src/observability/openinference.js +3 -3
- package/esm/src/observability/otlp.d.ts +3 -0
- package/esm/src/observability/otlp.js +3 -3
- package/esm/src/observability/phoenix.d.ts +1 -0
- package/esm/src/observability/policy.d.ts +3 -0
- package/esm/src/observability/policy.js +5 -1
- package/esm/src/observability/resolve-policy.js +11 -5
- package/esm/src/observability/spans.d.ts +8 -2
- package/esm/src/observability/spans.js +21 -5
- package/esm/src/observability/trace-catalog.d.ts +19 -2
- package/esm/src/observability/trace-catalog.js +128 -87
- package/esm/src/observability/trace-record.js +22 -17
- package/esm/src/observability/trace-schema.d.ts +3 -0
- package/esm/src/observability/trace-schema.js +1 -1
- package/esm/src/observability/trace-sink.d.ts +1 -0
- package/esm/src/observability/trace-sink.js +1 -1
- package/esm/src/observability/trace-span.d.ts +7 -1
- package/esm/src/observability/trace-span.js +3 -1
- package/esm/src/observability/trace.d.ts +2 -0
- package/esm/src/observability/trace.js +4 -2
- package/esm/src/observability/types.d.ts +35 -11
- package/esm/src/observability/types.js +1 -1
- package/esm/src/presets/google/speech-voices.d.ts +1 -0
- package/esm/src/presets/google-limits.d.ts +1 -0
- package/esm/src/presets/google.d.ts +27 -12
- package/esm/src/presets/google.js +34 -25
- package/esm/src/presets/local.d.ts +26 -0
- package/esm/src/presets/local.js +30 -0
- package/esm/src/presets/mod.d.ts +5 -4
- package/esm/src/presets/mod.js +4 -4
- package/esm/src/presets/openrouter.d.ts +14 -1
- package/esm/src/presets/openrouter.js +19 -1
- 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/builtins.d.ts +14 -0
- package/esm/src/providers/google/builtins.js +57 -0
- package/esm/src/providers/google/grounding.d.ts +4 -4
- package/esm/src/providers/google/interactions/framing.d.ts +20 -8
- package/esm/src/providers/google/interactions/framing.js +85 -44
- package/esm/src/providers/google/interactions/steps.d.ts +5 -5
- package/esm/src/providers/google/interactions/steps.js +4 -4
- package/esm/src/providers/google/interactions/stream.d.ts +10 -11
- package/esm/src/providers/google/interactions/stream.js +33 -100
- package/esm/src/providers/google/live/framing.d.ts +15 -5
- package/esm/src/providers/google/live/framing.js +25 -25
- package/esm/src/providers/google/live/stream.d.ts +6 -44
- package/esm/src/providers/google/live/stream.js +3 -209
- package/esm/src/providers/google/urls.d.ts +1 -3
- package/esm/src/providers/google/urls.js +1 -3
- package/esm/src/providers/google/usage.js +2 -2
- 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 +28 -7
- package/esm/src/providers/mod.js +19 -3
- 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 +0 -9
- package/esm/src/providers/openrouter/image.js +0 -153
- 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 +2 -2
- package/esm/src/providers/openrouter/openai/compat.js +6 -6
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +2 -2
- 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/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.js +2 -2
- 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 +2 -2
- 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 +0 -4
- package/esm/src/providers/shared/sse.js +50 -36
- package/esm/src/providers/shared/tool-args.d.ts +6 -7
- package/esm/src/providers/shared/tool-args.js +10 -6
- 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 +2 -2
- package/esm/src/providers/shared/upstream-tape.js +1 -1
- 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 +48 -16
- package/esm/src/providers/types.js +2 -1
- 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 +19 -1
- package/esm/src/surface/formats.js +68 -29
- package/esm/src/surface/mod.d.ts +4 -2
- package/esm/src/surface/mod.js +4 -2
- package/esm/src/surface/runtime.d.ts +4 -0
- package/esm/src/surface/runtime.js +2 -0
- package/esm/src/surface/tools.d.ts +2 -8
- package/esm/src/surface/tools.js +4 -22
- package/esm/src/surface/types.d.ts +6 -0
- package/package.json +5 -13
- package/esm/src/cli/commands/egress-compile.d.ts +0 -17
- package/esm/src/cli/commands/egress-compile.js +0 -25
- package/esm/src/guardrails/egress-policy.d.ts +0 -27
- package/esm/src/guardrails/egress-policy.js +0 -76
- package/esm/src/guardrails/egress-rules.d.ts +0 -54
- package/esm/src/guardrails/egress-rules.js +0 -49
- package/esm/src/guardrails/lexicon.d.ts +0 -30
- package/esm/src/guardrails/lexicon.js +0 -478
- package/esm/src/kernel/engine/media-probe/audio.d.ts +0 -7
- package/esm/src/kernel/engine/media-probe/audio.js +0 -342
- package/esm/src/kernel/engine/media-probe/bytes.d.ts +0 -6
- package/esm/src/kernel/engine/media-probe/bytes.js +0 -26
- package/esm/src/kernel/engine/media-probe/image.d.ts +0 -5
- package/esm/src/kernel/engine/media-probe/image.js +0 -171
- package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +0 -19
- package/esm/src/kernel/engine/media-probe/iso-bmff.js +0 -48
- package/esm/src/kernel/engine/media-probe/matroska.d.ts +0 -35
- package/esm/src/kernel/engine/media-probe/matroska.js +0 -226
- package/esm/src/kernel/engine/media-probe/mp4.d.ts +0 -22
- package/esm/src/kernel/engine/media-probe/mp4.js +0 -279
- package/esm/src/kernel/engine/media-probe/opus.d.ts +0 -4
- package/esm/src/kernel/engine/media-probe/opus.js +0 -23
- package/esm/src/kernel/engine/media-probe/pdf.d.ts +0 -5
- package/esm/src/kernel/engine/media-probe/pdf.js +0 -117
- package/esm/src/kernel/engine/media-probe/video.d.ts +0 -15
- package/esm/src/kernel/engine/media-probe/video.js +0 -49
- package/esm/src/presets/typesafe.d.ts +0 -2
- package/esm/src/presets/typesafe.js +0 -2
- package/esm/src/providers/create-provider.d.ts +0 -21
- package/esm/src/providers/create-provider.js +0 -90
- package/esm/src/providers/decision/usage.d.ts +0 -3
- package/esm/src/providers/decision/usage.js +0 -25
- package/esm/src/providers/google/interactions/mod.d.ts +0 -2
- package/esm/src/providers/google/interactions/mod.js +0 -2
- package/esm/src/providers/google/keys.d.ts +0 -20
- package/esm/src/providers/google/keys.js +0 -87
- package/esm/src/providers/google/live/mod.d.ts +0 -7
- package/esm/src/providers/google/live/mod.js +0 -7
- package/esm/src/providers/google/live/openapi-schema.d.ts +0 -1
- package/esm/src/providers/google/live/openapi-schema.js +0 -42
- package/esm/src/providers/google/live/session.d.ts +0 -14
- package/esm/src/providers/google/live/session.js +0 -150
- package/esm/src/providers/local/local.d.ts +0 -12
- package/esm/src/providers/local/local.js +0 -186
- package/esm/src/providers/local/mod.d.ts +0 -8
- package/esm/src/providers/local/mod.js +0 -8
- package/esm/src/providers/openrouter/cache-control.d.ts +0 -5
- package/esm/src/providers/openrouter/cache-control.js +0 -4
- package/esm/src/providers/openrouter/chat.d.ts +0 -64
- package/esm/src/providers/openrouter/chat.js +0 -490
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +0 -10
- package/esm/src/providers/openrouter/openai/sdk-messages.js +0 -99
- package/esm/src/providers/openrouter/resolve-api-key.d.ts +0 -3
- package/esm/src/providers/openrouter/resolve-api-key.js +0 -8
- package/esm/src/providers/openrouter/speech.d.ts +0 -18
- package/esm/src/providers/openrouter/speech.js +0 -109
- package/esm/src/providers/probe.d.ts +0 -5
- package/esm/src/providers/probe.js +0 -15
- package/esm/src/providers/shared/builtin-wire.d.ts +0 -4
- package/esm/src/providers/shared/builtin-wire.js +0 -9
- package/esm/src/providers/shared/vault.d.ts +0 -13
- package/esm/src/providers/shared/vault.js +0 -41
|
@@ -5,6 +5,7 @@ import type { GivenUrls } from './egress-urls.js';
|
|
|
5
5
|
import { TheoremError } from './error.js';
|
|
6
6
|
import { type ProgressiveYieldGate } from './progressive-yield.js';
|
|
7
7
|
import { type ThoughtGuard } from './thought-guard.js';
|
|
8
|
+
import type { OwnTools } from './tool-leak.js';
|
|
8
9
|
import type { GuardrailContext, GuardrailHit, ResolvedGuardrailPolicy } from './types.js';
|
|
9
10
|
/**
|
|
10
11
|
* One piece of output not yet released: a reply-stream chunk covering
|
|
@@ -16,6 +17,7 @@ export interface LiveHeldOutput {
|
|
|
16
17
|
start: number;
|
|
17
18
|
end: number;
|
|
18
19
|
}
|
|
20
|
+
/** The gate's state for one live session: its policy and context, the progressive gate, the output held, and how far reply text has been released. */
|
|
19
21
|
export interface LiveOutboundGateSession {
|
|
20
22
|
policy: ResolvedGuardrailPolicy;
|
|
21
23
|
context: GuardrailContext;
|
|
@@ -26,14 +28,12 @@ export interface LiveOutboundGateSession {
|
|
|
26
28
|
releasedTo: number;
|
|
27
29
|
/** Stop releasing held output after a progressive egress hit. */
|
|
28
30
|
withholdVisible: boolean;
|
|
29
|
-
/**
|
|
30
|
-
* System-prompt leaks this cycle withheld under a host policy. They pin the
|
|
31
|
-
* cycle's final verdict to block: no host verdict may release them.
|
|
32
|
-
*/
|
|
31
|
+
/** System-prompt leaks this cycle withheld. They pin the cycle's final verdict to block. */
|
|
33
32
|
promptLeaks?: GuardrailHit[];
|
|
34
33
|
/** Omits what in the session's thoughts leaks; carries from one cycle to the next. */
|
|
35
34
|
thoughts?: ThoughtGuard;
|
|
36
35
|
}
|
|
36
|
+
/** What the gate does with a batch of a live model's events: `emit` what is released, `withhold` with an error, or stay `idle` when nothing is released yet. */
|
|
37
37
|
export type LiveOutboundBatchResult = {
|
|
38
38
|
action: 'emit';
|
|
39
39
|
events: TurnEvent[];
|
|
@@ -44,11 +44,12 @@ export type LiveOutboundBatchResult = {
|
|
|
44
44
|
} | {
|
|
45
45
|
action: 'idle';
|
|
46
46
|
};
|
|
47
|
-
/**
|
|
48
|
-
declare function createLiveOutboundGateSession(profile: Profile, canary?: string, privateSystem?: readonly string[], givenUrls?: GivenUrls): LiveOutboundGateSession
|
|
49
|
-
|
|
47
|
+
/** The canary and the system instruction are read for only while their detectors read somewhere (`scopeOf`). */
|
|
48
|
+
declare function createLiveOutboundGateSession(profile: Profile, canary?: string, privateSystem?: readonly string[], givenUrls?: GivenUrls, ownTools?: OwnTools): Promise<LiveOutboundGateSession>;
|
|
49
|
+
/** Passes one provider message's events through the outbound gate: reply text and audio are held until the egress checks clear them, a prompt leak, or egress hit withholds, and thoughts go through the thought guard. */
|
|
50
|
+
declare function processLiveOutboundBatch(session: LiveOutboundGateSession, events: TurnEvent[]): LiveOutboundBatchResult;
|
|
50
51
|
/** Call once after the provider has finished the cycle; it also starts the next one. */
|
|
51
|
-
declare function finalizeLiveOutboundTurn(session: LiveOutboundGateSession):
|
|
52
|
+
declare function finalizeLiveOutboundTurn(session: LiveOutboundGateSession): LiveOutboundBatchResult;
|
|
52
53
|
/** Drop the cycle's held output when the user interrupts mid-turn. */
|
|
53
54
|
declare function abortLiveOutboundTurn(session: LiveOutboundGateSession): void;
|
|
54
55
|
export { abortLiveOutboundTurn, createLiveOutboundGateSession, finalizeLiveOutboundTurn, processLiveOutboundBatch, };
|
|
@@ -1,48 +1,30 @@
|
|
|
1
1
|
import { isStreamedCanaryEvent } from './canary.js';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { detectEvent, leakScopeOf, scopeOf } from './detect-at.js';
|
|
3
|
+
import { readReply, refusalAfter, replyAfter, standingBlock } from './detect-reply.js';
|
|
4
|
+
import { eventLeak, isPromptLeakHit, promptLeakReason, WITHHELD_REASON } from './egress.js';
|
|
4
5
|
import { TheoremError } from './error.js';
|
|
5
|
-
import { guardrailFromHits,
|
|
6
|
-
import { lexiconText } from './lexicon.js';
|
|
6
|
+
import { guardrailFromHits, guardrailTurnEvent } from './events.js';
|
|
7
7
|
import { resolveGuardrailPolicy } from './policy.js';
|
|
8
|
-
import { createOutboundProgressiveGate,
|
|
8
|
+
import { createOutboundProgressiveGate, outboundProgressiveGate, } from './progressive-yield.js';
|
|
9
9
|
import { thoughtGuardFor } from './thought-guard.js';
|
|
10
10
|
const UNTRANSCRIBED_HIT = { rule: 'live.untranscribed-audio', severity: 'high' };
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* The policy with Live's shorter default lookback when a host enforcer set
|
|
16
|
-
* none: every held character of transcript holds its audio. The bundled policy
|
|
17
|
-
* holds exactly and takes no lookback.
|
|
18
|
-
*/
|
|
19
|
-
function liveHoldback(policy) {
|
|
20
|
-
if (!policy.egress ||
|
|
21
|
-
policy.egress.holdback !== undefined ||
|
|
22
|
-
streamPlanOf(policy.egress.enforce)) {
|
|
23
|
-
return policy;
|
|
24
|
-
}
|
|
25
|
-
return { ...policy, egress: { ...policy.egress, holdback: LIVE_DEFAULT_HOLDBACK } };
|
|
26
|
-
}
|
|
27
|
-
/** A canary is attached only when the profile policy enables it and the caller supplied a token. */
|
|
28
|
-
function createLiveOutboundGateSession(profile, canary, privateSystem, givenUrls) {
|
|
29
|
-
const policy = liveHoldback(resolveGuardrailPolicy(profile.guardrails));
|
|
30
|
-
const useCanary = policy.canary && Boolean(canary);
|
|
11
|
+
/** The canary and the system instruction are read for only while their detectors read somewhere (`scopeOf`). */
|
|
12
|
+
async function createLiveOutboundGateSession(profile, canary, privateSystem, givenUrls, ownTools) {
|
|
13
|
+
const policy = resolveGuardrailPolicy(profile.guardrails);
|
|
31
14
|
const context = {
|
|
32
15
|
stage: 'live_outbound',
|
|
33
16
|
trust: 'untrusted',
|
|
34
17
|
profileId: profile.id,
|
|
35
|
-
...(
|
|
36
|
-
|
|
37
|
-
...(useCanary && policy.promptEcho && privateSystem?.length ? { privateSystem } : {}),
|
|
38
|
-
...(profile.lexicon ? { lexicon: profile.lexicon } : {}),
|
|
18
|
+
...leakScopeOf(policy.detect, { canary, privateSystem }),
|
|
19
|
+
...(profile.labels ? { labels: profile.labels } : {}),
|
|
39
20
|
...(givenUrls ? { givenUrls } : {}),
|
|
21
|
+
...(ownTools ? { ownTools } : {}),
|
|
40
22
|
};
|
|
41
|
-
const thoughts = thoughtGuardFor(policy
|
|
23
|
+
const thoughts = await thoughtGuardFor(policy, context);
|
|
42
24
|
return {
|
|
43
25
|
policy,
|
|
44
26
|
context,
|
|
45
|
-
gate: createOutboundProgressiveGate(policy, context),
|
|
27
|
+
gate: await createOutboundProgressiveGate(policy, context, 'live_reply'),
|
|
46
28
|
held: [],
|
|
47
29
|
releasedTo: 0,
|
|
48
30
|
withholdVisible: false,
|
|
@@ -51,16 +33,12 @@ function createLiveOutboundGateSession(profile, canary, privateSystem, givenUrls
|
|
|
51
33
|
}
|
|
52
34
|
function resetCycle(session) {
|
|
53
35
|
const carry = session.gate?.carryOut();
|
|
54
|
-
session.gate =
|
|
36
|
+
session.gate = outboundProgressiveGate(session.policy, session.context, 'live_reply', carry);
|
|
55
37
|
session.held = [];
|
|
56
38
|
session.releasedTo = 0;
|
|
57
39
|
session.withholdVisible = false;
|
|
58
40
|
session.promptLeaks = undefined;
|
|
59
41
|
}
|
|
60
|
-
/** Canary-only profiles stop the turn immediately; egress profiles defer to finalize. */
|
|
61
|
-
function canaryOnlyImmediateWithhold(session) {
|
|
62
|
-
return !egressSpec(session)?.enforce;
|
|
63
|
-
}
|
|
64
42
|
function withholdResult(reason, hits, prior = []) {
|
|
65
43
|
const guardrail = guardrailFromHits('live_outbound', 'untrusted', hits, 'block');
|
|
66
44
|
return {
|
|
@@ -102,34 +80,35 @@ function releaseHeld(session, gate, to, into, transcriptWhole = false) {
|
|
|
102
80
|
}
|
|
103
81
|
/**
|
|
104
82
|
* Apply a progressive scan result. Clean: release what the gate cleared.
|
|
105
|
-
* Blocked:
|
|
106
|
-
* the cycle and reports the hit. `undefined` means keep going.
|
|
83
|
+
* Blocked: the rest of the cycle is withheld for its verdict.
|
|
107
84
|
*/
|
|
108
85
|
function applyScan(session, gate, result, into) {
|
|
109
86
|
if (!result.blocked) {
|
|
87
|
+
const found = result.found && detectEvent('live_reply', result.found);
|
|
88
|
+
if (found)
|
|
89
|
+
into.push(guardrailTurnEvent(found));
|
|
110
90
|
releaseHeld(session, gate, clearedTo(gate), into);
|
|
111
|
-
return
|
|
112
|
-
}
|
|
113
|
-
if (canaryOnlyImmediateWithhold(session)) {
|
|
114
|
-
return withholdResult(promptLeakReason(result.hits), result.hits, into);
|
|
91
|
+
return;
|
|
115
92
|
}
|
|
116
93
|
const leaks = result.hits.filter(isPromptLeakHit);
|
|
117
94
|
if (leaks.length > 0) {
|
|
118
95
|
session.promptLeaks = leaks;
|
|
119
96
|
}
|
|
120
97
|
session.withholdVisible = true;
|
|
121
|
-
|
|
98
|
+
// why: A detector's stop is reported once, by the verdict on the whole reply.
|
|
99
|
+
const guardrail = result.boundary
|
|
100
|
+
? undefined
|
|
101
|
+
: guardrailFromHits('live_outbound', 'untrusted', result.hits, 'block');
|
|
122
102
|
if (guardrail) {
|
|
123
103
|
into.push(guardrail);
|
|
124
104
|
}
|
|
125
|
-
return undefined;
|
|
126
105
|
}
|
|
127
106
|
/** Scan and release everything held (a non-reply event, or the end of the cycle). */
|
|
128
|
-
|
|
107
|
+
function flushHeld(session, gate, into) {
|
|
129
108
|
if (session.withholdVisible || session.held.length === 0) {
|
|
130
|
-
return
|
|
109
|
+
return;
|
|
131
110
|
}
|
|
132
|
-
|
|
111
|
+
applyScan(session, gate, gate.flush(), into);
|
|
133
112
|
}
|
|
134
113
|
/** Media waits behind the reply before it, so speech is heard only after its transcript clears the scan. */
|
|
135
114
|
function holdMedia(session, gate, event, transcribed) {
|
|
@@ -146,57 +125,60 @@ function coverMedia(session, end) {
|
|
|
146
125
|
item.end = end;
|
|
147
126
|
}
|
|
148
127
|
}
|
|
149
|
-
|
|
128
|
+
function holdStreamChunk(session, gate, event, into) {
|
|
150
129
|
const text = event.text ?? '';
|
|
151
130
|
if (!text) {
|
|
152
|
-
return
|
|
131
|
+
return;
|
|
153
132
|
}
|
|
154
133
|
const start = gate.accumulated().length;
|
|
155
134
|
coverMedia(session, start + text.length);
|
|
156
135
|
session.held.push({ event, start, end: start + text.length });
|
|
157
|
-
const result =
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
return applyScan(session, gate, result, into);
|
|
136
|
+
const result = gate.process(text);
|
|
137
|
+
// why: A withheld cycle keeps feeding the window so finalize judges the whole of it.
|
|
138
|
+
if (!session.withholdVisible)
|
|
139
|
+
applyScan(session, gate, result, into);
|
|
163
140
|
}
|
|
164
|
-
|
|
141
|
+
/** Passes one provider message's events through the outbound gate: reply text and audio are held until the egress checks clear them, a prompt leak, or egress hit withholds, and thoughts go through the thought guard. */
|
|
142
|
+
function processLiveOutboundBatch(session, events) {
|
|
165
143
|
const toEmit = [];
|
|
166
144
|
const { gate } = session;
|
|
167
145
|
if (!gate) {
|
|
168
|
-
|
|
146
|
+
// why: Nothing reads the reply, but a thought is read at its own boundary.
|
|
147
|
+
const { thoughts } = session;
|
|
148
|
+
if (!thoughts)
|
|
149
|
+
return emitOrIdle(events);
|
|
150
|
+
return emitOrIdle(events.flatMap((event) => event.type === 'thought' ? thoughtEvents(thoughts.push(event.text), event) : [event]));
|
|
169
151
|
}
|
|
170
|
-
// One batch is one provider message: its transcript is its audio's.
|
|
152
|
+
// why: One batch is one provider message: its transcript is its audio's.
|
|
171
153
|
let transcribed = false;
|
|
172
154
|
for (const event of events) {
|
|
173
155
|
if (isStreamedCanaryEvent(event)) {
|
|
174
156
|
transcribed ||= Boolean(event.text);
|
|
175
|
-
|
|
176
|
-
if (stopped) {
|
|
177
|
-
return stopped;
|
|
178
|
-
}
|
|
157
|
+
holdStreamChunk(session, gate, event, toEmit);
|
|
179
158
|
continue;
|
|
180
159
|
}
|
|
181
160
|
if (event.type === 'media') {
|
|
182
161
|
holdMedia(session, gate, event, transcribed);
|
|
183
|
-
// Media not yet held until the next event can release it now.
|
|
162
|
+
// why: Media not yet held until the next event can release it now.
|
|
184
163
|
if (!session.withholdVisible)
|
|
185
164
|
releaseHeld(session, gate, clearedTo(gate), toEmit);
|
|
186
165
|
continue;
|
|
187
166
|
}
|
|
188
|
-
|
|
189
|
-
if (stopped) {
|
|
190
|
-
return stopped;
|
|
191
|
-
}
|
|
167
|
+
flushHeld(session, gate, toEmit);
|
|
192
168
|
if (isGenerationComplete(event)) {
|
|
193
169
|
releaseSpoken(session, gate, toEmit);
|
|
194
170
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
171
|
+
// why: The model's tool call is read at its `tool_arguments` boundary.
|
|
172
|
+
const leak = event.type === 'tool'
|
|
173
|
+
? undefined
|
|
174
|
+
: eventLeak(event, session.context, session.policy.detect, 'live_reply');
|
|
175
|
+
if (leak?.stop) {
|
|
176
|
+
return withholdResult(promptLeakReason(leak.hits), leak.hits, toEmit);
|
|
177
|
+
}
|
|
178
|
+
if (leak) {
|
|
179
|
+
const flagged = detectEvent('live_reply', { action: 'flag', hits: leak.hits });
|
|
180
|
+
if (flagged)
|
|
181
|
+
toEmit.push(guardrailTurnEvent(flagged));
|
|
200
182
|
}
|
|
201
183
|
if (event.type === 'thought' && session.thoughts) {
|
|
202
184
|
toEmit.push(...thoughtEvents(session.thoughts.push(event.text), event));
|
|
@@ -207,9 +189,14 @@ async function processLiveOutboundBatch(session, events) {
|
|
|
207
189
|
return emitOrIdle(toEmit);
|
|
208
190
|
}
|
|
209
191
|
/** What a thought guard released, after the event saying what it omitted from it. */
|
|
210
|
-
function thoughtEvents({ text, hits }, event) {
|
|
192
|
+
function thoughtEvents({ text, hits, found }, event) {
|
|
193
|
+
const detected = found && detectEvent('thought', found);
|
|
211
194
|
const guardrail = guardrailFromHits('thought', 'untrusted', hits, 'redact');
|
|
212
|
-
return [
|
|
195
|
+
return [
|
|
196
|
+
...(detected ? [guardrailTurnEvent(detected)] : []),
|
|
197
|
+
...(guardrail ? [guardrail] : []),
|
|
198
|
+
...(text ? [{ ...event, text }] : []),
|
|
199
|
+
];
|
|
213
200
|
}
|
|
214
201
|
function isGenerationComplete(event) {
|
|
215
202
|
return event.type === 'done' && event.stop?.kind === 'generation_complete';
|
|
@@ -230,26 +217,41 @@ function emitOrIdle(events) {
|
|
|
230
217
|
return events.length === 0 ? { action: 'idle' } : { action: 'emit', events };
|
|
231
218
|
}
|
|
232
219
|
/**
|
|
233
|
-
* Live has no repair loop.
|
|
234
|
-
*
|
|
220
|
+
* Live has no repair loop. `guardrails.detect` reads the cycle's whole
|
|
221
|
+
* transcript. Allow releases what is still held; redact and refuse replace it
|
|
222
|
+
* with text (held audio is dropped); block withholds it as a `safety` error.
|
|
235
223
|
*/
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
? {
|
|
241
|
-
:
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
224
|
+
function finalEgressVerdict(session, gate, prior) {
|
|
225
|
+
const { detect, blockedReply } = session.policy;
|
|
226
|
+
const read = readReply({ text: gate.accumulated() }, detect, {
|
|
227
|
+
boundary: 'live_reply',
|
|
228
|
+
...(session.withholdVisible ? { reportedTo: clearedTo(gate) } : {}),
|
|
229
|
+
scope: scopeOf(session.policy, session.context),
|
|
230
|
+
});
|
|
231
|
+
/** The part of the cycle's reply the host already has. */
|
|
232
|
+
const shown = gate.accumulated().slice(0, session.releasedTo);
|
|
233
|
+
const stopped = standingBlock(read, session.promptLeaks);
|
|
234
|
+
// why: A detector's block is reported by its own event, which names the boundary.
|
|
235
|
+
const judged = stopped && stopped !== read.blocked
|
|
236
|
+
? guardrailFromHits('live_outbound', 'untrusted', stopped, 'block')
|
|
237
|
+
: undefined;
|
|
238
|
+
const events = [...prior, ...read.events.map(guardrailTurnEvent), ...(judged ? [judged] : [])];
|
|
239
|
+
if (stopped) {
|
|
240
|
+
// why: Live never rewrites: audio already spoken cannot be taken back for another try.
|
|
241
|
+
if (blockedReply.onBlock === 'refuse') {
|
|
242
|
+
const text = refusalAfter(shown, session.context.labels);
|
|
250
243
|
return { action: 'emit', events: [...events, { type: 'text', text }] };
|
|
251
244
|
}
|
|
252
|
-
return
|
|
245
|
+
return {
|
|
246
|
+
action: 'withhold',
|
|
247
|
+
error: new TheoremError('safety', WITHHELD_REASON.egress),
|
|
248
|
+
events,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
if (read.rewritten) {
|
|
252
|
+
// why: The audio says what the transcript did: only the replaced text goes out.
|
|
253
|
+
const text = replyAfter(shown, read.payload.text);
|
|
254
|
+
return { action: 'emit', events: [...events, { type: 'text', text }] };
|
|
253
255
|
}
|
|
254
256
|
releaseHeld(session, gate, gate.accumulated().length, events, true);
|
|
255
257
|
return emitOrIdle(events);
|
|
@@ -265,31 +267,22 @@ function dropUntranscribed(session, events) {
|
|
|
265
267
|
const guardrail = guardrailFromHits('live_outbound', 'untrusted', [UNTRANSCRIBED_HIT], 'block');
|
|
266
268
|
return guardrail ? [...events, guardrail] : events;
|
|
267
269
|
}
|
|
268
|
-
|
|
270
|
+
function finalizeCycle(session, gate) {
|
|
269
271
|
const events = [];
|
|
270
|
-
|
|
271
|
-
if (stopped) {
|
|
272
|
-
return stopped;
|
|
273
|
-
}
|
|
272
|
+
flushHeld(session, gate, events);
|
|
274
273
|
if (!gate.accumulated()) {
|
|
275
274
|
return emitOrIdle(dropUntranscribed(session, events));
|
|
276
275
|
}
|
|
277
|
-
|
|
278
|
-
if (egress) {
|
|
279
|
-
return await finalEgressVerdict(session, gate, egress, events);
|
|
280
|
-
}
|
|
281
|
-
releaseHeld(session, gate, gate.accumulated().length, events, true);
|
|
282
|
-
return emitOrIdle(events);
|
|
276
|
+
return finalEgressVerdict(session, gate, events);
|
|
283
277
|
}
|
|
284
278
|
/** Call once after the provider has finished the cycle; it also starts the next one. */
|
|
285
|
-
|
|
286
|
-
if (!session.gate) {
|
|
287
|
-
return { action: 'idle' };
|
|
288
|
-
}
|
|
279
|
+
function finalizeLiveOutboundTurn(session) {
|
|
289
280
|
const thought = session.thoughts
|
|
290
281
|
? thoughtEvents(session.thoughts.flush(), { type: 'thought', text: '' })
|
|
291
282
|
: [];
|
|
292
|
-
|
|
283
|
+
if (!session.gate)
|
|
284
|
+
return emitOrIdle(thought);
|
|
285
|
+
const result = finalizeCycle(session, session.gate);
|
|
293
286
|
resetCycle(session);
|
|
294
287
|
if (thought.length === 0)
|
|
295
288
|
return result;
|
|
@@ -1,46 +1,54 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Inbound and outbound guardrail primitives: sanitization, injection and sensitive detection,
|
|
3
|
-
* canary egress gates,
|
|
2
|
+
* Inbound and outbound guardrail primitives: sanitization, injection, and sensitive detection,
|
|
3
|
+
* canary egress gates, the detectors, and public error mapping. App-specific policy copy stays host-owned.
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import "../../_dnt.polyfills.js";
|
|
8
|
+
export type { Boundary, BoundaryMeta, ToolBoundary, ToolCrossing, ToolKind, } from './boundaries.js';
|
|
9
|
+
export { BOUNDARIES, BOUNDARY_META, recordOf, TOOL_BOUNDARIES, TOOL_KINDS, toolBoundary, } from './boundaries.js';
|
|
8
10
|
export type { CanaryGateResult, CanaryStreamGate } from './canary.js';
|
|
9
11
|
export { bindCanary, createCanaryStreamGate, eventHasCanary, isStreamedCanaryEvent, mintCanary, OMIT_CANARY, redactCanary, scanTextForCanaryLeak, USER_CLOSE, USER_OPEN, wrapUserData, } from './canary.js';
|
|
10
12
|
export type { CanaryGateSession } from './canary-gate.js';
|
|
11
13
|
export { createCanaryGateSession, filterCanaryGatedEvents } from './canary-gate.js';
|
|
12
|
-
export type {
|
|
13
|
-
export {
|
|
14
|
-
export type {
|
|
15
|
-
export {
|
|
16
|
-
export type {
|
|
14
|
+
export type { DestinationVerdict, TurnDestinations } from './destinations.js';
|
|
15
|
+
export { addGivenDestinations, addHistoryDestinations, addRequestDestinations, addResultDestinations, checkDestinationGate, turnDestinations, } from './destinations.js';
|
|
16
|
+
export type { Detection, DetectOutcome } from './detect-at.js';
|
|
17
|
+
export { detectAt } from './detect-at.js';
|
|
18
|
+
export type { DetectAction, DetectMatrix, DetectMeta, Detector, DetectorConfig, DetectorDeclaration, DetectorGroup, DetectorRule, DetectorSource, DetectSources, DetectSpec, HostDetector, HostDetectorConfig, HostDetectorId, HostFind, HostSpan, NameAllow, ResolvedAllow, ResolvedDetect, UrlAllow, UrlDetector, } from './detectors.js';
|
|
19
|
+
export { actionAt, DETECT_ACTION_META, DETECT_ACTIONS, DETECT_DEFAULTS, DETECTOR_BOUNDARIES, DETECTOR_GROUP_META, DETECTOR_GROUPS, DETECTOR_META, DETECTORS, detectProblem, detects, HOST_FIND_HOLD, HOST_FIND_HOLD_LIVE, hintProblem, PATTERN_DETECTORS, resolveAllow, resolveDetect, } from './detectors.js';
|
|
20
|
+
export { hitRules } from './egress.js';
|
|
17
21
|
export type { GivenUrls } from './egress-urls.js';
|
|
18
22
|
export type { ErrorCopies, ErrorCopy, ErrorKind, TheoremErrorOptions } from './error.js';
|
|
19
|
-
export { describeError, ERROR_KINDS, errorKind, isAbortError, isTimeoutError, kindOfHttpStatus, publicError, TheoremError, throwIfAborted, toErrorEvent,
|
|
23
|
+
export { describeError, ERROR_KINDS, errorKind, isAbortError, isTimeoutError, kindOfHttpStatus, publicError, TheoremError, throwIfAborted, toErrorEvent, withPublicLabels, } from './error.js';
|
|
20
24
|
export { errorCopiesSchema, errorKindSchema, guardrailEventSchema } from './event-schemas.js';
|
|
21
25
|
export { guardrailFromHits, guardrailFromVerdict, guardrailTurnEvent, projectGuardrailTurnEvent, } from './events.js';
|
|
22
26
|
export { hitFromSpan, projectGuardrailEvent, } from './hits.js';
|
|
27
|
+
export type { CompiledPatterns, HostPattern } from './host-patterns.js';
|
|
28
|
+
export { listsPatterns, MAX_PATTERN_LENGTH, MAX_PATTERNS, patternListProblem, } from './host-patterns.js';
|
|
23
29
|
export { injectionSpans } from './injection.js';
|
|
24
|
-
export type {
|
|
25
|
-
export {
|
|
30
|
+
export type { ClientLabelKey, LabelKey, LabelOverrides, LabelParams } from './labels.js';
|
|
31
|
+
export { CLIENT_LABEL_KEYS, LABEL_KEYS, labelCatalogRows, labelDefault, labelText, overrideLabels, resetLabels, validateLabelOverrides, } from './labels.js';
|
|
26
32
|
export type { LiveHeldOutput, LiveOutboundBatchResult, LiveOutboundGateSession, } from './live-outbound-gate.js';
|
|
27
33
|
export { abortLiveOutboundTurn, createLiveOutboundGateSession, finalizeLiveOutboundTurn, processLiveOutboundBatch, } from './live-outbound-gate.js';
|
|
28
|
-
export
|
|
29
|
-
export { detectionForTrust, resolveGuardrailPolicy } from './policy.js';
|
|
34
|
+
export { resolveGuardrailPolicy } from './policy.js';
|
|
30
35
|
export type { ProgressiveYieldGate, ProgressiveYieldGateOptions, ProgressiveYieldResult, } from './progressive-yield.js';
|
|
31
|
-
export { createOutboundProgressiveGate, createProgressiveYieldGate
|
|
36
|
+
export { createOutboundProgressiveGate, createProgressiveYieldGate } from './progressive-yield.js';
|
|
32
37
|
export { PROMPT_ECHO_WORDS, scanTextForPromptEcho } from './prompt-echo.js';
|
|
33
38
|
export type { QuotaSlotStatus } from './quota.js';
|
|
34
39
|
export { clientIp, quotaExhausted, releaseSlot, resetSlots, skipQuota, takeSlot, } from './quota.js';
|
|
35
40
|
export type { GuardrailRule } from './rules.js';
|
|
36
|
-
export {
|
|
37
|
-
export {
|
|
38
|
-
export
|
|
39
|
-
export {
|
|
41
|
+
export { DETECT_RULES, detectRule, EGRESS_RULES, NETWORK_RULES, TOOL_RULES, } from './rules.js';
|
|
42
|
+
export type { SanitizedTurnRequest } from './sanitize.js';
|
|
43
|
+
export { sanitizeHistory, sanitizeProjectId, sanitizeTurnRequest, sanitizeTurnRequestWithEvents, } from './sanitize.js';
|
|
44
|
+
export { sensitiveSpans } from './sensitive.js';
|
|
45
|
+
export type { SensitiveGroup, SensitiveGroups, SensitiveSelection, SensitiveSwitches, } from './sensitive-groups.js';
|
|
46
|
+
export { SENSITIVE_GROUPS } from './sensitive-groups.js';
|
|
40
47
|
export type { ScanText } from './serialize.js';
|
|
41
48
|
export { scanTextOf, textForScan } from './serialize.js';
|
|
42
|
-
export {
|
|
43
|
-
export
|
|
49
|
+
export type { Directive, DirectiveSignal } from './tool-directives.js';
|
|
50
|
+
export { advisoryLevel, DIRECTIVE_SIGNALS, directives } from './tool-directives.js';
|
|
51
|
+
export type { GuardedToolText, InspectedToolArguments } from './tool-result.js';
|
|
44
52
|
export { checkTaintGate, composeToolText, guardToolFailureText, guardToolResult, inspectToolArguments, isRemoteOrigin, isSuspicious, isTainted, recordTaint, TOOL_CLOSE, toolCallEvent, wrapToolData, } from './tool-result.js';
|
|
45
|
-
export type { AdvisoryLevel,
|
|
46
|
-
export { ADVISORY_LEVELS,
|
|
53
|
+
export type { AdvisoryLevel, BlockedReplyOnBlock, BlockedReplySpec, DestinationGate, GuardrailAction, GuardrailContext, GuardrailEvent, GuardrailHit, GuardrailStage, HostGuardrailsSpec, NetworkGuardrailSpec, OutboundPayload, ProfileGuardrailsSpec, Provenance, QuotaGuardrailSpec, ResolvedBlockedReply, ResolvedGuardrailPolicy, Severity, TaintGate, TaintGuardrailSpec, ToolOrigin, TrustLevel, TurnTaint, Verdict, } from './types.js';
|
|
54
|
+
export { ADVISORY_LEVELS, BLOCKED_REPLY_ON_BLOCK, DESTINATION_GATES, GUARDRAIL_STAGES, SEVERITIES, TAINT_GATES, TOOL_ORIGINS, TRUST_LEVELS, } from './types.js';
|
|
@@ -1,29 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Inbound and outbound guardrail primitives: sanitization, injection and sensitive detection,
|
|
3
|
-
* canary egress gates,
|
|
2
|
+
* Inbound and outbound guardrail primitives: sanitization, injection, and sensitive detection,
|
|
3
|
+
* canary egress gates, the detectors, and public error mapping. App-specific policy copy stays host-owned.
|
|
4
4
|
*
|
|
5
5
|
* @module
|
|
6
6
|
*/
|
|
7
7
|
import "../../_dnt.polyfills.js";
|
|
8
|
+
export { BOUNDARIES, BOUNDARY_META, recordOf, TOOL_BOUNDARIES, TOOL_KINDS, toolBoundary, } from './boundaries.js';
|
|
8
9
|
export { bindCanary, createCanaryStreamGate, eventHasCanary, isStreamedCanaryEvent, mintCanary, OMIT_CANARY, redactCanary, scanTextForCanaryLeak, USER_CLOSE, USER_OPEN, wrapUserData, } from './canary.js';
|
|
9
10
|
export { createCanaryGateSession, filterCanaryGatedEvents } from './canary-gate.js';
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
11
|
+
export { addGivenDestinations, addHistoryDestinations, addRequestDestinations, addResultDestinations, checkDestinationGate, turnDestinations, } from './destinations.js';
|
|
12
|
+
export { detectAt } from './detect-at.js';
|
|
13
|
+
export { actionAt, DETECT_ACTION_META, DETECT_ACTIONS, DETECT_DEFAULTS, DETECTOR_BOUNDARIES, DETECTOR_GROUP_META, DETECTOR_GROUPS, DETECTOR_META, DETECTORS, detectProblem, detects, HOST_FIND_HOLD, HOST_FIND_HOLD_LIVE, hintProblem, PATTERN_DETECTORS, resolveAllow, resolveDetect, } from './detectors.js';
|
|
14
|
+
export { hitRules } from './egress.js';
|
|
15
|
+
export { describeError, ERROR_KINDS, errorKind, isAbortError, isTimeoutError, kindOfHttpStatus, publicError, TheoremError, throwIfAborted, toErrorEvent, withPublicLabels, } from './error.js';
|
|
13
16
|
export { errorCopiesSchema, errorKindSchema, guardrailEventSchema } from './event-schemas.js';
|
|
14
17
|
export { guardrailFromHits, guardrailFromVerdict, guardrailTurnEvent, projectGuardrailTurnEvent, } from './events.js';
|
|
15
18
|
export { hitFromSpan, projectGuardrailEvent, } from './hits.js';
|
|
19
|
+
export { listsPatterns, MAX_PATTERN_LENGTH, MAX_PATTERNS, patternListProblem, } from './host-patterns.js';
|
|
16
20
|
export { injectionSpans } from './injection.js';
|
|
17
|
-
export {
|
|
21
|
+
export { CLIENT_LABEL_KEYS, LABEL_KEYS, labelCatalogRows, labelDefault, labelText, overrideLabels, resetLabels, validateLabelOverrides, } from './labels.js';
|
|
18
22
|
export { abortLiveOutboundTurn, createLiveOutboundGateSession, finalizeLiveOutboundTurn, processLiveOutboundBatch, } from './live-outbound-gate.js';
|
|
19
|
-
export {
|
|
20
|
-
export { createOutboundProgressiveGate, createProgressiveYieldGate
|
|
23
|
+
export { resolveGuardrailPolicy } from './policy.js';
|
|
24
|
+
export { createOutboundProgressiveGate, createProgressiveYieldGate } from './progressive-yield.js';
|
|
21
25
|
export { PROMPT_ECHO_WORDS, scanTextForPromptEcho } from './prompt-echo.js';
|
|
22
26
|
export { clientIp, quotaExhausted, releaseSlot, resetSlots, skipQuota, takeSlot, } from './quota.js';
|
|
23
|
-
export {
|
|
24
|
-
export {
|
|
25
|
-
export {
|
|
27
|
+
export { DETECT_RULES, detectRule, EGRESS_RULES, NETWORK_RULES, TOOL_RULES, } from './rules.js';
|
|
28
|
+
export { sanitizeHistory, sanitizeProjectId, sanitizeTurnRequest, sanitizeTurnRequestWithEvents, } from './sanitize.js';
|
|
29
|
+
export { sensitiveSpans } from './sensitive.js';
|
|
30
|
+
export { SENSITIVE_GROUPS } from './sensitive-groups.js';
|
|
26
31
|
export { scanTextOf, textForScan } from './serialize.js';
|
|
27
|
-
export { advisoryLevel,
|
|
32
|
+
export { advisoryLevel, DIRECTIVE_SIGNALS, directives } from './tool-directives.js';
|
|
28
33
|
export { checkTaintGate, composeToolText, guardToolFailureText, guardToolResult, inspectToolArguments, isRemoteOrigin, isSuspicious, isTainted, recordTaint, TOOL_CLOSE, toolCallEvent, wrapToolData, } from './tool-result.js';
|
|
29
|
-
export { ADVISORY_LEVELS,
|
|
34
|
+
export { ADVISORY_LEVELS, BLOCKED_REPLY_ON_BLOCK, DESTINATION_GATES, GUARDRAIL_STAGES, SEVERITIES, TAINT_GATES, TOOL_ORIGINS, TRUST_LEVELS, } from './types.js';
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type { NetworkGuardrailSpec } from './types.js';
|
|
2
|
+
/** True for loopback addresses and names reserved for local use: `localhost`, `.local`, `.internal`, `.lan`, `.home.arpa`, and `.localdomain`. */
|
|
2
3
|
export declare function isLocalhostName(hostname: string): boolean;
|
|
4
|
+
/** True when the IP address, or bracketed IPv6 host, is a private or local IPv4 or IPv6 address. */
|
|
3
5
|
export declare function isPrivateOrLocalAddress(ipOrHost: string): boolean;
|
|
4
6
|
/** Throws a `TheoremError` when the URL is blocked. */
|
|
5
7
|
export declare function assertSafeUrl(urlStr: string, policy?: NetworkGuardrailSpec): URL;
|
|
8
|
+
/** Options for a fetch that checks the network policy on every hop. */
|
|
6
9
|
export interface GuardedFetchOptions {
|
|
7
10
|
policy?: NetworkGuardrailSpec;
|
|
8
11
|
/** Follow redirects, clearing each hop; when false a redirect comes back as the response. */
|
|
@@ -28,6 +31,7 @@ export type ResolveHost = (hostname: string, signal?: AbortSignal) => Promise<re
|
|
|
28
31
|
export declare function fetchGuarded(url: string, init: Omit<RequestInit, 'redirect' | 'body'> & {
|
|
29
32
|
body?: string;
|
|
30
33
|
}, options: GuardedFetchOptions): Promise<Response>;
|
|
34
|
+
/** Options for `dnsOverHttpsResolver`: the DNS JSON endpoint and an optional `fetch`. */
|
|
31
35
|
export interface DnsOverHttpsOptions {
|
|
32
36
|
/** A DNS JSON API endpoint, e.g. `https://cloudflare-dns.com/dns-query`. */
|
|
33
37
|
endpoint: string;
|
|
@@ -13,18 +13,18 @@ import { TheoremError } from './error.js';
|
|
|
13
13
|
/** Four dotted decimal octets and nothing else, so an IPv6 literal's dotted tail is never read as an IPv4 address. */
|
|
14
14
|
const IPV4_LITERAL = /^\d{1,3}(\.\d{1,3}){3}$/;
|
|
15
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,
|
|
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
28
|
];
|
|
29
29
|
function isPrivateOrLocalIPv4Parts(b0, b1, b2, _b3) {
|
|
30
30
|
return PRIVATE_OR_LOCAL_IPV4_MATCHES.some((match) => match(b0, b1, b2));
|
|
@@ -143,6 +143,7 @@ function isPrivateOrLocalIPv6(ip) {
|
|
|
143
143
|
return isPrivateOrLocalIPv4Parts((hi >> 8) & 0xff, hi & 0xff, (lo >> 8) & 0xff, lo & 0xff);
|
|
144
144
|
});
|
|
145
145
|
}
|
|
146
|
+
/** True for loopback addresses and names reserved for local use: `localhost`, `.local`, `.internal`, `.lan`, `.home.arpa`, and `.localdomain`. */
|
|
146
147
|
export function isLocalhostName(hostname) {
|
|
147
148
|
let lower = hostname.toLowerCase();
|
|
148
149
|
while (lower.endsWith('.')) {
|
|
@@ -164,6 +165,7 @@ export function isLocalhostName(hostname) {
|
|
|
164
165
|
lower === '::1' ||
|
|
165
166
|
lower === '[::1]');
|
|
166
167
|
}
|
|
168
|
+
/** True when the IP address, or bracketed IPv6 host, is a private or local IPv4 or IPv6 address. */
|
|
167
169
|
export function isPrivateOrLocalAddress(ipOrHost) {
|
|
168
170
|
const stripped = ipOrHost.startsWith('[') && ipOrHost.endsWith(']') ? ipOrHost.slice(1, -1) : ipOrHost;
|
|
169
171
|
return isPrivateOrLocalIPv4(stripped) || isPrivateOrLocalIPv6(stripped);
|
|
@@ -175,12 +177,12 @@ export function assertSafeUrl(urlStr, policy) {
|
|
|
175
177
|
parsed = new URL(urlStr);
|
|
176
178
|
}
|
|
177
179
|
catch {
|
|
178
|
-
throw new TheoremError('request', `Invalid URL provided: "${urlStr}"`); //
|
|
180
|
+
throw new TheoremError('request', `Invalid URL provided: "${urlStr}"`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
179
181
|
}
|
|
180
182
|
const allowPrivate = policy?.allowPrivateNetworks ?? false;
|
|
181
183
|
const allowedHosts = policy?.allowedHosts?.map((h) => h.toLowerCase()) ?? [];
|
|
182
184
|
const hostname = parsed.hostname.toLowerCase();
|
|
183
|
-
// An allowed host is exempt from the address checks, never from the scheme.
|
|
185
|
+
// invariant: An allowed host is exempt from the address checks, never from the scheme.
|
|
184
186
|
const defaultSchemes = allowPrivate ? ['http:', 'https:'] : ['https:'];
|
|
185
187
|
const allowedSchemes = policy?.allowedSchemes
|
|
186
188
|
? policy.allowedSchemes.map((s) => (s.endsWith(':') ? s.toLowerCase() : `${s.toLowerCase()}:`))
|
|
@@ -223,7 +225,7 @@ async function assertResolvesPublic(target, options, signal) {
|
|
|
223
225
|
}
|
|
224
226
|
const addresses = await resolveHost(hostname, signal ?? undefined);
|
|
225
227
|
if (addresses.length === 0) {
|
|
226
|
-
throw new TheoremError('blocked', `Host "${hostname}" did not resolve to an address.`); //
|
|
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)
|
|
227
229
|
}
|
|
228
230
|
const inward = addresses.find(isPrivateOrLocalAddress);
|
|
229
231
|
if (inward !== undefined) {
|
|
@@ -270,15 +272,15 @@ export async function fetchGuarded(url, init, options) {
|
|
|
270
272
|
body,
|
|
271
273
|
redirect: 'manual',
|
|
272
274
|
});
|
|
273
|
-
const
|
|
274
|
-
if (!options.followRedirects || !REDIRECT_STATUSES.has(response.status) ||
|
|
275
|
+
const redirect = response.headers.get('location');
|
|
276
|
+
if (!options.followRedirects || !REDIRECT_STATUSES.has(response.status) || redirect === null) {
|
|
275
277
|
return response;
|
|
276
278
|
}
|
|
277
279
|
await response.body?.cancel();
|
|
278
280
|
if (hop === FETCH_REDIRECT_LIMIT) {
|
|
279
|
-
throw new TheoremError('network', `Too many redirects from "${url}"`); //
|
|
281
|
+
throw new TheoremError('network', `Too many redirects from "${url}"`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
280
282
|
}
|
|
281
|
-
target = await clearHop(new URL(
|
|
283
|
+
target = await clearHop(new URL(redirect, target).href);
|
|
282
284
|
onOrigin &&= target.origin === origin;
|
|
283
285
|
if (redirectsToGet(response.status, method)) {
|
|
284
286
|
method = 'GET';
|