@danceiny/gotry 0.0.1-rc.18 → 0.0.1-rc.19

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 (137) hide show
  1. package/README.md +42 -16
  2. package/README.zh-CN.md +37 -15
  3. package/bin/gotry-bootstrap.js +236 -3
  4. package/bin/gotry-inner.js +66 -20
  5. package/bin/gotry-runtime-resolution.d.ts +1 -1
  6. package/bin/gotry-runtime-resolution.js +7 -8
  7. package/cordis.gotry-patch.yml +15 -5
  8. package/data/stations-12306-verify.json +524 -0
  9. package/dist/capabilities/agent-reach.js +4 -4
  10. package/dist/capabilities/channel-health.js +103 -0
  11. package/dist/capabilities/channel-registry.js +213 -0
  12. package/dist/capabilities/doctor.js +285 -0
  13. package/dist/capabilities/effect.js +178 -5
  14. package/dist/capabilities/flyai.js +13 -0
  15. package/dist/capabilities/session/adapters/ctrip-hotel.js +207 -0
  16. package/dist/capabilities/session/adapters/rail-12306.js +285 -0
  17. package/dist/capabilities/session/extension-bridge.js +14 -1
  18. package/dist/capabilities/session/extension-channel.js +4 -2
  19. package/dist/capabilities/session/extension-distribution.js +1 -1
  20. package/dist/capabilities/session-search.js +311 -0
  21. package/dist/capabilities/visa-policy.js +126 -0
  22. package/dist/scripts/agent-planning-turn-deadline-e2e.js +304 -0
  23. package/dist/scripts/agent-planning-turn-deadline-tests.js +281 -0
  24. package/dist/scripts/benchmark-environment-bridge-e2e.js +5 -10
  25. package/dist/scripts/benchmark-environment-bridge-tests.js +148 -142
  26. package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +26 -26
  27. package/dist/scripts/{booking-copilot-availability-policy-v2-tests.js → booking-copilot-availability-policy-tests.js} +115 -115
  28. package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +41 -1
  29. package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +75 -120
  30. package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +370 -61
  31. package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +2 -2
  32. package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +7 -3
  33. package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +15 -9
  34. package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +19 -11
  35. package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +16 -52
  36. package/dist/scripts/booking-copilot-runtime-proof-tests.js +3953 -155
  37. package/dist/scripts/booking-copilot-server-proof-tests.js +58 -23
  38. package/dist/scripts/booking-copilot-startup-proof-tests.js +10 -119
  39. package/dist/scripts/booking-surface-contract-proof-tests.js +1154 -326
  40. package/dist/scripts/bootstrap-tests.js +87 -2
  41. package/dist/scripts/build-metrics-report.js +339 -0
  42. package/dist/scripts/channel-probe-tests.js +148 -0
  43. package/dist/scripts/channel-probe.js +252 -0
  44. package/dist/scripts/channel-registry-tests.js +262 -0
  45. package/dist/scripts/doctor-tests.js +121 -0
  46. package/dist/scripts/effect-tests.js +274 -1
  47. package/dist/scripts/extension-tests.js +129 -11
  48. package/dist/scripts/fact-gate-tests.js +91 -2
  49. package/dist/scripts/flyai-tests.js +17 -1
  50. package/dist/scripts/hbcli-e2e-tests.js +1 -3
  51. package/dist/scripts/metrics-report-tests.js +288 -0
  52. package/dist/scripts/persona-surface-guard-tests.js +19 -0
  53. package/dist/scripts/session-tests.js +401 -1
  54. package/dist/scripts/smoke.js +100 -83
  55. package/dist/scripts/turn-handoff-collect-tests.js +216 -0
  56. package/dist/scripts/turn-handoff-collect.js +189 -0
  57. package/dist/scripts/turn-policy-tests.js +56 -0
  58. package/dist/scripts/typed-contract-canary.js +261 -0
  59. package/dist/scripts/visa-policy-tests.js +75 -0
  60. package/dist/scripts/wish-channel-gate-tests.js +111 -0
  61. package/dist/src/artifact-gate.js +91 -3
  62. package/dist/src/benchmark-agent-conformance.js +7 -4
  63. package/dist/src/benchmark-environment-bridge.js +68 -7
  64. package/dist/src/bookable-facts.js +62 -3
  65. package/dist/src/booking-surface/{availability-policy-v2.js → availability-policy.js} +89 -89
  66. package/dist/src/booking-surface/canonical-schema.js +8 -22
  67. package/dist/src/booking-surface/contracts.js +70 -19
  68. package/dist/src/booking-surface/dsh-planner.js +310 -177
  69. package/dist/src/booking-surface/dsh-plugin.js +3 -3
  70. package/dist/src/booking-surface/index.js +1 -5
  71. package/dist/src/booking-surface/profile.js +1 -1
  72. package/dist/src/booking-surface/runtime.js +1682 -247
  73. package/dist/src/booking-surface/server.js +371 -185
  74. package/dist/src/booking-surface/startup.js +17 -27
  75. package/dist/src/booking-surface/validation.js +270 -760
  76. package/dist/src/index.js +735 -149
  77. package/dist/src/turn-deadline.js +292 -0
  78. package/dist/src/turn-policy.js +146 -0
  79. package/dist/src/wish-pool.js +5 -0
  80. package/extension/background.js +23 -4
  81. package/extension/content-main.js +47 -9
  82. package/extension/manifest.json +27 -9
  83. package/package.json +6 -26
  84. package/schemas/booking.surface.schema.json +2593 -0
  85. package/ts/capabilities/agent-reach.ts +4 -4
  86. package/ts/capabilities/flyai.ts +21 -3
  87. package/ts/capabilities/session/action-cache.ts +1 -1
  88. package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
  89. package/ts/capabilities/session/adapters/rail-12306.ts +293 -0
  90. package/ts/capabilities/session/extension-bridge.ts +32 -2
  91. package/ts/capabilities/session/extension-channel.ts +9 -8
  92. package/ts/capabilities/session/extension-distribution.ts +3 -1
  93. package/ts/capabilities/session/health-watch.ts +1 -1
  94. package/ts/capabilities/session/read-guard.ts +1 -1
  95. package/ts/capabilities/session/wizard.ts +1 -1
  96. package/ts/capabilities/session-search.ts +323 -1
  97. package/ts/package.json +1 -0
  98. package/ts/scripts/turn-handoff-collect.ts +178 -0
  99. package/ts/src/artifact-gate.ts +82 -2
  100. package/ts/src/benchmark-agent-conformance.ts +14 -6
  101. package/ts/src/benchmark-environment-bridge.ts +29 -10
  102. package/ts/src/bookable-facts.ts +109 -5
  103. package/ts/src/booking-saga.ts +1 -1
  104. package/ts/src/booking-surface/{availability-policy-v2.ts → availability-policy.ts} +124 -125
  105. package/ts/src/booking-surface/canonical-schema.js +8 -22
  106. package/ts/src/booking-surface/contracts.ts +278 -239
  107. package/ts/src/booking-surface/dsh-planner.ts +333 -194
  108. package/ts/src/booking-surface/dsh-plugin.js +3 -3
  109. package/ts/src/booking-surface/index.ts +1 -5
  110. package/ts/src/booking-surface/profile.ts +11 -11
  111. package/ts/src/booking-surface/runtime.ts +1351 -351
  112. package/ts/src/booking-surface/server.ts +282 -175
  113. package/ts/src/booking-surface/startup.ts +36 -48
  114. package/ts/src/booking-surface/validation.ts +194 -442
  115. package/ts/src/contracts.ts +1 -1
  116. package/ts/src/index.ts +489 -171
  117. package/ts/src/loop.ts +1 -1
  118. package/ts/src/state-ledger.ts +1 -1
  119. package/ts/src/turn-deadline.ts +361 -0
  120. package/ts/src/turn-policy.ts +154 -0
  121. package/ts/src/wish-pool.ts +17 -4
  122. package/dist/scripts/agent-planning-budget-e2e.js +0 -227
  123. package/dist/scripts/agent-planning-budget-tests.js +0 -173
  124. package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +0 -3935
  125. package/dist/scripts/booking-surface-v2-contract-proof-tests.js +0 -1174
  126. package/dist/src/booking-surface/contracts-v2.js +0 -89
  127. package/dist/src/booking-surface/runtime-v2.js +0 -1771
  128. package/dist/src/booking-surface/server-v2.js +0 -334
  129. package/dist/src/booking-surface/validation-v2.js +0 -319
  130. package/dist/src/tool-budget.js +0 -136
  131. package/schemas/booking.surface.v1.schema.json +0 -927
  132. package/schemas/booking.surface.v2.schema.json +0 -61
  133. package/ts/src/booking-surface/contracts-v2.ts +0 -118
  134. package/ts/src/booking-surface/runtime-v2.ts +0 -1466
  135. package/ts/src/booking-surface/server-v2.ts +0 -247
  136. package/ts/src/booking-surface/validation-v2.ts +0 -205
  137. package/ts/src/tool-budget.ts +0 -165
@@ -0,0 +1,524 @@
1
+ {
2
+ "schema": "gotry_stations_12306_verify_v1",
3
+ "source": "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js",
4
+ "source_note": "12306 官方全量站表(3384 站);代表站规则=城市同名站,无同名站取城市组首站",
5
+ "calibrated_at": "2026-09-03",
6
+ "cities": {
7
+ "三亚": {
8
+ "telecode": "SEQ",
9
+ "representative_station": "三亚"
10
+ },
11
+ "上海": {
12
+ "telecode": "SHH",
13
+ "representative_station": "上海"
14
+ },
15
+ "上饶": {
16
+ "telecode": "SRG",
17
+ "representative_station": "上饶"
18
+ },
19
+ "东莞": {
20
+ "telecode": "RTQ",
21
+ "representative_station": "东莞"
22
+ },
23
+ "中卫": {
24
+ "telecode": "ZWJ",
25
+ "representative_station": "中卫"
26
+ },
27
+ "中山": {
28
+ "telecode": "ZSQ",
29
+ "representative_station": "中山"
30
+ },
31
+ "丽江": {
32
+ "telecode": "LHM",
33
+ "representative_station": "丽江"
34
+ },
35
+ "乌鲁木齐": {
36
+ "telecode": "WAR",
37
+ "representative_station": "乌鲁木齐"
38
+ },
39
+ "乐山": {
40
+ "telecode": "IVW",
41
+ "representative_station": "乐山"
42
+ },
43
+ "九江": {
44
+ "telecode": "JJG",
45
+ "representative_station": "九江"
46
+ },
47
+ "伊宁": {
48
+ "telecode": "YMR",
49
+ "representative_station": "伊宁"
50
+ },
51
+ "佛山": {
52
+ "telecode": "FSQ",
53
+ "representative_station": "佛山"
54
+ },
55
+ "保山": {
56
+ "telecode": "BAM",
57
+ "representative_station": "保山"
58
+ },
59
+ "六盘水": {
60
+ "telecode": "UMW",
61
+ "representative_station": "六盘水"
62
+ },
63
+ "兰州": {
64
+ "telecode": "LZJ",
65
+ "representative_station": "兰州"
66
+ },
67
+ "包头": {
68
+ "telecode": "BTC",
69
+ "representative_station": "包头"
70
+ },
71
+ "北京": {
72
+ "telecode": "BJP",
73
+ "representative_station": "北京"
74
+ },
75
+ "北海": {
76
+ "telecode": "BHZ",
77
+ "representative_station": "北海"
78
+ },
79
+ "十堰": {
80
+ "telecode": "SNN",
81
+ "representative_station": "十堰"
82
+ },
83
+ "南京": {
84
+ "telecode": "NJH",
85
+ "representative_station": "南京"
86
+ },
87
+ "南充": {
88
+ "telecode": "NCW",
89
+ "representative_station": "南充"
90
+ },
91
+ "南宁": {
92
+ "telecode": "NNZ",
93
+ "representative_station": "南宁"
94
+ },
95
+ "南昌": {
96
+ "telecode": "NCG",
97
+ "representative_station": "南昌"
98
+ },
99
+ "南通": {
100
+ "telecode": "NUH",
101
+ "representative_station": "南通"
102
+ },
103
+ "南阳": {
104
+ "telecode": "NFF",
105
+ "representative_station": "南阳"
106
+ },
107
+ "厦门": {
108
+ "telecode": "XMS",
109
+ "representative_station": "厦门"
110
+ },
111
+ "台州": {
112
+ "telecode": "TEU",
113
+ "representative_station": "台州"
114
+ },
115
+ "合肥": {
116
+ "telecode": "HFH",
117
+ "representative_station": "合肥"
118
+ },
119
+ "吉林": {
120
+ "telecode": "JLL",
121
+ "representative_station": "吉林"
122
+ },
123
+ "吐鲁番": {
124
+ "telecode": "TFR",
125
+ "representative_station": "吐鲁番"
126
+ },
127
+ "呼和浩特": {
128
+ "telecode": "HHC",
129
+ "representative_station": "呼和浩特"
130
+ },
131
+ "咸阳": {
132
+ "telecode": "XYY",
133
+ "representative_station": "咸阳"
134
+ },
135
+ "哈密": {
136
+ "telecode": "HMR",
137
+ "representative_station": "哈密"
138
+ },
139
+ "哈尔滨": {
140
+ "telecode": "HBB",
141
+ "representative_station": "哈尔滨"
142
+ },
143
+ "喀什": {
144
+ "telecode": "KSR",
145
+ "representative_station": "喀什"
146
+ },
147
+ "嘉兴": {
148
+ "telecode": "JXH",
149
+ "representative_station": "嘉兴"
150
+ },
151
+ "嘉峪关": {
152
+ "telecode": "JGJ",
153
+ "representative_station": "嘉峪关"
154
+ },
155
+ "大同": {
156
+ "telecode": "DTV",
157
+ "representative_station": "大同"
158
+ },
159
+ "大庆": {
160
+ "telecode": "DZX",
161
+ "representative_station": "大庆"
162
+ },
163
+ "大理": {
164
+ "telecode": "DKM",
165
+ "representative_station": "大理"
166
+ },
167
+ "大连": {
168
+ "telecode": "DLT",
169
+ "representative_station": "大连"
170
+ },
171
+ "天水": {
172
+ "telecode": "TSJ",
173
+ "representative_station": "天水"
174
+ },
175
+ "天津": {
176
+ "telecode": "TJP",
177
+ "representative_station": "天津"
178
+ },
179
+ "太原": {
180
+ "telecode": "TYV",
181
+ "representative_station": "太原"
182
+ },
183
+ "宁波": {
184
+ "telecode": "NGH",
185
+ "representative_station": "宁波"
186
+ },
187
+ "安顺": {
188
+ "telecode": "ASW",
189
+ "representative_station": "安顺"
190
+ },
191
+ "宜宾": {
192
+ "telecode": "YKE",
193
+ "representative_station": "宜宾"
194
+ },
195
+ "宜昌": {
196
+ "telecode": "YCN",
197
+ "representative_station": "宜昌"
198
+ },
199
+ "宝鸡": {
200
+ "telecode": "BJY",
201
+ "representative_station": "宝鸡"
202
+ },
203
+ "岳阳": {
204
+ "telecode": "YYQ",
205
+ "representative_station": "岳阳"
206
+ },
207
+ "常州": {
208
+ "telecode": "CZH",
209
+ "representative_station": "常州"
210
+ },
211
+ "常德": {
212
+ "telecode": "VGQ",
213
+ "representative_station": "常德"
214
+ },
215
+ "广州": {
216
+ "telecode": "GZQ",
217
+ "representative_station": "广州"
218
+ },
219
+ "库尔勒": {
220
+ "telecode": "KLR",
221
+ "representative_station": "库尔勒"
222
+ },
223
+ "延安": {
224
+ "telecode": "YWY",
225
+ "representative_station": "延安"
226
+ },
227
+ "开封": {
228
+ "telecode": "KFF",
229
+ "representative_station": "开封"
230
+ },
231
+ "张掖": {
232
+ "telecode": "ZYJ",
233
+ "representative_station": "张掖"
234
+ },
235
+ "徐州": {
236
+ "telecode": "XCH",
237
+ "representative_station": "徐州"
238
+ },
239
+ "德阳": {
240
+ "telecode": "DYW",
241
+ "representative_station": "德阳"
242
+ },
243
+ "惠州": {
244
+ "telecode": "HCQ",
245
+ "representative_station": "惠州"
246
+ },
247
+ "成都": {
248
+ "telecode": "CDW",
249
+ "representative_station": "成都"
250
+ },
251
+ "扬州": {
252
+ "telecode": "YLH",
253
+ "representative_station": "扬州"
254
+ },
255
+ "承德": {
256
+ "telecode": "CDP",
257
+ "representative_station": "承德"
258
+ },
259
+ "抚顺": {
260
+ "telecode": "FET",
261
+ "representative_station": "抚顺"
262
+ },
263
+ "拉萨": {
264
+ "telecode": "LSO",
265
+ "representative_station": "拉萨"
266
+ },
267
+ "揭阳": {
268
+ "telecode": "JYA",
269
+ "representative_station": "揭阳"
270
+ },
271
+ "新乡": {
272
+ "telecode": "XXF",
273
+ "representative_station": "新乡"
274
+ },
275
+ "无锡": {
276
+ "telecode": "WGH",
277
+ "representative_station": "无锡"
278
+ },
279
+ "日喀则": {
280
+ "telecode": "RKO",
281
+ "representative_station": "日喀则"
282
+ },
283
+ "昆明": {
284
+ "telecode": "KMM",
285
+ "representative_station": "昆明"
286
+ },
287
+ "普洱": {
288
+ "telecode": "PEM",
289
+ "representative_station": "普洱"
290
+ },
291
+ "景德镇": {
292
+ "telecode": "JCG",
293
+ "representative_station": "景德镇"
294
+ },
295
+ "曲靖": {
296
+ "telecode": "QJM",
297
+ "representative_station": "曲靖"
298
+ },
299
+ "杭州": {
300
+ "telecode": "HZH",
301
+ "representative_station": "杭州"
302
+ },
303
+ "林芝": {
304
+ "telecode": "LZO",
305
+ "representative_station": "林芝"
306
+ },
307
+ "柳州": {
308
+ "telecode": "LZZ",
309
+ "representative_station": "柳州"
310
+ },
311
+ "株洲": {
312
+ "telecode": "ZZQ",
313
+ "representative_station": "株洲"
314
+ },
315
+ "格尔木": {
316
+ "telecode": "GRO",
317
+ "representative_station": "格尔木"
318
+ },
319
+ "桂林": {
320
+ "telecode": "GLZ",
321
+ "representative_station": "桂林"
322
+ },
323
+ "梧州": {
324
+ "telecode": "WZZ",
325
+ "representative_station": "梧州"
326
+ },
327
+ "武汉": {
328
+ "telecode": "WHN",
329
+ "representative_station": "武汉"
330
+ },
331
+ "汉中": {
332
+ "telecode": "HOY",
333
+ "representative_station": "汉中"
334
+ },
335
+ "汕头": {
336
+ "telecode": "OTQ",
337
+ "representative_station": "汕头"
338
+ },
339
+ "沈阳": {
340
+ "telecode": "SYT",
341
+ "representative_station": "沈阳"
342
+ },
343
+ "泉州": {
344
+ "telecode": "QYS",
345
+ "representative_station": "泉州"
346
+ },
347
+ "泸州": {
348
+ "telecode": "LUE",
349
+ "representative_station": "泸州"
350
+ },
351
+ "洛阳": {
352
+ "telecode": "LYF",
353
+ "representative_station": "洛阳"
354
+ },
355
+ "济南": {
356
+ "telecode": "JNK",
357
+ "representative_station": "济南"
358
+ },
359
+ "深圳": {
360
+ "telecode": "SZQ",
361
+ "representative_station": "深圳"
362
+ },
363
+ "温州": {
364
+ "telecode": "RZH",
365
+ "representative_station": "温州"
366
+ },
367
+ "湛江": {
368
+ "telecode": "ZJZ",
369
+ "representative_station": "湛江"
370
+ },
371
+ "漳州": {
372
+ "telecode": "ZUS",
373
+ "representative_station": "漳州"
374
+ },
375
+ "潮州": {
376
+ "telecode": "CKQ",
377
+ "representative_station": "潮州"
378
+ },
379
+ "牡丹江": {
380
+ "telecode": "MDB",
381
+ "representative_station": "牡丹江"
382
+ },
383
+ "珠海": {
384
+ "telecode": "ZHQ",
385
+ "representative_station": "珠海"
386
+ },
387
+ "盐城": {
388
+ "telecode": "AFH",
389
+ "representative_station": "盐城"
390
+ },
391
+ "石家庄": {
392
+ "telecode": "SJP",
393
+ "representative_station": "石家庄"
394
+ },
395
+ "福州": {
396
+ "telecode": "FZS",
397
+ "representative_station": "福州"
398
+ },
399
+ "秦皇岛": {
400
+ "telecode": "QTP",
401
+ "representative_station": "秦皇岛"
402
+ },
403
+ "绍兴": {
404
+ "telecode": "SOH",
405
+ "representative_station": "绍兴"
406
+ },
407
+ "绵阳": {
408
+ "telecode": "MYW",
409
+ "representative_station": "绵阳"
410
+ },
411
+ "芜湖": {
412
+ "telecode": "WHH",
413
+ "representative_station": "芜湖"
414
+ },
415
+ "苏州": {
416
+ "telecode": "SZH",
417
+ "representative_station": "苏州"
418
+ },
419
+ "茂名": {
420
+ "telecode": "MDQ",
421
+ "representative_station": "茂名"
422
+ },
423
+ "莆田": {
424
+ "telecode": "PTS",
425
+ "representative_station": "莆田"
426
+ },
427
+ "衡阳": {
428
+ "telecode": "HYQ",
429
+ "representative_station": "衡阳"
430
+ },
431
+ "襄阳": {
432
+ "telecode": "XFN",
433
+ "representative_station": "襄阳"
434
+ },
435
+ "西宁": {
436
+ "telecode": "XNO",
437
+ "representative_station": "西宁"
438
+ },
439
+ "西安": {
440
+ "telecode": "XAY",
441
+ "representative_station": "西安"
442
+ },
443
+ "西昌": {
444
+ "telecode": "ECW",
445
+ "representative_station": "西昌"
446
+ },
447
+ "贵阳": {
448
+ "telecode": "GIW",
449
+ "representative_station": "贵阳"
450
+ },
451
+ "赣州": {
452
+ "telecode": "GZG",
453
+ "representative_station": "赣州"
454
+ },
455
+ "达州": {
456
+ "telecode": "RXW",
457
+ "representative_station": "达州"
458
+ },
459
+ "遵义": {
460
+ "telecode": "ZYE",
461
+ "representative_station": "遵义"
462
+ },
463
+ "郑州": {
464
+ "telecode": "ZZF",
465
+ "representative_station": "郑州"
466
+ },
467
+ "重庆": {
468
+ "telecode": "CUW",
469
+ "representative_station": "重庆"
470
+ },
471
+ "金华": {
472
+ "telecode": "JBH",
473
+ "representative_station": "金华"
474
+ },
475
+ "银川": {
476
+ "telecode": "YIJ",
477
+ "representative_station": "银川"
478
+ },
479
+ "镇江": {
480
+ "telecode": "ZJH",
481
+ "representative_station": "镇江"
482
+ },
483
+ "长春": {
484
+ "telecode": "CCT",
485
+ "representative_station": "长春"
486
+ },
487
+ "长沙": {
488
+ "telecode": "CSQ",
489
+ "representative_station": "长沙"
490
+ },
491
+ "阜阳": {
492
+ "telecode": "FYH",
493
+ "representative_station": "阜阳"
494
+ },
495
+ "青岛": {
496
+ "telecode": "QDK",
497
+ "representative_station": "青岛"
498
+ },
499
+ "鞍山": {
500
+ "telecode": "AST",
501
+ "representative_station": "鞍山"
502
+ },
503
+ "韶关": {
504
+ "telecode": "SNQ",
505
+ "representative_station": "韶关"
506
+ },
507
+ "香格里拉": {
508
+ "telecode": "EUM",
509
+ "representative_station": "香格里拉"
510
+ },
511
+ "香港": {
512
+ "telecode": "XJA",
513
+ "representative_station": "香港西九龙"
514
+ },
515
+ "齐齐哈尔": {
516
+ "telecode": "QHX",
517
+ "representative_station": "齐齐哈尔"
518
+ },
519
+ "龙岩": {
520
+ "telecode": "LYS",
521
+ "representative_station": "龙岩"
522
+ }
523
+ }
524
+ }
@@ -63,7 +63,7 @@ export async function reach(q) {
63
63
  verdict: 'not-installed',
64
64
  evidence: evidence('not-installed'),
65
65
  latencyMs: 0,
66
- setup: 'gotry .venv 缺 python — 见 docs/tokens.md(agent-reach 安装)'
66
+ setup: 'gotry .venv 缺 python——可选依赖未装配。补装:终端跑 npx gotry doctor --fix,或让用户看体检报告 npx gotry doctor'
67
67
  };
68
68
  }
69
69
  const args = Array.isArray(q.args) ? q.args : q.args ? q.args.split(/\s+/).filter(Boolean) : [];
@@ -85,7 +85,7 @@ export async function reach(q) {
85
85
  verdict: 'not-installed',
86
86
  evidence: evidence('not-installed'),
87
87
  latencyMs,
88
- setup: '.venv/bin/python 不可执行(装 agent-reach: 见 docs/tokens.md)'
88
+ setup: '.venv/bin/python 不可执行——补装:终端跑 npx gotry doctor --fix'
89
89
  };
90
90
  }
91
91
  if (parsed.ok === true) {
@@ -105,7 +105,7 @@ export async function reach(q) {
105
105
  verdict: 'not-installed',
106
106
  evidence: evidence('not-installed'),
107
107
  latencyMs,
108
- setup: '.venv 缺 agent-reach(pip install agent-reach,见 docs/tokens.md)'
108
+ setup: '.venv 缺 agent-reach 包——补装:终端跑 npx gotry doctor --fix'
109
109
  };
110
110
  }
111
111
  if (r.code === 2) {
@@ -184,7 +184,7 @@ export async function reachStatus(timeoutMs = 90_000) {
184
184
  via: 'not-installed',
185
185
  evidence: `[agent-reach:doctor@not-installed@${ts()}]`,
186
186
  latencyMs: 0,
187
- output: 'pip install agent-reach 于 .venv(见 docs/tokens.md)'
187
+ output: 'Agent Reach 未装配(.venv 缺失)——可选依赖,补装:终端跑 npx gotry doctor --fix;或让助手调 gotry_doctor 看整体体检报告'
188
188
  };
189
189
  }
190
190
  const r = await run(bin, [
@@ -0,0 +1,103 @@
1
+ const session = new Map();
2
+ export const DEFAULT_COOLDOWN_MS = 30_000;
3
+ export function markChannelDown(channel, reason, now = Date.now()) {
4
+ session.set(channel, {
5
+ state: 'down',
6
+ reason,
7
+ since: now
8
+ });
9
+ return {
10
+ channel,
11
+ state: 'down',
12
+ reason,
13
+ at: new Date(now).toISOString()
14
+ };
15
+ }
16
+ export function markChannelCooldown(channel, cooldownMs = DEFAULT_COOLDOWN_MS, now = Date.now()) {
17
+ session.set(channel, {
18
+ state: 'cooldown',
19
+ until: now + cooldownMs,
20
+ since: now
21
+ });
22
+ return {
23
+ channel,
24
+ state: 'cooldown',
25
+ at: new Date(now).toISOString()
26
+ };
27
+ }
28
+ export function clearChannel(channel) {
29
+ session.delete(channel);
30
+ }
31
+ export function channelState(channel, now = Date.now()) {
32
+ const e = session.get(channel);
33
+ if (!e) return undefined;
34
+ if (e.state === 'cooldown' && (e.until ?? 0) <= now) {
35
+ session.delete(channel);
36
+ return undefined;
37
+ }
38
+ return {
39
+ state: e.state,
40
+ reason: e.reason
41
+ };
42
+ }
43
+ export function resetChannelHealth() {
44
+ session.clear();
45
+ }
46
+ export function noteChannelVerdict(channel, verdict, opts = {}) {
47
+ const now = opts.now ?? Date.now();
48
+ switch(verdict){
49
+ case 'hit':
50
+ case 'found':
51
+ clearChannel(channel);
52
+ return undefined;
53
+ case 'needs-setup':
54
+ case 'needs-login':
55
+ case 'needs-extension':
56
+ case 'needs-attach':
57
+ case 'challenged':
58
+ return markChannelDown(channel, verdict, now);
59
+ case 'cooldown':
60
+ return markChannelCooldown(channel, opts.cooldownMs ?? DEFAULT_COOLDOWN_MS, now);
61
+ default:
62
+ return undefined;
63
+ }
64
+ }
65
+ export async function recordChannelEvent(stateRoot, event) {
66
+ try {
67
+ const { mkdir, appendFile } = await import('node:fs/promises');
68
+ const dir = `${stateRoot.replace(/\/+$/, '')}/gotry-state`;
69
+ await mkdir(dir, {
70
+ recursive: true
71
+ });
72
+ await appendFile(`${dir}/channel-health.jsonl`, `${JSON.stringify(event)}\n`, 'utf-8');
73
+ } catch {}
74
+ }
75
+ export async function readLatestChannelEvents(stateRoot, opts = {}) {
76
+ const latest = new Map();
77
+ try {
78
+ const { readFile } = await import('node:fs/promises');
79
+ const raw = await readFile(`${stateRoot.replace(/\/+$/, '')}/gotry-state/channel-health.jsonl`, 'utf-8');
80
+ const nowMs = opts.now ?? Date.now();
81
+ const cutoff = nowMs - (opts.limitDays ?? 30) * 86_400_000;
82
+ for (const line of raw.split('\n')){
83
+ const t = line.trim();
84
+ if (!t) continue;
85
+ try {
86
+ const ev = JSON.parse(t);
87
+ if (!ev || typeof ev.channel !== 'string' || typeof ev.state !== 'string') continue;
88
+ if (![
89
+ 'down',
90
+ 'cooldown',
91
+ 'ok'
92
+ ].includes(ev.state)) continue;
93
+ const atMs = Date.parse(ev.at ?? '');
94
+ if (Number.isFinite(atMs) && atMs < cutoff) continue;
95
+ latest.set(ev.channel, ev);
96
+ } catch {}
97
+ }
98
+ } catch {}
99
+ return latest;
100
+ }
101
+
102
+
103
+ //# sourceURL=ts/capabilities/channel-health.ts