@theoremjs/agents 0.0.0-stage → 0.3.0
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 +1264 -2
- package/esm/_dnt.polyfills.d.ts +66 -0
- package/esm/_dnt.polyfills.js +51 -0
- package/esm/mod.d.ts +65 -0
- package/esm/mod.js +42 -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 +458 -0
- package/esm/src/cli/commands/egress-compile.d.ts +17 -0
- package/esm/src/cli/commands/egress-compile.js +25 -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 +202 -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 +25 -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 +72 -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 +4 -0
- package/esm/src/evals/attachments.js +53 -0
- package/esm/src/evals/breakdown.d.ts +28 -0
- package/esm/src/evals/breakdown.js +68 -0
- package/esm/src/evals/graders/answer.d.ts +13 -0
- package/esm/src/evals/graders/answer.js +133 -0
- package/esm/src/evals/graders/code.d.ts +64 -0
- package/esm/src/evals/graders/code.js +205 -0
- package/esm/src/evals/graders/judge.d.ts +20 -0
- package/esm/src/evals/graders/judge.js +365 -0
- package/esm/src/evals/graders/latency.d.ts +5 -0
- package/esm/src/evals/graders/latency.js +81 -0
- package/esm/src/evals/graders/live.d.ts +11 -0
- package/esm/src/evals/graders/live.js +40 -0
- package/esm/src/evals/graders/media.d.ts +18 -0
- package/esm/src/evals/graders/media.js +92 -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 +17 -0
- package/esm/src/evals/graders/transcript.js +200 -0
- package/esm/src/evals/mod.d.ts +42 -0
- package/esm/src/evals/mod.js +30 -0
- package/esm/src/evals/record.d.ts +35 -0
- package/esm/src/evals/record.js +105 -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 +118 -0
- package/esm/src/evals/run.js +452 -0
- package/esm/src/evals/suite.d.ts +19 -0
- package/esm/src/evals/suite.js +92 -0
- package/esm/src/evals/summary.d.ts +32 -0
- package/esm/src/evals/summary.js +30 -0
- package/esm/src/evals/trial.d.ts +27 -0
- package/esm/src/evals/trial.js +158 -0
- package/esm/src/evals/types.d.ts +260 -0
- package/esm/src/evals/types.js +126 -0
- package/esm/src/evals/verdict.d.ts +18 -0
- package/esm/src/evals/verdict.js +45 -0
- package/esm/src/guardrails/canary-gate.d.ts +21 -0
- package/esm/src/guardrails/canary-gate.js +40 -0
- package/esm/src/guardrails/canary.d.ts +112 -0
- package/esm/src/guardrails/canary.js +901 -0
- package/esm/src/guardrails/compile-egress.d.ts +11 -0
- package/esm/src/guardrails/compile-egress.js +11 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +22 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +303 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +202 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +3 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +118 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +13 -0
- package/esm/src/guardrails/corpus/live-attacks.js +224 -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 +32 -0
- package/esm/src/guardrails/corpus/types.js +1 -0
- package/esm/src/guardrails/egress-automata.d.ts +14 -0
- package/esm/src/guardrails/egress-automata.js +6059 -0
- package/esm/src/guardrails/egress-compiler.d.ts +33 -0
- package/esm/src/guardrails/egress-compiler.js +237 -0
- package/esm/src/guardrails/egress-patterns.d.ts +24 -0
- package/esm/src/guardrails/egress-patterns.js +32 -0
- package/esm/src/guardrails/egress-policy.d.ts +27 -0
- package/esm/src/guardrails/egress-policy.js +76 -0
- package/esm/src/guardrails/egress-rules.d.ts +54 -0
- package/esm/src/guardrails/egress-rules.js +49 -0
- package/esm/src/guardrails/egress-stream.d.ts +105 -0
- package/esm/src/guardrails/egress-stream.js +645 -0
- package/esm/src/guardrails/egress-urls.d.ts +83 -0
- package/esm/src/guardrails/egress-urls.js +917 -0
- package/esm/src/guardrails/egress.d.ts +106 -0
- package/esm/src/guardrails/egress.js +374 -0
- package/esm/src/guardrails/error.d.ts +26 -0
- package/esm/src/guardrails/error.js +91 -0
- package/esm/src/guardrails/event-schemas.d.ts +57 -0
- package/esm/src/guardrails/event-schemas.js +41 -0
- package/esm/src/guardrails/events.d.ts +9 -0
- package/esm/src/guardrails/events.js +42 -0
- package/esm/src/guardrails/hits.d.ts +8 -0
- package/esm/src/guardrails/hits.js +19 -0
- package/esm/src/guardrails/injection-patterns.d.ts +15 -0
- package/esm/src/guardrails/injection-patterns.js +94 -0
- package/esm/src/guardrails/injection.d.ts +14 -0
- package/esm/src/guardrails/injection.js +237 -0
- package/esm/src/guardrails/lexicon.d.ts +30 -0
- package/esm/src/guardrails/lexicon.js +478 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +54 -0
- package/esm/src/guardrails/live-outbound-gate.js +305 -0
- package/esm/src/guardrails/mod.d.ts +46 -0
- package/esm/src/guardrails/mod.js +29 -0
- package/esm/src/guardrails/network.d.ts +42 -0
- package/esm/src/guardrails/network.js +328 -0
- package/esm/src/guardrails/normalize.d.ts +6 -0
- package/esm/src/guardrails/normalize.js +132 -0
- package/esm/src/guardrails/policy.d.ts +19 -0
- package/esm/src/guardrails/policy.js +50 -0
- package/esm/src/guardrails/progressive-yield.d.ts +69 -0
- package/esm/src/guardrails/progressive-yield.js +237 -0
- package/esm/src/guardrails/prompt-echo.d.ts +38 -0
- package/esm/src/guardrails/prompt-echo.js +225 -0
- package/esm/src/guardrails/quota.d.ts +20 -0
- package/esm/src/guardrails/quota.js +80 -0
- package/esm/src/guardrails/rules.d.ts +56 -0
- package/esm/src/guardrails/rules.js +54 -0
- package/esm/src/guardrails/sanitize.d.ts +23 -0
- package/esm/src/guardrails/sanitize.js +184 -0
- package/esm/src/guardrails/sensitive.d.ts +29 -0
- package/esm/src/guardrails/sensitive.js +113 -0
- package/esm/src/guardrails/serialize.d.ts +14 -0
- package/esm/src/guardrails/serialize.js +37 -0
- package/esm/src/guardrails/testing.d.ts +9 -0
- package/esm/src/guardrails/testing.js +8 -0
- package/esm/src/guardrails/theorem-error.d.ts +18 -0
- package/esm/src/guardrails/theorem-error.js +53 -0
- package/esm/src/guardrails/thought-guard.d.ts +55 -0
- package/esm/src/guardrails/thought-guard.js +464 -0
- package/esm/src/guardrails/tool-directives.d.ts +19 -0
- package/esm/src/guardrails/tool-directives.js +109 -0
- package/esm/src/guardrails/tool-result.d.ts +61 -0
- package/esm/src/guardrails/tool-result.js +248 -0
- package/esm/src/guardrails/types.d.ts +242 -0
- package/esm/src/guardrails/types.js +54 -0
- package/esm/src/host/client-turn.d.ts +9 -0
- package/esm/src/host/client-turn.js +38 -0
- package/esm/src/host/mint-trace.d.ts +28 -0
- package/esm/src/host/mint-trace.js +59 -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 +68 -0
- package/esm/src/host/reply.d.ts +7 -0
- package/esm/src/host/reply.js +35 -0
- package/esm/src/interface/blocks.d.ts +8 -0
- package/esm/src/interface/blocks.js +213 -0
- package/esm/src/interface/composer-actions.d.ts +20 -0
- package/esm/src/interface/composer-actions.js +31 -0
- package/esm/src/interface/draft.d.ts +14 -0
- package/esm/src/interface/draft.js +28 -0
- package/esm/src/interface/from-profile.d.ts +12 -0
- package/esm/src/interface/from-profile.js +144 -0
- package/esm/src/interface/history.d.ts +40 -0
- package/esm/src/interface/history.js +269 -0
- package/esm/src/interface/inputs.d.ts +10 -0
- package/esm/src/interface/inputs.js +64 -0
- package/esm/src/interface/mod.d.ts +31 -0
- package/esm/src/interface/mod.js +21 -0
- package/esm/src/interface/models.d.ts +19 -0
- package/esm/src/interface/models.js +45 -0
- package/esm/src/interface/pending.d.ts +48 -0
- package/esm/src/interface/pending.js +146 -0
- package/esm/src/interface/profile-interface.d.ts +4 -0
- package/esm/src/interface/profile-interface.js +223 -0
- package/esm/src/interface/session.d.ts +64 -0
- package/esm/src/interface/session.js +121 -0
- package/esm/src/interface/tool-calls.d.ts +20 -0
- package/esm/src/interface/tool-calls.js +73 -0
- package/esm/src/interface/tool-invoke.d.ts +4 -0
- package/esm/src/interface/tool-invoke.js +20 -0
- package/esm/src/interface/tool-media.d.ts +9 -0
- package/esm/src/interface/tool-media.js +112 -0
- package/esm/src/interface/types.d.ts +213 -0
- package/esm/src/interface/types.js +4 -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 +51 -0
- package/esm/src/kernel/auth/crypto.js +161 -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 +17 -0
- package/esm/src/kernel/auth/oauth.js +438 -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 +139 -0
- package/esm/src/kernel/auth/types.js +1 -0
- package/esm/src/kernel/default-scope.d.ts +34 -0
- package/esm/src/kernel/default-scope.js +72 -0
- package/esm/src/kernel/engine/compaction.d.ts +70 -0
- package/esm/src/kernel/engine/compaction.js +202 -0
- package/esm/src/kernel/engine/decision.d.ts +41 -0
- package/esm/src/kernel/engine/decision.js +412 -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 +9 -0
- package/esm/src/kernel/engine/live-inbound.js +19 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +9 -0
- package/esm/src/kernel/engine/live-ingress.js +37 -0
- package/esm/src/kernel/engine/media-probe/audio.d.ts +7 -0
- package/esm/src/kernel/engine/media-probe/audio.js +342 -0
- package/esm/src/kernel/engine/media-probe/bytes.d.ts +6 -0
- package/esm/src/kernel/engine/media-probe/bytes.js +26 -0
- package/esm/src/kernel/engine/media-probe/image.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/image.js +171 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +19 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.js +48 -0
- package/esm/src/kernel/engine/media-probe/matroska.d.ts +35 -0
- package/esm/src/kernel/engine/media-probe/matroska.js +226 -0
- package/esm/src/kernel/engine/media-probe/mp4.d.ts +22 -0
- package/esm/src/kernel/engine/media-probe/mp4.js +279 -0
- package/esm/src/kernel/engine/media-probe/opus.d.ts +4 -0
- package/esm/src/kernel/engine/media-probe/opus.js +23 -0
- package/esm/src/kernel/engine/media-probe/pdf.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/pdf.js +117 -0
- package/esm/src/kernel/engine/media-probe/video.d.ts +15 -0
- package/esm/src/kernel/engine/media-probe/video.js +49 -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 +322 -0
- package/esm/src/kernel/engine/runner/mod.d.ts +15 -0
- package/esm/src/kernel/engine/runner/mod.js +574 -0
- package/esm/src/kernel/engine/runner/schema-validation.d.ts +14 -0
- package/esm/src/kernel/engine/runner/schema-validation.js +105 -0
- package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
- package/esm/src/kernel/engine/runner/stages.js +48 -0
- package/esm/src/kernel/engine/runner/state.d.ts +76 -0
- package/esm/src/kernel/engine/runner/state.js +40 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
- package/esm/src/kernel/engine/runner/steps.js +360 -0
- package/esm/src/kernel/engine/runner/stream.d.ts +40 -0
- package/esm/src/kernel/engine/runner/stream.js +225 -0
- package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
- package/esm/src/kernel/engine/runner/usage.js +150 -0
- package/esm/src/kernel/engine/session/mod.d.ts +31 -0
- package/esm/src/kernel/engine/session/mod.js +951 -0
- package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
- package/esm/src/kernel/engine/session/session-trace.js +489 -0
- package/esm/src/kernel/engine/token-estimate.d.ts +77 -0
- package/esm/src/kernel/engine/token-estimate.js +218 -0
- package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
- package/esm/src/kernel/engine/tool-trace.js +131 -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 +118 -0
- package/esm/src/kernel/engine/turn-trace.js +863 -0
- package/esm/src/kernel/engine/usage.d.ts +30 -0
- package/esm/src/kernel/engine/usage.js +134 -0
- package/esm/src/kernel/interaction-parts.d.ts +10 -0
- package/esm/src/kernel/interaction-parts.js +22 -0
- package/esm/src/kernel/mod.d.ts +47 -0
- package/esm/src/kernel/mod.js +30 -0
- package/esm/src/kernel/profile-graph.d.ts +140 -0
- package/esm/src/kernel/profile-graph.js +151 -0
- package/esm/src/kernel/profile-presence.d.ts +9 -0
- package/esm/src/kernel/profile-presence.js +143 -0
- package/esm/src/kernel/profile-scope.d.ts +36 -0
- package/esm/src/kernel/profile-scope.js +262 -0
- package/esm/src/kernel/registry/attachments.d.ts +35 -0
- package/esm/src/kernel/registry/attachments.js +211 -0
- package/esm/src/kernel/registry/catalog.d.ts +19 -0
- package/esm/src/kernel/registry/catalog.js +78 -0
- package/esm/src/kernel/registry/ingress.d.ts +8 -0
- package/esm/src/kernel/registry/ingress.js +134 -0
- package/esm/src/kernel/registry/kernel-registry.d.ts +12 -0
- package/esm/src/kernel/registry/kernel-registry.js +8 -0
- package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
- package/esm/src/kernel/registry/profile-outputs.js +7 -0
- package/esm/src/kernel/registry/profiles.d.ts +92 -0
- package/esm/src/kernel/registry/profiles.js +698 -0
- package/esm/src/kernel/registry/provider-request.d.ts +6 -0
- package/esm/src/kernel/registry/provider-request.js +42 -0
- package/esm/src/kernel/registry/resolve.d.ts +14 -0
- package/esm/src/kernel/registry/resolve.js +237 -0
- package/esm/src/kernel/registry/schemas.d.ts +9 -0
- package/esm/src/kernel/registry/schemas.js +25 -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 +33 -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 +13 -0
- package/esm/src/kernel/registry/vault.js +14 -0
- package/esm/src/kernel/schema.d.ts +172 -0
- package/esm/src/kernel/schema.js +653 -0
- package/esm/src/kernel/scope.d.ts +22 -0
- package/esm/src/kernel/scope.js +25 -0
- package/esm/src/kernel/stages.d.ts +141 -0
- package/esm/src/kernel/stages.js +388 -0
- package/esm/src/kernel/stop.d.ts +93 -0
- package/esm/src/kernel/stop.js +125 -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 +16 -0
- package/esm/src/kernel/tools/activity-label.js +209 -0
- package/esm/src/kernel/tools/events.d.ts +51 -0
- package/esm/src/kernel/tools/events.js +149 -0
- package/esm/src/kernel/tools/execute.d.ts +64 -0
- package/esm/src/kernel/tools/execute.js +801 -0
- package/esm/src/kernel/tools/gate-answer.d.ts +50 -0
- package/esm/src/kernel/tools/gate-answer.js +54 -0
- package/esm/src/kernel/tools/harness.d.ts +16 -0
- package/esm/src/kernel/tools/harness.js +42 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +129 -0
- package/esm/src/kernel/tools/mcp-sessions.d.ts +20 -0
- package/esm/src/kernel/tools/mcp-sessions.js +64 -0
- package/esm/src/kernel/tools/mod.d.ts +9 -0
- package/esm/src/kernel/tools/mod.js +6 -0
- package/esm/src/kernel/tools/model-text.d.ts +11 -0
- package/esm/src/kernel/tools/model-text.js +25 -0
- package/esm/src/kernel/tools/permission.d.ts +6 -0
- package/esm/src/kernel/tools/permission.js +38 -0
- package/esm/src/kernel/tools/project.d.ts +8 -0
- package/esm/src/kernel/tools/project.js +25 -0
- package/esm/src/kernel/tools/registry.d.ts +20 -0
- package/esm/src/kernel/tools/registry.js +84 -0
- package/esm/src/kernel/tools/remote.d.ts +110 -0
- package/esm/src/kernel/tools/remote.js +998 -0
- package/esm/src/kernel/tools/resolve.d.ts +28 -0
- package/esm/src/kernel/tools/resolve.js +259 -0
- package/esm/src/kernel/tools/schema.d.ts +10 -0
- package/esm/src/kernel/tools/schema.js +174 -0
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +18 -0
- package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
- package/esm/src/kernel/tools/stage-run.d.ts +93 -0
- package/esm/src/kernel/tools/stage-run.js +140 -0
- package/esm/src/kernel/tools/types.d.ts +287 -0
- package/esm/src/kernel/tools/types.js +1 -0
- package/esm/src/kernel/turn-events.d.ts +599 -0
- package/esm/src/kernel/turn-events.js +425 -0
- package/esm/src/kernel/types.d.ts +884 -0
- package/esm/src/kernel/types.js +1 -0
- package/esm/src/kernel/util/base64.d.ts +2 -0
- package/esm/src/kernel/util/base64.js +13 -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/record.d.ts +1 -0
- package/esm/src/kernel/util/record.js +3 -0
- package/esm/src/observability/destinations.d.ts +9 -0
- package/esm/src/observability/destinations.js +38 -0
- package/esm/src/observability/jsonl.d.ts +18 -0
- package/esm/src/observability/jsonl.js +117 -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 +68 -0
- package/esm/src/observability/otlp.js +98 -0
- package/esm/src/observability/phoenix.d.ts +29 -0
- package/esm/src/observability/phoenix.js +71 -0
- package/esm/src/observability/policy.d.ts +14 -0
- package/esm/src/observability/policy.js +69 -0
- package/esm/src/observability/resolve-policy.d.ts +8 -0
- package/esm/src/observability/resolve-policy.js +58 -0
- package/esm/src/observability/spans.d.ts +16 -0
- package/esm/src/observability/spans.js +56 -0
- package/esm/src/observability/trace-catalog.d.ts +111 -0
- package/esm/src/observability/trace-catalog.js +865 -0
- package/esm/src/observability/trace-record.d.ts +23 -0
- package/esm/src/observability/trace-record.js +223 -0
- package/esm/src/observability/trace-schema.d.ts +54 -0
- package/esm/src/observability/trace-schema.js +59 -0
- package/esm/src/observability/trace-sink.d.ts +13 -0
- package/esm/src/observability/trace-sink.js +3 -0
- package/esm/src/observability/trace-span.d.ts +92 -0
- package/esm/src/observability/trace-span.js +199 -0
- package/esm/src/observability/trace.d.ts +11 -0
- package/esm/src/observability/trace.js +35 -0
- package/esm/src/observability/types.d.ts +85 -0
- package/esm/src/observability/types.js +3 -0
- package/esm/src/presets/google/speech-voices.d.ts +8 -0
- package/esm/src/presets/google/speech-voices.js +38 -0
- package/esm/src/presets/google-limits.d.ts +12 -0
- package/esm/src/presets/google-limits.js +18 -0
- package/esm/src/presets/google.d.ts +104 -0
- package/esm/src/presets/google.js +188 -0
- package/esm/src/presets/mod.d.ts +10 -0
- package/esm/src/presets/mod.js +9 -0
- package/esm/src/presets/openrouter.d.ts +13 -0
- package/esm/src/presets/openrouter.js +13 -0
- package/esm/src/presets/typesafe.d.ts +2 -0
- package/esm/src/presets/typesafe.js +2 -0
- package/esm/src/providers/create-provider.d.ts +21 -0
- package/esm/src/providers/create-provider.js +90 -0
- package/esm/src/providers/decision/usage.d.ts +3 -0
- package/esm/src/providers/decision/usage.js +25 -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/grounding.d.ts +5 -0
- package/esm/src/providers/google/grounding.js +226 -0
- package/esm/src/providers/google/interactions/framing.d.ts +15 -0
- package/esm/src/providers/google/interactions/framing.js +263 -0
- package/esm/src/providers/google/interactions/mod.d.ts +2 -0
- package/esm/src/providers/google/interactions/mod.js +2 -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 +24 -0
- package/esm/src/providers/google/interactions/stream.js +297 -0
- package/esm/src/providers/google/keys.d.ts +20 -0
- package/esm/src/providers/google/keys.js +87 -0
- package/esm/src/providers/google/live/framing.d.ts +51 -0
- package/esm/src/providers/google/live/framing.js +597 -0
- package/esm/src/providers/google/live/mod.d.ts +7 -0
- package/esm/src/providers/google/live/mod.js +7 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +1 -0
- package/esm/src/providers/google/live/openapi-schema.js +42 -0
- package/esm/src/providers/google/live/session.d.ts +14 -0
- package/esm/src/providers/google/live/session.js +150 -0
- package/esm/src/providers/google/live/stream.d.ts +51 -0
- package/esm/src/providers/google/live/stream.js +263 -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 +6 -0
- package/esm/src/providers/google/urls.js +6 -0
- package/esm/src/providers/google/usage.d.ts +7 -0
- package/esm/src/providers/google/usage.js +49 -0
- package/esm/src/providers/local/local.d.ts +12 -0
- package/esm/src/providers/local/local.js +186 -0
- package/esm/src/providers/local/mod.d.ts +8 -0
- package/esm/src/providers/local/mod.js +8 -0
- package/esm/src/providers/mod.d.ts +11 -0
- package/esm/src/providers/mod.js +7 -0
- package/esm/src/providers/openrouter/cache-control.d.ts +5 -0
- package/esm/src/providers/openrouter/cache-control.js +4 -0
- package/esm/src/providers/openrouter/chat.d.ts +64 -0
- package/esm/src/providers/openrouter/chat.js +490 -0
- package/esm/src/providers/openrouter/image.d.ts +24 -0
- package/esm/src/providers/openrouter/image.js +187 -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/sdk-messages.d.ts +10 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +99 -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/resolve-api-key.d.ts +3 -0
- package/esm/src/providers/openrouter/resolve-api-key.js +8 -0
- package/esm/src/providers/openrouter/speech.d.ts +18 -0
- package/esm/src/providers/openrouter/speech.js +109 -0
- package/esm/src/providers/probe.d.ts +5 -0
- package/esm/src/providers/probe.js +15 -0
- package/esm/src/providers/shared/builtin-wire.d.ts +4 -0
- package/esm/src/providers/shared/builtin-wire.js +9 -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/response-identity.d.ts +11 -0
- package/esm/src/providers/shared/response-identity.js +12 -0
- package/esm/src/providers/shared/sse.d.ts +10 -0
- package/esm/src/providers/shared/sse.js +79 -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 +25 -0
- package/esm/src/providers/shared/tool-args.js +84 -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/shared/vault.d.ts +13 -0
- package/esm/src/providers/shared/vault.js +41 -0
- package/esm/src/providers/types.d.ts +19 -0
- package/esm/src/providers/types.js +1 -0
- package/esm/src/surface/formats.d.ts +28 -0
- package/esm/src/surface/formats.js +139 -0
- package/esm/src/surface/mod.d.ts +14 -0
- package/esm/src/surface/mod.js +10 -0
- package/esm/src/surface/runtime.d.ts +40 -0
- package/esm/src/surface/runtime.js +439 -0
- package/esm/src/surface/tools.d.ts +15 -0
- package/esm/src/surface/tools.js +80 -0
- package/esm/src/surface/types.d.ts +104 -0
- package/esm/src/surface/types.js +4 -0
- package/package.json +108 -4
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
import { kindOfHttpStatus, TheoremError, throwIfAborted, } from '../../guardrails/error.js';
|
|
2
|
+
import { resolveTraceWriter } from '../../observability/policy.js';
|
|
3
|
+
import { writeSpans } from '../../observability/trace.js';
|
|
4
|
+
import { startTrace, traceJson } from '../../observability/trace-span.js';
|
|
5
|
+
import { decisionUsage } from '../../providers/decision/usage.js';
|
|
6
|
+
import { soleModelId } from '../registry/sole-model.js';
|
|
7
|
+
import { isRecord } from '../util/record.js';
|
|
8
|
+
import { endThrownSpan } from './turn-trace.js';
|
|
9
|
+
const TYPESAFE_SYSTEM_ONE_URL = 'https://api.typesafe.ai/v1/systemone';
|
|
10
|
+
const OPENROUTER_DECISIONS_URL = 'https://openrouter.ai/api/alpha/decisions';
|
|
11
|
+
const DECISION_ERROR_KINDS = {
|
|
12
|
+
invalid_request: 'request',
|
|
13
|
+
authentication: 'auth',
|
|
14
|
+
permission: 'auth',
|
|
15
|
+
rate_limited: 'rate_limit',
|
|
16
|
+
unavailable: 'unavailable',
|
|
17
|
+
network: 'network',
|
|
18
|
+
timeout: 'timeout',
|
|
19
|
+
cancelled: 'cancelled',
|
|
20
|
+
malformed_response: 'bad_response',
|
|
21
|
+
disclosure_blocked: 'blocked',
|
|
22
|
+
};
|
|
23
|
+
/** A normalized native-decision failure; response bodies are deliberately omitted. */
|
|
24
|
+
export class DecisionError extends TheoremError {
|
|
25
|
+
code;
|
|
26
|
+
status;
|
|
27
|
+
constructor(code, message, status) {
|
|
28
|
+
super(DECISION_ERROR_KINDS[code], message);
|
|
29
|
+
this.code = code;
|
|
30
|
+
this.status = status;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function requireDecisionProfile(registry, id) {
|
|
34
|
+
const profile = registry.profiles.get(id);
|
|
35
|
+
if (profile.type !== 'decision') {
|
|
36
|
+
throw new TheoremError('request',
|
|
37
|
+
// lexicon-exempt: developer contract error
|
|
38
|
+
`runDecision requires profile.type 'decision' (got '${profile.type}' for ${profile.id})`);
|
|
39
|
+
}
|
|
40
|
+
return profile;
|
|
41
|
+
}
|
|
42
|
+
/** The profile's one model; registration guarantees exactly one. */
|
|
43
|
+
function decisionModel(profile) {
|
|
44
|
+
const modelId = soleModelId(profile.models);
|
|
45
|
+
const binding = modelId ? profile.models[modelId] : undefined;
|
|
46
|
+
if (!modelId || !binding) {
|
|
47
|
+
throw new TheoremError('config', `Profile ${profile.id}: type 'decision' must declare exactly one model`);
|
|
48
|
+
}
|
|
49
|
+
return [modelId, binding];
|
|
50
|
+
}
|
|
51
|
+
function finite(value, path, min = 0, max = 1) {
|
|
52
|
+
if (typeof value !== 'number' || !Number.isFinite(value) || value < min || value > max) {
|
|
53
|
+
throw new DecisionError('malformed_response', `${path} is outside its valid range`); // lexicon-exempt: upstream contract error
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function distribution(value, labels, path) {
|
|
58
|
+
if (!isRecord(value) ||
|
|
59
|
+
Object.keys(value).length !== labels.length ||
|
|
60
|
+
labels.some((key) => !Object.hasOwn(value, key))) {
|
|
61
|
+
throw new DecisionError('malformed_response', `${path} does not match declared labels`); // lexicon-exempt: upstream contract error
|
|
62
|
+
}
|
|
63
|
+
const out = Object.create(null);
|
|
64
|
+
for (const label of labels)
|
|
65
|
+
out[label] = finite(value[label], `${path}.${label}`);
|
|
66
|
+
const total = Object.values(out).reduce((sum, item) => sum + item, 0);
|
|
67
|
+
if (Math.abs(total - 1) > 0.001) {
|
|
68
|
+
throw new DecisionError('malformed_response', `${path} must sum to one`); // lexicon-exempt: upstream contract error
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/** A score's legend: text for every declared level. */
|
|
73
|
+
function legend(value, labels, path) {
|
|
74
|
+
if (!isRecord(value) ||
|
|
75
|
+
Object.keys(value).length !== labels.length ||
|
|
76
|
+
labels.some((label) => !Object.hasOwn(value, label)) ||
|
|
77
|
+
Object.values(value).some((text) => typeof text !== 'string' || !text.trim())) {
|
|
78
|
+
throw new DecisionError('malformed_response', `${path} is invalid`); // lexicon-exempt: upstream contract error
|
|
79
|
+
}
|
|
80
|
+
return value;
|
|
81
|
+
}
|
|
82
|
+
function validateAnswers(raw, questions) {
|
|
83
|
+
if (!isRecord(raw) || Object.keys(raw).length !== Object.keys(questions).length) {
|
|
84
|
+
throw new DecisionError('malformed_response',
|
|
85
|
+
// lexicon-exempt: upstream contract error
|
|
86
|
+
'Decision provider returned an incomplete answer set');
|
|
87
|
+
}
|
|
88
|
+
const answers = Object.create(null);
|
|
89
|
+
for (const [id, question] of Object.entries(questions)) {
|
|
90
|
+
const answer = raw[id];
|
|
91
|
+
if (!isRecord(answer) || answer.type !== question.type) {
|
|
92
|
+
throw new DecisionError('malformed_response',
|
|
93
|
+
// lexicon-exempt: upstream contract error
|
|
94
|
+
`Decision provider returned an invalid answer for '${id}'`);
|
|
95
|
+
}
|
|
96
|
+
if (question.type === 'choice') {
|
|
97
|
+
const labels = Object.keys(question.criteria);
|
|
98
|
+
if (typeof answer.choice !== 'string' || !labels.includes(answer.choice)) {
|
|
99
|
+
throw new DecisionError('malformed_response',
|
|
100
|
+
// lexicon-exempt: upstream contract error
|
|
101
|
+
`Decision provider returned an undeclared choice for '${id}'`);
|
|
102
|
+
}
|
|
103
|
+
answers[id] = {
|
|
104
|
+
type: 'choice',
|
|
105
|
+
choice: answer.choice,
|
|
106
|
+
confidence: finite(answer.confidence, `${id}.confidence`),
|
|
107
|
+
probabilities: distribution(answer.probabilities, labels, `${id}.probabilities`),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
else if (question.type === 'noul') {
|
|
111
|
+
answers[id] = { type: 'noul', noul: finite(answer.noul, `${id}.noul`) };
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const labels = question.criteria.map((_, index) => String(index));
|
|
115
|
+
answers[id] = {
|
|
116
|
+
type: 'score',
|
|
117
|
+
score: finite(answer.score, `${id}.score`, 0, Math.max(0, labels.length - 1)),
|
|
118
|
+
confidence: finite(answer.confidence, `${id}.confidence`),
|
|
119
|
+
legend: legend(answer.legend, labels, `${id}.legend`),
|
|
120
|
+
probabilities: distribution(answer.probabilities, labels, `${id}.probabilities`),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return answers;
|
|
125
|
+
}
|
|
126
|
+
function isJson(value) {
|
|
127
|
+
const ancestors = new Set();
|
|
128
|
+
const pending = [{ value }];
|
|
129
|
+
while (pending.length) {
|
|
130
|
+
const next = pending.pop();
|
|
131
|
+
if (!next)
|
|
132
|
+
break;
|
|
133
|
+
const item = next.value;
|
|
134
|
+
if (next.exit) {
|
|
135
|
+
ancestors.delete(item);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
if (item === null || typeof item === 'string' || typeof item === 'boolean')
|
|
139
|
+
continue;
|
|
140
|
+
if (typeof item === 'number') {
|
|
141
|
+
if (!Number.isFinite(item))
|
|
142
|
+
return false;
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (typeof item !== 'object' || ancestors.has(item))
|
|
146
|
+
return false;
|
|
147
|
+
if (!Array.isArray(item) &&
|
|
148
|
+
Object.getPrototypeOf(item) !== Object.prototype &&
|
|
149
|
+
Object.getPrototypeOf(item) !== null)
|
|
150
|
+
return false;
|
|
151
|
+
if (Object.getOwnPropertySymbols(item).length)
|
|
152
|
+
return false;
|
|
153
|
+
ancestors.add(item);
|
|
154
|
+
pending.push({ value: item, exit: true });
|
|
155
|
+
const entries = Array.isArray(item) ? Array.from(item) : Object.values(item);
|
|
156
|
+
for (const entry of entries)
|
|
157
|
+
pending.push({ value: entry });
|
|
158
|
+
}
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
function validateQuestion(id, question) {
|
|
162
|
+
if (!isRecord(question) || !id.trim() || !isDecisionEntry(question.instructions)) {
|
|
163
|
+
throw new DecisionError('invalid_request',
|
|
164
|
+
// lexicon-exempt: developer contract error
|
|
165
|
+
`Decision question '${id}' must include instructions`);
|
|
166
|
+
}
|
|
167
|
+
if (question.type === 'noul' && question.criteria === undefined)
|
|
168
|
+
return;
|
|
169
|
+
if (typeof question.type !== 'string' ||
|
|
170
|
+
!['choice', 'noul', 'score'].includes(question.type) ||
|
|
171
|
+
(question.type === 'score' ? !Array.isArray(question.criteria) : !isRecord(question.criteria))) {
|
|
172
|
+
throw new DecisionError('invalid_request', `Decision question '${id}' has invalid criteria`); // lexicon-exempt: developer contract error
|
|
173
|
+
}
|
|
174
|
+
const criteria = Array.isArray(question.criteria)
|
|
175
|
+
? question.criteria
|
|
176
|
+
: Object.values(question.criteria);
|
|
177
|
+
if (!criteria.length || !criteria.every(isDecisionEntry)) {
|
|
178
|
+
throw new DecisionError('invalid_request',
|
|
179
|
+
// lexicon-exempt: developer contract error
|
|
180
|
+
`Decision ${question.type} '${id}' must declare criteria`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/** Check a decision before a host spends quota or dispatches it. Does not apply model-specific policy. */
|
|
184
|
+
export function validateDecisionRequest(request, profile) {
|
|
185
|
+
throwIfAborted(request.signal);
|
|
186
|
+
if (request.model !== undefined) {
|
|
187
|
+
throw new DecisionError('invalid_request',
|
|
188
|
+
// lexicon-exempt: developer contract error
|
|
189
|
+
'Decision requests do not select a model; the profile runs its one model');
|
|
190
|
+
}
|
|
191
|
+
if (request.state === null || !isJson(request.state)) {
|
|
192
|
+
throw new DecisionError('invalid_request', 'Decision state must be non-null JSON'); // lexicon-exempt: developer contract error
|
|
193
|
+
}
|
|
194
|
+
let serialized;
|
|
195
|
+
try {
|
|
196
|
+
serialized = JSON.stringify(request.state);
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// lexicon-exempt: developer contract error
|
|
200
|
+
throw new DecisionError('invalid_request', 'Decision state cannot be serialized as JSON');
|
|
201
|
+
}
|
|
202
|
+
const bytes = new TextEncoder().encode(serialized).byteLength;
|
|
203
|
+
if (profile.inputs.maxStateBytes !== undefined && bytes > profile.inputs.maxStateBytes) {
|
|
204
|
+
throw new DecisionError('invalid_request',
|
|
205
|
+
// lexicon-exempt: developer contract error
|
|
206
|
+
`Decision state exceeds ${profile.inputs.maxStateBytes} bytes`);
|
|
207
|
+
}
|
|
208
|
+
if (!isRecord(request.questions) ||
|
|
209
|
+
!isJson(request.questions) ||
|
|
210
|
+
Object.keys(request.questions).length === 0) {
|
|
211
|
+
throw new DecisionError('invalid_request',
|
|
212
|
+
// lexicon-exempt: developer contract error
|
|
213
|
+
'Decision request must declare at least one question');
|
|
214
|
+
}
|
|
215
|
+
for (const [id, question] of Object.entries(request.questions))
|
|
216
|
+
validateQuestion(id, question);
|
|
217
|
+
}
|
|
218
|
+
function isDecisionEntry(value) {
|
|
219
|
+
const pending = [value];
|
|
220
|
+
while (pending.length) {
|
|
221
|
+
const item = pending.pop();
|
|
222
|
+
if (typeof item === 'string') {
|
|
223
|
+
if (!item.trim())
|
|
224
|
+
return false;
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
if (!isRecord(item) && !Array.isArray(item))
|
|
228
|
+
return false;
|
|
229
|
+
const entries = Object.values(item);
|
|
230
|
+
if (!entries.length)
|
|
231
|
+
return false;
|
|
232
|
+
for (const entry of entries)
|
|
233
|
+
pending.push(entry);
|
|
234
|
+
}
|
|
235
|
+
return true;
|
|
236
|
+
}
|
|
237
|
+
function errorForStatus(status) {
|
|
238
|
+
if (status === 400 || status === 409 || status === 413 || status === 422)
|
|
239
|
+
return new DecisionError('invalid_request', 'Provider rejected the decision request', status); // lexicon-exempt: upstream contract error
|
|
240
|
+
if (status === 401)
|
|
241
|
+
return new DecisionError('authentication', 'Decision provider authentication failed', status); // lexicon-exempt: upstream contract error
|
|
242
|
+
if (status === 402 || status === 403)
|
|
243
|
+
return new DecisionError('permission', 'Decision provider refused the request', status); // lexicon-exempt: upstream contract error
|
|
244
|
+
if (status === 429)
|
|
245
|
+
return new DecisionError('rate_limited', 'Decision provider rate limited the request', status); // lexicon-exempt: upstream contract error
|
|
246
|
+
if (kindOfHttpStatus(status) === 'timeout')
|
|
247
|
+
return new DecisionError('timeout', 'Decision provider request timed out', status); // lexicon-exempt: upstream contract error
|
|
248
|
+
return new DecisionError('unavailable', 'Decision provider is unavailable', status); // lexicon-exempt: upstream contract error
|
|
249
|
+
}
|
|
250
|
+
async function enforceDisclosure(profile, model, provider, request) {
|
|
251
|
+
const verdict = await profile.guardrails?.disclosure?.enforce(request.state, {
|
|
252
|
+
destination: provider,
|
|
253
|
+
profileId: profile.id,
|
|
254
|
+
model,
|
|
255
|
+
questionIds: Object.keys(request.questions),
|
|
256
|
+
});
|
|
257
|
+
if (verdict?.action === 'block') {
|
|
258
|
+
throw new DecisionError('disclosure_blocked', 'Decision disclosure was blocked'); // lexicon-exempt: developer contract error
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
function requireApiKey(profile, binding, options) {
|
|
262
|
+
const keySlot = binding.key ?? profile.key;
|
|
263
|
+
const apiKey = keySlot ? options.vault?.[keySlot]?.trim() : undefined;
|
|
264
|
+
if (!apiKey)
|
|
265
|
+
throw new DecisionError('authentication', `the vault has no key in slot '${keySlot}'`); // lexicon-exempt: developer contract error
|
|
266
|
+
return apiKey;
|
|
267
|
+
}
|
|
268
|
+
async function sendDecisionRequest(args) {
|
|
269
|
+
try {
|
|
270
|
+
const response = await (args.options.fetch ?? globalThis.fetch)(args.options.endpoint ??
|
|
271
|
+
(args.provider === 'openrouter' ? OPENROUTER_DECISIONS_URL : TYPESAFE_SYSTEM_ONE_URL), {
|
|
272
|
+
method: 'POST',
|
|
273
|
+
headers: {
|
|
274
|
+
Authorization: `Bearer ${args.apiKey}`,
|
|
275
|
+
'Content-Type': 'application/json',
|
|
276
|
+
Accept: 'application/json',
|
|
277
|
+
},
|
|
278
|
+
body: JSON.stringify({
|
|
279
|
+
model: args.apiId,
|
|
280
|
+
state: args.request.state,
|
|
281
|
+
questions: args.request.questions,
|
|
282
|
+
}),
|
|
283
|
+
signal: args.signal,
|
|
284
|
+
});
|
|
285
|
+
if (!response.ok)
|
|
286
|
+
throw errorForStatus(response.status);
|
|
287
|
+
return response;
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
if (error instanceof DecisionError)
|
|
291
|
+
throw error;
|
|
292
|
+
if (args.request.signal?.aborted)
|
|
293
|
+
throw new DecisionError('cancelled', 'Decision request was cancelled'); // lexicon-exempt: developer contract error
|
|
294
|
+
if (args.signal.aborted)
|
|
295
|
+
throw new DecisionError('timeout', 'Decision request timed out'); // lexicon-exempt: developer contract error
|
|
296
|
+
throw new DecisionError('network', 'Decision provider network request failed'); // lexicon-exempt: upstream contract error
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
async function resultFromResponse(response, questions, binding, signal, requestSignal) {
|
|
300
|
+
let body;
|
|
301
|
+
try {
|
|
302
|
+
body = await response.json();
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
if (requestSignal?.aborted)
|
|
306
|
+
throw new DecisionError('cancelled', 'Decision request was cancelled'); // lexicon-exempt: developer contract error
|
|
307
|
+
if (signal.aborted)
|
|
308
|
+
throw new DecisionError('timeout', 'Decision request timed out'); // lexicon-exempt: developer contract error
|
|
309
|
+
if (!(error instanceof SyntaxError))
|
|
310
|
+
throw new DecisionError('network', 'Decision response body could not be read'); // lexicon-exempt: upstream contract error
|
|
311
|
+
throw new DecisionError('malformed_response', 'Decision provider returned non-JSON output'); // lexicon-exempt: upstream contract error
|
|
312
|
+
}
|
|
313
|
+
if (!isRecord(body) ||
|
|
314
|
+
typeof body.model !== 'string' ||
|
|
315
|
+
!body.model.trim() ||
|
|
316
|
+
!isRecord(body.answers)) {
|
|
317
|
+
throw new DecisionError('malformed_response', 'Decision response has an invalid shape'); // lexicon-exempt: upstream contract error
|
|
318
|
+
}
|
|
319
|
+
const usage = decisionUsage(body.usage, binding, body.model);
|
|
320
|
+
return {
|
|
321
|
+
model: body.model,
|
|
322
|
+
answers: validateAnswers(body.answers, questions),
|
|
323
|
+
...(usage ? { usage } : {}),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
function decisionSpanAttributes(profile, modelId, binding, request) {
|
|
327
|
+
return {
|
|
328
|
+
'gen_ai.operation.name': 'decide',
|
|
329
|
+
'gen_ai.provider.name': binding.provider,
|
|
330
|
+
'gen_ai.agent.name': profile.id,
|
|
331
|
+
'gen_ai.request.model': binding.apiId,
|
|
332
|
+
'theorem.model.id': modelId,
|
|
333
|
+
'theorem.decision.contract': profile.decision.contract,
|
|
334
|
+
'theorem.decision.state': traceJson(request.state),
|
|
335
|
+
'theorem.decision.questions': traceJson(request.questions),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
function recordResult(root, result) {
|
|
339
|
+
root.set({
|
|
340
|
+
'gen_ai.response.model': result.model,
|
|
341
|
+
'theorem.decision.answers': traceJson(result.answers),
|
|
342
|
+
...(result.usage
|
|
343
|
+
? {
|
|
344
|
+
'gen_ai.usage.input_tokens': result.usage.inputTokens,
|
|
345
|
+
'gen_ai.usage.output_tokens': result.usage.outputTokens,
|
|
346
|
+
...(result.usage.costUsd === undefined
|
|
347
|
+
? {}
|
|
348
|
+
: { 'theorem.usage.cost_usd': result.usage.costUsd }),
|
|
349
|
+
}
|
|
350
|
+
: {}),
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async function decide(profile, [modelId, binding], request, options) {
|
|
354
|
+
throwIfAborted(request.signal);
|
|
355
|
+
await enforceDisclosure(profile, modelId, binding.provider, request);
|
|
356
|
+
throwIfAborted(request.signal);
|
|
357
|
+
const apiKey = requireApiKey(profile, binding, options);
|
|
358
|
+
const controller = new AbortController();
|
|
359
|
+
const timeout = binding.timeoutMs
|
|
360
|
+
? setTimeout(() => controller.abort(), binding.timeoutMs)
|
|
361
|
+
: undefined;
|
|
362
|
+
const abort = () => controller.abort();
|
|
363
|
+
request.signal?.addEventListener('abort', abort, { once: true });
|
|
364
|
+
try {
|
|
365
|
+
const response = await sendDecisionRequest({
|
|
366
|
+
request,
|
|
367
|
+
apiId: binding.apiId,
|
|
368
|
+
provider: binding.provider,
|
|
369
|
+
apiKey,
|
|
370
|
+
options,
|
|
371
|
+
signal: controller.signal,
|
|
372
|
+
});
|
|
373
|
+
return await resultFromResponse(response, request.questions, binding, controller.signal, request.signal);
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
if (timeout !== undefined)
|
|
377
|
+
clearTimeout(timeout);
|
|
378
|
+
request.signal?.removeEventListener('abort', abort);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Exactly one decision request, traced however it ends. An ambiguous POST is never retried,
|
|
383
|
+
* and a trace write failure never changes the decision's outcome.
|
|
384
|
+
*/
|
|
385
|
+
export async function runDecisionInRegistry(registry, request, options) {
|
|
386
|
+
const profile = requireDecisionProfile(registry, request.profile);
|
|
387
|
+
validateDecisionRequest(request, profile);
|
|
388
|
+
const model = decisionModel(profile);
|
|
389
|
+
const [modelId, binding] = model;
|
|
390
|
+
const tree = startTrace(`decide ${binding.apiId}`, {
|
|
391
|
+
kind: 'CLIENT',
|
|
392
|
+
attributes: decisionSpanAttributes(profile, modelId, binding, request),
|
|
393
|
+
...(request.traceparent ? { traceparent: request.traceparent } : {}),
|
|
394
|
+
});
|
|
395
|
+
const { sink, policy } = resolveTraceWriter({
|
|
396
|
+
override: options.sink,
|
|
397
|
+
observability: profile.observability,
|
|
398
|
+
});
|
|
399
|
+
try {
|
|
400
|
+
const result = await decide(profile, model, request, options);
|
|
401
|
+
recordResult(tree.root, result);
|
|
402
|
+
tree.root.end({ code: 'OK' });
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
catch (error) {
|
|
406
|
+
endThrownSpan(tree.root, error);
|
|
407
|
+
throw error;
|
|
408
|
+
}
|
|
409
|
+
finally {
|
|
410
|
+
await writeSpans(sink, tree.collect(), policy, request.metadata);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function sha256(text: string): Promise<string>;
|
|
2
|
+
/** Hashes the decoded bytes, so the hash names the media whatever encoding carried it; `undefined` when not base64. */
|
|
3
|
+
export declare function sha256Base64(base64: string): Promise<{
|
|
4
|
+
hash: string;
|
|
5
|
+
bytes: number;
|
|
6
|
+
} | undefined>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { base64ToBytes } from '../util/base64.js';
|
|
2
|
+
const HEX_PAD = 2;
|
|
3
|
+
const HEX_RADIX = 16;
|
|
4
|
+
function hexSha256(bytes) {
|
|
5
|
+
return [...bytes].map((b) => b.toString(HEX_RADIX).padStart(HEX_PAD, '0')).join('');
|
|
6
|
+
}
|
|
7
|
+
export async function sha256(text) {
|
|
8
|
+
const buf = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
|
|
9
|
+
return hexSha256(new Uint8Array(buf));
|
|
10
|
+
}
|
|
11
|
+
/** Hashes the decoded bytes, so the hash names the media whatever encoding carried it; `undefined` when not base64. */
|
|
12
|
+
export async function sha256Base64(base64) {
|
|
13
|
+
let raw;
|
|
14
|
+
try {
|
|
15
|
+
raw = base64ToBytes(base64);
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const buf = await crypto.subtle.digest('SHA-256', raw);
|
|
21
|
+
return { hash: hexSha256(new Uint8Array(buf)), bytes: raw.byteLength };
|
|
22
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TurnEventOf } from '../turn-events.js';
|
|
2
|
+
import type { Profile } from '../types.js';
|
|
3
|
+
export interface LiveInboundPrepareResult {
|
|
4
|
+
text: string;
|
|
5
|
+
/** Present when inbound sanitize redacted spans. */
|
|
6
|
+
guardrail?: TurnEventOf<'guardrail'>;
|
|
7
|
+
}
|
|
8
|
+
declare function prepareLiveInboundText(profile: Profile, text: string): LiveInboundPrepareResult;
|
|
9
|
+
export { prepareLiveInboundText };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { wrapUserData } from '../../guardrails/canary.js';
|
|
2
|
+
import { guardrailFromHits, projectGuardrailTurnEvent } from '../../guardrails/events.js';
|
|
3
|
+
import { detectionForTrust, resolveGuardrailPolicy } from '../../guardrails/policy.js';
|
|
4
|
+
import { detectText } from '../../guardrails/sanitize.js';
|
|
5
|
+
import { resolveObservabilityPolicy } from '../../observability/resolve-policy.js';
|
|
6
|
+
// Resolves through the shared policy so Live ingress and the turn engine cannot drift on what an unset switch means.
|
|
7
|
+
function prepareLiveInboundText(profile, text) {
|
|
8
|
+
const policy = resolveGuardrailPolicy(profile.guardrails);
|
|
9
|
+
const detected = detectText(text, detectionForTrust(policy, 'untrusted'));
|
|
10
|
+
const raw = guardrailFromHits('live_inbound', 'untrusted', detected.hits, 'redact');
|
|
11
|
+
const includeMatch = resolveObservabilityPolicy(profile.observability).include
|
|
12
|
+
.guardrailMatchPreview;
|
|
13
|
+
const guardrail = raw ? projectGuardrailTurnEvent(raw, includeMatch) : undefined;
|
|
14
|
+
return {
|
|
15
|
+
text: wrapUserData(detected.text),
|
|
16
|
+
...(guardrail ? { guardrail } : {}),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export { prepareLiveInboundText };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LiveIngressSpec, Profile } from '../types.js';
|
|
2
|
+
export type LiveIngressChannel = keyof LiveIngressSpec;
|
|
3
|
+
/** Default when `live.ingress.<channel>` is omitted — mic and camera on, typed text off. */
|
|
4
|
+
export declare function liveIngressChannelDefault(channel: LiveIngressChannel): boolean;
|
|
5
|
+
export declare function liveIngressEnabledFromSpec(ingress: LiveIngressSpec | undefined, channel: LiveIngressChannel): boolean;
|
|
6
|
+
export declare function liveIngressEnabled(profile: Profile, channel: LiveIngressChannel): boolean;
|
|
7
|
+
export declare function hasAnyLiveIngress(profile: Profile): boolean;
|
|
8
|
+
export declare function assertLiveIngressConfigured(profile: Profile): void;
|
|
9
|
+
export declare function assertLiveIngress(profile: Profile, channel: LiveIngressChannel): void;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { TheoremError } from '../../guardrails/error.js';
|
|
2
|
+
const LIVE_INGRESS_CHANNELS = ['audio', 'video', 'text'];
|
|
3
|
+
function assertLiveProfile(profile) {
|
|
4
|
+
if (profile.type !== 'live') {
|
|
5
|
+
throw new TheoremError('request', `Profile '${profile.id}' is not type 'live'`); // lexicon-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
6
|
+
}
|
|
7
|
+
return profile;
|
|
8
|
+
}
|
|
9
|
+
/** Default when `live.ingress.<channel>` is omitted — mic and camera on, typed text off. */
|
|
10
|
+
export function liveIngressChannelDefault(channel) {
|
|
11
|
+
return channel !== 'text';
|
|
12
|
+
}
|
|
13
|
+
export function liveIngressEnabledFromSpec(ingress, channel) {
|
|
14
|
+
const value = ingress?.[channel];
|
|
15
|
+
if (value === undefined)
|
|
16
|
+
return liveIngressChannelDefault(channel);
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
export function liveIngressEnabled(profile, channel) {
|
|
20
|
+
const live = assertLiveProfile(profile);
|
|
21
|
+
return liveIngressEnabledFromSpec(live.live.ingress, channel);
|
|
22
|
+
}
|
|
23
|
+
export function hasAnyLiveIngress(profile) {
|
|
24
|
+
const live = assertLiveProfile(profile);
|
|
25
|
+
return LIVE_INGRESS_CHANNELS.some((channel) => liveIngressEnabledFromSpec(live.live.ingress, channel));
|
|
26
|
+
}
|
|
27
|
+
export function assertLiveIngressConfigured(profile) {
|
|
28
|
+
const live = assertLiveProfile(profile);
|
|
29
|
+
if (hasAnyLiveIngress(live))
|
|
30
|
+
return;
|
|
31
|
+
throw new TheoremError('config', `Profile '${live.id}': at least one live.ingress channel (audio, video, text) must be enabled`);
|
|
32
|
+
}
|
|
33
|
+
export function assertLiveIngress(profile, channel) {
|
|
34
|
+
if (liveIngressEnabled(profile, channel))
|
|
35
|
+
return;
|
|
36
|
+
throw new TheoremError('request', `Profile '${profile.id}' live.ingress.${channel} is disabled — cannot send on this channel`);
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identified by the bytes, not the declared MIME type. Decoded means what a decoder outputs: declared
|
|
3
|
+
* encoder delay and padding are dropped (Opus pre-skip, `CodecDelay`, `DiscardPadding`, LAME, the MP4
|
|
4
|
+
* edit list's leading skip); ADTS declares no delay, so its priming samples count. `undefined` when
|
|
5
|
+
* the duration cannot be read exactly.
|
|
6
|
+
*/
|
|
7
|
+
export declare function audioSeconds(bytes: Uint8Array): number | undefined;
|