@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,281 @@
1
+ import assert from 'node:assert/strict';
2
+ import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { installTurnDeadline, TURN_DEADLINE_EXHAUSTED, TURN_DEADLINE_HANDOFF, TURN_HANDOFF_SCHEMA, writeTurnHandoffTicket } from '../src/turn-deadline.js';
6
+ const success = ()=>({
7
+ isError: false,
8
+ value: null,
9
+ content: []
10
+ });
11
+ const handlers = new Map();
12
+ const restricted = [];
13
+ const lifted = [];
14
+ const makeAgent = (id)=>({
15
+ id,
16
+ ctx: {
17
+ tools: {
18
+ restrict (filter) {
19
+ restricted.push({
20
+ agentId: id,
21
+ deny: [
22
+ ...filter.deny
23
+ ]
24
+ });
25
+ return ()=>lifted.push(id);
26
+ }
27
+ }
28
+ }
29
+ });
30
+ const ctx = {
31
+ tools: {
32
+ schemas: ()=>[
33
+ {
34
+ name: 'gotry_alpha'
35
+ },
36
+ {
37
+ name: 'gotry_beta'
38
+ }
39
+ ]
40
+ },
41
+ on (event, listener) {
42
+ const bucket = handlers.get(event) ?? [];
43
+ bucket.push(listener);
44
+ handlers.set(event, bucket);
45
+ return ()=>{};
46
+ }
47
+ };
48
+ const productCtx = {
49
+ tools: {
50
+ schemas: ()=>[]
51
+ },
52
+ on (event) {
53
+ throw new Error(`opt-out path must not subscribe to ${event}`);
54
+ }
55
+ };
56
+ installTurnDeadline(productCtx, {
57
+ enabled: false
58
+ });
59
+ const clock = (()=>{
60
+ let t = 1_000_000;
61
+ return {
62
+ now: ()=>t,
63
+ advance: (ms)=>{
64
+ t += ms;
65
+ }
66
+ };
67
+ })();
68
+ const handoffRoot = mkdtempSync(join(tmpdir(), 'gotry-turn-handoff-tests-'));
69
+ installTurnDeadline(ctx, {
70
+ stateRoot: handoffRoot,
71
+ now: clock.now
72
+ });
73
+ const execute = handlers.get('tools/execute')?.[0];
74
+ const postExecute = handlers.get('tools/post-execute')?.[0];
75
+ const sessionEvent = handlers.get('session/event')?.[0];
76
+ const sessionDisposed = handlers.get('session/disposed')?.[0];
77
+ assert.ok(execute && postExecute && sessionEvent && sessionDisposed, 'all Cordis boundary hooks register');
78
+ const userMessage = (id, text, kind = 'user')=>sessionEvent({
79
+ id
80
+ }, {
81
+ type: 'user/message',
82
+ data: {
83
+ source: {
84
+ kind
85
+ },
86
+ content: [
87
+ {
88
+ type: 'text',
89
+ text
90
+ }
91
+ ]
92
+ }
93
+ });
94
+ const turnEvent = (id, type)=>sessionEvent({
95
+ id
96
+ }, {
97
+ type
98
+ });
99
+ {
100
+ let directBodies = 0;
101
+ for(let i = 0; i < 5; i++){
102
+ const result = await execute({
103
+ token: Symbol(`direct-${i}`)
104
+ }, async ()=>{
105
+ directBodies++;
106
+ return success();
107
+ });
108
+ assert.equal(result.isError, false);
109
+ }
110
+ assert.equal(directBodies, 5);
111
+ }{
112
+ const agent = makeAgent('agent-converge');
113
+ turnEvent(agent.id, 'turn/start');
114
+ userMessage(agent.id, '帮我看看10.1去杭州的高铁票');
115
+ {
116
+ const exec = {
117
+ token: Symbol('conv-1'),
118
+ agent
119
+ };
120
+ const result = await execute(exec, async ()=>success());
121
+ const post = await postExecute(exec, result, async ()=>({
122
+ kind: 'accept'
123
+ }));
124
+ assert.equal(result.isError, false);
125
+ assert.equal((post.additionalContexts ?? []).length, 0, 'no convergence context before soft');
126
+ assert.equal(restricted.length, 0);
127
+ }
128
+ clock.advance(300_001);
129
+ {
130
+ const exec = {
131
+ token: Symbol('conv-2'),
132
+ agent
133
+ };
134
+ const result = await execute(exec, async ()=>success());
135
+ const post = await postExecute(exec, result, async ()=>({
136
+ kind: 'accept'
137
+ }));
138
+ const contextText = post.additionalContexts?.flatMap((item)=>item.content ?? []).map((item)=>item.text ?? '').join('\n') ?? '';
139
+ assert.ok(contextText.includes('TURN_DEADLINE_SOFT'), 'soft context after crossing softMs');
140
+ assert.ok(contextText.includes('final answer'), 'converge soft text asks for a final answer');
141
+ }
142
+ clock.advance(300_000);
143
+ {
144
+ const exec = {
145
+ token: Symbol('conv-3'),
146
+ agent
147
+ };
148
+ let bodyRan = false;
149
+ const result = await execute(exec, async ()=>{
150
+ bodyRan = true;
151
+ return success();
152
+ });
153
+ assert.equal(bodyRan, false);
154
+ assert.equal(result.isError, true);
155
+ assert.deepEqual(result.error?.info, {
156
+ name: 'TurnDeadlineError',
157
+ code: TURN_DEADLINE_EXHAUSTED
158
+ });
159
+ assert.match(result.content[0]?.text ?? '', /TURN_DEADLINE_EXHAUSTED/);
160
+ }
161
+ assert.deepEqual(restricted.at(-1), {
162
+ agentId: agent.id,
163
+ deny: [
164
+ 'gotry_alpha',
165
+ 'gotry_beta'
166
+ ]
167
+ });
168
+ const convergeTicketDir = join(handoffRoot, 'gotry-state', 'turn-handoffs');
169
+ assert.equal(existsSync(convergeTicketDir) ? readdirSync(convergeTicketDir).length : 0, 0, 'converge writes no ticket');
170
+ turnEvent(agent.id, 'turn/end');
171
+ assert.equal(lifted.at(-1), agent.id);
172
+ }{
173
+ const agent = makeAgent('agent-handoff');
174
+ turnEvent(agent.id, 'turn/start');
175
+ const deepMessage = '2026年我还有6天IRW额度 ,我准备再请几天假,在国内待个十几天。' + '其中10.3要去湖南衡阳参加同学婚礼。其他我没有特别的要求,请根据我的实际情况,偏好,外部环境等因素,给我安排行程';
176
+ userMessage(agent.id, deepMessage);
177
+ clock.advance(120_001);
178
+ {
179
+ const exec = {
180
+ token: Symbol('hand-1'),
181
+ agent
182
+ };
183
+ const result = await execute(exec, async ()=>success());
184
+ const post = await postExecute(exec, result, async ()=>({
185
+ kind: 'accept'
186
+ }));
187
+ const contextText = post.additionalContexts?.flatMap((item)=>item.content ?? []).map((item)=>item.text ?? '').join('\n') ?? '';
188
+ assert.ok(contextText.includes('background planning'), 'handoff soft text announces the handoff');
189
+ assert.equal(result.isError, false);
190
+ }
191
+ clock.advance(120_000);
192
+ {
193
+ const exec = {
194
+ token: Symbol('hand-2'),
195
+ agent
196
+ };
197
+ let bodyRan = false;
198
+ const result = await execute(exec, async ()=>{
199
+ bodyRan = true;
200
+ return success();
201
+ });
202
+ assert.equal(bodyRan, false);
203
+ assert.equal(result.isError, true);
204
+ assert.deepEqual(result.error?.info, {
205
+ name: 'TurnDeadlineHandoff',
206
+ code: TURN_DEADLINE_HANDOFF
207
+ });
208
+ const text = result.content[0]?.text ?? '';
209
+ assert.match(text, /TURN_DEADLINE_HANDOFF/);
210
+ assert.match(text, /th-/, 'result names the persisted ticket id');
211
+ assert.match(text, /约 1 小时/, 'ETA label mirrors the S5 promise');
212
+ }
213
+ assert.deepEqual(restricted.at(-1), {
214
+ agentId: agent.id,
215
+ deny: [
216
+ 'gotry_alpha',
217
+ 'gotry_beta'
218
+ ]
219
+ });
220
+ const tickets = readdirSync(join(handoffRoot, 'gotry-state', 'turn-handoffs'));
221
+ assert.equal(tickets.length, 1, 'exactly one handoff ticket');
222
+ const ticket = JSON.parse(readFileSync(join(handoffRoot, 'gotry-state', 'turn-handoffs', tickets[0]), 'utf8'));
223
+ assert.equal(ticket.schema, TURN_HANDOFF_SCHEMA);
224
+ assert.equal(ticket.status, 'open');
225
+ assert.equal(ticket.userMessage, deepMessage, 'ticket carries the verbatim user ask');
226
+ assert.ok(ticket.requestedAt);
227
+ assert.equal(ticket.etaLabel, '约 1 小时');
228
+ turnEvent(agent.id, 'turn/end');
229
+ userMessage(agent.id, '你好');
230
+ {
231
+ const result = await execute({
232
+ token: Symbol('hand-3'),
233
+ agent
234
+ }, async ()=>success());
235
+ assert.equal(result.isError, false);
236
+ }
237
+ turnEvent(agent.id, 'turn/end');
238
+ assert.equal(readdirSync(join(handoffRoot, 'gotry-state', 'turn-handoffs')).length, 1, 'no extra tickets');
239
+ }{
240
+ const agent = makeAgent('agent-plugin-msg');
241
+ turnEvent(agent.id, 'turn/start');
242
+ userMessage(agent.id, '你好');
243
+ userMessage(agent.id, deepPlanningNoise(), 'plugin');
244
+ clock.advance(1_000_000);
245
+ {
246
+ const exec = {
247
+ token: Symbol('plug-1'),
248
+ agent
249
+ };
250
+ const result = await execute(exec, async ()=>success());
251
+ assert.deepEqual(result.error?.info, {
252
+ name: 'TurnDeadlineError',
253
+ code: TURN_DEADLINE_EXHAUSTED
254
+ });
255
+ }
256
+ turnEvent(agent.id, 'turn/end');
257
+ }function deepPlanningNoise() {
258
+ return '系统提醒样例:10.3 婚礼 IRW 请假 十几天 安排行程——这是插件注入,不该参与路由';
259
+ }
260
+ {
261
+ const root = mkdtempSync(join(tmpdir(), 'gotry-turn-handoff-writer-'));
262
+ const ticket = await writeTurnHandoffTicket(root, '短消息');
263
+ const dir = join(root, 'gotry-state', 'turn-handoffs');
264
+ assert.equal(readdirSync(dir).length, 1);
265
+ const loaded = JSON.parse(readFileSync(join(dir, `${ticket.id}.json`), 'utf8'));
266
+ assert.equal(loaded.userMessage, '短消息');
267
+ rmSync(root, {
268
+ recursive: true,
269
+ force: true
270
+ });
271
+ }sessionDisposed({
272
+ id: 'agent-handoff'
273
+ });
274
+ rmSync(handoffRoot, {
275
+ recursive: true,
276
+ force: true
277
+ });
278
+ console.log('agent turn deadline tests: OK (routing→converge/handoff exits, ticket persistence, plugin-message discipline, lifecycle)');
279
+
280
+
281
+ //# sourceURL=ts/scripts/agent-planning-turn-deadline-tests.ts
@@ -61,10 +61,7 @@ function assertRuntimeSelectionAndVersionGuards() {
61
61
  const legacyFallback = runRuntimeProbe({
62
62
  vendorVersion: '0.1.2-alpha.1'
63
63
  });
64
- assert.deepEqual(legacyFallback, {
65
- source: 'legacy-vendored',
66
- version: '0.1.2-alpha.1'
67
- }, 'non-benchmark source checkout may use the legacy vendored dsh fallback');
64
+ assert.equal(legacyFallback, null, 'D-27 removal (#120): legacy vendored fallback no longer resolves even outside benchmark — fail-closed');
68
65
  const wrongBenchmarkVersion = runRuntimeProbe({
69
66
  rootVersion: '0.1.2-alpha.1',
70
67
  vendorVersion: '0.1.2-alpha.1',
@@ -202,12 +199,10 @@ function toolCall(callId = 'bridge-call-1') {
202
199
  function: {
203
200
  name: TOOL,
204
201
  arguments: JSON.stringify({
205
- query: {
206
- action: 'call',
207
- tool: 'lookup',
208
- arguments: {
209
- city: 'Dubai'
210
- }
202
+ action: 'call',
203
+ tool: 'lookup',
204
+ arguments: {
205
+ city: 'Dubai'
211
206
  }
212
207
  })
213
208
  }