@theoremjs/agents 0.0.0-stage → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +545 -2
- package/esm/_dnt.polyfills.d.ts +66 -0
- package/esm/_dnt.polyfills.js +51 -0
- package/esm/mod.d.ts +79 -0
- package/esm/mod.js +49 -0
- package/esm/package.json +3 -0
- package/esm/src/cli/bin.d.ts +7 -0
- package/esm/src/cli/bin.js +9 -0
- package/esm/src/cli/commands/bench.d.ts +6 -0
- package/esm/src/cli/commands/bench.js +480 -0
- package/esm/src/cli/commands/detect-compile.d.ts +17 -0
- package/esm/src/cli/commands/detect-compile.js +22 -0
- package/esm/src/cli/commands/eval.d.ts +37 -0
- package/esm/src/cli/commands/eval.js +190 -0
- package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
- package/esm/src/cli/commands/fuzz-canary.js +241 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
- package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
- package/esm/src/cli/commands/profile.d.ts +2 -0
- package/esm/src/cli/commands/profile.js +80 -0
- package/esm/src/cli/commands/run.d.ts +13 -0
- package/esm/src/cli/commands/run.js +45 -0
- package/esm/src/cli/commands/test.d.ts +26 -0
- package/esm/src/cli/commands/test.js +143 -0
- package/esm/src/cli/event-log.d.ts +15 -0
- package/esm/src/cli/event-log.js +136 -0
- package/esm/src/cli/index.d.ts +10 -0
- package/esm/src/cli/index.js +267 -0
- package/esm/src/cli/matrix/fixtures.d.ts +10 -0
- package/esm/src/cli/matrix/fixtures.js +67 -0
- package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
- package/esm/src/cli/matrix/synthesizer.js +103 -0
- package/esm/src/evals/attachments.d.ts +5 -0
- package/esm/src/evals/attachments.js +55 -0
- package/esm/src/evals/breakdown.d.ts +30 -0
- package/esm/src/evals/breakdown.js +69 -0
- package/esm/src/evals/graders/answer.d.ts +16 -0
- package/esm/src/evals/graders/answer.js +134 -0
- package/esm/src/evals/graders/code.d.ts +40 -0
- package/esm/src/evals/graders/code.js +184 -0
- package/esm/src/evals/graders/judge.d.ts +24 -0
- package/esm/src/evals/graders/judge.js +367 -0
- package/esm/src/evals/graders/latency.d.ts +6 -0
- package/esm/src/evals/graders/latency.js +82 -0
- package/esm/src/evals/graders/live.d.ts +14 -0
- package/esm/src/evals/graders/live.js +42 -0
- package/esm/src/evals/graders/media.d.ts +18 -0
- package/esm/src/evals/graders/media.js +91 -0
- package/esm/src/evals/graders/shared.d.ts +11 -0
- package/esm/src/evals/graders/shared.js +62 -0
- package/esm/src/evals/graders/transcript.d.ts +19 -0
- package/esm/src/evals/graders/transcript.js +202 -0
- package/esm/src/evals/mod.d.ts +34 -0
- package/esm/src/evals/mod.js +22 -0
- package/esm/src/evals/record.d.ts +41 -0
- package/esm/src/evals/record.js +107 -0
- package/esm/src/evals/rubrics/catalog.d.ts +148 -0
- package/esm/src/evals/rubrics/catalog.js +846 -0
- package/esm/src/evals/rubrics/mod.d.ts +24 -0
- package/esm/src/evals/rubrics/mod.js +55 -0
- package/esm/src/evals/rubrics/mustache.d.ts +23 -0
- package/esm/src/evals/rubrics/mustache.js +154 -0
- package/esm/src/evals/rubrics/types.d.ts +54 -0
- package/esm/src/evals/rubrics/types.js +74 -0
- package/esm/src/evals/run.d.ts +75 -0
- package/esm/src/evals/run.js +418 -0
- package/esm/src/evals/suite.d.ts +28 -0
- package/esm/src/evals/suite.js +97 -0
- package/esm/src/evals/summary.d.ts +35 -0
- package/esm/src/evals/summary.js +31 -0
- package/esm/src/evals/trial.d.ts +14 -0
- package/esm/src/evals/trial.js +135 -0
- package/esm/src/evals/types.d.ts +169 -0
- package/esm/src/evals/types.js +113 -0
- package/esm/src/evals/verdict.d.ts +23 -0
- package/esm/src/evals/verdict.js +48 -0
- package/esm/src/guardrails/boundaries.d.ts +41 -0
- package/esm/src/guardrails/boundaries.js +103 -0
- package/esm/src/guardrails/canary-gate.d.ts +22 -0
- package/esm/src/guardrails/canary-gate.js +40 -0
- package/esm/src/guardrails/canary.d.ts +146 -0
- package/esm/src/guardrails/canary.js +974 -0
- package/esm/src/guardrails/compile-egress.d.ts +12 -0
- package/esm/src/guardrails/compile-egress.js +12 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +24 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +305 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +199 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +5 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +120 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +15 -0
- package/esm/src/guardrails/corpus/live-attacks.js +229 -0
- package/esm/src/guardrails/corpus/mod.d.ts +7 -0
- package/esm/src/guardrails/corpus/mod.js +4 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +23 -0
- package/esm/src/guardrails/corpus/strings.js +29 -0
- package/esm/src/guardrails/corpus/types.d.ts +36 -0
- package/esm/src/guardrails/corpus/types.js +1 -0
- package/esm/src/guardrails/credential-rules.d.ts +36 -0
- package/esm/src/guardrails/credential-rules.js +3001 -0
- package/esm/src/guardrails/credential-scan.d.ts +45 -0
- package/esm/src/guardrails/credential-scan.js +172 -0
- package/esm/src/guardrails/destinations.d.ts +45 -0
- package/esm/src/guardrails/destinations.js +234 -0
- package/esm/src/guardrails/detect-at.d.ts +107 -0
- package/esm/src/guardrails/detect-at.js +434 -0
- package/esm/src/guardrails/detect-reply.d.ts +61 -0
- package/esm/src/guardrails/detect-reply.js +95 -0
- package/esm/src/guardrails/detect-stream.d.ts +33 -0
- package/esm/src/guardrails/detect-stream.js +77 -0
- package/esm/src/guardrails/detectors.d.ts +216 -0
- package/esm/src/guardrails/detectors.js +503 -0
- package/esm/src/guardrails/egress-automata.d.ts +12 -0
- package/esm/src/guardrails/egress-automata.js +25582 -0
- package/esm/src/guardrails/egress-compiler.d.ts +55 -0
- package/esm/src/guardrails/egress-compiler.js +431 -0
- package/esm/src/guardrails/egress-patterns.d.ts +26 -0
- package/esm/src/guardrails/egress-patterns.js +36 -0
- package/esm/src/guardrails/egress-stream.d.ts +123 -0
- package/esm/src/guardrails/egress-stream.js +774 -0
- package/esm/src/guardrails/egress-urls.d.ts +86 -0
- package/esm/src/guardrails/egress-urls.js +909 -0
- package/esm/src/guardrails/egress.d.ts +46 -0
- package/esm/src/guardrails/egress.js +124 -0
- package/esm/src/guardrails/error.d.ts +31 -0
- package/esm/src/guardrails/error.js +96 -0
- package/esm/src/guardrails/event-schemas.d.ts +100 -0
- package/esm/src/guardrails/event-schemas.js +48 -0
- package/esm/src/guardrails/events.d.ts +13 -0
- package/esm/src/guardrails/events.js +45 -0
- package/esm/src/guardrails/hints.d.ts +14 -0
- package/esm/src/guardrails/hints.js +57 -0
- package/esm/src/guardrails/hits.d.ts +14 -0
- package/esm/src/guardrails/hits.js +30 -0
- package/esm/src/guardrails/host-patterns.d.ts +85 -0
- package/esm/src/guardrails/host-patterns.js +173 -0
- package/esm/src/guardrails/injection-patterns.d.ts +20 -0
- package/esm/src/guardrails/injection-patterns.js +126 -0
- package/esm/src/guardrails/injection-reversed.d.ts +9 -0
- package/esm/src/guardrails/injection-reversed.js +49 -0
- package/esm/src/guardrails/injection.d.ts +30 -0
- package/esm/src/guardrails/injection.js +460 -0
- package/esm/src/guardrails/labels.d.ts +40 -0
- package/esm/src/guardrails/labels.js +874 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +55 -0
- package/esm/src/guardrails/live-outbound-gate.js +298 -0
- package/esm/src/guardrails/mod.d.ts +54 -0
- package/esm/src/guardrails/mod.js +34 -0
- package/esm/src/guardrails/network.d.ts +46 -0
- package/esm/src/guardrails/network.js +330 -0
- package/esm/src/guardrails/normalize.d.ts +20 -0
- package/esm/src/guardrails/normalize.js +165 -0
- package/esm/src/guardrails/policy.d.ts +4 -0
- package/esm/src/guardrails/policy.js +21 -0
- package/esm/src/guardrails/progressive-yield.d.ts +110 -0
- package/esm/src/guardrails/progressive-yield.js +281 -0
- package/esm/src/guardrails/prompt-echo.d.ts +40 -0
- package/esm/src/guardrails/prompt-echo.js +306 -0
- package/esm/src/guardrails/quota.d.ts +21 -0
- package/esm/src/guardrails/quota.js +80 -0
- package/esm/src/guardrails/rules.d.ts +47 -0
- package/esm/src/guardrails/rules.js +47 -0
- package/esm/src/guardrails/sanitize.d.ts +40 -0
- package/esm/src/guardrails/sanitize.js +160 -0
- package/esm/src/guardrails/sensitive-groups.d.ts +21 -0
- package/esm/src/guardrails/sensitive-groups.js +12 -0
- package/esm/src/guardrails/sensitive.d.ts +22 -0
- package/esm/src/guardrails/sensitive.js +234 -0
- package/esm/src/guardrails/serialize.d.ts +15 -0
- package/esm/src/guardrails/serialize.js +37 -0
- package/esm/src/guardrails/testing.d.ts +11 -0
- package/esm/src/guardrails/testing.js +10 -0
- package/esm/src/guardrails/theorem-error.d.ts +21 -0
- package/esm/src/guardrails/theorem-error.js +54 -0
- package/esm/src/guardrails/thought-guard.d.ts +76 -0
- package/esm/src/guardrails/thought-guard.js +664 -0
- package/esm/src/guardrails/tool-directives.d.ts +38 -0
- package/esm/src/guardrails/tool-directives.js +195 -0
- package/esm/src/guardrails/tool-leak.d.ts +26 -0
- package/esm/src/guardrails/tool-leak.js +45 -0
- package/esm/src/guardrails/tool-result.d.ts +92 -0
- package/esm/src/guardrails/tool-result.js +272 -0
- package/esm/src/guardrails/types.d.ts +250 -0
- package/esm/src/guardrails/types.js +58 -0
- package/esm/src/host/client-turn.d.ts +36 -0
- package/esm/src/host/client-turn.js +80 -0
- package/esm/src/host/mint-trace.d.ts +29 -0
- package/esm/src/host/mint-trace.js +60 -0
- package/esm/src/host/mod.d.ts +13 -0
- package/esm/src/host/mod.js +11 -0
- package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
- package/esm/src/host/readStreamingJsonStringField.js +27 -0
- package/esm/src/host/reply.d.ts +13 -0
- package/esm/src/host/reply.js +41 -0
- package/esm/src/interface/blocks.d.ts +11 -0
- package/esm/src/interface/blocks.js +283 -0
- package/esm/src/interface/composer-actions.d.ts +24 -0
- package/esm/src/interface/composer-actions.js +33 -0
- package/esm/src/interface/draft.d.ts +20 -0
- package/esm/src/interface/draft.js +39 -0
- package/esm/src/interface/from-profile.d.ts +24 -0
- package/esm/src/interface/from-profile.js +179 -0
- package/esm/src/interface/history.d.ts +46 -0
- package/esm/src/interface/history.js +278 -0
- package/esm/src/interface/inputs.d.ts +11 -0
- package/esm/src/interface/inputs.js +67 -0
- package/esm/src/interface/mod.d.ts +33 -0
- package/esm/src/interface/mod.js +22 -0
- package/esm/src/interface/models.d.ts +26 -0
- package/esm/src/interface/models.js +50 -0
- package/esm/src/interface/pending.d.ts +57 -0
- package/esm/src/interface/pending.js +152 -0
- package/esm/src/interface/profile-interface.d.ts +4 -0
- package/esm/src/interface/profile-interface.js +237 -0
- package/esm/src/interface/session.d.ts +71 -0
- package/esm/src/interface/session.js +128 -0
- package/esm/src/interface/stop.d.ts +13 -0
- package/esm/src/interface/stop.js +28 -0
- package/esm/src/interface/tool-calls.d.ts +32 -0
- package/esm/src/interface/tool-calls.js +127 -0
- package/esm/src/interface/tool-invoke.d.ts +6 -0
- package/esm/src/interface/tool-invoke.js +22 -0
- package/esm/src/interface/tool-media.d.ts +11 -0
- package/esm/src/interface/tool-media.js +113 -0
- package/esm/src/interface/types.d.ts +278 -0
- package/esm/src/interface/types.js +5 -0
- package/esm/src/kernel/api-catalog.d.ts +85 -0
- package/esm/src/kernel/api-catalog.js +229 -0
- package/esm/src/kernel/auth/credential-source.d.ts +23 -0
- package/esm/src/kernel/auth/credential-source.js +11 -0
- package/esm/src/kernel/auth/crypto.d.ts +56 -0
- package/esm/src/kernel/auth/crypto.js +163 -0
- package/esm/src/kernel/auth/mod.d.ts +5 -0
- package/esm/src/kernel/auth/mod.js +5 -0
- package/esm/src/kernel/auth/oauth.d.ts +18 -0
- package/esm/src/kernel/auth/oauth.js +439 -0
- package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
- package/esm/src/kernel/auth/scope-refusal.js +8 -0
- package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
- package/esm/src/kernel/auth/typed-secret.js +23 -0
- package/esm/src/kernel/auth/types.d.ts +152 -0
- package/esm/src/kernel/auth/types.js +1 -0
- package/esm/src/kernel/checkpoint.d.ts +43 -0
- package/esm/src/kernel/checkpoint.js +58 -0
- package/esm/src/kernel/default-scope.d.ts +72 -0
- package/esm/src/kernel/default-scope.js +121 -0
- package/esm/src/kernel/engine/call-trace.d.ts +19 -0
- package/esm/src/kernel/engine/call-trace.js +29 -0
- package/esm/src/kernel/engine/compaction.d.ts +71 -0
- package/esm/src/kernel/engine/compaction.js +203 -0
- package/esm/src/kernel/engine/decision.d.ts +43 -0
- package/esm/src/kernel/engine/decision.js +439 -0
- package/esm/src/kernel/engine/embedding.d.ts +8 -0
- package/esm/src/kernel/engine/embedding.js +118 -0
- package/esm/src/kernel/engine/hash.d.ts +6 -0
- package/esm/src/kernel/engine/hash.js +22 -0
- package/esm/src/kernel/engine/live-inbound.d.ts +19 -0
- package/esm/src/kernel/engine/live-inbound.js +44 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +15 -0
- package/esm/src/kernel/engine/live-ingress.js +42 -0
- package/esm/src/kernel/engine/record.d.ts +3 -0
- package/esm/src/kernel/engine/record.js +11 -0
- package/esm/src/kernel/engine/repair.d.ts +7 -0
- package/esm/src/kernel/engine/repair.js +36 -0
- package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
- package/esm/src/kernel/engine/runner/gates.js +508 -0
- package/esm/src/kernel/engine/runner/mod.d.ts +29 -0
- package/esm/src/kernel/engine/runner/mod.js +625 -0
- package/esm/src/kernel/engine/runner/nested.d.ts +32 -0
- package/esm/src/kernel/engine/runner/nested.js +134 -0
- package/esm/src/kernel/engine/runner/schema-validation.d.ts +35 -0
- package/esm/src/kernel/engine/runner/schema-validation.js +179 -0
- package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
- package/esm/src/kernel/engine/runner/stages.js +41 -0
- package/esm/src/kernel/engine/runner/state.d.ts +97 -0
- package/esm/src/kernel/engine/runner/state.js +50 -0
- package/esm/src/kernel/engine/runner/step-order.d.ts +27 -0
- package/esm/src/kernel/engine/runner/step-order.js +165 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
- package/esm/src/kernel/engine/runner/steps.js +519 -0
- package/esm/src/kernel/engine/runner/stream.d.ts +71 -0
- package/esm/src/kernel/engine/runner/stream.js +376 -0
- package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
- package/esm/src/kernel/engine/runner/usage.js +148 -0
- package/esm/src/kernel/engine/session/mod.d.ts +33 -0
- package/esm/src/kernel/engine/session/mod.js +1182 -0
- package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
- package/esm/src/kernel/engine/session/session-trace.js +500 -0
- package/esm/src/kernel/engine/token-estimate.d.ts +23 -0
- package/esm/src/kernel/engine/token-estimate.js +38 -0
- package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
- package/esm/src/kernel/engine/tool-trace.js +132 -0
- package/esm/src/kernel/engine/tree.d.ts +2 -0
- package/esm/src/kernel/engine/tree.js +17 -0
- package/esm/src/kernel/engine/turn-trace.d.ts +119 -0
- package/esm/src/kernel/engine/turn-trace.js +855 -0
- package/esm/src/kernel/engine/usage.d.ts +36 -0
- package/esm/src/kernel/engine/usage.js +151 -0
- package/esm/src/kernel/interaction-parts.d.ts +13 -0
- package/esm/src/kernel/interaction-parts.js +40 -0
- package/esm/src/kernel/json.d.ts +10 -0
- package/esm/src/kernel/json.js +3 -0
- package/esm/src/kernel/mod.d.ts +74 -0
- package/esm/src/kernel/mod.js +45 -0
- package/esm/src/kernel/profile-graph.d.ts +145 -0
- package/esm/src/kernel/profile-graph.js +158 -0
- package/esm/src/kernel/profile-presence.d.ts +18 -0
- package/esm/src/kernel/profile-presence.js +158 -0
- package/esm/src/kernel/profile-scope.d.ts +40 -0
- package/esm/src/kernel/profile-scope.js +274 -0
- package/esm/src/kernel/protocols/binding.d.ts +65 -0
- package/esm/src/kernel/protocols/binding.js +125 -0
- package/esm/src/kernel/protocols/limits.d.ts +15 -0
- package/esm/src/kernel/protocols/limits.js +28 -0
- package/esm/src/kernel/protocols/mod.d.ts +5 -0
- package/esm/src/kernel/protocols/mod.js +5 -0
- package/esm/src/kernel/protocols/prices.d.ts +36 -0
- package/esm/src/kernel/protocols/prices.js +37 -0
- package/esm/src/kernel/protocols/protocol.d.ts +253 -0
- package/esm/src/kernel/protocols/protocol.js +253 -0
- package/esm/src/kernel/protocols/provider.d.ts +108 -0
- package/esm/src/kernel/protocols/provider.js +143 -0
- package/esm/src/kernel/protocols/runtime.d.ts +55 -0
- package/esm/src/kernel/protocols/runtime.js +534 -0
- package/esm/src/kernel/provider-budget.d.ts +32 -0
- package/esm/src/kernel/provider-budget.js +262 -0
- package/esm/src/kernel/provider-dispatch.d.ts +13 -0
- package/esm/src/kernel/provider-dispatch.js +36 -0
- package/esm/src/kernel/provider-live.d.ts +7 -0
- package/esm/src/kernel/provider-live.js +189 -0
- package/esm/src/kernel/provider-runtime.d.ts +57 -0
- package/esm/src/kernel/provider-runtime.js +524 -0
- package/esm/src/kernel/registry/attachments.d.ts +46 -0
- package/esm/src/kernel/registry/attachments.js +220 -0
- package/esm/src/kernel/registry/catalog.d.ts +25 -0
- package/esm/src/kernel/registry/catalog.js +85 -0
- package/esm/src/kernel/registry/embedding-rules.d.ts +28 -0
- package/esm/src/kernel/registry/embedding-rules.js +66 -0
- package/esm/src/kernel/registry/ingress.d.ts +12 -0
- package/esm/src/kernel/registry/ingress.js +179 -0
- package/esm/src/kernel/registry/kernel-registry.d.ts +15 -0
- package/esm/src/kernel/registry/kernel-registry.js +15 -0
- package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
- package/esm/src/kernel/registry/profile-outputs.js +10 -0
- package/esm/src/kernel/registry/profiles.d.ts +116 -0
- package/esm/src/kernel/registry/profiles.js +773 -0
- package/esm/src/kernel/registry/provider-request.d.ts +6 -0
- package/esm/src/kernel/registry/provider-request.js +34 -0
- package/esm/src/kernel/registry/resolve.d.ts +17 -0
- package/esm/src/kernel/registry/resolve.js +238 -0
- package/esm/src/kernel/registry/schemas.d.ts +12 -0
- package/esm/src/kernel/registry/schemas.js +27 -0
- package/esm/src/kernel/registry/slot-fill.d.ts +7 -0
- package/esm/src/kernel/registry/slot-fill.js +22 -0
- package/esm/src/kernel/registry/sole-model.d.ts +2 -0
- package/esm/src/kernel/registry/sole-model.js +4 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
- package/esm/src/kernel/registry/system-prompt.js +32 -0
- package/esm/src/kernel/registry/system-role.d.ts +3 -0
- package/esm/src/kernel/registry/system-role.js +9 -0
- package/esm/src/kernel/registry/vault.d.ts +14 -0
- package/esm/src/kernel/registry/vault.js +1 -0
- package/esm/src/kernel/schema.d.ts +226 -0
- package/esm/src/kernel/schema.js +895 -0
- package/esm/src/kernel/scope.d.ts +29 -0
- package/esm/src/kernel/scope.js +45 -0
- package/esm/src/kernel/stages.d.ts +176 -0
- package/esm/src/kernel/stages.js +431 -0
- package/esm/src/kernel/stop.d.ts +116 -0
- package/esm/src/kernel/stop.js +137 -0
- package/esm/src/kernel/system-parts.d.ts +26 -0
- package/esm/src/kernel/system-parts.js +98 -0
- package/esm/src/kernel/tools/activity-label.d.ts +22 -0
- package/esm/src/kernel/tools/activity-label.js +435 -0
- package/esm/src/kernel/tools/agent.d.ts +66 -0
- package/esm/src/kernel/tools/agent.js +212 -0
- package/esm/src/kernel/tools/coordinate.d.ts +4 -0
- package/esm/src/kernel/tools/coordinate.js +165 -0
- package/esm/src/kernel/tools/events.d.ts +66 -0
- package/esm/src/kernel/tools/events.js +184 -0
- package/esm/src/kernel/tools/execute.d.ts +100 -0
- package/esm/src/kernel/tools/execute.js +1173 -0
- package/esm/src/kernel/tools/gate-answer.d.ts +60 -0
- package/esm/src/kernel/tools/gate-answer.js +65 -0
- package/esm/src/kernel/tools/handler-events.d.ts +45 -0
- package/esm/src/kernel/tools/handler-events.js +106 -0
- package/esm/src/kernel/tools/harness.d.ts +17 -0
- package/esm/src/kernel/tools/harness.js +43 -0
- package/esm/src/kernel/tools/http-limit.d.ts +27 -0
- package/esm/src/kernel/tools/http-limit.js +85 -0
- package/esm/src/kernel/tools/invoke.d.ts +32 -0
- package/esm/src/kernel/tools/invoke.js +282 -0
- package/esm/src/kernel/tools/mcp-sessions.d.ts +23 -0
- package/esm/src/kernel/tools/mcp-sessions.js +69 -0
- package/esm/src/kernel/tools/mod.d.ts +10 -0
- package/esm/src/kernel/tools/mod.js +7 -0
- package/esm/src/kernel/tools/model-text.d.ts +16 -0
- package/esm/src/kernel/tools/model-text.js +31 -0
- package/esm/src/kernel/tools/operation.d.ts +76 -0
- package/esm/src/kernel/tools/operation.js +100 -0
- package/esm/src/kernel/tools/page-answer.d.ts +8 -0
- package/esm/src/kernel/tools/page-answer.js +19 -0
- package/esm/src/kernel/tools/permission.d.ts +15 -0
- package/esm/src/kernel/tools/permission.js +38 -0
- package/esm/src/kernel/tools/project.d.ts +11 -0
- package/esm/src/kernel/tools/project.js +55 -0
- package/esm/src/kernel/tools/registry.d.ts +27 -0
- package/esm/src/kernel/tools/registry.js +143 -0
- package/esm/src/kernel/tools/remote.d.ts +144 -0
- package/esm/src/kernel/tools/remote.js +1125 -0
- package/esm/src/kernel/tools/resolve.d.ts +31 -0
- package/esm/src/kernel/tools/resolve.js +267 -0
- package/esm/src/kernel/tools/run.d.ts +28 -0
- package/esm/src/kernel/tools/run.js +86 -0
- package/esm/src/kernel/tools/schema.d.ts +10 -0
- package/esm/src/kernel/tools/schema.js +95 -0
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +19 -0
- package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
- package/esm/src/kernel/tools/stage-run.d.ts +116 -0
- package/esm/src/kernel/tools/stage-run.js +198 -0
- package/esm/src/kernel/tools/types.d.ts +497 -0
- package/esm/src/kernel/tools/types.js +1 -0
- package/esm/src/kernel/tools/unchecked-output.d.ts +14 -0
- package/esm/src/kernel/tools/unchecked-output.js +18 -0
- package/esm/src/kernel/turn-events.d.ts +776 -0
- package/esm/src/kernel/turn-events.js +543 -0
- package/esm/src/kernel/types.d.ts +1025 -0
- package/esm/src/kernel/types.js +1 -0
- package/esm/src/kernel/util/base64.d.ts +4 -0
- package/esm/src/kernel/util/base64.js +15 -0
- package/esm/src/kernel/util/exact-type.d.ts +31 -0
- package/esm/src/kernel/util/exact-type.js +1 -0
- package/esm/src/kernel/util/find-last.d.ts +3 -0
- package/esm/src/kernel/util/find-last.js +9 -0
- package/esm/src/kernel/util/mime.d.ts +2 -0
- package/esm/src/kernel/util/mime.js +4 -0
- package/esm/src/kernel/util/partial-json.d.ts +23 -0
- package/esm/src/kernel/util/partial-json.js +128 -0
- package/esm/src/kernel/util/record.d.ts +2 -0
- package/esm/src/kernel/util/record.js +4 -0
- package/esm/src/observability/destinations.d.ts +14 -0
- package/esm/src/observability/destinations.js +43 -0
- package/esm/src/observability/jsonl.d.ts +18 -0
- package/esm/src/observability/jsonl.js +110 -0
- package/esm/src/observability/mod.d.ts +22 -0
- package/esm/src/observability/mod.js +16 -0
- package/esm/src/observability/openinference.d.ts +11 -0
- package/esm/src/observability/openinference.js +205 -0
- package/esm/src/observability/otlp.d.ts +71 -0
- package/esm/src/observability/otlp.js +98 -0
- package/esm/src/observability/phoenix.d.ts +30 -0
- package/esm/src/observability/phoenix.js +71 -0
- package/esm/src/observability/policy.d.ts +17 -0
- package/esm/src/observability/policy.js +73 -0
- package/esm/src/observability/resolve-policy.d.ts +8 -0
- package/esm/src/observability/resolve-policy.js +64 -0
- package/esm/src/observability/spans.d.ts +22 -0
- package/esm/src/observability/spans.js +72 -0
- package/esm/src/observability/trace-catalog.d.ts +128 -0
- package/esm/src/observability/trace-catalog.js +906 -0
- package/esm/src/observability/trace-record.d.ts +23 -0
- package/esm/src/observability/trace-record.js +228 -0
- package/esm/src/observability/trace-schema.d.ts +57 -0
- package/esm/src/observability/trace-schema.js +59 -0
- package/esm/src/observability/trace-sink.d.ts +14 -0
- package/esm/src/observability/trace-sink.js +3 -0
- package/esm/src/observability/trace-span.d.ts +98 -0
- package/esm/src/observability/trace-span.js +201 -0
- package/esm/src/observability/trace.d.ts +13 -0
- package/esm/src/observability/trace.js +37 -0
- package/esm/src/observability/types.d.ts +109 -0
- package/esm/src/observability/types.js +3 -0
- package/esm/src/presets/google/speech-voices.d.ts +9 -0
- package/esm/src/presets/google/speech-voices.js +38 -0
- package/esm/src/presets/google-limits.d.ts +13 -0
- package/esm/src/presets/google-limits.js +18 -0
- package/esm/src/presets/google.d.ts +119 -0
- package/esm/src/presets/google.js +197 -0
- package/esm/src/presets/local.d.ts +26 -0
- package/esm/src/presets/local.js +30 -0
- package/esm/src/presets/mod.d.ts +11 -0
- package/esm/src/presets/mod.js +9 -0
- package/esm/src/presets/openrouter.d.ts +26 -0
- package/esm/src/presets/openrouter.js +31 -0
- package/esm/src/providers/embedding-limits.d.ts +7 -0
- package/esm/src/providers/embedding-limits.js +12 -0
- package/esm/src/providers/gemini/embedding-protocol.d.ts +8 -0
- package/esm/src/providers/gemini/embedding-protocol.js +125 -0
- package/esm/src/providers/gemini/interactions-protocol.d.ts +8 -0
- package/esm/src/providers/gemini/interactions-protocol.js +105 -0
- package/esm/src/providers/gemini/live-protocol.d.ts +3 -0
- package/esm/src/providers/gemini/live-protocol.js +191 -0
- package/esm/src/providers/gemini/prices.d.ts +3 -0
- package/esm/src/providers/gemini/prices.js +63 -0
- package/esm/src/providers/gemini/provider.d.ts +7 -0
- package/esm/src/providers/gemini/provider.js +39 -0
- package/esm/src/providers/google/api-error.d.ts +8 -0
- package/esm/src/providers/google/api-error.js +123 -0
- package/esm/src/providers/google/builtins.d.ts +14 -0
- package/esm/src/providers/google/builtins.js +57 -0
- package/esm/src/providers/google/grounding.d.ts +5 -0
- package/esm/src/providers/google/grounding.js +226 -0
- package/esm/src/providers/google/interactions/framing.d.ts +27 -0
- package/esm/src/providers/google/interactions/framing.js +304 -0
- package/esm/src/providers/google/interactions/steps.d.ts +12 -0
- package/esm/src/providers/google/interactions/steps.js +200 -0
- package/esm/src/providers/google/interactions/stream.d.ts +23 -0
- package/esm/src/providers/google/interactions/stream.js +230 -0
- package/esm/src/providers/google/live/framing.d.ts +61 -0
- package/esm/src/providers/google/live/framing.js +597 -0
- package/esm/src/providers/google/live/stream.d.ts +13 -0
- package/esm/src/providers/google/live/stream.js +57 -0
- package/esm/src/providers/google/thinking.d.ts +3 -0
- package/esm/src/providers/google/thinking.js +8 -0
- package/esm/src/providers/google/urls.d.ts +4 -0
- package/esm/src/providers/google/urls.js +4 -0
- package/esm/src/providers/google/usage.d.ts +7 -0
- package/esm/src/providers/google/usage.js +49 -0
- package/esm/src/providers/live.d.ts +6 -0
- package/esm/src/providers/live.js +6 -0
- package/esm/src/providers/local/embedding-protocol.d.ts +7 -0
- package/esm/src/providers/local/embedding-protocol.js +60 -0
- package/esm/src/providers/local/provider.d.ts +7 -0
- package/esm/src/providers/local/provider.js +28 -0
- package/esm/src/providers/mod.d.ts +32 -0
- package/esm/src/providers/mod.js +23 -0
- package/esm/src/providers/open-ai/protocol.d.ts +3 -0
- package/esm/src/providers/open-ai/protocol.js +189 -0
- package/esm/src/providers/openrouter/embedding-protocol.d.ts +6 -0
- package/esm/src/providers/openrouter/embedding-protocol.js +86 -0
- package/esm/src/providers/openrouter/image.d.ts +15 -0
- package/esm/src/providers/openrouter/image.js +34 -0
- package/esm/src/providers/openrouter/images-protocol.d.ts +3 -0
- package/esm/src/providers/openrouter/images-protocol.js +82 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
- package/esm/src/providers/openrouter/openai/compat.js +162 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
- package/esm/src/providers/openrouter/openai/reasoning-state.d.ts +2 -0
- package/esm/src/providers/openrouter/openai/reasoning-state.js +31 -0
- package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
- package/esm/src/providers/openrouter/openai/usage.js +56 -0
- package/esm/src/providers/openrouter/protocol.d.ts +8 -0
- package/esm/src/providers/openrouter/protocol.js +171 -0
- package/esm/src/providers/openrouter/provider.d.ts +10 -0
- package/esm/src/providers/openrouter/provider.js +50 -0
- package/esm/src/providers/shared/carried-tool-files.d.ts +7 -0
- package/esm/src/providers/shared/carried-tool-files.js +43 -0
- package/esm/src/providers/shared/pcm.d.ts +14 -0
- package/esm/src/providers/shared/pcm.js +78 -0
- package/esm/src/providers/shared/protocol-events.d.ts +8 -0
- package/esm/src/providers/shared/protocol-events.js +20 -0
- package/esm/src/providers/shared/response-identity.d.ts +11 -0
- package/esm/src/providers/shared/response-identity.js +12 -0
- package/esm/src/providers/shared/retry.d.ts +17 -0
- package/esm/src/providers/shared/retry.js +90 -0
- package/esm/src/providers/shared/sse.d.ts +6 -0
- package/esm/src/providers/shared/sse.js +93 -0
- package/esm/src/providers/shared/structured-output.d.ts +4 -0
- package/esm/src/providers/shared/structured-output.js +11 -0
- package/esm/src/providers/shared/tool-args.d.ts +24 -0
- package/esm/src/providers/shared/tool-args.js +88 -0
- package/esm/src/providers/shared/tool-draft.d.ts +16 -0
- package/esm/src/providers/shared/tool-draft.js +14 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
- package/esm/src/providers/shared/upstream-tap.js +85 -0
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/shared/upstream-tape.js +88 -0
- package/esm/src/providers/system-one/protocol.d.ts +8 -0
- package/esm/src/providers/system-one/protocol.js +93 -0
- package/esm/src/providers/types.d.ts +51 -0
- package/esm/src/providers/types.js +2 -0
- package/esm/src/providers/typesafe/provider.d.ts +7 -0
- package/esm/src/providers/typesafe/provider.js +24 -0
- package/esm/src/surface/formats.d.ts +46 -0
- package/esm/src/surface/formats.js +178 -0
- package/esm/src/surface/mod.d.ts +16 -0
- package/esm/src/surface/mod.js +12 -0
- package/esm/src/surface/runtime.d.ts +44 -0
- package/esm/src/surface/runtime.js +441 -0
- package/esm/src/surface/tools.d.ts +9 -0
- package/esm/src/surface/tools.js +62 -0
- package/esm/src/surface/types.d.ts +110 -0
- package/esm/src/surface/types.js +4 -0
- package/package.json +100 -4
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import type { TraceSink } from '../../../observability/trace-sink.js';
|
|
2
|
+
import { type SpanHandle, type TraceAttributes, type TraceTree } from '../../../observability/trace-span.js';
|
|
3
|
+
import type { ResolvedObservabilityPolicy } from '../../../observability/types.js';
|
|
4
|
+
import { type LiveQueueItem } from '../../../providers/types.js';
|
|
5
|
+
import type { TurnEventOf } from '../../turn-events.js';
|
|
6
|
+
import type { ModelBinding, ModelRequest, Profile, ResolvedGeneration, SessionRequest, TurnEvent } from '../../types.js';
|
|
7
|
+
type LiveCloser = 'host' | 'provider' | 'theorem';
|
|
8
|
+
interface LiveTraceBinding {
|
|
9
|
+
request: ModelRequest;
|
|
10
|
+
generation: ResolvedGeneration;
|
|
11
|
+
binding: ModelBinding | undefined;
|
|
12
|
+
/** The system prompt as sent, canary bound. */
|
|
13
|
+
system: string;
|
|
14
|
+
canary: string;
|
|
15
|
+
}
|
|
16
|
+
interface LiveTraceEnd {
|
|
17
|
+
/** Thrown out of the session (an abort is recorded as cancelled). */
|
|
18
|
+
thrown?: unknown;
|
|
19
|
+
}
|
|
20
|
+
declare class LiveTrace {
|
|
21
|
+
private readonly tree;
|
|
22
|
+
private readonly out;
|
|
23
|
+
private readonly identity;
|
|
24
|
+
readonly root: SpanHandle;
|
|
25
|
+
private bound?;
|
|
26
|
+
private response?;
|
|
27
|
+
private lastResponse?;
|
|
28
|
+
private pendingFrames;
|
|
29
|
+
private pendingInput;
|
|
30
|
+
private pendingHeard;
|
|
31
|
+
/** What the provider holds from answered responses, for estimating unreported usage. */
|
|
32
|
+
private held?;
|
|
33
|
+
private readonly tokens;
|
|
34
|
+
private responses;
|
|
35
|
+
private readonly callParents;
|
|
36
|
+
private writes;
|
|
37
|
+
private failure?;
|
|
38
|
+
/** The provider closed the session after warning it would (`goAway`). */
|
|
39
|
+
private endedByGoAway;
|
|
40
|
+
private socketHasClosed;
|
|
41
|
+
private closing?;
|
|
42
|
+
/** Canaries bound by the turns this session's agent tools ran: scrubbed from every record after. */
|
|
43
|
+
readonly agentCanaries: string[];
|
|
44
|
+
constructor(tree: TraceTree, out: {
|
|
45
|
+
sink: TraceSink;
|
|
46
|
+
policy: ResolvedObservabilityPolicy;
|
|
47
|
+
metadata?: Record<string, unknown>;
|
|
48
|
+
}, identity: TraceAttributes);
|
|
49
|
+
/** Attach the resolved request; frames are recorded from here on. */
|
|
50
|
+
bind(binding: LiveTraceBinding): void;
|
|
51
|
+
/** The adapter's `tapUpstream`: every frame sent, as it is sent. */
|
|
52
|
+
readonly sent: (row: Record<string, unknown>) => void;
|
|
53
|
+
/** The pinned key was refused for quota at setup; the session reopens on the fallback slot, which its responses name. */
|
|
54
|
+
private keyFallback;
|
|
55
|
+
setup(frame: Record<string, unknown>): void;
|
|
56
|
+
/** One received queue item, before guardrails. */
|
|
57
|
+
receive(item: LiveQueueItem): void;
|
|
58
|
+
/**
|
|
59
|
+
* One event as the host received it. Output reaches the host only after
|
|
60
|
+
* `receive` opened its response, so every output part lands on the open one;
|
|
61
|
+
* a transcript of the user's speech is input, recorded where it was heard.
|
|
62
|
+
*/
|
|
63
|
+
delivered(event: TurnEvent): void;
|
|
64
|
+
/** A guardrail decision on the model's output: on the open response. */
|
|
65
|
+
outbound(event: TurnEventOf<'guardrail'>): void;
|
|
66
|
+
/** A guardrail decision on the session (inbound text): on the session span. */
|
|
67
|
+
inbound(event: TurnEventOf<'guardrail'>): void;
|
|
68
|
+
/** One run of the gate on the model's output, on the open response: a decision after it is its. */
|
|
69
|
+
outboundTime(ms: number): void;
|
|
70
|
+
/** The check on text the host sent into the session, pass or decision, with its time. */
|
|
71
|
+
inboundCheck(ms: number, event: TurnEventOf<'guardrail'> | undefined): void;
|
|
72
|
+
/**
|
|
73
|
+
* Record the socket closing; the first close is the one that ended the
|
|
74
|
+
* session. A provider close carries its warning (`goAway`) and what the code
|
|
75
|
+
* means as a failure, so a warned close stays fully diagnosable.
|
|
76
|
+
*/
|
|
77
|
+
socketClosed(code: number, reason: string, initiator: LiveCloser, provider?: Extract<LiveQueueItem, {
|
|
78
|
+
type: 'closed';
|
|
79
|
+
}>): void;
|
|
80
|
+
/**
|
|
81
|
+
* Close the response whose `turnComplete` arrived and write its record.
|
|
82
|
+
* Returns its one `tokens` event, reported or estimated.
|
|
83
|
+
*/
|
|
84
|
+
settle(): Promise<TurnEvent | undefined>;
|
|
85
|
+
/** The span a `done` ends: the open response, else the last one. */
|
|
86
|
+
responseTraceparent(): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Open the record for one `executeTool` call, under the response that asked
|
|
89
|
+
* for it (the session when the call id is unknown). `finish` writes it.
|
|
90
|
+
*/
|
|
91
|
+
toolRecord(callId: string): {
|
|
92
|
+
open: (name: string, attributes: TraceAttributes) => SpanHandle;
|
|
93
|
+
finish: () => void;
|
|
94
|
+
};
|
|
95
|
+
/** End the session: close what is open, write the session record, wait for every write. */
|
|
96
|
+
close(end: LiveTraceEnd): Promise<void>;
|
|
97
|
+
private finish;
|
|
98
|
+
private route;
|
|
99
|
+
private row;
|
|
100
|
+
private open;
|
|
101
|
+
/**
|
|
102
|
+
* Close the open response and write its record. A response ended by the
|
|
103
|
+
* session closing has no usage event: what was billed is unknown.
|
|
104
|
+
*/
|
|
105
|
+
private endResponse;
|
|
106
|
+
/** Build and write one record, after every earlier write. */
|
|
107
|
+
private write;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Open a session's trace: its `invoke_agent` span under the host's `traceparent`,
|
|
111
|
+
* written under the session's profile's `observability` and cleaned with its detectors.
|
|
112
|
+
*/
|
|
113
|
+
declare function startLiveTrace(req: SessionRequest, profile: Pick<Profile, 'observability' | 'guardrails'> | undefined, sinkOverride?: TraceSink): LiveTrace;
|
|
114
|
+
export type { LiveCloser, LiveTrace, LiveTraceBinding, LiveTraceEnd };
|
|
115
|
+
export { startLiveTrace };
|
|
@@ -0,0 +1,500 @@
|
|
|
1
|
+
import { errorKind, isAbortError, TheoremError } from '../../../guardrails/error.js';
|
|
2
|
+
import { resolveTraceWriter } from '../../../observability/policy.js';
|
|
3
|
+
import { writeTrace } from '../../../observability/trace.js';
|
|
4
|
+
import { buildRecord } from '../../../observability/trace-record.js';
|
|
5
|
+
import { startTrace, traceJson, } from '../../../observability/trace-span.js';
|
|
6
|
+
import { liveSentInput } from '../../../providers/live.js';
|
|
7
|
+
import { KEY_FALLBACK_ROW } from '../../../providers/types.js';
|
|
8
|
+
import { base64ToBytes, bytesToBase64 } from '../../util/base64.js';
|
|
9
|
+
import { asRecord } from '../record.js';
|
|
10
|
+
import { callTokensEvent, heldAfter, observeCallEvent, startCallUsage, } from '../runner/usage.js';
|
|
11
|
+
import { endThrownSpan, guardrailAttributes, guardrailCheckAttributes, OutputFold, optional, startCallTrace, traceLinks, usageAttributes, } from '../turn-trace.js';
|
|
12
|
+
import { sumTokens } from '../usage.js';
|
|
13
|
+
/** Events that are the model's output: they mark a response as answering. */
|
|
14
|
+
const OUTPUT_EVENTS = new Set(['text', 'thought', 'media', 'tool']);
|
|
15
|
+
const MS_PER_S = 1000;
|
|
16
|
+
/** One user message holding exactly one inline audio part: a realtime audio chunk. */
|
|
17
|
+
function audioChunk(msg) {
|
|
18
|
+
const [part, ...rest] = msg.parts ?? [];
|
|
19
|
+
if (msg.role !== 'user' || msg.content || rest.length > 0)
|
|
20
|
+
return undefined;
|
|
21
|
+
return part?.type === 'audio' && 'data' in part ? part : undefined;
|
|
22
|
+
}
|
|
23
|
+
/** A run's chunks as one part over their concatenated bytes; one part each when any is not base64. */
|
|
24
|
+
function audioRunParts(run) {
|
|
25
|
+
try {
|
|
26
|
+
const decoded = run.chunks.map(base64ToBytes);
|
|
27
|
+
const merged = new Uint8Array(decoded.reduce((size, bytes) => size + bytes.byteLength, 0));
|
|
28
|
+
let offset = 0;
|
|
29
|
+
for (const bytes of decoded) {
|
|
30
|
+
merged.set(bytes, offset);
|
|
31
|
+
offset += bytes.byteLength;
|
|
32
|
+
}
|
|
33
|
+
return [{ type: 'audio', mimeType: run.mimeType, data: bytesToBase64(merged) }];
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// why: Not base64: keep each chunk as sent, so the record labels what it holds.
|
|
37
|
+
return run.chunks.map((data) => ({ type: 'audio', mimeType: run.mimeType, data }));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Input sent since the previous response opened; a tool response is input to the response after the
|
|
42
|
+
* one that asked. Never the whole session: under sliding-window compression what the model read of
|
|
43
|
+
* it is unknowable. Contiguous audio of one format is one message.
|
|
44
|
+
*/
|
|
45
|
+
class LiveInput {
|
|
46
|
+
items = [];
|
|
47
|
+
run;
|
|
48
|
+
add(messages) {
|
|
49
|
+
for (const msg of messages) {
|
|
50
|
+
const chunk = audioChunk(msg);
|
|
51
|
+
if (chunk && this.run?.mimeType === chunk.mimeType) {
|
|
52
|
+
this.run.chunks.push(chunk.data);
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
this.run = chunk ? { mimeType: chunk.mimeType, chunks: [chunk.data] } : undefined;
|
|
56
|
+
this.items.push(this.run ?? msg);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
messages() {
|
|
60
|
+
return this.items.map((item) => 'chunks' in item ? { role: 'user', parts: audioRunParts(item) } : item);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/** A frame without its resumption handle: the handle is a credential. */
|
|
64
|
+
function withoutHandle(frame) {
|
|
65
|
+
const setup = asRecord(frame.setup);
|
|
66
|
+
const resumption = asRecord(setup?.sessionResumption);
|
|
67
|
+
if (setup && resumption && 'handle' in resumption) {
|
|
68
|
+
const { handle: _handle, ...rest } = resumption;
|
|
69
|
+
return { ...frame, setup: { ...setup, sessionResumption: rest } };
|
|
70
|
+
}
|
|
71
|
+
const update = asRecord(frame.sessionResumptionUpdate);
|
|
72
|
+
if (update && 'newHandle' in update) {
|
|
73
|
+
const { newHandle: _newHandle, ...rest } = update;
|
|
74
|
+
return { ...frame, sessionResumptionUpdate: rest };
|
|
75
|
+
}
|
|
76
|
+
return frame;
|
|
77
|
+
}
|
|
78
|
+
function stringAttribute(key, value) {
|
|
79
|
+
return typeof value === 'string' ? { [key]: value } : {};
|
|
80
|
+
}
|
|
81
|
+
/** A provider session signal as `theorem.session` attributes, or `undefined` for a response event. */
|
|
82
|
+
function sessionSignal(event) {
|
|
83
|
+
if (event.type === 'session') {
|
|
84
|
+
const { session } = event;
|
|
85
|
+
if (session.kind === 'turn_complete')
|
|
86
|
+
return undefined;
|
|
87
|
+
return {
|
|
88
|
+
kind: session.kind,
|
|
89
|
+
...('timeLeftMs' in session ? optional('time_left_ms', session.timeLeftMs) : {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (event.type !== 'evidence')
|
|
93
|
+
return undefined;
|
|
94
|
+
const { evidence } = event;
|
|
95
|
+
if (evidence.kind === 'voice_activity') {
|
|
96
|
+
const raw = asRecord(evidence.raw);
|
|
97
|
+
return {
|
|
98
|
+
kind: 'voice_activity',
|
|
99
|
+
...stringAttribute('activity', raw?.type),
|
|
100
|
+
...stringAttribute('audio_offset', raw?.audioOffset),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
if (evidence.kind === 'session_resumption') {
|
|
104
|
+
return {
|
|
105
|
+
kind: 'session_resumption',
|
|
106
|
+
...optional('resumable', evidence.resumable),
|
|
107
|
+
handle_issued: Boolean(event.sessionResumptionHandle),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
// why: Each record is written as soon as it is complete, so a long session never holds its whole trace.
|
|
113
|
+
class LiveTrace {
|
|
114
|
+
tree;
|
|
115
|
+
out;
|
|
116
|
+
identity;
|
|
117
|
+
root;
|
|
118
|
+
bound;
|
|
119
|
+
response;
|
|
120
|
+
lastResponse;
|
|
121
|
+
pendingFrames = [];
|
|
122
|
+
pendingInput = new LiveInput();
|
|
123
|
+
pendingHeard = [];
|
|
124
|
+
/** What the provider holds from answered responses, for estimating unreported usage. */
|
|
125
|
+
held;
|
|
126
|
+
tokens = [];
|
|
127
|
+
responses = 0;
|
|
128
|
+
callParents = new Map();
|
|
129
|
+
writes = Promise.resolve();
|
|
130
|
+
failure;
|
|
131
|
+
/** The provider closed the session after warning it would (`goAway`). */
|
|
132
|
+
endedByGoAway = false;
|
|
133
|
+
socketHasClosed = false;
|
|
134
|
+
closing;
|
|
135
|
+
/** Canaries bound by the turns this session's agent tools ran: scrubbed from every record after. */
|
|
136
|
+
agentCanaries = [];
|
|
137
|
+
constructor(tree, out, identity) {
|
|
138
|
+
this.tree = tree;
|
|
139
|
+
this.out = out;
|
|
140
|
+
this.identity = identity;
|
|
141
|
+
this.root = tree.root;
|
|
142
|
+
}
|
|
143
|
+
/** Attach the resolved request; frames are recorded from here on. */
|
|
144
|
+
bind(binding) {
|
|
145
|
+
this.bound = binding;
|
|
146
|
+
}
|
|
147
|
+
/** The adapter's `tapUpstream`: every frame sent, as it is sent. */
|
|
148
|
+
sent = (row) => {
|
|
149
|
+
if (row.eventType === KEY_FALLBACK_ROW) {
|
|
150
|
+
this.keyFallback(row);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (row.direction === 'receive') {
|
|
154
|
+
const body = asRecord(row.body);
|
|
155
|
+
if (body)
|
|
156
|
+
this.row(body);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const frame = asRecord(row.body);
|
|
160
|
+
if (!frame)
|
|
161
|
+
return;
|
|
162
|
+
const body = withoutHandle(frame);
|
|
163
|
+
if ('setup' in frame) {
|
|
164
|
+
this.root.event('theorem.wire.request', { body: traceJson(body) });
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
this.pendingInput.add(liveSentInput(row));
|
|
168
|
+
this.pendingFrames.push({ timeUnixNano: this.root.nowUnixNano(), body });
|
|
169
|
+
};
|
|
170
|
+
/** The pinned key was refused for quota at setup; the session reopens on the fallback slot, which its responses name. */
|
|
171
|
+
keyFallback(row) {
|
|
172
|
+
this.root.event('theorem.session', {
|
|
173
|
+
kind: 'key_fallback',
|
|
174
|
+
key_slot: String(row.from),
|
|
175
|
+
to_key_slot: String(row.keySlot),
|
|
176
|
+
'error.type': String(row.errorKind),
|
|
177
|
+
error: String(row.error),
|
|
178
|
+
});
|
|
179
|
+
const bound = this.bound;
|
|
180
|
+
if (bound?.binding)
|
|
181
|
+
this.bound = { ...bound, binding: { ...bound.binding, keySlot: String(row.keySlot) } };
|
|
182
|
+
}
|
|
183
|
+
setup(frame) {
|
|
184
|
+
this.root.event('theorem.upstream.row', { row: traceJson(frame) });
|
|
185
|
+
this.root.event('theorem.session', { kind: 'setup_complete' });
|
|
186
|
+
}
|
|
187
|
+
/** One received queue item, before guardrails. */
|
|
188
|
+
receive(item) {
|
|
189
|
+
switch (item.type) {
|
|
190
|
+
case 'batch':
|
|
191
|
+
for (const event of item.events)
|
|
192
|
+
this.route(event);
|
|
193
|
+
this.row(item.row);
|
|
194
|
+
return;
|
|
195
|
+
case 'row':
|
|
196
|
+
this.row(item.row);
|
|
197
|
+
return;
|
|
198
|
+
case 'error':
|
|
199
|
+
if (item.row)
|
|
200
|
+
this.row(item.row);
|
|
201
|
+
this.failure ??= item.error;
|
|
202
|
+
return;
|
|
203
|
+
case 'closed':
|
|
204
|
+
this.socketClosed(item.code, item.reason, 'provider', item);
|
|
205
|
+
// why: A close the provider warned of ends the session; it is not the session's failure.
|
|
206
|
+
if (item.goAway)
|
|
207
|
+
this.endedByGoAway = true;
|
|
208
|
+
else
|
|
209
|
+
this.failure ??= item.error;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* One event as the host received it. Output reaches the host only after
|
|
215
|
+
* `receive` opened its response, so every output part lands on the open one;
|
|
216
|
+
* a transcript of the user's speech is input, recorded where it was heard.
|
|
217
|
+
*/
|
|
218
|
+
delivered(event) {
|
|
219
|
+
if (event.type === 'evidence' && event.evidence.kind === 'input_transcription')
|
|
220
|
+
return;
|
|
221
|
+
this.response?.delivered.add(event, this.root.nowUnixNano());
|
|
222
|
+
}
|
|
223
|
+
/** A guardrail decision on the model's output: on the open response. */
|
|
224
|
+
outbound(event) {
|
|
225
|
+
if (this.response)
|
|
226
|
+
this.response.call.guardrail(event.guardrail);
|
|
227
|
+
else
|
|
228
|
+
this.inbound(event);
|
|
229
|
+
}
|
|
230
|
+
/** A guardrail decision on the session (inbound text): on the session span. */
|
|
231
|
+
inbound(event) {
|
|
232
|
+
this.root.event('theorem.guardrail', guardrailAttributes(event.guardrail));
|
|
233
|
+
}
|
|
234
|
+
/** One run of the gate on the model's output, on the open response: a decision after it is its. */
|
|
235
|
+
outboundTime(ms) {
|
|
236
|
+
this.response?.call.guardTime('live_output', ms);
|
|
237
|
+
}
|
|
238
|
+
/** The check on text the host sent into the session, pass or decision, with its time. */
|
|
239
|
+
inboundCheck(ms, event) {
|
|
240
|
+
this.root.event('theorem.guardrail', guardrailCheckAttributes('live_input', ms, event?.guardrail, {
|
|
241
|
+
stage: 'live_inbound',
|
|
242
|
+
trust: 'untrusted',
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Record the socket closing; the first close is the one that ended the
|
|
247
|
+
* session. A provider close carries its warning (`goAway`) and what the code
|
|
248
|
+
* means as a failure, so a warned close stays fully diagnosable.
|
|
249
|
+
*/
|
|
250
|
+
socketClosed(code, reason, initiator, provider) {
|
|
251
|
+
if (this.socketHasClosed)
|
|
252
|
+
return;
|
|
253
|
+
this.socketHasClosed = true;
|
|
254
|
+
const goAway = provider?.goAway;
|
|
255
|
+
this.root.event('theorem.session', {
|
|
256
|
+
kind: 'closed',
|
|
257
|
+
code,
|
|
258
|
+
reason,
|
|
259
|
+
initiator,
|
|
260
|
+
...(provider?.error ? { 'error.type': errorKind(provider.error) } : {}),
|
|
261
|
+
...(goAway
|
|
262
|
+
? {
|
|
263
|
+
cause: 'go_away',
|
|
264
|
+
...optional('time_left_ms', goAway.timeLeftMs),
|
|
265
|
+
closed_after_ms: goAway.closedAfterMs,
|
|
266
|
+
}
|
|
267
|
+
: {}),
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Close the response whose `turnComplete` arrived and write its record.
|
|
272
|
+
* Returns its one `tokens` event, reported or estimated.
|
|
273
|
+
*/
|
|
274
|
+
async settle() {
|
|
275
|
+
return this.response?.complete ? await this.endResponse({}) : undefined;
|
|
276
|
+
}
|
|
277
|
+
/** The span a `done` ends: the open response, else the last one. */
|
|
278
|
+
responseTraceparent() {
|
|
279
|
+
return (this.response?.call.span ?? this.lastResponse)?.traceparent();
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Open the record for one `executeTool` call, under the response that asked
|
|
283
|
+
* for it (the session when the call id is unknown). `finish` writes it.
|
|
284
|
+
*/
|
|
285
|
+
toolRecord(callId) {
|
|
286
|
+
let tree;
|
|
287
|
+
return {
|
|
288
|
+
open: (name, attributes) => {
|
|
289
|
+
tree = startTrace(name, {
|
|
290
|
+
attributes: { ...this.identity, ...attributes },
|
|
291
|
+
traceparent: this.callParents.get(callId) ?? this.root.traceparent(),
|
|
292
|
+
clock: this.tree.clock,
|
|
293
|
+
});
|
|
294
|
+
return tree.root;
|
|
295
|
+
},
|
|
296
|
+
finish: () => {
|
|
297
|
+
if (tree)
|
|
298
|
+
this.write(tree.collect());
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
/** End the session: close what is open, write the session record, wait for every write. */
|
|
303
|
+
close(end) {
|
|
304
|
+
this.closing ??= this.finish(end);
|
|
305
|
+
return this.closing;
|
|
306
|
+
}
|
|
307
|
+
async finish(end) {
|
|
308
|
+
const aborted = end.thrown !== undefined && isAbortError(end.thrown);
|
|
309
|
+
const thrown = aborted ? undefined : (end.thrown ?? this.failure);
|
|
310
|
+
if (this.response) {
|
|
311
|
+
await this.endResponse(thrown === undefined ? { cancelled: true } : { thrown });
|
|
312
|
+
}
|
|
313
|
+
// why: Sent after the last response: no response read it.
|
|
314
|
+
for (const frame of this.pendingFrames) {
|
|
315
|
+
this.root.event('theorem.wire.request', { body: traceJson(frame.body) }, frame.timeUnixNano);
|
|
316
|
+
}
|
|
317
|
+
this.pendingFrames = [];
|
|
318
|
+
const tokens = sumTokens(this.tokens);
|
|
319
|
+
this.root.set({
|
|
320
|
+
...(tokens ? usageAttributes(tokens) : {}),
|
|
321
|
+
'theorem.steps': this.responses,
|
|
322
|
+
...(aborted ? { 'theorem.stop.kind': 'cancelled' } : {}),
|
|
323
|
+
...(!aborted && this.endedByGoAway ? { 'theorem.stop.kind': 'go_away' } : {}),
|
|
324
|
+
});
|
|
325
|
+
if (thrown !== undefined) {
|
|
326
|
+
endThrownSpan(this.root, thrown);
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
// why: A warned close is no verdict: neither failed nor known to be fine.
|
|
330
|
+
this.root.end(aborted || this.endedByGoAway ? { code: 'UNSET' } : { code: 'OK' });
|
|
331
|
+
}
|
|
332
|
+
this.write(this.tree.collect());
|
|
333
|
+
await this.writes;
|
|
334
|
+
}
|
|
335
|
+
route(event) {
|
|
336
|
+
const signal = sessionSignal(event);
|
|
337
|
+
if (signal) {
|
|
338
|
+
this.root.event('theorem.session', signal);
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (event.type === 'tool' && event.tool.phase === 'cancel') {
|
|
342
|
+
(this.response?.call.span ?? this.root).event('theorem.tool.cancel', {
|
|
343
|
+
'gen_ai.tool.call.id': event.tool.callId,
|
|
344
|
+
'gen_ai.tool.name': event.tool.name,
|
|
345
|
+
});
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const kind = event.type === 'evidence' ? event.evidence.kind : undefined;
|
|
349
|
+
if (kind === 'input_transcription' && !(this.response && !this.response.answering)) {
|
|
350
|
+
// why: Heard after the model began answering: input for the next response.
|
|
351
|
+
this.pendingHeard.push(event);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const response = this.open();
|
|
355
|
+
if (event.type === 'session') {
|
|
356
|
+
response.complete = true;
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
observeCallEvent(response.usage, event);
|
|
360
|
+
response.call.observe(event);
|
|
361
|
+
if (!response.answering && (OUTPUT_EVENTS.has(event.type) || kind === 'output_transcription')) {
|
|
362
|
+
// why: The reply's first chunk, from the response's first input frame: what a person waited.
|
|
363
|
+
response.call.span.set({
|
|
364
|
+
'gen_ai.response.time_to_first_chunk': response.call.span.msSinceStart() / MS_PER_S,
|
|
365
|
+
});
|
|
366
|
+
response.answering = true;
|
|
367
|
+
}
|
|
368
|
+
if (event.type === 'tool' && event.tool.phase === undefined) {
|
|
369
|
+
this.callParents.set(event.tool.callId, response.call.span.traceparent());
|
|
370
|
+
}
|
|
371
|
+
if (event.type === 'done' &&
|
|
372
|
+
response.stop?.kind !== 'interrupted' &&
|
|
373
|
+
!(event.stop.kind === 'completed' && response.stop?.kind === 'generation_complete')) {
|
|
374
|
+
response.stop = event.stop;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
row(row) {
|
|
378
|
+
const span = this.response?.call.span ?? this.root;
|
|
379
|
+
span.event('theorem.upstream.row', { row: traceJson(withoutHandle(row)) });
|
|
380
|
+
}
|
|
381
|
+
open() {
|
|
382
|
+
if (this.response)
|
|
383
|
+
return this.response;
|
|
384
|
+
const bound = this.bound;
|
|
385
|
+
if (!bound) {
|
|
386
|
+
// labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
387
|
+
throw new TheoremError('internal', 'Live trace received a response before it was bound');
|
|
388
|
+
}
|
|
389
|
+
const usage = startCallUsage(bound.system, { history: [], input: [] }, this.held);
|
|
390
|
+
// why: A response starts at its first input frame, so its duration includes the model's listening time.
|
|
391
|
+
const startTimeUnixNano = this.pendingFrames[0]?.timeUnixNano;
|
|
392
|
+
let tree;
|
|
393
|
+
const call = startCallTrace((name, options) => {
|
|
394
|
+
tree = startTrace(name, {
|
|
395
|
+
...options,
|
|
396
|
+
// why: Each record stands alone (the session record may never be written): it names its agent.
|
|
397
|
+
attributes: { ...this.identity, ...options.attributes },
|
|
398
|
+
traceparent: this.root.traceparent(),
|
|
399
|
+
clock: this.tree.clock,
|
|
400
|
+
...(startTimeUnixNano ? { startTimeUnixNano } : {}),
|
|
401
|
+
});
|
|
402
|
+
return tree.root;
|
|
403
|
+
}, {
|
|
404
|
+
req: bound.request,
|
|
405
|
+
usage,
|
|
406
|
+
binding: bound.binding,
|
|
407
|
+
transport: bound.generation.transport,
|
|
408
|
+
step: this.responses + 1,
|
|
409
|
+
});
|
|
410
|
+
if (!tree) {
|
|
411
|
+
// labels-exempt: developer contract / internal diagnostic — not end-user or model copy (P2)
|
|
412
|
+
throw new TheoremError('internal', 'Live response span was not opened');
|
|
413
|
+
}
|
|
414
|
+
// why: A Live response streams over the session socket; no HTTP try says so.
|
|
415
|
+
call.span.set({ 'gen_ai.request.stream': true });
|
|
416
|
+
for (const frame of this.pendingFrames) {
|
|
417
|
+
call.span.event('theorem.wire.request', { body: traceJson(frame.body) }, frame.timeUnixNano);
|
|
418
|
+
}
|
|
419
|
+
const response = {
|
|
420
|
+
tree,
|
|
421
|
+
call,
|
|
422
|
+
usage,
|
|
423
|
+
input: this.pendingInput,
|
|
424
|
+
delivered: new OutputFold(),
|
|
425
|
+
answering: false,
|
|
426
|
+
complete: false,
|
|
427
|
+
};
|
|
428
|
+
for (const heard of this.pendingHeard)
|
|
429
|
+
call.observe(heard);
|
|
430
|
+
this.pendingFrames = [];
|
|
431
|
+
this.pendingInput = new LiveInput();
|
|
432
|
+
this.pendingHeard = [];
|
|
433
|
+
this.response = response;
|
|
434
|
+
return response;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Close the open response and write its record. A response ended by the
|
|
438
|
+
* session closing has no usage event: what was billed is unknown.
|
|
439
|
+
*/
|
|
440
|
+
async endResponse(end) {
|
|
441
|
+
const response = this.response;
|
|
442
|
+
const bound = this.bound;
|
|
443
|
+
if (!(response && bound))
|
|
444
|
+
return undefined;
|
|
445
|
+
this.response = undefined;
|
|
446
|
+
this.responses += 1;
|
|
447
|
+
response.usage.conversation = { history: response.input.messages(), input: [] };
|
|
448
|
+
const answered = end.thrown === undefined && !end.cancelled;
|
|
449
|
+
const tokens = answered ? await callTokensEvent(response.usage, bound.generation) : undefined;
|
|
450
|
+
if (answered)
|
|
451
|
+
this.held = await heldAfter(response.usage);
|
|
452
|
+
// why: Beside `output.messages` (what the model produced): what the host received of it.
|
|
453
|
+
response.call.span.set({
|
|
454
|
+
'theorem.output.delivered': [{ role: 'assistant', parts: response.delivered.parts }],
|
|
455
|
+
});
|
|
456
|
+
response.call.end({
|
|
457
|
+
...(tokens?.tokens ? { tokens: tokens.tokens } : {}),
|
|
458
|
+
stop: end.cancelled ? { kind: 'cancelled' } : response.stop,
|
|
459
|
+
...(end.thrown === undefined ? {} : { thrown: end.thrown }),
|
|
460
|
+
});
|
|
461
|
+
if (tokens?.tokens)
|
|
462
|
+
this.tokens.push(tokens.tokens);
|
|
463
|
+
this.lastResponse = response.call.span;
|
|
464
|
+
this.write(response.tree.collect());
|
|
465
|
+
return tokens;
|
|
466
|
+
}
|
|
467
|
+
/** Build and write one record, after every earlier write. */
|
|
468
|
+
write(spans) {
|
|
469
|
+
const record = buildRecord({
|
|
470
|
+
spans,
|
|
471
|
+
policy: this.out.policy,
|
|
472
|
+
canaries: [...(this.bound ? [this.bound.canary] : []), ...this.agentCanaries],
|
|
473
|
+
...(this.out.metadata ? { metadata: this.out.metadata } : {}),
|
|
474
|
+
});
|
|
475
|
+
this.writes = this.writes.then(() => writeTrace(this.out.sink, record, this.out.policy));
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Open a session's trace: its `invoke_agent` span under the host's `traceparent`,
|
|
480
|
+
* written under the session's profile's `observability` and cleaned with its detectors.
|
|
481
|
+
*/
|
|
482
|
+
function startLiveTrace(req, profile, sinkOverride) {
|
|
483
|
+
const { sink, policy } = resolveTraceWriter({
|
|
484
|
+
override: sinkOverride,
|
|
485
|
+
observability: profile?.observability,
|
|
486
|
+
guardrails: profile?.guardrails,
|
|
487
|
+
});
|
|
488
|
+
const identity = {
|
|
489
|
+
'gen_ai.agent.name': req.profile,
|
|
490
|
+
...optional('gen_ai.conversation.id', req.conversationId),
|
|
491
|
+
};
|
|
492
|
+
const tree = startTrace(`invoke_agent ${req.profile}`, {
|
|
493
|
+
kind: 'INTERNAL',
|
|
494
|
+
attributes: { 'gen_ai.operation.name': 'invoke_agent', ...identity },
|
|
495
|
+
links: traceLinks(req.links),
|
|
496
|
+
...(req.traceparent ? { traceparent: req.traceparent } : {}),
|
|
497
|
+
});
|
|
498
|
+
return new LiveTrace(tree, { sink, policy, ...(req.metadata ? { metadata: req.metadata } : {}) }, identity);
|
|
499
|
+
}
|
|
500
|
+
export { startLiveTrace };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text counts use a characters / 4 heuristic for all model families. Media is never estimated: a
|
|
3
|
+
* media part is reported as `unknownMedia`, and the upstream's own count is used when it gives one.
|
|
4
|
+
*/
|
|
5
|
+
import type { InteractionPart, TurnHistoryMessage } from '../types.js';
|
|
6
|
+
/** Text estimation method; retained under this name for API compatibility. */
|
|
7
|
+
export declare const TOKEN_TEXT_ENCODING = "chars/4";
|
|
8
|
+
/** A token count and the number of media parts left out of it. */
|
|
9
|
+
export interface TokenCount {
|
|
10
|
+
tokens: number;
|
|
11
|
+
/** Media parts left out of `tokens` because their count is unknown. */
|
|
12
|
+
unknownMedia: number;
|
|
13
|
+
}
|
|
14
|
+
/** Text counting is synchronous; anything with media is not. */
|
|
15
|
+
export interface TokenEstimator {
|
|
16
|
+
/** Approximate tokens: UTF-16 code units divided by four, rounded up. */
|
|
17
|
+
text: (text: string) => number;
|
|
18
|
+
parts: (parts: InteractionPart[]) => TokenCount;
|
|
19
|
+
/** Content, parts, and tool-call arguments across history messages. */
|
|
20
|
+
messages: (messages: TurnHistoryMessage[]) => TokenCount;
|
|
21
|
+
}
|
|
22
|
+
/** Returns the heuristic estimator; async for compatibility with existing callers. */
|
|
23
|
+
export declare function loadTokenEstimator(): Promise<TokenEstimator>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text counts use a characters / 4 heuristic for all model families. Media is never estimated: a
|
|
3
|
+
* media part is reported as `unknownMedia`, and the upstream's own count is used when it gives one.
|
|
4
|
+
*/
|
|
5
|
+
import { historyMessageParts } from '../interaction-parts.js';
|
|
6
|
+
/** Text estimation method; retained under this name for API compatibility. */
|
|
7
|
+
export const TOKEN_TEXT_ENCODING = 'chars/4';
|
|
8
|
+
function buildEstimator() {
|
|
9
|
+
const text = (value) => Math.ceil(value.length / 4);
|
|
10
|
+
const parts = (list) => {
|
|
11
|
+
const count = { tokens: 0, unknownMedia: 0 };
|
|
12
|
+
for (const part of list) {
|
|
13
|
+
if (part.type === 'text') {
|
|
14
|
+
count.tokens += text(part.text);
|
|
15
|
+
continue;
|
|
16
|
+
}
|
|
17
|
+
count.unknownMedia += 1;
|
|
18
|
+
}
|
|
19
|
+
return count;
|
|
20
|
+
};
|
|
21
|
+
const messages = (list) => {
|
|
22
|
+
const count = { tokens: 0, unknownMedia: 0 };
|
|
23
|
+
for (const msg of list) {
|
|
24
|
+
const fromParts = parts(historyMessageParts(msg));
|
|
25
|
+
count.tokens += fromParts.tokens;
|
|
26
|
+
count.unknownMedia += fromParts.unknownMedia;
|
|
27
|
+
for (const tc of msg.tool_calls ?? []) {
|
|
28
|
+
count.tokens += text(tc.function.name) + text(tc.function.arguments);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return count;
|
|
32
|
+
};
|
|
33
|
+
return { text, parts, messages };
|
|
34
|
+
}
|
|
35
|
+
/** Returns the heuristic estimator; async for compatibility with existing callers. */
|
|
36
|
+
export function loadTokenEstimator() {
|
|
37
|
+
return Promise.resolve(buildEstimator());
|
|
38
|
+
}
|