@danceiny/gotry 0.0.1-rc.9 → 0.2.0-rc.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +172 -219
- package/README.zh-CN.md +222 -0
- package/bin/gotry-backend.js +53 -0
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +1744 -0
- package/bin/gotry-inner.js +733 -83
- package/bin/gotry-process-liveness.d.ts +27 -0
- package/bin/gotry-process-liveness.js +97 -0
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +49 -0
- package/bin/gotry.js +1 -1
- package/client/client.js +203 -0
- package/cordis.gotry-patch.yml +80 -56
- package/data/airline-airports.json +39 -0
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach-deep.js +45 -122
- package/dist/capabilities/agent-reach.js +101 -146
- package/dist/capabilities/anything.js +135 -94
- package/dist/capabilities/artifacts.js +370 -0
- package/dist/capabilities/channel-health.js +131 -0
- package/dist/capabilities/channel-registry.js +256 -0
- package/dist/capabilities/doctor.js +546 -0
- package/dist/capabilities/effect.js +394 -0
- package/dist/capabilities/external-event.js +149 -0
- package/dist/capabilities/fact-log.js +55 -0
- package/dist/capabilities/flyai-config.js +337 -0
- package/dist/capabilities/flyai.js +947 -110
- package/dist/capabilities/fx-contract.js +293 -0
- package/dist/capabilities/geo-atlas.js +246 -0
- package/dist/capabilities/ground-transfer.js +509 -0
- package/dist/capabilities/hbcli.js +260 -123
- package/dist/capabilities/hotelbyte-transaction.js +194 -0
- package/dist/capabilities/incident-log.js +131 -61
- package/dist/capabilities/itinerary-artifact.js +190 -0
- package/dist/capabilities/itinerary-deck-artifact.js +194 -0
- package/dist/capabilities/itinerary-deck-export.js +339 -0
- package/dist/capabilities/lavish-local.js +924 -0
- package/dist/capabilities/model-override.js +38 -0
- package/dist/capabilities/opensky.js +54 -43
- package/dist/capabilities/resilience.js +191 -0
- package/dist/capabilities/session/action-cache.js +50 -44
- package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
- package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
- package/dist/capabilities/session/adapters/dida-portal.js +274 -0
- package/dist/capabilities/session/adapters/meituan-local.js +35 -54
- package/dist/capabilities/session/adapters/rail-12306.js +342 -0
- package/dist/capabilities/session/benchmark.js +189 -0
- package/dist/capabilities/session/bridge-ledger.js +224 -0
- package/dist/capabilities/session/extension-bridge.js +636 -0
- package/dist/capabilities/session/extension-channel.js +109 -0
- package/dist/capabilities/session/extension-distribution.js +230 -0
- package/dist/capabilities/session/extract.js +31 -21
- package/dist/capabilities/session/golden-score.js +114 -0
- package/dist/capabilities/session/health-watch.js +215 -0
- package/dist/capabilities/session/read-guard.js +75 -24
- package/dist/capabilities/session/static-flight-golden.js +150 -0
- package/dist/capabilities/session/transport.js +97 -83
- package/dist/capabilities/session/wizard.js +117 -0
- package/dist/capabilities/session-consent.js +178 -0
- package/dist/capabilities/session-login.js +170 -0
- package/dist/capabilities/session-search.js +635 -44
- package/dist/capabilities/spawn-bounded.js +203 -0
- package/dist/capabilities/sponsor-plugin.js +341 -0
- package/dist/capabilities/visa-policy.js +140 -0
- package/dist/capabilities/weather.js +243 -138
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +103 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +24 -59
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
- package/dist/scripts/agent-reach-deep-tests.js +30 -40
- package/dist/scripts/agent-reach-error-tests.js +354 -0
- package/dist/scripts/agent-reach-tests.js +26 -18
- package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
- package/dist/scripts/anything-tests.js +116 -60
- package/dist/scripts/artifact-client-contract-tests.js +220 -0
- package/dist/scripts/artifacts-capability-tests.js +727 -0
- package/dist/scripts/async-collect.js +50 -11
- package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
- package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
- package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
- package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
- package/dist/scripts/booking-copilot-dsh-warmer-proof.js +123 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
- package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
- package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
- package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
- package/dist/scripts/booking-executor-tests.js +80 -0
- package/dist/scripts/booking-recovery-chain-tests.js +182 -0
- package/dist/scripts/booking-saga-tests.js +125 -0
- package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
- package/dist/scripts/bootstrap-tests.js +1479 -0
- package/dist/scripts/bridge-events-tests.js +239 -0
- package/dist/scripts/bridge-ledger-tests.js +428 -0
- package/dist/scripts/build-changelog.js +238 -0
- package/dist/scripts/build-metrics-report.js +331 -0
- package/dist/scripts/changelog-tests.js +118 -0
- package/dist/scripts/channel-probe-tests.js +103 -0
- package/dist/scripts/channel-probe.js +169 -0
- package/dist/scripts/channel-registry-tests.js +208 -0
- package/dist/scripts/companion-tests.js +25 -70
- package/dist/scripts/dida-cookie-probe.js +87 -0
- package/dist/scripts/dida-runner-stop-tests.js +311 -0
- package/dist/scripts/dida-sw-probe.js +114 -0
- package/dist/scripts/diff-test.js +17 -12
- package/dist/scripts/doctor-tests.js +564 -0
- package/dist/scripts/dsh-artifact-e2e.js +279 -0
- package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
- package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
- package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
- package/dist/scripts/dsh-runtime-closure.js +162 -0
- package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
- package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
- package/dist/scripts/dsh-target-closure-proof.js +178 -0
- package/dist/scripts/effect-tests.js +539 -0
- package/dist/scripts/engine-run.js +1 -3
- package/dist/scripts/engine-tests.js +16 -10
- package/dist/scripts/evaluation-cadence-tests.js +174 -0
- package/dist/scripts/evaluation-contract-tests.js +268 -0
- package/dist/scripts/extension-distribution-cli.js +39 -0
- package/dist/scripts/extension-distribution-tests.js +443 -0
- package/dist/scripts/extension-tests.js +988 -0
- package/dist/scripts/external-event-tests.js +350 -0
- package/dist/scripts/fact-gate-tests.js +869 -0
- package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
- package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
- package/dist/scripts/flight-malformed-tests.js +159 -0
- package/dist/scripts/flyai-setup-tests.js +228 -0
- package/dist/scripts/flyai-setup-tool-tests.js +54 -0
- package/dist/scripts/flyai-tests.js +692 -0
- package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
- package/dist/scripts/fx-contract-tests.js +201 -0
- package/dist/scripts/g5-guard-tests.js +131 -0
- package/dist/scripts/g5-guard.js +189 -0
- package/dist/scripts/gen-lunar-anchors.js +106 -0
- package/dist/scripts/geo-atlas-tests.js +283 -0
- package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
- package/dist/scripts/gotry-try-demo-tests.js +79 -0
- package/dist/scripts/gotry-try-demo.js +49 -0
- package/dist/scripts/ground-transfer-tests.js +956 -0
- package/dist/scripts/hbcli-e2e-tests.js +159 -0
- package/dist/scripts/hbcli-live-optin-tests.js +96 -0
- package/dist/scripts/hbcli-release-contract-tests.js +122 -0
- package/dist/scripts/hbcli-tests.js +121 -69
- package/dist/scripts/health-watch-cli.js +73 -0
- package/dist/scripts/hotel-date-gate-tests.js +496 -0
- package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
- package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
- package/dist/scripts/i18n-tests.js +41 -0
- package/dist/scripts/incident-tests.js +281 -87
- package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
- package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
- package/dist/scripts/issue-271-liveness-tests.js +569 -0
- package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
- package/dist/scripts/issue-289-model-retry-tests.js +441 -0
- package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
- package/dist/scripts/issue-338-home-city-e2e.js +577 -0
- package/dist/scripts/issue343-real-entry-e2e.js +160 -0
- package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
- package/dist/scripts/itinerary-artifact-tests.js +368 -0
- package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
- package/dist/scripts/itinerary-deck-export-tests.js +552 -0
- package/dist/scripts/itinerary-deck-tests.js +435 -0
- package/dist/scripts/itinerary-html-tests.js +426 -0
- package/dist/scripts/journey-tests.js +22 -27
- package/dist/scripts/kernel-manifest-evidence.js +109 -0
- package/dist/scripts/kernel-manifest-gate.js +126 -0
- package/dist/scripts/kernel-manifest-tests.js +212 -0
- package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
- package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
- package/dist/scripts/kernel-manifest.js +369 -0
- package/dist/scripts/lavish-local-tests.js +1226 -0
- package/dist/scripts/lavish-product-tools-tests.js +537 -0
- package/dist/scripts/ledger-repair-apply-tests.js +316 -0
- package/dist/scripts/ledger-repair-plan-tests.js +375 -0
- package/dist/scripts/ledger-tests.js +382 -246
- package/dist/scripts/ledger-workflow-crash.js +10 -20
- package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
- package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
- package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
- package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
- package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
- package/dist/scripts/memory-capture-tests.js +242 -61
- package/dist/scripts/memory-decay-tests.js +18 -52
- package/dist/scripts/memory-lifecycle-tests.js +657 -0
- package/dist/scripts/memory-lifecycle.js +196 -0
- package/dist/scripts/memory-metrics.js +24 -12
- package/dist/scripts/memory-value-report.js +631 -0
- package/dist/scripts/memory-value-tests.js +328 -0
- package/dist/scripts/metrics-report-tests.js +151 -0
- package/dist/scripts/model-override-e2e.js +137 -0
- package/dist/scripts/nightly-evidence-tests.js +161 -0
- package/dist/scripts/nightly-evidence.js +286 -0
- package/dist/scripts/nudge-digest.js +39 -28
- package/dist/scripts/observability-tests.js +381 -0
- package/dist/scripts/onboarding-tests.js +161 -0
- package/dist/scripts/opensky-check.js +18 -13
- package/dist/scripts/opensky-tests.js +28 -28
- package/dist/scripts/persona-surface-guard-tests.js +49 -0
- package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
- package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
- package/dist/scripts/price-drift-tests.js +340 -0
- package/dist/scripts/price-drift-watch.js +447 -0
- package/dist/scripts/probe-poi-tests.js +53 -45
- package/dist/scripts/product-metrics.js +483 -0
- package/dist/scripts/publish-preverify.js +110 -0
- package/dist/scripts/realtime-pricing-tests.js +76 -0
- package/dist/scripts/recall-tests.js +513 -0
- package/dist/scripts/replay-async.js +20 -18
- package/dist/scripts/replay-real.js +18 -18
- package/dist/scripts/replay.js +52 -82
- package/dist/scripts/session-attach-diagnose.js +20 -20
- package/dist/scripts/session-attach-poc.js +34 -37
- package/dist/scripts/session-benchmark.js +180 -0
- package/dist/scripts/session-dida-live-e2e.js +199 -0
- package/dist/scripts/session-extract-tests.js +14 -35
- package/dist/scripts/session-link-tests.js +478 -0
- package/dist/scripts/session-login.js +27 -46
- package/dist/scripts/session-tests.js +796 -96
- package/dist/scripts/session-zones-tests.js +358 -0
- package/dist/scripts/sf-live-benchmark.js +367 -0
- package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
- package/dist/scripts/sf-live-cli-tests.js +92 -0
- package/dist/scripts/sf-live-options.js +46 -0
- package/dist/scripts/sf-manifest-tests.js +30 -0
- package/dist/scripts/sf-manifest.js +33 -0
- package/dist/scripts/sf-soft-score-tests.js +67 -0
- package/dist/scripts/sf-summary-tests.js +324 -0
- package/dist/scripts/sf-summary.js +525 -0
- package/dist/scripts/share-tests.js +432 -0
- package/dist/scripts/skeleton-check.js +16 -14
- package/dist/scripts/skeleton-integration-test.js +28 -11
- package/dist/scripts/skills-contract-tests.js +51 -46
- package/dist/scripts/smoke-session-gate-tests.js +21 -0
- package/dist/scripts/smoke.js +690 -246
- package/dist/scripts/spawn-bounded-abort-tests.js +241 -0
- package/dist/scripts/sponsor-reuse-tests.js +262 -0
- package/dist/scripts/state-cli-tests.js +226 -101
- package/dist/scripts/state-cli.js +550 -199
- package/dist/scripts/state-repair-cli.js +66 -0
- package/dist/scripts/state-repair-tests.js +140 -0
- package/dist/scripts/static-golden-tests.js +165 -0
- package/dist/scripts/time-eval-tests.js +210 -192
- package/dist/scripts/travel-timeline-tests.js +29 -93
- package/dist/scripts/turn-handoff-collect-tests.js +169 -0
- package/dist/scripts/turn-handoff-collect.js +161 -0
- package/dist/scripts/turn-policy-tests.js +55 -0
- package/dist/scripts/typed-contract-canary.js +176 -0
- package/dist/scripts/tz-resolver-sanity.js +50 -0
- package/dist/scripts/tz-resolver-tests.js +584 -0
- package/dist/scripts/unified-tests.js +23 -19
- package/dist/scripts/visa-policy-tests.js +62 -0
- package/dist/scripts/weather-tests.js +276 -41
- package/dist/scripts/wish-channel-gate-tests.js +54 -0
- package/dist/scripts/write-gate-tests.js +522 -0
- package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
- package/dist/scripts/z3-lifecycle-tests.js +170 -0
- package/dist/scripts/z3-race-repeat-tests.js +39 -0
- package/dist/scripts/z3-race-tests.js +41 -0
- package/dist/src/artifact-gate.js +829 -0
- package/dist/src/backend/kernel.js +91 -0
- package/dist/src/backend/modules/booking-copilot.js +92 -0
- package/dist/src/backend/modules/booking-executor.js +124 -0
- package/dist/src/backend/modules/session-search.js +551 -0
- package/dist/src/benchmark-agent-conformance.js +578 -0
- package/dist/src/benchmark-environment-bridge.js +515 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
- package/dist/src/benchmark-tool-isolation.js +151 -0
- package/dist/src/bookable-facts.js +533 -0
- package/dist/src/booking-saga.js +97 -0
- package/dist/src/booking-surface/availability-policy.js +697 -0
- package/dist/src/booking-surface/booking-intent.js +43 -0
- package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
- package/dist/src/booking-surface/canonical-schema.js +116 -0
- package/dist/src/booking-surface/contracts.js +75 -0
- package/dist/src/booking-surface/dsh-planner.js +1854 -0
- package/dist/src/booking-surface/dsh-plugin.js +378 -0
- package/dist/src/booking-surface/dsh-worker.js +98 -0
- package/dist/src/booking-surface/error-codes.js +231 -0
- package/dist/src/booking-surface/index.js +9 -0
- package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
- package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
- package/dist/src/booking-surface/profile.js +24 -0
- package/dist/src/booking-surface/recovery-chain.js +367 -0
- package/dist/src/booking-surface/runtime.js +1968 -0
- package/dist/src/booking-surface/server.js +674 -0
- package/dist/src/booking-surface/startup.js +168 -0
- package/dist/src/booking-surface/validation.js +261 -0
- package/dist/src/bridge.js +20 -13
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +97 -111
- package/dist/src/engine.js +276 -193
- package/dist/src/evaluation-cadence.js +97 -0
- package/dist/src/evaluation-contracts.js +283 -0
- package/dist/src/flight-pack-adapter.js +54 -0
- package/dist/src/flight-pack-contract.js +2 -0
- package/dist/src/flyai-setup-tool.js +70 -0
- package/dist/src/gotry-backend.js +125 -0
- package/dist/src/hotel-date-gate.js +118 -0
- package/dist/src/i18n.js +88 -0
- package/dist/src/index.js +2227 -882
- package/dist/src/itinerary-deck.js +139 -0
- package/dist/src/itinerary-doc-shared.js +661 -0
- package/dist/src/itinerary-html.js +131 -0
- package/dist/src/journey.js +155 -108
- package/dist/src/lavish-tools.js +400 -0
- package/dist/src/ledger-repair-apply.js +538 -0
- package/dist/src/ledger-repair-plan.js +463 -0
- package/dist/src/loop.js +319 -160
- package/dist/src/memory-capture.js +180 -32
- package/dist/src/memory-decay.js +30 -14
- package/dist/src/memory-lifecycle.js +1310 -0
- package/dist/src/memory-utility.js +27 -40
- package/dist/src/mock-llm.js +36 -61
- package/dist/src/model.js +81 -36
- package/dist/src/realtime-pricing.js +103 -0
- package/dist/src/recall/card.js +74 -0
- package/dist/src/recall/evaluator.js +140 -0
- package/dist/src/recall/integration.js +17 -0
- package/dist/src/recall/tick.js +166 -0
- package/dist/src/session-link/plan-it-action.js +48 -0
- package/dist/src/session-link/session-link.js +248 -0
- package/dist/src/session-zones.js +507 -0
- package/dist/src/share/adapters.js +51 -0
- package/dist/src/share/share-consent.js +76 -0
- package/dist/src/share/share-deck.js +58 -0
- package/dist/src/share/share-token.js +146 -0
- package/dist/src/slot-spec.js +84 -106
- package/dist/src/state-ledger.js +435 -516
- package/dist/src/state-repair.js +299 -0
- package/dist/src/subagent-job-id-guard.js +58 -0
- package/dist/src/time-anchor.js +231 -33
- package/dist/src/tool-packet.js +20 -8
- package/dist/src/travel-slots.js +58 -35
- package/dist/src/travel-timeline.js +44 -63
- package/dist/src/turn-deadline.js +287 -0
- package/dist/src/turn-policy.js +118 -0
- package/dist/src/tz-resolver.js +143 -0
- package/dist/src/unified.js +535 -359
- package/dist/src/wish-pool.js +42 -12
- package/dist/src/write-gate.js +495 -0
- package/dist/src/z3-shared.js +284 -0
- package/extension/README.md +21 -0
- package/extension/README.zh-CN.md +21 -0
- package/extension/background.js +463 -0
- package/extension/content-bridge.js +270 -0
- package/extension/content-main.js +111 -0
- package/extension/manifest.json +60 -0
- package/package.json +407 -14
- package/schemas/booking.intent.schema.json +193 -0
- package/schemas/booking.surface.schema.json +2622 -0
- package/ts/capabilities/agent-reach-deep.ts +114 -0
- package/ts/capabilities/agent-reach.ts +198 -0
- package/ts/capabilities/anything.ts +255 -0
- package/ts/capabilities/artifacts.ts +428 -0
- package/ts/capabilities/fact-log.ts +54 -0
- package/ts/capabilities/flyai-config.ts +388 -0
- package/ts/capabilities/flyai.ts +1274 -0
- package/ts/capabilities/hbcli.ts +253 -71
- package/ts/capabilities/incident-log.ts +88 -59
- package/ts/capabilities/itinerary-artifact.ts +214 -0
- package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
- package/ts/capabilities/itinerary-deck-export.ts +378 -0
- package/ts/capabilities/opensky.ts +121 -0
- package/ts/capabilities/session/action-cache.ts +148 -0
- package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
- package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
- package/ts/capabilities/session/benchmark.ts +276 -0
- package/ts/capabilities/session/bridge-ledger.ts +333 -0
- package/ts/capabilities/session/extension-bridge.ts +794 -0
- package/ts/capabilities/session/extension-channel.ts +144 -0
- package/ts/capabilities/session/extension-distribution.ts +266 -0
- package/ts/capabilities/session/extract.ts +54 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +264 -0
- package/ts/capabilities/session/read-guard.ts +141 -0
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/transport.ts +146 -0
- package/ts/capabilities/session/wizard.ts +140 -0
- package/ts/capabilities/session-consent.ts +211 -0
- package/ts/capabilities/session-login.ts +208 -0
- package/ts/capabilities/session-search.ts +893 -0
- package/ts/capabilities/weather.ts +330 -0
- package/ts/dsh-runtime/vendor/README.md +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
- package/ts/package.json +293 -3
- package/ts/scripts/async-collect.ts +91 -0
- package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
- package/ts/scripts/skeleton-check.ts +1 -1
- package/ts/scripts/skeleton-integration-test.ts +23 -1
- package/ts/scripts/state-cli.ts +568 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +991 -0
- package/ts/src/benchmark-agent-conformance.ts +619 -0
- package/ts/src/benchmark-environment-bridge.ts +538 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/bookable-facts.ts +837 -0
- package/ts/src/booking-saga.ts +133 -0
- package/ts/src/booking-surface/availability-policy.ts +522 -0
- package/ts/src/booking-surface/booking-intent.ts +86 -0
- package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
- package/ts/src/booking-surface/canonical-schema.js +116 -0
- package/ts/src/booking-surface/contracts.ts +475 -0
- package/ts/src/booking-surface/dsh-planner.ts +1949 -0
- package/ts/src/booking-surface/dsh-plugin.js +378 -0
- package/ts/src/booking-surface/dsh-worker.ts +110 -0
- package/ts/src/booking-surface/error-codes.ts +241 -0
- package/ts/src/booking-surface/index.ts +9 -0
- package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
- package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/recovery-chain.ts +409 -0
- package/ts/src/booking-surface/runtime.ts +1793 -0
- package/ts/src/booking-surface/server.ts +733 -0
- package/ts/src/booking-surface/startup.ts +201 -0
- package/ts/src/booking-surface/validation.ts +217 -0
- package/ts/src/companions.ts +113 -0
- package/ts/src/contracts.ts +13 -3
- package/ts/src/dsh-llm.ts +44 -11
- package/ts/src/flyai-setup-tool.ts +77 -0
- package/ts/src/index.ts +1948 -198
- package/ts/src/itinerary-deck.ts +189 -0
- package/ts/src/itinerary-doc-shared.ts +741 -0
- package/ts/src/itinerary-html.ts +171 -0
- package/ts/src/loop.ts +223 -25
- package/ts/src/memory-capture.ts +283 -0
- package/ts/src/memory-decay.ts +55 -0
- package/ts/src/memory-utility.ts +70 -0
- package/ts/src/mock-llm.ts +4 -8
- package/ts/src/model.ts +88 -2
- package/ts/src/recall/card.ts +106 -0
- package/ts/src/recall/evaluator.ts +170 -0
- package/ts/src/recall/integration.ts +35 -0
- package/ts/src/recall/tick.ts +213 -0
- package/ts/src/session-link/plan-it-action.ts +78 -0
- package/ts/src/session-link/session-link.ts +275 -0
- package/ts/src/share/adapters.ts +93 -0
- package/ts/src/share/share-consent.ts +105 -0
- package/ts/src/share/share-deck.ts +85 -0
- package/ts/src/share/share-token.ts +166 -0
- package/ts/src/slot-spec.ts +172 -0
- package/ts/src/state-ledger.ts +912 -0
- package/ts/src/subagent-job-id-guard.ts +72 -0
- package/ts/src/time-anchor.ts +338 -0
- package/ts/src/tool-packet.ts +32 -0
- package/ts/src/travel-slots.ts +219 -0
- package/ts/src/travel-timeline.ts +83 -0
- package/ts/src/turn-deadline.ts +366 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/unified.ts +354 -88
- package/ts/src/wish-pool.ts +79 -0
- package/dist/scripts/session-attach-wait.js +0 -41
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { accessSync, constants, lstatSync, readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { getuid } from 'node:process';
|
|
3
|
+
import { isAbsolute } from 'node:path';
|
|
4
|
+
import { assertSupportedJsonSchema, validateJsonSchemaValue, ToolArgsError, } from '@deepseek-ai/dsh-tools';
|
|
5
|
+
import { validateTerminalOutputConfig, } from './benchmark-agent-conformance.js';
|
|
6
|
+
// v4(#215 Round 12):terminal_output 携带 closed body schema(结构关键字白名单,
|
|
7
|
+
// 禁数据值注解面);v3 及更早配置缺该面,按契约不兼容 fail-closed。
|
|
8
|
+
const SCHEMA_VERSION = 'gotry_benchmark_environment_bridge_v4';
|
|
9
|
+
export const BENCHMARK_TOOL_RESULT_SCHEMA_VERSION = 'gotry_benchmark_tool_result_v1';
|
|
10
|
+
export const BENCHMARK_DOMAIN_RECOVERIES = ['none', 'retry_same', 'revise_arguments', 'choose_alternative'];
|
|
11
|
+
const IDENTIFIER = /^[A-Za-z][A-Za-z0-9_.-]*$/;
|
|
12
|
+
const RECOVERIES = new Set(BENCHMARK_DOMAIN_RECOVERIES);
|
|
13
|
+
const CONFIG_KEYS = ['argv_prefix', 'cwd', 'enabled', 'executable', 'isolation', 'max_output_bytes', 'schema_version', 'terminal_output', 'timeout_ms', 'tools'];
|
|
14
|
+
const INPUT_SCHEMA_MAX_BYTES = 16 * 1024;
|
|
15
|
+
const INPUT_SCHEMA_MAX_DEPTH = 8;
|
|
16
|
+
const INPUT_SCHEMA_MAX_NODES = 256;
|
|
17
|
+
const INPUT_SCHEMA_MAX_PROPERTIES = 256;
|
|
18
|
+
const INPUT_SCHEMA_MAX_ENUM_VALUES = 256;
|
|
19
|
+
const INPUT_SCHEMA_MAX_DESCRIPTION_LENGTH = 512;
|
|
20
|
+
const INPUT_SCHEMA_TYPES = new Set(['string', 'number', 'integer', 'boolean', 'null', 'array', 'object']);
|
|
21
|
+
function plainObject(value) {
|
|
22
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
23
|
+
}
|
|
24
|
+
function deepFreezeJson(value) {
|
|
25
|
+
if (!value || typeof value !== 'object' || Object.isFrozen(value))
|
|
26
|
+
return value;
|
|
27
|
+
for (const child of Object.values(value))
|
|
28
|
+
deepFreezeJson(child);
|
|
29
|
+
return Object.freeze(value);
|
|
30
|
+
}
|
|
31
|
+
function existingExecutable(value) {
|
|
32
|
+
if (typeof value !== 'string' || !isAbsolute(value))
|
|
33
|
+
return false;
|
|
34
|
+
try {
|
|
35
|
+
const stat = statSync(value);
|
|
36
|
+
accessSync(value, constants.X_OK);
|
|
37
|
+
return stat.isFile();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function existingDirectory(value) {
|
|
44
|
+
if (typeof value !== 'string' || !isAbsolute(value))
|
|
45
|
+
return false;
|
|
46
|
+
try {
|
|
47
|
+
return statSync(value).isDirectory();
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function identifiers(value, allowEmpty = false) {
|
|
54
|
+
return Array.isArray(value) && (allowEmpty || value.length > 0) && value.length <= 64 && new Set(value).size === value.length && value.every(item => typeof item === 'string' && item.length > 0 && IDENTIFIER.test(item));
|
|
55
|
+
}
|
|
56
|
+
function exactKeys(value, allowed) {
|
|
57
|
+
return Object.keys(value).every(key => allowed.includes(key));
|
|
58
|
+
}
|
|
59
|
+
function validDescription(value, required = false) {
|
|
60
|
+
if (value === undefined)
|
|
61
|
+
return !required;
|
|
62
|
+
return typeof value === 'string'
|
|
63
|
+
&& (!required || value.trim().length > 0)
|
|
64
|
+
&& value.length <= INPUT_SCHEMA_MAX_DESCRIPTION_LENGTH
|
|
65
|
+
&& !/[\u0000-\u001f\u007f]/.test(value);
|
|
66
|
+
}
|
|
67
|
+
function scalarMatches(type, value) {
|
|
68
|
+
if (type === 'string')
|
|
69
|
+
return typeof value === 'string' && value.length <= 512;
|
|
70
|
+
if (type === 'number')
|
|
71
|
+
return typeof value === 'number' && Number.isFinite(value);
|
|
72
|
+
if (type === 'integer')
|
|
73
|
+
return typeof value === 'number' && Number.isSafeInteger(value);
|
|
74
|
+
if (type === 'boolean')
|
|
75
|
+
return typeof value === 'boolean';
|
|
76
|
+
return type === 'null' && value === null;
|
|
77
|
+
}
|
|
78
|
+
function validInputSchema(value) {
|
|
79
|
+
if (!plainObject(value))
|
|
80
|
+
return false;
|
|
81
|
+
let serialized;
|
|
82
|
+
try {
|
|
83
|
+
serialized = JSON.stringify(value);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (Buffer.byteLength(serialized, 'utf8') > INPUT_SCHEMA_MAX_BYTES)
|
|
89
|
+
return false;
|
|
90
|
+
const pending = [{ node: value, depth: 0 }];
|
|
91
|
+
const seen = new Set();
|
|
92
|
+
let nodes = 0;
|
|
93
|
+
let properties = 0;
|
|
94
|
+
let enumValues = 0;
|
|
95
|
+
while (pending.length > 0) {
|
|
96
|
+
const { node, depth } = pending.pop();
|
|
97
|
+
if (seen.has(node) || ++nodes > INPUT_SCHEMA_MAX_NODES || depth > INPUT_SCHEMA_MAX_DEPTH)
|
|
98
|
+
return false;
|
|
99
|
+
seen.add(node);
|
|
100
|
+
if (!INPUT_SCHEMA_TYPES.has(String(node.type)) || !validDescription(node.description))
|
|
101
|
+
return false;
|
|
102
|
+
if (node.type === 'object') {
|
|
103
|
+
if (!exactKeys(node, ['type', 'description', 'properties', 'required', 'additionalProperties'])
|
|
104
|
+
|| !plainObject(node.properties)
|
|
105
|
+
|| !Array.isArray(node.required)
|
|
106
|
+
|| node.additionalProperties !== false)
|
|
107
|
+
return false;
|
|
108
|
+
const propertyEntries = Object.entries(node.properties);
|
|
109
|
+
properties += propertyEntries.length;
|
|
110
|
+
if (properties > INPUT_SCHEMA_MAX_PROPERTIES || propertyEntries.some(([key, child]) => !IDENTIFIER.test(key) || !plainObject(child)))
|
|
111
|
+
return false;
|
|
112
|
+
const required = node.required;
|
|
113
|
+
if (required.length > propertyEntries.length
|
|
114
|
+
|| new Set(required).size !== required.length
|
|
115
|
+
|| required.some(key => typeof key !== 'string' || !Object.hasOwn(node.properties, key)))
|
|
116
|
+
return false;
|
|
117
|
+
for (const [, child] of propertyEntries)
|
|
118
|
+
pending.push({ node: child, depth: depth + 1 });
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (node.type === 'array') {
|
|
122
|
+
if (!exactKeys(node, ['type', 'description', 'items']) || !plainObject(node.items))
|
|
123
|
+
return false;
|
|
124
|
+
pending.push({ node: node.items, depth: depth + 1 });
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
if (!exactKeys(node, ['type', 'description', 'enum', 'const'])
|
|
128
|
+
|| (Object.hasOwn(node, 'enum') && Object.hasOwn(node, 'const')))
|
|
129
|
+
return false;
|
|
130
|
+
if (Object.hasOwn(node, 'const') && !scalarMatches(String(node.type), node.const))
|
|
131
|
+
return false;
|
|
132
|
+
if (Object.hasOwn(node, 'enum')) {
|
|
133
|
+
if (!Array.isArray(node.enum) || node.enum.length === 0 || node.enum.length > 64)
|
|
134
|
+
return false;
|
|
135
|
+
enumValues += node.enum.length;
|
|
136
|
+
if (enumValues > INPUT_SCHEMA_MAX_ENUM_VALUES
|
|
137
|
+
|| new Set(node.enum).size !== node.enum.length
|
|
138
|
+
|| node.enum.some(item => !scalarMatches(String(node.type), item)))
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return value.type === 'object';
|
|
143
|
+
}
|
|
144
|
+
function toolDescriptors(value) {
|
|
145
|
+
if (!Array.isArray(value) || value.length === 0 || value.length > 64)
|
|
146
|
+
return false;
|
|
147
|
+
const names = new Set();
|
|
148
|
+
return value.every(item => {
|
|
149
|
+
if (!plainObject(item))
|
|
150
|
+
return false;
|
|
151
|
+
const keys = Object.keys(item).sort();
|
|
152
|
+
const required = ['description', 'domain_outcomes', 'input_schema', 'name'];
|
|
153
|
+
if (JSON.stringify(keys) !== JSON.stringify([...required, 'output_keys'].sort()))
|
|
154
|
+
return false;
|
|
155
|
+
if (typeof item.name !== 'string' || !IDENTIFIER.test(item.name) || names.has(item.name))
|
|
156
|
+
return false;
|
|
157
|
+
names.add(item.name);
|
|
158
|
+
if (!validDescription(item.description, true) || !validInputSchema(item.input_schema))
|
|
159
|
+
return false;
|
|
160
|
+
if (!Array.isArray(item.domain_outcomes) || item.domain_outcomes.length > 64)
|
|
161
|
+
return false;
|
|
162
|
+
const outcomeKeys = new Set();
|
|
163
|
+
if (!item.domain_outcomes.every(outcome => plainObject(outcome)
|
|
164
|
+
&& JSON.stringify(Object.keys(outcome).sort()) === JSON.stringify(['code', 'recovery', 'status'])
|
|
165
|
+
&& (outcome.status === 'miss' || outcome.status === 'error')
|
|
166
|
+
&& typeof outcome.code === 'string' && IDENTIFIER.test(outcome.code)
|
|
167
|
+
&& typeof outcome.recovery === 'string' && RECOVERIES.has(outcome.recovery)
|
|
168
|
+
&& !outcomeKeys.has(outcome.code)
|
|
169
|
+
&& (outcomeKeys.add(outcome.code), true)))
|
|
170
|
+
return false;
|
|
171
|
+
return identifiers(item.output_keys);
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// These are passed as direct argv entries (never through a shell), so options
|
|
175
|
+
// such as "-m" and dotted module names are valid. Keep the prefix bounded and
|
|
176
|
+
// reject line/control separators that could make diagnostics ambiguous.
|
|
177
|
+
function argvPrefix(value) {
|
|
178
|
+
return Array.isArray(value) && value.length > 0 && value.length <= 32 && value.every(item => typeof item === 'string'
|
|
179
|
+
&& item.length > 0
|
|
180
|
+
&& item.length <= 256
|
|
181
|
+
&& !item.includes('\0')
|
|
182
|
+
&& !item.includes('\r')
|
|
183
|
+
&& !item.includes('\n'));
|
|
184
|
+
}
|
|
185
|
+
function exactIsolation(value) {
|
|
186
|
+
if (!plainObject(value))
|
|
187
|
+
return false;
|
|
188
|
+
const keys = Object.keys(value).sort();
|
|
189
|
+
return JSON.stringify(keys) === JSON.stringify(['mode', 'network', 'writes'])
|
|
190
|
+
&& value.mode === 'host-enforced'
|
|
191
|
+
&& value.writes === 'forbidden'
|
|
192
|
+
&& value.network === 'denied';
|
|
193
|
+
}
|
|
194
|
+
function validBound(value, maximum) {
|
|
195
|
+
return typeof value === 'number' && Number.isInteger(value) && value >= 1 && value <= maximum;
|
|
196
|
+
}
|
|
197
|
+
function validate(value) {
|
|
198
|
+
const configKeys = plainObject(value) ? Object.keys(value).sort() : [];
|
|
199
|
+
const baseKeys = [...CONFIG_KEYS].sort();
|
|
200
|
+
if (!plainObject(value)
|
|
201
|
+
|| JSON.stringify(configKeys) !== JSON.stringify(baseKeys)
|
|
202
|
+
|| value.schema_version !== SCHEMA_VERSION
|
|
203
|
+
|| value.enabled !== true
|
|
204
|
+
|| !existingExecutable(value.executable)
|
|
205
|
+
|| !existingDirectory(value.cwd)
|
|
206
|
+
|| !argvPrefix(value.argv_prefix)
|
|
207
|
+
|| !toolDescriptors(value.tools)
|
|
208
|
+
|| !validBound(value.timeout_ms, 120_000)
|
|
209
|
+
|| !validBound(value.max_output_bytes, 10 * 1024 * 1024)
|
|
210
|
+
|| !validateTerminalOutputConfig(value.terminal_output)
|
|
211
|
+
|| !exactIsolation(value.isolation))
|
|
212
|
+
return false;
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
/** Read and validate an owner-local bridge config without exposing its contents. */
|
|
216
|
+
export function loadBenchmarkEnvironmentConfig(path) {
|
|
217
|
+
try {
|
|
218
|
+
if (!isAbsolute(path))
|
|
219
|
+
return null;
|
|
220
|
+
const metadata = lstatSync(path);
|
|
221
|
+
if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size > 64 * 1024)
|
|
222
|
+
return null;
|
|
223
|
+
if (typeof getuid !== 'function' || metadata.uid !== getuid())
|
|
224
|
+
return null;
|
|
225
|
+
if ((metadata.mode & 0o022) !== 0)
|
|
226
|
+
return null;
|
|
227
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
228
|
+
return validate(parsed) ? deepFreezeJson(parsed) : null;
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
return null;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function structuredObject(text) {
|
|
235
|
+
try {
|
|
236
|
+
const parsed = JSON.parse(text.trim());
|
|
237
|
+
return plainObject(parsed) ? parsed : null;
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
function jsonObject(value) {
|
|
244
|
+
return JSON.parse(JSON.stringify(value));
|
|
245
|
+
}
|
|
246
|
+
const FORBIDDEN_OUTPUT_KEY_FRAGMENTS = [
|
|
247
|
+
'answer', 'expected', 'gold', 'groundtruth', 'hiddenquery', 'label',
|
|
248
|
+
'loadermetadata', 'oracle', 'reference', 'reward', 'score',
|
|
249
|
+
];
|
|
250
|
+
export const BRIDGE_ERROR_CONTRACT = Object.freeze({
|
|
251
|
+
invalid_action: { recoverable: true, remedy: 'action 只允许 tools、call 或 errors' },
|
|
252
|
+
disallowed_tool: { recoverable: true, remedy: '先 action=tools 列出 allowed_tools 清单,再从清单内选工具' },
|
|
253
|
+
invalid_arguments: { recoverable: true, remedy: 'arguments 必须是可序列化 JSON 对象(≤64KB、深度≤12);收窄后重试' },
|
|
254
|
+
timed_out: { recoverable: true, remedy: '上游超时;可原样重试一次或换其他工具' },
|
|
255
|
+
output_truncated: { recoverable: true, remedy: '输出超出上限;让被调工具收窄查询范围后重试' },
|
|
256
|
+
invalid_json: { recoverable: true, remedy: '上游输出不是合法 JSON;重试一次或换工具' },
|
|
257
|
+
invalid_output: { recoverable: true, remedy: '上游输出结构不符;重试或换工具' },
|
|
258
|
+
runner_failed: { recoverable: true, remedy: '上游进程非零退出;可重试一次,持续失败换工具' },
|
|
259
|
+
spawn_failed: { recoverable: false, remedy: '可执行文件不可用——环境问题,调用方不可恢复' },
|
|
260
|
+
forbidden_output: { recoverable: false, remedy: '输出含未授权键(策略边界)——不可恢复,换工具或放弃' },
|
|
261
|
+
});
|
|
262
|
+
function inspectOutput(value) {
|
|
263
|
+
const pending = [{ value, depth: 0 }];
|
|
264
|
+
let nodes = 0;
|
|
265
|
+
while (pending.length > 0) {
|
|
266
|
+
const current = pending.pop();
|
|
267
|
+
if (++nodes > 10_000 || current.depth > 24)
|
|
268
|
+
return 'structure_limit';
|
|
269
|
+
if (Array.isArray(current.value)) {
|
|
270
|
+
for (const child of current.value)
|
|
271
|
+
pending.push({ value: child, depth: current.depth + 1 });
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
if (!plainObject(current.value))
|
|
275
|
+
continue;
|
|
276
|
+
for (const [key, child] of Object.entries(current.value)) {
|
|
277
|
+
if (!/^[\x20-\x7E]+$/.test(key))
|
|
278
|
+
return 'forbidden_key';
|
|
279
|
+
const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
280
|
+
if (FORBIDDEN_OUTPUT_KEY_FRAGMENTS.some(fragment => normalized.includes(fragment)))
|
|
281
|
+
return 'forbidden_key';
|
|
282
|
+
pending.push({ value: child, depth: current.depth + 1 });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return 'ok';
|
|
286
|
+
}
|
|
287
|
+
function inspectAllowedOutput(value, allowedKeys) {
|
|
288
|
+
const allowed = new Set(allowedKeys);
|
|
289
|
+
const pending = [{ value, depth: 0, coveredByDeclaredKey: false }];
|
|
290
|
+
let nodes = 0;
|
|
291
|
+
while (pending.length > 0) {
|
|
292
|
+
const current = pending.pop();
|
|
293
|
+
if (++nodes > 10_000 || current.depth > 24)
|
|
294
|
+
return false;
|
|
295
|
+
if (Array.isArray(current.value)) {
|
|
296
|
+
for (const child of current.value)
|
|
297
|
+
pending.push({ value: child, depth: current.depth + 1, coveredByDeclaredKey: current.coveredByDeclaredKey });
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
if (!plainObject(current.value)) {
|
|
301
|
+
if (!current.coveredByDeclaredKey)
|
|
302
|
+
return false;
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
for (const [key, child] of Object.entries(current.value)) {
|
|
306
|
+
if (!allowed.has(key))
|
|
307
|
+
return false;
|
|
308
|
+
pending.push({ value: child, depth: current.depth + 1, coveredByDeclaredKey: true });
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
function serializedArguments(value) {
|
|
314
|
+
const seen = new Set();
|
|
315
|
+
let nodes = 0;
|
|
316
|
+
let keys = 0;
|
|
317
|
+
const inspect = (current, depth) => {
|
|
318
|
+
if (++nodes > 10_000 || depth > 12)
|
|
319
|
+
return false;
|
|
320
|
+
if (current && typeof current === 'object') {
|
|
321
|
+
if (seen.has(current))
|
|
322
|
+
return false;
|
|
323
|
+
seen.add(current);
|
|
324
|
+
if (Array.isArray(current))
|
|
325
|
+
return current.every(item => inspect(item, depth + 1));
|
|
326
|
+
return Object.entries(current).every(([key, child]) => {
|
|
327
|
+
if (++keys > 10_000)
|
|
328
|
+
return false;
|
|
329
|
+
return inspect(key, depth + 1) && inspect(child, depth + 1);
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
return true;
|
|
333
|
+
};
|
|
334
|
+
if (!inspect(value, 0))
|
|
335
|
+
return { reason: 'serialization_limit' };
|
|
336
|
+
try {
|
|
337
|
+
const json = JSON.stringify(value);
|
|
338
|
+
if (typeof json !== 'string' || Buffer.byteLength(json, 'utf8') > 65_536)
|
|
339
|
+
return { reason: 'serialization_limit' };
|
|
340
|
+
return { json };
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return { reason: 'serialization_limit' };
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/** Register the opt-in model-facing bridge. */
|
|
347
|
+
export function registerBenchmarkEnvironmentBridge(path, register, subprocess) {
|
|
348
|
+
const bridge = loadBenchmarkEnvironmentConfig(path);
|
|
349
|
+
if (!bridge)
|
|
350
|
+
throw new Error('benchmark environment bridge configuration unavailable');
|
|
351
|
+
if (!subprocess)
|
|
352
|
+
throw new Error('benchmark environment bridge subprocess unavailable');
|
|
353
|
+
const parameters = deepFreezeJson({
|
|
354
|
+
type: 'object',
|
|
355
|
+
description: 'Flat benchmark bridge wire: choose an action, then provide the mapped tool and its arguments.',
|
|
356
|
+
properties: {
|
|
357
|
+
action: { type: 'string', enum: ['tools', 'call', 'errors'], description: 'tools=列出可调工具;call=执行工具;errors=拉取错误契约' },
|
|
358
|
+
tool: { type: 'string', enum: bridge.tools.map(item => item.name), description: 'action=call 时选择的冻结工具名' },
|
|
359
|
+
arguments: { type: 'object', additionalProperties: true, description: 'action=call 时传给工具的参数对象' },
|
|
360
|
+
},
|
|
361
|
+
required: ['action'],
|
|
362
|
+
additionalProperties: false,
|
|
363
|
+
});
|
|
364
|
+
assertSupportedJsonSchema(parameters);
|
|
365
|
+
const definition = {
|
|
366
|
+
name: 'gotry_benchmark_environment',
|
|
367
|
+
description: 'When a prompt asks to run agent_env.cli, use action=call here with the mapped tool; arbitrary shell is not exposed.',
|
|
368
|
+
parameters,
|
|
369
|
+
output: {
|
|
370
|
+
schema: {},
|
|
371
|
+
render: (_args, value) => [{ type: 'text', text: JSON.stringify(value) }],
|
|
372
|
+
},
|
|
373
|
+
async execute(args) {
|
|
374
|
+
const violations = validateJsonSchemaValue(parameters, args, 'arguments');
|
|
375
|
+
if (violations.length > 0)
|
|
376
|
+
throw new ToolArgsError(violations);
|
|
377
|
+
const query = args;
|
|
378
|
+
const tool = query.tool;
|
|
379
|
+
const descriptor = bridge.tools.find(item => item.name === tool);
|
|
380
|
+
const keys = Object.keys(query);
|
|
381
|
+
if (query.action === 'tools') {
|
|
382
|
+
if (keys.length !== 1)
|
|
383
|
+
throw new ToolArgsError(['arguments: tools action accepts no tool or arguments']);
|
|
384
|
+
return jsonObject({ ok: true, tools: bridge.tools });
|
|
385
|
+
}
|
|
386
|
+
if (query.action === 'errors') {
|
|
387
|
+
if (keys.length !== 1)
|
|
388
|
+
throw new ToolArgsError(['arguments: errors action accepts no tool or arguments']);
|
|
389
|
+
return jsonObject({ ok: true, errors: BRIDGE_ERROR_CONTRACT });
|
|
390
|
+
}
|
|
391
|
+
if (query.action !== 'call') {
|
|
392
|
+
return jsonObject({ ok: false, error: 'invalid_action' });
|
|
393
|
+
}
|
|
394
|
+
if (keys.length !== 3 || !Object.hasOwn(query, 'tool') || !Object.hasOwn(query, 'arguments')) {
|
|
395
|
+
throw new ToolArgsError(['arguments: call action requires exactly tool and arguments']);
|
|
396
|
+
}
|
|
397
|
+
if (typeof tool !== 'string' || !descriptor) {
|
|
398
|
+
return jsonObject({ ok: false, error: 'disallowed_tool' });
|
|
399
|
+
}
|
|
400
|
+
if (!plainObject(query.arguments)) {
|
|
401
|
+
return jsonObject({ ok: false, error: 'invalid_arguments' });
|
|
402
|
+
}
|
|
403
|
+
const callArguments = query.arguments;
|
|
404
|
+
const argumentViolations = validateJsonSchemaValue(descriptor.input_schema, callArguments, 'arguments');
|
|
405
|
+
if (argumentViolations.length > 0)
|
|
406
|
+
throw new ToolArgsError(argumentViolations);
|
|
407
|
+
const serialized = serializedArguments(callArguments);
|
|
408
|
+
if (serialized.reason)
|
|
409
|
+
return jsonObject({ ok: false, error: 'invalid_arguments', reason: serialized.reason });
|
|
410
|
+
const controller = new AbortController();
|
|
411
|
+
const timer = setTimeout(() => {
|
|
412
|
+
controller.abort();
|
|
413
|
+
}, bridge.timeout_ms);
|
|
414
|
+
let handle;
|
|
415
|
+
try {
|
|
416
|
+
const env = Object.fromEntries(Object.keys(process.env).map(key => [key, undefined]));
|
|
417
|
+
for (const key of ['PATH', 'LANG', 'LC_ALL', 'LC_CTYPE', 'TZ']) {
|
|
418
|
+
if (process.env[key] !== undefined)
|
|
419
|
+
env[key] = process.env[key];
|
|
420
|
+
}
|
|
421
|
+
env.PYTHONDONTWRITEBYTECODE = '1';
|
|
422
|
+
env.PYTHONNOUSERSITE = '1';
|
|
423
|
+
try {
|
|
424
|
+
handle = subprocess.spawn({
|
|
425
|
+
argv: [bridge.executable, ...bridge.argv_prefix, 'call', tool, serialized.json],
|
|
426
|
+
cwd: bridge.cwd,
|
|
427
|
+
stdio: {
|
|
428
|
+
stdin: 'ignore',
|
|
429
|
+
stdout: { maxBytes: bridge.max_output_bytes },
|
|
430
|
+
stderr: { maxBytes: bridge.max_output_bytes },
|
|
431
|
+
},
|
|
432
|
+
graceMs: Math.min(1_000, bridge.timeout_ms),
|
|
433
|
+
env,
|
|
434
|
+
signal: controller.signal,
|
|
435
|
+
});
|
|
436
|
+
}
|
|
437
|
+
catch {
|
|
438
|
+
if (controller.signal.aborted)
|
|
439
|
+
return jsonObject({ ok: false, error: 'timed_out' });
|
|
440
|
+
return jsonObject({ ok: false, error: 'spawn_failed' });
|
|
441
|
+
}
|
|
442
|
+
let status;
|
|
443
|
+
try {
|
|
444
|
+
status = await handle.done;
|
|
445
|
+
}
|
|
446
|
+
catch {
|
|
447
|
+
if (controller.signal.aborted)
|
|
448
|
+
return jsonObject({ ok: false, error: 'timed_out' });
|
|
449
|
+
return jsonObject({ ok: false, error: 'spawn_failed' });
|
|
450
|
+
}
|
|
451
|
+
if (controller.signal.aborted)
|
|
452
|
+
return jsonObject({ ok: false, error: 'timed_out' });
|
|
453
|
+
let stdout;
|
|
454
|
+
let stderr;
|
|
455
|
+
try {
|
|
456
|
+
stdout = handle.collected.stdout.readFrom(0);
|
|
457
|
+
stderr = handle.collected.stderr.readFrom(0);
|
|
458
|
+
}
|
|
459
|
+
catch {
|
|
460
|
+
return jsonObject({
|
|
461
|
+
ok: false,
|
|
462
|
+
error: 'runner_failed',
|
|
463
|
+
exit_code: status.exitCode,
|
|
464
|
+
signal: status.signal ?? null,
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
if (stdout.lossy || stderr.lossy)
|
|
468
|
+
return jsonObject({ ok: false, error: 'output_truncated' });
|
|
469
|
+
if (status.exitCode !== 0) {
|
|
470
|
+
return jsonObject({
|
|
471
|
+
ok: false,
|
|
472
|
+
error: 'runner_failed',
|
|
473
|
+
exit_code: status.exitCode,
|
|
474
|
+
signal: status.signal ?? null,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
477
|
+
const parsed = structuredObject(stdout.text);
|
|
478
|
+
if (!parsed)
|
|
479
|
+
return jsonObject({ ok: false, error: 'invalid_json' });
|
|
480
|
+
const outputInspection = inspectOutput(parsed);
|
|
481
|
+
if (outputInspection === 'forbidden_key')
|
|
482
|
+
return jsonObject({ ok: false, error: 'forbidden_output' });
|
|
483
|
+
if (outputInspection === 'structure_limit')
|
|
484
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
485
|
+
if (parsed.schema_version !== BENCHMARK_TOOL_RESULT_SCHEMA_VERSION || typeof parsed.status !== 'string') {
|
|
486
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
487
|
+
}
|
|
488
|
+
if (parsed.status === 'miss' || parsed.status === 'error') {
|
|
489
|
+
if (typeof parsed.code !== 'string' || typeof parsed.recovery !== 'string' || !descriptor.domain_outcomes.some(outcome => outcome.status === parsed.status && outcome.code === parsed.code && outcome.recovery === parsed.recovery))
|
|
490
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
491
|
+
if (Object.keys(parsed).sort().join(',') !== 'code,recovery,schema_version,status')
|
|
492
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
493
|
+
return jsonObject({ ok: true, outcome: parsed });
|
|
494
|
+
}
|
|
495
|
+
if (parsed.status !== 'ok' || !Object.hasOwn(parsed, 'result') || Object.keys(parsed).sort().join(',') !== 'result,schema_version,status')
|
|
496
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
497
|
+
const visibleResult = parsed.result;
|
|
498
|
+
if (!plainObject(visibleResult) && !Array.isArray(visibleResult))
|
|
499
|
+
return jsonObject({ ok: false, error: 'invalid_output' });
|
|
500
|
+
if (!inspectAllowedOutput(visibleResult, descriptor.output_keys))
|
|
501
|
+
return jsonObject({ ok: false, error: 'forbidden_output' });
|
|
502
|
+
return jsonObject({ ok: true, result: visibleResult });
|
|
503
|
+
}
|
|
504
|
+
finally {
|
|
505
|
+
clearTimeout(timer);
|
|
506
|
+
}
|
|
507
|
+
},
|
|
508
|
+
};
|
|
509
|
+
register(definition);
|
|
510
|
+
return Object.freeze({
|
|
511
|
+
toolName: 'gotry_benchmark_environment',
|
|
512
|
+
allowedTools: Object.freeze(bridge.tools.map(item => item.name)),
|
|
513
|
+
terminal: Object.freeze({ ...bridge.terminal_output }),
|
|
514
|
+
});
|
|
515
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/** Stable, redacted diagnostics carried on the benchmark-only control pipe. */
|
|
2
|
+
import { writeSync } from 'node:fs';
|
|
3
|
+
export const BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA = 'gotry_benchmark_child_diagnostic_v1';
|
|
4
|
+
export const BENCHMARK_CHILD_DIAGNOSTIC_FD_ENV = 'GOTRY_BENCHMARK_DIAGNOSTIC_FD';
|
|
5
|
+
export const BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES = 4 * 1024;
|
|
6
|
+
const FAILURE_CODES = new Set([
|
|
7
|
+
'child_output_truncated',
|
|
8
|
+
'child_signaled',
|
|
9
|
+
'child_lifecycle_failure',
|
|
10
|
+
'child_conformance_failure',
|
|
11
|
+
'child_bridge_timed_out',
|
|
12
|
+
'child_bridge_runner_failed',
|
|
13
|
+
'child_bridge_spawn_failed',
|
|
14
|
+
'child_bridge_output_truncated',
|
|
15
|
+
'child_bridge_failure',
|
|
16
|
+
'child_terminal_invalid',
|
|
17
|
+
'child_nonzero_exit',
|
|
18
|
+
'child_spawn_failure',
|
|
19
|
+
'child_model_auth',
|
|
20
|
+
'child_model_capacity',
|
|
21
|
+
'child_model_server',
|
|
22
|
+
'child_model_transport',
|
|
23
|
+
'child_model_stream',
|
|
24
|
+
'child_model_request',
|
|
25
|
+
'child_runtime_error',
|
|
26
|
+
'child_blocked',
|
|
27
|
+
'child_max_tokens',
|
|
28
|
+
'child_aborted',
|
|
29
|
+
'child_interrupted',
|
|
30
|
+
]);
|
|
31
|
+
const MODEL_AUTH = new Set(['AUTH', 'INVALID_CREDENTIAL', 'MISSING_CREDENTIAL']);
|
|
32
|
+
const MODEL_CAPACITY = new Set(['QUOTA', 'RATE_LIMIT']);
|
|
33
|
+
const MODEL_SERVER = new Set(['SERVER']);
|
|
34
|
+
const MODEL_TRANSPORT = new Set(['TRANSPORT', 'TIMEOUT']);
|
|
35
|
+
const MODEL_STREAM = new Set(['EMPTY_RESPONSE', 'STREAM_CLOSED', 'MALFORMED_RESPONSE', 'INVALID_RESPONSE']);
|
|
36
|
+
const MODEL_REQUEST = new Set(['INVALID_REQUEST', 'CONTEXT_WINDOW_EXCEEDED', 'NO_ADAPTER', 'UNKNOWN_MODEL', 'UNSUPPORTED_OPTION']);
|
|
37
|
+
/** Classify only the structured final turn/end envelope; free-form fields are ignored. */
|
|
38
|
+
export function classifyBenchmarkTurnEnd(reason) {
|
|
39
|
+
if (!plainObject(reason) || typeof reason.kind !== 'string')
|
|
40
|
+
return 'child_runtime_error';
|
|
41
|
+
switch (reason.kind) {
|
|
42
|
+
case 'completed': return undefined;
|
|
43
|
+
case 'blocked': return 'child_blocked';
|
|
44
|
+
case 'max-tokens': return 'child_max_tokens';
|
|
45
|
+
case 'aborted': return 'child_aborted';
|
|
46
|
+
case 'interrupted': return 'child_interrupted';
|
|
47
|
+
case 'error': {
|
|
48
|
+
const error = plainObject(reason.error) ? reason.error : {};
|
|
49
|
+
const code = typeof error.code === 'string' ? error.code : '';
|
|
50
|
+
const status = typeof error.status === 'number' && Number.isInteger(error.status) && error.status >= 100 && error.status <= 599
|
|
51
|
+
? error.status
|
|
52
|
+
: undefined;
|
|
53
|
+
if (MODEL_AUTH.has(code))
|
|
54
|
+
return 'child_model_auth';
|
|
55
|
+
if (MODEL_CAPACITY.has(code))
|
|
56
|
+
return 'child_model_capacity';
|
|
57
|
+
if (MODEL_SERVER.has(code))
|
|
58
|
+
return 'child_model_server';
|
|
59
|
+
if (MODEL_TRANSPORT.has(code))
|
|
60
|
+
return 'child_model_transport';
|
|
61
|
+
if (MODEL_STREAM.has(code))
|
|
62
|
+
return 'child_model_stream';
|
|
63
|
+
if (MODEL_REQUEST.has(code))
|
|
64
|
+
return 'child_model_request';
|
|
65
|
+
if (code === 'ABORTED')
|
|
66
|
+
return 'child_aborted';
|
|
67
|
+
if (status === 401 || status === 403)
|
|
68
|
+
return 'child_model_auth';
|
|
69
|
+
if (status === 429)
|
|
70
|
+
return 'child_model_capacity';
|
|
71
|
+
if (status !== undefined && status >= 500 && status <= 599)
|
|
72
|
+
return 'child_model_server';
|
|
73
|
+
return 'child_runtime_error';
|
|
74
|
+
}
|
|
75
|
+
default: return 'child_runtime_error';
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/** Per-session final arbiter. It emits one best closed enum, never its payload. */
|
|
79
|
+
export function createBenchmarkDiagnosticArbiter(write) {
|
|
80
|
+
const pending = new Map();
|
|
81
|
+
const emitted = new Set();
|
|
82
|
+
const rank = (code) => code.startsWith('child_bridge_') ? 4 : code === 'child_conformance_failure' ? 3 : code === 'child_runtime_error' ? 1 : 2;
|
|
83
|
+
return {
|
|
84
|
+
offer(session, code) {
|
|
85
|
+
if (code === undefined || emitted.has(session))
|
|
86
|
+
return;
|
|
87
|
+
const previous = pending.get(session);
|
|
88
|
+
if (previous === undefined || rank(code) > rank(previous))
|
|
89
|
+
pending.set(session, code);
|
|
90
|
+
},
|
|
91
|
+
flush(session) {
|
|
92
|
+
if (emitted.has(session))
|
|
93
|
+
return;
|
|
94
|
+
const code = pending.get(session);
|
|
95
|
+
if (code === undefined)
|
|
96
|
+
return;
|
|
97
|
+
emitted.add(session);
|
|
98
|
+
pending.delete(session);
|
|
99
|
+
write(code);
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function plainObject(value) {
|
|
104
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
105
|
+
}
|
|
106
|
+
/** Keep the newest bounded bytes so a final control record cannot be displaced by noise. */
|
|
107
|
+
export function appendBoundedChildDiagnostic(current, chunk) {
|
|
108
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
109
|
+
if (bytes.length >= BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES) {
|
|
110
|
+
return bytes.subarray(bytes.length - BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES);
|
|
111
|
+
}
|
|
112
|
+
if (current.length + bytes.length <= BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES) {
|
|
113
|
+
return Buffer.concat([current, bytes]);
|
|
114
|
+
}
|
|
115
|
+
const keep = BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES - bytes.length;
|
|
116
|
+
return Buffer.concat([current.subarray(current.length - keep), bytes]);
|
|
117
|
+
}
|
|
118
|
+
export function parseBenchmarkChildDiagnostic(raw) {
|
|
119
|
+
const lines = raw.split('\n').map(line => line.trim()).filter(Boolean);
|
|
120
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
121
|
+
try {
|
|
122
|
+
const parsed = JSON.parse(lines[index]);
|
|
123
|
+
if (!plainObject(parsed))
|
|
124
|
+
continue;
|
|
125
|
+
const keys = Object.keys(parsed).sort();
|
|
126
|
+
if (JSON.stringify(keys) !== JSON.stringify(['code', 'schema_version']))
|
|
127
|
+
continue;
|
|
128
|
+
if (parsed.schema_version !== BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA)
|
|
129
|
+
continue;
|
|
130
|
+
if (typeof parsed.code !== 'string' || !FAILURE_CODES.has(parsed.code))
|
|
131
|
+
continue;
|
|
132
|
+
return parsed.code;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
// The control pipe is fail-closed: malformed or unrelated records are ignored.
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
/** Emit one namespaced enum record without reflecting prompts, paths, or stderr. */
|
|
141
|
+
export function emitBenchmarkChildDiagnostic(code) {
|
|
142
|
+
const fd = Number(process.env[BENCHMARK_CHILD_DIAGNOSTIC_FD_ENV]);
|
|
143
|
+
if (!Number.isInteger(fd) || fd < 3)
|
|
144
|
+
return;
|
|
145
|
+
const record = `\n${JSON.stringify({ schema_version: BENCHMARK_CHILD_DIAGNOSTIC_SCHEMA, code })}\n`;
|
|
146
|
+
if (Buffer.byteLength(record, 'utf8') > BENCHMARK_CHILD_DIAGNOSTIC_MAX_BYTES)
|
|
147
|
+
return;
|
|
148
|
+
try {
|
|
149
|
+
writeSync(fd, record);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
// Diagnostics never change the conformance decision itself.
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
export function classifyBenchmarkChildFailure(input) {
|
|
156
|
+
if (input.outputTruncated)
|
|
157
|
+
return 'child_output_truncated';
|
|
158
|
+
if (input.signal)
|
|
159
|
+
return 'child_signaled';
|
|
160
|
+
const structured = parseBenchmarkChildDiagnostic(input.diagnostic ?? '');
|
|
161
|
+
if (structured)
|
|
162
|
+
return structured;
|
|
163
|
+
if (input.code !== 0)
|
|
164
|
+
return 'child_nonzero_exit';
|
|
165
|
+
return 'child_lifecycle_failure';
|
|
166
|
+
}
|