@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,212 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { TheoremError } from '../../guardrails/error.js';
|
|
3
|
+
import { interactionPartSchema, keptReply, sourceSchema } from '../turn-events.js';
|
|
4
|
+
import { findLast } from '../util/find-last.js';
|
|
5
|
+
import { profileToolAllow } from './resolve.js';
|
|
6
|
+
/** A call that settled without a reply; the model reads `failure`. */
|
|
7
|
+
class AgentCallFailed extends Error {
|
|
8
|
+
failure;
|
|
9
|
+
constructor(failure) {
|
|
10
|
+
super(failure.message);
|
|
11
|
+
this.failure = failure;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/** The agents an agent tool can run: each has a turn that takes text. */
|
|
15
|
+
const AGENT_TOOL_TYPES = new Set(['text', 'image', 'speech']);
|
|
16
|
+
// why: Bytes that are not base64, or a text of only spaces, would be refused inside the called turn as the host's error and end the caller's turn; checked here, the model reads a failed call.
|
|
17
|
+
const textInput = z.string().regex(/\S/);
|
|
18
|
+
const blobInput = z.strictObject({
|
|
19
|
+
mimeType: z.string(),
|
|
20
|
+
data: z.base64(),
|
|
21
|
+
name: z.string().optional(),
|
|
22
|
+
});
|
|
23
|
+
const mediaRefInput = z.strictObject({
|
|
24
|
+
mimeType: z.string(),
|
|
25
|
+
uri: z.string(),
|
|
26
|
+
name: z.string().optional(),
|
|
27
|
+
});
|
|
28
|
+
const speechInput = z.strictObject({
|
|
29
|
+
voice: z.string().optional(),
|
|
30
|
+
style: z.string().optional(),
|
|
31
|
+
speed: z.number().positive().optional(),
|
|
32
|
+
});
|
|
33
|
+
/** One choice per declared slot; a slot or a value the profile does not declare is refused. */
|
|
34
|
+
function slotsInput(slots) {
|
|
35
|
+
return z.strictObject(Object.fromEntries(Object.entries(slots).map(([slot, choices]) => [slot, z.enum(choices).optional()])));
|
|
36
|
+
}
|
|
37
|
+
/** The fields an agent tool's input can carry to the called agent; a host field takes none of these names. */
|
|
38
|
+
const AGENT_INPUT_FIELDS = new Set([
|
|
39
|
+
'text',
|
|
40
|
+
'attachments',
|
|
41
|
+
'voice',
|
|
42
|
+
'slots',
|
|
43
|
+
'speech',
|
|
44
|
+
]);
|
|
45
|
+
/**
|
|
46
|
+
* What the model sent, split into what goes to the called agent and what only the host reads.
|
|
47
|
+
*
|
|
48
|
+
* why: A host field is the host's own word for something (an id it resolves); the called profile does not take it, so it never reaches the agent's turn.
|
|
49
|
+
*/
|
|
50
|
+
function splitHostInput(tool, input) {
|
|
51
|
+
if (!tool.hostFields)
|
|
52
|
+
return { sent: input };
|
|
53
|
+
const all = { ...input };
|
|
54
|
+
const hostInput = {};
|
|
55
|
+
for (const field of Object.keys(tool.hostFields)) {
|
|
56
|
+
if (all[field] !== undefined)
|
|
57
|
+
hostInput[field] = all[field];
|
|
58
|
+
}
|
|
59
|
+
const { text, attachments, voice, slots, speech } = input;
|
|
60
|
+
return {
|
|
61
|
+
sent: {
|
|
62
|
+
text,
|
|
63
|
+
...(attachments ? { attachments } : {}),
|
|
64
|
+
...(voice ? { voice } : {}),
|
|
65
|
+
...(slots ? { slots } : {}),
|
|
66
|
+
...(speech ? { speech } : {}),
|
|
67
|
+
},
|
|
68
|
+
hostInput,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* The input of an agent tool that runs `agent`: text, and each channel the
|
|
73
|
+
* profile's `inputs` declares. Anything else is refused, never dropped. The
|
|
74
|
+
* called turn's own ingress checks MIME types and sizes.
|
|
75
|
+
*/
|
|
76
|
+
function agentToolInputFor(agent, tool) {
|
|
77
|
+
const { inputs } = agent;
|
|
78
|
+
const shape = { text: textInput };
|
|
79
|
+
if (inputs?.attachments) {
|
|
80
|
+
shape.attachments = z.array(z.union([blobInput, mediaRefInput])).optional();
|
|
81
|
+
}
|
|
82
|
+
if (inputs?.voice)
|
|
83
|
+
shape.voice = z.array(blobInput).optional();
|
|
84
|
+
if (inputs?.slots)
|
|
85
|
+
shape.slots = slotsInput(inputs.slots).optional();
|
|
86
|
+
if (agent.type === 'speech')
|
|
87
|
+
shape.speech = speechInput.optional();
|
|
88
|
+
for (const channel of tool?.hostOnly ?? []) {
|
|
89
|
+
if (!shape[channel]) {
|
|
90
|
+
throw new TheoremError('config', `Tool '${tool?.name}' keeps '${channel}' for the host, which its profile does not take`);
|
|
91
|
+
}
|
|
92
|
+
delete shape[channel];
|
|
93
|
+
}
|
|
94
|
+
for (const [field, text] of Object.entries(tool?.fieldText ?? {})) {
|
|
95
|
+
const schema = shape[field];
|
|
96
|
+
if (!schema) {
|
|
97
|
+
throw new TheoremError('config', `Tool '${tool?.name}' describes '${field}', which its profile does not take`);
|
|
98
|
+
}
|
|
99
|
+
shape[field] = schema.describe(text);
|
|
100
|
+
}
|
|
101
|
+
for (const [field, schema] of Object.entries(tool?.hostFields ?? {})) {
|
|
102
|
+
if (AGENT_INPUT_FIELDS.has(field)) {
|
|
103
|
+
throw new TheoremError('config', `Tool '${tool?.name}' declares the host field '${field}', which is a field of every agent tool`);
|
|
104
|
+
}
|
|
105
|
+
shape[field] = schema;
|
|
106
|
+
}
|
|
107
|
+
// why: The shape is built key by key from the profile, which zod cannot type; each key is an `AgentToolInput` field.
|
|
108
|
+
return z.strictObject(shape);
|
|
109
|
+
}
|
|
110
|
+
const agentToolOutput = z.object({
|
|
111
|
+
text: z.string().optional(),
|
|
112
|
+
structured: z.unknown().optional(),
|
|
113
|
+
removed: z
|
|
114
|
+
.array(z.object({ path: z.string(), reason: z.string(), item: z.unknown() }))
|
|
115
|
+
.optional(),
|
|
116
|
+
parts: z.array(interactionPartSchema).optional(),
|
|
117
|
+
sources: z.array(sourceSchema).optional(),
|
|
118
|
+
});
|
|
119
|
+
function profileTakesText(profile) {
|
|
120
|
+
if (profile.type === 'speech')
|
|
121
|
+
return true;
|
|
122
|
+
return (profile.type === 'text' || profile.type === 'image') && profile.inputs.text !== false;
|
|
123
|
+
}
|
|
124
|
+
/** A tool that can stop the turn on a gate: a gate inside the called agent has no one to answer it. */
|
|
125
|
+
function toolCanGate(tool) {
|
|
126
|
+
if (tool.type === 'builtin')
|
|
127
|
+
return false;
|
|
128
|
+
if (tool.permission !== 'auto')
|
|
129
|
+
return true;
|
|
130
|
+
return ('auth' in tool && tool.auth !== undefined && (tool.auth.onUnauthenticated ?? 'gate') === 'gate');
|
|
131
|
+
}
|
|
132
|
+
/** Why `profile` can't be run by an agent tool, or `undefined` when it can. */
|
|
133
|
+
function agentProfileProblem(profile, find) {
|
|
134
|
+
if (!AGENT_TOOL_TYPES.has(profile.type)) {
|
|
135
|
+
return `it is a ${profile.type} profile; an agent tool runs a text, image, or speech profile`; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
136
|
+
}
|
|
137
|
+
if (!profileTakesText(profile))
|
|
138
|
+
return 'it does not take text'; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
139
|
+
for (const id of profileToolAllow(profile)) {
|
|
140
|
+
const tool = find(id);
|
|
141
|
+
if (!tool)
|
|
142
|
+
return `its tool '${id}' is not registered; register it first`; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
143
|
+
if (toolCanGate(tool)) {
|
|
144
|
+
return `its tool '${id}' can stop on a gate; give it permission 'auto' and no sign-in`; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return undefined;
|
|
148
|
+
}
|
|
149
|
+
/** The profile an agent tool runs; throws `config` when the tool can't run it. */
|
|
150
|
+
function agentToolProfile(def, findProfile, findTool) {
|
|
151
|
+
const tag = `Agent tool "${def.name}"`; // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
152
|
+
const max = def.maxCallsPerTurn;
|
|
153
|
+
if (max !== undefined && !(Number.isInteger(max) && max > 0)) {
|
|
154
|
+
throw new TheoremError('config', `${tag}: maxCallsPerTurn must be a whole number above 0`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
155
|
+
}
|
|
156
|
+
const profile = findProfile(def.profile);
|
|
157
|
+
if (!profile) {
|
|
158
|
+
throw new TheoremError('config', `${tag}: profile '${def.profile}' must be registered before the tool`);
|
|
159
|
+
}
|
|
160
|
+
const problem = agentProfileProblem(profile, findTool);
|
|
161
|
+
if (problem) {
|
|
162
|
+
throw new TheoremError('config', `${tag} can't run '${def.profile}': ${problem}`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
163
|
+
}
|
|
164
|
+
return profile;
|
|
165
|
+
}
|
|
166
|
+
/** An agent with no tools of its own read only what it was sent; one with tools may have read outside content. */
|
|
167
|
+
function agentToolOrigin(profile) {
|
|
168
|
+
if (!profile)
|
|
169
|
+
return 'delegated';
|
|
170
|
+
const builtins = 'models' in profile
|
|
171
|
+
? Object.values(profile.models).some((binding) => (binding.builtInTools?.length ?? 0) > 0)
|
|
172
|
+
: false;
|
|
173
|
+
return profileToolAllow(profile).length === 0 && !builtins ? 'local' : 'delegated';
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The called agent's reply: its text or its last structured reply, its media as parts, and what it cited.
|
|
177
|
+
*
|
|
178
|
+
* why: A structured reply's text is the same JSON as a string, so returning both would have the caller's model read the answer twice.
|
|
179
|
+
*/
|
|
180
|
+
function agentToolOutputOf(turn) {
|
|
181
|
+
const events = keptReply(turn);
|
|
182
|
+
const text = events.flatMap((e) => (e.type === 'text' ? [e.text] : [])).join('');
|
|
183
|
+
const reply = findLast(events, (e) => e.type === 'structured');
|
|
184
|
+
const structured = reply?.structured;
|
|
185
|
+
const parts = events.flatMap((e) => e.type === 'media'
|
|
186
|
+
? [
|
|
187
|
+
{
|
|
188
|
+
type: e.media.mimeType.startsWith('audio/') ? 'audio' : 'image',
|
|
189
|
+
mimeType: e.media.mimeType,
|
|
190
|
+
data: e.media.data,
|
|
191
|
+
},
|
|
192
|
+
]
|
|
193
|
+
: []);
|
|
194
|
+
const sources = events.flatMap((e) => (e.type === 'citation' ? e.sources : []));
|
|
195
|
+
return {
|
|
196
|
+
...(structured === undefined ? { text } : { structured }),
|
|
197
|
+
...(reply?.removed?.length ? { removed: reply.removed } : {}),
|
|
198
|
+
...(parts.length > 0 ? { parts } : {}),
|
|
199
|
+
...(sources.length > 0 ? { sources } : {}),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function normalizeAgent(def, input, schemas) {
|
|
203
|
+
return {
|
|
204
|
+
...def,
|
|
205
|
+
type: 'agent',
|
|
206
|
+
input,
|
|
207
|
+
output: agentToolOutput,
|
|
208
|
+
sources: (output) => output.sources ?? [],
|
|
209
|
+
...schemas,
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
export { AgentCallFailed, agentProfileProblem, agentToolInputFor, agentToolOrigin, agentToolOutput, agentToolOutputOf, agentToolProfile, normalizeAgent, splitHostInput, };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { TurnEvent } from '../types.js';
|
|
2
|
+
import type { ToolExecuteSettlement } from './execute.js';
|
|
3
|
+
import { type ToolExecutionCoordinator, type ToolOperationClaim, type ToolOperationIdentity, type ToolOperationOutcome } from './operation.js';
|
|
4
|
+
export declare function coordinateTool(coordinator: ToolExecutionCoordinator | undefined, identity: Omit<ToolOperationIdentity, 'invocationHash'>, invocation: unknown, signal: AbortSignal | undefined, run: (beginBody?: (preparedInput: unknown) => Promise<ToolOperationClaim | undefined>) => AsyncGenerator<TurnEvent, ToolExecuteSettlement>, authorizeReplay?: (outcome: ToolOperationOutcome) => void | Promise<void>): AsyncGenerator<TurnEvent, ToolExecuteSettlement>;
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { TheoremError, throwIfAborted } from '../../guardrails/error.js';
|
|
2
|
+
import { labelText } from '../../guardrails/labels.js';
|
|
3
|
+
import { jsonObjectSchema } from '../json.js';
|
|
4
|
+
import { operationUnavailable, operationWireValue, toolInvocationHash, toolOperationOutcomeSchema, } from './operation.js';
|
|
5
|
+
class ReplayedOperation {
|
|
6
|
+
outcome;
|
|
7
|
+
constructor(outcome) {
|
|
8
|
+
this.outcome = outcome;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
function uncertainError(cause) {
|
|
12
|
+
return new TheoremError('unavailable', labelText('tool.execution_uncertain'), {
|
|
13
|
+
copy: { key: 'tool.execution_uncertain' },
|
|
14
|
+
cause,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
class CoordinatedExecution {
|
|
18
|
+
coordinator;
|
|
19
|
+
operation;
|
|
20
|
+
accepted;
|
|
21
|
+
signal;
|
|
22
|
+
claim;
|
|
23
|
+
committed = false;
|
|
24
|
+
writeFailed = false;
|
|
25
|
+
terminal;
|
|
26
|
+
constructor(coordinator, operation, accepted, signal) {
|
|
27
|
+
this.coordinator = coordinator;
|
|
28
|
+
this.operation = operation;
|
|
29
|
+
this.accepted = accepted;
|
|
30
|
+
this.signal = signal;
|
|
31
|
+
}
|
|
32
|
+
async beginBody(preparedInput) {
|
|
33
|
+
throwIfAborted(this.signal);
|
|
34
|
+
const operation = {
|
|
35
|
+
...this.operation,
|
|
36
|
+
invocation: { accepted: this.accepted, preparedInput: operationWireValue(preparedInput) },
|
|
37
|
+
};
|
|
38
|
+
const result = await this.coordinator.begin(operation);
|
|
39
|
+
if (result.kind === 'settled')
|
|
40
|
+
throw new ReplayedOperation(result.outcome);
|
|
41
|
+
if (result.kind === 'running' || result.kind === 'uncertain')
|
|
42
|
+
throw uncertainError();
|
|
43
|
+
if (result.kind !== 'acquired' || typeof result.claimToken !== 'string' || !result.claimToken)
|
|
44
|
+
throw operationUnavailable();
|
|
45
|
+
this.claim = { ...operation, claimToken: result.claimToken };
|
|
46
|
+
throwIfAborted(this.signal);
|
|
47
|
+
return this.claim;
|
|
48
|
+
}
|
|
49
|
+
observe(event) {
|
|
50
|
+
if (event.type !== 'tool')
|
|
51
|
+
return true;
|
|
52
|
+
if (event.tool.phase === 'complete' || event.tool.phase === 'error') {
|
|
53
|
+
this.terminal = { ...event, tool: event.tool };
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (this.claim && event.tool.phase === 'gate')
|
|
57
|
+
throw uncertainError();
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
async finish(settlement) {
|
|
61
|
+
if (settlement.gated) {
|
|
62
|
+
if (this.claim)
|
|
63
|
+
throw uncertainError();
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
if (!this.terminal)
|
|
67
|
+
throw operationUnavailable();
|
|
68
|
+
const { modelResult, outputRaw, failure, awaiting, denied, callNotStarted, aborted, pendingInject, } = settlement;
|
|
69
|
+
const effects = this.claim ? (failure ? 'unknown' : 'completed') : 'not_started';
|
|
70
|
+
const outcome = {
|
|
71
|
+
event: this.terminal,
|
|
72
|
+
effects,
|
|
73
|
+
replay: {
|
|
74
|
+
modelResult,
|
|
75
|
+
outputRaw,
|
|
76
|
+
failure,
|
|
77
|
+
awaiting,
|
|
78
|
+
denied,
|
|
79
|
+
callNotStarted,
|
|
80
|
+
aborted,
|
|
81
|
+
pendingInject,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
this.writeFailed = true;
|
|
85
|
+
const saved = toolOperationOutcomeSchema.parse(operationWireValue(outcome));
|
|
86
|
+
if (this.claim)
|
|
87
|
+
await this.coordinator.settle(this.claim, saved);
|
|
88
|
+
else
|
|
89
|
+
await this.coordinator.settleNotStarted(this.operation, saved);
|
|
90
|
+
this.committed = true;
|
|
91
|
+
return saved.event;
|
|
92
|
+
}
|
|
93
|
+
replay(error) {
|
|
94
|
+
const saved = toolOperationOutcomeSchema.parse(operationWireValue(error.outcome));
|
|
95
|
+
const { operationId, callId, toolId } = this.operation;
|
|
96
|
+
if (saved.event.tool.operationId !== operationId ||
|
|
97
|
+
saved.event.tool.callId !== callId ||
|
|
98
|
+
saved.event.tool.name !== toolId)
|
|
99
|
+
throw operationUnavailable();
|
|
100
|
+
this.committed = true;
|
|
101
|
+
return saved;
|
|
102
|
+
}
|
|
103
|
+
failure(error) {
|
|
104
|
+
return this.claim && !this.committed ? uncertainError(error) : error;
|
|
105
|
+
}
|
|
106
|
+
async close() {
|
|
107
|
+
if (this.claim && !this.committed) {
|
|
108
|
+
await this.coordinator.markUncertain(this.claim, this.writeFailed ? 'settlement_write_failed' : 'execution_interrupted');
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export async function* coordinateTool(coordinator, identity, invocation, signal, run, authorizeReplay) {
|
|
113
|
+
if (!coordinator)
|
|
114
|
+
return yield* run();
|
|
115
|
+
const accepted = jsonObjectSchema.parse(operationWireValue(invocation));
|
|
116
|
+
const operation = { ...identity, invocationHash: await toolInvocationHash(accepted) };
|
|
117
|
+
const execution = new CoordinatedExecution(coordinator, operation, accepted, signal);
|
|
118
|
+
throwIfAborted(signal);
|
|
119
|
+
const existing = await coordinator.lookup(operation);
|
|
120
|
+
throwIfAborted(signal);
|
|
121
|
+
if (existing?.kind === 'running' || existing?.kind === 'uncertain')
|
|
122
|
+
throw uncertainError();
|
|
123
|
+
if (existing?.kind === 'settled') {
|
|
124
|
+
if (!authorizeReplay)
|
|
125
|
+
throw operationUnavailable();
|
|
126
|
+
const saved = execution.replay(new ReplayedOperation(existing.outcome));
|
|
127
|
+
await authorizeReplay(saved);
|
|
128
|
+
throwIfAborted(signal);
|
|
129
|
+
yield saved.event;
|
|
130
|
+
return saved.replay;
|
|
131
|
+
}
|
|
132
|
+
const iterator = run((input) => execution.beginBody(input));
|
|
133
|
+
try {
|
|
134
|
+
for (;;) {
|
|
135
|
+
const next = await iterator.next();
|
|
136
|
+
if (next.done) {
|
|
137
|
+
const terminal = await execution.finish(next.value);
|
|
138
|
+
if (terminal)
|
|
139
|
+
yield terminal;
|
|
140
|
+
return next.value;
|
|
141
|
+
}
|
|
142
|
+
if (execution.observe(next.value))
|
|
143
|
+
yield next.value;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
if (error instanceof ReplayedOperation) {
|
|
148
|
+
if (!authorizeReplay)
|
|
149
|
+
throw operationUnavailable();
|
|
150
|
+
const saved = execution.replay(error);
|
|
151
|
+
await authorizeReplay(saved);
|
|
152
|
+
yield saved.event;
|
|
153
|
+
return saved.replay;
|
|
154
|
+
}
|
|
155
|
+
throw execution.failure(error);
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
try {
|
|
159
|
+
await execution.close();
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
await iterator.return({});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { type LabelOverrides } from '../../guardrails/labels.js';
|
|
3
|
+
import type { GuardrailEvent, NetworkGuardrailSpec } from '../../guardrails/types.js';
|
|
4
|
+
import type { SpanHandle } from '../../observability/trace-span.js';
|
|
5
|
+
import { type Source } from '../turn-events.js';
|
|
6
|
+
import type { TurnEvent, TurnEventOf } from '../types.js';
|
|
7
|
+
import type { ToolOperationClaim } from './operation.js';
|
|
8
|
+
import type { ToolCallRequest, ToolContext, ToolFailure, ToolLabels, ToolPhaseEvent } from './types.js';
|
|
9
|
+
export type ToolCallBase = Pick<ToolPhaseEvent, 'name' | 'callId'> & {
|
|
10
|
+
operationId?: string;
|
|
11
|
+
/** The call's failed label, from {@linkcode failedActivity}; absent, a failure names the tool. */
|
|
12
|
+
activityFailed?: string;
|
|
13
|
+
};
|
|
14
|
+
export type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
15
|
+
export type ToolPhasePatch = DistributiveOmit<ToolPhaseEvent, keyof ToolCallBase | 'at'>;
|
|
16
|
+
export declare function toolEvent(base: ToolCallBase, patch: ToolPhasePatch): TurnEventOf<'tool'>;
|
|
17
|
+
/**
|
|
18
|
+
* The label a failed call shows: the tool's own, filled from the input the model sent, else the
|
|
19
|
+
* labels' line naming the tool in words.
|
|
20
|
+
*/
|
|
21
|
+
export declare function failedActivity(name: string, profileLabels?: LabelOverrides, labels?: ToolLabels, input?: unknown): string;
|
|
22
|
+
/** The failed label of the call `base` names. */
|
|
23
|
+
export declare function failedActivityOf(base: ToolCallBase): string;
|
|
24
|
+
/** `readBack` is passed when the call's result guard already wrote the model's text. */
|
|
25
|
+
export declare function failureEvent(base: ToolCallBase, failure: ToolFailure, readBack?: string): TurnEventOf<'tool'>;
|
|
26
|
+
/** The first event of every call. */
|
|
27
|
+
export declare function toolCallRequestEvent(base: ToolCallBase, args: Record<string, unknown>, { reasoning, stepId, stepCallCount, }?: Pick<ToolCallRequest, 'reasoning' | 'stepId' | 'stepCallCount'>): TurnEventOf<'tool'>;
|
|
28
|
+
/** Unique: readers join a call's events by it. */
|
|
29
|
+
export declare function newCallId(name: string): string;
|
|
30
|
+
export declare function toolCallArguments(safeInput: unknown): Record<string, unknown>;
|
|
31
|
+
export declare function messageOf(err: unknown): string;
|
|
32
|
+
export declare function sourceEvents(base: ToolCallBase, sources: (output: unknown) => Source[], output: unknown): Generator<TurnEvent>;
|
|
33
|
+
export declare function dispatchToolBody(tool: {
|
|
34
|
+
labels?: ToolLabels;
|
|
35
|
+
}, input: unknown, ctx: ToolContext, base: ToolCallBase, beginBody?: (preparedInput: unknown) => Promise<ToolOperationClaim | undefined>): AsyncGenerator<TurnEvent, ToolOperationClaim | undefined>;
|
|
36
|
+
export declare function startToolExecution<T>(tool: {
|
|
37
|
+
input: z.ZodType<T>;
|
|
38
|
+
}, rawInput: unknown, ctx: ToolContext): {
|
|
39
|
+
ok: true;
|
|
40
|
+
data: T;
|
|
41
|
+
} | {
|
|
42
|
+
ok: false;
|
|
43
|
+
failure: ToolFailure;
|
|
44
|
+
};
|
|
45
|
+
export declare function networkBlockedEvent(): GuardrailEvent;
|
|
46
|
+
export declare function networkBlocked(err: unknown, guardrail?: GuardrailEvent): Generator<TurnEvent, ToolFailure>;
|
|
47
|
+
/**
|
|
48
|
+
* Shared by HTTP and MCP so they cannot diverge on what SSRF enforcement means.
|
|
49
|
+
* The check's time goes on the tool's span, when the call is traced.
|
|
50
|
+
*/
|
|
51
|
+
export declare function guardToolTarget(url: string, ctx: ToolContext, span?: SpanHandle): Generator<TurnEvent, {
|
|
52
|
+
ok: true;
|
|
53
|
+
url: URL;
|
|
54
|
+
} | {
|
|
55
|
+
ok: false;
|
|
56
|
+
failure: ToolFailure;
|
|
57
|
+
}>;
|
|
58
|
+
/** The checks a guarded request runs on its way, timed together: each hop's address, and its lookup. */
|
|
59
|
+
export interface RequestChecks {
|
|
60
|
+
/** Pass as `fetchGuarded`'s `onCheck`. */
|
|
61
|
+
onCheck: (ms: number) => void;
|
|
62
|
+
/** Records the checks once, when any ran, with the block they raised. */
|
|
63
|
+
record: (blocked?: GuardrailEvent) => void;
|
|
64
|
+
}
|
|
65
|
+
export declare function requestChecks(span: SpanHandle | undefined): RequestChecks;
|
|
66
|
+
export declare function toolNetworkPolicy(ctx: ToolContext): NetworkGuardrailSpec | undefined;
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { throwIfAborted } from '../../guardrails/error.js';
|
|
2
|
+
import { labelText } from '../../guardrails/labels.js';
|
|
3
|
+
import { assertSafeUrl } from '../../guardrails/network.js';
|
|
4
|
+
import { resolveGuardrailPolicy } from '../../guardrails/policy.js';
|
|
5
|
+
import { NETWORK_RULES } from '../../guardrails/rules.js';
|
|
6
|
+
import { recordToolCheck } from '../engine/tool-trace.js';
|
|
7
|
+
import { sourceSchema } from '../turn-events.js';
|
|
8
|
+
import { isRecord } from '../util/record.js';
|
|
9
|
+
import { fillActivityLabel, toolNameInWords } from './activity-label.js';
|
|
10
|
+
import { formatToolFailureForModel, formatToolResult } from './model-text.js';
|
|
11
|
+
export function toolEvent(base, patch) {
|
|
12
|
+
return {
|
|
13
|
+
type: 'tool',
|
|
14
|
+
tool: {
|
|
15
|
+
...patch,
|
|
16
|
+
name: base.name,
|
|
17
|
+
callId: base.callId,
|
|
18
|
+
...(base.operationId ? { operationId: base.operationId } : {}),
|
|
19
|
+
at: Date.now(),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The label a failed call shows: the tool's own, filled from the input the model sent, else the
|
|
25
|
+
* labels' line naming the tool in words.
|
|
26
|
+
*/
|
|
27
|
+
export function failedActivity(name, profileLabels, labels, input) {
|
|
28
|
+
return (fillActivityLabel(labels?.activityFailed, { input }) ??
|
|
29
|
+
labelText('tool.activity_failed', { tool: toolNameInWords(name) }, profileLabels));
|
|
30
|
+
}
|
|
31
|
+
/** The failed label of the call `base` names. */
|
|
32
|
+
export function failedActivityOf(base) {
|
|
33
|
+
return base.activityFailed ?? failedActivity(base.name);
|
|
34
|
+
}
|
|
35
|
+
/** `readBack` is passed when the call's result guard already wrote the model's text. */
|
|
36
|
+
export function failureEvent(base, failure, readBack = formatToolResult(formatToolFailureForModel(failure))) {
|
|
37
|
+
return toolEvent(base, {
|
|
38
|
+
phase: 'error',
|
|
39
|
+
failure,
|
|
40
|
+
readBack,
|
|
41
|
+
activityPast: failedActivityOf(base),
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/** The first event of every call. */
|
|
45
|
+
export function toolCallRequestEvent(base, args, { reasoning, stepId, stepCallCount, } = {}) {
|
|
46
|
+
return {
|
|
47
|
+
type: 'tool',
|
|
48
|
+
tool: {
|
|
49
|
+
name: base.name,
|
|
50
|
+
callId: base.callId,
|
|
51
|
+
...(base.operationId ? { operationId: base.operationId } : {}),
|
|
52
|
+
arguments: args,
|
|
53
|
+
...(reasoning?.length ? { reasoning } : {}),
|
|
54
|
+
...(stepId ? { stepId } : {}),
|
|
55
|
+
...(stepCallCount ? { stepCallCount } : {}),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Unique: readers join a call's events by it. */
|
|
60
|
+
export function newCallId(name) {
|
|
61
|
+
return `call_${name}_${crypto.randomUUID()}`;
|
|
62
|
+
}
|
|
63
|
+
export function toolCallArguments(safeInput) {
|
|
64
|
+
if (safeInput === undefined)
|
|
65
|
+
return {};
|
|
66
|
+
return isRecord(safeInput) ? safeInput : { value: safeInput };
|
|
67
|
+
}
|
|
68
|
+
export function messageOf(err) {
|
|
69
|
+
return err instanceof Error ? err.message : String(err);
|
|
70
|
+
}
|
|
71
|
+
function sourcesInvalid(base, message) {
|
|
72
|
+
return toolEvent(base, {
|
|
73
|
+
phase: 'warning',
|
|
74
|
+
warning: { code: 'sources_invalid', message, severity: 'warning' },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
export function* sourceEvents(base, sources, output) {
|
|
78
|
+
let listed;
|
|
79
|
+
try {
|
|
80
|
+
listed = sources(output);
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
yield sourcesInvalid(base, `sources threw: ${messageOf(err)}`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
if (!Array.isArray(listed)) {
|
|
87
|
+
yield sourcesInvalid(base, 'sources must return an array'); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const cited = [];
|
|
91
|
+
const invalid = [];
|
|
92
|
+
listed.forEach((entry, index) => {
|
|
93
|
+
const parsed = sourceSchema.safeParse(entry);
|
|
94
|
+
if (parsed.success)
|
|
95
|
+
cited.push(parsed.data);
|
|
96
|
+
else
|
|
97
|
+
invalid.push(`[${String(index)}] ${parsed.error.issues.map((i) => `${i.path.join('.') || 'source'}: ${i.message}`).join('; ')}`);
|
|
98
|
+
});
|
|
99
|
+
if (invalid.length > 0) {
|
|
100
|
+
yield sourcesInvalid(base, `sources not cited: ${invalid.join(' | ')}`); // labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
101
|
+
}
|
|
102
|
+
if (cited.length > 0)
|
|
103
|
+
yield { type: 'citation', sources: cited, callId: base.callId };
|
|
104
|
+
}
|
|
105
|
+
function toolRunningEvent(tool, rawInput, ctx, base) {
|
|
106
|
+
const edited = ctx.resume?.edited;
|
|
107
|
+
const activity = fillActivityLabel(tool.labels?.activity, { input: rawInput });
|
|
108
|
+
return toolEvent(base, {
|
|
109
|
+
phase: 'running',
|
|
110
|
+
...(edited ? { edited: { from: edited.from, to: toolCallArguments(rawInput) } } : {}),
|
|
111
|
+
...(activity ? { activity } : {}),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export async function* dispatchToolBody(tool, input, ctx, base, beginBody) {
|
|
115
|
+
const claim = await beginBody?.(input);
|
|
116
|
+
throwIfAborted(ctx.signal);
|
|
117
|
+
yield toolRunningEvent(tool, input, ctx, base);
|
|
118
|
+
return claim;
|
|
119
|
+
}
|
|
120
|
+
export function startToolExecution(tool, rawInput, ctx) {
|
|
121
|
+
throwIfAborted(ctx.signal);
|
|
122
|
+
const parsed = tool.input.safeParse(rawInput);
|
|
123
|
+
if (!parsed.success) {
|
|
124
|
+
return {
|
|
125
|
+
ok: false,
|
|
126
|
+
failure: {
|
|
127
|
+
code: 'invalid_input',
|
|
128
|
+
kind: 'bad_response',
|
|
129
|
+
message: labelText('tool.input_invalid', {}, ctx.profile.labels),
|
|
130
|
+
details: parsed.error.flatten(),
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
return { ok: true, data: parsed.data };
|
|
135
|
+
}
|
|
136
|
+
export function networkBlockedEvent() {
|
|
137
|
+
return {
|
|
138
|
+
stage: 'network',
|
|
139
|
+
trust: 'untrusted',
|
|
140
|
+
action: 'block',
|
|
141
|
+
hits: [{ rule: NETWORK_RULES.blocked, severity: 'high' }],
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
export function* networkBlocked(err, guardrail = networkBlockedEvent()) {
|
|
145
|
+
yield { type: 'guardrail', guardrail };
|
|
146
|
+
return { code: 'network_blocked', kind: 'blocked', message: messageOf(err) };
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Shared by HTTP and MCP so they cannot diverge on what SSRF enforcement means.
|
|
150
|
+
* The check's time goes on the tool's span, when the call is traced.
|
|
151
|
+
*/
|
|
152
|
+
export function* guardToolTarget(url, ctx, span) {
|
|
153
|
+
const start = performance.now();
|
|
154
|
+
try {
|
|
155
|
+
const safe = assertSafeUrl(url, toolNetworkPolicy(ctx));
|
|
156
|
+
recordToolCheck(span, 'network', performance.now() - start, undefined);
|
|
157
|
+
return { ok: true, url: safe };
|
|
158
|
+
}
|
|
159
|
+
catch (err) {
|
|
160
|
+
const blocked = networkBlockedEvent();
|
|
161
|
+
recordToolCheck(span, 'network', performance.now() - start, blocked);
|
|
162
|
+
return { ok: false, failure: yield* networkBlocked(err, blocked) };
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
export function requestChecks(span) {
|
|
166
|
+
let ms = 0;
|
|
167
|
+
let ran = false;
|
|
168
|
+
let recorded = false;
|
|
169
|
+
return {
|
|
170
|
+
onCheck: (took) => {
|
|
171
|
+
ms += took;
|
|
172
|
+
ran = true;
|
|
173
|
+
},
|
|
174
|
+
record: (blocked) => {
|
|
175
|
+
if (recorded || !ran)
|
|
176
|
+
return;
|
|
177
|
+
recorded = true;
|
|
178
|
+
recordToolCheck(span, 'network_request', ms, blocked);
|
|
179
|
+
},
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
export function toolNetworkPolicy(ctx) {
|
|
183
|
+
return resolveGuardrailPolicy(ctx.profile.guardrails).network;
|
|
184
|
+
}
|