@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
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import { kindOfHttpStatus, TheoremError } from '../../guardrails/error.js';
|
|
2
|
+
import { labelText } from '../../guardrails/labels.js';
|
|
3
|
+
import { retryTransient, waitDefault } from '../../providers/shared/retry.js';
|
|
4
|
+
import { readSseChunks } from '../../providers/shared/sse.js';
|
|
5
|
+
import { networkFetch, tapFetch } from '../../providers/shared/upstream-tap.js';
|
|
6
|
+
import { KEY_FALLBACK_ROW } from '../../providers/types.js';
|
|
7
|
+
import { jsonValueSchema } from '../json.js';
|
|
8
|
+
import { bytesToBase64 } from '../util/base64.js';
|
|
9
|
+
import { bindingServe, keySlotsOf, } from './binding.js';
|
|
10
|
+
import { resolveProviderLimits } from './limits.js';
|
|
11
|
+
import { costFromPrices } from './prices.js';
|
|
12
|
+
/**
|
|
13
|
+
* The runtime's own WebSocket. It takes no headers, so a sign-in that needs them is refused; a host
|
|
14
|
+
* that can send them passes `openWebSocket`.
|
|
15
|
+
*/
|
|
16
|
+
export function plainWebSocket(provider) {
|
|
17
|
+
return (url, init) => {
|
|
18
|
+
if ([...init.headers.keys()].length)
|
|
19
|
+
throw new TheoremError('unsupported', labelText('protocol.ws_headers', { provider }));
|
|
20
|
+
return Promise.resolve(new WebSocket(url, init.protocols));
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const CALL_ID_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
24
|
+
/** The bytes below this map evenly onto the alphabet; the rest are drawn again. */
|
|
25
|
+
const CALL_ID_EVEN = 256 - (256 % CALL_ID_ALPHABET.length);
|
|
26
|
+
/** A tool-call id Theorem owns: 24 letters and digits, each equally likely, the same for every provider. */
|
|
27
|
+
function mintCallId() {
|
|
28
|
+
let id = '';
|
|
29
|
+
while (id.length < 24) {
|
|
30
|
+
for (const byte of crypto.getRandomValues(new Uint8Array(24 - id.length)))
|
|
31
|
+
if (byte < CALL_ID_EVEN)
|
|
32
|
+
id += CALL_ID_ALPHABET[byte % CALL_ID_ALPHABET.length];
|
|
33
|
+
}
|
|
34
|
+
return id;
|
|
35
|
+
}
|
|
36
|
+
function serveOf(setup) {
|
|
37
|
+
return bindingServe(setup.provider, setup.binding);
|
|
38
|
+
}
|
|
39
|
+
const signers = new WeakMap();
|
|
40
|
+
/** A slot's entry, only when the vault holds it itself: an inherited one is never a key. */
|
|
41
|
+
function vaultEntry(vault, slot) {
|
|
42
|
+
return vault && Object.hasOwn(vault, slot) ? vault[slot] : undefined;
|
|
43
|
+
}
|
|
44
|
+
async function signerFor(setup, serve, slot) {
|
|
45
|
+
const { definition } = setup.provider;
|
|
46
|
+
const authorize = serve.authorize ?? definition.authorize;
|
|
47
|
+
if (!definition.key || !authorize)
|
|
48
|
+
return undefined;
|
|
49
|
+
const entry = slot ? vaultEntry(setup.vault, slot) : undefined;
|
|
50
|
+
const raw = typeof entry === 'function'
|
|
51
|
+
? await entry({
|
|
52
|
+
providerId: setup.provider.id,
|
|
53
|
+
apiId: setup.binding.apiId,
|
|
54
|
+
keySlot: slot,
|
|
55
|
+
...(setup.signal ? { signal: setup.signal } : {}),
|
|
56
|
+
})
|
|
57
|
+
: entry;
|
|
58
|
+
const value = typeof raw === 'string' ? raw.trim() || undefined : raw;
|
|
59
|
+
const parsed = definition.key.safeParse(value);
|
|
60
|
+
// invariant: a named slot promises a key, even where the provider's key is optional.
|
|
61
|
+
if (!parsed.success || (slot && value === undefined))
|
|
62
|
+
throw new TheoremError('auth', value === undefined
|
|
63
|
+
? labelText('provider.credential_missing', { slot: slot ?? '' })
|
|
64
|
+
: labelText('protocol.key_invalid', { slot: slot ?? '', provider: setup.provider.id }));
|
|
65
|
+
if (parsed.data === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
setup.onKey?.(slot, parsed.data);
|
|
68
|
+
const cacheKey = `${serve.protocol.id}\u0000${slot ?? ''}`;
|
|
69
|
+
const cache = signers.get(setup.provider) ?? new Map();
|
|
70
|
+
signers.set(setup.provider, cache);
|
|
71
|
+
const held = cache.get(cacheKey);
|
|
72
|
+
if (held && JSON.stringify(held.key) === JSON.stringify(parsed.data))
|
|
73
|
+
return held.signer;
|
|
74
|
+
const signer = authorize(parsed.data);
|
|
75
|
+
cache.set(cacheKey, { key: parsed.data, signer });
|
|
76
|
+
return signer;
|
|
77
|
+
}
|
|
78
|
+
function urlFor(serve, path, apiId, stream) {
|
|
79
|
+
if (serve.url)
|
|
80
|
+
return new URL(serve.url({ path, apiId, stream }));
|
|
81
|
+
return new URL(serve.baseUrl.replace(/\/+$/, '') + (path.startsWith('/') ? path : `/${path}`));
|
|
82
|
+
}
|
|
83
|
+
async function* defaultFraming(response, stream) {
|
|
84
|
+
const type = response.headers.get('content-type') ?? '';
|
|
85
|
+
if (!stream && !/json/i.test(type)) {
|
|
86
|
+
// why: a body that is not JSON (audio, an image) is one row; the tape keeps its hash, not its bytes.
|
|
87
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
88
|
+
yield { eventType: 'http_body', mime_type: type, data: bytesToBase64(bytes) };
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!stream) {
|
|
92
|
+
yield (await response.json());
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!response.body)
|
|
96
|
+
return;
|
|
97
|
+
for await (const row of readSseChunks(response.body)) {
|
|
98
|
+
if (row.eventType === 'sse_done')
|
|
99
|
+
return;
|
|
100
|
+
yield row;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A refused request's body: its JSON, the JSON a streamed refusal carries on its `data:` lines
|
|
105
|
+
* (Google answers `?alt=sse` with `event: error`), or else the text.
|
|
106
|
+
*/
|
|
107
|
+
function failureBody(text) {
|
|
108
|
+
const data = text
|
|
109
|
+
.split(/\r?\n/)
|
|
110
|
+
.filter((line) => line.startsWith('data:'))
|
|
111
|
+
.map((line) => line.slice('data:'.length).trim())
|
|
112
|
+
.join('\n');
|
|
113
|
+
for (const candidate of data ? [text, data] : [text]) {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.parse(candidate);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
// why: a body that is not JSON is passed on as text.
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return text;
|
|
122
|
+
}
|
|
123
|
+
async function failure(protocol, provider, response) {
|
|
124
|
+
const body = failureBody(await response.text());
|
|
125
|
+
const error = protocol.error?.({ status: response.status, body, headers: response.headers }) ??
|
|
126
|
+
new TheoremError(kindOfHttpStatus(response.status), labelText('protocol.http', { provider, status: response.status }));
|
|
127
|
+
// why: the host reads the upstream status beside the kind, e.g. a decision's 403 is `permission`.
|
|
128
|
+
return Object.assign(error, { status: response.status });
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* invariant: the ids this request asks for, not the binding's whole list: a step that answers
|
|
132
|
+
* only, or a turn that toggles a tool off, sends fewer than the binding names.
|
|
133
|
+
*/
|
|
134
|
+
function builtinIds(request) {
|
|
135
|
+
return request.builtins.map((builtin) => builtin.id);
|
|
136
|
+
}
|
|
137
|
+
function refuseUnwritten(protocol, asked, wrote = []) {
|
|
138
|
+
const tool = asked.find((id) => !wrote.includes(id));
|
|
139
|
+
if (tool !== undefined)
|
|
140
|
+
throw new TheoremError('unsupported', labelText('protocol.builtin_unwritten', { protocol: protocol.id, tool }));
|
|
141
|
+
}
|
|
142
|
+
async function frameText(data) {
|
|
143
|
+
if (typeof data === 'string')
|
|
144
|
+
return data;
|
|
145
|
+
if (data instanceof ArrayBuffer)
|
|
146
|
+
return new TextDecoder().decode(data);
|
|
147
|
+
if (typeof Blob !== 'undefined' && data instanceof Blob)
|
|
148
|
+
return await data.text();
|
|
149
|
+
return String(data);
|
|
150
|
+
}
|
|
151
|
+
function frameRow(text) {
|
|
152
|
+
try {
|
|
153
|
+
const value = JSON.parse(text);
|
|
154
|
+
if (value && typeof value === 'object' && !Array.isArray(value))
|
|
155
|
+
return value;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// why: a frame that is not JSON is handed on as text, for the protocol to refuse by name.
|
|
159
|
+
}
|
|
160
|
+
return { eventType: 'ws_unparsed', data: text };
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* A WebSocket as JSON frames in and out, in the order they happened. Frames sent before it opens
|
|
164
|
+
* wait for it; frames arriving before anyone reads are kept. A socket error is a
|
|
165
|
+
* `{ eventType: 'ws_error' }` row, and the last row is `{ eventType: 'ws_close', code, reason }`,
|
|
166
|
+
* so the protocol reads what the close means.
|
|
167
|
+
*/
|
|
168
|
+
function socketFrames(socket, tap) {
|
|
169
|
+
const queue = [];
|
|
170
|
+
const waiting = [];
|
|
171
|
+
let wake;
|
|
172
|
+
let closed = false;
|
|
173
|
+
let order = Promise.resolve();
|
|
174
|
+
const arrive = (row) => {
|
|
175
|
+
tap(row);
|
|
176
|
+
queue.push(row);
|
|
177
|
+
wake?.();
|
|
178
|
+
};
|
|
179
|
+
const then = (step) => {
|
|
180
|
+
order = order.then(step);
|
|
181
|
+
};
|
|
182
|
+
socket.addEventListener('open', () => {
|
|
183
|
+
for (const frame of waiting.splice(0))
|
|
184
|
+
socket.send(frame);
|
|
185
|
+
});
|
|
186
|
+
socket.addEventListener('message', (event) => then(async () => {
|
|
187
|
+
const text = await frameText(event.data);
|
|
188
|
+
if (text.trim())
|
|
189
|
+
arrive(frameRow(text));
|
|
190
|
+
}));
|
|
191
|
+
socket.addEventListener('error', () => then(() => arrive({ eventType: 'ws_error' })));
|
|
192
|
+
socket.addEventListener('close', (event) => then(() => {
|
|
193
|
+
const { code, reason } = event;
|
|
194
|
+
arrive({ eventType: 'ws_close', code, reason });
|
|
195
|
+
closed = true;
|
|
196
|
+
}));
|
|
197
|
+
return {
|
|
198
|
+
send(frame, input) {
|
|
199
|
+
tap({
|
|
200
|
+
eventType: 'ws_send',
|
|
201
|
+
body: frame,
|
|
202
|
+
...(input?.length ? { input: jsonValueSchema.parse(input) } : {}),
|
|
203
|
+
});
|
|
204
|
+
const text = JSON.stringify(frame);
|
|
205
|
+
if (socket.readyState === WebSocket.CONNECTING)
|
|
206
|
+
waiting.push(text);
|
|
207
|
+
else
|
|
208
|
+
socket.send(text);
|
|
209
|
+
},
|
|
210
|
+
async *frames() {
|
|
211
|
+
for (;;) {
|
|
212
|
+
const next = queue.shift();
|
|
213
|
+
if (next)
|
|
214
|
+
yield next;
|
|
215
|
+
else if (closed)
|
|
216
|
+
return;
|
|
217
|
+
else
|
|
218
|
+
await new Promise((resolve) => (wake = resolve));
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
close(code, reason) {
|
|
222
|
+
if (socket.readyState === WebSocket.CONNECTING || socket.readyState === WebSocket.OPEN)
|
|
223
|
+
socket.close(code, reason);
|
|
224
|
+
},
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
/** The context one protocol call gets: `send` and `connect` carry the URL, headers, and sign-in. */
|
|
228
|
+
function protocolContext(setup, slot, raw, wire = { sent: false }, asked = []) {
|
|
229
|
+
const serve = serveOf(setup);
|
|
230
|
+
const { protocol } = serve;
|
|
231
|
+
const { apiId } = setup.binding;
|
|
232
|
+
const builtInTools = ('builtInTools' in setup.binding ? setup.binding.builtInTools : undefined) ?? [];
|
|
233
|
+
const tap = (row) => {
|
|
234
|
+
setup.tapUpstream?.(row);
|
|
235
|
+
if (setup.rawRows)
|
|
236
|
+
raw.push(row);
|
|
237
|
+
};
|
|
238
|
+
const pathFor = (path) => {
|
|
239
|
+
const chosen = path ?? protocol.endpoints[setup.profileType];
|
|
240
|
+
if (chosen === undefined)
|
|
241
|
+
throw new TheoremError('unsupported', labelText('protocol.profile_type', {
|
|
242
|
+
protocol: protocol.id,
|
|
243
|
+
profileType: setup.profileType,
|
|
244
|
+
}));
|
|
245
|
+
return chosen;
|
|
246
|
+
};
|
|
247
|
+
return {
|
|
248
|
+
profileType: setup.profileType,
|
|
249
|
+
apiId,
|
|
250
|
+
options: setup.binding.options ?? {},
|
|
251
|
+
builtInTools,
|
|
252
|
+
limits: setup.limits ?? resolveProviderLimits(),
|
|
253
|
+
...(setup.signal ? { signal: setup.signal } : {}),
|
|
254
|
+
tapUpstream: tap,
|
|
255
|
+
async *send(body, init) {
|
|
256
|
+
refuseUnwritten(protocol, asked, init.wroteTools);
|
|
257
|
+
const headers = new Headers({ 'content-type': 'application/json' });
|
|
258
|
+
if (init.stream)
|
|
259
|
+
headers.set('accept', 'text/event-stream');
|
|
260
|
+
for (const [name, value] of Object.entries(serve.headers ?? {}))
|
|
261
|
+
headers.set(name, value);
|
|
262
|
+
for (const [name, value] of Object.entries(init.headers ?? {}))
|
|
263
|
+
headers.set(name, value);
|
|
264
|
+
const outgoing = {
|
|
265
|
+
transport: 'http',
|
|
266
|
+
url: urlFor(serve, pathFor(init.path), apiId, init.stream),
|
|
267
|
+
headers,
|
|
268
|
+
protocols: [],
|
|
269
|
+
body: JSON.stringify(body),
|
|
270
|
+
};
|
|
271
|
+
await (await signerFor(setup, serve, slot))?.sign(outgoing);
|
|
272
|
+
const post = retryTransient(tapFetch(setup.tapUpstream && ((row) => setup.tapUpstream?.(row)), networkFetch(setup.fetch ?? fetch), slot), setup.wait ?? waitDefault, setup.timeLeft);
|
|
273
|
+
wire.sent = true;
|
|
274
|
+
const response = await post(outgoing.url, {
|
|
275
|
+
method: 'POST',
|
|
276
|
+
headers: outgoing.headers,
|
|
277
|
+
body: outgoing.body ?? null,
|
|
278
|
+
...(setup.signal ? { signal: setup.signal } : {}),
|
|
279
|
+
});
|
|
280
|
+
if (!response.ok)
|
|
281
|
+
throw await failure(protocol, setup.provider.id, response);
|
|
282
|
+
for await (const row of (protocol.framing ?? defaultFraming)(response, init.stream)) {
|
|
283
|
+
tap(row);
|
|
284
|
+
yield row;
|
|
285
|
+
}
|
|
286
|
+
},
|
|
287
|
+
async connect(setupFrame, init) {
|
|
288
|
+
refuseUnwritten(protocol, asked, init?.wroteTools);
|
|
289
|
+
const outgoing = {
|
|
290
|
+
transport: 'ws',
|
|
291
|
+
url: urlFor(serve, pathFor(undefined), apiId, true),
|
|
292
|
+
headers: new Headers(serve.headers),
|
|
293
|
+
protocols: [],
|
|
294
|
+
};
|
|
295
|
+
await (await signerFor(setup, serve, slot))?.sign(outgoing);
|
|
296
|
+
const open = setup.openWebSocket ?? plainWebSocket(setup.provider.id);
|
|
297
|
+
wire.sent = true;
|
|
298
|
+
const socket = socketFrames(await open(outgoing.url.toString(), {
|
|
299
|
+
headers: outgoing.headers,
|
|
300
|
+
protocols: outgoing.protocols,
|
|
301
|
+
}), tap);
|
|
302
|
+
socket.send(setupFrame);
|
|
303
|
+
return socket;
|
|
304
|
+
},
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function isKind(error, kind) {
|
|
308
|
+
return error instanceof TheoremError && error.kind === kind;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Runs one call with the kernel's retries, all before the first event: once on the fallback slot
|
|
312
|
+
* when the first key is out of quota, and once after an `auth` refusal with the minted token
|
|
313
|
+
* dropped. A fallback starts clean: it may be another account, so it never sends the first key's
|
|
314
|
+
* state.
|
|
315
|
+
*/
|
|
316
|
+
async function* withKeys(setup, run) {
|
|
317
|
+
const { keySlot: primary, fallbackKeySlot: fallback } = keySlotsOf(setup.provider, setup.binding);
|
|
318
|
+
let slot = primary;
|
|
319
|
+
let clean = false;
|
|
320
|
+
let refreshed = false;
|
|
321
|
+
for (;;) {
|
|
322
|
+
let started = false;
|
|
323
|
+
try {
|
|
324
|
+
for await (const event of run(slot, clean)) {
|
|
325
|
+
started = true;
|
|
326
|
+
yield event;
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
if (started)
|
|
332
|
+
throw error;
|
|
333
|
+
if (isKind(error, 'rate_limit') &&
|
|
334
|
+
fallback &&
|
|
335
|
+
slot !== fallback &&
|
|
336
|
+
holdsKey(setup, fallback)) {
|
|
337
|
+
setup.tapUpstream?.({
|
|
338
|
+
eventType: KEY_FALLBACK_ROW,
|
|
339
|
+
from: slot ?? null,
|
|
340
|
+
keySlot: fallback,
|
|
341
|
+
errorKind: error.kind,
|
|
342
|
+
error: error.message,
|
|
343
|
+
});
|
|
344
|
+
slot = fallback;
|
|
345
|
+
clean = true;
|
|
346
|
+
}
|
|
347
|
+
else if (isKind(error, 'auth') && !refreshed) {
|
|
348
|
+
refreshed = true;
|
|
349
|
+
const serve = serveOf(setup);
|
|
350
|
+
signers
|
|
351
|
+
.get(setup.provider)
|
|
352
|
+
?.get(`${serve.protocol.id}\u0000${slot ?? ''}`)
|
|
353
|
+
?.signer.invalidate?.();
|
|
354
|
+
}
|
|
355
|
+
else
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
/** Whether the vault has something under the slot; an empty slot is never tried. */
|
|
361
|
+
function holdsKey(setup, slot) {
|
|
362
|
+
const entry = vaultEntry(setup.vault, slot);
|
|
363
|
+
if (typeof entry === 'string')
|
|
364
|
+
return entry.trim() !== '';
|
|
365
|
+
return typeof entry === 'function' || (typeof entry === 'object' && entry !== null);
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* A failure once the call is sent ends it as an `error` event, so the turn keeps what it showed
|
|
369
|
+
* and may resume. A cancel, a config mistake, or anything refused before sending still throws.
|
|
370
|
+
*/
|
|
371
|
+
function failureEvent(error) {
|
|
372
|
+
if (!(error instanceof TheoremError) || error.kind === 'cancelled' || error.kind === 'config')
|
|
373
|
+
throw error;
|
|
374
|
+
return {
|
|
375
|
+
type: 'error',
|
|
376
|
+
errorKind: error.kind,
|
|
377
|
+
// invariant: `error` is the person's wording, added from the profile's labels; the upstream text is internal.
|
|
378
|
+
errorInternal: error.message,
|
|
379
|
+
...(error.copy ? { errorCopy: error.copy } : {}),
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
function cleanRequest(request) {
|
|
383
|
+
if (request.state === undefined)
|
|
384
|
+
return request;
|
|
385
|
+
if (!request.history?.length)
|
|
386
|
+
throw new TheoremError('request', labelText('protocol.history_needed'));
|
|
387
|
+
const { state: _state, stateHistoryLength: _length, ...rest } = request;
|
|
388
|
+
return rest;
|
|
389
|
+
}
|
|
390
|
+
/** Theorem's id on each call, the wire's kept beside it; origin and estimated cost filled in. */
|
|
391
|
+
function finishEvents(setup) {
|
|
392
|
+
const ids = new Map();
|
|
393
|
+
const idFor = (wire) => {
|
|
394
|
+
const held = ids.get(wire);
|
|
395
|
+
if (held)
|
|
396
|
+
return held;
|
|
397
|
+
const minted = mintCallId();
|
|
398
|
+
ids.set(wire, minted);
|
|
399
|
+
return minted;
|
|
400
|
+
};
|
|
401
|
+
const prices = setup.provider.definition.prices;
|
|
402
|
+
const wireOf = (id) => {
|
|
403
|
+
for (const [wire, minted] of ids)
|
|
404
|
+
if (minted === id)
|
|
405
|
+
return wire;
|
|
406
|
+
return id;
|
|
407
|
+
};
|
|
408
|
+
const finish = (event) => {
|
|
409
|
+
switch (event.type) {
|
|
410
|
+
case 'tool_call':
|
|
411
|
+
return {
|
|
412
|
+
...event,
|
|
413
|
+
call: { ...event.call, callId: idFor(event.call.callId), wireCallId: event.call.callId },
|
|
414
|
+
};
|
|
415
|
+
case 'tool_cancel':
|
|
416
|
+
case 'tool_draft':
|
|
417
|
+
return { ...event, callId: idFor(event.callId) };
|
|
418
|
+
case 'reasoning':
|
|
419
|
+
return {
|
|
420
|
+
...event,
|
|
421
|
+
origin: {
|
|
422
|
+
protocol: event.origin?.protocol ?? setup.binding.protocol,
|
|
423
|
+
provider: setup.provider.id,
|
|
424
|
+
apiId: setup.binding.apiId,
|
|
425
|
+
},
|
|
426
|
+
};
|
|
427
|
+
case 'tokens': {
|
|
428
|
+
if (event.tokens.cost || !prices)
|
|
429
|
+
return event;
|
|
430
|
+
const cost = costFromPrices(prices, setup.binding.apiId, event.tokens);
|
|
431
|
+
return cost ? { ...event, tokens: { ...event.tokens, cost } } : event;
|
|
432
|
+
}
|
|
433
|
+
default:
|
|
434
|
+
return event;
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
return { finish, wireOf };
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* A decision whose reply has no cost gets one from the provider's prices for the model the reply
|
|
441
|
+
* names, marked estimated; a model the prices don't cover stays unpriced.
|
|
442
|
+
*/
|
|
443
|
+
function pricedDecision(setup, result) {
|
|
444
|
+
const prices = setup.provider.definition.prices;
|
|
445
|
+
if (!result.usage || result.usage.costUsd !== undefined || !prices)
|
|
446
|
+
return result;
|
|
447
|
+
const { inputTokens: input, outputTokens: output } = result.usage;
|
|
448
|
+
const cost = costFromPrices(prices, result.model, {
|
|
449
|
+
input,
|
|
450
|
+
output,
|
|
451
|
+
total: input + output,
|
|
452
|
+
});
|
|
453
|
+
return cost
|
|
454
|
+
? { ...result, usage: { ...result.usage, costUsd: cost.usd, estimated: true } }
|
|
455
|
+
: result;
|
|
456
|
+
}
|
|
457
|
+
function protocolFor(setup) {
|
|
458
|
+
return serveOf(setup).protocol;
|
|
459
|
+
}
|
|
460
|
+
function operation(protocol, operations, name) {
|
|
461
|
+
const found = operations[name];
|
|
462
|
+
if (!found)
|
|
463
|
+
throw new TheoremError('unsupported', labelText('protocol.no_operation', { protocol: protocol.id, operation: name }));
|
|
464
|
+
const method = found;
|
|
465
|
+
return ((...args) => method.apply(operations, args));
|
|
466
|
+
}
|
|
467
|
+
/** One request with one answer, tried across the binding's key slots. */
|
|
468
|
+
async function answerOnce(setup, name, request) {
|
|
469
|
+
const protocol = protocolFor(setup);
|
|
470
|
+
for await (const result of withKeys(setup, (slot) => (async function* () {
|
|
471
|
+
const operations = protocol.create(protocolContext(setup, slot, []));
|
|
472
|
+
const run = operation(protocol, operations, name);
|
|
473
|
+
yield await run(request);
|
|
474
|
+
})()))
|
|
475
|
+
return result;
|
|
476
|
+
throw new TheoremError('internal', labelText('provider.decision_failed'));
|
|
477
|
+
}
|
|
478
|
+
export function callProtocol(setup) {
|
|
479
|
+
const protocol = protocolFor(setup);
|
|
480
|
+
return {
|
|
481
|
+
async *complete(request) {
|
|
482
|
+
const { finish } = finishEvents(setup);
|
|
483
|
+
const raw = [];
|
|
484
|
+
const wire = { sent: false };
|
|
485
|
+
const events = withKeys(setup, (slot, clean) => {
|
|
486
|
+
wire.sent = false;
|
|
487
|
+
const operations = protocol.create(protocolContext(setup, slot, raw, wire, builtinIds(request)));
|
|
488
|
+
return operation(protocol, operations, 'complete')(clean ? cleanRequest(request) : request);
|
|
489
|
+
});
|
|
490
|
+
try {
|
|
491
|
+
for await (const event of events) {
|
|
492
|
+
for (const row of raw.splice(0))
|
|
493
|
+
yield { type: 'raw', row };
|
|
494
|
+
yield finish(event);
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
for (const row of raw.splice(0))
|
|
499
|
+
yield { type: 'raw', row };
|
|
500
|
+
if (!wire.sent)
|
|
501
|
+
throw error;
|
|
502
|
+
yield failureEvent(error);
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
for (const row of raw.splice(0))
|
|
506
|
+
yield { type: 'raw', row };
|
|
507
|
+
},
|
|
508
|
+
async openSession(request) {
|
|
509
|
+
const { finish, wireOf } = finishEvents(setup);
|
|
510
|
+
const raw = [];
|
|
511
|
+
let opened;
|
|
512
|
+
for await (const session of withKeys(setup, (slot, clean) => (async function* () {
|
|
513
|
+
const operations = protocol.create(protocolContext(setup, slot, raw, undefined, builtinIds(request)));
|
|
514
|
+
yield await operation(protocol, operations, 'openSession')(clean ? cleanRequest(request) : request);
|
|
515
|
+
})()))
|
|
516
|
+
opened = session;
|
|
517
|
+
const session = opened;
|
|
518
|
+
return {
|
|
519
|
+
...session,
|
|
520
|
+
// why: the wire matches a result to the id it issued, never Theorem's.
|
|
521
|
+
sendToolResult: (result) => session.sendToolResult({ ...result, callId: wireOf(result.callId) }),
|
|
522
|
+
async *events() {
|
|
523
|
+
for await (const event of session.events()) {
|
|
524
|
+
for (const row of raw.splice(0))
|
|
525
|
+
yield { type: 'raw', row };
|
|
526
|
+
yield finish(event);
|
|
527
|
+
}
|
|
528
|
+
},
|
|
529
|
+
};
|
|
530
|
+
},
|
|
531
|
+
decide: async (request) => pricedDecision(setup, await answerOnce(setup, 'decide', request)),
|
|
532
|
+
embed: (request) => answerOnce(setup, 'embed', request),
|
|
533
|
+
};
|
|
534
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ProviderLimits } from './protocols/limits.js';
|
|
2
|
+
import type { ProtocolEvent } from './protocols/protocol.js';
|
|
3
|
+
import type { OpenWebSocket } from './protocols/runtime.js';
|
|
4
|
+
export declare class ProviderBudget {
|
|
5
|
+
readonly limits: ProviderLimits;
|
|
6
|
+
readonly controller: AbortController;
|
|
7
|
+
readonly signal: AbortSignal;
|
|
8
|
+
private timer?;
|
|
9
|
+
private timerDeadline?;
|
|
10
|
+
private wireBytes;
|
|
11
|
+
private stepBytes;
|
|
12
|
+
private stepEvents;
|
|
13
|
+
private calls;
|
|
14
|
+
private deadline;
|
|
15
|
+
private releaseSignal;
|
|
16
|
+
constructor(limits: ProviderLimits, caller?: AbortSignal, timeoutMs?: number);
|
|
17
|
+
resumeOperation(): void;
|
|
18
|
+
/** Milliseconds before the running timer ends the call. */
|
|
19
|
+
timeLeft(): number;
|
|
20
|
+
startTimer(ms: number): void;
|
|
21
|
+
stopTimer(): void;
|
|
22
|
+
close(): void;
|
|
23
|
+
dispose(): void;
|
|
24
|
+
startLiveStep(): void;
|
|
25
|
+
fail(): never;
|
|
26
|
+
private checkDeadline;
|
|
27
|
+
value(value: unknown): void;
|
|
28
|
+
event(event: ProtocolEvent): void;
|
|
29
|
+
resetStep(): void;
|
|
30
|
+
socket(open: OpenWebSocket): OpenWebSocket;
|
|
31
|
+
fetch(upstream: typeof fetch): typeof fetch;
|
|
32
|
+
}
|