@danceiny/gotry 0.0.1-rc.9 → 0.2.0-rc.28
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 +1788 -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 +161 -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 +553 -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 +676 -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/provider-detail-sanitize.js +64 -0
- package/dist/capabilities/resilience.js +191 -0
- package/dist/capabilities/route-provider-conformance.js +341 -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-path-measure-tests.js +133 -0
- package/dist/scripts/anything-path-measure.js +150 -0
- package/dist/scripts/anything-tests.js +250 -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 +126 -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 +1549 -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/city-scenario-tier-tests.js +234 -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 +600 -0
- package/dist/scripts/drill-multiuser-ledger-tests.js +1076 -0
- package/dist/scripts/drill-sdk-descendant-cleanup-tests.js +606 -0
- package/dist/scripts/drill-w2a-sensor-tests.js +788 -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-llm-tests.js +437 -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 +150 -0
- package/dist/scripts/g5-guard.js +193 -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/m3-cohort-tests.js +714 -0
- package/dist/scripts/m3-cohort.js +310 -0
- 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 +203 -0
- package/dist/scripts/nightly-evidence.js +303 -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/outcome-projection-tests.js +427 -0
- package/dist/scripts/persona-sim-tests.js +603 -0
- package/dist/scripts/persona-sim.js +1081 -0
- 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 +22 -18
- package/dist/scripts/replay-real.js +18 -18
- package/dist/scripts/replay.js +54 -82
- package/dist/scripts/route-provider-conformance-tests.js +391 -0
- 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-zone-crash.js +49 -0
- package/dist/scripts/session-zone-ledger-tests.js +432 -0
- package/dist/scripts/session-zone-observation-tests.js +492 -0
- package/dist/scripts/session-zone-observe.js +135 -0
- package/dist/scripts/session-zone-wiring-tests.js +566 -0
- package/dist/scripts/session-zones-tests.js +374 -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 +244 -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 +565 -198
- 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 +212 -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 +60 -20
- 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 +46 -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/city-scenario-tier.js +378 -0
- package/dist/src/companions.js +48 -74
- package/dist/src/contracts.js +21 -43
- package/dist/src/dsh-llm.js +171 -115
- 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 +2385 -881
- 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 +331 -161
- package/dist/src/m3-cohort.js +1577 -0
- 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/outcome-projection.js +746 -0
- 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-zone-ledger.js +312 -0
- package/dist/src/session-zone-observation.js +354 -0
- package/dist/src/session-zone-wiring.js +658 -0
- package/dist/src/session-zones.js +510 -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 +696 -524
- 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 +600 -360
- 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 +282 -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 +586 -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 +17 -3
- package/ts/src/dsh-llm.ts +152 -17
- package/ts/src/flyai-setup-tool.ts +77 -0
- package/ts/src/index.ts +2123 -200
- 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 +234 -26
- 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 +1166 -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 +444 -105
- package/ts/src/wish-pool.ts +79 -0
- package/dist/scripts/session-attach-wait.js +0 -41
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-agent, per-turn wall-clock boundary driven by routing (ADR-24 v2).
|
|
3
|
+
*
|
|
4
|
+
* 职责只有一件:保证每一轮终结在三态之一——当面答完(converge)、转后台
|
|
5
|
+
* 并给出回访承诺(handoff)、或明确暂停。绝不允许第四态:流死掉、什么
|
|
6
|
+
* 都没交付(2026-09-02 轨迹的失败形态)。
|
|
7
|
+
*
|
|
8
|
+
* - 阈值不再固定:每次 user/message 由 `turn-policy.ts` 的确定性分类器
|
|
9
|
+
* 解析 TurnPolicy(softMs/hardMs/exit);benchmark opt-in 用 fixedPolicy
|
|
10
|
+
* 钉死以保证可复现。
|
|
11
|
+
* - 硬阈拒绝时**同步**抑制工具 schema(防同 step 回环),并按 exit 语义
|
|
12
|
+
* 返回两种结构化结果:converge=用已有证据作答;handoff=落
|
|
13
|
+
* `gotry_turn_handoff.v1` 工单并指令模型告知用户 ETA 与回访方式。
|
|
14
|
+
* - handoff 工单是**新的独立格式**,落在 `<stateRoot>/gotry-state/
|
|
15
|
+
* turn-handoffs/`,不与 `async/` 的 loop 求解工单混用——async-collect
|
|
16
|
+
* 对无 spec 的 state 会立即结算 failed(假失败),收集器是未来的
|
|
17
|
+
* agent tick(loopx),不是 async-collect。
|
|
18
|
+
*/
|
|
19
|
+
import { randomUUID } from 'node:crypto';
|
|
20
|
+
import { mkdir, readdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
21
|
+
import { join } from 'node:path';
|
|
22
|
+
import { classifyTurn, TURN_HANDOFF_ETA_LABEL, turnPolicyFor } from './turn-policy.js';
|
|
23
|
+
export const TURN_DEADLINE_SOFT = 'TURN_DEADLINE_SOFT';
|
|
24
|
+
export const TURN_DEADLINE_EXHAUSTED = 'TURN_DEADLINE_EXHAUSTED';
|
|
25
|
+
export const TURN_DEADLINE_HANDOFF = 'TURN_DEADLINE_HANDOFF';
|
|
26
|
+
export const TURN_HANDOFF_SCHEMA = 'gotry_turn_handoff.v1';
|
|
27
|
+
export async function writeTurnHandoffTicket(stateRoot, userMessage) {
|
|
28
|
+
const ticket = {
|
|
29
|
+
schema: TURN_HANDOFF_SCHEMA,
|
|
30
|
+
id: `th-${Date.now().toString(36)}-${randomUUID().slice(0, 6)}`,
|
|
31
|
+
objective: userMessage.length > 120 ? `${userMessage.slice(0, 120)}…` : userMessage,
|
|
32
|
+
userMessage,
|
|
33
|
+
requestedAt: new Date().toISOString(),
|
|
34
|
+
etaLabel: TURN_HANDOFF_ETA_LABEL,
|
|
35
|
+
status: 'open',
|
|
36
|
+
};
|
|
37
|
+
await writeTicketJson(stateRoot, ticket);
|
|
38
|
+
return ticket;
|
|
39
|
+
}
|
|
40
|
+
function handoffDir(stateRoot) {
|
|
41
|
+
const root = stateRoot === '.' ? process.cwd() : stateRoot;
|
|
42
|
+
return join(root, 'gotry-state', 'turn-handoffs');
|
|
43
|
+
}
|
|
44
|
+
async function writeTicketJson(stateRoot, ticket) {
|
|
45
|
+
const dir = handoffDir(stateRoot);
|
|
46
|
+
await mkdir(dir, { recursive: true });
|
|
47
|
+
const path = join(dir, `${ticket.id}.json`);
|
|
48
|
+
const tmp = `${path}.tmp`;
|
|
49
|
+
await writeFile(tmp, JSON.stringify(ticket, null, 2), 'utf-8');
|
|
50
|
+
await rename(tmp, path);
|
|
51
|
+
return path;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* 结算工单:交付物落 `<id>.deliverable.md`(settled=规划产物;failed=诚实
|
|
55
|
+
* 失败说明),工单 json 原子更新 status/settledAt/deliverableFile/error。
|
|
56
|
+
*/
|
|
57
|
+
export async function settleTurnHandoffTicket(stateRoot, ticket, status, deliverable, error) {
|
|
58
|
+
const dir = handoffDir(stateRoot);
|
|
59
|
+
await mkdir(dir, { recursive: true });
|
|
60
|
+
const deliverablePath = join(dir, `${ticket.id}.deliverable.md`);
|
|
61
|
+
const deliverableTmp = `${deliverablePath}.tmp`;
|
|
62
|
+
await writeFile(deliverableTmp, deliverable, 'utf-8');
|
|
63
|
+
await rename(deliverableTmp, deliverablePath);
|
|
64
|
+
const settled = {
|
|
65
|
+
...ticket,
|
|
66
|
+
status,
|
|
67
|
+
settledAt: new Date().toISOString(),
|
|
68
|
+
deliverableFile: `${ticket.id}.deliverable.md`,
|
|
69
|
+
...(error ? { error } : {}),
|
|
70
|
+
};
|
|
71
|
+
const ticketPath = await writeTicketJson(stateRoot, settled);
|
|
72
|
+
return { ticketPath, deliverablePath };
|
|
73
|
+
}
|
|
74
|
+
/** 复访查询:按请求时间倒序列出工单;settled 附交付物摘录(≤600 字)。 */
|
|
75
|
+
export async function listTurnHandoffTickets(stateRoot) {
|
|
76
|
+
const dir = handoffDir(stateRoot);
|
|
77
|
+
let names;
|
|
78
|
+
try {
|
|
79
|
+
names = await readdir(dir);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
const views = [];
|
|
85
|
+
for (const name of names) {
|
|
86
|
+
if (!name.endsWith('.json'))
|
|
87
|
+
continue;
|
|
88
|
+
try {
|
|
89
|
+
const raw = JSON.parse(await readFile(join(dir, name), 'utf-8'));
|
|
90
|
+
if (raw?.schema !== TURN_HANDOFF_SCHEMA)
|
|
91
|
+
continue;
|
|
92
|
+
const view = {
|
|
93
|
+
id: raw.id,
|
|
94
|
+
status: raw.status,
|
|
95
|
+
objective: raw.objective,
|
|
96
|
+
requestedAt: raw.requestedAt,
|
|
97
|
+
etaLabel: raw.etaLabel,
|
|
98
|
+
...(raw.settledAt ? { settledAt: raw.settledAt } : {}),
|
|
99
|
+
...(raw.error ? { error: raw.error } : {}),
|
|
100
|
+
};
|
|
101
|
+
if (raw.status !== 'open' && raw.deliverableFile) {
|
|
102
|
+
try {
|
|
103
|
+
const text = await readFile(join(dir, raw.deliverableFile), 'utf-8');
|
|
104
|
+
view.deliverableExcerpt = text.length > 600 ? `${text.slice(0, 600)}…` : text;
|
|
105
|
+
}
|
|
106
|
+
catch { /* 交付物缺失时视图降级,不阻塞列表 */ }
|
|
107
|
+
}
|
|
108
|
+
views.push(view);
|
|
109
|
+
}
|
|
110
|
+
catch { /* 单个坏工单不阻塞列表 */ }
|
|
111
|
+
}
|
|
112
|
+
views.sort((a, b) => (a.requestedAt < b.requestedAt ? 1 : -1));
|
|
113
|
+
return views;
|
|
114
|
+
}
|
|
115
|
+
function resolveEnvPin(name) {
|
|
116
|
+
const raw = process.env[name];
|
|
117
|
+
if (!raw)
|
|
118
|
+
return null;
|
|
119
|
+
const parsed = Number.parseInt(raw, 10);
|
|
120
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
|
|
121
|
+
}
|
|
122
|
+
function convergenceContext(code, text) {
|
|
123
|
+
return {
|
|
124
|
+
id: randomUUID(),
|
|
125
|
+
role: 'user',
|
|
126
|
+
content: [{ type: 'text', text: `${code}: ${text}` }],
|
|
127
|
+
// 0.2.0-rc.2(V4 会话格式)移除 'plugin' source kind;运行时自产注入归 system-prompt。
|
|
128
|
+
source: { kind: 'system-prompt' },
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function exhaustionResult(reason) {
|
|
132
|
+
return {
|
|
133
|
+
isError: true,
|
|
134
|
+
error: {
|
|
135
|
+
message: reason,
|
|
136
|
+
info: { name: 'TurnDeadlineError', code: TURN_DEADLINE_EXHAUSTED },
|
|
137
|
+
},
|
|
138
|
+
content: [{ type: 'text', text: reason }],
|
|
139
|
+
additionalContexts: [convergenceContext(TURN_DEADLINE_EXHAUSTED, 'No more tool dispatches are permitted in this turn. Produce the final answer from existing results.')],
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
function handoffResult(ticket) {
|
|
143
|
+
const instruction = `Turn handed off to background planning. Async ticket ${ticket.id} created (ETA ${ticket.etaLabel}). Stop dispatching tools and tell the user in one short message: the deep planning continues in the background, the expected time, and to check back later (mention ticket ${ticket.id}).`;
|
|
144
|
+
return {
|
|
145
|
+
isError: true,
|
|
146
|
+
error: {
|
|
147
|
+
message: `${TURN_DEADLINE_HANDOFF}: sync window exhausted for a deep-planning turn; ticket ${ticket.id}`,
|
|
148
|
+
info: { name: 'TurnDeadlineHandoff', code: TURN_DEADLINE_HANDOFF },
|
|
149
|
+
},
|
|
150
|
+
content: [{ type: 'text', text: `${TURN_DEADLINE_HANDOFF}: ${instruction}` }],
|
|
151
|
+
additionalContexts: [convergenceContext(TURN_DEADLINE_HANDOFF, instruction)],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Install the runtime boundary, kept separate from the GoTry tool catalog so
|
|
156
|
+
* the actual Cordis waterfalls can be exercised without booting every tool.
|
|
157
|
+
*/
|
|
158
|
+
export function installTurnDeadline(ctx, options = {}) {
|
|
159
|
+
if (options.enabled === false)
|
|
160
|
+
return;
|
|
161
|
+
// Some offline contract tests intentionally provide a registration-only
|
|
162
|
+
// Context slice. They do not drive an agent loop, so there is no boundary
|
|
163
|
+
// to install and no reason to require an event bus.
|
|
164
|
+
if (typeof ctx.on !== 'function')
|
|
165
|
+
return;
|
|
166
|
+
const now = options.now ?? (() => Date.now());
|
|
167
|
+
// Test/benchmark seam only: pin the resolved numbers without touching the
|
|
168
|
+
// routed exit strategy. Product runs never set these.
|
|
169
|
+
const softPin = resolveEnvPin('GOTRY_TURN_DEADLINE_SOFT_MS');
|
|
170
|
+
const hardPin = resolveEnvPin('GOTRY_TURN_DEADLINE_HARD_MS');
|
|
171
|
+
const defaultPolicy = options.fixedPolicy ?? turnPolicyFor('sync-planning');
|
|
172
|
+
const routePolicy = (message) => {
|
|
173
|
+
if (options.fixedPolicy)
|
|
174
|
+
return { ...options.fixedPolicy };
|
|
175
|
+
const policy = turnPolicyFor(classifyTurn(message));
|
|
176
|
+
return { ...policy, softMs: softPin ?? policy.softMs, hardMs: hardPin ?? policy.hardMs };
|
|
177
|
+
};
|
|
178
|
+
const stateByAgent = new Map();
|
|
179
|
+
const softExecutions = new Map();
|
|
180
|
+
const finalOnlyDisposers = new Map();
|
|
181
|
+
const clearAgent = (agentId) => {
|
|
182
|
+
stateByAgent.delete(agentId);
|
|
183
|
+
for (const [token, owner] of softExecutions) {
|
|
184
|
+
if (owner.agentId === agentId)
|
|
185
|
+
softExecutions.delete(token);
|
|
186
|
+
}
|
|
187
|
+
finalOnlyDisposers.get(agentId)?.();
|
|
188
|
+
finalOnlyDisposers.delete(agentId);
|
|
189
|
+
};
|
|
190
|
+
const enterFinalOnly = (agent) => {
|
|
191
|
+
const agentId = String(agent.id);
|
|
192
|
+
if (finalOnlyDisposers.has(agentId))
|
|
193
|
+
return;
|
|
194
|
+
const globalTools = ctx.tools;
|
|
195
|
+
const scopedTools = agent.ctx?.tools;
|
|
196
|
+
if (typeof globalTools.schemas !== 'function' || typeof scopedTools?.restrict !== 'function') {
|
|
197
|
+
// No registry to suppress: subsequent tool calls in the same turn hit the
|
|
198
|
+
// same per-call denial branch and stay refused until the next turn.
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const inheritedNames = globalTools.schemas()
|
|
202
|
+
.map(schema => schema.name)
|
|
203
|
+
.filter(name => name !== 'run_code');
|
|
204
|
+
if (inheritedNames.length === 0)
|
|
205
|
+
return;
|
|
206
|
+
finalOnlyDisposers.set(agentId, scopedTools.restrict({ deny: inheritedNames }));
|
|
207
|
+
};
|
|
208
|
+
// 事件主体是 session 对象;agent 归属同一 session 时共用同一预算键。
|
|
209
|
+
const keyOfAgent = (agent) => {
|
|
210
|
+
const session = agent.session;
|
|
211
|
+
return String(session?.id ?? agent.id);
|
|
212
|
+
};
|
|
213
|
+
ctx.on('session/event', (subject, event) => {
|
|
214
|
+
const agentId = String(subject.id);
|
|
215
|
+
if (event.type === 'turn/end') {
|
|
216
|
+
clearAgent(agentId);
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
if (event.type === 'turn/start') {
|
|
220
|
+
finalOnlyDisposers.get(agentId)?.();
|
|
221
|
+
finalOnlyDisposers.delete(agentId);
|
|
222
|
+
if (!stateByAgent.has(agentId)) {
|
|
223
|
+
stateByAgent.set(agentId, {
|
|
224
|
+
startedAt: now(),
|
|
225
|
+
policy: { ...defaultPolicy, softMs: softPin ?? defaultPolicy.softMs, hardMs: hardPin ?? defaultPolicy.hardMs },
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
if (event.type === 'user/message') {
|
|
231
|
+
// dsh 事件载荷在 event.data 下(benchmark-agent-conformance 同型读法)。
|
|
232
|
+
const message = event.data;
|
|
233
|
+
if (message?.source?.kind !== 'user')
|
|
234
|
+
return;
|
|
235
|
+
const text = (message.content ?? []).find(block => block.type === 'text')?.text ?? '';
|
|
236
|
+
if (!text.trim())
|
|
237
|
+
return;
|
|
238
|
+
// 每个 user 消息 = 新的预算:路由分类 + 时钟重置。plugin/skill 注入
|
|
239
|
+
// 的 user/message(source.kind !== 'user')不参与路由。
|
|
240
|
+
stateByAgent.set(agentId, { startedAt: now(), policy: routePolicy(text), userMessage: text });
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
ctx.on('session/disposed', subject => clearAgent(String(subject.id)));
|
|
244
|
+
ctx.on('tools/execute', (exec, next) => {
|
|
245
|
+
// Programmatic/direct calls are not part of a model planner turn.
|
|
246
|
+
if (!exec.agent)
|
|
247
|
+
return next();
|
|
248
|
+
const agentId = keyOfAgent(exec.agent);
|
|
249
|
+
const state = stateByAgent.get(agentId)
|
|
250
|
+
?? { startedAt: now(), policy: { ...defaultPolicy, softMs: softPin ?? defaultPolicy.softMs, hardMs: hardPin ?? defaultPolicy.hardMs } };
|
|
251
|
+
stateByAgent.set(agentId, state);
|
|
252
|
+
const elapsed = now() - state.startedAt;
|
|
253
|
+
if (elapsed > state.policy.hardMs) {
|
|
254
|
+
// Synchronous schema suppression so same-step follow-up calls cannot
|
|
255
|
+
// loop on refusal results (the 2026-09-02 trajectory failure).
|
|
256
|
+
enterFinalOnly(exec.agent);
|
|
257
|
+
if (state.policy.exit === 'handoff' && state.userMessage && options.stateRoot) {
|
|
258
|
+
return writeTurnHandoffTicket(options.stateRoot, state.userMessage)
|
|
259
|
+
.then(ticket => handoffResult(ticket))
|
|
260
|
+
.catch(() => exhaustionResult(`${TURN_DEADLINE_EXHAUSTED}: hard deadline ${state.policy.hardMs}ms reached (ticket persistence failed; degraded to converge)`));
|
|
261
|
+
}
|
|
262
|
+
return Promise.resolve(exhaustionResult(`${TURN_DEADLINE_EXHAUSTED}: turn exceeded hard deadline of ${state.policy.hardMs}ms (elapsed ${elapsed}ms); provide a final answer using existing results`));
|
|
263
|
+
}
|
|
264
|
+
if (elapsed > state.policy.softMs) {
|
|
265
|
+
softExecutions.set(exec.token, { agentId, exit: state.policy.exit });
|
|
266
|
+
}
|
|
267
|
+
return next();
|
|
268
|
+
});
|
|
269
|
+
ctx.on('tools/post-execute', (exec, _result, next) => {
|
|
270
|
+
return next().then(decision => {
|
|
271
|
+
const owner = softExecutions.get(exec.token);
|
|
272
|
+
if (!owner)
|
|
273
|
+
return decision;
|
|
274
|
+
softExecutions.delete(exec.token);
|
|
275
|
+
const text = owner.exit === 'handoff'
|
|
276
|
+
? 'Turn has crossed the soft deadline of a deep-planning turn. Wrap up context gathering now; the turn will hand off to background planning at the hard deadline.'
|
|
277
|
+
: 'Turn has crossed the soft deadline. Stop dispatching new tools and produce the final answer from gathered evidence.';
|
|
278
|
+
return {
|
|
279
|
+
...decision,
|
|
280
|
+
additionalContexts: [
|
|
281
|
+
...(decision.additionalContexts ?? []),
|
|
282
|
+
convergenceContext(TURN_DEADLINE_SOFT, text),
|
|
283
|
+
],
|
|
284
|
+
};
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-turn routing & time allocation (ADR-24 v2).
|
|
3
|
+
*
|
|
4
|
+
* 用户主观时间是产品路径唯一的预算:复杂度决定**出口结构**(converge /
|
|
5
|
+
* handoff),时间只是在所选结构内的资源分配。路由在 user/message 落地时
|
|
6
|
+
* 一次完成,纯函数、零 LLM、零 IO——控制面判定必须是确定性组件
|
|
7
|
+
* (stage1 责任铁律;ADR-9 同型先例),且不能花它要分配的资源。
|
|
8
|
+
*
|
|
9
|
+
* Tier 0(消息内禀)是 v1 的全部规则输入;Tier 1(账本读回)只在
|
|
10
|
+
* handoff 落单时用于工单上下文,不参与分类。`loop.ts` 的 isComplex 是
|
|
11
|
+
* S5 循环架构内的访谈后复核,不在产品路径上,不进本层。
|
|
12
|
+
*/
|
|
13
|
+
/** v1 阈值表:数据不是代码;评测/部署换表不换执行器。 */
|
|
14
|
+
export const TURN_POLICIES = {
|
|
15
|
+
// quick:实际上限只是安全网——quick 类历史上没有发散记录。
|
|
16
|
+
quick: { softMs: 120_000, hardMs: 180_000, exit: 'converge' },
|
|
17
|
+
'sync-planning': { softMs: 300_000, hardMs: 600_000, exit: 'converge' },
|
|
18
|
+
// deep-planning:同步窗口只够"摸底 + 落单承诺",到点必须转后台。
|
|
19
|
+
'deep-planning': { softMs: 120_000, hardMs: 240_000, exit: 'handoff' },
|
|
20
|
+
};
|
|
21
|
+
export const TURN_HANDOFF_ETA_LABEL = '约 1 小时';
|
|
22
|
+
/** 约束词表:只作弱信号(命中≥2 才可能推 deep);新增词=加一行+一测。 */
|
|
23
|
+
export const TURN_CONSTRAINT_LEXICON = [
|
|
24
|
+
'婚礼', '婚宴', '回门', '订婚',
|
|
25
|
+
'IRW', 'irw',
|
|
26
|
+
'请假', '年假', '调休', '额度',
|
|
27
|
+
'签证', '同行', '伴侣', '亲子', '带娃', '父母', '团建', '出差',
|
|
28
|
+
'红眼', '中转', '联程', '多城',
|
|
29
|
+
];
|
|
30
|
+
const CN_DIGITS = {
|
|
31
|
+
一: 1, 二: 2, 两: 2, 三: 3, 四: 4, 五: 5, 六: 6, 七: 7, 八: 8, 九: 9, 十: 10,
|
|
32
|
+
};
|
|
33
|
+
function dayCount(year, month, day) {
|
|
34
|
+
// 无年份时按平年锚定:跨度计算只需要差值,月份跨年场景 v1 不覆盖。
|
|
35
|
+
const y = year ?? 1970;
|
|
36
|
+
return Date.UTC(y, month - 1, day) / 86_400_000;
|
|
37
|
+
}
|
|
38
|
+
/** 跨度词 → 估算天数;按声明强度取第一个命中,v1 不做组合。 */
|
|
39
|
+
function spanWordDays(message) {
|
|
40
|
+
if (/十几天/.test(message))
|
|
41
|
+
return 12;
|
|
42
|
+
if (/半个月/.test(message))
|
|
43
|
+
return 15;
|
|
44
|
+
if (/一个月/.test(message))
|
|
45
|
+
return 30;
|
|
46
|
+
const week = message.match(/[一两]个?(?:星期|周)/);
|
|
47
|
+
if (week)
|
|
48
|
+
return week[0].startsWith('两') ? 14 : 7;
|
|
49
|
+
const dayMatch = message.match(/([0-9一二两三四五六七八九十]+)\s*天/);
|
|
50
|
+
if (dayMatch) {
|
|
51
|
+
const raw = dayMatch[1];
|
|
52
|
+
if (/^[0-9]+$/.test(raw))
|
|
53
|
+
return Math.min(Number.parseInt(raw, 10), 60);
|
|
54
|
+
if (CN_DIGITS[raw] !== undefined)
|
|
55
|
+
return Math.min(CN_DIGITS[raw], 60);
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
export function extractTurnSignals(message) {
|
|
60
|
+
const absoluteDates = [];
|
|
61
|
+
// 完整日期先摘除,避免 2026-10-03 再被月/日模式重复计数。
|
|
62
|
+
let rest = message.replace(/(?<!\d)(\d{4})[年\-.\/](\d{1,2})[月\-.\/](\d{1,2})日?(?!\d)/g, (_all, y, m, d) => {
|
|
63
|
+
const month = Number.parseInt(m, 10);
|
|
64
|
+
const day = Number.parseInt(d, 10);
|
|
65
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
66
|
+
absoluteDates.push({ year: Number.parseInt(y, 10), month, day });
|
|
67
|
+
}
|
|
68
|
+
return ' ';
|
|
69
|
+
});
|
|
70
|
+
rest = rest.replace(/(?<!\d)(\d{1,2})月(\d{1,2})日?(?!\d)/g, (_all, m, d) => {
|
|
71
|
+
const month = Number.parseInt(m, 10);
|
|
72
|
+
const day = Number.parseInt(d, 10);
|
|
73
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
74
|
+
absoluteDates.push({ year: null, month, day });
|
|
75
|
+
}
|
|
76
|
+
return ' ';
|
|
77
|
+
});
|
|
78
|
+
rest = rest.replace(/(?<!\d)(\d{1,2})[.\/](\d{1,2})(?!\d)/g, (_all, m, d) => {
|
|
79
|
+
const month = Number.parseInt(m, 10);
|
|
80
|
+
const day = Number.parseInt(d, 10);
|
|
81
|
+
if (month >= 1 && month <= 12 && day >= 1 && day <= 31) {
|
|
82
|
+
absoluteDates.push({ year: null, month, day });
|
|
83
|
+
}
|
|
84
|
+
return ' ';
|
|
85
|
+
});
|
|
86
|
+
const constraintHits = TURN_CONSTRAINT_LEXICON.filter(word => message.includes(word));
|
|
87
|
+
let spanDays = null;
|
|
88
|
+
if (absoluteDates.length >= 2) {
|
|
89
|
+
const counts = absoluteDates.map(d => dayCount(d.year, d.month, d.day));
|
|
90
|
+
spanDays = Math.max(...counts) - Math.min(...counts);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
spanDays = spanWordDays(message);
|
|
94
|
+
}
|
|
95
|
+
return { messageLength: message.length, absoluteDates, spanDays, constraintHits };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 分类规则(有序,可表测):长跨度或多约束 → deep(转后台);无日期无约束
|
|
99
|
+
* 且短 → quick;其余落默认中间档 sync-planning。误分有界:三态出口保证
|
|
100
|
+
* 最坏结局是"本可当面答的被转了后台"(下一轮可救),而非流死掉。
|
|
101
|
+
*/
|
|
102
|
+
export function classifyTurn(message) {
|
|
103
|
+
const s = extractTurnSignals(message);
|
|
104
|
+
if (s.spanDays !== null && s.spanDays >= 7)
|
|
105
|
+
return 'deep-planning';
|
|
106
|
+
if (s.absoluteDates.length >= 2 && s.constraintHits.length >= 1)
|
|
107
|
+
return 'deep-planning';
|
|
108
|
+
if (s.constraintHits.length >= 2 && (s.absoluteDates.length >= 1 || s.spanDays !== null)) {
|
|
109
|
+
return 'deep-planning';
|
|
110
|
+
}
|
|
111
|
+
if (s.absoluteDates.length === 0 && s.constraintHits.length === 0 && s.spanDays === null && s.messageLength <= 60) {
|
|
112
|
+
return 'quick';
|
|
113
|
+
}
|
|
114
|
+
return 'sync-planning';
|
|
115
|
+
}
|
|
116
|
+
export function turnPolicyFor(taskClass) {
|
|
117
|
+
return { ...TURN_POLICIES[taskClass] };
|
|
118
|
+
}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tz-resolver(v1):IANA 时区权威路径的统一模型输入(Issue #343)。
|
|
3
|
+
*
|
|
4
|
+
* 设计动机:
|
|
5
|
+
* - `ts/src/unified.ts` 既往消费 `tz_offset_min / origin_tz_offset_min / home_tz_offset_min` 数值,
|
|
6
|
+
* 无法表达 DST/历史/未来规则。中国出境首发已跨区(Asia/Shanghai ↔ Asia/Tokyo),
|
|
7
|
+
* 同一班次在不同时点 offset 不同,数值口径不可持续。
|
|
8
|
+
* - 此模块只做 IANA zone + 当地日期 → 确定性 offset(分)。无网络无新依赖;
|
|
9
|
+
* Node24 内置 `Intl.DateTimeFormat` 已足够,并由其构造结果作为 zone authority。
|
|
10
|
+
* - 不存在的"DST 跳过"墙时(spring forward gap)与"两次出现"的"DST 重复"墙时
|
|
11
|
+
* (fall back overlap)必须**显式拒绝**,不允许静默选边——这是 §acceptance 第 2 条。
|
|
12
|
+
* - 结果不依赖 `Date.now`、机器时区或外部 IO;formatter 仅作 module-local cache,同一输入必给同一输出。
|
|
13
|
+
*
|
|
14
|
+
* 不变量:
|
|
15
|
+
* - `offsetMin` 单位 = 分,正值 = 东向 UTC(Asia/Tokyo = +540)。
|
|
16
|
+
* - 输入校验失败返回结构化失败;调用方显式决定是否拒绝。
|
|
17
|
+
* - unknown zone / gap / overlap 用同名 `string` 字段区分(returned object 形态);
|
|
18
|
+
* 调用方负责转 typed error。
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* 以同一份 formatter cache 作为 zone authority。
|
|
22
|
+
* `Intl.supportedValuesOf` 不是完整 authority(例如 `US/Pacific` 等 alias 可能不列出),
|
|
23
|
+
* 而 `Intl.DateTimeFormat` 会接受合法 alias 并拒绝 `Foo/Bar`。
|
|
24
|
+
*/
|
|
25
|
+
export function isKnownZoneLoose(zone) {
|
|
26
|
+
try {
|
|
27
|
+
wallFormatter(zone);
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
// 每个 zone 缓存一份 Intl.DateTimeFormat(root 要求:不要为每条候选 instant 重造)。
|
|
35
|
+
// Node 的 DateTimeFormat 本身不可缓存结果(因 ms 输入不同),但实例可重用(无外部 IO)。
|
|
36
|
+
const FMT_CACHE = new Map();
|
|
37
|
+
function wallFormatter(zone) {
|
|
38
|
+
let f = FMT_CACHE.get(zone);
|
|
39
|
+
if (f)
|
|
40
|
+
return f;
|
|
41
|
+
f = new Intl.DateTimeFormat('en-US', {
|
|
42
|
+
timeZone: zone,
|
|
43
|
+
year: 'numeric', month: '2-digit', day: '2-digit',
|
|
44
|
+
hour: '2-digit', minute: '2-digit',
|
|
45
|
+
hour12: false,
|
|
46
|
+
});
|
|
47
|
+
FMT_CACHE.set(zone, f);
|
|
48
|
+
return f;
|
|
49
|
+
}
|
|
50
|
+
/** UTC instant → 该 zone 的墙时分量。导出用于 workWindowBlocks 把 depUtcMs 投影到 home zone。 */
|
|
51
|
+
export function readWallParts(zone, ms) {
|
|
52
|
+
const parts = wallFormatter(zone).formatToParts(new Date(ms));
|
|
53
|
+
const out = {};
|
|
54
|
+
for (const p of parts)
|
|
55
|
+
out[p.type] = p.value;
|
|
56
|
+
// Intl en-US hour12:false 在午夜 0:00 有时给 "24";规范化回 "00"
|
|
57
|
+
let hour = Number(out.hour);
|
|
58
|
+
if (hour === 24)
|
|
59
|
+
hour = 0;
|
|
60
|
+
return {
|
|
61
|
+
year: Number(out.year),
|
|
62
|
+
month: Number(out.month),
|
|
63
|
+
day: Number(out.day),
|
|
64
|
+
hour,
|
|
65
|
+
minute: Number(out.minute),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** wall 时分量 → ISO yyyy-mm-dd hh:mm 表示(供 parseFlightPackToSpecV2 work window 用)。 */
|
|
69
|
+
export function wallPartsToIso(p) {
|
|
70
|
+
return {
|
|
71
|
+
ymd: `${String(p.year).padStart(4, '0')}-${String(p.month).padStart(2, '0')}-${String(p.day).padStart(2, '0')}`,
|
|
72
|
+
hhmm: `${String(p.hour).padStart(2, '0')}:${String(p.minute).padStart(2, '0')}`,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function wallEqual(a, b) {
|
|
76
|
+
return a.year === b.year && a.month === b.month && a.day === b.day && a.hour === b.hour && a.minute === b.minute;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* IANA zone + 当地日期 + 当地时间 → 确定性 offset(分)与对应 UTC instant。
|
|
80
|
+
*
|
|
81
|
+
* 失败 4 类:
|
|
82
|
+
* unknown_zone — `Intl.DateTimeFormat` 不接受该 zone。
|
|
83
|
+
* malformed_input — ymd / hhmm 解析失败或非法(wall 不存在的月日,如 2-30)。
|
|
84
|
+
* gap_nonexistent — DST spring-forward 跳过该墙时(墙上 02:30 不存在)。
|
|
85
|
+
* overlap_ambiguous — DST fall-back 重复该墙时(墙上 01:30 发生两次)。
|
|
86
|
+
*
|
|
87
|
+
* 实现要点:
|
|
88
|
+
* - 把 ymd/hhmm 当作 UTC 算 epoch 得到候选点 `wallAsUtcMs`;
|
|
89
|
+
* - 计算该候选点 offset 用 longOffset 解析,得到"大概"UTC;
|
|
90
|
+
* - 在 ±14h 内以 1 分步长扫描,统计能映射回同一 wall 的候选数:
|
|
91
|
+
* 0 → gap;1 → 唯一;≥2 → overlap。
|
|
92
|
+
* - 唯一候选 offset 即结果。
|
|
93
|
+
*/
|
|
94
|
+
export function resolveOffsetForLocalDate(zone, ymd, hhmm) {
|
|
95
|
+
if (!isKnownZoneLoose(zone))
|
|
96
|
+
return { ok: false, kind: 'unknown_zone', zone };
|
|
97
|
+
const dateMatch = ymd.match(/^(\d{4})-(\d{2})-(\d{2})$/);
|
|
98
|
+
if (!dateMatch)
|
|
99
|
+
return { ok: false, kind: 'malformed_input', zone, reason: `bad date ${ymd}` };
|
|
100
|
+
const timeMatch = hhmm.match(/^(\d{2}):(\d{2})$/);
|
|
101
|
+
if (!timeMatch)
|
|
102
|
+
return { ok: false, kind: 'malformed_input', zone, reason: `bad time ${hhmm}` };
|
|
103
|
+
const y = Number(dateMatch[1]);
|
|
104
|
+
const mo = Number(dateMatch[2]);
|
|
105
|
+
const d = Number(dateMatch[3]);
|
|
106
|
+
const h = Number(timeMatch[1]);
|
|
107
|
+
const mi = Number(timeMatch[2]);
|
|
108
|
+
if (mo < 1 || mo > 12 || d < 1 || d > 31 || h < 0 || h > 23 || mi < 0 || mi > 59) {
|
|
109
|
+
return { ok: false, kind: 'malformed_input', zone, reason: `out-of-range ${ymd} ${hhmm}` };
|
|
110
|
+
}
|
|
111
|
+
const want = { year: y, month: mo, day: d, hour: h, minute: mi };
|
|
112
|
+
const wallAsUtcMs = Date.UTC(y, mo - 1, d, h, mi);
|
|
113
|
+
// ±14h 1-min 步长扫描;此范围覆盖全球 ±14:00 时区(含政治区)+ DST 1-2h 偏移
|
|
114
|
+
const matches = [];
|
|
115
|
+
for (let offMin = -14 * 60; offMin <= 14 * 60; offMin++) {
|
|
116
|
+
// 假 wall 是 UTC,实际 UTC 与 wall 相差 offMin 分钟。
|
|
117
|
+
// wall = UTC + offMin ⇒ UTC = wall - offMin。
|
|
118
|
+
const ms = wallAsUtcMs - offMin * 60_000;
|
|
119
|
+
const local = readWallParts(zone, ms);
|
|
120
|
+
if (wallEqual(local, want)) {
|
|
121
|
+
matches.push({ offsetMin: offMin, utcMs: ms });
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (matches.length === 0)
|
|
125
|
+
return { ok: false, kind: 'gap_nonexistent', zone, ymd, hhmm };
|
|
126
|
+
if (matches.length > 1)
|
|
127
|
+
return { ok: false, kind: 'overlap_ambiguous', zone, ymd, hhmm };
|
|
128
|
+
return { ok: true, offsetMin: matches[0].offsetMin, utcMs: matches[0].utcMs };
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 仅取 offset(分),不返回 utcMs;若失败给出失败描述字符串(便于 wire 到 red_flags / unsat_core)。
|
|
132
|
+
*
|
|
133
|
+
* `unknown != null` 语义在调用方需要的场景(差异日志)很贵,故另开轻 API;
|
|
134
|
+
* 主路径应使用 `resolveOffsetForLocalDate` 的 discriminated union。
|
|
135
|
+
*/
|
|
136
|
+
export function describeResolveFailure(f) {
|
|
137
|
+
switch (f.kind) {
|
|
138
|
+
case 'unknown_zone': return `unknown IANA zone: ${f.zone}`;
|
|
139
|
+
case 'malformed_input': return `malformed input (${f.reason}) for zone ${f.zone}`;
|
|
140
|
+
case 'gap_nonexistent': return `DST gap (wall time skipped) in ${f.zone} at ${f.ymd} ${f.hhmm}`;
|
|
141
|
+
case 'overlap_ambiguous': return `DST overlap (wall time ambiguous) in ${f.zone} at ${f.ymd} ${f.hhmm}`;
|
|
142
|
+
}
|
|
143
|
+
}
|