@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
|
@@ -1,32 +1,57 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { toolBoundary } from '../../guardrails/boundaries.js';
|
|
2
|
+
import { checkDestinationGate } from '../../guardrails/destinations.js';
|
|
3
|
+
import { scopeOf } from '../../guardrails/detect-at.js';
|
|
4
|
+
import { errorKind, isAbortError, TheoremError, throwIfAborted } from '../../guardrails/error.js';
|
|
5
|
+
import { labelText } from '../../guardrails/labels.js';
|
|
3
6
|
import { resolveGuardrailPolicy } from '../../guardrails/policy.js';
|
|
4
|
-
import {
|
|
5
|
-
import { checkTaintGate, guardToolFailureText, guardToolResult, inspectToolArguments, toolCallEvent, } from '../../guardrails/tool-result.js';
|
|
7
|
+
import { checkTaintGate, guardShownValue, guardToolFailureText, guardToolResult, inspectToolArguments, toolCallEvent, } from '../../guardrails/tool-result.js';
|
|
6
8
|
import { recordToolCheck, startToolTrace, } from '../engine/tool-trace.js';
|
|
7
|
-
import {
|
|
9
|
+
import { jsonObjectSchema } from '../json.js';
|
|
10
|
+
import { isAwaitingUserInput } from '../turn-events.js';
|
|
8
11
|
import { isRecord } from '../util/record.js';
|
|
9
12
|
import { fillActivityLabel } from './activity-label.js';
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
+
import { AgentCallFailed, agentToolOrigin } from './agent.js';
|
|
14
|
+
import { coordinateTool } from './coordinate.js';
|
|
15
|
+
import { dispatchToolBody, failedActivity, failedActivityOf, failureEvent, messageOf, networkBlocked, networkBlockedEvent, requestChecks, sourceEvents, startToolExecution, toolCallArguments, toolEvent, } from './events.js';
|
|
16
|
+
import { HandlerEvents } from './handler-events.js';
|
|
17
|
+
import { formatToolFailureForModel, formatToolResult, frameToolFailure } from './model-text.js';
|
|
18
|
+
import { operationUnavailable, operationWireValue } from './operation.js';
|
|
19
|
+
import { checkPermission, gateDetails, isGateResumeDenied, isGateResumeGranted, isResumeContinuation, } from './permission.js';
|
|
13
20
|
import { executeHttpTool, executeMcpTool, failureWithoutSecret, modelResultFromOutput, omitSecret, outcomeFromUnauth, parseToolOutput, refusedCredentialOutcome, resolveToolAuth, withMedia, } from './remote.js';
|
|
14
21
|
import { extractLoadedIds, profileToolAllow, profileToolsSpec, promoteLoadedTools, } from './resolve.js';
|
|
15
22
|
import { plainToolInput } from './schema.js';
|
|
16
23
|
import { CredentialRefusedError, signedInFetch } from './signed-in-fetch.js';
|
|
17
24
|
import { emitGateSettlement, runPostToolStages, runPreToolPipeline, } from './stage-run.js';
|
|
18
25
|
export { checkPermission, isGateResumeGranted, isResumeContinuation, permissionGranted, } from './permission.js';
|
|
19
|
-
|
|
20
|
-
|
|
26
|
+
import { UncheckedOutput } from './unchecked-output.js';
|
|
27
|
+
function originOfTool(tool, tools) {
|
|
28
|
+
if (tool.type === 'agent')
|
|
29
|
+
return agentToolOrigin(tools.findProfile(tool.profile));
|
|
30
|
+
if (tool.type === 'http')
|
|
21
31
|
return 'http';
|
|
22
|
-
if (type === 'mcp')
|
|
32
|
+
if (tool.type === 'mcp')
|
|
23
33
|
return 'mcp';
|
|
24
|
-
if (type === 'builtin')
|
|
34
|
+
if (tool.type === 'builtin')
|
|
25
35
|
return 'builtin';
|
|
26
36
|
return 'local';
|
|
27
37
|
}
|
|
28
|
-
|
|
29
|
-
|
|
38
|
+
/** The kind whose boundaries a tool's calls cross. A provider builtin crosses none. */
|
|
39
|
+
function toolKindOf(tool) {
|
|
40
|
+
return tool.type === 'builtin' ? undefined : tool.type;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The boundary a call of `name` is read at before its tool gets it: none for a provider builtin,
|
|
44
|
+
* whose text the kernel never reads. A call no tool takes is read as a function tool's.
|
|
45
|
+
*/
|
|
46
|
+
export function toolArgumentsBoundary(tools, name) {
|
|
47
|
+
const tool = tools.get(name);
|
|
48
|
+
const kind = tool ? toolKindOf(tool) : 'function';
|
|
49
|
+
return kind && toolBoundary('tool_arguments', kind);
|
|
50
|
+
}
|
|
51
|
+
/** A delegated reply is one hop past the called agent's own tools. */
|
|
52
|
+
function provenanceFor(tool, tools) {
|
|
53
|
+
const origin = originOfTool(tool, tools);
|
|
54
|
+
return { origin, tool: tool.name, depth: origin === 'delegated' ? 2 : 1 };
|
|
30
55
|
}
|
|
31
56
|
function isStreamHandler(handler) {
|
|
32
57
|
return (typeof handler === 'function' &&
|
|
@@ -59,27 +84,14 @@ export function coerceToolResultParts(raw) {
|
|
|
59
84
|
}
|
|
60
85
|
return parts.length > 0 ? parts : undefined;
|
|
61
86
|
}
|
|
87
|
+
/** A tool's output without its `parts` key, which carries media the model receives separately; any other value is returned as it is. */
|
|
62
88
|
export function leanToolResultData(output) {
|
|
63
89
|
if (!isRecord(output))
|
|
64
90
|
return output;
|
|
65
91
|
const { parts: _parts, ...rest } = output;
|
|
66
92
|
return rest;
|
|
67
93
|
}
|
|
68
|
-
|
|
69
|
-
if (event.kind === 'progress') {
|
|
70
|
-
yield toolEvent(base, { phase: 'progress', data: event.data });
|
|
71
|
-
}
|
|
72
|
-
else if (event.kind === 'trace') {
|
|
73
|
-
yield toolEvent(base, { phase: 'trace', step: event.step });
|
|
74
|
-
}
|
|
75
|
-
else if (event.kind === 'artifact') {
|
|
76
|
-
yield toolEvent(base, { phase: 'artifact', artifact: event.artifact });
|
|
77
|
-
}
|
|
78
|
-
else if (event.kind === 'warning') {
|
|
79
|
-
yield toolEvent(base, { phase: 'warning', warning: event.warning });
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
async function* runHandler(handler, input, ctx, base) {
|
|
94
|
+
async function* runHandler(handler, input, ctx, shown) {
|
|
83
95
|
if (isStreamHandler(handler)) {
|
|
84
96
|
let output;
|
|
85
97
|
const gen = handler(input, ctx);
|
|
@@ -89,20 +101,22 @@ async function* runHandler(handler, input, ctx, base) {
|
|
|
89
101
|
output = event.output;
|
|
90
102
|
continue;
|
|
91
103
|
}
|
|
92
|
-
yield*
|
|
104
|
+
yield* shown.show(event);
|
|
93
105
|
}
|
|
106
|
+
yield* shown.end();
|
|
94
107
|
return output;
|
|
95
108
|
}
|
|
96
109
|
const output = await handler(input, ctx);
|
|
97
|
-
return output;
|
|
110
|
+
return output instanceof UncheckedOutput ? output.value : output;
|
|
98
111
|
}
|
|
99
|
-
|
|
112
|
+
/** What the model is told of a function tool's output: a fixed finding for a hidden tool, a finding plus the output for an awaiting-user result, otherwise the tool's own summary or finding and its data. */
|
|
113
|
+
export function projectForModel(tool, output, labels) {
|
|
100
114
|
if (tool.exposeToModel === false) {
|
|
101
|
-
return { finding:
|
|
115
|
+
return { finding: labelText('tool.completed_hidden', {}, labels) };
|
|
102
116
|
}
|
|
103
117
|
if (isAwaitingUserInput(output)) {
|
|
104
118
|
return {
|
|
105
|
-
finding:
|
|
119
|
+
finding: labelText('tool.awaiting_user', { kind: output.kind, prompt: output.prompt }, labels),
|
|
106
120
|
data: leanToolResultData(output),
|
|
107
121
|
};
|
|
108
122
|
}
|
|
@@ -131,7 +145,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
|
|
|
131
145
|
failure: {
|
|
132
146
|
code: 'invalid_output',
|
|
133
147
|
kind: 'bad_response',
|
|
134
|
-
message:
|
|
148
|
+
message: labelText('tool.t2_loader_needs_snapshot', { tool: tool.name }, ctx.profile.labels),
|
|
135
149
|
},
|
|
136
150
|
};
|
|
137
151
|
}
|
|
@@ -142,7 +156,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
|
|
|
142
156
|
failure: {
|
|
143
157
|
code: 'invalid_output',
|
|
144
158
|
kind: 'bad_response',
|
|
145
|
-
message:
|
|
159
|
+
message: labelText('tool.t2_loader_shape', { tool: tool.name }, ctx.profile.labels),
|
|
146
160
|
},
|
|
147
161
|
};
|
|
148
162
|
}
|
|
@@ -158,7 +172,7 @@ function applyT2LoaderPromotion(tools, tool, checkedData, ctx, snapshot) {
|
|
|
158
172
|
failure: {
|
|
159
173
|
code: 'invalid_output',
|
|
160
174
|
kind: 'bad_response',
|
|
161
|
-
message:
|
|
175
|
+
message: labelText('tool.t2_loader_output_invalid', {}, ctx.profile.labels),
|
|
162
176
|
details: rechecked.error.flatten(),
|
|
163
177
|
},
|
|
164
178
|
};
|
|
@@ -176,7 +190,7 @@ function* reviseAfterStages(post, guard, reproject) {
|
|
|
176
190
|
return {
|
|
177
191
|
failure,
|
|
178
192
|
outputRaw: undefined,
|
|
179
|
-
modelResult: yield* guard.failure(failure),
|
|
193
|
+
modelResult: (yield* guard.failure(failure)).modelResult,
|
|
180
194
|
awaiting: false,
|
|
181
195
|
};
|
|
182
196
|
}
|
|
@@ -187,22 +201,33 @@ function* reviseAfterStages(post, guard, reproject) {
|
|
|
187
201
|
return {
|
|
188
202
|
failure: next.failure,
|
|
189
203
|
outputRaw: undefined,
|
|
190
|
-
modelResult: yield* guard.failure(next.failure),
|
|
204
|
+
modelResult: (yield* guard.failure(next.failure)).modelResult,
|
|
205
|
+
awaiting: false,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
const guarded = yield* guard.result(next.modelResult);
|
|
209
|
+
if (guarded.withheld) {
|
|
210
|
+
return {
|
|
211
|
+
failure: guarded.withheld,
|
|
212
|
+
outputRaw: undefined,
|
|
213
|
+
modelResult: guarded.modelResult,
|
|
191
214
|
awaiting: false,
|
|
192
215
|
};
|
|
193
216
|
}
|
|
194
217
|
return {
|
|
195
218
|
outputRaw: next.outputRaw,
|
|
196
|
-
modelResult:
|
|
219
|
+
modelResult: guarded.modelResult,
|
|
197
220
|
awaiting: isAwaitingUserInput(next.outputRaw),
|
|
198
221
|
};
|
|
199
222
|
}
|
|
223
|
+
function pastActivity(labels, input, output) {
|
|
224
|
+
return fillActivityLabel(labels?.activityPast, { input, output });
|
|
225
|
+
}
|
|
200
226
|
function completeEvent(base, settled) {
|
|
201
227
|
const { input, outputRaw, modelResult } = settled;
|
|
202
|
-
const activityPast =
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
});
|
|
228
|
+
const activityPast = settled.labelFailed
|
|
229
|
+
? failedActivityOf(base)
|
|
230
|
+
: pastActivity(settled.labels, input, outputRaw);
|
|
206
231
|
return toolEvent(base, {
|
|
207
232
|
phase: 'complete',
|
|
208
233
|
output: outputRaw,
|
|
@@ -217,16 +242,18 @@ function completeEvent(base, settled) {
|
|
|
217
242
|
*/
|
|
218
243
|
async function* settleToolCall(args) {
|
|
219
244
|
const { base, toolName, callId, input, stages, provisional, guard, reproject, sources } = args;
|
|
220
|
-
|
|
245
|
+
const guarded = yield* 'failure' in provisional
|
|
221
246
|
? guard.failure(provisional.failure)
|
|
222
247
|
: guard.result(provisional.modelResult);
|
|
223
|
-
let
|
|
224
|
-
let
|
|
248
|
+
let modelResult = guarded.modelResult;
|
|
249
|
+
let failure = 'failure' in provisional ? provisional.failure : guarded.withheld;
|
|
250
|
+
let outputRaw = 'outputRaw' in provisional && !failure ? provisional.outputRaw : undefined;
|
|
225
251
|
const callNotStarted = 'callNotStarted' in provisional ? provisional.callNotStarted : undefined;
|
|
226
252
|
let denied = 'denied' in provisional ? provisional.denied : undefined;
|
|
227
253
|
let awaiting = !failure && isAwaitingUserInput(outputRaw);
|
|
228
254
|
let post;
|
|
229
255
|
if (stages) {
|
|
256
|
+
const activityPast = failure ? undefined : pastActivity(args.labels, input, outputRaw);
|
|
230
257
|
post = yield* runPostToolStages({
|
|
231
258
|
stages,
|
|
232
259
|
toolName,
|
|
@@ -235,6 +262,8 @@ async function* settleToolCall(args) {
|
|
|
235
262
|
callNotStarted,
|
|
236
263
|
outputRaw,
|
|
237
264
|
outputModel: modelResult,
|
|
265
|
+
...(activityPast ? { activityPast } : {}),
|
|
266
|
+
activityFailed: failedActivityOf(base),
|
|
238
267
|
failure,
|
|
239
268
|
awaiting: awaiting || undefined,
|
|
240
269
|
mutable: !failure && reproject !== undefined,
|
|
@@ -249,14 +278,26 @@ async function* settleToolCall(args) {
|
|
|
249
278
|
if (!failure && sources)
|
|
250
279
|
yield* sourceEvents(base, sources, outputRaw);
|
|
251
280
|
yield failure
|
|
252
|
-
? failureEvent(base, failure, formatToolResult(modelResult))
|
|
253
|
-
: completeEvent(base, {
|
|
281
|
+
? failureEvent(base, { ...failure, message: String(yield* guard.shown(failure.message)) }, formatToolResult(modelResult))
|
|
282
|
+
: completeEvent(base, {
|
|
283
|
+
input,
|
|
284
|
+
outputRaw: yield* guard.shown(outputRaw),
|
|
285
|
+
modelResult,
|
|
286
|
+
labels: args.labels,
|
|
287
|
+
...(post?.labelFailed ? { labelFailed: true } : {}),
|
|
288
|
+
});
|
|
254
289
|
return {
|
|
255
290
|
modelResult,
|
|
256
291
|
...(failure ? { failure } : { outputRaw }),
|
|
257
292
|
...(denied ? { denied } : {}),
|
|
258
293
|
...(callNotStarted ? { callNotStarted: true } : {}),
|
|
259
294
|
...(awaiting ? { awaiting: true } : {}),
|
|
295
|
+
...stageSettlement(post),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
/** What the after-call stages add to a settlement: a turn to stop, input to hand the model. */
|
|
299
|
+
function stageSettlement(post) {
|
|
300
|
+
return {
|
|
260
301
|
...(post?.abort !== undefined ? { aborted: post.abort } : {}),
|
|
261
302
|
...(post?.inject.length ? { pendingInject: post.inject } : {}),
|
|
262
303
|
};
|
|
@@ -276,16 +317,52 @@ function settleToolFailure(guard, base, failure, stages, args) {
|
|
|
276
317
|
},
|
|
277
318
|
});
|
|
278
319
|
}
|
|
279
|
-
function resultGuard(tool, ctx, snapshot, span) {
|
|
280
|
-
const provenance = provenanceFor(tool);
|
|
320
|
+
function resultGuard(tools, tool, ctx, snapshot, span) {
|
|
321
|
+
const provenance = provenanceFor(tool, tools);
|
|
281
322
|
const policy = resolveGuardrailPolicy(ctx.profile.guardrails);
|
|
282
323
|
const callableTools = snapshot?.executable ?? [];
|
|
283
|
-
const inputs = {
|
|
324
|
+
const inputs = {
|
|
325
|
+
provenance,
|
|
326
|
+
policy,
|
|
327
|
+
kind: toolKindOf(tool),
|
|
328
|
+
callableTools,
|
|
329
|
+
labels: ctx.profile.labels,
|
|
330
|
+
span,
|
|
331
|
+
};
|
|
332
|
+
const { kind } = inputs;
|
|
333
|
+
const handlerEvents = (drafts) => kind && {
|
|
334
|
+
profileId: ctx.profile.id,
|
|
335
|
+
provenance,
|
|
336
|
+
policy,
|
|
337
|
+
boundary: toolBoundary('tool_output', kind),
|
|
338
|
+
shown: toolBoundary('tool_shown', kind),
|
|
339
|
+
callableTools,
|
|
340
|
+
drafts,
|
|
341
|
+
};
|
|
342
|
+
const shown = (value) => showValue(value, inputs);
|
|
343
|
+
const service = isGateResumeGranted(ctx.resume) ? signInService(tool, ctx.resume) : undefined;
|
|
344
|
+
if (!service) {
|
|
345
|
+
return {
|
|
346
|
+
result: (result) => guardResult(result, inputs),
|
|
347
|
+
failure: (failure) => guardFailure(failure, inputs),
|
|
348
|
+
handlerEvents,
|
|
349
|
+
shown,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
const note = labelText('sign_in.done', { service }, ctx.profile.labels);
|
|
284
353
|
return {
|
|
285
|
-
result: (result) => guardResult(result, inputs),
|
|
286
|
-
failure: (failure) => guardFailure(failure, inputs),
|
|
354
|
+
result: (result) => afterSignIn(note, guardResult(result, inputs)),
|
|
355
|
+
failure: (failure) => afterSignIn(note, guardFailure(failure, inputs)),
|
|
356
|
+
handlerEvents,
|
|
357
|
+
shown,
|
|
287
358
|
};
|
|
288
359
|
}
|
|
360
|
+
/** A call the person signed in for tells the model so before what it read back. */
|
|
361
|
+
function* afterSignIn(note, guarded) {
|
|
362
|
+
const read = yield* guarded;
|
|
363
|
+
const modelText = `${note}\n\n${formatToolResult(read.modelResult)}`;
|
|
364
|
+
return { ...read, modelResult: { ...read.modelResult, modelText } };
|
|
365
|
+
}
|
|
289
366
|
async function* runFunctionPreBodyStages(args) {
|
|
290
367
|
const { tool, base, stages, guard } = args;
|
|
291
368
|
const pre = yield* runPreToolPipeline(args);
|
|
@@ -305,7 +382,7 @@ async function* runFunctionPreBodyStages(args) {
|
|
|
305
382
|
...(pre.denied ? { denied: true } : {}),
|
|
306
383
|
});
|
|
307
384
|
}
|
|
308
|
-
function makeReproject(parse, project,
|
|
385
|
+
function makeReproject(parse, project, labels) {
|
|
309
386
|
return (output) => {
|
|
310
387
|
const checked = parse(output);
|
|
311
388
|
if (!checked.success) {
|
|
@@ -314,7 +391,7 @@ function makeReproject(parse, project, lexicon) {
|
|
|
314
391
|
failure: {
|
|
315
392
|
code: 'invalid_output',
|
|
316
393
|
kind: 'bad_response',
|
|
317
|
-
message:
|
|
394
|
+
message: labelText('tool.output_invalid_after_mutate', {}, labels),
|
|
318
395
|
details: checked.error.flatten(),
|
|
319
396
|
},
|
|
320
397
|
};
|
|
@@ -333,31 +410,64 @@ async function* resolveFunctionSignIn(tool, ctx, base) {
|
|
|
333
410
|
return {
|
|
334
411
|
prepared: {
|
|
335
412
|
authHeaders: resolved.headers,
|
|
413
|
+
...(resolved.query ? { query: resolved.query } : {}),
|
|
336
414
|
...(resolved.audience ? { audience: resolved.audience } : {}),
|
|
337
415
|
},
|
|
338
416
|
...(resolved.secret ? { secret: resolved.secret } : {}),
|
|
339
417
|
};
|
|
340
418
|
}
|
|
341
|
-
|
|
342
|
-
|
|
419
|
+
function functionHandlerFailure(error) {
|
|
420
|
+
return {
|
|
421
|
+
code: 'handler_error',
|
|
422
|
+
kind: error instanceof TheoremError ? error.kind : 'failed',
|
|
423
|
+
message: messageOf(error),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
function waitsForPage(tool, ctx) {
|
|
427
|
+
return tool.answeredBy === 'page' && ctx.page === undefined && !ctx.pageExecution;
|
|
428
|
+
}
|
|
429
|
+
async function* receivePageAnswer(tool, ctx, claim, base) {
|
|
430
|
+
const execution = ctx.pageExecution;
|
|
431
|
+
if (tool.answeredBy !== 'page' || !execution)
|
|
432
|
+
return ctx;
|
|
433
|
+
if (!claim?.invocation)
|
|
434
|
+
throw operationUnavailable();
|
|
435
|
+
const argumentsForPage = jsonObjectSchema.parse(operationWireValue(claim.invocation.preparedInput));
|
|
436
|
+
const dispatch = await execution.dispatch(claim, ctx.signal);
|
|
437
|
+
throwIfAborted(ctx.signal);
|
|
438
|
+
if (!dispatch.grantId)
|
|
439
|
+
throw operationUnavailable();
|
|
440
|
+
yield toolEvent(base, {
|
|
441
|
+
phase: 'dispatch',
|
|
442
|
+
grantId: dispatch.grantId,
|
|
443
|
+
arguments: argumentsForPage,
|
|
444
|
+
});
|
|
445
|
+
ctx = { ...ctx, page: await dispatch.result };
|
|
446
|
+
throwIfAborted(ctx.signal);
|
|
447
|
+
return ctx;
|
|
448
|
+
}
|
|
449
|
+
export async function* executeFunction(tools, tool, rawInput, ctx, base, snapshot, stages,
|
|
450
|
+
/** Set when `tool` runs an agent tool: its trust, and its handler's failures and faults. */
|
|
451
|
+
agent, beginBody) {
|
|
452
|
+
const guard = resultGuard(tools, agent ?? tool, ctx, snapshot, stages?.span);
|
|
343
453
|
const callId = base.callId;
|
|
344
|
-
const parsed =
|
|
454
|
+
const parsed = startToolExecution(tool, rawInput, ctx);
|
|
345
455
|
if (!parsed.ok) {
|
|
346
|
-
return yield* settleToolFailure(guard, base, {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
456
|
+
return yield* settleToolFailure(guard, base, parsed.failure, stages, {
|
|
457
|
+
toolName: tool.name,
|
|
458
|
+
callId,
|
|
459
|
+
callNotStarted: true,
|
|
460
|
+
});
|
|
351
461
|
}
|
|
352
462
|
let input = parsed.data;
|
|
353
|
-
const permissionGate = checkPermission(tool.name, tool.permission, ctx.sessionPermissions, ctx.resume);
|
|
463
|
+
const permissionGate = checkPermission(tool.name, tool.permission, ctx.sessionPermissions, ctx.resume, gateDetails(tool, input));
|
|
354
464
|
if (permissionGate) {
|
|
355
465
|
yield* emitGateSettlement({
|
|
356
466
|
base,
|
|
357
467
|
gate: permissionGate,
|
|
358
468
|
callId,
|
|
359
469
|
toolName: tool.name,
|
|
360
|
-
|
|
470
|
+
labels: ctx.profile.labels,
|
|
361
471
|
});
|
|
362
472
|
return { gated: permissionGate, callNotStarted: true };
|
|
363
473
|
}
|
|
@@ -370,7 +480,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
370
480
|
safeInput: input,
|
|
371
481
|
stages,
|
|
372
482
|
guard,
|
|
373
|
-
|
|
483
|
+
labels: ctx.profile.labels,
|
|
374
484
|
});
|
|
375
485
|
const signedIn = yield* resolveFunctionSignIn(tool, ctx, base);
|
|
376
486
|
if (signedIn.outcome)
|
|
@@ -380,7 +490,21 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
380
490
|
return preBody;
|
|
381
491
|
}
|
|
382
492
|
input = preBody.input;
|
|
493
|
+
if (waitsForPage(tool, ctx)) {
|
|
494
|
+
// why: Last of the checks, so the page is asked only for a call every guardrail and gate let through.
|
|
495
|
+
const gate = { kind: 'page', tool: tool.name, ...gateDetails(tool, input) };
|
|
496
|
+
yield* emitGateSettlement({
|
|
497
|
+
base,
|
|
498
|
+
gate,
|
|
499
|
+
callId,
|
|
500
|
+
toolName: tool.name,
|
|
501
|
+
labels: ctx.profile.labels,
|
|
502
|
+
});
|
|
503
|
+
return { gated: gate, callNotStarted: true };
|
|
504
|
+
}
|
|
383
505
|
throwIfAborted(ctx.signal);
|
|
506
|
+
const claim = yield* dispatchToolBody(tool, input, ctx, base, beginBody);
|
|
507
|
+
ctx = yield* receivePageAnswer(tool, ctx, claim, base);
|
|
384
508
|
const { secret } = signedIn;
|
|
385
509
|
const fail = (failure) => settleToolFailure(guard, base, secret ? failureWithoutSecret(failure, secret) : failure, stages, { toolName: tool.name, callId, input });
|
|
386
510
|
const checks = requestChecks(stages?.span);
|
|
@@ -389,13 +513,20 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
389
513
|
: ctx;
|
|
390
514
|
let output;
|
|
391
515
|
try {
|
|
392
|
-
|
|
516
|
+
const shown = new HandlerEvents(base, guard.handlerEvents(stages?.drafts === true));
|
|
517
|
+
output = yield* runHandler(tool.handler, input, handlerCtx, shown);
|
|
393
518
|
checks.record();
|
|
394
519
|
}
|
|
395
520
|
catch (err) {
|
|
521
|
+
if (agent) {
|
|
522
|
+
// why: Anything but a settled failure is the host's to fix, as a compactor's is.
|
|
523
|
+
if (err instanceof AgentCallFailed)
|
|
524
|
+
return yield* fail(err.failure);
|
|
525
|
+
throw err;
|
|
526
|
+
}
|
|
396
527
|
if (signedIn.prepared && err instanceof CredentialRefusedError) {
|
|
397
528
|
checks.record();
|
|
398
|
-
const refused = yield* refusedCredentialOutcome(tool, err.refusal, signedIn.
|
|
529
|
+
const refused = yield* refusedCredentialOutcome(tool, err.refusal, signedIn.secret !== undefined, ctx, base);
|
|
399
530
|
if (refused)
|
|
400
531
|
return yield* settleOutcome(refused);
|
|
401
532
|
}
|
|
@@ -404,7 +535,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
404
535
|
checks.record(blocked);
|
|
405
536
|
return yield* fail(yield* networkBlocked(err, blocked));
|
|
406
537
|
}
|
|
407
|
-
return yield* fail(
|
|
538
|
+
return yield* fail(functionHandlerFailure(err));
|
|
408
539
|
}
|
|
409
540
|
if (secret)
|
|
410
541
|
output = omitSecret(output, secret);
|
|
@@ -412,7 +543,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
412
543
|
return yield* fail({
|
|
413
544
|
code: 'invalid_output',
|
|
414
545
|
kind: 'bad_response',
|
|
415
|
-
message:
|
|
546
|
+
message: labelText('tool.handler_no_output', {}, ctx.profile.labels),
|
|
416
547
|
});
|
|
417
548
|
}
|
|
418
549
|
const checked = tool.output.safeParse(output);
|
|
@@ -420,7 +551,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
420
551
|
return yield* fail({
|
|
421
552
|
code: 'invalid_output',
|
|
422
553
|
kind: 'bad_response',
|
|
423
|
-
message:
|
|
554
|
+
message: labelText('tool.output_invalid', {}, ctx.profile.labels),
|
|
424
555
|
details: checked.error.flatten(),
|
|
425
556
|
});
|
|
426
557
|
}
|
|
@@ -428,7 +559,7 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
428
559
|
if (!promoted.ok) {
|
|
429
560
|
return yield* fail(promoted.failure);
|
|
430
561
|
}
|
|
431
|
-
// The T2 loader's output drives the snapshot, so the host may not mutate it.
|
|
562
|
+
// why: The T2 loader's output drives the snapshot, so the host may not mutate it.
|
|
432
563
|
const ownsOutput = loadsT2(tool, ctx);
|
|
433
564
|
return yield* settleToolCall({
|
|
434
565
|
base,
|
|
@@ -439,25 +570,24 @@ export async function* executeFunction(tools, tool, rawInput, ctx, base, snapsho
|
|
|
439
570
|
guard,
|
|
440
571
|
provisional: {
|
|
441
572
|
outputRaw: promoted.output,
|
|
442
|
-
modelResult: projectForModel(tool, promoted.output, ctx.profile.
|
|
573
|
+
modelResult: projectForModel(tool, promoted.output, ctx.profile.labels),
|
|
443
574
|
},
|
|
444
575
|
sources: tool.sources,
|
|
445
576
|
labels: tool.labels,
|
|
446
577
|
...(ownsOutput
|
|
447
578
|
? {}
|
|
448
579
|
: {
|
|
449
|
-
reproject: makeReproject((v) => tool.output.safeParse(v), (data) => projectForModel(tool, data, ctx.profile.
|
|
580
|
+
reproject: makeReproject((v) => tool.output.safeParse(v), (data) => projectForModel(tool, data, ctx.profile.labels), ctx.profile.labels),
|
|
450
581
|
}),
|
|
451
582
|
});
|
|
452
583
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
return lexiconText('tool.not_loaded_t2', { tool: tool.name }, lexicon);
|
|
584
|
+
/** Names the profile's loader when it can load the tool, so the model knows which call comes first. */
|
|
585
|
+
export function notLoadedMessage(tool, profile) {
|
|
586
|
+
const loader = profileToolsSpec(profile)?.t2Loader;
|
|
587
|
+
if (tool.loadTier === 'T2' && loader) {
|
|
588
|
+
return labelText('tool.not_loaded_t2', { tool: tool.name, loader }, profile.labels);
|
|
459
589
|
}
|
|
460
|
-
return
|
|
590
|
+
return labelText('tool.not_visible', { tool: tool.name }, profile.labels);
|
|
461
591
|
}
|
|
462
592
|
function earlyFailure(failure) {
|
|
463
593
|
return { failure, callNotStarted: true, modelResult: formatToolFailureForModel(failure) };
|
|
@@ -469,7 +599,7 @@ export async function* executeBuiltin(tool, ctx, base, snapshot) {
|
|
|
469
599
|
const failure = {
|
|
470
600
|
code: 'not_loaded',
|
|
471
601
|
kind: 'request',
|
|
472
|
-
message:
|
|
602
|
+
message: labelText('tool.builtin_not_enabled', { tool: tool.name }, ctx.profile.labels),
|
|
473
603
|
};
|
|
474
604
|
yield failureEvent(base, failure);
|
|
475
605
|
return earlyFailure(failure);
|
|
@@ -477,7 +607,7 @@ export async function* executeBuiltin(tool, ctx, base, snapshot) {
|
|
|
477
607
|
const failure = {
|
|
478
608
|
code: 'provider_native',
|
|
479
609
|
kind: 'request',
|
|
480
|
-
message:
|
|
610
|
+
message: labelText('tool.provider_native', { tool: tool.name }, ctx.profile.labels),
|
|
481
611
|
};
|
|
482
612
|
yield failureEvent(base, failure);
|
|
483
613
|
return earlyFailure(failure);
|
|
@@ -488,7 +618,7 @@ function registeredEligibilityFailure(args) {
|
|
|
488
618
|
return {
|
|
489
619
|
code: 'not_allowed',
|
|
490
620
|
kind: 'blocked',
|
|
491
|
-
message:
|
|
621
|
+
message: labelText('tool.not_allowed', { tool: name, profile: profile.id }, profile.labels),
|
|
492
622
|
};
|
|
493
623
|
}
|
|
494
624
|
if (!snapshot)
|
|
@@ -498,24 +628,46 @@ function registeredEligibilityFailure(args) {
|
|
|
498
628
|
return {
|
|
499
629
|
code: 'not_gated',
|
|
500
630
|
kind: 'request',
|
|
501
|
-
message:
|
|
631
|
+
message: labelText('tool.not_eligible', { tool: name }, profile.labels),
|
|
502
632
|
};
|
|
503
633
|
}
|
|
504
|
-
if (!snapshot.visible.includes(name)) {
|
|
634
|
+
if (!(args.visible ?? snapshot.visible).includes(name)) {
|
|
505
635
|
const skipLoadCheck = continuing && tool.loadTier === 'T0';
|
|
506
636
|
if (!skipLoadCheck) {
|
|
507
637
|
return {
|
|
508
638
|
code: 'not_loaded',
|
|
509
639
|
kind: 'request',
|
|
510
|
-
message: notLoadedMessage(tool, profile
|
|
640
|
+
message: notLoadedMessage(tool, profile),
|
|
511
641
|
};
|
|
512
642
|
}
|
|
513
643
|
}
|
|
514
644
|
return undefined;
|
|
515
645
|
}
|
|
646
|
+
export function authorizeToolReplay(args) {
|
|
647
|
+
const tool = args.tools.get(args.name);
|
|
648
|
+
if (!tool || tool.type === 'builtin') {
|
|
649
|
+
throw new TheoremError('blocked', labelText('error.blocked'));
|
|
650
|
+
}
|
|
651
|
+
const failure = registeredEligibilityFailure({ ...args, tool });
|
|
652
|
+
if (failure)
|
|
653
|
+
throw new TheoremError(failure.kind, failure.message);
|
|
654
|
+
if (args.outcome)
|
|
655
|
+
authorizeSavedDisclosure(args, tool, args.outcome);
|
|
656
|
+
}
|
|
657
|
+
function authorizeSavedDisclosure(args, tool, outcome) {
|
|
658
|
+
const blocked = () => new TheoremError('blocked', labelText('detect.output_blocked', {}, args.profile.labels));
|
|
659
|
+
const result = outcome.replay.modelResult;
|
|
660
|
+
if (tool.type === 'function' &&
|
|
661
|
+
tool.exposeToModel === false &&
|
|
662
|
+
result?.finding !== labelText('tool.completed_hidden', {}, args.profile.labels))
|
|
663
|
+
throw blocked();
|
|
664
|
+
const guard = guardToolResult(outcome.event.tool.readBack ?? '', { event: outcome.event, output: outcome.replay.outputRaw }, provenanceFor(tool, args.tools), resolveGuardrailPolicy(args.profile.guardrails), tool.type === 'builtin' ? undefined : toolBoundary('tool_output', tool.type), args.snapshot?.executable ?? [], args.profile.labels);
|
|
665
|
+
if (guard.event?.action === 'block' || guard.event?.action === 'redact')
|
|
666
|
+
throw blocked();
|
|
667
|
+
}
|
|
516
668
|
/** Settles an outcome the kernel reached without a handler's own result: a remote body, or a sign-in. */
|
|
517
669
|
async function* settleBodyOutcome(args) {
|
|
518
|
-
const { outcome, tool, base, callId, safeInput, stages, guard,
|
|
670
|
+
const { outcome, tool, base, callId, safeInput, stages, guard, labels } = args;
|
|
519
671
|
const name = tool.name;
|
|
520
672
|
if (outcome.kind === 'gated') {
|
|
521
673
|
if (outcome.gate.kind === 'confirmation') {
|
|
@@ -526,7 +678,7 @@ async function* settleBodyOutcome(args) {
|
|
|
526
678
|
gate: outcome.gate,
|
|
527
679
|
callId,
|
|
528
680
|
toolName: name,
|
|
529
|
-
|
|
681
|
+
labels,
|
|
530
682
|
});
|
|
531
683
|
return { gated: outcome.gate, callNotStarted: true, ...(gateReadBack ? { gateReadBack } : {}) };
|
|
532
684
|
}
|
|
@@ -553,8 +705,8 @@ async function* settleBodyOutcome(args) {
|
|
|
553
705
|
sources: tool.sources,
|
|
554
706
|
labels: tool.labels,
|
|
555
707
|
reproject: makeReproject((v) => parseToolOutput(tool.output, v),
|
|
556
|
-
// A hook's edit replaces the value; the media the tool returned stays.
|
|
557
|
-
(data) => withMedia(modelResultFromOutput(data), outcome.modelResult.parts),
|
|
708
|
+
// why: A hook's edit replaces the value; the media the tool returned stays.
|
|
709
|
+
(data) => withMedia(modelResultFromOutput(data), outcome.modelResult.parts), labels),
|
|
558
710
|
});
|
|
559
711
|
}
|
|
560
712
|
function turnReadBack({ modelResult }) {
|
|
@@ -562,9 +714,9 @@ function turnReadBack({ modelResult }) {
|
|
|
562
714
|
? { text: formatToolResult(modelResult), parts: modelResult.parts }
|
|
563
715
|
: undefined;
|
|
564
716
|
}
|
|
565
|
-
/** The service a
|
|
566
|
-
function
|
|
567
|
-
if (!resume?.signIn || tool.type === 'builtin')
|
|
717
|
+
/** The service a sign-in gate's answer names, from the tool's own auth config. */
|
|
718
|
+
function signInService(tool, resume) {
|
|
719
|
+
if (!resume?.signIn || tool.type === 'builtin' || tool.type === 'agent')
|
|
568
720
|
return undefined;
|
|
569
721
|
return tool.auth?.service;
|
|
570
722
|
}
|
|
@@ -572,34 +724,34 @@ function refusedSignInService(tool, resume) {
|
|
|
572
724
|
* A gate nobody answered: a sign-in for `expiredService` whose link expired, or any other gate
|
|
573
725
|
* left behind. Both settle as `cancelled`.
|
|
574
726
|
*/
|
|
575
|
-
export function lapsedGateFailure(toolName, expiredService,
|
|
727
|
+
export function lapsedGateFailure(toolName, expiredService, labels) {
|
|
576
728
|
if (expiredService) {
|
|
577
729
|
return {
|
|
578
730
|
code: 'expired',
|
|
579
731
|
kind: 'cancelled',
|
|
580
|
-
message:
|
|
732
|
+
message: labelText('sign_in.expired', { service: expiredService }, labels),
|
|
581
733
|
};
|
|
582
734
|
}
|
|
583
735
|
return {
|
|
584
736
|
code: 'cancelled',
|
|
585
737
|
kind: 'cancelled',
|
|
586
|
-
message:
|
|
738
|
+
message: labelText('session.abandon_gated', { tool: toolName }, labels),
|
|
587
739
|
};
|
|
588
740
|
}
|
|
589
741
|
/** `abandoned` and `expired` settle as `cancelled`. */
|
|
590
|
-
function refusalFailure(tool, resume,
|
|
591
|
-
const service =
|
|
742
|
+
function refusalFailure(tool, resume, labels) {
|
|
743
|
+
const service = signInService(tool, resume);
|
|
592
744
|
const cause = resume?.cause ?? 'declined';
|
|
593
745
|
if (cause === 'declined') {
|
|
594
746
|
return {
|
|
595
747
|
code: 'denied',
|
|
596
748
|
kind: 'declined',
|
|
597
749
|
message: service
|
|
598
|
-
?
|
|
599
|
-
:
|
|
750
|
+
? labelText('sign_in.declined', { service }, labels)
|
|
751
|
+
: labelText('session.tool_denied', { tool: tool.name }, labels),
|
|
600
752
|
};
|
|
601
753
|
}
|
|
602
|
-
return lapsedGateFailure(tool.name, cause === 'expired' ? service : undefined,
|
|
754
|
+
return lapsedGateFailure(tool.name, cause === 'expired' ? service : undefined, labels);
|
|
603
755
|
}
|
|
604
756
|
function resumeApproval(resume) {
|
|
605
757
|
if (isGateResumeGranted(resume))
|
|
@@ -629,7 +781,53 @@ function toolCallEnd(settlement, readBack) {
|
|
|
629
781
|
...(failure ? { failure } : {}),
|
|
630
782
|
};
|
|
631
783
|
}
|
|
784
|
+
/** Runs one registered tool call as a stream of turn events and returns how it settled; when `openSpan` is given the call is recorded as a tool span that ends with the outcome. */
|
|
785
|
+
/**
|
|
786
|
+
* A call's arguments as its tool gets them, which is what the call's first
|
|
787
|
+
* event shows the host: a detector's placeholder where it redacts, and none
|
|
788
|
+
* when the call is stopped. A call no tool takes is read as a function tool's.
|
|
789
|
+
*/
|
|
790
|
+
export function shownToolArguments(call) {
|
|
791
|
+
const tool = call.tools.get(call.name);
|
|
792
|
+
const policy = resolveGuardrailPolicy(call.profile.guardrails);
|
|
793
|
+
const inspected = inspectToolArguments(plainToolInput(call.input), tool ? provenanceFor(tool, call.tools) : { origin: 'local', tool: call.name, depth: 1 }, policy, toolArgumentsBoundary(call.tools, call.name), scopeOf(policy, call.scope ?? {}));
|
|
794
|
+
const { args } = inspected;
|
|
795
|
+
return args !== null && typeof args === 'object' && !Array.isArray(args)
|
|
796
|
+
? args
|
|
797
|
+
: {};
|
|
798
|
+
}
|
|
632
799
|
export async function* executeRegisteredTool(args) {
|
|
800
|
+
args = {
|
|
801
|
+
...args,
|
|
802
|
+
ctx: { ...args.ctx, operationId: args.ctx.operationId ?? crypto.randomUUID() },
|
|
803
|
+
};
|
|
804
|
+
return yield* coordinateTool(args.execution, {
|
|
805
|
+
operationId: args.ctx.operationId ?? crypto.randomUUID(),
|
|
806
|
+
callId: args.callId,
|
|
807
|
+
profileId: args.profile.id,
|
|
808
|
+
toolId: args.name,
|
|
809
|
+
}, {
|
|
810
|
+
input: args.input,
|
|
811
|
+
resume: args.ctx.resume,
|
|
812
|
+
snapshot: args.snapshot,
|
|
813
|
+
context: args.invocation,
|
|
814
|
+
}, args.ctx.signal, (beginBody) => executeTracedTool({
|
|
815
|
+
...args,
|
|
816
|
+
beginBody: async (input) => {
|
|
817
|
+
const claim = (await beginBody?.(input)) ?? (await args.beginBody?.(input));
|
|
818
|
+
args.onDispatch?.();
|
|
819
|
+
return claim;
|
|
820
|
+
},
|
|
821
|
+
}), (outcome) => authorizeToolReplay({
|
|
822
|
+
outcome,
|
|
823
|
+
tools: args.tools,
|
|
824
|
+
profile: args.profile,
|
|
825
|
+
name: args.name,
|
|
826
|
+
resume: args.ctx.resume,
|
|
827
|
+
snapshot: args.snapshot,
|
|
828
|
+
}));
|
|
829
|
+
}
|
|
830
|
+
async function* executeTracedTool(args) {
|
|
633
831
|
const tool = args.tools.get(args.name);
|
|
634
832
|
if (!args.openSpan) {
|
|
635
833
|
return yield* runRegisteredTool(args, tool);
|
|
@@ -638,7 +836,7 @@ export async function* executeRegisteredTool(args) {
|
|
|
638
836
|
name: args.name,
|
|
639
837
|
callId: args.callId,
|
|
640
838
|
call: { arguments: toolCallArguments(plainToolInput(args.input)) },
|
|
641
|
-
origin: tool ? originOfTool(tool.
|
|
839
|
+
origin: tool ? originOfTool(tool, args.tools) : undefined,
|
|
642
840
|
permission: tool && 'permission' in tool ? tool.permission : undefined,
|
|
643
841
|
approved: resumeApproval(args.ctx.resume),
|
|
644
842
|
step: args.ctx.turn?.step,
|
|
@@ -664,7 +862,7 @@ export async function* executeRegisteredTool(args) {
|
|
|
664
862
|
throw err;
|
|
665
863
|
}
|
|
666
864
|
finally {
|
|
667
|
-
// The host stopped reading mid-call.
|
|
865
|
+
// why: The host stopped reading mid-call.
|
|
668
866
|
if (!trace.span.ended) {
|
|
669
867
|
trace.end({ outcome: 'cancelled' });
|
|
670
868
|
await exec.return({});
|
|
@@ -674,12 +872,18 @@ export async function* executeRegisteredTool(args) {
|
|
|
674
872
|
async function* runRegisteredTool(args, tool) {
|
|
675
873
|
const { profile, name, input, callId, ctx, snapshot, stages } = args;
|
|
676
874
|
const safeInput = plainToolInput(input);
|
|
677
|
-
const
|
|
875
|
+
const operationId = ctx.operationId ?? crypto.randomUUID();
|
|
876
|
+
const base = {
|
|
877
|
+
name,
|
|
878
|
+
callId,
|
|
879
|
+
operationId,
|
|
880
|
+
activityFailed: failedActivity(name, profile.labels, tool?.labels, safeInput),
|
|
881
|
+
};
|
|
678
882
|
if (!tool) {
|
|
679
883
|
const failure = {
|
|
680
884
|
code: 'unknown_tool',
|
|
681
885
|
kind: 'request',
|
|
682
|
-
message:
|
|
886
|
+
message: labelText('tool.not_registered', { tool: name }, profile.labels),
|
|
683
887
|
};
|
|
684
888
|
yield failureEvent(base, failure);
|
|
685
889
|
return earlyFailure(failure);
|
|
@@ -689,12 +893,12 @@ async function* runRegisteredTool(args, tool) {
|
|
|
689
893
|
const failure = {
|
|
690
894
|
code: 'provider_native',
|
|
691
895
|
kind: 'request',
|
|
692
|
-
message:
|
|
896
|
+
message: labelText('tool.builtin_needs_snapshot', { tool: name }, profile.labels),
|
|
693
897
|
};
|
|
694
898
|
yield failureEvent(base, failure);
|
|
695
899
|
return earlyFailure(failure);
|
|
696
900
|
}
|
|
697
|
-
const fullCtx = { ...ctx, callId, profile };
|
|
901
|
+
const fullCtx = { ...ctx, callId, profile, operationId };
|
|
698
902
|
return yield* executeBuiltin(tool, fullCtx, base, snapshot);
|
|
699
903
|
}
|
|
700
904
|
const eligibility = registeredEligibilityFailure({
|
|
@@ -703,25 +907,36 @@ async function* runRegisteredTool(args, tool) {
|
|
|
703
907
|
name,
|
|
704
908
|
resume: ctx.resume,
|
|
705
909
|
snapshot,
|
|
910
|
+
visible: ctx.turn?.visible,
|
|
706
911
|
});
|
|
707
912
|
if (eligibility) {
|
|
708
913
|
yield failureEvent(base, eligibility);
|
|
709
914
|
return earlyFailure(eligibility);
|
|
710
915
|
}
|
|
711
916
|
if (isGateResumeDenied(ctx.resume)) {
|
|
712
|
-
return yield* settleToolFailure(resultGuard(tool, { ...ctx, callId, profile }, snapshot, stages?.span), base, refusalFailure(tool, ctx.resume, profile.
|
|
917
|
+
return yield* settleToolFailure(resultGuard(args.tools, tool, { ...ctx, callId, profile, operationId }, snapshot, stages?.span), base, refusalFailure(tool, ctx.resume, profile.labels), stages, { toolName: name, callId, input: safeInput, callNotStarted: true, denied: true });
|
|
713
918
|
}
|
|
714
|
-
const fullCtx = { ...ctx, callId, profile };
|
|
919
|
+
const fullCtx = { ...ctx, callId, profile, operationId };
|
|
715
920
|
const policy = resolveGuardrailPolicy(profile.guardrails);
|
|
716
|
-
const provenance = provenanceFor(tool);
|
|
921
|
+
const provenance = provenanceFor(tool, args.tools);
|
|
717
922
|
const argsStart = performance.now();
|
|
718
|
-
const
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
923
|
+
const kind = toolKindOf(tool);
|
|
924
|
+
const inspected = inspectToolArguments(safeInput, provenance, policy, kind && toolBoundary('tool_arguments', kind), scopeOf(policy, args.scope ?? {}));
|
|
925
|
+
recordToolCheck(stages?.span, 'tool_arguments', performance.now() - argsStart, inspected.event);
|
|
926
|
+
if (inspected.event) {
|
|
927
|
+
yield { type: 'guardrail', guardrail: inspected.event };
|
|
928
|
+
}
|
|
929
|
+
if (!('args' in inspected)) {
|
|
930
|
+
const failure = {
|
|
931
|
+
code: 'arguments_blocked',
|
|
932
|
+
kind: 'blocked',
|
|
933
|
+
message: labelText('detect.call_blocked', {}, profile.labels),
|
|
934
|
+
};
|
|
935
|
+
yield failureEvent(base, failure);
|
|
936
|
+
return { ...earlyFailure(failure), denied: true };
|
|
722
937
|
}
|
|
723
938
|
const taintStart = performance.now();
|
|
724
|
-
const taintVerdict = checkTaintGate(ctx.turn?.taint, tool.access, policy, profile.
|
|
939
|
+
const taintVerdict = checkTaintGate(ctx.turn?.taint, tool.access, policy, profile.labels);
|
|
725
940
|
const taintEvent = toolCallEvent(taintVerdict, provenance);
|
|
726
941
|
recordToolCheck(stages?.span, 'taint', performance.now() - taintStart, taintEvent);
|
|
727
942
|
if (taintEvent) {
|
|
@@ -736,23 +951,155 @@ async function* runRegisteredTool(args, tool) {
|
|
|
736
951
|
yield failureEvent(base, failure);
|
|
737
952
|
return { ...earlyFailure(failure), denied: true };
|
|
738
953
|
}
|
|
739
|
-
|
|
954
|
+
const stopped = yield* settleRemoteDestination({
|
|
955
|
+
tool,
|
|
956
|
+
input: inspected.args,
|
|
957
|
+
ctx: fullCtx,
|
|
958
|
+
base,
|
|
959
|
+
provenance,
|
|
960
|
+
policy,
|
|
961
|
+
span: stages?.span,
|
|
962
|
+
});
|
|
963
|
+
if (stopped)
|
|
964
|
+
return stopped;
|
|
965
|
+
return yield* settleByType(args.tools, tool, inspected.args, fullCtx, base, snapshot, stages, args.agents, args.beginBody);
|
|
966
|
+
}
|
|
967
|
+
/** The call's settlement when a destination in its arguments stops it: refused, or held for the user's answer. */
|
|
968
|
+
async function* settleRemoteDestination(args) {
|
|
969
|
+
const { tool, input, ctx, base } = args;
|
|
970
|
+
const { labels } = ctx.profile;
|
|
971
|
+
const start = performance.now();
|
|
972
|
+
const { verdict, confirm } = checkDestinationGate(ctx.turn?.destinations, input, args.policy, labels);
|
|
973
|
+
const event = toolCallEvent(verdict, args.provenance);
|
|
974
|
+
recordToolCheck(args.span, 'destination', performance.now() - start, event);
|
|
975
|
+
if (event) {
|
|
976
|
+
yield { type: 'guardrail', guardrail: event };
|
|
977
|
+
}
|
|
978
|
+
if (verdict.action === 'block') {
|
|
979
|
+
const failure = {
|
|
980
|
+
code: 'remote_destination',
|
|
981
|
+
kind: 'blocked',
|
|
982
|
+
message: verdict.rejection,
|
|
983
|
+
};
|
|
984
|
+
yield failureEvent(base, failure);
|
|
985
|
+
return { ...earlyFailure(failure), denied: true };
|
|
986
|
+
}
|
|
987
|
+
if (!confirm || isGateResumeGranted(ctx.resume))
|
|
988
|
+
return undefined;
|
|
989
|
+
const gate = {
|
|
990
|
+
kind: 'confirmation',
|
|
991
|
+
tool: tool.name,
|
|
992
|
+
summary: confirm,
|
|
993
|
+
...gateDetails(tool, input),
|
|
994
|
+
};
|
|
995
|
+
yield* emitGateSettlement({
|
|
996
|
+
base,
|
|
997
|
+
gate,
|
|
998
|
+
callId: ctx.callId,
|
|
999
|
+
toolName: tool.name,
|
|
1000
|
+
labels,
|
|
1001
|
+
});
|
|
1002
|
+
return { gated: gate, callNotStarted: true };
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* An agent tool runs as a function tool whose handler is the called agent's
|
|
1006
|
+
* turn, so input checks, gates, stages, and the result guard are the same. The
|
|
1007
|
+
* agent's reply streams as the call's drafts and its other events as its
|
|
1008
|
+
* `progress`, and its usage rides on the call's last phase.
|
|
1009
|
+
*/
|
|
1010
|
+
async function* executeAgentTool(args) {
|
|
1011
|
+
const { tool, ctx, base, agents } = args;
|
|
1012
|
+
if (!agents) {
|
|
1013
|
+
const failure = {
|
|
1014
|
+
code: 'unknown_tool',
|
|
1015
|
+
kind: 'unsupported',
|
|
1016
|
+
message: labelText('tool.unsupported_type', { tool: tool.name }, ctx.profile.labels),
|
|
1017
|
+
};
|
|
1018
|
+
yield failureEvent(base, failure);
|
|
1019
|
+
return earlyFailure(failure);
|
|
1020
|
+
}
|
|
1021
|
+
let tokens;
|
|
1022
|
+
const span = args.stages?.span;
|
|
1023
|
+
const handler = async function* (input, handlerCtx) {
|
|
1024
|
+
const run = agents.run({
|
|
1025
|
+
tool,
|
|
1026
|
+
callId: handlerCtx.callId,
|
|
1027
|
+
// why: Checked against the tool's input schema before the handler runs.
|
|
1028
|
+
input: input,
|
|
1029
|
+
caller: handlerCtx.profile,
|
|
1030
|
+
...(span ? { span } : {}),
|
|
1031
|
+
...(handlerCtx.signal ? { signal: handlerCtx.signal } : {}),
|
|
1032
|
+
});
|
|
1033
|
+
// why: A retry throws away the reply drafted so far; the drafts stop there, and the output arrives whole.
|
|
1034
|
+
let retried = false;
|
|
1035
|
+
for (;;) {
|
|
1036
|
+
const next = await run.next();
|
|
1037
|
+
if (next.done) {
|
|
1038
|
+
tokens = next.value.tokens;
|
|
1039
|
+
if ('failure' in next.value)
|
|
1040
|
+
throw new AgentCallFailed(next.value.failure);
|
|
1041
|
+
yield { kind: 'complete', output: next.value.output };
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
const event = next.value;
|
|
1045
|
+
if (event.type === 'attempt')
|
|
1046
|
+
retried = true;
|
|
1047
|
+
if (event.type === 'text' || event.type === 'structured_draft') {
|
|
1048
|
+
if (!retried)
|
|
1049
|
+
yield { kind: 'draft', text: event.text };
|
|
1050
|
+
continue;
|
|
1051
|
+
}
|
|
1052
|
+
yield { kind: 'progress', data: { agent: tool.profile, event } };
|
|
1053
|
+
}
|
|
1054
|
+
};
|
|
1055
|
+
// why: Its hooks take `AgentToolInput`, which the input schema has already checked.
|
|
1056
|
+
const asFunction = { ...tool, type: 'function', handler };
|
|
1057
|
+
const exec = executeFunction(args.tools, asFunction, args.safeInput, ctx, base, args.snapshot, args.stages, tool, args.beginBody);
|
|
1058
|
+
for (;;) {
|
|
1059
|
+
const next = await exec.next();
|
|
1060
|
+
if (next.done)
|
|
1061
|
+
return next.value;
|
|
1062
|
+
yield withAgentTokens(next.value, base.callId, tokens);
|
|
1063
|
+
}
|
|
1064
|
+
}
|
|
1065
|
+
/** The called agent's usage on the call's `complete` or `error` phase. */
|
|
1066
|
+
function withAgentTokens(event, callId, tokens) {
|
|
1067
|
+
if (!tokens || event.type !== 'tool' || event.tool.callId !== callId)
|
|
1068
|
+
return event;
|
|
1069
|
+
const { tool } = event;
|
|
1070
|
+
if (tool.phase !== 'complete' && tool.phase !== 'error')
|
|
1071
|
+
return event;
|
|
1072
|
+
return { ...event, tool: { ...tool, tokens } };
|
|
740
1073
|
}
|
|
741
|
-
async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, stages) {
|
|
1074
|
+
async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, stages, agents, beginBody) {
|
|
742
1075
|
const { name } = tool;
|
|
743
1076
|
if (tool.type === 'function') {
|
|
744
|
-
return yield* executeFunction(tools, tool, safeInput, fullCtx, base, snapshot, stages);
|
|
1077
|
+
return yield* executeFunction(tools, tool, safeInput, fullCtx, base, snapshot, stages, undefined, beginBody);
|
|
1078
|
+
}
|
|
1079
|
+
if (tool.type === 'agent') {
|
|
1080
|
+
return yield* executeAgentTool({
|
|
1081
|
+
tools,
|
|
1082
|
+
tool,
|
|
1083
|
+
safeInput,
|
|
1084
|
+
ctx: fullCtx,
|
|
1085
|
+
base,
|
|
1086
|
+
snapshot,
|
|
1087
|
+
stages,
|
|
1088
|
+
agents,
|
|
1089
|
+
beginBody,
|
|
1090
|
+
});
|
|
745
1091
|
}
|
|
746
1092
|
if (tool.type !== 'http' && tool.type !== 'mcp') {
|
|
747
1093
|
return earlyFailure({
|
|
748
1094
|
code: 'unknown_tool',
|
|
749
1095
|
kind: 'request',
|
|
750
|
-
message:
|
|
1096
|
+
message: labelText('tool.unsupported_type', { tool: name }, fullCtx.profile.labels),
|
|
751
1097
|
});
|
|
752
1098
|
}
|
|
1099
|
+
const guard = resultGuard(tools, tool, fullCtx, snapshot, stages?.span);
|
|
753
1100
|
const remoteOutcome = tool.type === 'http'
|
|
754
|
-
? yield* executeHttpTool(tool, safeInput, fullCtx, base, stages)
|
|
755
|
-
: yield* executeMcpTool(tool, safeInput, fullCtx, base, stages, tools.mcpSessions);
|
|
1101
|
+
? yield* executeHttpTool(tool, safeInput, fullCtx, base, stages, beginBody, new HandlerEvents(base, guard.handlerEvents(stages?.drafts === true)))
|
|
1102
|
+
: yield* executeMcpTool(tool, safeInput, fullCtx, base, stages, tools.mcpSessions, beginBody);
|
|
756
1103
|
return yield* settleBodyOutcome({
|
|
757
1104
|
outcome: remoteOutcome,
|
|
758
1105
|
tool,
|
|
@@ -760,37 +1107,62 @@ async function* settleByType(tools, tool, safeInput, fullCtx, base, snapshot, st
|
|
|
760
1107
|
callId: base.callId,
|
|
761
1108
|
safeInput,
|
|
762
1109
|
stages,
|
|
763
|
-
guard
|
|
764
|
-
|
|
1110
|
+
guard,
|
|
1111
|
+
labels: fullCtx.profile.labels,
|
|
765
1112
|
});
|
|
766
1113
|
}
|
|
767
1114
|
/**
|
|
768
|
-
* A
|
|
769
|
-
*
|
|
770
|
-
*
|
|
771
|
-
*
|
|
1115
|
+
* A remote server writes its own error strings, so a failure's message is read
|
|
1116
|
+
* at `tool_failure_<kind>` before the kernel frames it for the model as a system
|
|
1117
|
+
* report. A blocked message is replaced by the labels' words. The framed
|
|
1118
|
+
* report is the kernel's own text and is not read again.
|
|
772
1119
|
*/
|
|
773
1120
|
function* guardFailure(failure, guard) {
|
|
774
1121
|
const start = performance.now();
|
|
775
|
-
const checked = guardToolFailureText(failure.message, guard.provenance,
|
|
776
|
-
...guard.policy,
|
|
777
|
-
sanitizeInput: true,
|
|
778
|
-
redactSensitive: resolveSensitive(true),
|
|
779
|
-
});
|
|
1122
|
+
const checked = guardToolFailureText(failure.message, guard.provenance, guard.policy, guard.kind && toolBoundary('tool_failure', guard.kind));
|
|
780
1123
|
recordToolCheck(guard.span, 'tool_failure', performance.now() - start, checked.event);
|
|
781
1124
|
if (checked.event) {
|
|
782
1125
|
yield { type: 'guardrail', guardrail: checked.event };
|
|
783
1126
|
}
|
|
784
|
-
|
|
1127
|
+
const message = checked.text ?? labelText('detect.output_blocked', {}, guard.labels);
|
|
1128
|
+
return { modelResult: yield* reportFailure({ ...failure, message }, guard) };
|
|
785
1129
|
}
|
|
1130
|
+
/** A failure framed for the model in the kernel's own words, fenced and labelled like any result. */
|
|
1131
|
+
function* reportFailure(failure, guard) {
|
|
1132
|
+
const framed = frameToolFailure(failure);
|
|
1133
|
+
return (yield* readBack(framed, guard, undefined)) ?? framed;
|
|
1134
|
+
}
|
|
1135
|
+
/** A result read at `tool_output_<kind>`. A blocked one settles as a failed call the model is told about. */
|
|
786
1136
|
function* guardResult(result, guard) {
|
|
1137
|
+
const read = yield* readBack(result, guard, guard.kind && toolBoundary('tool_output', guard.kind));
|
|
1138
|
+
if (read)
|
|
1139
|
+
return { modelResult: read };
|
|
1140
|
+
const withheld = {
|
|
1141
|
+
code: 'output_blocked',
|
|
1142
|
+
kind: 'blocked',
|
|
1143
|
+
message: labelText('detect.output_blocked', {}, guard.labels),
|
|
1144
|
+
};
|
|
1145
|
+
return { modelResult: yield* reportFailure(withheld, guard), withheld };
|
|
1146
|
+
}
|
|
1147
|
+
/** What the person is shown of `value`, read at `tool_shown_<kind>`; a blocked one is the labels' words. */
|
|
1148
|
+
function* showValue(value, guard) {
|
|
1149
|
+
const boundary = guard.kind && toolBoundary('tool_shown', guard.kind);
|
|
1150
|
+
const shown = guardShownValue(value, guard.provenance, guard.policy, boundary);
|
|
1151
|
+
if (shown.event)
|
|
1152
|
+
yield { type: 'guardrail', guardrail: shown.event };
|
|
1153
|
+
return 'value' in shown ? shown.value : labelText('detect.shown_blocked', {}, guard.labels);
|
|
1154
|
+
}
|
|
1155
|
+
/** What the model reads of `result`, or `undefined` when a match at `boundary` blocks it. */
|
|
1156
|
+
function* readBack(result, guard, boundary) {
|
|
787
1157
|
const { provenance, span } = guard;
|
|
788
1158
|
const start = performance.now();
|
|
789
|
-
const guarded = guardToolResult(result.finding, result.data, provenance, guard.policy, guard.callableTools, guard.
|
|
1159
|
+
const guarded = guardToolResult(result.finding, result.data, provenance, guard.policy, boundary, guard.callableTools, guard.labels);
|
|
790
1160
|
recordToolCheck(span, 'tool_result', performance.now() - start, guarded.event);
|
|
791
1161
|
if (guarded.event) {
|
|
792
1162
|
yield { type: 'guardrail', guardrail: guarded.event };
|
|
793
1163
|
}
|
|
1164
|
+
if (guarded.text === undefined)
|
|
1165
|
+
return undefined;
|
|
794
1166
|
return {
|
|
795
1167
|
...result,
|
|
796
1168
|
modelText: guarded.text,
|