@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,288 @@
1
+ import { strict as assert } from 'node:assert';
2
+ import { mkdtempSync, rmSync, mkdirSync, writeFileSync, readdirSync, readFileSync, existsSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { aggregateFacts, aggregateChannels, aggregateIncidents, aggregateLatency, collectMetrics, renderMetricsReport, main } from './build-metrics-report.js';
6
+ const NOW = new Date('2026-09-05T12:00:00Z');
7
+ const DAY = 86_400_000;
8
+ const iso = (daysAgo)=>new Date(NOW.getTime() - daysAgo * DAY).toISOString();
9
+ let checkCount = 0;
10
+ function check(name, fn) {
11
+ fn();
12
+ checkCount += 1;
13
+ console.log(` ok ${checkCount} ${name}`);
14
+ }
15
+ async function withRoot(fn) {
16
+ const root = mkdtempSync(join(tmpdir(), 'gotry-metrics-'));
17
+ const stateDir = join(root, 'gotry-state');
18
+ mkdirSync(stateDir, {
19
+ recursive: true
20
+ });
21
+ try {
22
+ return await fn(root, stateDir);
23
+ } finally{
24
+ rmSync(root, {
25
+ recursive: true,
26
+ force: true
27
+ });
28
+ }
29
+ }
30
+ function writeJsonl(dir, name, lines) {
31
+ writeFileSync(join(dir, name), lines.map((l)=>typeof l === 'string' ? l : JSON.stringify(l)).join('\n') + '\n', 'utf-8');
32
+ }
33
+ check('事实闸聚合:去重/blocked 率/坏行容忍', ()=>{
34
+ const stats = aggregateFacts([
35
+ {
36
+ schema: 'gotry_bookable_fact.v1',
37
+ fact_id: 'f1',
38
+ kind: 'flight_like',
39
+ verdict: 'hit'
40
+ },
41
+ 'NOT JSON',
42
+ {
43
+ schema: 'gotry_bookable_fact.v1',
44
+ fact_id: 'f1',
45
+ kind: 'flight_like',
46
+ verdict: 'error'
47
+ },
48
+ {
49
+ schema: 'gotry_bookable_fact.v1',
50
+ fact_id: 'f2',
51
+ kind: 'flight_like',
52
+ verdict: 'hit'
53
+ },
54
+ {
55
+ schema: 'gotry_bookable_fact.v1',
56
+ fact_id: 'f3',
57
+ kind: 'hotel',
58
+ verdict: 'needs-setup'
59
+ },
60
+ {
61
+ schema: 'gotry_bookable_fact.v1',
62
+ fact_id: 'f4',
63
+ kind: 'hotel',
64
+ verdict: 'miss'
65
+ },
66
+ {
67
+ fact_id: 'f5',
68
+ kind: 'hotel'
69
+ }
70
+ ]);
71
+ assert.equal(stats.lines, 7);
72
+ assert.equal(stats.deduped, 5);
73
+ const flight = stats.byKind.flight_like;
74
+ assert.equal(flight.total, 2);
75
+ assert.equal(flight.verdicts.error, 1);
76
+ assert.equal(flight.verdicts.hit, 1);
77
+ assert.equal(flight.blocked, 1);
78
+ const hotel = stats.byKind.hotel;
79
+ assert.equal(hotel.total, 3);
80
+ assert.equal(hotel.blocked, 1);
81
+ assert.equal(hotel.verdicts['n/a'], 1);
82
+ });
83
+ check('通道健康聚合:30 天窗/最新事件/计数', ()=>{
84
+ const stats = aggregateChannels([
85
+ {
86
+ channel: 'flyai',
87
+ state: 'down',
88
+ reason: 'trial-exhausted',
89
+ at: iso(40)
90
+ },
91
+ {
92
+ channel: 'flyai',
93
+ state: 'down',
94
+ reason: '429',
95
+ at: iso(2)
96
+ },
97
+ {
98
+ channel: 'flyai',
99
+ state: 'cooldown',
100
+ reason: 'retry-after',
101
+ at: iso(1)
102
+ },
103
+ {
104
+ channel: 'session:ctrip-hotel',
105
+ state: 'down',
106
+ reason: 'needs-login',
107
+ at: iso(5)
108
+ },
109
+ 'BROKEN'
110
+ ], {
111
+ now: NOW
112
+ });
113
+ assert.equal(stats.latest.length, 2);
114
+ const flyai = stats.latest.find((c)=>c.channel === 'flyai');
115
+ assert.equal(flyai?.state, 'cooldown');
116
+ assert.equal(flyai?.events, 2);
117
+ const ctrip = stats.latest.find((c)=>c.channel === 'session:ctrip-hotel');
118
+ assert.equal(ctrip?.events, 1);
119
+ });
120
+ check('事故面聚合:窗口/kind 计数/最近一条/top 来源', ()=>{
121
+ const stats = aggregateIncidents([
122
+ {
123
+ ts: iso(10),
124
+ kind: 'uncaughtException',
125
+ message: '太旧不计',
126
+ source: 'old-plugin'
127
+ },
128
+ {
129
+ ts: iso(1),
130
+ kind: 'plugin_error',
131
+ message: 'z3 wasm boom',
132
+ source: 'z3'
133
+ },
134
+ {
135
+ ts: iso(0.2),
136
+ kind: 'plugin_error',
137
+ message: 'second boom',
138
+ source: 'z3'
139
+ },
140
+ {
141
+ ts: iso(0.1),
142
+ kind: 'tool_execute_error',
143
+ message: 'flyai 429',
144
+ source: 'flyai'
145
+ }
146
+ ], {
147
+ now: NOW,
148
+ windowDays: 7
149
+ });
150
+ assert.equal(stats.totalInWindow, 3);
151
+ assert.equal(stats.byKind.plugin_error.count, 2);
152
+ assert.equal(stats.byKind.plugin_error.lastMessage, 'second boom');
153
+ assert.deepEqual(stats.topSources[0], {
154
+ source: 'z3',
155
+ count: 2
156
+ });
157
+ });
158
+ check('桥延迟聚合:p50/p95/max/超预算', ()=>{
159
+ const stats = aggregateLatency([
160
+ {
161
+ ts: iso(1),
162
+ kind: 'hotel_search:hbcli',
163
+ latencyMs: 100
164
+ },
165
+ {
166
+ ts: iso(1),
167
+ kind: 'hotel_search:hbcli',
168
+ latencyMs: 200
169
+ },
170
+ {
171
+ ts: iso(0.5),
172
+ kind: 'weather:open-meteo',
173
+ latencyMs: 300
174
+ },
175
+ {
176
+ ts: iso(0.4),
177
+ kind: 'weather:open-meteo',
178
+ latencyMs: 400
179
+ },
180
+ {
181
+ ts: iso(0.3),
182
+ kind: 'hotel_search:session',
183
+ latencyMs: 501
184
+ },
185
+ {
186
+ ts: iso(9),
187
+ kind: 'old',
188
+ latencyMs: 999_999
189
+ },
190
+ {
191
+ ts: iso(0.2),
192
+ kind: 'bad',
193
+ latencyMs: Number.NaN
194
+ }
195
+ ], {
196
+ now: NOW,
197
+ windowDays: 7
198
+ });
199
+ assert.equal(stats.count, 5);
200
+ assert.equal(stats.p50, 300);
201
+ assert.equal(stats.p95, 501);
202
+ assert.equal(stats.max, 501);
203
+ assert.equal(stats.overBudget, 1);
204
+ assert.deepEqual(stats.topKinds[0], {
205
+ kind: 'hotel_search:hbcli',
206
+ count: 2
207
+ });
208
+ });
209
+ await withRoot(async (root)=>{
210
+ const before = readdirSync(root).sort();
211
+ const snap = await collectMetrics(root, {
212
+ now: NOW
213
+ });
214
+ const md = renderMetricsReport(snap);
215
+ assert.match(md, /事实闸 verdict 分布/);
216
+ assert.match(md, /通道健康/);
217
+ assert.match(md, /事故面/);
218
+ assert.match(md, /桥延迟/);
219
+ assert.match(md, /\(空:窗口内无事故\)/);
220
+ assert.match(md, /不存在\(该 stateRoot 无账本\)/);
221
+ assert.deepEqual(readdirSync(root).sort(), before, 'collect 不得在 stateRoot 新建任何文件');
222
+ checkCount += 1;
223
+ console.log(` ok ${checkCount} 空 stateRoot:报告成型且零写入`);
224
+ });
225
+ await withRoot(async (root, stateDir)=>{
226
+ writeJsonl(stateDir, 'bookable-facts.jsonl', [
227
+ {
228
+ schema: 'gotry_bookable_fact.v1',
229
+ fact_id: 'a',
230
+ kind: 'hotel',
231
+ verdict: 'hit'
232
+ },
233
+ {
234
+ schema: 'gotry_bookable_fact.v1',
235
+ fact_id: 'b',
236
+ kind: 'hotel',
237
+ verdict: 'error'
238
+ }
239
+ ]);
240
+ writeJsonl(stateDir, 'channel-health.jsonl', [
241
+ {
242
+ channel: 'flyai',
243
+ state: 'down',
244
+ reason: 'trial-exhausted',
245
+ at: iso(1)
246
+ }
247
+ ]);
248
+ writeJsonl(stateDir, 'incidents.jsonl', [
249
+ {
250
+ ts: iso(1),
251
+ kind: 'plugin_error',
252
+ message: 'boom',
253
+ source: 'z3'
254
+ }
255
+ ]);
256
+ writeJsonl(stateDir, 'bridge-latency.jsonl', [
257
+ {
258
+ ts: iso(1),
259
+ kind: 'hotel_search:hbcli',
260
+ latencyMs: 120
261
+ }
262
+ ]);
263
+ writeFileSync(join(stateDir, 'doctor-report.md'), '# doctor\n', 'utf-8');
264
+ const before = readdirSync(stateDir).sort();
265
+ const outPath = join(root, 'report.md');
266
+ await main([
267
+ '--state-root',
268
+ root,
269
+ '--out',
270
+ outPath,
271
+ '--days',
272
+ '7'
273
+ ]);
274
+ const md = readFileSync(outPath, 'utf-8');
275
+ assert.match(md, /hotel \| 2 \| hit:1 \/ error:1 \| 1\/2\(50%\)/);
276
+ assert.match(md, /\| flyai \| down \| trial-exhausted \|/);
277
+ assert.match(md, /plugin_error \| 1 /);
278
+ assert.match(md, /p50=120ms/);
279
+ assert.match(md, /doctor 报告 doctor-report\.md:存在/);
280
+ assert.deepEqual(readdirSync(stateDir).sort(), before, '报告生成不得改动 gotry-state 目录');
281
+ assert.ok(existsSync(outPath));
282
+ checkCount += 1;
283
+ console.log(` ok ${checkCount} 端到端:侧车聚合→--out 落盘,stateRoot 只读`);
284
+ });
285
+ console.log(`\nMETRICS REPORT TESTS OK(${checkCount} checks)`);
286
+
287
+
288
+ //# sourceURL=ts/scripts/metrics-report-tests.ts
@@ -0,0 +1,19 @@
1
+ import assert from 'node:assert/strict';
2
+ import { readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ const patch = readFileSync(join(process.cwd(), '..', 'cordis.gotry-patch.yml'), 'utf-8');
5
+ const guard = '表层规则:gotry 的全部能力一律是【工具调用】';
6
+ assert.equal((patch.match(new RegExp(guard, 'g')) ?? []).length, 1, '表层规则句应恰好出现一次');
7
+ assert.ok(patch.includes('绝不把 gotry_* 名字传给 skill 加载器'), '应显式禁止 gotry_* 进 skill 加载器');
8
+ const markers = new Set([
9
+ ...patch.matchAll(/\((\d{1,2})\)/g)
10
+ ].map((m)=>Number(m[1])));
11
+ for(let i = 1; i <= 22; i += 1){
12
+ assert.ok(markers.has(i), `行为契约 (${i}) 应存在`);
13
+ }
14
+ assert.equal(markers.size, 22, `契约条目应恰为 22 条,实际 ${markers.size}`);
15
+ assert.ok(patch.includes('改回 tool call'), '应指引失败后改回 tool call');
16
+ console.log('PERSONA SURFACE GUARD TESTS: 3/3 OK(表层规则句 / 22 条契约完整 / skill 失败行为指引)');
17
+
18
+
19
+ //# sourceURL=ts/scripts/persona-surface-guard-tests.ts