@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,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure-JavaScript dsh plugin for the embedded Booking Copilot profile.
|
|
3
|
+
*
|
|
4
|
+
* It registers one tool per typed planning action kind plus one terminal tool.
|
|
5
|
+
* Every action tool advertises a single concrete closed schema (const kind +
|
|
6
|
+
* that kind's input + intent) instead of a union, because provider tool-call
|
|
7
|
+
* support for top-level anyOf is unreliable outside DeepSeek: weaker models
|
|
8
|
+
* either drop the union or imitate the canonical receipts they see in context.
|
|
9
|
+
* There is no Book/payment tool and no access to HotelByte credentials or
|
|
10
|
+
* business APIs. The tool body only acknowledges a typed decision;
|
|
11
|
+
* PortalBookingPort remains the sole executor after the parent adapter
|
|
12
|
+
* validates the canonical action.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import Ajv2020 from 'ajv/dist/2020.js'
|
|
16
|
+
import { ToolArgsError } from '@deepseek-ai/dsh-tools'
|
|
17
|
+
import {
|
|
18
|
+
canonicalBookingActionSchemaForKind,
|
|
19
|
+
canonicalBookingIntentProjectionSchema,
|
|
20
|
+
dshBookingActionSchemaForKind,
|
|
21
|
+
dshBookingIntentProjectionSchema,
|
|
22
|
+
} from './canonical-schema.js'
|
|
23
|
+
|
|
24
|
+
export const name = 'gotry-embedded-booking'
|
|
25
|
+
export const inject = ['tools']
|
|
26
|
+
|
|
27
|
+
const string = { type: 'string' }
|
|
28
|
+
const plannerSafeRefPattern = '^[A-Za-z0-9][A-Za-z0-9:._-]*$'
|
|
29
|
+
const plannerSafeFactRefPattern = '^(?!modelref:)[A-Za-z0-9][A-Za-z0-9:._-]*$'
|
|
30
|
+
|
|
31
|
+
function isPlainRecord(value) {
|
|
32
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) return false
|
|
33
|
+
const prototype = Object.getPrototypeOf(value)
|
|
34
|
+
return prototype === Object.prototype || prototype === null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function exactKeys(value, allowed) {
|
|
38
|
+
return isPlainRecord(value)
|
|
39
|
+
&& Object.keys(value).length === allowed.length
|
|
40
|
+
&& Object.keys(value).every((key) => allowed.includes(key))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function decisionBranchKeys(decision) {
|
|
44
|
+
if (!isPlainRecord(decision) || typeof decision.kind !== 'string') return null
|
|
45
|
+
const branch = {
|
|
46
|
+
operation: 'action',
|
|
47
|
+
question: 'question',
|
|
48
|
+
explanation: 'explanation',
|
|
49
|
+
terminal: 'terminal',
|
|
50
|
+
error: 'error',
|
|
51
|
+
}[decision.kind]
|
|
52
|
+
return branch ? ['kind', branch] : null
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function exactDecision(decision) {
|
|
56
|
+
const keys = decisionBranchKeys(decision)
|
|
57
|
+
if (keys === null) return false
|
|
58
|
+
return decision.kind === 'operation'
|
|
59
|
+
? exactKeys(decision, [...keys, 'intent'])
|
|
60
|
+
: exactKeys(decision, keys)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Provider compatibility is deliberately structural and one-layer only. It
|
|
64
|
+
// accepts the two JSON-equivalent serializations observed in OpenAI-compatible
|
|
65
|
+
// tool streams (a stringified decision member or a directly-hoisted decision),
|
|
66
|
+
// but never scans prose, strips arbitrary siblings, or recursively parses.
|
|
67
|
+
function normalizeProviderDecisionEnvelope(args) {
|
|
68
|
+
if (!isPlainRecord(args)) return null
|
|
69
|
+
let envelope = args
|
|
70
|
+
if (exactDecision(args)) envelope = { decision: args }
|
|
71
|
+
if (!exactKeys(envelope, ['decision'])) return null
|
|
72
|
+
let decision = envelope.decision
|
|
73
|
+
if (typeof decision === 'string') {
|
|
74
|
+
try {
|
|
75
|
+
decision = JSON.parse(decision)
|
|
76
|
+
} catch {
|
|
77
|
+
return null
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (!exactDecision(decision)) return null
|
|
81
|
+
return { decision }
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function closedObject(properties, required = Object.keys(properties)) {
|
|
85
|
+
return { type: 'object', properties, required, additionalProperties: false }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function actionSchema(kind, schema = dshBookingActionSchemaForKind(kind)) {
|
|
89
|
+
return {
|
|
90
|
+
...schema,
|
|
91
|
+
properties: {
|
|
92
|
+
...schema.properties,
|
|
93
|
+
actionId: { ...schema.properties.actionId, pattern: plannerSafeRefPattern },
|
|
94
|
+
factRefs: {
|
|
95
|
+
...schema.properties.factRefs,
|
|
96
|
+
items: { ...schema.properties.factRefs.items, pattern: plannerSafeFactRefPattern, maxLength: 512 },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function semanticInputSchema(value) {
|
|
103
|
+
if (Array.isArray(value)) return value.map(semanticInputSchema)
|
|
104
|
+
if (!isPlainRecord(value)) return value
|
|
105
|
+
const projected = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, semanticInputSchema(item)]))
|
|
106
|
+
// Money provenance is runtime-owned. The model supplies the amount and may
|
|
107
|
+
// name a currency; the planner binds it to the durable user turn and uses
|
|
108
|
+
// the authoritative workspace currency when the model omits one.
|
|
109
|
+
if (isPlainRecord(projected.properties)
|
|
110
|
+
&& Object.prototype.hasOwnProperty.call(projected.properties, 'amount')
|
|
111
|
+
&& Object.prototype.hasOwnProperty.call(projected.properties, 'currency')
|
|
112
|
+
&& Object.prototype.hasOwnProperty.call(projected.properties, 'sourceFactRef')) {
|
|
113
|
+
const { sourceFactRef: _sourceFactRef, ...properties } = projected.properties
|
|
114
|
+
projected.properties = properties
|
|
115
|
+
projected.required = Array.isArray(projected.required)
|
|
116
|
+
? projected.required.filter((key) => key !== 'sourceFactRef' && key !== 'currency')
|
|
117
|
+
: projected.required
|
|
118
|
+
}
|
|
119
|
+
return projected
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function intentProposalSchema(schema) {
|
|
123
|
+
const semantic = semanticInputSchema(schema)
|
|
124
|
+
const { schemaVersion: _schemaVersion, ...properties } = semantic.properties
|
|
125
|
+
return {
|
|
126
|
+
...semantic,
|
|
127
|
+
properties,
|
|
128
|
+
required: semantic.required.filter((key) => key !== 'schemaVersion'),
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function actionProposalSchema(kind, canonical = dshBookingActionSchemaForKind(kind), intent = intentProposalSchema(dshBookingIntentProjectionSchema())) {
|
|
133
|
+
return closedObject({
|
|
134
|
+
kind: canonical.properties.kind,
|
|
135
|
+
input: semanticInputSchema(canonical.properties.input),
|
|
136
|
+
intent,
|
|
137
|
+
}, ['kind', 'input', 'intent'])
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Per-tool guidance: the exact argument shape for this one action kind. */
|
|
141
|
+
const KIND_ARGUMENT_GUIDE = {
|
|
142
|
+
'search.patch': 'input.patch property names are EXACT: destination, hotel, stay, occupancy, budget, starRating, guestRating, facilities, distance. There is no "criteria" property. Amenities (pool, parking) go under facilities; included breakfast/meal-plan and free-cancellation belong in intent.offerCriteria, never in facilities. An accepted patch is compiled into search.run by the runtime itself.',
|
|
143
|
+
'search.run': 'input is always exactly {} — the runtime runs the draft criteria as-is.',
|
|
144
|
+
'results.view.patch': 'input.patch adjusts only the results view (sort/filter of the current result set); it never changes the draft criteria.',
|
|
145
|
+
'hotel.focus': 'input is exactly {"hotelRef":"<ref quoted from an authoritative receipt>"} — never invent a hotelRef.',
|
|
146
|
+
'hotel.select': 'input is exactly {"hotelRef":"<ref quoted from an authoritative receipt>"} — never invent a hotelRef.',
|
|
147
|
+
'offers.query': 'input is exactly {"hotelRefs":["<ref>",...],"criteria":{...}} with hotelRefs quoted from authoritative receipts.',
|
|
148
|
+
'offers.view.patch': 'input is exactly {"hotelRef":"<ref>","criteria":{...}} adjusting the offer view for that one hotel.',
|
|
149
|
+
'offers.compare': 'input is exactly {"offerRefs":["<ref>",...],"requestedCount":N} with offerRefs quoted from authoritative receipts.',
|
|
150
|
+
'offer.select': 'input is exactly {"offerRef":"<ref>","offerVersionRef":"<ref>"} quoted from authoritative receipts.',
|
|
151
|
+
'offer.check': 'input is exactly {"offerRef":"<ref>","offerVersionRef":"<ref>"} quoted from authoritative receipts.',
|
|
152
|
+
'checkout.prepare': 'input is exactly {"offerRef":"<ref>","offerVersionRef":"<ref>","verifiedOfferRef":"<ref>"} quoted from authoritative receipts.',
|
|
153
|
+
'order.observe': 'input is exactly {"orderRef":"<ref from the trusted order context>"}.',
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function typedActionTool(toolName, kind) {
|
|
157
|
+
const fullIntentProposalSchema = intentProposalSchema(canonicalBookingIntentProjectionSchema())
|
|
158
|
+
const operationDecision = closedObject({
|
|
159
|
+
kind: { type: 'string', const: 'operation' },
|
|
160
|
+
action: actionSchema(kind, canonicalBookingActionSchemaForKind(kind)),
|
|
161
|
+
intent: fullIntentProposalSchema,
|
|
162
|
+
})
|
|
163
|
+
const legacyParameters = closedObject({
|
|
164
|
+
decision: operationDecision,
|
|
165
|
+
})
|
|
166
|
+
const terminalProposal = closedObject({ kind: { type: 'string', const: 'terminal' } })
|
|
167
|
+
// The advertised dsh dialect intentionally omits unsupported numeric/string
|
|
168
|
+
// keywords. Execute-time validation must still use the full canonical
|
|
169
|
+
// semantic input, otherwise dsh can conclude a turn that the parent rejects
|
|
170
|
+
// (for example patch:{}, star=9, an invalid date, or an empty facility list).
|
|
171
|
+
// Throwing ToolArgsError here keeps the correction inside the same bounded
|
|
172
|
+
// model run and prevents a false-success tool/result pair.
|
|
173
|
+
const canonicalProposalSchema = actionProposalSchema(kind, canonicalBookingActionSchemaForKind(kind), fullIntentProposalSchema)
|
|
174
|
+
// One concrete closed schema per tool: const kind + that kind's input +
|
|
175
|
+
// intent. No top-level anyOf — the tool name itself selects the branch.
|
|
176
|
+
const parameters = actionProposalSchema(kind)
|
|
177
|
+
const ajv = new Ajv2020({ allErrors: true, strict: false, ownProperties: true })
|
|
178
|
+
const proposalValidator = ajv.compile(canonicalProposalSchema)
|
|
179
|
+
const validateTerminalProposal = ajv.compile(terminalProposal)
|
|
180
|
+
const validateLegacyArgs = ajv.compile(legacyParameters)
|
|
181
|
+
|
|
182
|
+
function isCompactProposal(value) {
|
|
183
|
+
if (!isPlainRecord(value)) return false
|
|
184
|
+
if (value.kind === kind) {
|
|
185
|
+
return exactKeys(value, ['kind', 'input', 'intent'])
|
|
186
|
+
}
|
|
187
|
+
return value.kind === 'terminal' && exactKeys(value, ['kind'])
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function compactProposal(args, legacyEnvelope) {
|
|
191
|
+
if (isCompactProposal(args)) return args
|
|
192
|
+
if (isPlainRecord(args) && args.kind === 'operation' && isPlainRecord(args.action)) {
|
|
193
|
+
if (exactKeys(args, ['kind', 'action']) && exactKeys(args.action, ['kind', 'input', 'intent'])) {
|
|
194
|
+
return args.action
|
|
195
|
+
}
|
|
196
|
+
if (exactKeys(args, ['kind', 'action', 'intent']) && exactKeys(args.action, ['kind', 'input'])) {
|
|
197
|
+
return { ...args.action, intent: args.intent }
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
if (isPlainRecord(args) && exactKeys(args, ['decision'])) {
|
|
201
|
+
let wrapped = args.decision
|
|
202
|
+
if (typeof wrapped === 'string') {
|
|
203
|
+
try { wrapped = JSON.parse(wrapped) } catch { wrapped = null }
|
|
204
|
+
}
|
|
205
|
+
if (isCompactProposal(wrapped)) return wrapped
|
|
206
|
+
if (isPlainRecord(wrapped) && wrapped.kind === 'operation' && isPlainRecord(wrapped.action)) {
|
|
207
|
+
if (exactKeys(wrapped, ['kind', 'action']) && exactKeys(wrapped.action, ['kind', 'input', 'intent'])) {
|
|
208
|
+
return wrapped.action
|
|
209
|
+
}
|
|
210
|
+
if (exactKeys(wrapped, ['kind', 'action', 'intent']) && exactKeys(wrapped.action, ['kind', 'input'])) {
|
|
211
|
+
return { ...wrapped.action, intent: wrapped.intent }
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const decision = legacyEnvelope?.decision
|
|
216
|
+
if (decision?.kind === 'operation' && isPlainRecord(decision.action)
|
|
217
|
+
&& exactKeys(decision.action, ['kind', 'input', 'intent'])) return decision.action
|
|
218
|
+
return null
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
function acceptedValue(proposal, legacyEnvelope) {
|
|
222
|
+
if (proposal?.kind === 'terminal') return { accepted: true, decisionKind: 'terminal' }
|
|
223
|
+
const legacyAction = legacyEnvelope?.decision?.kind === 'operation'
|
|
224
|
+
&& isPlainRecord(legacyEnvelope.decision.action)
|
|
225
|
+
? legacyEnvelope.decision.action
|
|
226
|
+
: null
|
|
227
|
+
return {
|
|
228
|
+
accepted: true,
|
|
229
|
+
decisionKind: 'operation',
|
|
230
|
+
actionKind: proposal?.kind ?? legacyAction?.kind,
|
|
231
|
+
...(typeof legacyAction?.actionId === 'string' ? { actionId: legacyAction.actionId } : {}),
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function conciseErrors(validator) {
|
|
236
|
+
return (validator?.errors ?? []).slice(0, 8).map((error) => `${error.instancePath || '/'}: ${error.message}`)
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Keep near-miss arguments available to Ajv even when they are not exact
|
|
240
|
+
// enough to become an executable proposal. This gives the model a concrete
|
|
241
|
+
// field-level repair such as "must have required property 'intent'" instead
|
|
242
|
+
// of a generic envelope error, while acceptance still goes through the
|
|
243
|
+
// closed compact/legacy paths above.
|
|
244
|
+
function validationCandidate(args) {
|
|
245
|
+
let candidate = args
|
|
246
|
+
if (isPlainRecord(candidate) && exactKeys(candidate, ['decision'])) {
|
|
247
|
+
candidate = candidate.decision
|
|
248
|
+
if (typeof candidate === 'string') {
|
|
249
|
+
try { candidate = JSON.parse(candidate) } catch { return null }
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (isPlainRecord(candidate) && candidate.kind === 'operation' && isPlainRecord(candidate.action)) {
|
|
253
|
+
const action = candidate.action
|
|
254
|
+
return action.intent === undefined && candidate.intent !== undefined
|
|
255
|
+
? { ...action, intent: candidate.intent }
|
|
256
|
+
: action
|
|
257
|
+
}
|
|
258
|
+
return candidate
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
return Object.freeze({
|
|
262
|
+
name: toolName,
|
|
263
|
+
description: `Emit exactly one typed ${kind} decision for the existing Booking workspace. ${KIND_ARGUMENT_GUIDE[kind] ?? ''} Every operation must carry intent; if task.activeIntent exists, repeat its semantic fields exactly. This capability never books, pays, edits holder/guest data, or calls a supplier. Never emit actionId, contextRef, expectedRevision, factRefs, reason, or schemaVersion — the runtime owns them. Never write the decision as assistant text: answer only with this tool call.`,
|
|
264
|
+
parameters,
|
|
265
|
+
output: {
|
|
266
|
+
schema: closedObject({
|
|
267
|
+
accepted: { type: 'boolean', const: true },
|
|
268
|
+
decisionKind: string,
|
|
269
|
+
actionKind: string,
|
|
270
|
+
actionId: string,
|
|
271
|
+
}, ['accepted', 'decisionKind']),
|
|
272
|
+
render(_args, value) {
|
|
273
|
+
return [{ type: 'text', text: `Typed booking decision accepted (${value.decisionKind}). End this turn.` }]
|
|
274
|
+
},
|
|
275
|
+
},
|
|
276
|
+
async execute(args, exec) {
|
|
277
|
+
// The model authors only semantic action kind/input. Context, revision,
|
|
278
|
+
// action identity, evidence and reason are runtime-owned and therefore
|
|
279
|
+
// absent from the advertised schema. Validation is dispatched by the
|
|
280
|
+
// tool's single known kind so one local mistake does not expand into
|
|
281
|
+
// dozens of union errors.
|
|
282
|
+
const legacyEnvelope = normalizeProviderDecisionEnvelope(args)
|
|
283
|
+
const proposal = compactProposal(args, legacyEnvelope)
|
|
284
|
+
const candidate = proposal ?? validationCandidate(args)
|
|
285
|
+
const proposalValidatorForCandidate = candidate?.kind === 'terminal'
|
|
286
|
+
? validateTerminalProposal
|
|
287
|
+
: candidate?.kind === kind
|
|
288
|
+
? proposalValidator
|
|
289
|
+
: undefined
|
|
290
|
+
const proposalValid = Boolean(proposal && proposalValidatorForCandidate?.(proposal))
|
|
291
|
+
if (proposalValid) {
|
|
292
|
+
exec.concludeTurn()
|
|
293
|
+
return acceptedValue(proposal, legacyEnvelope)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Hidden compatibility accepts a fully canonical action only when the
|
|
297
|
+
// operation also carries the mandatory semantic intent. It is never
|
|
298
|
+
// advertised to the model, and the parent planner repeats every semantic
|
|
299
|
+
// and authority validation before use.
|
|
300
|
+
if (legacyEnvelope && validateLegacyArgs(legacyEnvelope)) {
|
|
301
|
+
exec.concludeTurn()
|
|
302
|
+
return acceptedValue(null, legacyEnvelope)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (!proposalValid) proposalValidatorForCandidate?.(candidate)
|
|
306
|
+
const errors = proposalValidatorForCandidate
|
|
307
|
+
? conciseErrors(proposalValidatorForCandidate)
|
|
308
|
+
: legacyEnvelope?.decision?.kind === 'operation'
|
|
309
|
+
? ['/: runtime-owned action metadata is invalid; emit exactly {"kind":...,"input":...}']
|
|
310
|
+
: [`/: expected a ${kind} proposal with exactly {"kind","input","intent"} (or {"kind":"terminal"} to finish)`]
|
|
311
|
+
throw new ToolArgsError([`decision_schema_violation: ${errors.join('; ')}`])
|
|
312
|
+
},
|
|
313
|
+
})
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function finishTurnTool() {
|
|
317
|
+
return Object.freeze({
|
|
318
|
+
name: 'booking_finish_turn',
|
|
319
|
+
description: 'Finish the planning turn as terminal because the requested waypoint is already reached by an authoritative receipt. Arguments must be exactly {"kind":"terminal"}. The runtime alone owns terminal status, summary, and evidence. Never write the decision as assistant text: answer only with this tool call.',
|
|
320
|
+
parameters: closedObject({ kind: { type: 'string', const: 'terminal' } }, ['kind']),
|
|
321
|
+
output: {
|
|
322
|
+
schema: closedObject({
|
|
323
|
+
accepted: { type: 'boolean', const: true },
|
|
324
|
+
decisionKind: string,
|
|
325
|
+
}, ['accepted', 'decisionKind']),
|
|
326
|
+
render(_args, value) {
|
|
327
|
+
return [{ type: 'text', text: `Typed booking decision accepted (${value.decisionKind}). End this turn.` }]
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
async execute(args, exec) {
|
|
331
|
+
// Compatibility: the terminal proposal is accepted through the same
|
|
332
|
+
// shallow path as the action tools; runtime-owned terminal metadata is
|
|
333
|
+
// never accepted from the model.
|
|
334
|
+
const shallow = isPlainRecord(args) && exactKeys(args, ['kind']) && args.kind === 'terminal'
|
|
335
|
+
const legacyTerminal = !shallow
|
|
336
|
+
&& isPlainRecord(args)
|
|
337
|
+
&& exactKeys(args, ['decision'])
|
|
338
|
+
&& (isPlainRecord(args.decision)
|
|
339
|
+
? exactKeys(args.decision, ['kind']) && args.decision.kind === 'terminal'
|
|
340
|
+
: (typeof args.decision === 'string'
|
|
341
|
+
&& (() => { try { return exactKeys(JSON.parse(args.decision), ['kind']) && JSON.parse(args.decision).kind === 'terminal' } catch { return false } })()))
|
|
342
|
+
if (!shallow && !legacyTerminal) {
|
|
343
|
+
throw new ToolArgsError(['decision_schema_violation: /: arguments must be exactly {"kind":"terminal"}'])
|
|
344
|
+
}
|
|
345
|
+
exec.concludeTurn()
|
|
346
|
+
return { accepted: true, decisionKind: 'terminal' }
|
|
347
|
+
},
|
|
348
|
+
})
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* One tool per action kind. The six historical capability tool names survive
|
|
353
|
+
* as the primary kind of their group so provider streams recorded against the
|
|
354
|
+
* grouped tools still parse; the remaining kinds gained dedicated tools.
|
|
355
|
+
*/
|
|
356
|
+
const EMBEDDED_ACTION_TOOLS = [
|
|
357
|
+
['booking_search_hotels', 'search.patch'],
|
|
358
|
+
['booking_run_search', 'search.run'],
|
|
359
|
+
['booking_refine_results', 'results.view.patch'],
|
|
360
|
+
['booking_focus_hotel', 'hotel.focus'],
|
|
361
|
+
['booking_select_hotel', 'hotel.select'],
|
|
362
|
+
['booking_find_room_offers', 'offers.query'],
|
|
363
|
+
['booking_view_offers', 'offers.view.patch'],
|
|
364
|
+
['booking_compare_offers', 'offers.compare'],
|
|
365
|
+
['booking_select_offer', 'offer.select'],
|
|
366
|
+
['booking_prepare_booking', 'offer.check'],
|
|
367
|
+
['booking_prepare_checkout', 'checkout.prepare'],
|
|
368
|
+
['booking_observe_booking', 'order.observe'],
|
|
369
|
+
]
|
|
370
|
+
|
|
371
|
+
export const embeddedBookingToolDefinitions = Object.freeze([
|
|
372
|
+
...EMBEDDED_ACTION_TOOLS.map(([toolName, kind]) => typedActionTool(toolName, kind)),
|
|
373
|
+
finishTurnTool(),
|
|
374
|
+
])
|
|
375
|
+
|
|
376
|
+
export function apply(ctx) {
|
|
377
|
+
for (const tool of embeddedBookingToolDefinitions) ctx.tools.register(tool)
|
|
378
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline'
|
|
2
|
+
import { DeepSeekHarness, RequestTimeoutError, type DeepSeekHarnessOptions } from '@deepseek-ai/dsh-sdk-client'
|
|
3
|
+
|
|
4
|
+
type Request = { id: number; prompt?: string; sessionId?: string; warmup?: boolean; options?: Record<string, unknown> }
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* What one worker request paid for the SDK initialize handshake: the wall time
|
|
8
|
+
* of the handshake when this request performed it, and zero when the harness
|
|
9
|
+
* was already initialized. Our own process boot has to stay cheap next to the
|
|
10
|
+
* provider budget, so it is measured at the seam that owns it.
|
|
11
|
+
*/
|
|
12
|
+
type BootObservation = { initializeMs: number; mode: 'started' | 'reused' }
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The initialize handshake carries its own deadline (the planner sets it), so
|
|
16
|
+
* an expiry here is a statement about our own runtime, not about the provider.
|
|
17
|
+
* It is typed apart from a hard start failure so a caller can never read a
|
|
18
|
+
* local boot timeout as a model stall.
|
|
19
|
+
*/
|
|
20
|
+
function isHandshakeTimeout(error: unknown): boolean {
|
|
21
|
+
if (error instanceof RequestTimeoutError) return true
|
|
22
|
+
return error instanceof AggregateError && error.errors.some(isHandshakeTimeout)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Closed classification for a failed request. While no handshake has completed,
|
|
27
|
+
* the failure belongs to our own runtime boot; once one has, it belongs to the
|
|
28
|
+
* run that followed it.
|
|
29
|
+
*/
|
|
30
|
+
function failureCode(warmup: boolean, error: unknown): string {
|
|
31
|
+
if (!booted) return isHandshakeTimeout(error) ? 'HARNESS_BOOT_TIMEOUT' : 'HARNESS_START_FAILED'
|
|
32
|
+
return warmup ? 'HARNESS_START_FAILED' : 'HARNESS_RUN_FAILED'
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const input = createInterface({ input: process.stdin, crlfDelay: Infinity })
|
|
36
|
+
let harness: DeepSeekHarness | undefined
|
|
37
|
+
let booted: { initializeMs: number; mode: 'started' } | undefined
|
|
38
|
+
let chain = Promise.resolve()
|
|
39
|
+
|
|
40
|
+
function reply(value: unknown): void {
|
|
41
|
+
process.stdout.write(`${JSON.stringify(value)}\n`)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Start the runtime once and report what this request paid for it. `start()` is
|
|
46
|
+
* memoized by the SDK, so awaiting it before the first run neither spawns twice
|
|
47
|
+
* nor changes the classification a failed start produces.
|
|
48
|
+
*/
|
|
49
|
+
async function startTimed(): Promise<BootObservation> {
|
|
50
|
+
if (booted) return { initializeMs: 0, mode: 'reused' }
|
|
51
|
+
const startedAt = Date.now()
|
|
52
|
+
await harness!.start()
|
|
53
|
+
booted = { initializeMs: Date.now() - startedAt, mode: 'started' }
|
|
54
|
+
return booted
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// The public subprocess handle deliberately hides its PID. This private
|
|
58
|
+
// worker-owned receipt identifies the group when teardown diagnostics fail.
|
|
59
|
+
reply({ lifecycle: 'worker_started', workerPid: process.pid, parentPid: process.ppid })
|
|
60
|
+
|
|
61
|
+
async function handle(request: Request): Promise<void> {
|
|
62
|
+
try {
|
|
63
|
+
harness ??= new DeepSeekHarness((request.options ?? {}) as DeepSeekHarnessOptions)
|
|
64
|
+
// Construction is lazy. Only start() spawns the runtime and awaits its
|
|
65
|
+
// initialize handshake, including the profile, patches and plugins.
|
|
66
|
+
const boot = await startTimed()
|
|
67
|
+
// The handshake is known before the run can stall or be killed, so it is
|
|
68
|
+
// reported as its own checkpoint instead of only on a terminal reply: a
|
|
69
|
+
// cold boot that then times out must still show what the boot cost.
|
|
70
|
+
process.stdout.write(`${JSON.stringify({ id: request.id, boot })}\n`)
|
|
71
|
+
if (request.warmup) {
|
|
72
|
+
reply({ id: request.id, ok: true })
|
|
73
|
+
return
|
|
74
|
+
}
|
|
75
|
+
const result = await harness.run(request.prompt!, {
|
|
76
|
+
sessionId: request.sessionId!,
|
|
77
|
+
// Stream liveness to the parent: every notification (model step, tool
|
|
78
|
+
// call, receipt) resets the parent's idle-stall timer, so a healthy
|
|
79
|
+
// multi-step run is never mistaken for a hung stream.
|
|
80
|
+
onNotification: () => {
|
|
81
|
+
process.stdout.write(`${JSON.stringify({ id: request.id, progress: true })}\n`)
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
reply({ id: request.id, ok: true, result })
|
|
85
|
+
} catch (error) {
|
|
86
|
+
// Raw SDK/provider exceptions may contain URLs, model output or request
|
|
87
|
+
// fragments. Only a closed classification crosses the worker protocol.
|
|
88
|
+
reply({ id: request.id, ok: false, error: failureCode(request.warmup === true, error) })
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
input.on('line', (line) => {
|
|
93
|
+
if (line.trim() === '') return
|
|
94
|
+
let request: Request
|
|
95
|
+
try { request = JSON.parse(line) as Request } catch {
|
|
96
|
+
reply({ id: null, ok: false, error: 'INVALID_WORKER_REQUEST' })
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
chain = chain.then(() => handle(request!))
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
async function shutdown(): Promise<void> {
|
|
103
|
+
input.close()
|
|
104
|
+
await chain
|
|
105
|
+
await harness?.close()
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
process.once('SIGTERM', () => { void shutdown().finally(() => process.exit(143)) })
|
|
109
|
+
process.once('SIGINT', () => { void shutdown().finally(() => process.exit(130)) })
|
|
110
|
+
process.stdin.once('end', () => { void shutdown().finally(() => process.exit(0)) })
|