@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
package/ts/src/dsh-llm.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /**
2
2
  * 真 LlmPort:OpenAI 兼容接口的 provider 中立适配器(DeepSeek/MiniMax-M2 实测)。
3
3
  * 零新依赖(node 内建 fetch)。环境变量:LLM_API_KEY/LLM_BASE_URL/LLM_MODEL
4
- * (兼容旧 DEEPSEEK_* 别名)。MiniMax-M2 是推理模型:输出带 <think> 块,
4
+ * (兼容旧 DEEPSEEK_* 别名);GOTRY_LLM_TIMEOUT_MS = 单次请求总预算(默认 300000ms,
5
+ * 非正整数忽略)。MiniMax-M2 是推理模型:输出带 <think> 块,
5
6
  * 必须先剥离再解析——JSON 藏在 think 里是常见失败模式。
6
7
  * 无 key 时抛出明确错误,replay-real 自动回退 mock(ADR-8)。
7
8
  * 责任铁律不变:本适配器只做翻译/润色/解释,判定与算术在确定性组件。
@@ -12,17 +13,125 @@ import type { InterviewQuestion, TravelerProfile, TripState, Turn, CalendarState
12
13
  import { parseFlightPackToSpec, type JourneySpecTS } from './unified.ts'
13
14
  import { buildTimeAnchor } from './time-anchor.ts'
14
15
  import { buildSlotSystem, flagExpiredSlots, normalizeExtraction, type TravelSlotExtraction } from './travel-slots.ts'
16
+ import { mergeProfileWorkWindow } from './flight-pack-adapter.ts'
15
17
 
16
18
  // 惰性读取(env 在调用时取值):模块顶常量会在 .env 加载前冻结(ESM import 提升),
17
19
  // 脚本先 loadEnv 再 import 也救不了——401 错配(key 发往默认端点)的存量隐患由此根除。
18
20
  const model = () => process.env['LLM_MODEL'] ?? process.env['DEEPSEEK_MODEL'] ?? 'MiniMax-M2'
19
21
  const base = () => (process.env['LLM_BASE_URL'] ?? process.env['DEEPSEEK_BASE_URL'] ?? 'https://api.minimax.io/v1').replace(/\/$/, '')
20
22
 
21
- async function chat(messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>, json: boolean): Promise<string> {
23
+ /**
24
+ * Token 用量累计器(OpenAI 兼容 usage 映射)。nightly real-LLM 成本证据(Issue #22
25
+ * `gotry_m3_nightly_run_v1.cost_usd`)的唯一测量来源——成本不允许凭空断言,只允许
26
+ * 这里实测出的 tokens × 封存价表换算;responsesMissingUsage > 0 时成本不可证,调用方必须 fail-closed。
27
+ */
28
+ export interface LlmUsageTracker {
29
+ calls: number
30
+ inputTokens: number
31
+ outputTokens: number
32
+ inputCacheHitTokens: number
33
+ inputCacheMissTokens: number
34
+ responsesMissingUsage: number
35
+ }
36
+
37
+ function emptyUsage(): LlmUsageTracker {
38
+ return { calls: 0, inputTokens: 0, outputTokens: 0, inputCacheHitTokens: 0, inputCacheMissTokens: 0, responsesMissingUsage: 0 }
39
+ }
40
+
41
+ /** 单次请求(连接→响应头→正文读完)的默认总预算:对推理模型足够宽松,只兜「连上了却永不应答」的卡死。 */
42
+ export const DEFAULT_LLM_TIMEOUT_MS = 300_000
43
+ /**
44
+ * 超时上限 = 2^31-1 ms(≈24.8 天)。Node 对更大的延迟会溢出并**悄悄改成 1ms**
45
+ * (TimeoutOverflowWarning),即「配得越大越立刻超时」——所以必须夹住,绝不原样透传。
46
+ */
47
+ const MAX_LLM_TIMEOUT_MS = 2_147_483_647
48
+
49
+ /**
50
+ * chat() 的请求级选项。timeoutMs 压过环境变量 GOTRY_LLM_TIMEOUT_MS;signal 由调用方持有并与
51
+ * 超时合并(AbortSignal.any)——任一先触发就终止本次请求,落成 LlmRequestError。
52
+ */
53
+ export interface LlmRequestOptions {
54
+ timeoutMs?: number
55
+ signal?: AbortSignal
56
+ }
57
+
58
+ /** 只认十进制正整数(数值或纯数字串);其余(0/负数/小数/NaN/带单位/空串)一律 undefined——绝不退化成「无超时」。 */
59
+ function parseTimeoutMs(raw: unknown): number | undefined {
60
+ const n = typeof raw === 'string' ? (/^\d+$/.test(raw.trim()) ? Number(raw.trim()) : Number.NaN) : raw
61
+ return typeof n === 'number' && Number.isSafeInteger(n) && n > 0 ? Math.min(n, MAX_LLM_TIMEOUT_MS) : undefined
62
+ }
63
+
64
+ /** 解析顺序:本次调用显式值 > 环境变量 GOTRY_LLM_TIMEOUT_MS(调用时取值,同 base()/model())> 默认值。 */
65
+ export function resolveLlmTimeoutMs(callMs?: number): number {
66
+ return parseTimeoutMs(callMs) ?? parseTimeoutMs(process.env['GOTRY_LLM_TIMEOUT_MS']) ?? DEFAULT_LLM_TIMEOUT_MS
67
+ }
68
+
69
+ export type LlmRequestFailureCode = 'timeout' | 'aborted'
70
+
71
+ /**
72
+ * chat() 请求被截断(超时 / 调用方取消)的类型化失败——不是挂起,也不会被吞。
73
+ * 与既有错误形态一致,而非另起一套:
74
+ * - message 沿用本模块 `llm <kind>: <detail>` 约定(同 `llm 429: …`),只读 .message 的调用方
75
+ * (nightly-evidence / persona-sim / time-eval --real)原样可用;
76
+ * - name 取平台既有名 TimeoutError / AbortError(AbortSignal.timeout 与手动 abort 抛的同名),
77
+ * persona-sim、channel-probe 等按 name 分类的代码零改动即可识别;
78
+ * - cause 保留 fetch 抛出的原始错误(调用方自定义的 abort reason 也在其中)。
79
+ * HTTP 非 2xx(`llm <status>`)、DNS/连接重置、坏 JSON 仍是原样的普通 Error——只改写「被我们的 signal 终止」的失败。
80
+ */
81
+ export class LlmRequestError extends Error {
82
+ readonly code: LlmRequestFailureCode
83
+ /** 本次生效的超时预算;仅 code === 'timeout' 有值 */
84
+ readonly timeoutMs: number | undefined
85
+
86
+ constructor(code: LlmRequestFailureCode, detail: string, options: { cause?: unknown; timeoutMs?: number } = {}) {
87
+ super(`llm ${code}: ${detail}`, options.cause === undefined ? undefined : { cause: options.cause })
88
+ this.name = code === 'timeout' ? 'TimeoutError' : 'AbortError'
89
+ this.code = code
90
+ this.timeoutMs = options.timeoutMs
91
+ }
92
+ }
93
+
94
+ interface ChatCompletion {
95
+ choices: Array<{ message: { content: string } }>
96
+ usage?: { prompt_tokens?: number; completion_tokens?: number; prompt_cache_hit_tokens?: number; prompt_cache_miss_tokens?: number }
97
+ }
98
+
99
+ /**
100
+ * 发一次请求并读完正文。**同一个 signal 贯穿 fetch 与 res.json()/res.text()**,所以超时覆盖整个请求
101
+ * (含「响应头已到、正文卡住」与「非 2xx 的错误正文卡住」),调用方取消同理。
102
+ * 只有「被我们的 signal 终止」才改写成 LlmRequestError;其余错误原样上抛。
103
+ */
104
+ async function requestCompletion(
105
+ url: string,
106
+ init: { headers: Record<string, string>; body: string },
107
+ request: LlmRequestOptions,
108
+ ): Promise<{ ok: true; data: ChatCompletion } | { ok: false; status: number; text: string }> {
109
+ const timeoutMs = resolveLlmTimeoutMs(request.timeoutMs)
110
+ const timeout = AbortSignal.timeout(timeoutMs)
111
+ const signal = request.signal ? AbortSignal.any([request.signal, timeout]) : timeout
112
+ try {
113
+ const res = await fetch(url, { method: 'POST', headers: init.headers, body: init.body, signal })
114
+ if (!res.ok) return { ok: false, status: res.status, text: await res.text() }
115
+ return { ok: true, data: await res.json() as ChatCompletion }
116
+ } catch (error) {
117
+ if (!signal.aborted) throw error
118
+ // AbortSignal.any 的 reason 是最先触发的那个源的 reason:等于超时信号的 reason 即超时先到,否则是调用方取消
119
+ if (timeout.aborted && signal.reason === timeout.reason) {
120
+ throw new LlmRequestError('timeout', `no complete response within ${timeoutMs}ms (GOTRY_LLM_TIMEOUT_MS)`, { cause: error, timeoutMs })
121
+ }
122
+ throw new LlmRequestError('aborted', "request cancelled by the caller's AbortSignal", { cause: error })
123
+ }
124
+ }
125
+
126
+ async function chat(
127
+ messages: Array<{ role: 'system' | 'user' | 'assistant'; content: string }>,
128
+ json: boolean,
129
+ usage?: LlmUsageTracker,
130
+ request: LlmRequestOptions = {},
131
+ ): Promise<string> {
22
132
  const key = process.env['LLM_API_KEY'] ?? process.env['DEEPSEEK_API_KEY']
23
133
  if (!key) throw new Error('LLM_API_KEY 未设置(兼容 DEEPSEEK_API_KEY 别名)——真 LLM 路径不可用,请回退 mock(ADR-8)')
24
- const res = await fetch(`${base()}/chat/completions`, {
25
- method: 'POST',
134
+ const reply = await requestCompletion(`${base()}/chat/completions`, {
26
135
  headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${key}` },
27
136
  body: JSON.stringify({
28
137
  model: model(),
@@ -30,9 +139,22 @@ async function chat(messages: Array<{ role: 'system' | 'user' | 'assistant'; con
30
139
  ...(json ? { response_format: { type: 'json_object' } } : {}),
31
140
  temperature: json ? 0 : 0.7,
32
141
  }),
33
- })
34
- if (!res.ok) throw new Error(`llm ${res.status}: ${(await res.text()).slice(0, 300)}`)
35
- const data = await res.json() as { choices: Array<{ message: { content: string } }> }
142
+ }, request)
143
+ if (!reply.ok) throw new Error(`llm ${reply.status}: ${reply.text.slice(0, 300)}`)
144
+ const data = reply.data
145
+ if (usage) {
146
+ usage.calls += 1
147
+ const u = data.usage
148
+ if (u && Number.isFinite(u.prompt_tokens) && Number.isFinite(u.completion_tokens)) {
149
+ usage.inputTokens += u.prompt_tokens ?? 0
150
+ usage.outputTokens += u.completion_tokens ?? 0
151
+ usage.inputCacheHitTokens += u.prompt_cache_hit_tokens ?? 0
152
+ // 无缓存明细的 provider:全部输入按 miss 记(随后按 peak miss 价换算,只高不低)
153
+ usage.inputCacheMissTokens += u.prompt_cache_miss_tokens ?? (u.prompt_tokens ?? 0)
154
+ } else {
155
+ usage.responsesMissingUsage += 1
156
+ }
157
+ }
36
158
  const raw = data.choices[0]?.message?.content ?? ''
37
159
  // 推理模型(MiniMax-M2 等):剥 <think> 块,只留正文;未闭合时留全文由上层容错
38
160
  return raw.replace(/<think>[\s\S]*?<\/think>/g, '').trim() || raw
@@ -51,10 +173,10 @@ function parseJsonBlock(text: string): Record<string, unknown> | null {
51
173
 
52
174
  const FACTS_SYSTEM = `你是旅行规划的事实抽取器。从对话中抽取两类事实并以 JSON 返回:
53
175
  {"calendar": {"year": 数字, "assertedWeekdays": {"YYYY-MM-DD": "mon|tue|wed|thu|fri|sat|sun"}},
54
- "profile": {"workWindow": {"homeTzOffsetMin": 数字, "startMin": 数字, "endMin": 数字, "workdays": [0,1,2,3,4], "evidence": "用户原话"},
176
+ "profile": {"workWindow": {"homeTzOffsetMin": 数字(仅 legacy v1;用户未明确时可省略), "startMin": 数字, "endMin": 数字, "workdays": [0,1,2,3,4], "evidence": "用户原话"},
55
177
  "companions": ["..."], "budgetTier": "economy|comfort|convenience",
56
178
  "bookedResources": [{"kind": "flight|hotel", "ref": "...", "window": "..."}]}}
57
- 只放用户明确说过的事实;没有的字段省略。分钟数从 HH:MM 换算;UTC+4 → homeTzOffsetMin=240。
179
+ 只放用户明确说过的事实;没有的字段省略。分钟数从 HH:MM 换算;用户未明确说 numeric offset 时不要猜、不要输出 homeTzOffsetMin;v2 pack 的 IANA home zone 属于数据层权威。
58
180
  **休假语义(关键)**:用户说「请假/年假/不用办公/休假」→ workWindow 输出 {"vacation": true}(不是省略!省略会触发重复追问);只有用户明确给了工作时间才输出完整 workWindow 对象。只输出 JSON。`
59
181
 
60
182
  const SKELETON_SYSTEM = `你是行程骨架抽取器。从对话中抽取行程的**骨架**——段(移动)与锚点,不包含任何班次数据(班次来自数据层,你不要编造时刻/价格/航班号)。
@@ -62,8 +184,13 @@ const SKELETON_SYSTEM = `你是行程骨架抽取器。从对话中抽取行程
62
184
  规则:每个跨城移动一段;锚点只放用户明说或必然的(如"当天到"→arriveByMin 23:59=1439);时刻用当日分钟。
63
185
  scenario 判定:「洱海/大理/千岛湖/太湖+选目的地」→erhai(候选集);「普吉/workation/远程办公+多城链」→workation(五段链);「云南/大理丽江」→yunnan;不确定→generic。只输出 JSON。`
64
186
 
65
- export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date = () => new Date()): LlmPort {
187
+ /**
188
+ * request:本端口每次 chat() 共用的请求级选项(timeoutMs / signal)。signal 是端口级取消——
189
+ * 调用方可借它在会话/批次截止时真正掐断在途请求,而不是放着它继续挂在 provider 上。
190
+ */
191
+ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date = () => new Date(), request: LlmRequestOptions = {}): LlmPort & { usage: LlmUsageTracker } {
66
192
  const pack = flightPackPath
193
+ const usage = emptyUsage()
67
194
  const historyText = (h: Turn[]) => h.map(t => `${t.role === 'user' ? '用户' : '助手'}: ${t.text}`).join('\n')
68
195
  // 时间锚点卡:每条抽取链路都带上「今天」——legacy 路径此前无时间注入,
69
196
  // 过期/相对日期语义全靠它(算术在 time-anchor 层,LLM 只查卡)。
@@ -73,6 +200,8 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
73
200
  const out = await chat(
74
201
  [{ role: 'system', content: FACTS_SYSTEM }, { role: 'user', content: `${anchorContext()}\n\n${historyText(history)}` }],
75
202
  true,
203
+ usage,
204
+ request,
76
205
  )
77
206
  const obj = parseJsonBlock(out)
78
207
  if (!obj) return { assumptions: [] }
@@ -87,6 +216,8 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
87
216
  const out = await chat(
88
217
  [{ role: 'system', content: SKELETON_SYSTEM }, { role: 'user', content: `${context}\n\n${historyText(history)}` }],
89
218
  true,
219
+ usage,
220
+ request,
90
221
  )
91
222
  const skeleton = parseJsonBlock(out)
92
223
  if (!skeleton || !Array.isArray(skeleton['segments']) || (skeleton['segments'] as unknown[]).length === 0) return null
@@ -112,7 +243,11 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
112
243
  return { segments: [], note: 'erhai-candidates', budgetCny: 3000 } as unknown as JourneySpecTS
113
244
  }
114
245
  packSpec = parseFlightPackToSpec(JSON.parse(await readFile(packPath, 'utf-8')))
115
- } catch {
246
+ } catch (e) {
247
+ // issue #620:数据包被 parse 边界拒收时,原因必须留痕——否则用户只看到
248
+ // 「骨架还不完整」,运维看不到是哪个包的哪个字段把求解面挡住了。
249
+ const err = e as Error & { code?: string }
250
+ console.error(`[gotry] extractSpec: 数据包不可用 ${packPath}(${err.code ?? 'parse_failed'}):`, (err.message ?? '').slice(0, 200))
116
251
  return null
117
252
  }
118
253
  const anchorsById = new Map<string, Record<string, unknown>>(
@@ -121,12 +256,7 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
121
256
  const a = anchorsById.get(seg.id) as { arriveByMin?: number } | undefined
122
257
  if (a?.arriveByMin !== undefined) seg.anchors = { arriveByMin: a.arriveByMin }
123
258
  }
124
- packSpec.workWindow = state.profile.workWindow ? {
125
- homeTzOffsetMin: state.profile.workWindow.homeTzOffsetMin,
126
- startMin: state.profile.workWindow.startMin,
127
- endMin: state.profile.workWindow.endMin,
128
- workdays: state.profile.workWindow.workdays,
129
- } : undefined
259
+ packSpec = mergeProfileWorkWindow(packSpec, state.profile.workWindow)
130
260
  packSpec.budgetCny = 9000
131
261
  return packSpec
132
262
  },
@@ -136,6 +266,8 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
136
266
  const out = await chat(
137
267
  [{ role: 'system', content: buildSlotSystem(anchor) }, { role: 'user', content: historyText(history) }],
138
268
  true,
269
+ usage,
270
+ request,
139
271
  )
140
272
  const obj = parseJsonBlock(out)
141
273
  if (!obj) return null
@@ -148,8 +280,11 @@ export function createOpenAICompatLlm(flightPackPath?: string, clock: () => Date
148
280
  [{ role: 'system', content: '把旅行规划的追问润色得更自然,保留全部信息(含为什么问),一两句话,不要加表情。' },
149
281
  { role: 'user', content: `【${q.key}】${q.text}(为什么问:${q.why})` }],
150
282
  false,
283
+ usage,
284
+ request,
151
285
  )
152
286
  return out.trim() || `【${q.key}】${q.text}`
153
287
  },
288
+ usage,
154
289
  }
155
290
  }
@@ -0,0 +1,77 @@
1
+ /** Read-only model surface. Credentials are entered only through the local CLI. */
2
+ import { homedir } from 'node:os'
3
+ import { defineTool } from '@deepseek-ai/dsh-tools'
4
+ import type { EffectInterpreter } from '../capabilities/effect.ts'
5
+ import {
6
+ displayEndpoint, endpointFingerprint, readFlyaiVerification, resolveFlyaiEndpoint,
7
+ resolveFlyaiKey, sha256Hex, writeFlyaiVerification,
8
+ } from '../capabilities/flyai-config.ts'
9
+ import type { FlyaiResult } from '../capabilities/flyai.ts'
10
+ import { readLatestChannelEvents } from '../capabilities/channel-health.ts'
11
+
12
+ const guidance = '在本机运行 gotry setup flyai(隐藏输入),或 gotry setup flyai --stdin;清除文件配置用 --clear。不要在聊天中发送 API key。打开 https://flyai.open.fliggy.com/console,登录后复制 API Key。'
13
+ const guidanceImpact = '影响面:未配置 key 时 gotry_flyai_search 走匿名共享额度池(易达 Trial limit reached,达限本会话该工具不可用);配置后额度走本机 key,失败时按 verdict 改道 gotry_session_search 账号会话通道。'
14
+
15
+ export function createFlyaiSetupTool(runEffect: EffectInterpreter, stateRoot?: string) {
16
+ return defineTool({
17
+ name: 'gotry_flyai_setup',
18
+ description: 'Inspect FlyAI credential source and verification status, or check the current configuration with a read-only search. Never accepts, changes or returns credentials. Check updates only a verification receipt; setting or clearing credentials requires the local gotry setup flyai command.',
19
+ parameters: { action: { type: 'string', enum: ['status', 'check'], description: 'status (default): local status; check: read-only provider verification' } },
20
+ output: { schema: { type: 'json' }, render: (_a, value) => [{ type: 'text', text: JSON.stringify(value) }] },
21
+ async execute(args, exec) {
22
+ // Reject unknown arguments before any provider invocation or metadata write.
23
+ if (Object.keys(args).some(key => key !== 'action') || (args.action !== undefined && args.action !== 'status' && args.action !== 'check')) {
24
+ return { ok: false, summary: `仅支持 status/check;不接收凭据。${guidance} ${guidanceImpact}` }
25
+ }
26
+ const home = homedir()
27
+ const current = resolveFlyaiKey()
28
+ const endpoint = resolveFlyaiEndpoint()
29
+ const fingerprint = endpointFingerprint(endpoint.url)
30
+ let receipt = readFlyaiVerification(home)
31
+ let checkVerdict: string | undefined
32
+ let receiptSaved: boolean | undefined
33
+ if (args.action === 'check') {
34
+ const date = new Date(Date.now() + 7 * 86_400_000).toISOString().slice(0, 10)
35
+ const outcome = await runEffect({ effect: 'FLYAI_SEARCH', params: {
36
+ kind: 'flight', origin: '上海', destination: '北京', depDate: date,
37
+ timeoutMs: 20_000, signal: exec?.signal,
38
+ } })
39
+ const result = outcome.result as FlyaiResult | null
40
+ checkVerdict = outcome.trace.declined === 'aborted' ? 'cancelled' : result?.verdict ?? 'error'
41
+ // A concurrent local credential change invalidates this check's receipt.
42
+ const after = resolveFlyaiKey()
43
+ const unchanged = current.key === after.key && current.source === after.source
44
+ && fingerprint === endpointFingerprint(resolveFlyaiEndpoint().url)
45
+ if (current.key && fingerprint && unchanged && checkVerdict !== 'cancelled') {
46
+ const allowed = ['auth-error', 'forbidden', 'rate-limited', 'timeout', 'needs-setup', 'error'] as const
47
+ const verdict = checkVerdict === 'hit' || checkVerdict === 'miss' ? 'verified'
48
+ : allowed.find(value => value === checkVerdict) ?? 'error'
49
+ receipt = { schema: 'gotry.flyai-verification.v1', source: current.source,
50
+ keySha256: sha256Hex(current.key), maskedKey: current.maskedKey ?? '****',
51
+ endpointFingerprint: fingerprint, endpointDebug: endpoint.debug,
52
+ verdict, at: new Date().toISOString() }
53
+ receiptSaved = writeFlyaiVerification(receipt, home)
54
+ }
55
+ }
56
+ const matches = Boolean(current.key && receipt && receipt.keySha256 === sha256Hex(current.key)
57
+ && receipt.source === current.source && receipt.endpointFingerprint === fingerprint
58
+ && receipt.endpointDebug === endpoint.debug)
59
+ const verified = matches && receipt?.verdict === 'verified'
60
+ const event = stateRoot ? (await readLatestChannelEvents(stateRoot, { requireValidTimestamp: true })).get('flyai') : undefined
61
+ const lastTrialLimit = event?.state === 'down' && event.reason === 'needs-setup' ? event.at : undefined
62
+ const status = !current.key ? '匿名试用(共享额度)' : verified ? '已验证当前配置' : '已配置,未验证通过'
63
+ const summary = `${status};来源 ${current.source};endpoint ${displayEndpoint(endpoint.url)}${endpoint.debug ? '(DEBUG)' : ''}。`
64
+ + (checkVerdict ? `本次只读检查:${checkVerdict}。` : '')
65
+ + (lastTrialLimit ? `最近试用额度受限:${lastTrialLimit}。` : '')
66
+ + (receiptSaved === false ? '验证回执保存失败,doctor 状态尚未更新。' : '') + guidance
67
+ + ' ' + guidanceImpact
68
+ return JSON.parse(JSON.stringify({ ok: receiptSaved !== false && (!checkVerdict || checkVerdict === 'hit' || checkVerdict === 'miss'), action: args.action ?? 'status',
69
+ source: current.source, configured: Boolean(current.key), verified,
70
+ maskedKey: current.maskedKey, configPath: current.configPath,
71
+ endpoint: displayEndpoint(endpoint.url), endpointDebug: endpoint.debug,
72
+ checkVerdict, receiptSaved, lastTrialLimit, summary })) as Record<string, never>
73
+ },
74
+ // Do not retain unexpected arguments even when a host bypasses schema validation.
75
+ presentCall: args => ({ card: 'generic', title: 'FlyAI 配置检查', kind: 'fetch', rawInput: { action: args.action === 'check' ? 'check' : 'status' } }),
76
+ })
77
+ }