@theoremjs/agents 0.0.0-stage → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1264 -2
- package/esm/_dnt.polyfills.d.ts +66 -0
- package/esm/_dnt.polyfills.js +51 -0
- package/esm/mod.d.ts +65 -0
- package/esm/mod.js +42 -0
- package/esm/package.json +3 -0
- package/esm/src/cli/bin.d.ts +7 -0
- package/esm/src/cli/bin.js +9 -0
- package/esm/src/cli/commands/bench.d.ts +6 -0
- package/esm/src/cli/commands/bench.js +458 -0
- package/esm/src/cli/commands/egress-compile.d.ts +17 -0
- package/esm/src/cli/commands/egress-compile.js +25 -0
- package/esm/src/cli/commands/eval.d.ts +37 -0
- package/esm/src/cli/commands/eval.js +190 -0
- package/esm/src/cli/commands/fuzz-canary.d.ts +15 -0
- package/esm/src/cli/commands/fuzz-canary.js +202 -0
- package/esm/src/cli/commands/fuzz-guardrails.d.ts +2 -0
- package/esm/src/cli/commands/fuzz-guardrails.js +5 -0
- package/esm/src/cli/commands/profile.d.ts +2 -0
- package/esm/src/cli/commands/profile.js +80 -0
- package/esm/src/cli/commands/run.d.ts +13 -0
- package/esm/src/cli/commands/run.js +45 -0
- package/esm/src/cli/commands/test.d.ts +25 -0
- package/esm/src/cli/commands/test.js +143 -0
- package/esm/src/cli/event-log.d.ts +15 -0
- package/esm/src/cli/event-log.js +136 -0
- package/esm/src/cli/index.d.ts +10 -0
- package/esm/src/cli/index.js +267 -0
- package/esm/src/cli/matrix/fixtures.d.ts +10 -0
- package/esm/src/cli/matrix/fixtures.js +72 -0
- package/esm/src/cli/matrix/synthesizer.d.ts +18 -0
- package/esm/src/cli/matrix/synthesizer.js +103 -0
- package/esm/src/evals/attachments.d.ts +4 -0
- package/esm/src/evals/attachments.js +53 -0
- package/esm/src/evals/breakdown.d.ts +28 -0
- package/esm/src/evals/breakdown.js +68 -0
- package/esm/src/evals/graders/answer.d.ts +13 -0
- package/esm/src/evals/graders/answer.js +133 -0
- package/esm/src/evals/graders/code.d.ts +64 -0
- package/esm/src/evals/graders/code.js +205 -0
- package/esm/src/evals/graders/judge.d.ts +20 -0
- package/esm/src/evals/graders/judge.js +365 -0
- package/esm/src/evals/graders/latency.d.ts +5 -0
- package/esm/src/evals/graders/latency.js +81 -0
- package/esm/src/evals/graders/live.d.ts +11 -0
- package/esm/src/evals/graders/live.js +40 -0
- package/esm/src/evals/graders/media.d.ts +18 -0
- package/esm/src/evals/graders/media.js +92 -0
- package/esm/src/evals/graders/shared.d.ts +11 -0
- package/esm/src/evals/graders/shared.js +62 -0
- package/esm/src/evals/graders/transcript.d.ts +17 -0
- package/esm/src/evals/graders/transcript.js +200 -0
- package/esm/src/evals/mod.d.ts +42 -0
- package/esm/src/evals/mod.js +30 -0
- package/esm/src/evals/record.d.ts +35 -0
- package/esm/src/evals/record.js +105 -0
- package/esm/src/evals/rubrics/catalog.d.ts +148 -0
- package/esm/src/evals/rubrics/catalog.js +846 -0
- package/esm/src/evals/rubrics/mod.d.ts +24 -0
- package/esm/src/evals/rubrics/mod.js +55 -0
- package/esm/src/evals/rubrics/mustache.d.ts +23 -0
- package/esm/src/evals/rubrics/mustache.js +154 -0
- package/esm/src/evals/rubrics/types.d.ts +54 -0
- package/esm/src/evals/rubrics/types.js +74 -0
- package/esm/src/evals/run.d.ts +118 -0
- package/esm/src/evals/run.js +452 -0
- package/esm/src/evals/suite.d.ts +19 -0
- package/esm/src/evals/suite.js +92 -0
- package/esm/src/evals/summary.d.ts +32 -0
- package/esm/src/evals/summary.js +30 -0
- package/esm/src/evals/trial.d.ts +27 -0
- package/esm/src/evals/trial.js +158 -0
- package/esm/src/evals/types.d.ts +260 -0
- package/esm/src/evals/types.js +126 -0
- package/esm/src/evals/verdict.d.ts +18 -0
- package/esm/src/evals/verdict.js +45 -0
- package/esm/src/guardrails/canary-gate.d.ts +21 -0
- package/esm/src/guardrails/canary-gate.js +40 -0
- package/esm/src/guardrails/canary.d.ts +112 -0
- package/esm/src/guardrails/canary.js +901 -0
- package/esm/src/guardrails/compile-egress.d.ts +11 -0
- package/esm/src/guardrails/compile-egress.js +11 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.d.ts +22 -0
- package/esm/src/guardrails/corpus/canary-egress-attacks.js +303 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.d.ts +5 -0
- package/esm/src/guardrails/corpus/fuzz-inbound.js +202 -0
- package/esm/src/guardrails/corpus/inbound-payloads.d.ts +3 -0
- package/esm/src/guardrails/corpus/inbound-payloads.js +118 -0
- package/esm/src/guardrails/corpus/live-attacks.d.ts +13 -0
- package/esm/src/guardrails/corpus/live-attacks.js +224 -0
- package/esm/src/guardrails/corpus/mod.d.ts +7 -0
- package/esm/src/guardrails/corpus/mod.js +4 -0
- package/esm/src/guardrails/corpus/secrets.d.ts +12 -0
- package/esm/src/guardrails/corpus/secrets.js +16 -0
- package/esm/src/guardrails/corpus/strings.d.ts +23 -0
- package/esm/src/guardrails/corpus/strings.js +29 -0
- package/esm/src/guardrails/corpus/types.d.ts +32 -0
- package/esm/src/guardrails/corpus/types.js +1 -0
- package/esm/src/guardrails/egress-automata.d.ts +14 -0
- package/esm/src/guardrails/egress-automata.js +6059 -0
- package/esm/src/guardrails/egress-compiler.d.ts +33 -0
- package/esm/src/guardrails/egress-compiler.js +237 -0
- package/esm/src/guardrails/egress-patterns.d.ts +24 -0
- package/esm/src/guardrails/egress-patterns.js +32 -0
- package/esm/src/guardrails/egress-policy.d.ts +27 -0
- package/esm/src/guardrails/egress-policy.js +76 -0
- package/esm/src/guardrails/egress-rules.d.ts +54 -0
- package/esm/src/guardrails/egress-rules.js +49 -0
- package/esm/src/guardrails/egress-stream.d.ts +105 -0
- package/esm/src/guardrails/egress-stream.js +645 -0
- package/esm/src/guardrails/egress-urls.d.ts +83 -0
- package/esm/src/guardrails/egress-urls.js +917 -0
- package/esm/src/guardrails/egress.d.ts +106 -0
- package/esm/src/guardrails/egress.js +374 -0
- package/esm/src/guardrails/error.d.ts +26 -0
- package/esm/src/guardrails/error.js +91 -0
- package/esm/src/guardrails/event-schemas.d.ts +57 -0
- package/esm/src/guardrails/event-schemas.js +41 -0
- package/esm/src/guardrails/events.d.ts +9 -0
- package/esm/src/guardrails/events.js +42 -0
- package/esm/src/guardrails/hits.d.ts +8 -0
- package/esm/src/guardrails/hits.js +19 -0
- package/esm/src/guardrails/injection-patterns.d.ts +15 -0
- package/esm/src/guardrails/injection-patterns.js +94 -0
- package/esm/src/guardrails/injection.d.ts +14 -0
- package/esm/src/guardrails/injection.js +237 -0
- package/esm/src/guardrails/lexicon.d.ts +30 -0
- package/esm/src/guardrails/lexicon.js +478 -0
- package/esm/src/guardrails/live-outbound-gate.d.ts +54 -0
- package/esm/src/guardrails/live-outbound-gate.js +305 -0
- package/esm/src/guardrails/mod.d.ts +46 -0
- package/esm/src/guardrails/mod.js +29 -0
- package/esm/src/guardrails/network.d.ts +42 -0
- package/esm/src/guardrails/network.js +328 -0
- package/esm/src/guardrails/normalize.d.ts +6 -0
- package/esm/src/guardrails/normalize.js +132 -0
- package/esm/src/guardrails/policy.d.ts +19 -0
- package/esm/src/guardrails/policy.js +50 -0
- package/esm/src/guardrails/progressive-yield.d.ts +69 -0
- package/esm/src/guardrails/progressive-yield.js +237 -0
- package/esm/src/guardrails/prompt-echo.d.ts +38 -0
- package/esm/src/guardrails/prompt-echo.js +225 -0
- package/esm/src/guardrails/quota.d.ts +20 -0
- package/esm/src/guardrails/quota.js +80 -0
- package/esm/src/guardrails/rules.d.ts +56 -0
- package/esm/src/guardrails/rules.js +54 -0
- package/esm/src/guardrails/sanitize.d.ts +23 -0
- package/esm/src/guardrails/sanitize.js +184 -0
- package/esm/src/guardrails/sensitive.d.ts +29 -0
- package/esm/src/guardrails/sensitive.js +113 -0
- package/esm/src/guardrails/serialize.d.ts +14 -0
- package/esm/src/guardrails/serialize.js +37 -0
- package/esm/src/guardrails/testing.d.ts +9 -0
- package/esm/src/guardrails/testing.js +8 -0
- package/esm/src/guardrails/theorem-error.d.ts +18 -0
- package/esm/src/guardrails/theorem-error.js +53 -0
- package/esm/src/guardrails/thought-guard.d.ts +55 -0
- package/esm/src/guardrails/thought-guard.js +464 -0
- package/esm/src/guardrails/tool-directives.d.ts +19 -0
- package/esm/src/guardrails/tool-directives.js +109 -0
- package/esm/src/guardrails/tool-result.d.ts +61 -0
- package/esm/src/guardrails/tool-result.js +248 -0
- package/esm/src/guardrails/types.d.ts +242 -0
- package/esm/src/guardrails/types.js +54 -0
- package/esm/src/host/client-turn.d.ts +9 -0
- package/esm/src/host/client-turn.js +38 -0
- package/esm/src/host/mint-trace.d.ts +28 -0
- package/esm/src/host/mint-trace.js +59 -0
- package/esm/src/host/mod.d.ts +13 -0
- package/esm/src/host/mod.js +11 -0
- package/esm/src/host/readStreamingJsonStringField.d.ts +2 -0
- package/esm/src/host/readStreamingJsonStringField.js +68 -0
- package/esm/src/host/reply.d.ts +7 -0
- package/esm/src/host/reply.js +35 -0
- package/esm/src/interface/blocks.d.ts +8 -0
- package/esm/src/interface/blocks.js +213 -0
- package/esm/src/interface/composer-actions.d.ts +20 -0
- package/esm/src/interface/composer-actions.js +31 -0
- package/esm/src/interface/draft.d.ts +14 -0
- package/esm/src/interface/draft.js +28 -0
- package/esm/src/interface/from-profile.d.ts +12 -0
- package/esm/src/interface/from-profile.js +144 -0
- package/esm/src/interface/history.d.ts +40 -0
- package/esm/src/interface/history.js +269 -0
- package/esm/src/interface/inputs.d.ts +10 -0
- package/esm/src/interface/inputs.js +64 -0
- package/esm/src/interface/mod.d.ts +31 -0
- package/esm/src/interface/mod.js +21 -0
- package/esm/src/interface/models.d.ts +19 -0
- package/esm/src/interface/models.js +45 -0
- package/esm/src/interface/pending.d.ts +48 -0
- package/esm/src/interface/pending.js +146 -0
- package/esm/src/interface/profile-interface.d.ts +4 -0
- package/esm/src/interface/profile-interface.js +223 -0
- package/esm/src/interface/session.d.ts +64 -0
- package/esm/src/interface/session.js +121 -0
- package/esm/src/interface/tool-calls.d.ts +20 -0
- package/esm/src/interface/tool-calls.js +73 -0
- package/esm/src/interface/tool-invoke.d.ts +4 -0
- package/esm/src/interface/tool-invoke.js +20 -0
- package/esm/src/interface/tool-media.d.ts +9 -0
- package/esm/src/interface/tool-media.js +112 -0
- package/esm/src/interface/types.d.ts +213 -0
- package/esm/src/interface/types.js +4 -0
- package/esm/src/kernel/auth/credential-source.d.ts +23 -0
- package/esm/src/kernel/auth/credential-source.js +11 -0
- package/esm/src/kernel/auth/crypto.d.ts +51 -0
- package/esm/src/kernel/auth/crypto.js +161 -0
- package/esm/src/kernel/auth/mod.d.ts +5 -0
- package/esm/src/kernel/auth/mod.js +5 -0
- package/esm/src/kernel/auth/oauth.d.ts +17 -0
- package/esm/src/kernel/auth/oauth.js +438 -0
- package/esm/src/kernel/auth/scope-refusal.d.ts +9 -0
- package/esm/src/kernel/auth/scope-refusal.js +8 -0
- package/esm/src/kernel/auth/typed-secret.d.ts +13 -0
- package/esm/src/kernel/auth/typed-secret.js +23 -0
- package/esm/src/kernel/auth/types.d.ts +139 -0
- package/esm/src/kernel/auth/types.js +1 -0
- package/esm/src/kernel/default-scope.d.ts +34 -0
- package/esm/src/kernel/default-scope.js +72 -0
- package/esm/src/kernel/engine/compaction.d.ts +70 -0
- package/esm/src/kernel/engine/compaction.js +202 -0
- package/esm/src/kernel/engine/decision.d.ts +41 -0
- package/esm/src/kernel/engine/decision.js +412 -0
- package/esm/src/kernel/engine/hash.d.ts +6 -0
- package/esm/src/kernel/engine/hash.js +22 -0
- package/esm/src/kernel/engine/live-inbound.d.ts +9 -0
- package/esm/src/kernel/engine/live-inbound.js +19 -0
- package/esm/src/kernel/engine/live-ingress.d.ts +9 -0
- package/esm/src/kernel/engine/live-ingress.js +37 -0
- package/esm/src/kernel/engine/media-probe/audio.d.ts +7 -0
- package/esm/src/kernel/engine/media-probe/audio.js +342 -0
- package/esm/src/kernel/engine/media-probe/bytes.d.ts +6 -0
- package/esm/src/kernel/engine/media-probe/bytes.js +26 -0
- package/esm/src/kernel/engine/media-probe/image.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/image.js +171 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.d.ts +19 -0
- package/esm/src/kernel/engine/media-probe/iso-bmff.js +48 -0
- package/esm/src/kernel/engine/media-probe/matroska.d.ts +35 -0
- package/esm/src/kernel/engine/media-probe/matroska.js +226 -0
- package/esm/src/kernel/engine/media-probe/mp4.d.ts +22 -0
- package/esm/src/kernel/engine/media-probe/mp4.js +279 -0
- package/esm/src/kernel/engine/media-probe/opus.d.ts +4 -0
- package/esm/src/kernel/engine/media-probe/opus.js +23 -0
- package/esm/src/kernel/engine/media-probe/pdf.d.ts +5 -0
- package/esm/src/kernel/engine/media-probe/pdf.js +117 -0
- package/esm/src/kernel/engine/media-probe/video.d.ts +15 -0
- package/esm/src/kernel/engine/media-probe/video.js +49 -0
- package/esm/src/kernel/engine/record.d.ts +3 -0
- package/esm/src/kernel/engine/record.js +11 -0
- package/esm/src/kernel/engine/repair.d.ts +7 -0
- package/esm/src/kernel/engine/repair.js +36 -0
- package/esm/src/kernel/engine/runner/gates.d.ts +5 -0
- package/esm/src/kernel/engine/runner/gates.js +322 -0
- package/esm/src/kernel/engine/runner/mod.d.ts +15 -0
- package/esm/src/kernel/engine/runner/mod.js +574 -0
- package/esm/src/kernel/engine/runner/schema-validation.d.ts +14 -0
- package/esm/src/kernel/engine/runner/schema-validation.js +105 -0
- package/esm/src/kernel/engine/runner/stages.d.ts +28 -0
- package/esm/src/kernel/engine/runner/stages.js +48 -0
- package/esm/src/kernel/engine/runner/state.d.ts +76 -0
- package/esm/src/kernel/engine/runner/state.js +40 -0
- package/esm/src/kernel/engine/runner/steps.d.ts +14 -0
- package/esm/src/kernel/engine/runner/steps.js +360 -0
- package/esm/src/kernel/engine/runner/stream.d.ts +40 -0
- package/esm/src/kernel/engine/runner/stream.js +225 -0
- package/esm/src/kernel/engine/runner/usage.d.ts +45 -0
- package/esm/src/kernel/engine/runner/usage.js +150 -0
- package/esm/src/kernel/engine/session/mod.d.ts +31 -0
- package/esm/src/kernel/engine/session/mod.js +951 -0
- package/esm/src/kernel/engine/session/session-trace.d.ts +115 -0
- package/esm/src/kernel/engine/session/session-trace.js +489 -0
- package/esm/src/kernel/engine/token-estimate.d.ts +77 -0
- package/esm/src/kernel/engine/token-estimate.js +218 -0
- package/esm/src/kernel/engine/tool-trace.d.ts +58 -0
- package/esm/src/kernel/engine/tool-trace.js +131 -0
- package/esm/src/kernel/engine/tree.d.ts +2 -0
- package/esm/src/kernel/engine/tree.js +17 -0
- package/esm/src/kernel/engine/turn-trace.d.ts +118 -0
- package/esm/src/kernel/engine/turn-trace.js +863 -0
- package/esm/src/kernel/engine/usage.d.ts +30 -0
- package/esm/src/kernel/engine/usage.js +134 -0
- package/esm/src/kernel/interaction-parts.d.ts +10 -0
- package/esm/src/kernel/interaction-parts.js +22 -0
- package/esm/src/kernel/mod.d.ts +47 -0
- package/esm/src/kernel/mod.js +30 -0
- package/esm/src/kernel/profile-graph.d.ts +140 -0
- package/esm/src/kernel/profile-graph.js +151 -0
- package/esm/src/kernel/profile-presence.d.ts +9 -0
- package/esm/src/kernel/profile-presence.js +143 -0
- package/esm/src/kernel/profile-scope.d.ts +36 -0
- package/esm/src/kernel/profile-scope.js +262 -0
- package/esm/src/kernel/registry/attachments.d.ts +35 -0
- package/esm/src/kernel/registry/attachments.js +211 -0
- package/esm/src/kernel/registry/catalog.d.ts +19 -0
- package/esm/src/kernel/registry/catalog.js +78 -0
- package/esm/src/kernel/registry/ingress.d.ts +8 -0
- package/esm/src/kernel/registry/ingress.js +134 -0
- package/esm/src/kernel/registry/kernel-registry.d.ts +12 -0
- package/esm/src/kernel/registry/kernel-registry.js +8 -0
- package/esm/src/kernel/registry/profile-outputs.d.ts +3 -0
- package/esm/src/kernel/registry/profile-outputs.js +7 -0
- package/esm/src/kernel/registry/profiles.d.ts +92 -0
- package/esm/src/kernel/registry/profiles.js +698 -0
- package/esm/src/kernel/registry/provider-request.d.ts +6 -0
- package/esm/src/kernel/registry/provider-request.js +42 -0
- package/esm/src/kernel/registry/resolve.d.ts +14 -0
- package/esm/src/kernel/registry/resolve.js +237 -0
- package/esm/src/kernel/registry/schemas.d.ts +9 -0
- package/esm/src/kernel/registry/schemas.js +25 -0
- package/esm/src/kernel/registry/sole-model.d.ts +2 -0
- package/esm/src/kernel/registry/sole-model.js +4 -0
- package/esm/src/kernel/registry/system-prompt.d.ts +8 -0
- package/esm/src/kernel/registry/system-prompt.js +33 -0
- package/esm/src/kernel/registry/system-role.d.ts +3 -0
- package/esm/src/kernel/registry/system-role.js +9 -0
- package/esm/src/kernel/registry/vault.d.ts +13 -0
- package/esm/src/kernel/registry/vault.js +14 -0
- package/esm/src/kernel/schema.d.ts +172 -0
- package/esm/src/kernel/schema.js +653 -0
- package/esm/src/kernel/scope.d.ts +22 -0
- package/esm/src/kernel/scope.js +25 -0
- package/esm/src/kernel/stages.d.ts +141 -0
- package/esm/src/kernel/stages.js +388 -0
- package/esm/src/kernel/stop.d.ts +93 -0
- package/esm/src/kernel/stop.js +125 -0
- package/esm/src/kernel/system-parts.d.ts +26 -0
- package/esm/src/kernel/system-parts.js +98 -0
- package/esm/src/kernel/tools/activity-label.d.ts +16 -0
- package/esm/src/kernel/tools/activity-label.js +209 -0
- package/esm/src/kernel/tools/events.d.ts +51 -0
- package/esm/src/kernel/tools/events.js +149 -0
- package/esm/src/kernel/tools/execute.d.ts +64 -0
- package/esm/src/kernel/tools/execute.js +801 -0
- package/esm/src/kernel/tools/gate-answer.d.ts +50 -0
- package/esm/src/kernel/tools/gate-answer.js +54 -0
- package/esm/src/kernel/tools/harness.d.ts +16 -0
- package/esm/src/kernel/tools/harness.js +42 -0
- package/esm/src/kernel/tools/invoke.d.ts +10 -0
- package/esm/src/kernel/tools/invoke.js +129 -0
- package/esm/src/kernel/tools/mcp-sessions.d.ts +20 -0
- package/esm/src/kernel/tools/mcp-sessions.js +64 -0
- package/esm/src/kernel/tools/mod.d.ts +9 -0
- package/esm/src/kernel/tools/mod.js +6 -0
- package/esm/src/kernel/tools/model-text.d.ts +11 -0
- package/esm/src/kernel/tools/model-text.js +25 -0
- package/esm/src/kernel/tools/permission.d.ts +6 -0
- package/esm/src/kernel/tools/permission.js +38 -0
- package/esm/src/kernel/tools/project.d.ts +8 -0
- package/esm/src/kernel/tools/project.js +25 -0
- package/esm/src/kernel/tools/registry.d.ts +20 -0
- package/esm/src/kernel/tools/registry.js +84 -0
- package/esm/src/kernel/tools/remote.d.ts +110 -0
- package/esm/src/kernel/tools/remote.js +998 -0
- package/esm/src/kernel/tools/resolve.d.ts +28 -0
- package/esm/src/kernel/tools/resolve.js +259 -0
- package/esm/src/kernel/tools/schema.d.ts +10 -0
- package/esm/src/kernel/tools/schema.js +174 -0
- package/esm/src/kernel/tools/signed-in-fetch.d.ts +18 -0
- package/esm/src/kernel/tools/signed-in-fetch.js +45 -0
- package/esm/src/kernel/tools/stage-run.d.ts +93 -0
- package/esm/src/kernel/tools/stage-run.js +140 -0
- package/esm/src/kernel/tools/types.d.ts +287 -0
- package/esm/src/kernel/tools/types.js +1 -0
- package/esm/src/kernel/turn-events.d.ts +599 -0
- package/esm/src/kernel/turn-events.js +425 -0
- package/esm/src/kernel/types.d.ts +884 -0
- package/esm/src/kernel/types.js +1 -0
- package/esm/src/kernel/util/base64.d.ts +2 -0
- package/esm/src/kernel/util/base64.js +13 -0
- package/esm/src/kernel/util/exact-type.d.ts +31 -0
- package/esm/src/kernel/util/exact-type.js +1 -0
- package/esm/src/kernel/util/find-last.d.ts +3 -0
- package/esm/src/kernel/util/find-last.js +9 -0
- package/esm/src/kernel/util/mime.d.ts +2 -0
- package/esm/src/kernel/util/mime.js +4 -0
- package/esm/src/kernel/util/record.d.ts +1 -0
- package/esm/src/kernel/util/record.js +3 -0
- package/esm/src/observability/destinations.d.ts +9 -0
- package/esm/src/observability/destinations.js +38 -0
- package/esm/src/observability/jsonl.d.ts +18 -0
- package/esm/src/observability/jsonl.js +117 -0
- package/esm/src/observability/mod.d.ts +22 -0
- package/esm/src/observability/mod.js +16 -0
- package/esm/src/observability/openinference.d.ts +11 -0
- package/esm/src/observability/openinference.js +205 -0
- package/esm/src/observability/otlp.d.ts +68 -0
- package/esm/src/observability/otlp.js +98 -0
- package/esm/src/observability/phoenix.d.ts +29 -0
- package/esm/src/observability/phoenix.js +71 -0
- package/esm/src/observability/policy.d.ts +14 -0
- package/esm/src/observability/policy.js +69 -0
- package/esm/src/observability/resolve-policy.d.ts +8 -0
- package/esm/src/observability/resolve-policy.js +58 -0
- package/esm/src/observability/spans.d.ts +16 -0
- package/esm/src/observability/spans.js +56 -0
- package/esm/src/observability/trace-catalog.d.ts +111 -0
- package/esm/src/observability/trace-catalog.js +865 -0
- package/esm/src/observability/trace-record.d.ts +23 -0
- package/esm/src/observability/trace-record.js +223 -0
- package/esm/src/observability/trace-schema.d.ts +54 -0
- package/esm/src/observability/trace-schema.js +59 -0
- package/esm/src/observability/trace-sink.d.ts +13 -0
- package/esm/src/observability/trace-sink.js +3 -0
- package/esm/src/observability/trace-span.d.ts +92 -0
- package/esm/src/observability/trace-span.js +199 -0
- package/esm/src/observability/trace.d.ts +11 -0
- package/esm/src/observability/trace.js +35 -0
- package/esm/src/observability/types.d.ts +85 -0
- package/esm/src/observability/types.js +3 -0
- package/esm/src/presets/google/speech-voices.d.ts +8 -0
- package/esm/src/presets/google/speech-voices.js +38 -0
- package/esm/src/presets/google-limits.d.ts +12 -0
- package/esm/src/presets/google-limits.js +18 -0
- package/esm/src/presets/google.d.ts +104 -0
- package/esm/src/presets/google.js +188 -0
- package/esm/src/presets/mod.d.ts +10 -0
- package/esm/src/presets/mod.js +9 -0
- package/esm/src/presets/openrouter.d.ts +13 -0
- package/esm/src/presets/openrouter.js +13 -0
- package/esm/src/presets/typesafe.d.ts +2 -0
- package/esm/src/presets/typesafe.js +2 -0
- package/esm/src/providers/create-provider.d.ts +21 -0
- package/esm/src/providers/create-provider.js +90 -0
- package/esm/src/providers/decision/usage.d.ts +3 -0
- package/esm/src/providers/decision/usage.js +25 -0
- package/esm/src/providers/google/api-error.d.ts +8 -0
- package/esm/src/providers/google/api-error.js +123 -0
- package/esm/src/providers/google/grounding.d.ts +5 -0
- package/esm/src/providers/google/grounding.js +226 -0
- package/esm/src/providers/google/interactions/framing.d.ts +15 -0
- package/esm/src/providers/google/interactions/framing.js +263 -0
- package/esm/src/providers/google/interactions/mod.d.ts +2 -0
- package/esm/src/providers/google/interactions/mod.js +2 -0
- package/esm/src/providers/google/interactions/steps.d.ts +12 -0
- package/esm/src/providers/google/interactions/steps.js +200 -0
- package/esm/src/providers/google/interactions/stream.d.ts +24 -0
- package/esm/src/providers/google/interactions/stream.js +297 -0
- package/esm/src/providers/google/keys.d.ts +20 -0
- package/esm/src/providers/google/keys.js +87 -0
- package/esm/src/providers/google/live/framing.d.ts +51 -0
- package/esm/src/providers/google/live/framing.js +597 -0
- package/esm/src/providers/google/live/mod.d.ts +7 -0
- package/esm/src/providers/google/live/mod.js +7 -0
- package/esm/src/providers/google/live/openapi-schema.d.ts +1 -0
- package/esm/src/providers/google/live/openapi-schema.js +42 -0
- package/esm/src/providers/google/live/session.d.ts +14 -0
- package/esm/src/providers/google/live/session.js +150 -0
- package/esm/src/providers/google/live/stream.d.ts +51 -0
- package/esm/src/providers/google/live/stream.js +263 -0
- package/esm/src/providers/google/thinking.d.ts +3 -0
- package/esm/src/providers/google/thinking.js +8 -0
- package/esm/src/providers/google/urls.d.ts +6 -0
- package/esm/src/providers/google/urls.js +6 -0
- package/esm/src/providers/google/usage.d.ts +7 -0
- package/esm/src/providers/google/usage.js +49 -0
- package/esm/src/providers/local/local.d.ts +12 -0
- package/esm/src/providers/local/local.js +186 -0
- package/esm/src/providers/local/mod.d.ts +8 -0
- package/esm/src/providers/local/mod.js +8 -0
- package/esm/src/providers/mod.d.ts +11 -0
- package/esm/src/providers/mod.js +7 -0
- package/esm/src/providers/openrouter/cache-control.d.ts +5 -0
- package/esm/src/providers/openrouter/cache-control.js +4 -0
- package/esm/src/providers/openrouter/chat.d.ts +64 -0
- package/esm/src/providers/openrouter/chat.js +490 -0
- package/esm/src/providers/openrouter/image.d.ts +24 -0
- package/esm/src/providers/openrouter/image.js +187 -0
- package/esm/src/providers/openrouter/openai/compat.d.ts +19 -0
- package/esm/src/providers/openrouter/openai/compat.js +162 -0
- package/esm/src/providers/openrouter/openai/image-payload.d.ts +9 -0
- package/esm/src/providers/openrouter/openai/image-payload.js +115 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.d.ts +10 -0
- package/esm/src/providers/openrouter/openai/sdk-messages.js +99 -0
- package/esm/src/providers/openrouter/openai/usage.d.ts +8 -0
- package/esm/src/providers/openrouter/openai/usage.js +56 -0
- package/esm/src/providers/openrouter/resolve-api-key.d.ts +3 -0
- package/esm/src/providers/openrouter/resolve-api-key.js +8 -0
- package/esm/src/providers/openrouter/speech.d.ts +18 -0
- package/esm/src/providers/openrouter/speech.js +109 -0
- package/esm/src/providers/probe.d.ts +5 -0
- package/esm/src/providers/probe.js +15 -0
- package/esm/src/providers/shared/builtin-wire.d.ts +4 -0
- package/esm/src/providers/shared/builtin-wire.js +9 -0
- package/esm/src/providers/shared/pcm.d.ts +14 -0
- package/esm/src/providers/shared/pcm.js +78 -0
- package/esm/src/providers/shared/response-identity.d.ts +11 -0
- package/esm/src/providers/shared/response-identity.js +12 -0
- package/esm/src/providers/shared/sse.d.ts +10 -0
- package/esm/src/providers/shared/sse.js +79 -0
- package/esm/src/providers/shared/structured-output.d.ts +4 -0
- package/esm/src/providers/shared/structured-output.js +11 -0
- package/esm/src/providers/shared/tool-args.d.ts +25 -0
- package/esm/src/providers/shared/tool-args.js +84 -0
- package/esm/src/providers/shared/upstream-tap.d.ts +8 -0
- package/esm/src/providers/shared/upstream-tap.js +85 -0
- package/esm/src/providers/shared/upstream-tape.d.ts +6 -0
- package/esm/src/providers/shared/upstream-tape.js +88 -0
- package/esm/src/providers/shared/vault.d.ts +13 -0
- package/esm/src/providers/shared/vault.js +41 -0
- package/esm/src/providers/types.d.ts +19 -0
- package/esm/src/providers/types.js +1 -0
- package/esm/src/surface/formats.d.ts +28 -0
- package/esm/src/surface/formats.js +139 -0
- package/esm/src/surface/mod.d.ts +14 -0
- package/esm/src/surface/mod.js +10 -0
- package/esm/src/surface/runtime.d.ts +40 -0
- package/esm/src/surface/runtime.js +439 -0
- package/esm/src/surface/tools.d.ts +15 -0
- package/esm/src/surface/tools.js +80 -0
- package/esm/src/surface/types.d.ts +104 -0
- package/esm/src/surface/types.js +4 -0
- package/package.json +108 -4
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `runSuite`: every case, `repeat` times, graded from the trace. Live mode
|
|
3
|
+
* runs the profile now through `runTurn` with the host's provider and grades
|
|
4
|
+
* what the memory sink caught; recorded mode grades records a host already
|
|
5
|
+
* has. Both build the same trials, so the same graders give the same results.
|
|
6
|
+
*
|
|
7
|
+
* Every trial's results become a `theorem.eval.trial` span in the judged
|
|
8
|
+
* trace; the run becomes one `theorem.eval.run` record. Both go to the sink
|
|
9
|
+
* the host names, or nowhere.
|
|
10
|
+
*
|
|
11
|
+
* @module
|
|
12
|
+
*/
|
|
13
|
+
import { errorKind, TheoremError } from '../guardrails/error.js';
|
|
14
|
+
import { getProfile, runTurn } from '../kernel/default-scope.js';
|
|
15
|
+
import { isModelProfile } from '../kernel/registry/resolve.js';
|
|
16
|
+
import { isRecord } from '../kernel/util/record.js';
|
|
17
|
+
import { resolveObservabilityPolicy } from '../observability/resolve-policy.js';
|
|
18
|
+
import { memorySink, writeTrace } from '../observability/trace.js';
|
|
19
|
+
import { attachmentData } from './attachments.js';
|
|
20
|
+
import { modelCalls, spanDurationMs } from './graders/shared.js';
|
|
21
|
+
import { buildRunRecord, startTrialRecord } from './record.js';
|
|
22
|
+
import { buildTrial, groupByTrace, hasTurn } from './trial.js';
|
|
23
|
+
import { caseVerdict, trialOutcome } from './verdict.js';
|
|
24
|
+
/** A judge turn's stamp carries `judge`; the turn it judged does not. */
|
|
25
|
+
function isJudgeStamp(record) {
|
|
26
|
+
const stamp = record.metadata?.eval;
|
|
27
|
+
return isRecord(stamp) && stamp.judge !== undefined;
|
|
28
|
+
}
|
|
29
|
+
function stampOf(record) {
|
|
30
|
+
const stamp = record?.metadata?.eval;
|
|
31
|
+
if (!isRecord(stamp) || stamp.judge !== undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
const { suite, case: caseId, trial } = stamp;
|
|
34
|
+
if (typeof suite !== 'string' || typeof caseId !== 'string' || typeof trial !== 'number') {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
return { suite, case: caseId, trial };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Grade one trial with every grader that applies, all at once; a grader that
|
|
41
|
+
* throws yields `grader_error`. Judge records reach `context.traced` in grader
|
|
42
|
+
* order once every grader is done, so a run writes the same records in the
|
|
43
|
+
* same order whichever judge answered first.
|
|
44
|
+
*/
|
|
45
|
+
async function gradeTrial(graders, trial, context) {
|
|
46
|
+
const applicable = trial.case ? graders : graders.filter((grader) => !grader.needsExpect);
|
|
47
|
+
const graded = await Promise.all(applicable.map(async (grader) => {
|
|
48
|
+
const records = [];
|
|
49
|
+
const own = {
|
|
50
|
+
...context,
|
|
51
|
+
traced: (traced) => {
|
|
52
|
+
records.push(...traced);
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
try {
|
|
56
|
+
return { records, result: await grader.grade(trial, own), graderIdentity: grader.identity };
|
|
57
|
+
}
|
|
58
|
+
catch (thrown) {
|
|
59
|
+
return {
|
|
60
|
+
records,
|
|
61
|
+
result: {
|
|
62
|
+
name: grader.name,
|
|
63
|
+
source: grader.source,
|
|
64
|
+
errorType: 'grader_error',
|
|
65
|
+
explanation: thrown instanceof Error ? thrown.message : String(thrown),
|
|
66
|
+
},
|
|
67
|
+
graderIdentity: grader.identity,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
for (const { records } of graded)
|
|
72
|
+
await context.traced(records);
|
|
73
|
+
return graded.map(({ result, graderIdentity }) => ({ result, graderIdentity }));
|
|
74
|
+
}
|
|
75
|
+
/** Every applicable grader's result as the error that kept the turn from producing a trace. */
|
|
76
|
+
function erroredResults(graders, evalCase, error) {
|
|
77
|
+
const applicable = evalCase ? graders : graders.filter((grader) => !grader.needsExpect);
|
|
78
|
+
return applicable.map((grader) => ({
|
|
79
|
+
name: grader.name,
|
|
80
|
+
source: grader.source,
|
|
81
|
+
errorType: error,
|
|
82
|
+
}));
|
|
83
|
+
}
|
|
84
|
+
/** The record's root: the span no other span in it parents (a judge call's root has the trial span above it). */
|
|
85
|
+
function recordRoot(record) {
|
|
86
|
+
const ids = new Set(record.spans.map((span) => span.spanId));
|
|
87
|
+
return record.spans.find((span) => span.parentSpanId === undefined || !ids.has(span.parentSpanId));
|
|
88
|
+
}
|
|
89
|
+
/** A record's root cost, and whether it is whole: absent or partial, some calls went unpriced. */
|
|
90
|
+
function recordCost(record) {
|
|
91
|
+
const attributes = recordRoot(record)?.attributes;
|
|
92
|
+
const cost = attributes?.['theorem.usage.cost_usd'];
|
|
93
|
+
if (typeof cost !== 'number')
|
|
94
|
+
return { whole: false };
|
|
95
|
+
return { usd: cost, whole: attributes?.['theorem.usage.cost_partial'] !== true };
|
|
96
|
+
}
|
|
97
|
+
/** The profile a record ran on (`gen_ai.agent.name` on its root). */
|
|
98
|
+
function recordAgent(record) {
|
|
99
|
+
const agent = recordRoot(record)?.attributes['gen_ai.agent.name'];
|
|
100
|
+
return typeof agent === 'string' ? agent : undefined;
|
|
101
|
+
}
|
|
102
|
+
/** Build, grade and write one trial from the records of one trace. */
|
|
103
|
+
async function gradeRecords(grading, evalCase, index, records) {
|
|
104
|
+
const trial = buildTrial({ suite: grading.suite.suite.id, case: evalCase, index, records });
|
|
105
|
+
const trialRecord = startTrialRecord({
|
|
106
|
+
trial,
|
|
107
|
+
policy: grading.policy,
|
|
108
|
+
...(grading.clock ? { clock: grading.clock } : {}),
|
|
109
|
+
});
|
|
110
|
+
const usage = trial.usage();
|
|
111
|
+
const judgeRecords = [];
|
|
112
|
+
let judgeCostUsd;
|
|
113
|
+
let unpriced = usage.costUsd === undefined || usage.tokens.cost?.partial ? 1 : 0;
|
|
114
|
+
let priced = usage.costUsd === undefined ? 0 : 1;
|
|
115
|
+
const { judging } = grading;
|
|
116
|
+
const context = {
|
|
117
|
+
...(judging.suiteJudge ? { judge: judging.suiteJudge } : {}),
|
|
118
|
+
...(judging.provider ? { judgeProvider: judging.provider } : {}),
|
|
119
|
+
...(judging.decision ? { judgeDecision: judging.decision } : {}),
|
|
120
|
+
...(judging.media ? { media: judging.media } : {}),
|
|
121
|
+
traceparent: trialRecord.traceparent,
|
|
122
|
+
traced: async (traced) => {
|
|
123
|
+
for (const record of traced) {
|
|
124
|
+
judgeRecords.push(record);
|
|
125
|
+
const cost = recordCost(record);
|
|
126
|
+
if (cost.usd !== undefined) {
|
|
127
|
+
judgeCostUsd = (judgeCostUsd ?? 0) + cost.usd;
|
|
128
|
+
priced += 1;
|
|
129
|
+
}
|
|
130
|
+
if (!cost.whole)
|
|
131
|
+
unpriced += 1;
|
|
132
|
+
const policy = judging.policies.get(recordAgent(record) ?? '');
|
|
133
|
+
if (grading.sink && policy)
|
|
134
|
+
await writeTrace(grading.sink, Promise.resolve(record), policy);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
...(grading.signal ? { signal: grading.signal } : {}),
|
|
138
|
+
};
|
|
139
|
+
const graded = await gradeTrial(grading.suite.suite.graders, trial, context);
|
|
140
|
+
const results = graded.map((entry) => entry.result);
|
|
141
|
+
const built = await trialRecord.finish(graded);
|
|
142
|
+
grading.trialSpans.push(built.span);
|
|
143
|
+
if (grading.sink)
|
|
144
|
+
await writeTrace(grading.sink, Promise.resolve(built.record), grading.policy);
|
|
145
|
+
const { costUsd } = usage;
|
|
146
|
+
return {
|
|
147
|
+
...(evalCase ? { case: evalCase } : {}),
|
|
148
|
+
index,
|
|
149
|
+
outcome: trialOutcome(results),
|
|
150
|
+
results,
|
|
151
|
+
traceId: trial.root.traceId,
|
|
152
|
+
turn: {
|
|
153
|
+
durationMs: spanDurationMs(trial.top),
|
|
154
|
+
modelCalls: modelCalls(trial).length,
|
|
155
|
+
toolCalls: trial.spans('execute_tool').length,
|
|
156
|
+
...(typeof trial.root.attributes['theorem.stop.kind'] === 'string'
|
|
157
|
+
? { stop: trial.root.attributes['theorem.stop.kind'] }
|
|
158
|
+
: {}),
|
|
159
|
+
},
|
|
160
|
+
records,
|
|
161
|
+
...(costUsd === undefined ? {} : { costUsd }),
|
|
162
|
+
...(judgeCostUsd === undefined ? {} : { judgeCostUsd }),
|
|
163
|
+
unpriced,
|
|
164
|
+
priced,
|
|
165
|
+
judgeRecords,
|
|
166
|
+
trialRecord: built.record,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
async function turnRequest(suite, evalCase, index) {
|
|
170
|
+
if ('session' in evalCase.input) {
|
|
171
|
+
throw new TheoremError('config', `case ${evalCase.id} is a session script; suite ${suite.suite.id} runs turns`);
|
|
172
|
+
}
|
|
173
|
+
const stamp = { suite: suite.suite.id, case: evalCase.id, trial: index };
|
|
174
|
+
return {
|
|
175
|
+
profile: suite.suite.profile,
|
|
176
|
+
input: {
|
|
177
|
+
...(evalCase.input.text === undefined ? {} : { text: evalCase.input.text }),
|
|
178
|
+
...(evalCase.input.attachments
|
|
179
|
+
? {
|
|
180
|
+
attachments: await Promise.all(evalCase.input.attachments.map(async (attachment) => ({
|
|
181
|
+
mimeType: attachment.mimeType,
|
|
182
|
+
data: await attachmentData(attachment),
|
|
183
|
+
...(attachment.name === undefined ? {} : { name: attachment.name }),
|
|
184
|
+
}))),
|
|
185
|
+
}
|
|
186
|
+
: {}),
|
|
187
|
+
},
|
|
188
|
+
metadata: { eval: stamp },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/** Run one turn live; its records are what the memory sink caught. */
|
|
192
|
+
async function runLiveTrial(grading, provider, evalCase, index, signal) {
|
|
193
|
+
const records = [];
|
|
194
|
+
let thrown;
|
|
195
|
+
try {
|
|
196
|
+
const request = {
|
|
197
|
+
...(await turnRequest(grading.suite, evalCase, index)),
|
|
198
|
+
...(signal ? { signal } : {}),
|
|
199
|
+
};
|
|
200
|
+
for await (const _event of runTurn(request, provider, memorySink(records))) {
|
|
201
|
+
// The trace is the record of the turn; events are not graded.
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
thrown = error;
|
|
206
|
+
}
|
|
207
|
+
if (records.length > 0) {
|
|
208
|
+
// The turn's own records go to the host's sink too: a label points at a transcript someone can read.
|
|
209
|
+
if (grading.sink) {
|
|
210
|
+
for (const record of records) {
|
|
211
|
+
await writeTrace(grading.sink, Promise.resolve(record), grading.policy);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return gradeRecords(grading, evalCase, index, records);
|
|
215
|
+
}
|
|
216
|
+
const error = thrown === undefined ? 'internal' : errorKind(thrown);
|
|
217
|
+
const results = erroredResults(grading.suite.suite.graders, evalCase, error);
|
|
218
|
+
return {
|
|
219
|
+
case: evalCase,
|
|
220
|
+
index,
|
|
221
|
+
outcome: trialOutcome(results),
|
|
222
|
+
results,
|
|
223
|
+
records,
|
|
224
|
+
unpriced: 0,
|
|
225
|
+
priced: 0,
|
|
226
|
+
judgeRecords: [],
|
|
227
|
+
error,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* What the suite's model graders judge with. Each grader names its judge
|
|
232
|
+
* profile (its own, else the suite's); a text judge needs a provider (the
|
|
233
|
+
* option, else the suite's `judgeProvider` export, else the agent's), a
|
|
234
|
+
* decision judge a key (the option, else the suite's `judgeDecision` export).
|
|
235
|
+
*/
|
|
236
|
+
function judgingOf(loaded, options) {
|
|
237
|
+
const { suite } = loaded;
|
|
238
|
+
const provider = options.judgeProvider ?? loaded.judgeProvider ?? options.provider;
|
|
239
|
+
const decision = options.judgeDecision ?? loaded.judgeDecision;
|
|
240
|
+
const media = options.media ?? loaded.media;
|
|
241
|
+
const policies = new Map();
|
|
242
|
+
for (const grader of suite.graders) {
|
|
243
|
+
for (const id of grader.judgeProfiles?.(suite.judge?.profile) ?? []) {
|
|
244
|
+
const profile = getProfile(id);
|
|
245
|
+
if (profile.type === 'decision' && !decision) {
|
|
246
|
+
throw new TheoremError('config', `suite ${suite.id}: grader ${grader.name} needs a key for decision judge profile ${id}; export judgeDecision`);
|
|
247
|
+
}
|
|
248
|
+
if (profile.type !== 'decision' && !provider) {
|
|
249
|
+
throw new TheoremError('config', `suite ${suite.id}: grader ${grader.name} needs a provider for judge profile ${id}`);
|
|
250
|
+
}
|
|
251
|
+
policies.set(id, resolveObservabilityPolicy(profile.observability));
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return {
|
|
255
|
+
...(suite.judge ? { suiteJudge: suite.judge.profile } : {}),
|
|
256
|
+
...(provider ? { provider } : {}),
|
|
257
|
+
...(decision ? { decision } : {}),
|
|
258
|
+
...(media ? { media } : {}),
|
|
259
|
+
policies,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function checkSuite(loaded, options) {
|
|
263
|
+
const { suite } = loaded;
|
|
264
|
+
const profile = getProfile(suite.profile);
|
|
265
|
+
if (!isModelProfile(profile)) {
|
|
266
|
+
throw new TheoremError('config', `suite ${suite.id}: profile ${suite.profile} runs no model turn`); // lexicon-exempt: developer contract error
|
|
267
|
+
}
|
|
268
|
+
if (suite.mode === 'session') {
|
|
269
|
+
throw new TheoremError('config', `suite ${suite.id}: session suites are not run yet`); // lexicon-exempt: developer contract error
|
|
270
|
+
}
|
|
271
|
+
if (profile.type === 'live') {
|
|
272
|
+
throw new TheoremError('config', `suite ${suite.id}: a live profile needs mode 'session'`); // lexicon-exempt: developer contract error
|
|
273
|
+
}
|
|
274
|
+
if (!options.recorded && !options.provider) {
|
|
275
|
+
throw new TheoremError('config', `suite ${suite.id}: live mode needs a provider`); // lexicon-exempt: developer contract error
|
|
276
|
+
}
|
|
277
|
+
if (suite.graders.length === 0) {
|
|
278
|
+
throw new TheoremError('config', `suite ${suite.id}: no graders`); // lexicon-exempt: developer contract error
|
|
279
|
+
}
|
|
280
|
+
const warnings = [];
|
|
281
|
+
const repeat = options.repeat ?? suite.trials.repeat;
|
|
282
|
+
if (repeat === 1) {
|
|
283
|
+
warnings.push('one trial per case cannot tell noise from change; set trials.repeat to 3 or more');
|
|
284
|
+
}
|
|
285
|
+
return warnings;
|
|
286
|
+
}
|
|
287
|
+
/** A trial's whole cost: the agent's turn and its judge turns. */
|
|
288
|
+
function reportCost(report) {
|
|
289
|
+
return (report.costUsd ?? 0) + (report.judgeCostUsd ?? 0);
|
|
290
|
+
}
|
|
291
|
+
function summedCost(reports) {
|
|
292
|
+
return reports.reduce((sum, report) => sum + reportCost(report), 0);
|
|
293
|
+
}
|
|
294
|
+
function summedCalls(reports, key) {
|
|
295
|
+
return reports.reduce((sum, report) => sum + report[key], 0);
|
|
296
|
+
}
|
|
297
|
+
/** Recorded mode: each trace's records become one trial, matched to a case by its eval stamp. */
|
|
298
|
+
async function gradeRecorded(grading, records) {
|
|
299
|
+
const byCase = new Map();
|
|
300
|
+
const caseless = [];
|
|
301
|
+
const cases = new Map(grading.suite.cases.map((evalCase) => [evalCase.id, evalCase]));
|
|
302
|
+
const skipped = { judge: 0, other: 0 };
|
|
303
|
+
for (const [, group] of groupByTrace(records)) {
|
|
304
|
+
// A directory of eval traces holds judge calls (under their trial) and run records beside the turns; only turns are trials.
|
|
305
|
+
const traceRecords = group.filter((record) => !isJudgeStamp(record));
|
|
306
|
+
skipped.judge += group.length - traceRecords.length;
|
|
307
|
+
if (traceRecords.length === 0)
|
|
308
|
+
continue;
|
|
309
|
+
if (!hasTurn(traceRecords)) {
|
|
310
|
+
skipped.other += 1;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const stamp = traceRecords
|
|
314
|
+
.map(stampOf)
|
|
315
|
+
.find((found) => found?.suite === grading.suite.suite.id);
|
|
316
|
+
const evalCase = stamp ? cases.get(stamp.case) : undefined;
|
|
317
|
+
if (!evalCase) {
|
|
318
|
+
caseless.push(await gradeRecords(grading, undefined, caseless.length, traceRecords));
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
const index = stamp?.trial ?? 0;
|
|
322
|
+
const report = await gradeRecords(grading, evalCase, index, traceRecords);
|
|
323
|
+
byCase.set(evalCase.id, [...(byCase.get(evalCase.id) ?? []), report]);
|
|
324
|
+
}
|
|
325
|
+
const reports = [...byCase.values(), caseless].flat();
|
|
326
|
+
return {
|
|
327
|
+
byCase,
|
|
328
|
+
caseless,
|
|
329
|
+
costUsd: summedCost(reports),
|
|
330
|
+
unpriced: summedCalls(reports, 'unpriced'),
|
|
331
|
+
priced: summedCalls(reports, 'priced'),
|
|
332
|
+
skipped,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Live mode: every case, `repeat` times, started in suite order with up to
|
|
337
|
+
* `concurrency` in flight, until the cost ceiling. The ceiling is checked
|
|
338
|
+
* before each start, so a stop lets what is in flight finish and count.
|
|
339
|
+
*/
|
|
340
|
+
async function runLive(grading, provider, repeat, options) {
|
|
341
|
+
const jobs = grading.suite.cases.flatMap((evalCase) => Array.from({ length: repeat }, (_, index) => ({ evalCase, index })));
|
|
342
|
+
const reports = new Map(grading.suite.cases.map((evalCase) => [evalCase.id, []]));
|
|
343
|
+
let next = 0;
|
|
344
|
+
let costUsd = 0;
|
|
345
|
+
let stopped;
|
|
346
|
+
const worker = async () => {
|
|
347
|
+
while (next < jobs.length) {
|
|
348
|
+
if (options.maxCostUsd !== undefined && costUsd > options.maxCostUsd) {
|
|
349
|
+
stopped = 'budget';
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const job = jobs[next++];
|
|
353
|
+
if (!job)
|
|
354
|
+
return;
|
|
355
|
+
const report = await runLiveTrial(grading, provider, job.evalCase, job.index, options.signal);
|
|
356
|
+
costUsd += reportCost(report);
|
|
357
|
+
reports.get(job.evalCase.id)?.push(report);
|
|
358
|
+
options.onTrial?.(report);
|
|
359
|
+
}
|
|
360
|
+
};
|
|
361
|
+
const workers = Math.max(1, Math.min(options.concurrency ?? 1, jobs.length));
|
|
362
|
+
await Promise.all(Array.from({ length: workers }, worker));
|
|
363
|
+
const byCase = new Map();
|
|
364
|
+
for (const [id, list] of reports) {
|
|
365
|
+
byCase.set(id, [...list].sort((a, b) => a.index - b.index));
|
|
366
|
+
}
|
|
367
|
+
const all = [...byCase.values()].flat();
|
|
368
|
+
return {
|
|
369
|
+
byCase,
|
|
370
|
+
caseless: [],
|
|
371
|
+
...(stopped ? { stopped } : {}),
|
|
372
|
+
costUsd,
|
|
373
|
+
unpriced: summedCalls(all, 'unpriced'),
|
|
374
|
+
priced: summedCalls(all, 'priced'),
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
async function ranOf(grading, repeat, options) {
|
|
378
|
+
if (options.recorded !== undefined) {
|
|
379
|
+
const ran = await gradeRecorded(grading, options.recorded);
|
|
380
|
+
for (const report of [...ran.byCase.values(), ran.caseless].flat())
|
|
381
|
+
options.onTrial?.(report);
|
|
382
|
+
return ran;
|
|
383
|
+
}
|
|
384
|
+
if (!options.provider) {
|
|
385
|
+
throw new TheoremError('config', `suite ${grading.suite.suite.id}: live mode needs a provider`); // lexicon-exempt: developer contract error
|
|
386
|
+
}
|
|
387
|
+
return runLive(grading, options.provider, repeat, options);
|
|
388
|
+
}
|
|
389
|
+
/** Run a loaded suite live or over records, write its trial and run records, and report every verdict. */
|
|
390
|
+
async function runSuite(loaded, options = {}) {
|
|
391
|
+
const warnings = checkSuite(loaded, options);
|
|
392
|
+
const { suite } = loaded;
|
|
393
|
+
const repeat = options.repeat ?? suite.trials.repeat;
|
|
394
|
+
const profile = getProfile(suite.profile);
|
|
395
|
+
const policy = resolveObservabilityPolicy(isModelProfile(profile) ? profile.observability : undefined);
|
|
396
|
+
const grading = {
|
|
397
|
+
suite: loaded,
|
|
398
|
+
policy,
|
|
399
|
+
judging: judgingOf(loaded, options),
|
|
400
|
+
...(options.sink ? { sink: options.sink } : {}),
|
|
401
|
+
...(options.clock ? { clock: options.clock } : {}),
|
|
402
|
+
trialSpans: [],
|
|
403
|
+
...(options.signal ? { signal: options.signal } : {}),
|
|
404
|
+
};
|
|
405
|
+
const ran = await ranOf(grading, repeat, options);
|
|
406
|
+
if (ran.skipped && ran.skipped.judge + ran.skipped.other > 0) {
|
|
407
|
+
warnings.push(`skipped ${ran.skipped.judge} judge call record(s) and ${ran.skipped.other} record(s) with no turn; they are not trials`);
|
|
408
|
+
}
|
|
409
|
+
if (options.maxCostUsd !== undefined && ran.unpriced > 0) {
|
|
410
|
+
warnings.push(`maxCostUsd counts only the costs providers report; ${ran.unpriced} call(s) reported none or only part, so the ceiling could not hold them`);
|
|
411
|
+
}
|
|
412
|
+
const rule = suite.trials.pass ?? 'all';
|
|
413
|
+
const verdicts = loaded.cases.map((evalCase) => caseVerdict(evalCase, (ran.byCase.get(evalCase.id) ?? []).map((report) => report.results), rule));
|
|
414
|
+
const decided = verdicts.filter((verdict) => verdict.decided);
|
|
415
|
+
const undecided = verdicts.length - decided.length;
|
|
416
|
+
if (undecided > 0) {
|
|
417
|
+
warnings.push(`${undecided} case(s) undecided: too few of their trials escaped error to apply the pass rule, so no pass rate counts them`);
|
|
418
|
+
}
|
|
419
|
+
const run = await buildRunRecord({
|
|
420
|
+
suite: {
|
|
421
|
+
id: suite.id,
|
|
422
|
+
trials: { repeat, ...(suite.trials.pass ? { pass: suite.trials.pass } : {}) },
|
|
423
|
+
},
|
|
424
|
+
verdicts,
|
|
425
|
+
trialSpans: grading.trialSpans,
|
|
426
|
+
policy,
|
|
427
|
+
...(options.clock ? { clock: options.clock } : {}),
|
|
428
|
+
...(ran.caseless.length > 0 ? { caseless: true } : {}),
|
|
429
|
+
...(ran.stopped ? { stopped: ran.stopped } : {}),
|
|
430
|
+
...(options.revision ? { revision: options.revision } : {}),
|
|
431
|
+
});
|
|
432
|
+
if (options.sink)
|
|
433
|
+
await writeTrace(options.sink, Promise.resolve(run), policy);
|
|
434
|
+
const trials = [...ran.byCase.values()].flat();
|
|
435
|
+
return {
|
|
436
|
+
suite: suite.id,
|
|
437
|
+
mode: options.recorded !== undefined ? 'recorded' : 'live',
|
|
438
|
+
repeat,
|
|
439
|
+
passRule: rule,
|
|
440
|
+
verdicts,
|
|
441
|
+
trials,
|
|
442
|
+
caseless: ran.caseless,
|
|
443
|
+
passed: ran.stopped === undefined && decided.length > 0 && decided.every((verdict) => verdict.passed),
|
|
444
|
+
...(ran.stopped ? { stopped: ran.stopped } : {}),
|
|
445
|
+
costUsd: ran.costUsd,
|
|
446
|
+
unpriced: ran.unpriced,
|
|
447
|
+
priced: ran.priced,
|
|
448
|
+
warnings,
|
|
449
|
+
run,
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
export { runSuite };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { RunDecisionOptions } from '../kernel/engine/decision.js';
|
|
3
|
+
import type { ModelProvider } from '../kernel/types.js';
|
|
4
|
+
import { type TraceRecord } from '../observability/trace-schema.js';
|
|
5
|
+
import { type EvalCase, type EvalMediaResolver, type EvalSuite } from './types.js';
|
|
6
|
+
interface LoadedSuite {
|
|
7
|
+
suite: EvalSuite;
|
|
8
|
+
cases: EvalCase[];
|
|
9
|
+
provider?: ModelProvider;
|
|
10
|
+
judgeProvider?: ModelProvider;
|
|
11
|
+
judgeDecision?: Omit<RunDecisionOptions, 'sink'>;
|
|
12
|
+
media?: EvalMediaResolver;
|
|
13
|
+
path: string;
|
|
14
|
+
}
|
|
15
|
+
declare function readJsonl<T>(path: string, schema: z.ZodType<T>, what: string): Promise<T[]>;
|
|
16
|
+
declare function readTraceRecords(path: string): Promise<TraceRecord[]>;
|
|
17
|
+
declare function loadSuite(modulePath: string): Promise<LoadedSuite>;
|
|
18
|
+
export type { LoadedSuite };
|
|
19
|
+
export { loadSuite, readJsonl, readTraceRecords };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { cwd } from 'node:process';
|
|
3
|
+
import { TheoremError } from '../guardrails/error.js';
|
|
4
|
+
import { isRecord } from '../kernel/util/record.js';
|
|
5
|
+
import { traceRecordSchema } from '../observability/trace-schema.js';
|
|
6
|
+
import { pinCaseFiles } from './attachments.js';
|
|
7
|
+
import { evalCaseSchema, evalSuiteSchema, } from './types.js';
|
|
8
|
+
function isProvider(value) {
|
|
9
|
+
return isRecord(value) && typeof value.complete === 'function';
|
|
10
|
+
}
|
|
11
|
+
function isDecisionKey(value) {
|
|
12
|
+
return isRecord(value) && isRecord(value.vault);
|
|
13
|
+
}
|
|
14
|
+
function absolute(path) {
|
|
15
|
+
return path.startsWith('/') ? path : `${cwd()}/${path}`;
|
|
16
|
+
}
|
|
17
|
+
function siblingOf(modulePath, relative) {
|
|
18
|
+
const dir = modulePath.slice(0, modulePath.lastIndexOf('/'));
|
|
19
|
+
return relative.startsWith('/') ? relative : `${dir}/${relative}`;
|
|
20
|
+
}
|
|
21
|
+
async function readJsonl(path, schema, what) {
|
|
22
|
+
const text = await readFile(path, 'utf8');
|
|
23
|
+
const out = [];
|
|
24
|
+
const lines = text.split('\n');
|
|
25
|
+
for (const [index, line] of lines.entries()) {
|
|
26
|
+
if (line.trim() === '')
|
|
27
|
+
continue;
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = JSON.parse(line);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new TheoremError('config', `${path}:${index + 1}: ${what} is not JSON`); // lexicon-exempt: developer contract error
|
|
34
|
+
}
|
|
35
|
+
const result = schema.safeParse(parsed);
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
const issue = result.error.issues[0];
|
|
38
|
+
const at = issue?.path.join('.') || '(root)';
|
|
39
|
+
throw new TheoremError('config', `${path}:${index + 1}: ${what} ${at}: ${issue?.message ?? 'invalid'}`);
|
|
40
|
+
}
|
|
41
|
+
out.push(result.data);
|
|
42
|
+
}
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
async function readTraceRecords(path) {
|
|
46
|
+
const target = absolute(path);
|
|
47
|
+
const info = await stat(target);
|
|
48
|
+
if (!info.isDirectory())
|
|
49
|
+
return readJsonl(target, traceRecordSchema, 'trace record');
|
|
50
|
+
const files = [];
|
|
51
|
+
for (const entry of await readdir(target, { withFileTypes: true })) {
|
|
52
|
+
if (entry.isFile() && entry.name.endsWith('.jsonl'))
|
|
53
|
+
files.push(`${target}/${entry.name}`);
|
|
54
|
+
}
|
|
55
|
+
files.sort();
|
|
56
|
+
const records = [];
|
|
57
|
+
for (const file of files)
|
|
58
|
+
records.push(...(await readJsonl(file, traceRecordSchema, 'trace record')));
|
|
59
|
+
return records;
|
|
60
|
+
}
|
|
61
|
+
async function loadSuite(modulePath) {
|
|
62
|
+
const path = absolute(modulePath);
|
|
63
|
+
const module = await import(new URL(`file://${path}`).href);
|
|
64
|
+
if (!isRecord(module)) {
|
|
65
|
+
throw new TheoremError('config', `${modulePath}: not a module`); // lexicon-exempt: developer contract error
|
|
66
|
+
}
|
|
67
|
+
const parsed = evalSuiteSchema.safeParse(module.default);
|
|
68
|
+
if (!parsed.success) {
|
|
69
|
+
const issue = parsed.error.issues[0];
|
|
70
|
+
throw new TheoremError('config', `${modulePath}: default export is not an EvalSuite (${issue?.path.join('.') || 'root'}: ${issue?.message ?? 'invalid'})`);
|
|
71
|
+
}
|
|
72
|
+
const suite = parsed.data;
|
|
73
|
+
const casesPath = siblingOf(path, suite.cases);
|
|
74
|
+
const cases = await readJsonl(casesPath, evalCaseSchema, 'case');
|
|
75
|
+
const ids = new Set();
|
|
76
|
+
for (const evalCase of cases) {
|
|
77
|
+
if (ids.has(evalCase.id)) {
|
|
78
|
+
throw new TheoremError('config', `${suite.cases}: case id ${evalCase.id} appears twice`); // lexicon-exempt: developer contract error
|
|
79
|
+
}
|
|
80
|
+
ids.add(evalCase.id);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
suite,
|
|
84
|
+
cases: await pinCaseFiles(cases, casesPath),
|
|
85
|
+
path,
|
|
86
|
+
...(isProvider(module.provider) ? { provider: module.provider } : {}),
|
|
87
|
+
...(isProvider(module.judgeProvider) ? { judgeProvider: module.judgeProvider } : {}),
|
|
88
|
+
...(isDecisionKey(module.judgeDecision) ? { judgeDecision: module.judgeDecision } : {}),
|
|
89
|
+
...(typeof module.media === 'function' ? { media: module.media } : {}),
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export { loadSuite, readJsonl, readTraceRecords };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type GroupSummary } from './breakdown.js';
|
|
2
|
+
import type { SuiteRun, TurnShape } from './run.js';
|
|
3
|
+
import type { EvalPassRule, EvalResult } from './types.js';
|
|
4
|
+
import type { CaseVerdict, TrialOutcome } from './verdict.js';
|
|
5
|
+
interface TrialSummary {
|
|
6
|
+
case?: string;
|
|
7
|
+
index: number;
|
|
8
|
+
outcome: TrialOutcome;
|
|
9
|
+
traceId?: string;
|
|
10
|
+
turn?: TurnShape;
|
|
11
|
+
error?: string;
|
|
12
|
+
results: EvalResult[];
|
|
13
|
+
}
|
|
14
|
+
interface RunSummary {
|
|
15
|
+
suite: string;
|
|
16
|
+
mode: 'live' | 'recorded';
|
|
17
|
+
repeat: number;
|
|
18
|
+
passRule: EvalPassRule;
|
|
19
|
+
passed: boolean;
|
|
20
|
+
stopped?: 'budget';
|
|
21
|
+
costUsd: number;
|
|
22
|
+
unpriced: number;
|
|
23
|
+
priced: number;
|
|
24
|
+
verdicts: CaseVerdict[];
|
|
25
|
+
groups: GroupSummary[];
|
|
26
|
+
trials: TrialSummary[];
|
|
27
|
+
runTraceId?: string;
|
|
28
|
+
warnings: string[];
|
|
29
|
+
}
|
|
30
|
+
declare function summarizeRun(run: SuiteRun): RunSummary;
|
|
31
|
+
export type { RunSummary, TrialSummary };
|
|
32
|
+
export { summarizeRun };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { groupSummaries } from './breakdown.js';
|
|
2
|
+
function summarizeRun(run) {
|
|
3
|
+
const trials = [...run.trials, ...run.caseless].map((report) => ({
|
|
4
|
+
...(report.case ? { case: report.case.id } : {}),
|
|
5
|
+
index: report.index,
|
|
6
|
+
outcome: report.outcome,
|
|
7
|
+
...(report.traceId ? { traceId: report.traceId } : {}),
|
|
8
|
+
...(report.turn ? { turn: report.turn } : {}),
|
|
9
|
+
...(report.error ? { error: report.error } : {}),
|
|
10
|
+
results: report.results,
|
|
11
|
+
}));
|
|
12
|
+
const runTraceId = run.run.spans[0]?.traceId;
|
|
13
|
+
return {
|
|
14
|
+
suite: run.suite,
|
|
15
|
+
mode: run.mode,
|
|
16
|
+
repeat: run.repeat,
|
|
17
|
+
passRule: run.passRule,
|
|
18
|
+
passed: run.passed,
|
|
19
|
+
...(run.stopped ? { stopped: run.stopped } : {}),
|
|
20
|
+
costUsd: run.costUsd,
|
|
21
|
+
unpriced: run.unpriced,
|
|
22
|
+
priced: run.priced,
|
|
23
|
+
verdicts: run.verdicts,
|
|
24
|
+
groups: groupSummaries(run),
|
|
25
|
+
trials,
|
|
26
|
+
...(runTraceId ? { runTraceId } : {}),
|
|
27
|
+
warnings: run.warnings,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export { summarizeRun };
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Records → `Trial`. A live run hands the runner what its memory sink caught;
|
|
3
|
+
* a recorded run hands it what a file held. Both build the same trial, so the
|
|
4
|
+
* same graders give the same results.
|
|
5
|
+
*
|
|
6
|
+
* The root is the `invoke_agent` span with no agent above it in the set; a host
|
|
7
|
+
* span above it (the host's request, when the host nests the turn under its own
|
|
8
|
+
* span) does not hide it, and the topmost span above it is the trial's `top`. It
|
|
9
|
+
* is never assumed to be the first record: a compaction turn's record can be
|
|
10
|
+
* written before its parent's (P9).
|
|
11
|
+
*
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { type TraceRecord } from '../observability/trace-record.js';
|
|
15
|
+
import type { EvalCase, Trial } from './types.js';
|
|
16
|
+
/** Build the trial every grader receives from the records that share one trace. */
|
|
17
|
+
declare function buildTrial(args: {
|
|
18
|
+
suite: string;
|
|
19
|
+
case?: EvalCase;
|
|
20
|
+
index: number;
|
|
21
|
+
records: TraceRecord[];
|
|
22
|
+
}): Trial;
|
|
23
|
+
/** Group records by trace id, in first-seen order. */
|
|
24
|
+
declare function groupByTrace(records: TraceRecord[]): Map<string, TraceRecord[]>;
|
|
25
|
+
/** Whether these records hold a turn at all: an `invoke_agent` span. An eval run record does not. */
|
|
26
|
+
declare function hasTurn(records: readonly TraceRecord[]): boolean;
|
|
27
|
+
export { buildTrial, groupByTrace, hasTurn };
|