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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"objective-loader.d.ts","sourceRoot":"","sources":["../../src/routes/objective-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EAGb,cAAc,EACd,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB;;2EAE2E;AAC3E,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,QAAQ,EAAE,MAAM,EAAE,GACjB;
|
|
1
|
+
{"version":3,"file":"objective-loader.d.ts","sourceRoot":"","sources":["../../src/routes/objective-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EAGb,cAAc,EACd,UAAU,EACX,MAAM,gBAAgB,CAAC;AAExB;;2EAE2E;AAC3E,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,QAAQ,EAAE,MAAM,EAAE,GACjB;IACD,SAAS,CAAC,EAAE,cAAc,CAAC;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,WAAW,CAAC,EAAE,SAAS,UAAU,EAAE,CAAC;IACpC,KAAK,CAAC,EAAE;QAAE,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACnC,CAmBA;AAYD,iFAAiF;AACjF,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAEhD;;;kFAGkF;AAClF,wBAAgB,eAAe,CAC7B,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAAE,GACjB;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAavC;AA0BD;mEACmE;AACnE,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,cAAc,GAAG,SAAS,CAqD3F;AAqCD;;2EAE2E;AAC3E,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,QAAQ,EAAE,MAAM,EAAE,GACjB,aAAa,GAAG,SAAS,CA+F3B;AAoED;uCACuC;AACvC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAS,UAAU,EAAE,GAAG,SAAS,CAqCpG;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAUvG"}
|
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* unit-tested directly.
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DEFAULT_GRADE_PASS_THRESHOLD = void 0;
|
|
10
11
|
exports.parseRb1Fields = parseRb1Fields;
|
|
12
|
+
exports.parseGradeBlock = parseGradeBlock;
|
|
11
13
|
exports.parseObjective = parseObjective;
|
|
12
14
|
exports.parseBakeoffConfig = parseBakeoffConfig;
|
|
13
15
|
exports.parseValueChecks = parseValueChecks;
|
|
@@ -19,6 +21,9 @@ function parseRb1Fields(doc, route, candidates, problems) {
|
|
|
19
21
|
const objective = parseObjective(doc.objective, problems);
|
|
20
22
|
const bakeoff = parseBakeoffConfig(doc.bakeoff, candidates, problems);
|
|
21
23
|
const valueChecks = parseValueChecks(doc.value_checks, problems);
|
|
24
|
+
// Grade primitive (R2): the optional per-route pass threshold rides the same
|
|
25
|
+
// additive-route-knobs parse, keeping loader.ts under the LOC cap.
|
|
26
|
+
const grade = parseGradeBlock(doc.grade, problems);
|
|
22
27
|
// Only nag routes that OPT INTO RB-1 (declare objective/bakeoff) but omit a
|
|
23
28
|
// bound — a legacy route with neither block is not using regret bake-offs.
|
|
24
29
|
if (objective !== undefined || bakeoff !== undefined) {
|
|
@@ -30,6 +35,7 @@ function parseRb1Fields(doc, route, candidates, problems) {
|
|
|
30
35
|
...(objective !== undefined ? { objective } : {}),
|
|
31
36
|
...(bakeoff !== undefined ? { bakeoff } : {}),
|
|
32
37
|
...(valueChecks !== undefined ? { valueChecks } : {}),
|
|
38
|
+
...(grade !== undefined ? { grade } : {}),
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
41
|
const OBJECTIVE_MODES = new Set([
|
|
@@ -40,6 +46,28 @@ const OBJECTIVE_MODES = new Set([
|
|
|
40
46
|
function isRecord(v) {
|
|
41
47
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
42
48
|
}
|
|
49
|
+
/** Default grade pass threshold when a route declares no `grade:` block (R2). */
|
|
50
|
+
exports.DEFAULT_GRADE_PASS_THRESHOLD = 0.5;
|
|
51
|
+
/** Parse the optional `grade:` block (grade primitive, R2). Currently one knob,
|
|
52
|
+
* `pass_threshold` (0–1). Declared + validated here but UNREAD until GP-2 wires
|
|
53
|
+
* verdict derivation. Absent ⇒ undefined (⇒ the default 0.5 is applied downstream).
|
|
54
|
+
* A malformed value pushes a teaching problem, exactly like every other field. */
|
|
55
|
+
function parseGradeBlock(raw, problems) {
|
|
56
|
+
if (raw === undefined || raw === null)
|
|
57
|
+
return undefined;
|
|
58
|
+
if (!isRecord(raw)) {
|
|
59
|
+
problems.push("grade must be an object { pass_threshold: <0..1> }");
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
const t = raw.pass_threshold;
|
|
63
|
+
if (t === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
if (typeof t !== "number" || !Number.isFinite(t) || t < 0 || t > 1) {
|
|
66
|
+
problems.push(`grade.pass_threshold must be a number in [0, 1], got ${String(t)}`);
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
return { passThreshold: t };
|
|
70
|
+
}
|
|
43
71
|
function parsePriceCeiling(raw, field, problems) {
|
|
44
72
|
if (raw === undefined || raw === null)
|
|
45
73
|
return undefined;
|
|
@@ -222,15 +250,69 @@ function parseBakeoffConfig(raw, candidates, problems) {
|
|
|
222
250
|
pairwise = { judge: pwJudge };
|
|
223
251
|
}
|
|
224
252
|
}
|
|
253
|
+
// Q1 regret monitor (spec §5) + N4 upgrade watch (spec §4) — additive, optional.
|
|
254
|
+
const regretMonitor = parseRegretMonitor(raw.regret_monitor, problems);
|
|
255
|
+
let upgradeWatch;
|
|
256
|
+
if (raw.upgrade_watch !== undefined) {
|
|
257
|
+
if (typeof raw.upgrade_watch !== "boolean") {
|
|
258
|
+
problems.push("bakeoff.upgrade_watch must be a boolean");
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
upgradeWatch = raw.upgrade_watch;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// Teaching (spec §3 opt-in rule): a monitor/upgrade-watch with NO reference has
|
|
265
|
+
// nothing to measure against — warn (non-fatal), mirroring missingBoundWarning.
|
|
266
|
+
const noReference = reference === undefined;
|
|
267
|
+
if (noReference && (regretMonitor?.enabled === true || upgradeWatch === true)) {
|
|
268
|
+
console.warn(`modelrig: route bakeoff sets ${regretMonitor?.enabled === true ? "regret_monitor.enabled" : "upgrade_watch"}` +
|
|
269
|
+
" but declares no bakeoff.reference — there is no ceiling to measure regret against, so neither the" +
|
|
270
|
+
" regret monitor nor the up-swap watch can fire. Declare bakeoff.reference (auto or provider/model).");
|
|
271
|
+
}
|
|
225
272
|
const out = {
|
|
226
273
|
...(reference !== undefined ? { reference } : {}),
|
|
227
274
|
...(referenceAllowExternal ? { referenceAllowExternal: true } : {}),
|
|
228
275
|
...(referenceEnvelopeUsd !== undefined ? { referenceEnvelopeUsd } : {}),
|
|
229
276
|
...(judge !== undefined ? { judge } : {}),
|
|
230
277
|
...(pairwise !== undefined ? { pairwise } : {}),
|
|
278
|
+
...(regretMonitor !== undefined ? { regretMonitor } : {}),
|
|
279
|
+
...(upgradeWatch !== undefined ? { upgradeWatch } : {}),
|
|
231
280
|
};
|
|
232
281
|
return Object.freeze(out);
|
|
233
282
|
}
|
|
283
|
+
/** Parse `bakeoff.regret_monitor: { enabled, sample_n?, window_days?,
|
|
284
|
+
* baseline_days? }` (spec §5). Absent ⇒ undefined. Each numeric bound must be a
|
|
285
|
+
* positive integer when present. */
|
|
286
|
+
function parseRegretMonitor(raw, problems) {
|
|
287
|
+
if (raw === undefined || raw === null)
|
|
288
|
+
return undefined;
|
|
289
|
+
if (!isRecord(raw)) {
|
|
290
|
+
problems.push("bakeoff.regret_monitor must be an object { enabled, sample_n?, window_days?, baseline_days? }");
|
|
291
|
+
return undefined;
|
|
292
|
+
}
|
|
293
|
+
if (typeof raw.enabled !== "boolean") {
|
|
294
|
+
problems.push("bakeoff.regret_monitor.enabled must be a boolean");
|
|
295
|
+
return undefined;
|
|
296
|
+
}
|
|
297
|
+
const posInt = (v, field) => {
|
|
298
|
+
if (v === undefined)
|
|
299
|
+
return undefined;
|
|
300
|
+
if (typeof v !== "number" || !Number.isInteger(v) || v < 1) {
|
|
301
|
+
problems.push(`bakeoff.regret_monitor.${field} must be a positive integer`);
|
|
302
|
+
return undefined;
|
|
303
|
+
}
|
|
304
|
+
return v;
|
|
305
|
+
};
|
|
306
|
+
const sampleN = posInt(raw.sample_n, "sample_n");
|
|
307
|
+
const windowDays = posInt(raw.window_days, "window_days");
|
|
308
|
+
const baselineDays = posInt(raw.baseline_days, "baseline_days");
|
|
309
|
+
return Object.freeze({
|
|
310
|
+
enabled: raw.enabled,
|
|
311
|
+
...(sampleN !== undefined ? { sampleN } : {}),
|
|
312
|
+
...(windowDays !== undefined ? { windowDays } : {}),
|
|
313
|
+
...(baselineDays !== undefined ? { baselineDays } : {}),
|
|
314
|
+
});
|
|
315
|
+
}
|
|
234
316
|
/** Parse a `{ model, max_samples }` judge spec (shared by `bakeoff.judge` and
|
|
235
317
|
* `bakeoff.pairwise.judge`). Enforces #223 F3: the judge model must be a declared
|
|
236
318
|
* candidate. Returns the parsed spec, or undefined when absent/invalid (problems
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Route OUTPUT contract at load — the `schema:` file reader and the `output:`
|
|
3
|
+
* block (GitLab issue #1, incident 2026-10-11: a prose route had no way to say
|
|
4
|
+
* "my output is not JSON" and was rejected `content_invalid` on every call).
|
|
5
|
+
*
|
|
6
|
+
* Carved out of routes/loader.ts (which sits at the 700-LOC cap, dev-rule P1):
|
|
7
|
+
* `readSchema` is a PURE MOVE; `parseOutputBlock` is new.
|
|
8
|
+
*
|
|
9
|
+
* YAML forms accepted for `output:`:
|
|
10
|
+
* (absent) → json (the default; byte-identical)
|
|
11
|
+
* output: json → json (explicit; identical to absent)
|
|
12
|
+
* output: text → text (prose/markdown, returned verbatim)
|
|
13
|
+
* output: { kind: text, min_chars: N } → text with a declared length floor
|
|
14
|
+
* output: { kind: json } → json
|
|
15
|
+
*
|
|
16
|
+
* The parsed result OMITS `outputKind` for json so a JSON route's bundle (and
|
|
17
|
+
* its `bundle_sha`) is unchanged; only `text` is ever carried.
|
|
18
|
+
*/
|
|
19
|
+
import type { RepairPolicy, Requirement, RouteVariant } from "../types/route";
|
|
20
|
+
export declare const OUTPUT_KINDS: ReadonlySet<string>;
|
|
21
|
+
export declare const PROSE_DOCS_ANCHOR = "route-bundles.md#prose-and-markdown-output-output-text";
|
|
22
|
+
/** Resolve + parse the bundle's `schema:` file (null / absent ⇒ schema-less). */
|
|
23
|
+
export declare function readSchema(schemaRaw: unknown, bundleDir: string, problems: string[]): object | null;
|
|
24
|
+
export interface ParsedOutputBlock {
|
|
25
|
+
/** Present ONLY for `text` (json ⇒ omitted ⇒ byte-identical bundle). */
|
|
26
|
+
readonly outputKind?: "text";
|
|
27
|
+
readonly outputMinChars?: number;
|
|
28
|
+
}
|
|
29
|
+
/** What the loader already parsed that an `output: text` declaration must be
|
|
30
|
+
* consistent with — each conflict is a LOAD error that teaches, never a run-time
|
|
31
|
+
* surprise. */
|
|
32
|
+
export interface OutputBlockContext {
|
|
33
|
+
readonly outputSchema: object | null;
|
|
34
|
+
readonly schemaDeclared: boolean;
|
|
35
|
+
readonly require: readonly Requirement[];
|
|
36
|
+
readonly repair: RepairPolicy | undefined;
|
|
37
|
+
readonly variants: readonly RouteVariant[];
|
|
38
|
+
}
|
|
39
|
+
/** Parse the bundle's `output:` key. Pushes teaching problems; returns `{}` for
|
|
40
|
+
* json (absent / explicit) so the bundle spread adds nothing. */
|
|
41
|
+
export declare function parseOutputBlock(raw: unknown, ctx: OutputBlockContext, problems: string[]): ParsedOutputBlock;
|
|
42
|
+
//# sourceMappingURL=output-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-loader.d.ts","sourceRoot":"","sources":["../../src/routes/output-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAc,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE1F,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAAyC,CAAC;AAGvF,eAAO,MAAM,iBAAiB,2DAA2D,CAAC;AAM1F,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAsBnG;AAED,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;CAClC;AAED;;eAEe;AACf,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,YAAY,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;CAC5C;AAED;iEACiE;AACjE,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,kBAAkB,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAqD7G"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Route OUTPUT contract at load — the `schema:` file reader and the `output:`
|
|
4
|
+
* block (GitLab issue #1, incident 2026-10-11: a prose route had no way to say
|
|
5
|
+
* "my output is not JSON" and was rejected `content_invalid` on every call).
|
|
6
|
+
*
|
|
7
|
+
* Carved out of routes/loader.ts (which sits at the 700-LOC cap, dev-rule P1):
|
|
8
|
+
* `readSchema` is a PURE MOVE; `parseOutputBlock` is new.
|
|
9
|
+
*
|
|
10
|
+
* YAML forms accepted for `output:`:
|
|
11
|
+
* (absent) → json (the default; byte-identical)
|
|
12
|
+
* output: json → json (explicit; identical to absent)
|
|
13
|
+
* output: text → text (prose/markdown, returned verbatim)
|
|
14
|
+
* output: { kind: text, min_chars: N } → text with a declared length floor
|
|
15
|
+
* output: { kind: json } → json
|
|
16
|
+
*
|
|
17
|
+
* The parsed result OMITS `outputKind` for json so a JSON route's bundle (and
|
|
18
|
+
* its `bundle_sha`) is unchanged; only `text` is ever carried.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.PROSE_DOCS_ANCHOR = exports.OUTPUT_KINDS = void 0;
|
|
22
|
+
exports.readSchema = readSchema;
|
|
23
|
+
exports.parseOutputBlock = parseOutputBlock;
|
|
24
|
+
const node_fs_1 = require("node:fs");
|
|
25
|
+
const node_path_1 = require("node:path");
|
|
26
|
+
exports.OUTPUT_KINDS = new Set(["json", "text"]);
|
|
27
|
+
const OUTPUT_BLOCK_KEYS = new Set(["kind", "min_chars"]);
|
|
28
|
+
exports.PROSE_DOCS_ANCHOR = "route-bundles.md#prose-and-markdown-output-output-text";
|
|
29
|
+
function isRecord(v) {
|
|
30
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
31
|
+
}
|
|
32
|
+
/** Resolve + parse the bundle's `schema:` file (null / absent ⇒ schema-less). */
|
|
33
|
+
function readSchema(schemaRaw, bundleDir, problems) {
|
|
34
|
+
if (schemaRaw === null || schemaRaw === undefined)
|
|
35
|
+
return null;
|
|
36
|
+
if (typeof schemaRaw !== "string" || schemaRaw === "") {
|
|
37
|
+
problems.push("schema must be a relative path or null");
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const schemaPath = (0, node_path_1.resolve)(bundleDir, schemaRaw);
|
|
41
|
+
if (!(0, node_fs_1.existsSync)(schemaPath)) {
|
|
42
|
+
problems.push(`schema file not found: ${schemaRaw}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
try {
|
|
46
|
+
const parsed = JSON.parse((0, node_fs_1.readFileSync)(schemaPath, "utf8"));
|
|
47
|
+
if (!isRecord(parsed)) {
|
|
48
|
+
problems.push(`schema file ${schemaRaw} must contain a JSON object`);
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
problems.push(`schema file ${schemaRaw} is not valid JSON: ${err.message}`);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Parse the bundle's `output:` key. Pushes teaching problems; returns `{}` for
|
|
59
|
+
* json (absent / explicit) so the bundle spread adds nothing. */
|
|
60
|
+
function parseOutputBlock(raw, ctx, problems) {
|
|
61
|
+
if (raw === undefined || raw === null)
|
|
62
|
+
return {};
|
|
63
|
+
let kind;
|
|
64
|
+
let minChars;
|
|
65
|
+
if (typeof raw === "string") {
|
|
66
|
+
kind = raw;
|
|
67
|
+
}
|
|
68
|
+
else if (isRecord(raw)) {
|
|
69
|
+
for (const key of Object.keys(raw)) {
|
|
70
|
+
if (!OUTPUT_BLOCK_KEYS.has(key)) {
|
|
71
|
+
problems.push(`output.${key} is not a known key — the block is {kind: json|text, min_chars?: integer >= 1}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
kind = raw.kind;
|
|
75
|
+
if (raw.min_chars !== undefined) {
|
|
76
|
+
if (typeof raw.min_chars !== "number" || !Number.isInteger(raw.min_chars) || raw.min_chars < 1) {
|
|
77
|
+
problems.push("output.min_chars must be an integer >= 1");
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
minChars = raw.min_chars;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
problems.push(`output must be "json", "text", or {kind, min_chars?} — got ${JSON.stringify(raw)}`);
|
|
86
|
+
return {};
|
|
87
|
+
}
|
|
88
|
+
if (typeof kind !== "string" || !exports.OUTPUT_KINDS.has(kind)) {
|
|
89
|
+
problems.push(`output "${String(kind)}" is not one of [json, text] — write \`output: text\` for a prose/markdown route, ` +
|
|
90
|
+
`or omit it for JSON (the default)`);
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
if (kind === "json") {
|
|
94
|
+
if (minChars !== undefined)
|
|
95
|
+
problems.push("output.min_chars applies to output: text only — a JSON route conforms to its schema instead");
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
// kind === "text": the prose contract must not contradict the JSON machinery.
|
|
99
|
+
if (ctx.schemaDeclared || ctx.outputSchema !== null) {
|
|
100
|
+
problems.push("output: text cannot be combined with schema: — a prose route has no JSON Schema to conform to. " +
|
|
101
|
+
"Remove `schema:` (or set it to null), or drop `output: text` to serve JSON");
|
|
102
|
+
}
|
|
103
|
+
if (ctx.require.includes("schema_conformant")) {
|
|
104
|
+
problems.push("output: text cannot require schema_conformant — there is no schema; remove it from `require`");
|
|
105
|
+
}
|
|
106
|
+
const repairDeclared = ctx.repair !== undefined || ctx.variants.some((v) => v.repair !== undefined);
|
|
107
|
+
if (repairDeclared) {
|
|
108
|
+
problems.push("repair: is the JSON repair rung and never runs on an output: text route — remove it (a prose " +
|
|
109
|
+
"response that fails min_chars is retried from the content_invalid budget instead)");
|
|
110
|
+
}
|
|
111
|
+
return { outputKind: "text", ...(minChars !== undefined ? { outputMinChars: minChars } : {}) };
|
|
112
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bundle's `prompt:` block at load — `prompt.system`, the per-call
|
|
3
|
+
* `prompt.user` (GitLab issue #5, R1), and `prompt.variables`.
|
|
4
|
+
*
|
|
5
|
+
* Carved out of routes/loader.ts (which sits at the 700-LOC cap, dev-rule P1):
|
|
6
|
+
* the `prompt.system` + `variables` handling is a PURE MOVE; `prompt.user` and
|
|
7
|
+
* the cache/system-only advisory are new.
|
|
8
|
+
*
|
|
9
|
+
* YAML forms accepted for `prompt:`:
|
|
10
|
+
* prompt: { system: <path>, variables: [...] } → today (byte-identical)
|
|
11
|
+
* prompt: { system: <path>, user: <path>, variables: [...] } → system + per-call user turn
|
|
12
|
+
* prompt: { user: <path>, variables: [...] } → user turn only (empty system)
|
|
13
|
+
*
|
|
14
|
+
* Both templates are files relative to the bundle (same rule as `schema:`);
|
|
15
|
+
* both render with the same variables, capability conditionals and `x-trust`
|
|
16
|
+
* removal. `prompt.user` must be a non-empty file — an empty user turn next to
|
|
17
|
+
* a cache handle would send the handle and nothing else, the exact trap R1
|
|
18
|
+
* closes.
|
|
19
|
+
*/
|
|
20
|
+
import type { CandidateSpec } from "../types/route";
|
|
21
|
+
export declare const CACHE_PROMPT_DOCS_ANCHOR = "caching-lifecycle.md#a-cache-handle-changes-where-the-template-is-delivered";
|
|
22
|
+
export interface ParsedPromptBlock {
|
|
23
|
+
readonly systemTemplate: string;
|
|
24
|
+
/** Present ONLY when `prompt.user` was declared (absent ⇒ byte-identical bundle). */
|
|
25
|
+
readonly userTemplate?: string;
|
|
26
|
+
readonly variables: readonly string[];
|
|
27
|
+
readonly variableTrust?: Record<string, "untrusted">;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Parse the bundle's `prompt:` block. `prompt.system` stays REQUIRED unless
|
|
31
|
+
* `prompt.user` is declared (a user-turn-only route has an empty system
|
|
32
|
+
* template — the shape a Gemini cache handle wants, since the cache already
|
|
33
|
+
* holds the system content). Returns `systemTemplate: ""` on any problem so the
|
|
34
|
+
* caller's later checks stay total; the collected problems fail the load.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parsePromptBlock(raw: unknown, bundleDir: string, problems: string[]): ParsedPromptBlock;
|
|
37
|
+
/**
|
|
38
|
+
* Issue #5 (R1) advisory, P4 "errors teach": a route that opts into caching
|
|
39
|
+
* (`cache: auto`) AND has a Gemini candidate AND renders a non-empty system
|
|
40
|
+
* template with NO `prompt.user` is the shape that loses content the moment a
|
|
41
|
+
* customer passes a Gemini cache handle on `rig.run` — the handle forbids
|
|
42
|
+
* `systemInstruction`, so the rendered template is delivered as the user turn
|
|
43
|
+
* (never dropped), but the author almost certainly meant the cache to hold the
|
|
44
|
+
* prefix and `prompt.user` to hold the delta. Warn once at load naming the
|
|
45
|
+
* rule. Non-fatal: the route loads and serves as declared. Pure — unit-tested
|
|
46
|
+
* directly. Returns the warning line, or null.
|
|
47
|
+
*/
|
|
48
|
+
export declare function cachedRouteSystemOnlyWarning(route: string, cache: boolean, candidates: readonly CandidateSpec[], systemTemplate: string, userTemplate: string | undefined): string | null;
|
|
49
|
+
//# sourceMappingURL=prompt-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-loader.d.ts","sourceRoot":"","sources":["../../src/routes/prompt-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGpD,eAAO,MAAM,wBAAwB,gFAAgF,CAAC;AAMtH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,qFAAqF;IACrF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;CACtD;AAkBD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAiCvG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,OAAO,EACd,UAAU,EAAE,SAAS,aAAa,EAAE,EACpC,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,IAAI,CAYf"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The bundle's `prompt:` block at load — `prompt.system`, the per-call
|
|
4
|
+
* `prompt.user` (GitLab issue #5, R1), and `prompt.variables`.
|
|
5
|
+
*
|
|
6
|
+
* Carved out of routes/loader.ts (which sits at the 700-LOC cap, dev-rule P1):
|
|
7
|
+
* the `prompt.system` + `variables` handling is a PURE MOVE; `prompt.user` and
|
|
8
|
+
* the cache/system-only advisory are new.
|
|
9
|
+
*
|
|
10
|
+
* YAML forms accepted for `prompt:`:
|
|
11
|
+
* prompt: { system: <path>, variables: [...] } → today (byte-identical)
|
|
12
|
+
* prompt: { system: <path>, user: <path>, variables: [...] } → system + per-call user turn
|
|
13
|
+
* prompt: { user: <path>, variables: [...] } → user turn only (empty system)
|
|
14
|
+
*
|
|
15
|
+
* Both templates are files relative to the bundle (same rule as `schema:`);
|
|
16
|
+
* both render with the same variables, capability conditionals and `x-trust`
|
|
17
|
+
* removal. `prompt.user` must be a non-empty file — an empty user turn next to
|
|
18
|
+
* a cache handle would send the handle and nothing else, the exact trap R1
|
|
19
|
+
* closes.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.CACHE_PROMPT_DOCS_ANCHOR = void 0;
|
|
23
|
+
exports.parsePromptBlock = parsePromptBlock;
|
|
24
|
+
exports.cachedRouteSystemOnlyWarning = cachedRouteSystemOnlyWarning;
|
|
25
|
+
const node_fs_1 = require("node:fs");
|
|
26
|
+
const node_path_1 = require("node:path");
|
|
27
|
+
const screen_loader_1 = require("./screen-loader");
|
|
28
|
+
exports.CACHE_PROMPT_DOCS_ANCHOR = "caching-lifecycle.md#a-cache-handle-changes-where-the-template-is-delivered";
|
|
29
|
+
function isRecord(v) {
|
|
30
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
31
|
+
}
|
|
32
|
+
/** Read a template file named by `prompt.<key>` relative to the bundle. Pushes
|
|
33
|
+
* a teaching problem and returns null when the key is not a path or the file is
|
|
34
|
+
* missing. */
|
|
35
|
+
function readTemplateFile(raw, key, bundleDir, problems) {
|
|
36
|
+
if (typeof raw !== "string" || raw === "") {
|
|
37
|
+
problems.push(`prompt.${key} must be a relative path`);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
const path = (0, node_path_1.resolve)(bundleDir, raw);
|
|
41
|
+
if (!(0, node_fs_1.existsSync)(path)) {
|
|
42
|
+
problems.push(`prompt.${key} file not found: ${raw}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return (0, node_fs_1.readFileSync)(path, "utf8");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Parse the bundle's `prompt:` block. `prompt.system` stays REQUIRED unless
|
|
49
|
+
* `prompt.user` is declared (a user-turn-only route has an empty system
|
|
50
|
+
* template — the shape a Gemini cache handle wants, since the cache already
|
|
51
|
+
* holds the system content). Returns `systemTemplate: ""` on any problem so the
|
|
52
|
+
* caller's later checks stay total; the collected problems fail the load.
|
|
53
|
+
*/
|
|
54
|
+
function parsePromptBlock(raw, bundleDir, problems) {
|
|
55
|
+
if (!isRecord(raw)) {
|
|
56
|
+
problems.push("prompt.system must be a relative path");
|
|
57
|
+
return { systemTemplate: "", variables: [] };
|
|
58
|
+
}
|
|
59
|
+
const userDeclared = raw.user !== undefined && raw.user !== null;
|
|
60
|
+
let systemTemplate = "";
|
|
61
|
+
if (raw.system !== undefined && raw.system !== null) {
|
|
62
|
+
systemTemplate = readTemplateFile(raw.system, "system", bundleDir, problems) ?? "";
|
|
63
|
+
}
|
|
64
|
+
else if (!userDeclared) {
|
|
65
|
+
problems.push("prompt.system must be a relative path");
|
|
66
|
+
}
|
|
67
|
+
let userTemplate;
|
|
68
|
+
if (userDeclared) {
|
|
69
|
+
const text = readTemplateFile(raw.user, "user", bundleDir, problems);
|
|
70
|
+
if (text !== null) {
|
|
71
|
+
if (text.trim() === "") {
|
|
72
|
+
problems.push(`prompt.user file is empty: ${String(raw.user)} — the user turn must carry content (with a cache handle ` +
|
|
73
|
+
`it is the ONLY per-call content the model sees; omit prompt.user to keep the fixed trigger)`);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
userTemplate = text;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const parsed = (0, screen_loader_1.parseVariables)(raw.variables ?? [], problems);
|
|
81
|
+
return {
|
|
82
|
+
systemTemplate,
|
|
83
|
+
...(userTemplate !== undefined ? { userTemplate } : {}),
|
|
84
|
+
variables: parsed.names,
|
|
85
|
+
...(parsed.trust !== undefined ? { variableTrust: parsed.trust } : {}),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Issue #5 (R1) advisory, P4 "errors teach": a route that opts into caching
|
|
90
|
+
* (`cache: auto`) AND has a Gemini candidate AND renders a non-empty system
|
|
91
|
+
* template with NO `prompt.user` is the shape that loses content the moment a
|
|
92
|
+
* customer passes a Gemini cache handle on `rig.run` — the handle forbids
|
|
93
|
+
* `systemInstruction`, so the rendered template is delivered as the user turn
|
|
94
|
+
* (never dropped), but the author almost certainly meant the cache to hold the
|
|
95
|
+
* prefix and `prompt.user` to hold the delta. Warn once at load naming the
|
|
96
|
+
* rule. Non-fatal: the route loads and serves as declared. Pure — unit-tested
|
|
97
|
+
* directly. Returns the warning line, or null.
|
|
98
|
+
*/
|
|
99
|
+
function cachedRouteSystemOnlyWarning(route, cache, candidates, systemTemplate, userTemplate) {
|
|
100
|
+
if (!cache)
|
|
101
|
+
return null;
|
|
102
|
+
if (userTemplate !== undefined)
|
|
103
|
+
return null;
|
|
104
|
+
if (systemTemplate.trim() === "")
|
|
105
|
+
return null;
|
|
106
|
+
if (!candidates.some((c) => c.provider === "gemini"))
|
|
107
|
+
return null;
|
|
108
|
+
return (`route "${route}" declares cache: with a Gemini candidate, a non-empty prompt.system and no prompt.user. ` +
|
|
109
|
+
`A Gemini cache handle (rig.run(..., { cache: { key, provider: "gemini" } })) forbids systemInstruction, so ` +
|
|
110
|
+
`on a cached dispatch the rendered system template is delivered AS THE USER TURN (prompt_delivery: ` +
|
|
111
|
+
`"user+cache") — never dropped, but probably not what you meant. Put the shared prefix in the cache ` +
|
|
112
|
+
`resource and the per-call delta in a \`prompt.user\` template (see ${exports.CACHE_PROMPT_DOCS_ANCHOR}).`);
|
|
113
|
+
}
|
|
@@ -25,6 +25,9 @@
|
|
|
25
25
|
* schema it fingerprints.
|
|
26
26
|
*/
|
|
27
27
|
import type { LoadedRoutes } from "./loader";
|
|
28
|
+
import type { ScreenPolicy } from "../screen/types";
|
|
29
|
+
import type { ResolvedMaskPolicy } from "../mask/types";
|
|
30
|
+
import type { Manifest } from "../prompts/manifest";
|
|
28
31
|
import type { CandidateSpec, Preference, RepairPolicy, Requirement, RouteBundle, RoutePolicy, RouteVariant } from "../types/route";
|
|
29
32
|
/**
|
|
30
33
|
* The canonical, JSON-serialisable form of a resolved route bundle. Every field
|
|
@@ -37,21 +40,87 @@ export interface ResolvedRouteBundle {
|
|
|
37
40
|
readonly version: number;
|
|
38
41
|
/** Resolved, parsed JSON Schema (null = unstructured route). Inlined at sync. */
|
|
39
42
|
readonly outputSchema: object | null;
|
|
43
|
+
/** Issue #1 — `output: text`. Carried ONLY as `"text"` (a json route omits the
|
|
44
|
+
* key, so its `bundle_sha` is unchanged); the hosted/mirror lane rebuilds the
|
|
45
|
+
* same prose contract and never JSON-parses the response. `outputMinChars` is
|
|
46
|
+
* the declared floor, text routes only. Absent ⇒ json ⇒ byte-identical. */
|
|
47
|
+
readonly outputKind?: "text";
|
|
48
|
+
readonly outputMinChars?: number;
|
|
40
49
|
readonly candidates: readonly CandidateSpec[];
|
|
41
50
|
readonly require: readonly Requirement[];
|
|
42
51
|
readonly prefer: readonly Preference[];
|
|
43
52
|
/** Raw template text — the prompt FILE, inlined at sync. */
|
|
44
53
|
readonly systemTemplate: string;
|
|
54
|
+
/** Issue #5 (R1) — the per-call `prompt.user` template, inlined at sync and
|
|
55
|
+
* carried ONLY when declared (absent ⇒ the fixed trigger ⇒ unchanged
|
|
56
|
+
* `bundle_sha`), so the hosted/mirror lane renders the same user turn and a
|
|
57
|
+
* cache handle composes there too. */
|
|
58
|
+
readonly userTemplate?: string;
|
|
45
59
|
readonly variables: readonly string[];
|
|
46
60
|
readonly policy: RoutePolicy;
|
|
47
61
|
readonly repair?: RepairPolicy;
|
|
48
62
|
readonly variants: readonly RouteVariant[];
|
|
49
63
|
readonly capture: boolean;
|
|
50
64
|
readonly groundingQuery?: string;
|
|
65
|
+
/** S1 grounding assembly mode (`legacy` | `spotlight`). Carried so a route's
|
|
66
|
+
* spotlight opt-in survives to the hosted (mirror) lane. Absent ⇒ legacy. */
|
|
67
|
+
readonly groundingAssembly?: "legacy" | "spotlight";
|
|
68
|
+
/** S2 per-variable `x-trust` annotation. S3 mirror plumbing (spec §11.3, gap
|
|
69
|
+
* #3): previously DROPPED on the round-trip, so any bundle-borne trust signal
|
|
70
|
+
* was `undefined` on every mirror-lane run. Carried now so route `x-trust`
|
|
71
|
+
* annotations survive to the hosted lane. Absent ⇒ every variable stays `semi`
|
|
72
|
+
* (byte-identical). */
|
|
73
|
+
readonly variableTrust?: Readonly<Record<string, "untrusted">>;
|
|
74
|
+
/** SC-1b mirror fix (spec §4, SC-1b req 1 — the #322 QA finding). Previously
|
|
75
|
+
* DROPPED on the round-trip: `route.screen` was `undefined` on every
|
|
76
|
+
* mirror-lane run, so screening was silently INERT (a fail-open) — an
|
|
77
|
+
* `enforce` route did not screen at all on the hosted lane. Carried now as the
|
|
78
|
+
* RAW `ScreenPolicy` (the serialisable `.policy` — the built detector closures
|
|
79
|
+
* on `ResolvedScreenPolicy` cannot cross the wire); `bundleFromResolved`
|
|
80
|
+
* RE-RESOLVES it with `resolveScreenPolicy`, which always rebuilds the T0
|
|
81
|
+
* pattern detector deterministically. Absent ⇒ no screening (byte-identical).
|
|
82
|
+
* A `screen: enforce` route that relies on a T1 `classifier:` detector is
|
|
83
|
+
* REFUSED at export by {@link assertMirrorSafe} (weights can't be guaranteed on
|
|
84
|
+
* the gateway ⇒ it would silently degrade to T0 — never a silent inert
|
|
85
|
+
* enforce). */
|
|
86
|
+
readonly screenPolicy?: ScreenPolicy;
|
|
87
|
+
/** SC-1b mirror fix (spec §3, SC-1b req 1). The `mask:` block had the IDENTICAL
|
|
88
|
+
* drop gap — `route.mask` was `undefined` on the mirror lane, so masking was
|
|
89
|
+
* silently INERT. Carried now as the FULLY-RESOLVED policy: unlike screen, a
|
|
90
|
+
* `ResolvedMaskPolicy` has its dictionary `entries` INLINED and is fully
|
|
91
|
+
* serialisable, so it is passed straight through (no re-resolve, no filesystem
|
|
92
|
+
* on the gateway) and re-materialises byte-identically — so `mask: block`
|
|
93
|
+
* always re-resolves on the mirror and needs no export refusal. Absent ⇒ no
|
|
94
|
+
* masking (byte-identical). */
|
|
95
|
+
readonly mask?: ResolvedMaskPolicy;
|
|
96
|
+
/** PSR-2 (spec §2.1/§3) — the served prompt's assembly manifest (structure-only).
|
|
97
|
+
* A promote writes the promoted `prompt_versions` row's `manifest` through into
|
|
98
|
+
* `routes.bundle` alongside the `systemTemplate`, and recomputes `bundle_sha`
|
|
99
|
+
* over this whole object — so the served projection carries the manifest the
|
|
100
|
+
* client-fill engine (PSR-2b) resolves against. Absent ⇒ no PSR manifest
|
|
101
|
+
* (byte-identical to a pre-PSR mirror). Additive & optional. */
|
|
102
|
+
readonly manifest?: Manifest;
|
|
51
103
|
}
|
|
52
104
|
/** Project an already-loaded (resolved) bundle to its serialisable form. Pure —
|
|
53
105
|
* no filesystem; the loader already followed every file reference. */
|
|
54
106
|
export declare function resolveRouteBundle(bundle: RouteBundle): ResolvedRouteBundle;
|
|
107
|
+
/**
|
|
108
|
+
* Refuse-on-export guard (SC-1b req 1 — the #322 QA finding). A route that
|
|
109
|
+
* declares `screen: enforce` MUST be guaranteed to re-resolve its enforcement on
|
|
110
|
+
* the hosted (mirror) lane, or the hosted lane silently fails open. The mirror
|
|
111
|
+
* rebuilds the screen policy with `resolveScreenPolicy`, which ALWAYS builds the
|
|
112
|
+
* T0 pattern detector deterministically (no filesystem) — so a pure-T0 enforce
|
|
113
|
+
* policy re-resolves identically and mirrors safely. A T1 `classifier:` detector,
|
|
114
|
+
* though, depends on gateway-local weights the mirror cannot guarantee: there it
|
|
115
|
+
* would DEGRADE to T0 SILENTLY, weaker than what was authored and proven. Rather
|
|
116
|
+
* than ship a silently-degraded enforce we REFUSE at export with a teaching
|
|
117
|
+
* error. `mask` needs no guard: its resolved policy (dictionary entries inlined)
|
|
118
|
+
* crosses the wire whole and re-materialises identically.
|
|
119
|
+
*
|
|
120
|
+
* Called from the exporter (`buildExportedRouteMirrors`) — a hard failure at
|
|
121
|
+
* SYNC, on the developer's machine, never a silent inert enforce at request.
|
|
122
|
+
*/
|
|
123
|
+
export declare function assertMirrorSafe(bundle: RouteBundle): void;
|
|
55
124
|
/** The canonical serialisation whose hash becomes `bundle_sha`. */
|
|
56
125
|
export declare function canonicalBundleJson(bundle: ResolvedRouteBundle): string;
|
|
57
126
|
/** Content hash of the canonical bundle — `sha256:<hex>`. Self-describing so a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolved-bundle.d.ts","sourceRoot":"","sources":["../../src/routes/resolved-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"resolved-bundle.d.ts","sourceRoot":"","sources":["../../src/routes/resolved-bundle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EACV,aAAa,EACb,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,WAAW,EACX,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,iFAAiF;IACjF,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC;;;+EAG2E;IAC3E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,UAAU,EAAE,SAAS,aAAa,EAAE,CAAC;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,4DAA4D;IAC5D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC;;;0CAGsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC;iFAC6E;IAC7E,QAAQ,CAAC,iBAAiB,CAAC,EAAE,QAAQ,GAAG,WAAW,CAAC;IACpD;;;;2BAIuB;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IAC/D;;;;;;;;;;;mBAWe;IACf,QAAQ,CAAC,YAAY,CAAC,EAAE,YAAY,CAAC;IACrC;;;;;;;mCAO+B;IAC/B,QAAQ,CAAC,IAAI,CAAC,EAAE,kBAAkB,CAAC;IACnC;;;;;oEAKgE;IAChE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;sEACsE;AACtE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,mBAAmB,CA8B3E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI,CAe1D;AAiBD,mEAAmE;AACnE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEvE;AAED;gFACgF;AAChF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,WAAW,CAoE5D;AAED;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,YAAY,CAclE"}
|