@danceiny/gotry 0.0.1-rc.18 → 0.0.1-rc.20
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.
- package/README.md +42 -16
- package/README.zh-CN.md +37 -15
- package/bin/gotry-bootstrap.js +309 -30
- package/bin/gotry-inner.js +74 -23
- package/bin/gotry-runtime-resolution.d.ts +1 -1
- package/bin/gotry-runtime-resolution.js +7 -8
- package/cordis.gotry-patch.yml +22 -8
- package/data/stations-12306-verify.json +524 -0
- package/dist/capabilities/agent-reach.js +4 -4
- package/dist/capabilities/anything.js +62 -29
- package/dist/capabilities/channel-health.js +103 -0
- package/dist/capabilities/channel-registry.js +213 -0
- package/dist/capabilities/doctor.js +307 -0
- package/dist/capabilities/effect.js +178 -5
- package/dist/capabilities/flyai.js +13 -0
- package/dist/capabilities/hbcli.js +28 -2
- package/dist/capabilities/session/adapters/ctrip-hotel.js +207 -0
- package/dist/capabilities/session/adapters/rail-12306.js +285 -0
- package/dist/capabilities/session/extension-bridge.js +14 -1
- package/dist/capabilities/session/extension-channel.js +4 -2
- package/dist/capabilities/session/extension-distribution.js +1 -1
- package/dist/capabilities/session-search.js +311 -0
- package/dist/capabilities/visa-policy.js +126 -0
- package/dist/scripts/agent-planning-turn-deadline-e2e.js +305 -0
- package/dist/scripts/agent-planning-turn-deadline-tests.js +281 -0
- package/dist/scripts/anything-tests.js +70 -21
- package/dist/scripts/benchmark-environment-bridge-e2e.js +139 -37
- package/dist/scripts/benchmark-environment-bridge-tests.js +1099 -306
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +26 -26
- package/dist/scripts/{booking-copilot-availability-policy-v2-tests.js → booking-copilot-availability-policy-tests.js} +115 -115
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +41 -1
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +75 -120
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +370 -61
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +2 -2
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +7 -3
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +15 -9
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +19 -11
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +16 -52
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +3953 -155
- package/dist/scripts/booking-copilot-server-proof-tests.js +58 -23
- package/dist/scripts/booking-copilot-startup-proof-tests.js +10 -119
- package/dist/scripts/booking-surface-contract-proof-tests.js +1154 -326
- package/dist/scripts/bootstrap-tests.js +113 -2
- package/dist/scripts/build-metrics-report.js +339 -0
- package/dist/scripts/channel-probe-tests.js +148 -0
- package/dist/scripts/channel-probe.js +252 -0
- package/dist/scripts/channel-registry-tests.js +262 -0
- package/dist/scripts/doctor-tests.js +175 -0
- package/dist/scripts/effect-tests.js +274 -1
- package/dist/scripts/extension-tests.js +129 -11
- package/dist/scripts/fact-gate-tests.js +91 -2
- package/dist/scripts/flyai-tests.js +17 -1
- package/dist/scripts/hbcli-e2e-tests.js +1 -3
- package/dist/scripts/hbcli-tests.js +38 -1
- package/dist/scripts/metrics-report-tests.js +288 -0
- package/dist/scripts/persona-surface-guard-tests.js +19 -0
- package/dist/scripts/session-tests.js +401 -1
- package/dist/scripts/smoke.js +100 -83
- package/dist/scripts/turn-handoff-collect-tests.js +216 -0
- package/dist/scripts/turn-handoff-collect.js +189 -0
- package/dist/scripts/turn-policy-tests.js +56 -0
- package/dist/scripts/typed-contract-canary.js +261 -0
- package/dist/scripts/visa-policy-tests.js +75 -0
- package/dist/scripts/wish-channel-gate-tests.js +111 -0
- package/dist/src/artifact-gate.js +91 -3
- package/dist/src/benchmark-agent-conformance.js +39 -16
- package/dist/src/benchmark-environment-bridge.js +316 -52
- package/dist/src/bookable-facts.js +62 -3
- package/dist/src/booking-surface/{availability-policy-v2.js → availability-policy.js} +89 -89
- package/dist/src/booking-surface/canonical-schema.js +8 -22
- package/dist/src/booking-surface/contracts.js +70 -19
- package/dist/src/booking-surface/dsh-planner.js +310 -177
- package/dist/src/booking-surface/dsh-plugin.js +3 -3
- package/dist/src/booking-surface/index.js +1 -5
- package/dist/src/booking-surface/profile.js +1 -1
- package/dist/src/booking-surface/runtime.js +1682 -247
- package/dist/src/booking-surface/server.js +371 -185
- package/dist/src/booking-surface/startup.js +17 -27
- package/dist/src/booking-surface/validation.js +270 -760
- package/dist/src/index.js +739 -150
- package/dist/src/turn-deadline.js +292 -0
- package/dist/src/turn-policy.js +146 -0
- package/dist/src/wish-pool.js +5 -0
- package/extension/background.js +23 -4
- package/extension/content-main.js +47 -9
- package/extension/manifest.json +27 -9
- package/package.json +7 -26
- package/schemas/booking.surface.schema.json +2593 -0
- package/ts/capabilities/agent-reach.ts +4 -4
- package/ts/capabilities/anything.ts +89 -38
- package/ts/capabilities/flyai.ts +21 -3
- package/ts/capabilities/hbcli.ts +53 -4
- package/ts/capabilities/session/action-cache.ts +1 -1
- package/ts/capabilities/session/adapters/ctrip-hotel.ts +238 -0
- package/ts/capabilities/session/adapters/rail-12306.ts +293 -0
- package/ts/capabilities/session/extension-bridge.ts +32 -2
- package/ts/capabilities/session/extension-channel.ts +9 -8
- package/ts/capabilities/session/extension-distribution.ts +3 -1
- package/ts/capabilities/session/health-watch.ts +1 -1
- package/ts/capabilities/session/read-guard.ts +1 -1
- package/ts/capabilities/session/wizard.ts +1 -1
- package/ts/capabilities/session-search.ts +323 -1
- package/ts/dsh-runtime/vendor/README.md +60 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/LICENSE +21 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.en.md +200 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/README.md +202 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/client/client.js +216 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/cordis.patch.yml +5 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/amap.js +371 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/nominatim.js +63 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/osrm.js +56 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/clients/photon.js +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-file.js +87 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config-route.js +126 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/config.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/index.js +109 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/settings-ns.js +27 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/geocode.js +127 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/poi.js +84 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/tools/routes.js +170 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/amap.d.ts +53 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/nominatim.d.ts +17 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/osrm.d.ts +15 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/clients/photon.d.ts +22 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-file.d.ts +33 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config-route.d.ts +20 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/config.d.ts +23 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/index.d.ts +18 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/settings-ns.d.ts +14 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/geocode.d.ts +11 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/poi.d.ts +9 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/tools/routes.d.ts +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types/types.d.ts +55 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/lib/types.js +16 -0
- package/ts/dsh-runtime/vendor/dsh-map-tools/package.json +91 -0
- package/ts/package.json +9 -0
- package/ts/scripts/turn-handoff-collect.ts +178 -0
- package/ts/src/artifact-gate.ts +82 -2
- package/ts/src/benchmark-agent-conformance.ts +54 -15
- package/ts/src/benchmark-environment-bridge.ts +234 -46
- package/ts/src/bookable-facts.ts +109 -5
- package/ts/src/booking-saga.ts +1 -1
- package/ts/src/booking-surface/{availability-policy-v2.ts → availability-policy.ts} +124 -125
- package/ts/src/booking-surface/canonical-schema.js +8 -22
- package/ts/src/booking-surface/contracts.ts +278 -239
- package/ts/src/booking-surface/dsh-planner.ts +333 -194
- package/ts/src/booking-surface/dsh-plugin.js +3 -3
- package/ts/src/booking-surface/index.ts +1 -5
- package/ts/src/booking-surface/profile.ts +11 -11
- package/ts/src/booking-surface/runtime.ts +1351 -351
- package/ts/src/booking-surface/server.ts +282 -175
- package/ts/src/booking-surface/startup.ts +36 -48
- package/ts/src/booking-surface/validation.ts +194 -442
- package/ts/src/contracts.ts +1 -1
- package/ts/src/index.ts +492 -172
- package/ts/src/loop.ts +1 -1
- package/ts/src/state-ledger.ts +1 -1
- package/ts/src/turn-deadline.ts +365 -0
- package/ts/src/turn-policy.ts +154 -0
- package/ts/src/wish-pool.ts +17 -4
- package/dist/scripts/agent-planning-budget-e2e.js +0 -227
- package/dist/scripts/agent-planning-budget-tests.js +0 -173
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +0 -3935
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +0 -1174
- package/dist/src/booking-surface/contracts-v2.js +0 -89
- package/dist/src/booking-surface/runtime-v2.js +0 -1771
- package/dist/src/booking-surface/server-v2.js +0 -334
- package/dist/src/booking-surface/validation-v2.js +0 -319
- package/dist/src/tool-budget.js +0 -136
- package/schemas/booking.surface.v1.schema.json +0 -927
- package/schemas/booking.surface.v2.schema.json +0 -61
- package/ts/src/booking-surface/contracts-v2.ts +0 -118
- package/ts/src/booking-surface/runtime-v2.ts +0 -1466
- package/ts/src/booking-surface/server-v2.ts +0 -247
- package/ts/src/booking-surface/validation-v2.ts +0 -205
- package/ts/src/tool-budget.ts +0 -165
|
@@ -30,7 +30,7 @@ const plannerFactory = (initialTask)=>{
|
|
|
30
30
|
{
|
|
31
31
|
kind: 'operation',
|
|
32
32
|
action: {
|
|
33
|
-
schemaVersion: 'booking.surface
|
|
33
|
+
schemaVersion: 'booking.surface',
|
|
34
34
|
kind: 'search.run',
|
|
35
35
|
actionId: 'action-http-1',
|
|
36
36
|
contextRef: task.contextRef,
|
|
@@ -72,7 +72,12 @@ const endpoint = `http://127.0.0.1:${serverHandle.port}/a2a/booking-copilot/turn
|
|
|
72
72
|
const expectedProbe = {
|
|
73
73
|
schemaVersion: SCHEMA_VERSION,
|
|
74
74
|
schemaSha256: SCHEMA_SHA256,
|
|
75
|
-
status: 'ready'
|
|
75
|
+
status: 'ready',
|
|
76
|
+
ingressMode: 'bff-bound-turn-only',
|
|
77
|
+
acceptedTurnKinds: [
|
|
78
|
+
'user.turn',
|
|
79
|
+
'action.receipt.continuation'
|
|
80
|
+
]
|
|
76
81
|
};
|
|
77
82
|
const runtimeReport = process.report?.getReport?.();
|
|
78
83
|
const runtimeGlibcVersion = runtimeReport?.header?.glibcVersionRuntime ?? '';
|
|
@@ -115,7 +120,7 @@ for (const path of [
|
|
|
115
120
|
assert.deepEqual(await authorized.json(), expectedProbe, `${path} exposes only typed readiness contract`);
|
|
116
121
|
}
|
|
117
122
|
const workspace = {
|
|
118
|
-
schemaVersion: 'booking.surface
|
|
123
|
+
schemaVersion: 'booking.surface',
|
|
119
124
|
contextRef: 'ctx-http-1',
|
|
120
125
|
surface: 'tenant',
|
|
121
126
|
revision: 0,
|
|
@@ -136,9 +141,10 @@ const workspace = {
|
|
|
136
141
|
}
|
|
137
142
|
};
|
|
138
143
|
const userTurn = {
|
|
139
|
-
schemaVersion: 'booking.surface
|
|
144
|
+
schemaVersion: 'booking.surface',
|
|
140
145
|
kind: 'user.turn',
|
|
141
146
|
taskId: 'task-http-1',
|
|
147
|
+
turnId: 'http-turn-1',
|
|
142
148
|
workspace,
|
|
143
149
|
request: {
|
|
144
150
|
text: '执行当前搜索'
|
|
@@ -173,20 +179,29 @@ const wrongSchemaHash = await post(userTurn, `Bearer ${API_KEY}`, {
|
|
|
173
179
|
});
|
|
174
180
|
assert.equal(wrongSchemaHash.status, 409, 'schema drift is rejected before planning');
|
|
175
181
|
const directIngress = await post({
|
|
176
|
-
schemaVersion: 'booking.surface
|
|
182
|
+
schemaVersion: 'booking.surface',
|
|
177
183
|
kind: 'user.turn.ingress',
|
|
184
|
+
requestKey: 'browser-request-1',
|
|
178
185
|
surfaceHint: 'tenant',
|
|
179
186
|
workspace: {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
187
|
+
schemaVersion: 'booking.surface',
|
|
188
|
+
revision: 0,
|
|
189
|
+
locale: 'zh-CN',
|
|
190
|
+
currency: 'AED',
|
|
191
|
+
searchDraft: {},
|
|
192
|
+
results: {
|
|
193
|
+
status: 'idle'
|
|
194
|
+
},
|
|
195
|
+
visibleHotels: [],
|
|
196
|
+
loadedOffers: [],
|
|
197
|
+
shortlistedOfferRefs: []
|
|
184
198
|
},
|
|
185
199
|
request: {
|
|
186
200
|
text: 'browser must use same-origin BFF'
|
|
187
201
|
}
|
|
188
202
|
});
|
|
189
|
-
assert.equal(directIngress.status,
|
|
203
|
+
assert.equal(directIngress.status, 503, 'GoTry server rejects unbound browser ingress');
|
|
204
|
+
assert.equal((await directIngress.json()).error.code, 'trusted_ingress_binding_required');
|
|
190
205
|
const tokenSmuggle = await post({
|
|
191
206
|
...userTurn,
|
|
192
207
|
portalToken: 'ST:must-not-cross-boundary'
|
|
@@ -208,15 +223,17 @@ const firstEvents = parseSse(await first.text());
|
|
|
208
223
|
assert.deepEqual(firstEvents.map((event)=>event.kind), [
|
|
209
224
|
'status',
|
|
210
225
|
'status',
|
|
211
|
-
'operation'
|
|
226
|
+
'operation',
|
|
227
|
+
'status'
|
|
212
228
|
]);
|
|
229
|
+
assert.equal(firstEvents[3].kind === 'status' ? firstEvents[3].status : '', 'waiting_receipt', 'the operation leaves the task durably waiting for its receipt');
|
|
213
230
|
assert.ok(firstEvents.every((event)=>event.contextRef === workspace.contextRef), 'every typed event carries BFF-minted contextRef');
|
|
214
231
|
const operation = firstEvents[2];
|
|
215
232
|
assert.equal(operation?.kind, 'operation');
|
|
216
233
|
assert.equal(factoryCalls, 1);
|
|
217
234
|
assert.equal(sessionTurns, 1);
|
|
218
235
|
const receiptTurn = {
|
|
219
|
-
schemaVersion: 'booking.surface
|
|
236
|
+
schemaVersion: 'booking.surface',
|
|
220
237
|
kind: 'action.receipt.continuation',
|
|
221
238
|
taskId: 'task-http-1',
|
|
222
239
|
workspace: {
|
|
@@ -229,7 +246,7 @@ const receiptTurn = {
|
|
|
229
246
|
}
|
|
230
247
|
},
|
|
231
248
|
receipt: {
|
|
232
|
-
schemaVersion: 'booking.surface
|
|
249
|
+
schemaVersion: 'booking.surface',
|
|
233
250
|
kind: 'action.receipt',
|
|
234
251
|
actionId: 'action-http-1',
|
|
235
252
|
contextRef: workspace.contextRef,
|
|
@@ -244,7 +261,9 @@ const receiptTurn = {
|
|
|
244
261
|
outcome: 'complete',
|
|
245
262
|
hardCriteriaMet: true,
|
|
246
263
|
factRefs: [],
|
|
247
|
-
gapCodes: []
|
|
264
|
+
gapCodes: [],
|
|
265
|
+
blockers: [],
|
|
266
|
+
relaxationsApplied: []
|
|
248
267
|
}
|
|
249
268
|
}
|
|
250
269
|
};
|
|
@@ -261,15 +280,18 @@ assert.equal(sessionTurns, 2);
|
|
|
261
280
|
assert.ok(!secondEvents.some((event)=>event.kind === 'operation'), 'JSON-looking explanation text is not parsed into an operation');
|
|
262
281
|
assert.ok(secondEvents[0].sequence > firstEvents.at(-1).sequence, 'SSE sequence is monotonic across turns');
|
|
263
282
|
await serverHandle.close();
|
|
264
|
-
|
|
283
|
+
const preRestartRuntime = new BookingCopilotTaskRuntime(ledger, {
|
|
284
|
+
idFactory: (prefix)=>`${prefix}-probe-${++nextId}`,
|
|
285
|
+
now: ()=>'2026-08-30T12:01:00.000Z'
|
|
286
|
+
});
|
|
287
|
+
const recovered = preRestartRuntime.resumeTask('task-http-1');
|
|
288
|
+
assert.equal(recovered?.lastReceipt?.actionId, 'action-http-1', 'new server process seam restores task from last typed receipt');
|
|
289
|
+
assert.equal(recovered?.phase, 'terminal', 'the completed task stays durably terminal across restart');
|
|
265
290
|
const restarted = await startBookingCopilotServer({
|
|
266
291
|
apiKey: API_KEY,
|
|
267
|
-
runtime:
|
|
268
|
-
idFactory: (prefix)=>`${prefix}-restart-${++nextId}`,
|
|
269
|
-
now: ()=>'2026-08-30T12:01:00.000Z'
|
|
270
|
-
}),
|
|
292
|
+
runtime: preRestartRuntime,
|
|
271
293
|
plannerFactory: (initialTask)=>{
|
|
272
|
-
|
|
294
|
+
assert.equal(initialTask.taskId, 'task-http-2');
|
|
273
295
|
return {
|
|
274
296
|
async next () {
|
|
275
297
|
return [
|
|
@@ -298,13 +320,26 @@ const afterRestartResponse = await fetch(restartedEndpoint, {
|
|
|
298
320
|
},
|
|
299
321
|
body: JSON.stringify({
|
|
300
322
|
...userTurn,
|
|
301
|
-
|
|
323
|
+
taskId: 'task-http-2',
|
|
324
|
+
turnId: 'http-restart-turn-1',
|
|
325
|
+
workspace: {
|
|
326
|
+
...workspace,
|
|
327
|
+
contextRef: 'ctx-http-2'
|
|
328
|
+
}
|
|
302
329
|
})
|
|
303
330
|
});
|
|
304
331
|
assert.equal(afterRestartResponse.status, 200);
|
|
305
|
-
assert.equal(recoveredLastReceipt, true, 'new server process seam restores task from last typed receipt');
|
|
306
332
|
const restartEvents = parseSse(await afterRestartResponse.text());
|
|
307
|
-
assert.
|
|
333
|
+
assert.deepEqual(restartEvents.map((event)=>event.kind), [
|
|
334
|
+
'status',
|
|
335
|
+
'status',
|
|
336
|
+
'terminal'
|
|
337
|
+
]);
|
|
338
|
+
assert.deepEqual(restartEvents.map((event)=>event.sequence), [
|
|
339
|
+
1,
|
|
340
|
+
2,
|
|
341
|
+
3
|
|
342
|
+
], 'the restarted process allocates fresh task-scoped sequences after recovering the ledger');
|
|
308
343
|
await restarted.close();
|
|
309
344
|
ledger.close();
|
|
310
345
|
rmSync(stateRoot, {
|
|
@@ -3,7 +3,7 @@ import { mkdtempSync, rmSync } from 'node:fs';
|
|
|
3
3
|
import { tmpdir } from 'node:os';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { resolveBookingCopilotStartupConfig, startBookingCopilotFromEnvironment } from '../src/booking-surface/startup.js';
|
|
6
|
-
import {
|
|
6
|
+
import { BOOKING_READ_ACTION_KINDS } from '../src/booking-surface/contracts.js';
|
|
7
7
|
assert.throws(()=>resolveBookingCopilotStartupConfig({}), /booking_copilot_api_key_required/);
|
|
8
8
|
assert.throws(()=>resolveBookingCopilotStartupConfig({
|
|
9
9
|
GOTRY_BOOKING_COPILOT_API_KEY: 'bff-key',
|
|
@@ -26,8 +26,8 @@ const env = {
|
|
|
26
26
|
};
|
|
27
27
|
await assert.rejects(startBookingCopilotFromEnvironment({
|
|
28
28
|
...env,
|
|
29
|
-
|
|
30
|
-
}, {}), /
|
|
29
|
+
GOTRY_BOOKING_COPILOT_INGRESS_MODE: 'bff-ingress-binding'
|
|
30
|
+
}, {}), /booking_copilot_ingress_binding_required/, 'explicit ingress mode rejects startup when the trusted BFF seam is absent');
|
|
31
31
|
await assert.rejects(startBookingCopilotFromEnvironment(env, {
|
|
32
32
|
ingressBinding: {
|
|
33
33
|
bind: ()=>({
|
|
@@ -36,17 +36,17 @@ await assert.rejects(startBookingCopilotFromEnvironment(env, {
|
|
|
36
36
|
contextRef: 'partial-context',
|
|
37
37
|
surface: 'tenant',
|
|
38
38
|
allowedActions: [
|
|
39
|
-
...
|
|
39
|
+
...BOOKING_READ_ACTION_KINDS
|
|
40
40
|
]
|
|
41
41
|
})
|
|
42
42
|
}
|
|
43
|
-
}), /
|
|
43
|
+
}), /booking_copilot_ingress_binding_pair_required/, 'partial trusted BFF seam is rejected before startup');
|
|
44
44
|
await assert.rejects(startBookingCopilotFromEnvironment(env, {
|
|
45
45
|
principal: {
|
|
46
46
|
subject: 'partial-bff',
|
|
47
47
|
scope: 'booking:read'
|
|
48
48
|
}
|
|
49
|
-
}), /
|
|
49
|
+
}), /booking_copilot_ingress_binding_pair_required/, 'principal without a binding is rejected before startup');
|
|
50
50
|
let standaloneIngressMode = '';
|
|
51
51
|
const standaloneStateRoot = mkdtempSync(join(tmpdir(), 'gotry-booking-startup-standalone-'));
|
|
52
52
|
const standalone = await startBookingCopilotFromEnvironment({
|
|
@@ -71,21 +71,8 @@ const standalone = await startBookingCopilotFromEnvironment({
|
|
|
71
71
|
},
|
|
72
72
|
async close () {}
|
|
73
73
|
}),
|
|
74
|
-
runtimeFactoryV2 () {
|
|
75
|
-
return {};
|
|
76
|
-
},
|
|
77
|
-
createPlannerV2: async ()=>({
|
|
78
|
-
plannerFactory () {
|
|
79
|
-
return {
|
|
80
|
-
async next () {
|
|
81
|
-
return [];
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
async close () {}
|
|
86
|
-
}),
|
|
87
74
|
async startServer (options) {
|
|
88
|
-
standaloneIngressMode = options.
|
|
75
|
+
standaloneIngressMode = options.ingressMode ?? '';
|
|
89
76
|
return {
|
|
90
77
|
server: {},
|
|
91
78
|
port: 43122,
|
|
@@ -102,12 +89,11 @@ rmSync(standaloneStateRoot, {
|
|
|
102
89
|
});
|
|
103
90
|
const closeOrder = [];
|
|
104
91
|
let plannerEnv;
|
|
105
|
-
let plannerV2Env;
|
|
106
92
|
let serverApiKey = '';
|
|
107
93
|
let serverArtifactId = '';
|
|
108
94
|
const trustedEnv = {
|
|
109
95
|
...env,
|
|
110
|
-
|
|
96
|
+
GOTRY_BOOKING_COPILOT_INGRESS_MODE: 'bff-ingress-binding'
|
|
111
97
|
};
|
|
112
98
|
const fakeLedger = {
|
|
113
99
|
close () {
|
|
@@ -121,7 +107,7 @@ const trustedBinding = {
|
|
|
121
107
|
contextRef: 'startup-context',
|
|
122
108
|
surface: 'tenant',
|
|
123
109
|
allowedActions: [
|
|
124
|
-
...
|
|
110
|
+
...BOOKING_READ_ACTION_KINDS
|
|
125
111
|
]
|
|
126
112
|
})
|
|
127
113
|
};
|
|
@@ -147,24 +133,6 @@ const started = await startBookingCopilotFromEnvironment(trustedEnv, {
|
|
|
147
133
|
}
|
|
148
134
|
};
|
|
149
135
|
},
|
|
150
|
-
runtimeFactoryV2 () {
|
|
151
|
-
return {};
|
|
152
|
-
},
|
|
153
|
-
async createPlannerV2 (options) {
|
|
154
|
-
plannerV2Env = options.env;
|
|
155
|
-
return {
|
|
156
|
-
plannerFactory () {
|
|
157
|
-
return {
|
|
158
|
-
async next () {
|
|
159
|
-
return [];
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
},
|
|
163
|
-
async close () {
|
|
164
|
-
closeOrder.push('planner-v2');
|
|
165
|
-
}
|
|
166
|
-
};
|
|
167
|
-
},
|
|
168
136
|
ingressBinding: trustedBinding,
|
|
169
137
|
principal: {
|
|
170
138
|
subject: 'startup-bff',
|
|
@@ -173,7 +141,7 @@ const started = await startBookingCopilotFromEnvironment(trustedEnv, {
|
|
|
173
141
|
async startServer (options) {
|
|
174
142
|
serverApiKey = options.apiKey;
|
|
175
143
|
serverArtifactId = options.artifactId ?? '';
|
|
176
|
-
assert.equal(options.
|
|
144
|
+
assert.equal(options.ingressMode, 'bff-ingress-binding');
|
|
177
145
|
return {
|
|
178
146
|
server: {},
|
|
179
147
|
port: 43123,
|
|
@@ -190,93 +158,16 @@ assert.equal(plannerEnv?.DEEPSEEK_API_KEY, 'model-only-key');
|
|
|
190
158
|
assert.equal(plannerEnv?.GOTRY_BOOKING_COPILOT_API_KEY, undefined);
|
|
191
159
|
assert.equal(plannerEnv?.PORTAL_TOKEN, undefined);
|
|
192
160
|
assert.equal(plannerEnv?.HOTELBYTE_TOKEN, undefined);
|
|
193
|
-
assert.equal(plannerV2Env?.DEEPSEEK_API_KEY, 'model-only-key');
|
|
194
161
|
await started.close();
|
|
195
162
|
assert.deepEqual(closeOrder, [
|
|
196
163
|
'server',
|
|
197
164
|
'planner',
|
|
198
|
-
'planner-v2',
|
|
199
165
|
'ledger'
|
|
200
166
|
]);
|
|
201
167
|
rmSync(stateRoot, {
|
|
202
168
|
recursive: true,
|
|
203
169
|
force: true
|
|
204
170
|
});
|
|
205
|
-
const v2StateRoot = mkdtempSync(join(tmpdir(), 'gotry-booking-startup-v2-'));
|
|
206
|
-
let v2Passed = false;
|
|
207
|
-
let v2PlannerEnv;
|
|
208
|
-
const v2CloseOrder = [];
|
|
209
|
-
const v2Started = await startBookingCopilotFromEnvironment({
|
|
210
|
-
...trustedEnv,
|
|
211
|
-
GOTRY_BOOKING_COPILOT_STATE_ROOT: v2StateRoot
|
|
212
|
-
}, {
|
|
213
|
-
ensureLedger () {
|
|
214
|
-
return {
|
|
215
|
-
close () {
|
|
216
|
-
v2CloseOrder.push('ledger');
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
},
|
|
220
|
-
runtimeFactory () {
|
|
221
|
-
return {};
|
|
222
|
-
},
|
|
223
|
-
createPlanner: async ()=>({
|
|
224
|
-
plannerFactory () {
|
|
225
|
-
return {
|
|
226
|
-
async next () {
|
|
227
|
-
return [];
|
|
228
|
-
}
|
|
229
|
-
};
|
|
230
|
-
},
|
|
231
|
-
async close () {}
|
|
232
|
-
}),
|
|
233
|
-
runtimeFactoryV2 () {
|
|
234
|
-
return {};
|
|
235
|
-
},
|
|
236
|
-
async createPlannerV2 (options) {
|
|
237
|
-
v2PlannerEnv = options.env;
|
|
238
|
-
return {
|
|
239
|
-
plannerFactory () {
|
|
240
|
-
return {
|
|
241
|
-
async next () {
|
|
242
|
-
return [];
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
},
|
|
246
|
-
async close () {
|
|
247
|
-
v2CloseOrder.push('planner-v2');
|
|
248
|
-
}
|
|
249
|
-
};
|
|
250
|
-
},
|
|
251
|
-
ingressBinding: trustedBinding,
|
|
252
|
-
principal: {
|
|
253
|
-
subject: 'startup-bff',
|
|
254
|
-
scope: 'booking:read'
|
|
255
|
-
},
|
|
256
|
-
async startServer (options) {
|
|
257
|
-
v2Passed = Boolean(options.v2 && options.runtime && options.plannerFactory);
|
|
258
|
-
return {
|
|
259
|
-
server: {},
|
|
260
|
-
port: 43124,
|
|
261
|
-
async close () {
|
|
262
|
-
v2CloseOrder.push('server');
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
assert.equal(v2Started.port, 43124);
|
|
268
|
-
assert.equal(v2Passed, true, 'v2 startup constructs and passes the real v2 adapter seam');
|
|
269
|
-
assert.equal(v2PlannerEnv?.DEEPSEEK_API_KEY, 'model-only-key');
|
|
270
|
-
await v2Started.close();
|
|
271
|
-
assert.deepEqual(v2CloseOrder, [
|
|
272
|
-
'server',
|
|
273
|
-
'planner-v2',
|
|
274
|
-
'ledger'
|
|
275
|
-
]);
|
|
276
|
-
rmSync(v2StateRoot, {
|
|
277
|
-
recursive: true,
|
|
278
|
-
force: true
|
|
279
|
-
});
|
|
280
171
|
console.log('BOOKING COPILOT STARTUP PROOF: env split/server+planner+ledger lifecycle OK');
|
|
281
172
|
|
|
282
173
|
|