@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.
Files changed (533) hide show
  1. package/README.md +172 -219
  2. package/README.zh-CN.md +222 -0
  3. package/bin/gotry-backend.js +53 -0
  4. package/bin/gotry-booking-copilot.js +53 -0
  5. package/bin/gotry-bootstrap.js +1788 -0
  6. package/bin/gotry-inner.js +733 -83
  7. package/bin/gotry-process-liveness.d.ts +27 -0
  8. package/bin/gotry-process-liveness.js +97 -0
  9. package/bin/gotry-runtime-resolution.d.ts +27 -0
  10. package/bin/gotry-runtime-resolution.js +49 -0
  11. package/bin/gotry.js +1 -1
  12. package/client/client.js +203 -0
  13. package/cordis.gotry-patch.yml +80 -56
  14. package/data/airline-airports.json +39 -0
  15. package/data/stations-12306-verify.json +524 -0
  16. package/dist/capabilities/agent-reach-deep.js +45 -122
  17. package/dist/capabilities/agent-reach.js +101 -146
  18. package/dist/capabilities/anything.js +161 -94
  19. package/dist/capabilities/artifacts.js +370 -0
  20. package/dist/capabilities/channel-health.js +131 -0
  21. package/dist/capabilities/channel-registry.js +256 -0
  22. package/dist/capabilities/doctor.js +553 -0
  23. package/dist/capabilities/effect.js +394 -0
  24. package/dist/capabilities/external-event.js +149 -0
  25. package/dist/capabilities/fact-log.js +55 -0
  26. package/dist/capabilities/flyai-config.js +337 -0
  27. package/dist/capabilities/flyai.js +947 -110
  28. package/dist/capabilities/fx-contract.js +293 -0
  29. package/dist/capabilities/geo-atlas.js +246 -0
  30. package/dist/capabilities/ground-transfer.js +676 -0
  31. package/dist/capabilities/hbcli.js +260 -123
  32. package/dist/capabilities/hotelbyte-transaction.js +194 -0
  33. package/dist/capabilities/incident-log.js +131 -61
  34. package/dist/capabilities/itinerary-artifact.js +190 -0
  35. package/dist/capabilities/itinerary-deck-artifact.js +194 -0
  36. package/dist/capabilities/itinerary-deck-export.js +339 -0
  37. package/dist/capabilities/lavish-local.js +924 -0
  38. package/dist/capabilities/model-override.js +38 -0
  39. package/dist/capabilities/opensky.js +54 -43
  40. package/dist/capabilities/provider-detail-sanitize.js +64 -0
  41. package/dist/capabilities/resilience.js +191 -0
  42. package/dist/capabilities/route-provider-conformance.js +341 -0
  43. package/dist/capabilities/session/action-cache.js +50 -44
  44. package/dist/capabilities/session/adapters/ctrip-flight.js +120 -62
  45. package/dist/capabilities/session/adapters/ctrip-hotel.js +222 -0
  46. package/dist/capabilities/session/adapters/dida-portal.js +274 -0
  47. package/dist/capabilities/session/adapters/meituan-local.js +35 -54
  48. package/dist/capabilities/session/adapters/rail-12306.js +342 -0
  49. package/dist/capabilities/session/benchmark.js +189 -0
  50. package/dist/capabilities/session/bridge-ledger.js +224 -0
  51. package/dist/capabilities/session/extension-bridge.js +636 -0
  52. package/dist/capabilities/session/extension-channel.js +109 -0
  53. package/dist/capabilities/session/extension-distribution.js +230 -0
  54. package/dist/capabilities/session/extract.js +31 -21
  55. package/dist/capabilities/session/golden-score.js +114 -0
  56. package/dist/capabilities/session/health-watch.js +215 -0
  57. package/dist/capabilities/session/read-guard.js +75 -24
  58. package/dist/capabilities/session/static-flight-golden.js +150 -0
  59. package/dist/capabilities/session/transport.js +97 -83
  60. package/dist/capabilities/session/wizard.js +117 -0
  61. package/dist/capabilities/session-consent.js +178 -0
  62. package/dist/capabilities/session-login.js +170 -0
  63. package/dist/capabilities/session-search.js +635 -44
  64. package/dist/capabilities/spawn-bounded.js +203 -0
  65. package/dist/capabilities/sponsor-plugin.js +341 -0
  66. package/dist/capabilities/visa-policy.js +140 -0
  67. package/dist/capabilities/weather.js +243 -138
  68. package/dist/data/session-golden-20.json +25 -0
  69. package/dist/data/sf-golden-manifest.json +103 -0
  70. package/dist/data/sf-static-routes.json +91 -0
  71. package/dist/scripts/action-cache-tests.js +24 -59
  72. package/dist/scripts/agent-planning-turn-deadline-e2e.js +242 -0
  73. package/dist/scripts/agent-planning-turn-deadline-tests.js +185 -0
  74. package/dist/scripts/agent-reach-deep-tests.js +30 -40
  75. package/dist/scripts/agent-reach-error-tests.js +354 -0
  76. package/dist/scripts/agent-reach-tests.js +26 -18
  77. package/dist/scripts/agent-reach-wrapper-tests.js +50 -50
  78. package/dist/scripts/anything-path-measure-tests.js +133 -0
  79. package/dist/scripts/anything-path-measure.js +150 -0
  80. package/dist/scripts/anything-tests.js +250 -60
  81. package/dist/scripts/artifact-client-contract-tests.js +220 -0
  82. package/dist/scripts/artifacts-capability-tests.js +727 -0
  83. package/dist/scripts/async-collect.js +50 -11
  84. package/dist/scripts/benchmark-environment-bridge-e2e.js +741 -0
  85. package/dist/scripts/benchmark-environment-bridge-tests.js +1452 -0
  86. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +126 -0
  87. package/dist/scripts/booking-copilot-availability-policy-tests.js +265 -0
  88. package/dist/scripts/booking-copilot-bin-proof-tests.js +66 -0
  89. package/dist/scripts/booking-copilot-cleanup-proof-helper.js +76 -0
  90. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +144 -0
  91. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +424 -0
  92. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +2839 -0
  93. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +309 -0
  94. package/dist/scripts/booking-copilot-dsh-readiness-proof.js +238 -0
  95. package/dist/scripts/booking-copilot-dsh-warmer-proof.js +126 -0
  96. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +156 -0
  97. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +70 -0
  98. package/dist/scripts/booking-copilot-intent-proof-tests.js +422 -0
  99. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +184 -0
  100. package/dist/scripts/booking-copilot-planner-live-probe.js +95 -0
  101. package/dist/scripts/booking-copilot-proof-runtime.js +42 -0
  102. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +210 -0
  103. package/dist/scripts/booking-copilot-runtime-proof-tests.js +2349 -0
  104. package/dist/scripts/booking-copilot-server-proof-tests.js +784 -0
  105. package/dist/scripts/booking-copilot-startup-proof-tests.js +94 -0
  106. package/dist/scripts/booking-executor-tests.js +80 -0
  107. package/dist/scripts/booking-recovery-chain-tests.js +182 -0
  108. package/dist/scripts/booking-saga-tests.js +125 -0
  109. package/dist/scripts/booking-surface-contract-proof-tests.js +212 -0
  110. package/dist/scripts/bootstrap-tests.js +1549 -0
  111. package/dist/scripts/bridge-events-tests.js +239 -0
  112. package/dist/scripts/bridge-ledger-tests.js +428 -0
  113. package/dist/scripts/build-changelog.js +238 -0
  114. package/dist/scripts/build-metrics-report.js +331 -0
  115. package/dist/scripts/changelog-tests.js +118 -0
  116. package/dist/scripts/channel-probe-tests.js +103 -0
  117. package/dist/scripts/channel-probe.js +169 -0
  118. package/dist/scripts/channel-registry-tests.js +208 -0
  119. package/dist/scripts/city-scenario-tier-tests.js +234 -0
  120. package/dist/scripts/companion-tests.js +25 -70
  121. package/dist/scripts/dida-cookie-probe.js +87 -0
  122. package/dist/scripts/dida-runner-stop-tests.js +311 -0
  123. package/dist/scripts/dida-sw-probe.js +114 -0
  124. package/dist/scripts/diff-test.js +17 -12
  125. package/dist/scripts/doctor-tests.js +600 -0
  126. package/dist/scripts/drill-multiuser-ledger-tests.js +1076 -0
  127. package/dist/scripts/drill-sdk-descendant-cleanup-tests.js +606 -0
  128. package/dist/scripts/drill-w2a-sensor-tests.js +788 -0
  129. package/dist/scripts/dsh-artifact-e2e.js +279 -0
  130. package/dist/scripts/dsh-artifact-web-e2e.js +675 -0
  131. package/dist/scripts/dsh-http-proxy-sse-proof.js +90 -0
  132. package/dist/scripts/dsh-llm-tests.js +437 -0
  133. package/dist/scripts/dsh-runtime-closure-tests.js +182 -0
  134. package/dist/scripts/dsh-runtime-closure.js +162 -0
  135. package/dist/scripts/dsh-session-v3-migration-proof.js +109 -0
  136. package/dist/scripts/dsh-subprocess-local-proof.js +150 -0
  137. package/dist/scripts/dsh-target-closure-proof.js +178 -0
  138. package/dist/scripts/effect-tests.js +539 -0
  139. package/dist/scripts/engine-run.js +1 -3
  140. package/dist/scripts/engine-tests.js +16 -10
  141. package/dist/scripts/evaluation-cadence-tests.js +174 -0
  142. package/dist/scripts/evaluation-contract-tests.js +268 -0
  143. package/dist/scripts/extension-distribution-cli.js +39 -0
  144. package/dist/scripts/extension-distribution-tests.js +443 -0
  145. package/dist/scripts/extension-tests.js +988 -0
  146. package/dist/scripts/external-event-tests.js +350 -0
  147. package/dist/scripts/fact-gate-tests.js +869 -0
  148. package/dist/scripts/fixtures/extension-bridge-unref-child.mjs +21 -0
  149. package/dist/scripts/flight-hotel-anchor-363-registered-e2e.js +169 -0
  150. package/dist/scripts/flight-malformed-tests.js +159 -0
  151. package/dist/scripts/flyai-setup-tests.js +228 -0
  152. package/dist/scripts/flyai-setup-tool-tests.js +54 -0
  153. package/dist/scripts/flyai-tests.js +692 -0
  154. package/dist/scripts/flyai-tool-registration-contract-tests.js +91 -0
  155. package/dist/scripts/fx-contract-tests.js +201 -0
  156. package/dist/scripts/g5-guard-tests.js +150 -0
  157. package/dist/scripts/g5-guard.js +193 -0
  158. package/dist/scripts/gen-lunar-anchors.js +106 -0
  159. package/dist/scripts/geo-atlas-tests.js +283 -0
  160. package/dist/scripts/gotry-backend-kernel-tests.js +206 -0
  161. package/dist/scripts/gotry-try-demo-tests.js +79 -0
  162. package/dist/scripts/gotry-try-demo.js +49 -0
  163. package/dist/scripts/ground-transfer-tests.js +956 -0
  164. package/dist/scripts/hbcli-e2e-tests.js +159 -0
  165. package/dist/scripts/hbcli-live-optin-tests.js +96 -0
  166. package/dist/scripts/hbcli-release-contract-tests.js +122 -0
  167. package/dist/scripts/hbcli-tests.js +121 -69
  168. package/dist/scripts/health-watch-cli.js +73 -0
  169. package/dist/scripts/hotel-date-gate-tests.js +496 -0
  170. package/dist/scripts/hotelbyte-reconcile-tests.js +141 -0
  171. package/dist/scripts/hotelbyte-spawn-e2e-tests.js +373 -0
  172. package/dist/scripts/i18n-tests.js +41 -0
  173. package/dist/scripts/incident-tests.js +281 -87
  174. package/dist/scripts/issue-194-job-id-guard-tests.js +106 -0
  175. package/dist/scripts/issue-233-cancel-refund-commission-tests.js +392 -0
  176. package/dist/scripts/issue-271-liveness-tests.js +569 -0
  177. package/dist/scripts/issue-289-model-retry-real-tests.js +296 -0
  178. package/dist/scripts/issue-289-model-retry-tests.js +441 -0
  179. package/dist/scripts/issue-289-web-retry-e2e.js +630 -0
  180. package/dist/scripts/issue-338-home-city-e2e.js +577 -0
  181. package/dist/scripts/issue343-real-entry-e2e.js +160 -0
  182. package/dist/scripts/issue436-persisted-routing-e2e.js +247 -0
  183. package/dist/scripts/itinerary-artifact-tests.js +368 -0
  184. package/dist/scripts/itinerary-deck-artifact-tests.js +416 -0
  185. package/dist/scripts/itinerary-deck-export-tests.js +552 -0
  186. package/dist/scripts/itinerary-deck-tests.js +435 -0
  187. package/dist/scripts/itinerary-html-tests.js +426 -0
  188. package/dist/scripts/journey-tests.js +22 -27
  189. package/dist/scripts/kernel-manifest-evidence.js +109 -0
  190. package/dist/scripts/kernel-manifest-gate.js +126 -0
  191. package/dist/scripts/kernel-manifest-tests.js +212 -0
  192. package/dist/scripts/kernel-manifest-trace-entry.js +7 -0
  193. package/dist/scripts/kernel-manifest-trace-hook.mjs +28 -0
  194. package/dist/scripts/kernel-manifest.js +369 -0
  195. package/dist/scripts/lavish-local-tests.js +1226 -0
  196. package/dist/scripts/lavish-product-tools-tests.js +537 -0
  197. package/dist/scripts/ledger-repair-apply-tests.js +316 -0
  198. package/dist/scripts/ledger-repair-plan-tests.js +375 -0
  199. package/dist/scripts/ledger-tests.js +382 -246
  200. package/dist/scripts/ledger-workflow-crash.js +10 -20
  201. package/dist/scripts/m3-cohort-tests.js +714 -0
  202. package/dist/scripts/m3-cohort.js +310 -0
  203. package/dist/scripts/managed-dsh-cleanup-diagnostic-proof.js +184 -0
  204. package/dist/scripts/managed-dsh-close-failure-proof.js +172 -0
  205. package/dist/scripts/managed-dsh-run-port-proof.js +153 -0
  206. package/dist/scripts/managed-dsh-terminal-proof.js +252 -0
  207. package/dist/scripts/map-tools-vendor-package-proof.js +365 -0
  208. package/dist/scripts/memory-capture-tests.js +242 -61
  209. package/dist/scripts/memory-decay-tests.js +18 -52
  210. package/dist/scripts/memory-lifecycle-tests.js +657 -0
  211. package/dist/scripts/memory-lifecycle.js +196 -0
  212. package/dist/scripts/memory-metrics.js +24 -12
  213. package/dist/scripts/memory-value-report.js +631 -0
  214. package/dist/scripts/memory-value-tests.js +328 -0
  215. package/dist/scripts/metrics-report-tests.js +151 -0
  216. package/dist/scripts/model-override-e2e.js +137 -0
  217. package/dist/scripts/nightly-evidence-tests.js +203 -0
  218. package/dist/scripts/nightly-evidence.js +303 -0
  219. package/dist/scripts/nudge-digest.js +39 -28
  220. package/dist/scripts/observability-tests.js +381 -0
  221. package/dist/scripts/onboarding-tests.js +161 -0
  222. package/dist/scripts/opensky-check.js +18 -13
  223. package/dist/scripts/opensky-tests.js +28 -28
  224. package/dist/scripts/outcome-projection-tests.js +427 -0
  225. package/dist/scripts/persona-sim-tests.js +603 -0
  226. package/dist/scripts/persona-sim.js +1081 -0
  227. package/dist/scripts/persona-surface-guard-tests.js +49 -0
  228. package/dist/scripts/pnpm-dsh-closure-proof.js +17 -0
  229. package/dist/scripts/policy-anchor-359-registered-e2e.js +214 -0
  230. package/dist/scripts/price-drift-tests.js +340 -0
  231. package/dist/scripts/price-drift-watch.js +447 -0
  232. package/dist/scripts/probe-poi-tests.js +53 -45
  233. package/dist/scripts/product-metrics.js +483 -0
  234. package/dist/scripts/publish-preverify.js +110 -0
  235. package/dist/scripts/realtime-pricing-tests.js +76 -0
  236. package/dist/scripts/recall-tests.js +513 -0
  237. package/dist/scripts/replay-async.js +22 -18
  238. package/dist/scripts/replay-real.js +18 -18
  239. package/dist/scripts/replay.js +54 -82
  240. package/dist/scripts/route-provider-conformance-tests.js +391 -0
  241. package/dist/scripts/session-attach-diagnose.js +20 -20
  242. package/dist/scripts/session-attach-poc.js +34 -37
  243. package/dist/scripts/session-benchmark.js +180 -0
  244. package/dist/scripts/session-dida-live-e2e.js +199 -0
  245. package/dist/scripts/session-extract-tests.js +14 -35
  246. package/dist/scripts/session-link-tests.js +478 -0
  247. package/dist/scripts/session-login.js +27 -46
  248. package/dist/scripts/session-tests.js +796 -96
  249. package/dist/scripts/session-zone-crash.js +49 -0
  250. package/dist/scripts/session-zone-ledger-tests.js +432 -0
  251. package/dist/scripts/session-zone-observation-tests.js +492 -0
  252. package/dist/scripts/session-zone-observe.js +135 -0
  253. package/dist/scripts/session-zone-wiring-tests.js +566 -0
  254. package/dist/scripts/session-zones-tests.js +374 -0
  255. package/dist/scripts/sf-live-benchmark.js +367 -0
  256. package/dist/scripts/sf-live-challenge-stop-tests.js +453 -0
  257. package/dist/scripts/sf-live-cli-tests.js +92 -0
  258. package/dist/scripts/sf-live-options.js +46 -0
  259. package/dist/scripts/sf-manifest-tests.js +30 -0
  260. package/dist/scripts/sf-manifest.js +33 -0
  261. package/dist/scripts/sf-soft-score-tests.js +67 -0
  262. package/dist/scripts/sf-summary-tests.js +324 -0
  263. package/dist/scripts/sf-summary.js +525 -0
  264. package/dist/scripts/share-tests.js +432 -0
  265. package/dist/scripts/skeleton-check.js +16 -14
  266. package/dist/scripts/skeleton-integration-test.js +28 -11
  267. package/dist/scripts/skills-contract-tests.js +51 -46
  268. package/dist/scripts/smoke-session-gate-tests.js +21 -0
  269. package/dist/scripts/smoke.js +690 -246
  270. package/dist/scripts/spawn-bounded-abort-tests.js +244 -0
  271. package/dist/scripts/sponsor-reuse-tests.js +262 -0
  272. package/dist/scripts/state-cli-tests.js +226 -101
  273. package/dist/scripts/state-cli.js +565 -198
  274. package/dist/scripts/state-repair-cli.js +66 -0
  275. package/dist/scripts/state-repair-tests.js +140 -0
  276. package/dist/scripts/static-golden-tests.js +165 -0
  277. package/dist/scripts/time-eval-tests.js +212 -192
  278. package/dist/scripts/travel-timeline-tests.js +29 -93
  279. package/dist/scripts/turn-handoff-collect-tests.js +169 -0
  280. package/dist/scripts/turn-handoff-collect.js +161 -0
  281. package/dist/scripts/turn-policy-tests.js +55 -0
  282. package/dist/scripts/typed-contract-canary.js +176 -0
  283. package/dist/scripts/tz-resolver-sanity.js +50 -0
  284. package/dist/scripts/tz-resolver-tests.js +584 -0
  285. package/dist/scripts/unified-tests.js +60 -20
  286. package/dist/scripts/visa-policy-tests.js +62 -0
  287. package/dist/scripts/weather-tests.js +276 -41
  288. package/dist/scripts/wish-channel-gate-tests.js +54 -0
  289. package/dist/scripts/write-gate-tests.js +522 -0
  290. package/dist/scripts/z3-lifecycle-fault-tests.js +188 -0
  291. package/dist/scripts/z3-lifecycle-tests.js +170 -0
  292. package/dist/scripts/z3-race-repeat-tests.js +39 -0
  293. package/dist/scripts/z3-race-tests.js +46 -0
  294. package/dist/src/artifact-gate.js +829 -0
  295. package/dist/src/backend/kernel.js +91 -0
  296. package/dist/src/backend/modules/booking-copilot.js +92 -0
  297. package/dist/src/backend/modules/booking-executor.js +124 -0
  298. package/dist/src/backend/modules/session-search.js +551 -0
  299. package/dist/src/benchmark-agent-conformance.js +578 -0
  300. package/dist/src/benchmark-environment-bridge.js +515 -0
  301. package/dist/src/benchmark-headless-child-diagnostics.js +166 -0
  302. package/dist/src/benchmark-tool-isolation.js +151 -0
  303. package/dist/src/bookable-facts.js +533 -0
  304. package/dist/src/booking-saga.js +97 -0
  305. package/dist/src/booking-surface/availability-policy.js +697 -0
  306. package/dist/src/booking-surface/booking-intent.js +43 -0
  307. package/dist/src/booking-surface/cancel-refund-commission.js +379 -0
  308. package/dist/src/booking-surface/canonical-schema.js +116 -0
  309. package/dist/src/booking-surface/contracts.js +75 -0
  310. package/dist/src/booking-surface/dsh-planner.js +1854 -0
  311. package/dist/src/booking-surface/dsh-plugin.js +378 -0
  312. package/dist/src/booking-surface/dsh-worker.js +98 -0
  313. package/dist/src/booking-surface/error-codes.js +231 -0
  314. package/dist/src/booking-surface/index.js +9 -0
  315. package/dist/src/booking-surface/managed-dsh-cleanup-diagnostic.js +97 -0
  316. package/dist/src/booking-surface/managed-dsh-run-port.js +244 -0
  317. package/dist/src/booking-surface/profile.js +24 -0
  318. package/dist/src/booking-surface/recovery-chain.js +367 -0
  319. package/dist/src/booking-surface/runtime.js +1968 -0
  320. package/dist/src/booking-surface/server.js +674 -0
  321. package/dist/src/booking-surface/startup.js +168 -0
  322. package/dist/src/booking-surface/validation.js +261 -0
  323. package/dist/src/bridge.js +20 -13
  324. package/dist/src/city-scenario-tier.js +378 -0
  325. package/dist/src/companions.js +48 -74
  326. package/dist/src/contracts.js +21 -43
  327. package/dist/src/dsh-llm.js +171 -115
  328. package/dist/src/engine.js +276 -193
  329. package/dist/src/evaluation-cadence.js +97 -0
  330. package/dist/src/evaluation-contracts.js +283 -0
  331. package/dist/src/flight-pack-adapter.js +54 -0
  332. package/dist/src/flight-pack-contract.js +2 -0
  333. package/dist/src/flyai-setup-tool.js +70 -0
  334. package/dist/src/gotry-backend.js +125 -0
  335. package/dist/src/hotel-date-gate.js +118 -0
  336. package/dist/src/i18n.js +88 -0
  337. package/dist/src/index.js +2385 -881
  338. package/dist/src/itinerary-deck.js +139 -0
  339. package/dist/src/itinerary-doc-shared.js +661 -0
  340. package/dist/src/itinerary-html.js +131 -0
  341. package/dist/src/journey.js +155 -108
  342. package/dist/src/lavish-tools.js +400 -0
  343. package/dist/src/ledger-repair-apply.js +538 -0
  344. package/dist/src/ledger-repair-plan.js +463 -0
  345. package/dist/src/loop.js +331 -161
  346. package/dist/src/m3-cohort.js +1577 -0
  347. package/dist/src/memory-capture.js +180 -32
  348. package/dist/src/memory-decay.js +30 -14
  349. package/dist/src/memory-lifecycle.js +1310 -0
  350. package/dist/src/memory-utility.js +27 -40
  351. package/dist/src/mock-llm.js +36 -61
  352. package/dist/src/model.js +81 -36
  353. package/dist/src/outcome-projection.js +746 -0
  354. package/dist/src/realtime-pricing.js +103 -0
  355. package/dist/src/recall/card.js +74 -0
  356. package/dist/src/recall/evaluator.js +140 -0
  357. package/dist/src/recall/integration.js +17 -0
  358. package/dist/src/recall/tick.js +166 -0
  359. package/dist/src/session-link/plan-it-action.js +48 -0
  360. package/dist/src/session-link/session-link.js +248 -0
  361. package/dist/src/session-zone-ledger.js +312 -0
  362. package/dist/src/session-zone-observation.js +354 -0
  363. package/dist/src/session-zone-wiring.js +658 -0
  364. package/dist/src/session-zones.js +510 -0
  365. package/dist/src/share/adapters.js +51 -0
  366. package/dist/src/share/share-consent.js +76 -0
  367. package/dist/src/share/share-deck.js +58 -0
  368. package/dist/src/share/share-token.js +146 -0
  369. package/dist/src/slot-spec.js +84 -106
  370. package/dist/src/state-ledger.js +696 -524
  371. package/dist/src/state-repair.js +299 -0
  372. package/dist/src/subagent-job-id-guard.js +58 -0
  373. package/dist/src/time-anchor.js +231 -33
  374. package/dist/src/tool-packet.js +20 -8
  375. package/dist/src/travel-slots.js +58 -35
  376. package/dist/src/travel-timeline.js +44 -63
  377. package/dist/src/turn-deadline.js +287 -0
  378. package/dist/src/turn-policy.js +118 -0
  379. package/dist/src/tz-resolver.js +143 -0
  380. package/dist/src/unified.js +600 -360
  381. package/dist/src/wish-pool.js +42 -12
  382. package/dist/src/write-gate.js +495 -0
  383. package/dist/src/z3-shared.js +284 -0
  384. package/extension/README.md +21 -0
  385. package/extension/README.zh-CN.md +21 -0
  386. package/extension/background.js +463 -0
  387. package/extension/content-bridge.js +270 -0
  388. package/extension/content-main.js +111 -0
  389. package/extension/manifest.json +60 -0
  390. package/package.json +407 -14
  391. package/schemas/booking.intent.schema.json +193 -0
  392. package/schemas/booking.surface.schema.json +2622 -0
  393. package/ts/capabilities/agent-reach-deep.ts +114 -0
  394. package/ts/capabilities/agent-reach.ts +198 -0
  395. package/ts/capabilities/anything.ts +282 -0
  396. package/ts/capabilities/artifacts.ts +428 -0
  397. package/ts/capabilities/fact-log.ts +54 -0
  398. package/ts/capabilities/flyai-config.ts +388 -0
  399. package/ts/capabilities/flyai.ts +1274 -0
  400. package/ts/capabilities/hbcli.ts +253 -71
  401. package/ts/capabilities/incident-log.ts +88 -59
  402. package/ts/capabilities/itinerary-artifact.ts +214 -0
  403. package/ts/capabilities/itinerary-deck-artifact.ts +218 -0
  404. package/ts/capabilities/itinerary-deck-export.ts +378 -0
  405. package/ts/capabilities/opensky.ts +121 -0
  406. package/ts/capabilities/session/action-cache.ts +148 -0
  407. package/ts/capabilities/session/adapters/ctrip-flight.ts +181 -0
  408. package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
  409. package/ts/capabilities/session/adapters/dida-portal.ts +338 -0
  410. package/ts/capabilities/session/adapters/meituan-local.ts +70 -0
  411. package/ts/capabilities/session/adapters/rail-12306.ts +392 -0
  412. package/ts/capabilities/session/benchmark.ts +276 -0
  413. package/ts/capabilities/session/bridge-ledger.ts +333 -0
  414. package/ts/capabilities/session/extension-bridge.ts +794 -0
  415. package/ts/capabilities/session/extension-channel.ts +144 -0
  416. package/ts/capabilities/session/extension-distribution.ts +266 -0
  417. package/ts/capabilities/session/extract.ts +54 -0
  418. package/ts/capabilities/session/golden-score.ts +139 -0
  419. package/ts/capabilities/session/health-watch.ts +264 -0
  420. package/ts/capabilities/session/read-guard.ts +141 -0
  421. package/ts/capabilities/session/static-flight-golden.ts +209 -0
  422. package/ts/capabilities/session/transport.ts +146 -0
  423. package/ts/capabilities/session/wizard.ts +140 -0
  424. package/ts/capabilities/session-consent.ts +211 -0
  425. package/ts/capabilities/session-login.ts +208 -0
  426. package/ts/capabilities/session-search.ts +893 -0
  427. package/ts/capabilities/weather.ts +330 -0
  428. package/ts/dsh-runtime/vendor/README.md +68 -0
  429. package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
  430. package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +405 -0
  431. package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +404 -0
  432. package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +1584 -0
  433. package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
  434. package/ts/dsh-runtime/vendor/dsh-map-tools/icon.svg +5 -0
  435. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +595 -0
  436. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
  437. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +58 -0
  438. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
  439. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
  440. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +131 -0
  441. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
  442. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/geo.js +232 -0
  443. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +120 -0
  444. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +40 -0
  445. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/staticmap-route.js +115 -0
  446. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
  447. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
  448. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +267 -0
  449. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +90 -0
  450. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
  451. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
  452. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
  453. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
  454. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +23 -0
  455. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
  456. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/geo.d.ts +61 -0
  457. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
  458. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
  459. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/staticmap-route.d.ts +31 -0
  460. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
  461. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
  462. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +75 -0
  463. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +68 -0
  464. package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
  465. package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +97 -0
  466. package/ts/package.json +293 -3
  467. package/ts/scripts/async-collect.ts +91 -0
  468. package/ts/scripts/map-tools-vendor-package-proof.ts +404 -0
  469. package/ts/scripts/skeleton-check.ts +1 -1
  470. package/ts/scripts/skeleton-integration-test.ts +23 -1
  471. package/ts/scripts/state-cli.ts +586 -0
  472. package/ts/scripts/turn-handoff-collect.ts +178 -0
  473. package/ts/src/artifact-gate.ts +991 -0
  474. package/ts/src/benchmark-agent-conformance.ts +619 -0
  475. package/ts/src/benchmark-environment-bridge.ts +538 -0
  476. package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
  477. package/ts/src/benchmark-tool-isolation.ts +166 -0
  478. package/ts/src/bookable-facts.ts +837 -0
  479. package/ts/src/booking-saga.ts +133 -0
  480. package/ts/src/booking-surface/availability-policy.ts +522 -0
  481. package/ts/src/booking-surface/booking-intent.ts +86 -0
  482. package/ts/src/booking-surface/cancel-refund-commission.ts +488 -0
  483. package/ts/src/booking-surface/canonical-schema.js +116 -0
  484. package/ts/src/booking-surface/contracts.ts +475 -0
  485. package/ts/src/booking-surface/dsh-planner.ts +1949 -0
  486. package/ts/src/booking-surface/dsh-plugin.js +378 -0
  487. package/ts/src/booking-surface/dsh-worker.ts +110 -0
  488. package/ts/src/booking-surface/error-codes.ts +241 -0
  489. package/ts/src/booking-surface/index.ts +9 -0
  490. package/ts/src/booking-surface/managed-dsh-cleanup-diagnostic.ts +151 -0
  491. package/ts/src/booking-surface/managed-dsh-run-port.ts +273 -0
  492. package/ts/src/booking-surface/profile.ts +42 -0
  493. package/ts/src/booking-surface/recovery-chain.ts +409 -0
  494. package/ts/src/booking-surface/runtime.ts +1793 -0
  495. package/ts/src/booking-surface/server.ts +733 -0
  496. package/ts/src/booking-surface/startup.ts +201 -0
  497. package/ts/src/booking-surface/validation.ts +217 -0
  498. package/ts/src/companions.ts +113 -0
  499. package/ts/src/contracts.ts +17 -3
  500. package/ts/src/dsh-llm.ts +152 -17
  501. package/ts/src/flyai-setup-tool.ts +77 -0
  502. package/ts/src/index.ts +2123 -200
  503. package/ts/src/itinerary-deck.ts +189 -0
  504. package/ts/src/itinerary-doc-shared.ts +741 -0
  505. package/ts/src/itinerary-html.ts +171 -0
  506. package/ts/src/loop.ts +234 -26
  507. package/ts/src/memory-capture.ts +283 -0
  508. package/ts/src/memory-decay.ts +55 -0
  509. package/ts/src/memory-utility.ts +70 -0
  510. package/ts/src/mock-llm.ts +4 -8
  511. package/ts/src/model.ts +88 -2
  512. package/ts/src/recall/card.ts +106 -0
  513. package/ts/src/recall/evaluator.ts +170 -0
  514. package/ts/src/recall/integration.ts +35 -0
  515. package/ts/src/recall/tick.ts +213 -0
  516. package/ts/src/session-link/plan-it-action.ts +78 -0
  517. package/ts/src/session-link/session-link.ts +275 -0
  518. package/ts/src/share/adapters.ts +93 -0
  519. package/ts/src/share/share-consent.ts +105 -0
  520. package/ts/src/share/share-deck.ts +85 -0
  521. package/ts/src/share/share-token.ts +166 -0
  522. package/ts/src/slot-spec.ts +172 -0
  523. package/ts/src/state-ledger.ts +1166 -0
  524. package/ts/src/subagent-job-id-guard.ts +72 -0
  525. package/ts/src/time-anchor.ts +338 -0
  526. package/ts/src/tool-packet.ts +32 -0
  527. package/ts/src/travel-slots.ts +219 -0
  528. package/ts/src/travel-timeline.ts +83 -0
  529. package/ts/src/turn-deadline.ts +366 -0
  530. package/ts/src/turn-policy.ts +154 -0
  531. package/ts/src/unified.ts +444 -105
  532. package/ts/src/wish-pool.ts +79 -0
  533. package/dist/scripts/session-attach-wait.js +0 -41
@@ -1,14 +1,37 @@
1
+ /**
2
+ * 时间感评测(时间锚点层 + travel_slot_extraction.v1 槽位抽取):
3
+ *
4
+ * 确定性部分(进 CI,run-all-tests.sh 挂载):
5
+ * 1. 锚点卡:固定 now=2026-08-27(周四)断言关键换算(下周一/大后天/下下周四/下个月中旬/季度/节日)
6
+ * 2. 过期校验 flagExpiredSlots:绝对月日早于锚点今天判过期;相对表达永不判;幂等
7
+ * 3. 评分器 scoreExtraction 自测(通过/语言/域/槽位值/missing_slots/多键 warning)
8
+ * 4. mock 回放管道:25 题 golden 经 mock 回吐,评分管道应 25/25(管道自测,与模型质量解耦)
9
+ * 7. 春节锚点生成面(issue #274):到期即红守卫(最晚锚点年份 ≥ 当前年+3)+ 双 oracle
10
+ * 交叉验证(旧表 2026-2031 六条 + 港天文台 2032-2040 九条)+ 耗尽显式告警
11
+ *
12
+ * 真模型巡检(只读报告,不进 CI 红线;ADR-11 质量层定位):
13
+ * cd ts && npx tsx scripts/time-eval-tests.ts --real
14
+ * 需 LLM_API_KEY(或 DEEPSEEK_API_KEY;仓根 .env 亦可)。锚点固定 anchor_date=2026-08-27
15
+ * (golden 的过期判定依赖它,见数据文件 note)。只读:不碰 gotry-state(巡检状态纪律)。
16
+ */
1
17
  import assert from 'node:assert/strict';
2
18
  import { readFileSync } from 'node:fs';
3
19
  import { join } from 'node:path';
4
- import { buildTimeAnchor, parseAbsoluteDate } from '../src/time-anchor.js';
20
+ import { SPRING_FESTIVAL, SPRING_FESTIVAL_HORIZON_MIN_YEARS, buildTimeAnchor, parseAbsoluteDate, springFestivalHorizonOk, springFestivalHorizonYears, } from '../src/time-anchor.js';
5
21
  import { detectLanguage, flagExpiredSlots, scoreExtraction } from '../src/travel-slots.js';
6
22
  import { resolveSlotDate, resolveSlots, specDateMismatches } from '../src/slot-spec.js';
7
23
  import { createMockLlm } from '../src/mock-llm.js';
8
24
  import { createOpenAICompatLlm } from '../src/dsh-llm.js';
25
+ import { newState, runTurn } from '../src/loop.js';
26
+ import { parseRequest } from '../src/model.js';
27
+ import { solveChoiceSegment } from '../src/unified.js';
28
+ import { parsePlanningWindow } from '../src/time-anchor.js';
29
+ // issue #617:确定性部分(第 6 节)经 runTurn,其 PoI 探针缺省不得 spawn 本机真实 hbcli(显式设置的值不覆盖)
30
+ process.env['GOTRY_HBCLI_LIVE'] ??= '0';
9
31
  const dataset = JSON.parse(readFileSync(join('..', 'data', 'time-slot-eval.json'), 'utf-8'));
10
32
  const [ay, am, ad] = dataset.anchor_date.split('-').map(Number);
11
- const ANCHOR_NOW = new Date(ay, am - 1, ad, 12);
33
+ const ANCHOR_NOW = new Date(ay, am - 1, ad, 12); // 锚点日中午,避免午夜边界
34
+ // ---- 1. 锚点卡(固定 now 断言) ------------------------------------------------
12
35
  {
13
36
  const a = buildTimeAnchor(ANCHOR_NOW);
14
37
  assert.equal(a.today, '2026-08-27', 'today');
@@ -26,124 +49,58 @@ const ANCHOR_NOW = new Date(ay, am - 1, ad, 12);
26
49
  assert.ok(c.includes('元旦 2027-01-01'), '元旦取下一次发生');
27
50
  assert.ok(c.includes('春节 2027-02-06'), '春节锚点(2026 春节已过,取 2027)');
28
51
  console.log('1. 锚点卡断言 OK(固定 2026-08-27:下周一/大后天/下下周四/月分段/季度/节日)');
52
+ // D-9 扩表回归:2030 年中锚点 → 春节 2031-01-23(表外年份静默缺失的回归闸)
29
53
  const a2030 = buildTimeAnchor(new Date(2030, 5, 1, 12));
30
54
  assert.ok(a2030.card.includes('春节 2031-01-23'), 'D-9 扩表:2030 年视视角春节取 2031-01-23');
31
55
  console.log('1b. D-9 扩表断言 OK(2030 锚点 → 春节 2031-01-23,表覆盖至 2031)');
32
- }{
56
+ }
57
+ // ---- 2. 过期校验(确定性,对齐 golden 约定) ------------------------------------
58
+ {
33
59
  const anchor = buildTimeAnchor(ANCHOR_NOW);
34
60
  const base = {
35
- schema_version: 'travel_slot_extraction.v1',
36
- language: 'zh',
37
- domains: [
38
- 'requisition'
39
- ],
40
- slots: {
41
- requisition: {
42
- start_date: '8.1',
43
- end_date: '8.10'
44
- }
45
- },
46
- missing_slots: []
61
+ schema_version: 'travel_slot_extraction.v1', language: 'zh',
62
+ domains: ['requisition'], slots: { requisition: { start_date: '8.1', end_date: '8.10' } }, missing_slots: [],
47
63
  };
48
64
  const flagged = flagExpiredSlots(base, anchor);
49
- assert.deepEqual(flagged.missing_slots, [
50
- 'requisition.start_date (date is expired)'
51
- ], '8.1 在 08-27 锚点下过期');
65
+ assert.deepEqual(flagged.missing_slots, ['requisition.start_date (date is expired)'], '8.1 在 08-27 锚点下过期');
52
66
  assert.equal(flagged.slots.requisition.start_date, '8.1', '槽位原值逐字保留');
53
67
  assert.equal(flagged.missing_slots.length, 1, 'end_date 不重复判(只判主日期字段,对齐 golden)');
54
68
  const again = flagExpiredSlots(flagged, anchor);
55
69
  assert.equal(again.missing_slots.length, 1, '幂等不重复加');
56
- const future = flagExpiredSlots({
57
- ...base,
58
- slots: {
59
- requisition: {
60
- start_date: '9.1'
61
- }
62
- }
63
- }, anchor);
70
+ const future = flagExpiredSlots({ ...base, slots: { requisition: { start_date: '9.1' } } }, anchor);
64
71
  assert.equal(future.missing_slots.length, 0, '9.1 不过期');
65
- const relative = flagExpiredSlots({
66
- ...base,
67
- slots: {
68
- requisition: {
69
- start_date: '本周三'
70
- }
71
- }
72
- }, anchor);
72
+ const relative = flagExpiredSlots({ ...base, slots: { requisition: { start_date: '本周三' } } }, anchor);
73
73
  assert.equal(relative.missing_slots.length, 0, '相对表达(本周三)永不判过期');
74
- const iso = flagExpiredSlots({
75
- ...base,
76
- slots: {
77
- requisition: {
78
- start_date: '2026-08-01'
79
- }
80
- }
81
- }, anchor);
74
+ const iso = flagExpiredSlots({ ...base, slots: { requisition: { start_date: '2026-08-01' } } }, anchor);
82
75
  assert.equal(iso.missing_slots.length, 1, 'ISO 绝对日期判过期');
83
- const zhDate = flagExpiredSlots({
84
- ...base,
85
- slots: {
86
- requisition: {
87
- start_date: '8月5日'
88
- }
89
- }
90
- }, anchor);
76
+ const zhDate = flagExpiredSlots({ ...base, slots: { requisition: { start_date: '8月5日' } } }, anchor);
91
77
  assert.equal(zhDate.missing_slots.length, 1, '中文月日判过期');
92
- const enDate = flagExpiredSlots({
93
- ...base,
94
- slots: {
95
- requisition: {
96
- start_date: 'Aug-5'
97
- }
98
- }
99
- }, anchor);
78
+ const enDate = flagExpiredSlots({ ...base, slots: { requisition: { start_date: 'Aug-5' } } }, anchor);
100
79
  assert.equal(enDate.missing_slots.length, 0, '英文月名不判过期(逐字传递,对齐 golden time_english_date_range)');
101
- const flight = flagExpiredSlots({
102
- ...base,
103
- domains: [
104
- 'flight'
105
- ],
106
- slots: {
107
- flight: {
108
- departure_date: '8.1'
109
- }
110
- }
111
- }, anchor);
112
- assert.deepEqual(flight.missing_slots, [
113
- 'flight.departure_date (date is expired)'
114
- ], 'flight 主日期字段');
80
+ const flight = flagExpiredSlots({ ...base, domains: ['flight'], slots: { flight: { departure_date: '8.1' } } }, anchor);
81
+ assert.deepEqual(flight.missing_slots, ['flight.departure_date (date is expired)'], 'flight 主日期字段');
115
82
  assert.equal(parseAbsoluteDate('下周一', 2026), null, 'parseAbsoluteDate 不碰相对表达');
116
- for (const c of dataset.cases){
83
+ // language 判定归代码层(detectLanguage):全中文 zh / 全英文 en / 混排 mixed
84
+ for (const c of dataset.cases) {
117
85
  assert.equal(detectLanguage(c.utterance), c.expected.language, `detectLanguage ${c.id}`);
118
86
  }
119
87
  console.log('2. 过期校验断言 OK(8.1 过期/9.1 不/本周三不/ISO+中文月日判/英文不判/幂等)+ detectLanguage 全题对齐');
120
- }{
88
+ }
89
+ // ---- 3. 评分器自测 ------------------------------------------------------------
90
+ {
121
91
  const exp = dataset.cases[0].expected;
122
92
  const identical = structuredClone(exp);
123
93
  assert.equal(scoreExtraction(exp, identical).pass, true, '完全一致应 pass');
124
- const wrongLang = {
125
- ...structuredClone(exp),
126
- language: 'en'
127
- };
94
+ const wrongLang = { ...structuredClone(exp), language: 'en' };
128
95
  assert.equal(scoreExtraction(exp, wrongLang).pass, false, 'language 不一致应 fail');
129
- const wrongDomain = {
130
- ...structuredClone(exp),
131
- domains: [
132
- 'flight'
133
- ]
134
- };
96
+ const wrongDomain = { ...structuredClone(exp), domains: ['flight'] };
135
97
  assert.equal(scoreExtraction(exp, wrongDomain).pass, false, 'domains 不一致应 fail');
136
98
  const wrongSlot = structuredClone(exp);
137
99
  wrongSlot.slots.requisition.destination = '北京';
138
100
  const r = scoreExtraction(exp, wrongSlot);
139
101
  assert.equal(r.pass, false, '槽位值不一致应 fail');
140
- assert.ok(r.diffs.some((d)=>d.includes('slots.requisition.destination')), 'diff 带路径');
141
- const wrongMissing = {
142
- ...structuredClone(exp),
143
- missing_slots: [
144
- 'requisition.start_date (date is expired)'
145
- ]
146
- };
102
+ assert.ok(r.diffs.some(d => d.includes('slots.requisition.destination')), 'diff 带路径');
103
+ const wrongMissing = { ...structuredClone(exp), missing_slots: ['requisition.start_date (date is expired)'] };
147
104
  assert.equal(scoreExtraction(exp, wrongMissing).pass, false, 'missing_slots 不一致应 fail');
148
105
  const extraKey = structuredClone(exp);
149
106
  extraKey.slots.requisition['adults'] = 2;
@@ -151,149 +108,212 @@ const ANCHOR_NOW = new Date(ay, am - 1, ad, 12);
151
108
  assert.equal(rk.pass, true, '多出键不 fail(非致命)');
152
109
  assert.equal(rk.warnings.length, 1, '多出键记 warning');
153
110
  console.log('3. 评分器自测 OK(pass/language/domains/槽位值/missing_slots/extra-key warning)');
154
- }{
155
- const script = dataset.cases.map((c)=>({
156
- when: c.utterance,
157
- extraction: c.expected
158
- }));
111
+ }
112
+ // ---- 4. mock 回放管道(25/25 管道自测) ------------------------------------------
113
+ {
114
+ const script = dataset.cases.map(c => ({ when: c.utterance, extraction: c.expected }));
159
115
  const llm = createMockLlm(undefined, script);
160
116
  let pass = 0;
161
- for (const c of dataset.cases){
162
- const ext = await llm.extractSlots([
163
- {
164
- role: 'user',
165
- text: c.utterance
166
- }
167
- ]);
117
+ for (const c of dataset.cases) {
118
+ const ext = await llm.extractSlots([{ role: 'user', text: c.utterance }]);
168
119
  assert.ok(ext, `mock 应命中 ${c.id}`);
169
120
  const r = scoreExtraction(c.expected, ext);
170
121
  assert.ok(r.pass, `mock 回放 ${c.id} 应 pass:${r.diffs.join(';')}`);
171
122
  pass++;
172
123
  }
173
124
  console.log(`4. mock 回放管道 OK(${pass}/${dataset.cases.length}——评分管道自身正确)`);
174
- }{
175
- const anchor = buildTimeAnchor(ANCHOR_NOW);
176
- const r = (expr)=>resolveSlotDate(expr, anchor);
125
+ }
126
+ // ---- 5. 槽位→日期解析层(D-10 切片 A,slot-spec.ts) ------------------------------
127
+ {
128
+ const anchor = buildTimeAnchor(ANCHOR_NOW); // 2026-08-27 周四
129
+ const r = (expr) => resolveSlotDate(expr, anchor);
130
+ // 绝对表达:ISO/点分/中文月日(kind=absolute)
177
131
  assert.equal(r('2026-09-05').date, '2026-09-05', 'ISO');
178
132
  assert.equal(r('8.20').date, '2026-08-20', '点分');
179
133
  assert.equal(r('9月5日').date, '2026-09-05', '中文月日');
134
+ // 锚点卡词表:相对周/近邻日/月分段(kind=card)
180
135
  assert.equal(r('下周一').date, '2026-08-31', '下周一');
181
136
  assert.equal(r('本周六').date, '2026-08-29', '本周六');
182
137
  assert.equal(r('下下周四').date, '2026-09-10', '下下周四');
183
138
  assert.equal(r('明天').date, '2026-08-28', '明天');
184
139
  assert.equal(r('下个月中旬').date, '2026-09-11', '下个月中旬取首日');
140
+ // 「+N」后缀(槽位规则 5/6 拼接约定)
185
141
  assert.equal(r('下周五+3').date, '2026-09-07', '下周五+3');
186
142
  assert.equal(r('8.20+2天').date, '2026-08-22', '8.20+2天');
143
+ // 词表外:unresolved 逐字保留(不做开放式解析,ADR-12 边界)
187
144
  assert.equal(r('近期').kind, 'unresolved', '模糊词');
188
145
  assert.equal(r('这阵子').date, null, '模糊词不猜');
189
146
  assert.equal(r('next Monday').kind, 'unresolved', '英文相对不解析');
190
147
  assert.equal(r('next Monday').raw, 'next Monday', 'unresolved 保留原话');
148
+ // 整张抽取解析:hotel+flight 双域 + unresolved 清单
191
149
  const ext = {
192
150
  schema_version: 'travel_slot_extraction.v1',
193
151
  language: 'zh',
194
- domains: [
195
- 'hotel',
196
- 'flight'
197
- ],
152
+ domains: ['hotel', 'flight'],
198
153
  slots: {
199
- hotel: {
200
- action: 'search',
201
- city: '上海',
202
- check_in_date: '下周五',
203
- check_out_date: '下周五+3'
204
- },
205
- flight: {
206
- action: 'search',
207
- origin: '上海',
208
- destination: '杭州',
209
- departure_date: '这阵子',
210
- trip_type: 'one_way'
211
- }
154
+ hotel: { action: 'search', city: '上海', check_in_date: '下周五', check_out_date: '下周五+3' },
155
+ flight: { action: 'search', origin: '上海', destination: '杭州', departure_date: '这阵子', trip_type: 'one_way' },
212
156
  },
213
- missing_slots: []
157
+ missing_slots: [],
214
158
  };
215
159
  const resolved = resolveSlots(ext, anchor);
216
160
  assert.equal(resolved.hotel?.check_in_date?.date, '2026-09-04', 'hotel 入住=下周五');
217
161
  assert.equal(resolved.hotel?.check_out_date?.date, '2026-09-07', 'hotel 退房=下周五+3');
218
- assert.deepEqual(resolved.unresolved, [
219
- {
220
- field: 'flight.departure_date',
221
- raw: '这阵子'
222
- }
223
- ], 'unresolved 清单');
224
- assert.equal(specDateMismatches({
225
- segments: [
226
- {
227
- date: '2026-09-04'
228
- }
229
- ]
230
- }, resolved).length, 0, '一致则零 mismatch');
231
- const mm = specDateMismatches({
232
- segments: [
233
- {
234
- date: '2026-09-05'
235
- }
236
- ]
237
- }, resolved);
162
+ assert.deepEqual(resolved.unresolved, [{ field: 'flight.departure_date', raw: '这阵子' }], 'unresolved 清单');
163
+ // spec 一致性闸:单日期段分歧必须暴露;多段/无日期/unresolved 不判(不造假阳性)
164
+ assert.equal(specDateMismatches({ segments: [{ date: '2026-09-04' }] }, resolved).length, 0, '一致则零 mismatch');
165
+ const mm = specDateMismatches({ segments: [{ date: '2026-09-05' }] }, resolved);
238
166
  assert.equal(mm.length, 1, '单日期段分歧暴露');
239
167
  assert.equal(mm[0]?.specDate, '2026-09-05');
240
168
  assert.equal(mm[0]?.slotDate, '2026-09-04');
241
- assert.equal(specDateMismatches({
242
- segments: [
243
- {
244
- date: '2026-09-04'
245
- },
246
- {
247
- date: '2026-09-05'
248
- }
249
- ]
250
- }, resolved).length, 0, '多段无逐段真值不判(巡检修正)');
251
- const unresolvedOnly = {
252
- unresolved: [
253
- {
254
- field: 'flight.departure_date',
255
- raw: '近期'
256
- }
257
- ]
258
- };
259
- assert.equal(specDateMismatches({
260
- segments: [
261
- {
262
- date: '2026-09-05'
263
- }
264
- ]
265
- }, unresolvedOnly).length, 0, '全 unresolved 不参与比对');
266
- assert.equal(specDateMismatches({
267
- segments: []
268
- }, resolved).length, 0, 'spec 无日期不比对');
169
+ assert.equal(specDateMismatches({ segments: [{ date: '2026-09-04' }, { date: '2026-09-05' }] }, resolved).length, 0, '多段无逐段真值不判(巡检修正)');
170
+ const unresolvedOnly = { unresolved: [{ field: 'flight.departure_date', raw: '近期' }] };
171
+ assert.equal(specDateMismatches({ segments: [{ date: '2026-09-05' }] }, unresolvedOnly).length, 0, '全 unresolved 不参与比对');
172
+ assert.equal(specDateMismatches({ segments: [] }, resolved).length, 0, 'spec 无日期不比对');
269
173
  console.log('5. 槽位→日期解析 OK(绝对/词表/+N/unresolved 边界/整张解析/spec 一致性闸)');
270
- }console.log('\nTIME-EVAL TESTS: 5/5 OK(确定性部分,CI 口径)');
174
+ }
175
+ // ---- 6. Issue #2 未来年度窗口(真实 runTurn→validateSpec→solve 路径) -----------
176
+ {
177
+ const request = parseRequest({
178
+ note: 'issue-2-fixture',
179
+ home: { hubs: { H: { to_hub_min: 0 } } },
180
+ motivation: { weights: {}, hard: { wake_not_before: '06:00', min_arrival_energy_pct: 0 } },
181
+ window_days: 2,
182
+ budget_cny: 1000,
183
+ });
184
+ const option = (id, date, score) => ({
185
+ id, label: id, date, score, minDays: 1,
186
+ move: {
187
+ hub: 'H',
188
+ services: [{ id: `out-${id}`, depMin: 600, arrMin: 700, priceCny: 10 }],
189
+ retServices: [{ id: `ret-${id}`, depMin: 1000, arrMin: 1100, priceCny: 10 }],
190
+ transfers: [{ mode: 'walk', minutes: 10, priceCny: 0 }],
191
+ bufferMin: 30, bufferRetMin: 30, originTransferMin: 0, destTransferMin: 0,
192
+ },
193
+ stay: { nights: 1, stayCnyPerNight: 10, localDailyCny: 10 },
194
+ });
195
+ const spec = () => ({
196
+ segments: [{ id: 'dest', role: 'choice', options: [
197
+ option('past', '2026-09-01', 1), option('valid', '2026-10-01', 0.5), option('next-year', '2027-01-01', 0.9),
198
+ ] }],
199
+ });
200
+ const llmFor = (planned) => ({
201
+ extractFacts: async () => ({
202
+ assumptions: [],
203
+ profile: { workWindow: { homeTzOffsetMin: 0, startMin: 600, endMin: 1080, workdays: [0, 1, 2, 3, 4], evidence: 'fixture' }, bookedResources: [] },
204
+ }),
205
+ extractSpec: async () => structuredClone(planned),
206
+ extractSlots: async () => null,
207
+ polishQuestion: async (q) => q.text,
208
+ });
209
+ const run = (message, now) => runTurn(newState(2026), message, llmFor(spec()), [], async (candidate) => solveChoiceSegment(candidate, request), now);
210
+ const anchor = buildTimeAnchor(new Date(2026, 8, 10, 12));
211
+ const parsed = parsePlanningWindow('计划在2026年内完成一次旅行', anchor);
212
+ assert.deepEqual(parsed, { referenceDate: '2026-09-10', requestedYear: 2026, intent: 'future' }, 'named-year future context');
213
+ assert.equal(parsePlanningWindow('不要再推荐过去的时段,计划2026年内完成旅行', anchor)?.intent, 'future', 'negated past recommendation is not historical intent');
214
+ assert.equal(parsePlanningWindow('2025年没去成,计划2026年内完成旅行', anchor)?.requestedYear, 2026, 'historical context does not override requested future year');
215
+ assert.equal(parsePlanningWindow('计划在2025年或2026年内完成旅行', anchor), null, 'conflicting future years remain ambiguous');
216
+ assert.equal(parsePlanningWindow('历史回测2025年,计划2026年内完成旅行', anchor), null, 'historical and future years remain ambiguous');
217
+ // 相对年份(今年/明年/后年/年内)按本轮锚点换算为命名年窗口——未来时态不落过去(issue #2)
218
+ assert.deepEqual(parsePlanningWindow('今年年内完成一次旅行', anchor), { referenceDate: '2026-09-10', requestedYear: 2026, intent: 'future' }, 'relative this-year future context resolves against the anchor');
219
+ assert.equal(parsePlanningWindow('计划明年出行一次', anchor)?.requestedYear, 2027, 'relative next-year future context');
220
+ assert.equal(parsePlanningWindow('计划在明年或后年完成旅行', anchor), null, 'conflicting relative years remain ambiguous');
221
+ assert.equal(parsePlanningWindow('今年的计划很多', anchor), null, 'non-planning mention of this year is not a window');
222
+ assert.equal(parsePlanningWindow('历史回测今年内的方案', anchor)?.intent, 'historical', 'relative-year historical lookup stays historical');
223
+ assert.equal(parsePlanningWindow('2025年没去成,今年年内完成旅行', anchor)?.requestedYear, 2026, 'past failure does not override relative future year');
224
+ const future = await run('计划在2026年内完成一次旅行', new Date(2026, 8, 10, 12));
225
+ assert.deepEqual(future.state.spec?.segments[0]?.options.map(o => o.date), ['2026-10-01'], 'past option removed before solve');
226
+ assert.equal(future.state.solve?.recommended, 'valid', 'solver accepts only same-year future option');
227
+ assert.match(future.reply, /已排除规划窗口外的候选/, 'reply records deterministic rejection');
228
+ const expired = await run('计划在2025年内完成一次旅行', new Date(2026, 8, 10, 12));
229
+ assert.equal(expired.state.solve, undefined, 'expired requested year does not solve');
230
+ assert.match(expired.reply, /2025 年已结束/, 'expired requested year is explicit');
231
+ assert.doesNotMatch(expired.reply, /2027/, 'expired year is not silently rolled over');
232
+ const historical = await run('历史回测2026年内的方案', new Date(2026, 8, 10, 12));
233
+ assert.deepEqual(historical.state.spec?.segments[0]?.options.map(o => o.date), ['2026-09-01', '2026-10-01', '2027-01-01'], 'historical lookup bypass preserved');
234
+ assert.equal(historical.state.solve?.recommended, 'past', 'historical solver may select historical option');
235
+ // 相对年份未来意图同样不得把过去候选送进求解(issue #2 剩余面,固定时钟反例)
236
+ const relativeFuture = await run('今年年内完成一次旅行', new Date(2026, 8, 10, 12));
237
+ assert.deepEqual(relativeFuture.state.spec?.segments[0]?.options.map(o => o.date), ['2026-10-01'], 'relative this-year intent removes past option before solve');
238
+ assert.equal(relativeFuture.state.solve?.recommended, 'valid', 'relative this-year intent does not recommend a past slot');
239
+ assert.match(relativeFuture.reply, /已排除规划窗口外的候选/, 'relative this-year intent records deterministic rejection');
240
+ const relativeNextYear = await run('计划明年出行一次', new Date(2026, 8, 10, 12));
241
+ assert.deepEqual(relativeNextYear.state.spec?.segments[0]?.options.map(o => o.date), ['2027-01-01'], 'relative next-year intent keeps only in-window options');
242
+ assert.equal(relativeNextYear.state.solve?.recommended, 'next-year', 'relative next-year intent solves within the requested year');
243
+ const relativeHistorical = await run('历史回测今年内的方案', new Date(2026, 8, 10, 12));
244
+ assert.deepEqual(relativeHistorical.state.spec?.segments[0]?.options.map(o => o.date), ['2026-09-01', '2026-10-01', '2027-01-01'], 'explicit relative-year historical lookup keeps past options');
245
+ assert.equal(relativeHistorical.state.solve?.recommended, 'past', 'relative-year historical lookup may select past option');
246
+ const refreshedState = newState(2026);
247
+ await runTurn(refreshedState, '计划在2026年内完成一次旅行', llmFor(spec()), [], async (candidate) => solveChoiceSegment(candidate, request), new Date(2026, 8, 10, 12));
248
+ const refreshed = await runTurn(refreshedState, '计划在2026年内完成一次旅行', llmFor(spec()), [], async (candidate) => solveChoiceSegment(candidate, request), new Date(2026, 9, 2, 12));
249
+ assert.equal(refreshed.state.solve, undefined, 'later eligible turn refreshes reference date');
250
+ assert.match(refreshed.reply, /2026-10-02 至 2026-12-31/, 'later reference date is used');
251
+ assert.equal('planningWindow' in refreshed.state, false, 'planning reference is not persisted in TripState');
252
+ console.log('6. Issue #2 未来年度窗口 OK(runTurn→validateSpec→solve:排除过去候选/拒绝过期年/保留历史回测/刷新参考日)');
253
+ }
254
+ // ---- 7. Issue #274 春节锚点生成面:到期即红守卫 + 双 oracle 交叉验证 + 耗尽显式告警 ----
255
+ {
256
+ // 守卫(真实时钟):最晚锚点年份 ≥ 当前年+3——现在过,临近耗尽自动红(2099 表则 2097 年起红)
257
+ assert.ok(springFestivalHorizonOk(), `春节锚点地平线不足 ${SPRING_FESTIVAL_HORIZON_MIN_YEARS} 年(到期即红守卫)`);
258
+ // 牙齿证明:被否决的旧 2031 手抄表,进入预警窗(2029-01-01 时钟)守卫必红——而非 2031 静默耗尽
259
+ const LEGACY_HAND_2031 = {
260
+ 2026: '2026-02-17', 2027: '2027-02-06', 2028: '2028-01-26',
261
+ 2029: '2029-02-13', 2030: '2030-02-03', 2031: '2031-01-23',
262
+ };
263
+ assert.ok(springFestivalHorizonYears(LEGACY_HAND_2031, new Date(2029, 0, 1)) < SPRING_FESTIVAL_HORIZON_MIN_YEARS, '旧 2031 手抄表在 2029 时钟下守卫必须红(牙齿证明)');
264
+ // 守卫行程自证(对当前表,表扩展后无需改测试):耗尽前 3 年绿、前 2 年红
265
+ const latestYear = Math.max(...Object.keys(SPRING_FESTIVAL).map(Number));
266
+ assert.equal(springFestivalHorizonOk(new Date(latestYear - 3, 0, 1)), true, '耗尽前 3 年守卫绿');
267
+ assert.equal(springFestivalHorizonOk(new Date(latestYear - 2, 0, 1)), false, '耗尽前 2 年守卫红');
268
+ // oracle A:仓库旧表 2026-2031 逐条比对——库生成不许漂移现状行为
269
+ for (const [year, date] of Object.entries(LEGACY_HAND_2031)) {
270
+ assert.equal(SPRING_FESTIVAL[Number(year)], date, `oracle A 旧表 ${year}`);
271
+ }
272
+ // oracle B:#384 港天文台核实 2032-2040(gts/time/calendar T2032e–T2040e 正月初一行,2026-09-11 取)
273
+ const HKO_2032_2040 = {
274
+ 2032: '2032-02-11', 2033: '2033-01-31', 2034: '2034-02-19',
275
+ 2035: '2035-02-08', 2036: '2036-01-28', 2037: '2037-02-15',
276
+ 2038: '2038-02-04', 2039: '2039-01-24', 2040: '2040-02-12',
277
+ };
278
+ for (const [year, date] of Object.entries(HKO_2032_2040)) {
279
+ assert.equal(SPRING_FESTIVAL[Number(year)], date, `oracle B 港天文台 ${year}`);
280
+ }
281
+ // 生成面贯通:旧表外年份(2038)经 buildTimeAnchor 真实出现在锚点卡
282
+ const a2038 = buildTimeAnchor(new Date(2038, 0, 10, 12));
283
+ assert.ok(a2038.card.includes('春节 2038-02-04'), '2038 视角春节取 2038-02-04(生成表贯通锚点卡)');
284
+ // 耗尽显式告警:表耗尽后锚点卡显式标注,不再静默省略;未耗尽则不告警
285
+ const exhausted = buildTimeAnchor(new Date(latestYear + 1, 5, 1, 12));
286
+ assert.ok(exhausted.card.includes('春节(锚点表已到期'), '耗尽后锚点卡显式告警(非静默省略)');
287
+ assert.ok(!buildTimeAnchor(ANCHOR_NOW).card.includes('锚点表已到期'), '未耗尽不告警');
288
+ console.log('7. 春节锚点生成面 OK(到期守卫/旧 2031 表牙齿/行程自证/双 oracle 15 条/生成贯通/耗尽告警)');
289
+ }
290
+ console.log('\nTIME-EVAL TESTS: 7/7 OK(确定性部分,CI 口径)');
291
+ // ---- 真模型巡检(--real,只读报告,不进 CI 红线) ----------------------------------
271
292
  if (process.argv.includes('--real')) {
272
293
  try {
273
- for (const line of readFileSync(join('..', '.env'), 'utf-8').split('\n')){
294
+ for (const line of readFileSync(join('..', '.env'), 'utf-8').split('\n')) {
274
295
  const m = line.match(/^([A-Z_]+)=(.*)$/);
275
- if (m && !process.env[m[1]]) process.env[m[1]] = m[2].trim();
296
+ if (m && !process.env[m[1]])
297
+ process.env[m[1]] = m[2].trim();
276
298
  }
277
- } catch {}
299
+ }
300
+ catch { /* .env 可选 */ }
278
301
  const hasKey = Boolean(process.env['LLM_API_KEY'] ?? process.env['DEEPSEEK_API_KEY']);
279
302
  if (!hasKey) {
280
303
  console.log('\n--real:无 LLM_API_KEY,跳过真模型巡检(ADR-8 回退原则)');
281
- } else {
282
- const clock = ()=>ANCHOR_NOW;
304
+ }
305
+ else {
306
+ const clock = () => ANCHOR_NOW; // 锚点固定:golden 过期判定依赖 anchor_date
283
307
  const llm = createOpenAICompatLlm(undefined, clock);
284
308
  console.log(`\n=== 真模型巡检(${process.env['LLM_MODEL'] ?? 'MiniMax-M2'},锚点 ${dataset.anchor_date})===`);
285
309
  let pass = 0;
286
310
  let p0Pass = 0;
287
311
  let p0Total = 0;
288
- for (const c of dataset.cases){
289
- if (c.priority === 'P0') p0Total++;
312
+ for (const c of dataset.cases) {
313
+ if (c.priority === 'P0')
314
+ p0Total++;
290
315
  try {
291
- const ext = await llm.extractSlots([
292
- {
293
- role: 'user',
294
- text: c.utterance
295
- }
296
- ]);
316
+ const ext = await llm.extractSlots([{ role: 'user', text: c.utterance }]);
297
317
  if (!ext) {
298
318
  console.log(`FAIL ${c.id}(${c.priority}):模型未产出合法 v1 JSON`);
299
319
  continue;
@@ -301,18 +321,18 @@ if (process.argv.includes('--real')) {
301
321
  const r = scoreExtraction(c.expected, ext);
302
322
  if (r.pass) {
303
323
  pass++;
304
- if (c.priority === 'P0') p0Pass++;
324
+ if (c.priority === 'P0')
325
+ p0Pass++;
305
326
  console.log(`PASS ${c.id}${r.warnings.length ? `(warning: ${r.warnings.join(';')})` : ''}`);
306
- } else {
327
+ }
328
+ else {
307
329
  console.log(`FAIL ${c.id}(${c.priority}):\n ${r.diffs.join('\n ')}`);
308
330
  }
309
- } catch (e) {
331
+ }
332
+ catch (e) {
310
333
  console.log(`ERROR ${c.id}(${c.priority}):${e.message.slice(0, 120)}`);
311
334
  }
312
335
  }
313
336
  console.log(`\nREAL ACCURACY: ${pass}/${dataset.cases.length}(P0: ${p0Pass}/${p0Total})——巡检报告口径,不设红线`);
314
337
  }
315
338
  }
316
-
317
-
318
- //# sourceURL=/Users/bytedance/work/gotry/ts/scripts/time-eval-tests.ts