modelrig 0.8.1 → 0.10.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/CHANGELOG.md +324 -0
- package/README.md +55 -29
- package/data/PROVENANCE.md +14 -0
- package/data/pricing-map.json +26 -0
- package/dist/adapters/attempt-meta-map.d.ts +8 -1
- package/dist/adapters/attempt-meta-map.d.ts.map +1 -1
- package/dist/adapters/attempt-meta-map.js +4 -0
- package/dist/adapters/build-adapters.js +2 -2
- package/dist/adapters/gemini.d.ts +28 -1
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +38 -9
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +53 -4
- package/dist/adapters/openai-compat.d.ts +8 -2
- package/dist/adapters/openai-compat.d.ts.map +1 -1
- package/dist/adapters/openai-compat.js +8 -1
- package/dist/adapters/openai-stream.d.ts +10 -2
- package/dist/adapters/openai-stream.d.ts.map +1 -1
- package/dist/adapters/openai-stream.js +5 -1
- package/dist/adapters/openai.d.ts +10 -1
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +57 -7
- package/dist/adapters/responses-api.d.ts +61 -0
- package/dist/adapters/responses-api.d.ts.map +1 -0
- package/dist/adapters/responses-api.js +124 -0
- package/dist/artifacts/artifact.d.ts +31 -12
- package/dist/artifacts/artifact.d.ts.map +1 -1
- package/dist/artifacts/artifact.js +218 -188
- package/dist/artifacts/index.d.ts +15 -5
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/index.js +19 -5
- package/dist/artifacts/run-context.d.ts +3 -24
- package/dist/artifacts/run-context.d.ts.map +1 -1
- package/dist/artifacts/run-context.js +3 -39
- package/dist/bakeoff/engine.d.ts +29 -0
- package/dist/bakeoff/engine.d.ts.map +1 -1
- package/dist/bakeoff/engine.js +47 -0
- package/dist/bakeoff/eval-cases-rig.d.ts +36 -0
- package/dist/bakeoff/eval-cases-rig.d.ts.map +1 -0
- package/dist/bakeoff/eval-cases-rig.js +27 -0
- package/dist/bakeoff/eval-cases.d.ts +19 -0
- package/dist/bakeoff/eval-cases.d.ts.map +1 -1
- package/dist/bakeoff/eval-cases.js +18 -1
- package/dist/bakeoff/golden-judge.d.ts +47 -0
- package/dist/bakeoff/golden-judge.d.ts.map +1 -0
- package/dist/bakeoff/golden-judge.js +49 -0
- package/dist/bakeoff/groundedness.d.ts +58 -0
- package/dist/bakeoff/groundedness.d.ts.map +1 -0
- package/dist/bakeoff/groundedness.js +165 -0
- package/dist/bakeoff/quality.d.ts +43 -0
- package/dist/bakeoff/quality.d.ts.map +1 -1
- package/dist/bakeoff/quality.js +31 -0
- package/dist/bakeoff/replay.d.ts +11 -0
- package/dist/bakeoff/replay.d.ts.map +1 -1
- package/dist/bakeoff/replay.js +12 -0
- package/dist/bakeoff/report.d.ts +7 -0
- package/dist/bakeoff/report.d.ts.map +1 -1
- package/dist/bakeoff/report.js +26 -0
- package/dist/cli-judge.d.ts +12 -0
- package/dist/cli-judge.d.ts.map +1 -0
- package/dist/cli-judge.js +48 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +22 -42
- package/dist/config.d.ts +85 -29
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +109 -47
- package/dist/detect/detector.d.ts +4 -2
- package/dist/detect/detector.d.ts.map +1 -1
- package/dist/detect/safe-harbor.d.ts +57 -0
- package/dist/detect/safe-harbor.d.ts.map +1 -0
- package/dist/detect/safe-harbor.js +278 -0
- package/dist/doctor-cli.d.ts +7 -0
- package/dist/doctor-cli.d.ts.map +1 -0
- package/dist/doctor-cli.js +67 -0
- package/dist/doctor-preflight.d.ts +52 -0
- package/dist/doctor-preflight.d.ts.map +1 -0
- package/dist/doctor-preflight.js +112 -0
- package/dist/feedback/coverage.d.ts +11 -8
- package/dist/feedback/coverage.d.ts.map +1 -1
- package/dist/feedback/coverage.js +29 -16
- package/dist/feedback/grade.d.ts +58 -0
- package/dist/feedback/grade.d.ts.map +1 -0
- package/dist/feedback/grade.js +67 -0
- package/dist/gateway/http-protocol.d.ts +20 -1
- package/dist/gateway/http-protocol.d.ts.map +1 -1
- package/dist/gateway/http-protocol.js +1 -1
- package/dist/gateway/serve-client.d.ts +99 -0
- package/dist/gateway/serve-client.d.ts.map +1 -0
- package/dist/gateway/serve-client.js +360 -0
- package/dist/index.d.ts +68 -29
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +167 -46
- package/dist/init/observe-cli.js +1 -1
- package/dist/init/observe.d.ts +2 -2
- package/dist/init/observe.d.ts.map +1 -1
- package/dist/init/observe.js +11 -7
- package/dist/mask/arm.d.ts +112 -0
- package/dist/mask/arm.d.ts.map +1 -0
- package/dist/mask/arm.js +179 -0
- package/dist/mask/index.d.ts +2 -0
- package/dist/mask/index.d.ts.map +1 -1
- package/dist/mask/index.js +7 -1
- package/dist/mask/mask-policy-cli.d.ts +12 -4
- package/dist/mask/mask-policy-cli.d.ts.map +1 -1
- package/dist/mask/mask-policy-cli.js +34 -9
- package/dist/prompts/manifest.d.ts +128 -0
- package/dist/prompts/manifest.d.ts.map +1 -0
- package/dist/prompts/manifest.js +214 -0
- package/dist/prompts/prompt-fetch.d.ts +84 -0
- package/dist/prompts/prompt-fetch.d.ts.map +1 -0
- package/dist/prompts/prompt-fetch.js +120 -0
- package/dist/prompts/prompt-resolve.d.ts +76 -0
- package/dist/prompts/prompt-resolve.d.ts.map +1 -0
- package/dist/prompts/prompt-resolve.js +93 -0
- package/dist/prompts/slot-resolver.d.ts +91 -0
- package/dist/prompts/slot-resolver.d.ts.map +1 -0
- package/dist/prompts/slot-resolver.js +135 -0
- package/dist/prompts/tools-register.d.ts +60 -0
- package/dist/prompts/tools-register.d.ts.map +1 -0
- package/dist/prompts/tools-register.js +48 -0
- package/dist/prompts/version-hash.d.ts +29 -0
- package/dist/prompts/version-hash.d.ts.map +1 -0
- package/dist/prompts/version-hash.js +54 -0
- package/dist/prompts-export-cli.d.ts +21 -0
- package/dist/prompts-export-cli.d.ts.map +1 -0
- package/dist/prompts-export-cli.js +130 -0
- package/dist/query/grammar.d.ts +2 -2
- package/dist/query/grammar.d.ts.map +1 -1
- package/dist/query/grammar.js +3 -1
- package/dist/query/saved.d.ts +13 -0
- package/dist/query/saved.d.ts.map +1 -1
- package/dist/query/saved.js +67 -1
- package/dist/receipts/types.d.ts +1 -1
- package/dist/receipts/types.d.ts.map +1 -1
- package/dist/receipts/types.js +1 -0
- package/dist/registry/build.d.ts +43 -1
- package/dist/registry/build.d.ts.map +1 -1
- package/dist/registry/build.js +52 -0
- package/dist/registry/cache-policy.d.ts.map +1 -1
- package/dist/registry/cache-policy.js +22 -0
- package/dist/registry/pricing-shape.d.ts +67 -8
- package/dist/registry/pricing-shape.d.ts.map +1 -1
- package/dist/registry/pricing-shape.js +50 -13
- package/dist/registry/pricing.d.ts +6 -5
- package/dist/registry/pricing.d.ts.map +1 -1
- package/dist/registry/pricing.js +9 -5
- package/dist/registry/rows.d.ts.map +1 -1
- package/dist/registry/rows.js +1 -0
- package/dist/registry/select.d.ts +6 -1
- package/dist/registry/select.d.ts.map +1 -1
- package/dist/registry/select.js +11 -0
- package/dist/routes/call-config.d.ts +199 -0
- package/dist/routes/call-config.d.ts.map +1 -0
- package/dist/routes/call-config.js +343 -0
- package/dist/routes/destination-loader.d.ts +16 -0
- package/dist/routes/destination-loader.d.ts.map +1 -0
- package/dist/routes/destination-loader.js +29 -0
- package/dist/routes/draft.d.ts +7 -0
- package/dist/routes/draft.d.ts.map +1 -1
- package/dist/routes/draft.js +12 -0
- package/dist/routes/loader.d.ts.map +1 -1
- package/dist/routes/loader.js +31 -56
- package/dist/routes/objective-loader.d.ts +12 -0
- package/dist/routes/objective-loader.d.ts.map +1 -1
- package/dist/routes/objective-loader.js +82 -0
- package/dist/routes/output-loader.d.ts +42 -0
- package/dist/routes/output-loader.d.ts.map +1 -0
- package/dist/routes/output-loader.js +112 -0
- package/dist/routes/prompt-loader.d.ts +49 -0
- package/dist/routes/prompt-loader.d.ts.map +1 -0
- package/dist/routes/prompt-loader.js +113 -0
- package/dist/routes/resolved-bundle.d.ts +69 -0
- package/dist/routes/resolved-bundle.d.ts.map +1 -1
- package/dist/routes/resolved-bundle.js +76 -0
- package/dist/routes/screen-loader.d.ts +29 -1
- package/dist/routes/screen-loader.d.ts.map +1 -1
- package/dist/routes/screen-loader.js +59 -1
- package/dist/run/accept.d.ts +5 -0
- package/dist/run/accept.d.ts.map +1 -1
- package/dist/run/accept.js +2 -0
- package/dist/run/cost.d.ts +31 -2
- package/dist/run/cost.d.ts.map +1 -1
- package/dist/run/cost.js +57 -2
- package/dist/run/destination.d.ts +39 -0
- package/dist/run/destination.d.ts.map +1 -0
- package/dist/run/destination.js +45 -0
- package/dist/run/dispatch.d.ts +67 -16
- package/dist/run/dispatch.d.ts.map +1 -1
- package/dist/run/dispatch.js +133 -29
- package/dist/run/grounding.d.ts +28 -2
- package/dist/run/grounding.d.ts.map +1 -1
- package/dist/run/grounding.js +54 -10
- package/dist/run/raw-defaults.d.ts.map +1 -1
- package/dist/run/raw-defaults.js +6 -1
- package/dist/run/raw-finalize.d.ts +50 -0
- package/dist/run/raw-finalize.d.ts.map +1 -0
- package/dist/run/raw-finalize.js +266 -0
- package/dist/run/raw-knobs.d.ts +36 -0
- package/dist/run/raw-knobs.d.ts.map +1 -0
- package/dist/run/raw-knobs.js +99 -0
- package/dist/run/raw-request.d.ts +24 -0
- package/dist/run/raw-request.d.ts.map +1 -0
- package/dist/run/raw-request.js +69 -0
- package/dist/run/raw-schema.d.ts +76 -0
- package/dist/run/raw-schema.d.ts.map +1 -0
- package/dist/run/raw-schema.js +166 -0
- package/dist/run/raw-search-cost.d.ts +48 -0
- package/dist/run/raw-search-cost.d.ts.map +1 -0
- package/dist/run/raw-search-cost.js +78 -0
- package/dist/run/raw-support.d.ts +64 -6
- package/dist/run/raw-support.d.ts.map +1 -1
- package/dist/run/raw-support.js +84 -11
- package/dist/run/raw.d.ts +25 -26
- package/dist/run/raw.d.ts.map +1 -1
- package/dist/run/raw.js +30 -351
- package/dist/run/record-attempt.d.ts +12 -0
- package/dist/run/record-attempt.d.ts.map +1 -1
- package/dist/run/record-attempt.js +30 -12
- package/dist/run/repair-attempt.d.ts +68 -0
- package/dist/run/repair-attempt.d.ts.map +1 -0
- package/dist/run/repair-attempt.js +180 -0
- package/dist/run/resolve-destination.d.ts +49 -0
- package/dist/run/resolve-destination.d.ts.map +1 -0
- package/dist/run/resolve-destination.js +76 -0
- package/dist/run/routing-docs.d.ts.map +1 -1
- package/dist/run/routing-docs.js +10 -5
- package/dist/run/run.d.ts +30 -1
- package/dist/run/run.d.ts.map +1 -1
- package/dist/run/run.js +94 -172
- package/dist/run/telemetry-row.d.ts +92 -0
- package/dist/run/telemetry-row.d.ts.map +1 -0
- package/dist/run/telemetry-row.js +81 -0
- package/dist/run/validate.d.ts +12 -1
- package/dist/run/validate.d.ts.map +1 -1
- package/dist/run/validate.js +31 -0
- package/dist/run/web-search-pricing.d.ts +43 -0
- package/dist/run/web-search-pricing.d.ts.map +1 -0
- package/dist/run/web-search-pricing.js +56 -0
- package/dist/savings/odometer.d.ts +4 -0
- package/dist/savings/odometer.d.ts.map +1 -1
- package/dist/savings/odometer.js +20 -1
- package/dist/savings/swap-execute.d.ts +7 -0
- package/dist/savings/swap-execute.d.ts.map +1 -1
- package/dist/savings/swap-execute.js +30 -0
- package/dist/savings/swaps-client.d.ts +10 -0
- package/dist/savings/swaps-client.d.ts.map +1 -1
- package/dist/screen/fixtures/probe-corpora.d.ts +23 -0
- package/dist/screen/fixtures/probe-corpora.d.ts.map +1 -0
- package/dist/screen/fixtures/probe-corpora.js +69 -0
- package/dist/screen/index.d.ts +21 -0
- package/dist/screen/index.d.ts.map +1 -0
- package/dist/screen/index.js +64 -0
- package/dist/screen/model-screen.d.ts +111 -0
- package/dist/screen/model-screen.d.ts.map +1 -0
- package/dist/screen/model-screen.js +178 -0
- package/dist/screen/patterns.d.ts +51 -0
- package/dist/screen/patterns.d.ts.map +1 -0
- package/dist/screen/patterns.js +151 -0
- package/dist/screen/phi-gate.d.ts +52 -0
- package/dist/screen/phi-gate.d.ts.map +1 -0
- package/dist/screen/phi-gate.js +86 -0
- package/dist/screen/policy.d.ts +71 -0
- package/dist/screen/policy.d.ts.map +1 -0
- package/dist/screen/policy.js +334 -0
- package/dist/screen/probe.d.ts +118 -0
- package/dist/screen/probe.d.ts.map +1 -0
- package/dist/screen/probe.js +132 -0
- package/dist/screen/screen-cli.d.ts +16 -0
- package/dist/screen/screen-cli.d.ts.map +1 -0
- package/dist/screen/screen-cli.js +178 -0
- package/dist/screen/screen.d.ts +99 -0
- package/dist/screen/screen.d.ts.map +1 -0
- package/dist/screen/screen.js +0 -0
- package/dist/screen/sidecar.d.ts +69 -0
- package/dist/screen/sidecar.d.ts.map +1 -0
- package/dist/screen/sidecar.js +145 -0
- package/dist/screen/types.d.ts +43 -2
- package/dist/screen/types.d.ts.map +1 -1
- package/dist/settings/api-fetcher.d.ts +14 -3
- package/dist/settings/api-fetcher.d.ts.map +1 -1
- package/dist/settings/api-fetcher.js +61 -10
- package/dist/settings/grading-guide.d.ts +102 -0
- package/dist/settings/grading-guide.d.ts.map +1 -0
- package/dist/settings/grading-guide.js +23 -0
- package/dist/settings/index.d.ts +3 -2
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +2 -1
- package/dist/settings/task-settings.d.ts +44 -7
- package/dist/settings/task-settings.d.ts.map +1 -1
- package/dist/settings/task-settings.js +53 -12
- package/dist/status.d.ts +32 -20
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +51 -30
- package/dist/telemetry/artifact-store.d.ts +5 -6
- package/dist/telemetry/artifact-store.d.ts.map +1 -1
- package/dist/telemetry/artifact-store.js +21 -24
- package/dist/telemetry/attempt-meta.d.ts +76 -1
- package/dist/telemetry/attempt-meta.d.ts.map +1 -1
- package/dist/telemetry/attempt-meta.js +33 -1
- package/dist/telemetry/exporter-setup.d.ts +2 -0
- package/dist/telemetry/exporter-setup.d.ts.map +1 -1
- package/dist/telemetry/exporter-setup.js +6 -1
- package/dist/telemetry/exporter.d.ts +2 -2
- package/dist/telemetry/exporter.d.ts.map +1 -1
- package/dist/telemetry/exporter.js +22 -41
- package/dist/telemetry/grade-mappers.d.ts +25 -0
- package/dist/telemetry/grade-mappers.d.ts.map +1 -0
- package/dist/telemetry/grade-mappers.js +64 -0
- package/dist/telemetry/grades-sql.d.ts +56 -0
- package/dist/telemetry/grades-sql.d.ts.map +1 -0
- package/dist/telemetry/grades-sql.js +156 -0
- package/dist/telemetry/ingest-protocol.d.ts +55 -48
- package/dist/telemetry/ingest-protocol.d.ts.map +1 -1
- package/dist/telemetry/ingest-protocol.js +48 -83
- package/dist/telemetry/org-identity.d.ts +44 -0
- package/dist/telemetry/org-identity.d.ts.map +1 -0
- package/dist/telemetry/org-identity.js +98 -0
- package/dist/telemetry/route-registration.d.ts +48 -0
- package/dist/telemetry/route-registration.d.ts.map +1 -0
- package/dist/telemetry/route-registration.js +77 -0
- package/dist/telemetry/sinks.d.ts +10 -1
- package/dist/telemetry/sinks.d.ts.map +1 -1
- package/dist/telemetry/sinks.js +52 -6
- package/dist/telemetry/store-migrations.d.ts.map +1 -1
- package/dist/telemetry/store-migrations.js +64 -0
- package/dist/telemetry/store.d.ts +9 -6
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/store.js +8 -50
- package/dist/tenancy/api-key-format.d.ts +45 -1
- package/dist/tenancy/api-key-format.d.ts.map +1 -1
- package/dist/tenancy/api-key-format.js +50 -1
- package/dist/types/provider.d.ts +23 -3
- package/dist/types/provider.d.ts.map +1 -1
- package/dist/types/provider.js +26 -0
- package/dist/types/route.d.ts +154 -2
- package/dist/types/route.d.ts.map +1 -1
- package/dist/types/telemetry.d.ts +73 -48
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/validate-cli.d.ts.map +1 -1
- package/dist/validate-cli.js +32 -0
- package/dist/verify/verify.d.ts +5 -0
- package/dist/verify/verify.d.ts.map +1 -1
- package/dist/verify/verify.js +2 -0
- package/dist/watch/evaluate.d.ts +84 -1
- package/dist/watch/evaluate.d.ts.map +1 -1
- package/dist/watch/evaluate.js +28 -0
- package/dist/watch/monitor.d.ts +8 -2
- package/dist/watch/monitor.d.ts.map +1 -1
- package/dist/watch/monitor.js +13 -5
- package/dist/watch/regret-monitor-cli.d.ts +16 -0
- package/dist/watch/regret-monitor-cli.d.ts.map +1 -0
- package/dist/watch/regret-monitor-cli.js +137 -0
- package/dist/watch/regret-monitor.d.ts +168 -0
- package/dist/watch/regret-monitor.d.ts.map +1 -0
- package/dist/watch/regret-monitor.js +304 -0
- package/dist/watch/upgrade.d.ts +62 -0
- package/dist/watch/upgrade.d.ts.map +1 -0
- package/dist/watch/upgrade.js +57 -0
- package/docs/agent-skill/SKILL.md +181 -9
- package/docs/how-it-fits.md +3 -2
- package/docs/instrumentation.md +219 -46
- package/docs/llms.txt +158 -35
- package/docs/managed-serving.md +150 -0
- package/docs/mcp-oracle.md +322 -0
- package/docs/migration-playbook.md +5 -4
- package/docs/quickstart.md +263 -89
- package/package.json +18 -4
- package/registry/leaderboard.json +74 -0
- package/registry/registry.json +232 -112
- package/screen.d.ts +16 -0
- package/templates/call-disposition-qa.json +77 -0
- package/templates/catalog-cleansing.json +77 -0
- package/templates/compliance-review.json +76 -0
- package/templates/cs-next-action.json +76 -0
- package/templates/document-extraction.json +78 -0
- package/templates/financial-classification.json +75 -0
- package/templates/lead-qualification.json +76 -0
- package/templates/medical-classification.json +71 -0
- package/templates/ticket-triage.json +76 -0
- package/dist/feedback/feedback.d.ts +0 -35
- package/dist/feedback/feedback.d.ts.map +0 -1
- package/dist/feedback/feedback.js +0 -39
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evidence groundedness grader (call-QA F3 / research §4 G6, spec §5). A
|
|
3
|
+
* DETERMINISTIC bake-off tier that scores a scorecard OUTPUT by whether its
|
|
4
|
+
* evidence quotes are actually present in the replayed INPUT (the transcript /
|
|
5
|
+
* source). A scorer that invents justifications — quotes that never appear in
|
|
6
|
+
* the input — is penalized; this is what stops a model from fabricating
|
|
7
|
+
* evidence to defend a score.
|
|
8
|
+
*
|
|
9
|
+
* Unlike the golden tiers (exact / field-level / llm-judge in quality.ts), this
|
|
10
|
+
* grades the output against the INPUT, not a corrected golden, so it applies
|
|
11
|
+
* whether or not an eval-case `expected` value is present.
|
|
12
|
+
*
|
|
13
|
+
* The scorecard OUTPUT shape (call-QA F2 emit):
|
|
14
|
+
* { criteria: [{ id, score, evidence: [{ quote, turn_id? }], comment }], score, comment }
|
|
15
|
+
*
|
|
16
|
+
* Grounding is a normalized SUBSTRING match against the DECODED input values
|
|
17
|
+
* (inputHaystack): the string leaf values the model was actually shown — never
|
|
18
|
+
* the JSON envelope's escaping or its keys — so a truthful quote spanning escaped
|
|
19
|
+
* chars is grounded and a fabricated quote equal to a key is not. Trivially short
|
|
20
|
+
* quotes never ground (MIN_GROUNDED_QUOTE_LEN).
|
|
21
|
+
*
|
|
22
|
+
* SCOPE NOTE (F3 vs F5): `turn_id` on an evidence entry is carried but NOT
|
|
23
|
+
* hard-validated — turn-scoped matching against the diarized transcript-with-
|
|
24
|
+
* turns artifact is F5's job (spec §7). F3 is substring grounding only.
|
|
25
|
+
*
|
|
26
|
+
* Pure; no I/O. Unit-tested directly (groundedness.test.ts).
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Pull every `criteria[].evidence[].quote` string from a scorecard output.
|
|
30
|
+
* Tolerant of missing / malformed shapes: a non-object output, a missing or
|
|
31
|
+
* non-array `criteria`, a criterion without an `evidence` array, or an evidence
|
|
32
|
+
* entry without a string `quote` are all skipped rather than throwing. Returns
|
|
33
|
+
* [] for anything it cannot read. Empty (whitespace-only) quotes are dropped —
|
|
34
|
+
* they carry no evidence to ground.
|
|
35
|
+
*/
|
|
36
|
+
export declare function extractEvidenceQuotes(output: unknown): string[];
|
|
37
|
+
/**
|
|
38
|
+
* The fraction in [0,1] of a scorecard's evidence quotes that are grounded in
|
|
39
|
+
* the input, or null when there is nothing to ground.
|
|
40
|
+
*
|
|
41
|
+
* A quote is GROUNDED when its whitespace-collapsed, case-insensitive form is a
|
|
42
|
+
* substring of the DECODED input's whitespace-collapsed, case-insensitive text
|
|
43
|
+
* ({@link inputHaystack} — the string leaf VALUES the model was shown, not the
|
|
44
|
+
* serialized envelope or its keys) AND it is at least {@link MIN_GROUNDED_QUOTE_LEN}
|
|
45
|
+
* chars long (a too-trivial quote is never grounded).
|
|
46
|
+
*
|
|
47
|
+
* Edge cases (explicit, tested):
|
|
48
|
+
* • ZERO evidence quotes across the whole scorecard (none present, or a
|
|
49
|
+
* malformed shape yields none) ⇒ null. There is nothing to ground, so the
|
|
50
|
+
* caller falls through to the next quality tier — NOT a spurious 1.0 or 0.0.
|
|
51
|
+
* • An empty / absent input WITH quotes ⇒ every quote is ungrounded ⇒ 0.
|
|
52
|
+
* • Quotes present but ALL below the min length ⇒ 0, NOT null — they were
|
|
53
|
+
* emitted, they just carry no evidentiary weight (null is only for ZERO
|
|
54
|
+
* emitted quotes).
|
|
55
|
+
* • All quotes grounded ⇒ 1; some grounded ⇒ grounded / total.
|
|
56
|
+
*/
|
|
57
|
+
export declare function groundednessScore(output: unknown, input: unknown): number | null;
|
|
58
|
+
//# sourceMappingURL=groundedness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groundedness.d.ts","sourceRoot":"","sources":["../../src/bakeoff/groundedness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAoEH;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,CAgB/D;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAYhF"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Evidence groundedness grader (call-QA F3 / research §4 G6, spec §5). A
|
|
4
|
+
* DETERMINISTIC bake-off tier that scores a scorecard OUTPUT by whether its
|
|
5
|
+
* evidence quotes are actually present in the replayed INPUT (the transcript /
|
|
6
|
+
* source). A scorer that invents justifications — quotes that never appear in
|
|
7
|
+
* the input — is penalized; this is what stops a model from fabricating
|
|
8
|
+
* evidence to defend a score.
|
|
9
|
+
*
|
|
10
|
+
* Unlike the golden tiers (exact / field-level / llm-judge in quality.ts), this
|
|
11
|
+
* grades the output against the INPUT, not a corrected golden, so it applies
|
|
12
|
+
* whether or not an eval-case `expected` value is present.
|
|
13
|
+
*
|
|
14
|
+
* The scorecard OUTPUT shape (call-QA F2 emit):
|
|
15
|
+
* { criteria: [{ id, score, evidence: [{ quote, turn_id? }], comment }], score, comment }
|
|
16
|
+
*
|
|
17
|
+
* Grounding is a normalized SUBSTRING match against the DECODED input values
|
|
18
|
+
* (inputHaystack): the string leaf values the model was actually shown — never
|
|
19
|
+
* the JSON envelope's escaping or its keys — so a truthful quote spanning escaped
|
|
20
|
+
* chars is grounded and a fabricated quote equal to a key is not. Trivially short
|
|
21
|
+
* quotes never ground (MIN_GROUNDED_QUOTE_LEN).
|
|
22
|
+
*
|
|
23
|
+
* SCOPE NOTE (F3 vs F5): `turn_id` on an evidence entry is carried but NOT
|
|
24
|
+
* hard-validated — turn-scoped matching against the diarized transcript-with-
|
|
25
|
+
* turns artifact is F5's job (spec §7). F3 is substring grounding only.
|
|
26
|
+
*
|
|
27
|
+
* Pure; no I/O. Unit-tested directly (groundedness.test.ts).
|
|
28
|
+
*/
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.extractEvidenceQuotes = extractEvidenceQuotes;
|
|
31
|
+
exports.groundednessScore = groundednessScore;
|
|
32
|
+
function isObject(v) {
|
|
33
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
34
|
+
}
|
|
35
|
+
/** Collapse all runs of whitespace to a single space, trim, and lowercase — the
|
|
36
|
+
* comparison basis for grounding. This makes a quote grounded regardless of
|
|
37
|
+
* incidental whitespace (newlines, tabs, doubled spaces) or letter case, while
|
|
38
|
+
* never doing a fuzzy match: a quote whose WORDS are not in the input is still
|
|
39
|
+
* ungrounded. Mirrors quality.ts's "normalized, never fuzzy" discipline. */
|
|
40
|
+
function collapse(text) {
|
|
41
|
+
return text.replace(/\s+/g, " ").trim().toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Quotes whose collapsed length is below this count as UNGROUNDED, never
|
|
45
|
+
* grounded (they still count toward the denominator — see {@link groundednessScore}).
|
|
46
|
+
* A 1–2 char fragment ("a", "no", "ok") is a substring of almost any transcript,
|
|
47
|
+
* so a raw substring match would let a fabricator score 1.0 with trivial
|
|
48
|
+
* "evidence"; too-short quotes carry no evidentiary weight. 12 chars ≈ a few
|
|
49
|
+
* words — enough to be a real span, not an accidental hit. */
|
|
50
|
+
const MIN_GROUNDED_QUOTE_LEN = 12;
|
|
51
|
+
/** Collect every STRING LEAF from a decoded JSON value — object VALUES and array
|
|
52
|
+
* items, NEVER object KEYS. This is the text the model was actually shown (the
|
|
53
|
+
* decoded variable values), so grounding is checked against values, and a
|
|
54
|
+
* fabricated quote equal to a structural KEY (e.g. "transcript") cannot
|
|
55
|
+
* false-pass. */
|
|
56
|
+
function collectStringLeaves(v, out) {
|
|
57
|
+
if (typeof v === "string") {
|
|
58
|
+
out.push(v);
|
|
59
|
+
}
|
|
60
|
+
else if (Array.isArray(v)) {
|
|
61
|
+
for (const item of v)
|
|
62
|
+
collectStringLeaves(item, out);
|
|
63
|
+
}
|
|
64
|
+
else if (isObject(v)) {
|
|
65
|
+
for (const key of Object.keys(v))
|
|
66
|
+
collectStringLeaves(v[key], out);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Render the replayed input to the haystack grounding is checked against: the
|
|
71
|
+
* DECODED string leaf values, joined by spaces — NOT the serialized envelope.
|
|
72
|
+
*
|
|
73
|
+
* The model was shown the decoded variable VALUES, not the JSON wrapper, so:
|
|
74
|
+
* • a string input (the serialized route variables) is JSON.parse'd first,
|
|
75
|
+
* which un-escapes `\"`→`"` and `\n`→newline, then its string leaves are
|
|
76
|
+
* collected — a parse failure means a bare (non-JSON) transcript, used as-is;
|
|
77
|
+
* • an object/array input is walked directly.
|
|
78
|
+
* Object KEYS are excluded (leaves are values only), so a quote equal to a key
|
|
79
|
+
* ("transcript") is not grounded. `undefined`/`null` ⇒ "" (every quote
|
|
80
|
+
* ungrounded). */
|
|
81
|
+
function inputHaystack(input) {
|
|
82
|
+
if (input === undefined || input === null)
|
|
83
|
+
return "";
|
|
84
|
+
if (typeof input === "string") {
|
|
85
|
+
try {
|
|
86
|
+
const parsed = JSON.parse(input);
|
|
87
|
+
const leaves = [];
|
|
88
|
+
collectStringLeaves(parsed, leaves);
|
|
89
|
+
return leaves.join(" ");
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return input; // not JSON — a bare transcript string; use as-is.
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const leaves = [];
|
|
96
|
+
collectStringLeaves(input, leaves);
|
|
97
|
+
return leaves.join(" ");
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Pull every `criteria[].evidence[].quote` string from a scorecard output.
|
|
101
|
+
* Tolerant of missing / malformed shapes: a non-object output, a missing or
|
|
102
|
+
* non-array `criteria`, a criterion without an `evidence` array, or an evidence
|
|
103
|
+
* entry without a string `quote` are all skipped rather than throwing. Returns
|
|
104
|
+
* [] for anything it cannot read. Empty (whitespace-only) quotes are dropped —
|
|
105
|
+
* they carry no evidence to ground.
|
|
106
|
+
*/
|
|
107
|
+
function extractEvidenceQuotes(output) {
|
|
108
|
+
if (!isObject(output))
|
|
109
|
+
return [];
|
|
110
|
+
const criteria = output.criteria;
|
|
111
|
+
if (!Array.isArray(criteria))
|
|
112
|
+
return [];
|
|
113
|
+
const quotes = [];
|
|
114
|
+
for (const criterion of criteria) {
|
|
115
|
+
if (!isObject(criterion))
|
|
116
|
+
continue;
|
|
117
|
+
const evidence = criterion.evidence;
|
|
118
|
+
if (!Array.isArray(evidence))
|
|
119
|
+
continue;
|
|
120
|
+
for (const item of evidence) {
|
|
121
|
+
if (!isObject(item))
|
|
122
|
+
continue;
|
|
123
|
+
const quote = item.quote;
|
|
124
|
+
if (typeof quote === "string" && quote.trim() !== "")
|
|
125
|
+
quotes.push(quote);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return quotes;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The fraction in [0,1] of a scorecard's evidence quotes that are grounded in
|
|
132
|
+
* the input, or null when there is nothing to ground.
|
|
133
|
+
*
|
|
134
|
+
* A quote is GROUNDED when its whitespace-collapsed, case-insensitive form is a
|
|
135
|
+
* substring of the DECODED input's whitespace-collapsed, case-insensitive text
|
|
136
|
+
* ({@link inputHaystack} — the string leaf VALUES the model was shown, not the
|
|
137
|
+
* serialized envelope or its keys) AND it is at least {@link MIN_GROUNDED_QUOTE_LEN}
|
|
138
|
+
* chars long (a too-trivial quote is never grounded).
|
|
139
|
+
*
|
|
140
|
+
* Edge cases (explicit, tested):
|
|
141
|
+
* • ZERO evidence quotes across the whole scorecard (none present, or a
|
|
142
|
+
* malformed shape yields none) ⇒ null. There is nothing to ground, so the
|
|
143
|
+
* caller falls through to the next quality tier — NOT a spurious 1.0 or 0.0.
|
|
144
|
+
* • An empty / absent input WITH quotes ⇒ every quote is ungrounded ⇒ 0.
|
|
145
|
+
* • Quotes present but ALL below the min length ⇒ 0, NOT null — they were
|
|
146
|
+
* emitted, they just carry no evidentiary weight (null is only for ZERO
|
|
147
|
+
* emitted quotes).
|
|
148
|
+
* • All quotes grounded ⇒ 1; some grounded ⇒ grounded / total.
|
|
149
|
+
*/
|
|
150
|
+
function groundednessScore(output, input) {
|
|
151
|
+
const quotes = extractEvidenceQuotes(output);
|
|
152
|
+
if (quotes.length === 0)
|
|
153
|
+
return null;
|
|
154
|
+
const haystack = collapse(inputHaystack(input));
|
|
155
|
+
let grounded = 0;
|
|
156
|
+
for (const q of quotes) {
|
|
157
|
+
const needle = collapse(q);
|
|
158
|
+
// Too-trivial quotes never ground (they still count in the denominator).
|
|
159
|
+
if (needle.length < MIN_GROUNDED_QUOTE_LEN)
|
|
160
|
+
continue;
|
|
161
|
+
if (haystack.includes(needle))
|
|
162
|
+
grounded += 1;
|
|
163
|
+
}
|
|
164
|
+
return grounded / quotes.length;
|
|
165
|
+
}
|
|
@@ -13,6 +13,20 @@
|
|
|
13
13
|
* ordering.
|
|
14
14
|
*/
|
|
15
15
|
import type { ValueCheck } from "../types/route";
|
|
16
|
+
/**
|
|
17
|
+
* The grader a golden eval set scores with (live-routing-evals §2.2/§4). All
|
|
18
|
+
* three are wired: `exact` (binary normalized equality, LRE-1b), `field-level`
|
|
19
|
+
* (schema-aware per-field partial credit via {@link fieldAccuracy}, first-class
|
|
20
|
+
* as of LRE-2), and `llm-judge` (a PAIRWISE comparison of the output against the
|
|
21
|
+
* golden — NOT a deterministic tier, so this resolver returns null for it and the
|
|
22
|
+
* caller's golden judge (golden-judge.ts, LRE-2) scores it against `expected`).
|
|
23
|
+
*
|
|
24
|
+
* `evidence-grounded` (call-QA F3 / G6) is a fourth, GOLDEN-FREE deterministic
|
|
25
|
+
* kind: it scores a scorecard output by whether its evidence quotes appear in
|
|
26
|
+
* the replayed INPUT (groundedness.ts), not against a corrected golden. It is
|
|
27
|
+
* dispatched here regardless of whether an `expected` value is present.
|
|
28
|
+
*/
|
|
29
|
+
export type GraderType = "exact" | "field-level" | "llm-judge" | "evidence-grounded";
|
|
16
30
|
/**
|
|
17
31
|
* Schema-aware field accuracy in [0,1]: the fraction of the EXPECTED value's leaf
|
|
18
32
|
* fields that the actual output matches. Recurses into objects/arrays keyed by
|
|
@@ -21,6 +35,18 @@ import type { ValueCheck } from "../types/route";
|
|
|
21
35
|
* expected ⇒ 1 (nothing to be wrong about).
|
|
22
36
|
*/
|
|
23
37
|
export declare function fieldAccuracy(expected: unknown, actual: unknown): number;
|
|
38
|
+
/**
|
|
39
|
+
* The `exact` grader (LRE-1b, spec §4): normalized EQUALITY of the parsed output
|
|
40
|
+
* against the golden → 1 (match) or 0 (mismatch). Binary, never partial credit —
|
|
41
|
+
* that is the whole point of `exact` vs `field-level` (`fieldAccuracy`).
|
|
42
|
+
*
|
|
43
|
+
* Normalization is `normalizeDeep`: object keys are order-insensitive (sorted),
|
|
44
|
+
* string leaves are whitespace-trimmed, arrays stay ORDER-sensitive (a reordered
|
|
45
|
+
* list is a different value), and types are strict (`1` ≠ `"1"`, `null` ≠
|
|
46
|
+
* `undefined`). So `{a:1, b:" x "}` matches `{b:"x", a:1}` but `[1,2]` does not
|
|
47
|
+
* match `[2,1]`. Pure + unit-tested (exact-grader.test.ts).
|
|
48
|
+
*/
|
|
49
|
+
export declare function exactMatch(expected: unknown, actual: unknown): number;
|
|
24
50
|
/** Resolve an RFC 6901 JSON pointer against a value. Returns `undefined` when any
|
|
25
51
|
* segment is missing (a missing field fails its value check). */
|
|
26
52
|
export declare function resolveJsonPointer(value: unknown, pointer: string): unknown;
|
|
@@ -29,12 +55,29 @@ export declare function checkPasses(output: unknown, check: ValueCheck): boolean
|
|
|
29
55
|
export interface DeterministicQualityInput {
|
|
30
56
|
readonly output: unknown;
|
|
31
57
|
readonly valueChecks?: readonly ValueCheck[];
|
|
58
|
+
/** The replayed capture INPUT (transcript / source). Consulted ONLY by the
|
|
59
|
+
* `evidence-grounded` grader (F3/G6), which grounds the output's evidence
|
|
60
|
+
* quotes against it. A string is used as-is; anything else is JSON.stringify'd
|
|
61
|
+
* (groundedness.ts). Ignored by every other grader kind. */
|
|
62
|
+
readonly input?: unknown;
|
|
32
63
|
/** The corrected/golden expected output for this capture, when a bake-off runs
|
|
33
64
|
* from eval cases with a corrected artifact. */
|
|
34
65
|
readonly expected?: unknown;
|
|
35
66
|
/** Set when `expected` is meaningfully present (distinguishes a golden `null`
|
|
36
67
|
* expected value from "no eval case"). */
|
|
37
68
|
readonly hasExpected?: boolean;
|
|
69
|
+
/** The golden set's grader. Only consulted alongside `hasExpected`:
|
|
70
|
+
* • `exact` → binary normalized equality (exactMatch).
|
|
71
|
+
* • `field-level`→ schema-aware per-field partial credit (fieldAccuracy) —
|
|
72
|
+
* the fraction of the golden's leaf fields the output matches, in [0,1].
|
|
73
|
+
* • `llm-judge` → NOT a deterministic tier; returns null so the caller's
|
|
74
|
+
* golden judge (golden-judge.ts) scores the output against the golden via
|
|
75
|
+
* the N5/N6 pairwise judge (LRE-2).
|
|
76
|
+
* • `evidence-grounded` → GOLDEN-FREE (F3/G6); scores the output's evidence
|
|
77
|
+
* quotes against {@link DeterministicQualityInput.input}, independent of
|
|
78
|
+
* `expected`/`hasExpected`. See {@link groundednessScore}.
|
|
79
|
+
* Absent ⇒ `field-level` behavior (byte-identical to pre-LRE-1b default). */
|
|
80
|
+
readonly graderType?: GraderType;
|
|
38
81
|
}
|
|
39
82
|
/**
|
|
40
83
|
* Deterministic value accuracy for one sample, or null when neither an eval-case
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/bakeoff/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"quality.d.ts","sourceRoot":"","sources":["../../src/bakeoff/quality.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAGjD;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,aAAa,GAAG,WAAW,GAAG,mBAAmB,CAAC;AAiBrF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAgBxE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAErE;AAED;iEACiE;AACjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAmB3E;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAWvE;AAYD,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7C;;;gEAG4D;IAC5D,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB;oDACgD;IAChD,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B;8CAC0C;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;iFAU6E;IAC7E,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CAClC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,yBAAyB,GAAG,MAAM,GAAG,IAAI,CAuB3F"}
|
package/dist/bakeoff/quality.js
CHANGED
|
@@ -15,9 +15,11 @@
|
|
|
15
15
|
*/
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
exports.fieldAccuracy = fieldAccuracy;
|
|
18
|
+
exports.exactMatch = exactMatch;
|
|
18
19
|
exports.resolveJsonPointer = resolveJsonPointer;
|
|
19
20
|
exports.checkPasses = checkPasses;
|
|
20
21
|
exports.resolveDeterministicQuality = resolveDeterministicQuality;
|
|
22
|
+
const groundedness_1 = require("./groundedness");
|
|
21
23
|
/** Normalize a scalar for comparison: trim strings; leave numbers/booleans as-is.
|
|
22
24
|
* "normalized match" (spec §4.3) means insensitivity to surrounding whitespace,
|
|
23
25
|
* never a fuzzy match — a wrong value is still wrong. */
|
|
@@ -58,6 +60,20 @@ function fieldAccuracy(expected, actual) {
|
|
|
58
60
|
}
|
|
59
61
|
return scalarEqual(expected, actual) ? 1 : 0;
|
|
60
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* The `exact` grader (LRE-1b, spec §4): normalized EQUALITY of the parsed output
|
|
65
|
+
* against the golden → 1 (match) or 0 (mismatch). Binary, never partial credit —
|
|
66
|
+
* that is the whole point of `exact` vs `field-level` (`fieldAccuracy`).
|
|
67
|
+
*
|
|
68
|
+
* Normalization is `normalizeDeep`: object keys are order-insensitive (sorted),
|
|
69
|
+
* string leaves are whitespace-trimmed, arrays stay ORDER-sensitive (a reordered
|
|
70
|
+
* list is a different value), and types are strict (`1` ≠ `"1"`, `null` ≠
|
|
71
|
+
* `undefined`). So `{a:1, b:" x "}` matches `{b:"x", a:1}` but `[1,2]` does not
|
|
72
|
+
* match `[2,1]`. Pure + unit-tested (exact-grader.test.ts).
|
|
73
|
+
*/
|
|
74
|
+
function exactMatch(expected, actual) {
|
|
75
|
+
return JSON.stringify(normalizeDeep(expected)) === JSON.stringify(normalizeDeep(actual)) ? 1 : 0;
|
|
76
|
+
}
|
|
61
77
|
/** Resolve an RFC 6901 JSON pointer against a value. Returns `undefined` when any
|
|
62
78
|
* segment is missing (a missing field fails its value check). */
|
|
63
79
|
function resolveJsonPointer(value, pointer) {
|
|
@@ -114,7 +130,22 @@ function normalizeDeep(v) {
|
|
|
114
130
|
* expected value nor a value check applies (the caller then tries the judge).
|
|
115
131
|
*/
|
|
116
132
|
function resolveDeterministicQuality(input) {
|
|
133
|
+
// evidence-grounded (F3/G6): GOLDEN-FREE. Scores the output's evidence quotes
|
|
134
|
+
// against the replayed INPUT, NOT a golden — so it runs whether or not an
|
|
135
|
+
// eval-case `expected` value is present, and does not disturb the exact/
|
|
136
|
+
// field-level/llm-judge/hasExpected/valueChecks precedence below. A null
|
|
137
|
+
// (no evidence quotes to ground) defers to the next tier exactly like the
|
|
138
|
+
// other deterministic kinds.
|
|
139
|
+
if (input.graderType === "evidence-grounded") {
|
|
140
|
+
return (0, groundedness_1.groundednessScore)(input.output, input.input);
|
|
141
|
+
}
|
|
117
142
|
if (input.hasExpected === true) {
|
|
143
|
+
// llm-judge is not deterministic — defer to the judge tier (LRE-2 seam).
|
|
144
|
+
if (input.graderType === "llm-judge")
|
|
145
|
+
return null;
|
|
146
|
+
if (input.graderType === "exact")
|
|
147
|
+
return exactMatch(input.expected, input.output);
|
|
148
|
+
// field-level (explicit) or unspecified default → schema-aware field accuracy.
|
|
118
149
|
return fieldAccuracy(input.expected, input.output);
|
|
119
150
|
}
|
|
120
151
|
const checks = input.valueChecks;
|
package/dist/bakeoff/replay.d.ts
CHANGED
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import type { CaptureStore } from "../telemetry/capture";
|
|
21
21
|
import type { RunDeps } from "../run/run";
|
|
22
|
+
import type { GraderType } from "./quality";
|
|
22
23
|
import type { JudgeScorer } from "./judge";
|
|
24
|
+
import type { GoldenJudgeScorer } from "./golden-judge";
|
|
23
25
|
import type { QualityGate } from "../types/quality";
|
|
24
26
|
export interface ReplayRequest {
|
|
25
27
|
readonly route: string;
|
|
@@ -42,9 +44,18 @@ export interface ReplayRequest {
|
|
|
42
44
|
readonly expected?: ReadonlyMap<string, {
|
|
43
45
|
readonly value: unknown;
|
|
44
46
|
}>;
|
|
47
|
+
/** LRE-1b: the golden set's grader — how an `expected` value is scored against
|
|
48
|
+
* the output (`exact` binary, `field-level` per-field, `llm-judge` deferred to
|
|
49
|
+
* the judge tier). Absent ⇒ field-level (pre-LRE-1b behavior). */
|
|
50
|
+
readonly graderType?: GraderType;
|
|
45
51
|
/** RB-1: an opt-in judge scorer (tier 3), used only when neither an eval-case
|
|
46
52
|
* expected value nor a declared value check yields a score. Capped internally. */
|
|
47
53
|
readonly judge?: JudgeScorer;
|
|
54
|
+
/** LRE-2: the `llm-judge` grader — scores a produced output against its GOLDEN
|
|
55
|
+
* (`expected`) value via the N5/N6 pairwise judge. Used ONLY when
|
|
56
|
+
* `graderType==='llm-judge'` AND this sample has an eval-case expected value (a
|
|
57
|
+
* failure case with no golden still scores by conformance). Capped internally. */
|
|
58
|
+
readonly goldenJudge?: GoldenJudgeScorer;
|
|
48
59
|
/** Q1 quality gate (spec §4.2): scored on each replayed sample's output to
|
|
49
60
|
* populate `valueAccuracy` + `qualityPassed`. NOT passed into the inner
|
|
50
61
|
* `run()` — a bake-off MEASURES quality, it does not gate serving; injecting
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/bakeoff/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/bakeoff/replay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGpD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B;;uCAEmC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;kFAI8E;IAC9E,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C;;yEAEqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IACrE;;sEAEkE;IAClE,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;IACjC;sFACkF;IAClF,QAAQ,CAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAC7B;;;sFAGkF;IAClF,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IACzC;;;;;iFAK6E;IAC7E,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;CACpC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;wEACoE;IACpE,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC;;;oCAGgC;IAChC,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B;yDACqD;IACrD,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,oEAAoE;IACpE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B;sDACkD;IAClD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,OAAO,EACb,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,SAAS,kBAAkB,EAAE,CAAC,CAoJxC"}
|
package/dist/bakeoff/replay.js
CHANGED
|
@@ -110,8 +110,13 @@ async function replayVariant(deps, captures, req) {
|
|
|
110
110
|
const expected = req.expected?.get(capture.inferenceId);
|
|
111
111
|
const det = (0, quality_1.resolveDeterministicQuality)({
|
|
112
112
|
output: outputValue,
|
|
113
|
+
// The replayed capture INPUT, for the `evidence-grounded` grader (F3/G6)
|
|
114
|
+
// — the serialized route variables (which carry the transcript/source),
|
|
115
|
+
// used as-is since it is already text. Ignored by every other grader.
|
|
116
|
+
input: capture.variablesJson,
|
|
113
117
|
...(route.valueChecks !== undefined ? { valueChecks: route.valueChecks } : {}),
|
|
114
118
|
...(expected !== undefined ? { hasExpected: true, expected: expected.value } : {}),
|
|
119
|
+
...(req.graderType !== undefined ? { graderType: req.graderType } : {}),
|
|
115
120
|
});
|
|
116
121
|
let gateScore = null;
|
|
117
122
|
if (req.qualityGate !== undefined && gated !== null) {
|
|
@@ -126,6 +131,13 @@ async function replayVariant(deps, captures, req) {
|
|
|
126
131
|
valueAccuracy = det;
|
|
127
132
|
else if (gateScore !== null)
|
|
128
133
|
valueAccuracy = gateScore;
|
|
134
|
+
// LRE-2 llm-judge grader: a golden-set case whose grader is `llm-judge`
|
|
135
|
+
// scores the output against its GOLDEN via the pairwise judge (det is null
|
|
136
|
+
// for llm-judge — resolveDeterministicQuality defers it here). Only a case
|
|
137
|
+
// WITH an expected value is golden-judged; a failure case falls through.
|
|
138
|
+
else if (req.graderType === "llm-judge" && expected !== undefined && req.goldenJudge !== undefined) {
|
|
139
|
+
valueAccuracy = await req.goldenJudge.score(outputValue, expected.value, JSON.parse(capture.variablesJson));
|
|
140
|
+
}
|
|
129
141
|
else if (req.judge !== undefined) {
|
|
130
142
|
valueAccuracy = await req.judge.score(outputValue, JSON.parse(capture.variablesJson));
|
|
131
143
|
}
|
package/dist/bakeoff/report.d.ts
CHANGED
|
@@ -43,6 +43,13 @@ export declare function formatCacheAdjustedSection(rows: readonly CacheAdjustedR
|
|
|
43
43
|
* (returns strings); empty when nothing disagreed. Exported for direct testing.
|
|
44
44
|
*/
|
|
45
45
|
export declare function formatDisagreementSummary(artifact: BakeoffArtifact): string[];
|
|
46
|
+
/**
|
|
47
|
+
* N4 (spec §4.2/§6): the proposed swap's direction line — ⬆/⬇/→ + the signed
|
|
48
|
+
* effective-cost delta ($/1k). An up-swap is framed as a quality investment, NEVER
|
|
49
|
+
* a saving (claim ceiling §8). Pure (returns strings); empty when there is no
|
|
50
|
+
* proposal or the delta is indeterminate. Exported for direct testing.
|
|
51
|
+
*/
|
|
52
|
+
export declare function formatSwapDirection(artifact: BakeoffArtifact): string[];
|
|
46
53
|
export declare function printMatrix(artifact: BakeoffArtifact, cacheAdjusted?: readonly CacheAdjustedRow[]): void;
|
|
47
54
|
/**
|
|
48
55
|
* `modelrig bakeoff --from-eval-cases <task> --variants a,b,c` — replay a task's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/bakeoff/report.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA2CpD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAexE;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAgCtF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,CAiB7E;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,EAAE,aAAa,GAAE,SAAS,gBAAgB,EAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/bakeoff/report.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AA2CpD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAexE;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,gFAAgF;IAChF,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,WAAW,EAAE,mBAAmB,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,SAAS,gBAAgB,EAAE,GAAG,MAAM,EAAE,CAgCtF;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,CAiB7E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,EAAE,CAavE;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,eAAe,EAAE,aAAa,GAAE,SAAS,gBAAgB,EAAO,GAAG,IAAI,CA4D5G;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,IAAI,EAAE,eAAe,GAAG,SAAS,EACjC,MAAM,EAAE,OAAO,EACf,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,MAAM,CAAC,CA+CjB"}
|
package/dist/bakeoff/report.js
CHANGED
|
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
9
9
|
exports.bakeoffHeadline = bakeoffHeadline;
|
|
10
10
|
exports.formatCacheAdjustedSection = formatCacheAdjustedSection;
|
|
11
11
|
exports.formatDisagreementSummary = formatDisagreementSummary;
|
|
12
|
+
exports.formatSwapDirection = formatSwapDirection;
|
|
12
13
|
exports.printMatrix = printMatrix;
|
|
13
14
|
exports.runEvalCaseBakeoffCli = runEvalCaseBakeoffCli;
|
|
14
15
|
const node_fs_1 = require("node:fs");
|
|
@@ -144,6 +145,26 @@ function formatDisagreementSummary(artifact) {
|
|
|
144
145
|
}
|
|
145
146
|
return lines;
|
|
146
147
|
}
|
|
148
|
+
/**
|
|
149
|
+
* N4 (spec §4.2/§6): the proposed swap's direction line — ⬆/⬇/→ + the signed
|
|
150
|
+
* effective-cost delta ($/1k). An up-swap is framed as a quality investment, NEVER
|
|
151
|
+
* a saving (claim ceiling §8). Pure (returns strings); empty when there is no
|
|
152
|
+
* proposal or the delta is indeterminate. Exported for direct testing.
|
|
153
|
+
*/
|
|
154
|
+
function formatSwapDirection(artifact) {
|
|
155
|
+
const dir = (0, engine_1.deriveSwapDirection)(artifact);
|
|
156
|
+
if (dir === null || dir.costDeltaUsdPer1k === null)
|
|
157
|
+
return [];
|
|
158
|
+
const arrow = dir.direction === "up" ? "⬆" : dir.direction === "down" ? "⬇" : "→";
|
|
159
|
+
const delta = dir.costDeltaUsdPer1k;
|
|
160
|
+
const sign = delta >= 0 ? "+" : "−";
|
|
161
|
+
const note = dir.direction === "up"
|
|
162
|
+
? " — raises effective cost to cut regret; a quality investment, not a saving"
|
|
163
|
+
: dir.direction === "down"
|
|
164
|
+
? " — cost-reducing"
|
|
165
|
+
: "";
|
|
166
|
+
return [` direction: ${arrow} ${dir.direction}-swap (${sign}$${Math.abs(delta).toFixed(2)}/1k effective${note})`];
|
|
167
|
+
}
|
|
147
168
|
function printMatrix(artifact, cacheAdjusted = []) {
|
|
148
169
|
console.log(`bakeoff ${artifact.id}\nroute ${artifact.route}@${artifact.routeVersion} · replayed ${artifact.replayN} captured inputs · ${artifact.ranAt}`);
|
|
149
170
|
// RB-1: a reference arm is present ⇒ show quality + regret columns and badge
|
|
@@ -195,6 +216,11 @@ function printMatrix(artifact, cacheAdjusted = []) {
|
|
|
195
216
|
else {
|
|
196
217
|
console.log("proposal: none (no variant beats the incumbent's gates)");
|
|
197
218
|
}
|
|
219
|
+
// N4 (spec §6/§9): the proposed swap's direction + signed cost delta on the CLI
|
|
220
|
+
// proposal line — an up-swap raises effective cost (a quality investment), a
|
|
221
|
+
// down-swap is the shipped saving. Printed only when a proposal exists.
|
|
222
|
+
for (const l of formatSwapDirection(artifact))
|
|
223
|
+
console.log(l);
|
|
198
224
|
// N6 disagreement summary — printed only when candidates were mined; absent ⇒
|
|
199
225
|
// byte-identical to the pre-N6 matrix output.
|
|
200
226
|
for (const l of formatDisagreementSummary(artifact))
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `modelrig judge <run>` — E5 V.4: explicitly ask the bounded model-judge to
|
|
3
|
+
* score a run. Goes through the API boundary (T12: the CLI never holds a DB
|
|
4
|
+
* client) — POST /v1/runs/:id/judge on the configured server, authed with a
|
|
5
|
+
* rig_sk key. The daily cap + metering are the SERVER's; this just triggers one.
|
|
6
|
+
*
|
|
7
|
+
* Extracted from cli.ts (which sits at the ≤700-LOC cap) into its own module,
|
|
8
|
+
* mirroring `cli-query.ts`. Behaviour is byte-identical to the inline command.
|
|
9
|
+
*/
|
|
10
|
+
import type { Flags } from "./cli";
|
|
11
|
+
export declare function cmdJudge(flags: Flags): Promise<number>;
|
|
12
|
+
//# sourceMappingURL=cli-judge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-judge.d.ts","sourceRoot":"","sources":["../src/cli-judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAEnC,wBAAsB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAoC5D"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* `modelrig judge <run>` — E5 V.4: explicitly ask the bounded model-judge to
|
|
4
|
+
* score a run. Goes through the API boundary (T12: the CLI never holds a DB
|
|
5
|
+
* client) — POST /v1/runs/:id/judge on the configured server, authed with a
|
|
6
|
+
* rig_sk key. The daily cap + metering are the SERVER's; this just triggers one.
|
|
7
|
+
*
|
|
8
|
+
* Extracted from cli.ts (which sits at the ≤700-LOC cap) into its own module,
|
|
9
|
+
* mirroring `cli-query.ts`. Behaviour is byte-identical to the inline command.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.cmdJudge = cmdJudge;
|
|
13
|
+
const config_1 = require("./config");
|
|
14
|
+
async function cmdJudge(flags) {
|
|
15
|
+
const runId = flags.positional[0] ?? "";
|
|
16
|
+
// Config is the only env reader (package-invariants rule). The judge endpoint
|
|
17
|
+
// lives on the same server as the api-mode ingest sink, so the base is that
|
|
18
|
+
// URL's origin and the credential is the api key.
|
|
19
|
+
const exp = (0, config_1.loadConfigFromEnv)().export;
|
|
20
|
+
const api = exp !== undefined && exp.mode === "api" ? exp : undefined;
|
|
21
|
+
const base = api !== undefined ? new URL(api.ingestUrl).origin : "";
|
|
22
|
+
const key = api?.apiKey ?? "";
|
|
23
|
+
if (runId === "" || base === "" || key === "") {
|
|
24
|
+
console.error([
|
|
25
|
+
"usage: modelrig judge <runId>",
|
|
26
|
+
"",
|
|
27
|
+
"Needs api-mode telemetry configured (the judge is on the same server):",
|
|
28
|
+
" MODELRIG_API_KEY a rig_sk_ key with the `oracle-act` scope",
|
|
29
|
+
" MODELRIG_INGEST_URL optional — the server base; defaults to the hosted API",
|
|
30
|
+
"",
|
|
31
|
+
"The judge is EXPLICIT-only and metered; scoring rides the gateway (a route),",
|
|
32
|
+
"so the org's daily cap and spend-stops apply. Nothing schedules it.",
|
|
33
|
+
].join("\n"));
|
|
34
|
+
return 1;
|
|
35
|
+
}
|
|
36
|
+
const res = await fetch(`${base}/v1/runs/${encodeURIComponent(runId)}/judge`, {
|
|
37
|
+
method: "POST",
|
|
38
|
+
headers: { authorization: `Bearer ${key}`, "content-type": "application/json" },
|
|
39
|
+
body: "{}",
|
|
40
|
+
});
|
|
41
|
+
const body = (await res.json().catch(() => ({})));
|
|
42
|
+
if (!res.ok) {
|
|
43
|
+
console.error(`judge ${res.status}: ${typeof body.error === "string" ? body.error : "failed"}`);
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
console.log(JSON.stringify(body, null, 2));
|
|
47
|
+
return 0;
|
|
48
|
+
}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAsDH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CACpC;AAeD,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAuBxD;AA+eD,wBAAsB,IAAI,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CA+CnE"}
|