@danceiny/gotry 0.0.1-rc.16 → 0.0.1-rc.18
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 +161 -116
- package/README.zh-CN.md +173 -144
- package/bin/gotry-booking-copilot.js +53 -0
- package/bin/gotry-bootstrap.js +113 -66
- package/bin/gotry-inner.js +436 -70
- package/bin/gotry-runtime-resolution.d.ts +27 -0
- package/bin/gotry-runtime-resolution.js +50 -0
- package/bin/gotry.js +1 -1
- package/cordis.gotry-patch.yml +5 -1
- package/dist/capabilities/agent-reach-deep.js +1 -1
- package/dist/capabilities/agent-reach.js +1 -1
- package/dist/capabilities/anything.js +1 -1
- package/dist/capabilities/artifacts.js +1 -1
- package/dist/capabilities/effect.js +1 -1
- package/dist/capabilities/fact-log.js +1 -1
- package/dist/capabilities/flyai.js +20 -6
- package/dist/capabilities/hbcli.js +1 -1
- package/dist/capabilities/incident-log.js +1 -1
- package/dist/capabilities/model-override.js +18 -0
- package/dist/capabilities/opensky.js +1 -1
- package/dist/capabilities/resilience.js +1 -1
- package/dist/capabilities/session/action-cache.js +1 -1
- package/dist/capabilities/session/adapters/ctrip-flight.js +1 -1
- package/dist/capabilities/session/adapters/meituan-local.js +1 -1
- package/dist/capabilities/session/benchmark.js +1 -1
- package/dist/capabilities/session/extension-bridge.js +19 -6
- package/dist/capabilities/session/extension-channel.js +3 -3
- package/dist/capabilities/session/extension-distribution.js +234 -0
- package/dist/capabilities/session/extract.js +1 -1
- package/dist/capabilities/session/golden-score.js +92 -0
- package/dist/capabilities/session/health-watch.js +1 -1
- package/dist/capabilities/session/read-guard.js +1 -1
- package/dist/capabilities/session/static-flight-golden.js +137 -0
- package/dist/capabilities/session/transport.js +1 -1
- package/dist/capabilities/session/wizard.js +21 -251
- package/dist/capabilities/session-consent.js +1 -1
- package/dist/capabilities/session-login.js +11 -5
- package/dist/capabilities/session-search.js +46 -4
- package/dist/capabilities/weather.js +168 -46
- package/dist/data/session-golden-20.json +25 -0
- package/dist/data/sf-golden-manifest.json +102 -0
- package/dist/data/sf-static-routes.json +91 -0
- package/dist/scripts/action-cache-tests.js +1 -1
- package/dist/scripts/agent-planning-budget-e2e.js +227 -0
- package/dist/scripts/agent-planning-budget-tests.js +173 -0
- package/dist/scripts/agent-reach-deep-tests.js +1 -1
- package/dist/scripts/agent-reach-tests.js +1 -1
- package/dist/scripts/agent-reach-wrapper-tests.js +1 -1
- package/dist/scripts/anything-tests.js +1 -1
- package/dist/scripts/async-collect.js +1 -1
- package/dist/scripts/benchmark-environment-bridge-e2e.js +981 -0
- package/dist/scripts/benchmark-environment-bridge-tests.js +2544 -0
- package/dist/scripts/booking-copilot-availability-ledger-binding-tests.js +335 -0
- package/dist/scripts/booking-copilot-availability-policy-v2-tests.js +1355 -0
- package/dist/scripts/booking-copilot-bin-proof-tests.js +89 -0
- package/dist/scripts/booking-copilot-crossrepo-fixture-server.js +113 -0
- package/dist/scripts/booking-copilot-dsh-core-proof-tests.js +356 -0
- package/dist/scripts/booking-copilot-dsh-planner-proof-tests.js +557 -0
- package/dist/scripts/booking-copilot-dsh-plugin-proof-tests.js +140 -0
- package/dist/scripts/booking-copilot-event-sequence-concurrency-proof-tests.js +202 -0
- package/dist/scripts/booking-copilot-gap-code-contract-proof-tests.js +102 -0
- package/dist/scripts/booking-copilot-operation-ledger-concurrency-proof-tests.js +374 -0
- package/dist/scripts/booking-copilot-receipt-ledger-concurrency-proof-tests.js +447 -0
- package/dist/scripts/booking-copilot-runtime-proof-tests.js +205 -0
- package/dist/scripts/booking-copilot-server-proof-tests.js +317 -0
- package/dist/scripts/booking-copilot-startup-proof-tests.js +283 -0
- package/dist/scripts/booking-copilot-v2-runtime-proof-tests.js +3935 -0
- package/dist/scripts/booking-saga-tests.js +1 -1
- package/dist/scripts/booking-surface-contract-proof-tests.js +393 -0
- package/dist/scripts/booking-surface-v2-contract-proof-tests.js +1174 -0
- package/dist/scripts/bootstrap-tests.js +45 -39
- package/dist/scripts/build-changelog.js +1 -1
- package/dist/scripts/changelog-tests.js +1 -1
- package/dist/scripts/companion-tests.js +1 -1
- package/dist/scripts/diff-test.js +1 -1
- package/dist/scripts/dsh-runtime-closure-tests.js +225 -0
- package/dist/scripts/dsh-runtime-closure.js +150 -0
- package/dist/scripts/effect-tests.js +1 -1
- package/dist/scripts/engine-run.js +1 -1
- package/dist/scripts/engine-tests.js +1 -1
- package/dist/scripts/evaluation-cadence-tests.js +347 -0
- package/dist/scripts/evaluation-contract-tests.js +574 -0
- package/dist/scripts/extension-distribution-cli.js +35 -0
- package/dist/scripts/extension-distribution-tests.js +341 -0
- package/dist/scripts/extension-tests.js +128 -23
- package/dist/scripts/fact-gate-tests.js +1 -1
- package/dist/scripts/flyai-tests.js +1 -1
- package/dist/scripts/hbcli-e2e-tests.js +1 -1
- package/dist/scripts/hbcli-tests.js +1 -1
- package/dist/scripts/health-watch-cli.js +1 -1
- package/dist/scripts/i18n-tests.js +1 -1
- package/dist/scripts/incident-tests.js +1 -1
- package/dist/scripts/journey-tests.js +1 -1
- package/dist/scripts/ledger-tests.js +1 -1
- package/dist/scripts/ledger-workflow-crash.js +1 -1
- package/dist/scripts/memory-capture-tests.js +1 -1
- package/dist/scripts/memory-decay-tests.js +1 -1
- package/dist/scripts/memory-metrics.js +1 -1
- package/dist/scripts/memory-value-report.js +1 -1
- package/dist/scripts/model-override-e2e.js +176 -0
- package/dist/scripts/nightly-evidence-tests.js +1 -1
- package/dist/scripts/nightly-evidence.js +1 -1
- package/dist/scripts/nudge-digest.js +1 -1
- package/dist/scripts/onboarding-tests.js +21 -53
- package/dist/scripts/opensky-check.js +1 -1
- package/dist/scripts/opensky-tests.js +1 -1
- package/dist/scripts/pnpm-dsh-closure-proof.js +20 -0
- package/dist/scripts/price-drift-tests.js +1 -1
- package/dist/scripts/price-drift-watch.js +1 -1
- package/dist/scripts/probe-poi-tests.js +1 -1
- package/dist/scripts/product-metrics.js +1 -1
- package/dist/scripts/publish-preverify.js +40 -4
- package/dist/scripts/realtime-pricing-tests.js +1 -1
- package/dist/scripts/replay-async.js +1 -1
- package/dist/scripts/replay-real.js +1 -1
- package/dist/scripts/replay.js +1 -1
- package/dist/scripts/session-attach-diagnose.js +1 -1
- package/dist/scripts/session-attach-poc.js +1 -1
- package/dist/scripts/session-benchmark.js +1 -1
- package/dist/scripts/session-extract-tests.js +1 -1
- package/dist/scripts/session-login.js +1 -1
- package/dist/scripts/session-tests.js +70 -20
- package/dist/scripts/sf-live-benchmark.js +338 -0
- package/dist/scripts/sf-live-cli-tests.js +21 -0
- package/dist/scripts/sf-soft-score-tests.js +108 -0
- package/dist/scripts/sf-summary.js +93 -0
- package/dist/scripts/skeleton-check.js +1 -1
- package/dist/scripts/skeleton-integration-test.js +1 -1
- package/dist/scripts/skills-contract-tests.js +1 -1
- package/dist/scripts/smoke-session-gate-tests.js +29 -0
- package/dist/scripts/smoke.js +79 -33
- package/dist/scripts/state-cli-tests.js +1 -1
- package/dist/scripts/state-cli.js +1 -1
- package/dist/scripts/static-golden-tests.js +299 -0
- package/dist/scripts/time-eval-tests.js +1 -1
- package/dist/scripts/travel-timeline-tests.js +1 -1
- package/dist/scripts/unified-tests.js +1 -1
- package/dist/scripts/weather-tests.js +694 -44
- package/dist/scripts/z3-race-tests.js +1 -1
- package/dist/src/artifact-gate.js +1 -1
- package/dist/src/benchmark-agent-conformance.js +370 -0
- package/dist/src/benchmark-environment-bridge.js +384 -0
- package/dist/src/benchmark-headless-child-diagnostics.js +173 -0
- package/dist/src/benchmark-tool-isolation.js +124 -0
- package/dist/src/bookable-facts.js +1 -1
- package/dist/src/booking-saga.js +1 -1
- package/dist/src/booking-surface/availability-policy-v2.js +830 -0
- package/dist/src/booking-surface/canonical-schema.js +113 -0
- package/dist/src/booking-surface/contracts-v2.js +89 -0
- package/dist/src/booking-surface/contracts.js +46 -0
- package/dist/src/booking-surface/dsh-planner.js +453 -0
- package/dist/src/booking-surface/dsh-plugin.js +93 -0
- package/dist/src/booking-surface/error-codes.js +94 -0
- package/dist/src/booking-surface/index.js +15 -0
- package/dist/src/booking-surface/profile.js +68 -0
- package/dist/src/booking-surface/runtime-v2.js +1771 -0
- package/dist/src/booking-surface/runtime.js +351 -0
- package/dist/src/booking-surface/server-v2.js +334 -0
- package/dist/src/booking-surface/server.js +302 -0
- package/dist/src/booking-surface/startup.js +159 -0
- package/dist/src/booking-surface/validation-v2.js +319 -0
- package/dist/src/booking-surface/validation.js +809 -0
- package/dist/src/bridge.js +1 -1
- package/dist/src/companions.js +1 -1
- package/dist/src/contracts.js +1 -1
- package/dist/src/dsh-llm.js +1 -1
- package/dist/src/engine.js +1 -1
- package/dist/src/evaluation-cadence.js +234 -0
- package/dist/src/evaluation-contracts.js +906 -0
- package/dist/src/i18n.js +1 -1
- package/dist/src/index.js +50 -19
- package/dist/src/journey.js +1 -1
- package/dist/src/loop.js +1 -1
- package/dist/src/memory-capture.js +1 -1
- package/dist/src/memory-decay.js +1 -1
- package/dist/src/memory-utility.js +1 -1
- package/dist/src/mock-llm.js +1 -1
- package/dist/src/model.js +1 -1
- package/dist/src/realtime-pricing.js +1 -1
- package/dist/src/slot-spec.js +1 -1
- package/dist/src/state-ledger.js +2 -1
- package/dist/src/time-anchor.js +1 -1
- package/dist/src/tool-budget.js +136 -0
- package/dist/src/tool-packet.js +1 -1
- package/dist/src/travel-slots.js +1 -1
- package/dist/src/travel-timeline.js +1 -1
- package/dist/src/unified.js +1 -1
- package/dist/src/wish-pool.js +1 -1
- package/dist/src/z3-shared.js +1 -1
- package/extension/README.md +31 -7
- package/package.json +286 -11
- package/schemas/booking.surface.v1.schema.json +927 -0
- package/schemas/booking.surface.v2.schema.json +61 -0
- package/ts/capabilities/flyai.ts +16 -3
- package/ts/capabilities/session/extension-bridge.ts +37 -14
- package/ts/capabilities/session/extension-channel.ts +6 -3
- package/ts/capabilities/session/extension-distribution.ts +264 -0
- package/ts/capabilities/session/golden-score.ts +139 -0
- package/ts/capabilities/session/health-watch.ts +1 -1
- package/ts/capabilities/session/static-flight-golden.ts +209 -0
- package/ts/capabilities/session/wizard.ts +34 -176
- package/ts/capabilities/session-login.ts +15 -5
- package/ts/capabilities/session-search.ts +40 -3
- package/ts/capabilities/weather.ts +141 -52
- package/ts/package.json +3 -3
- package/ts/src/benchmark-agent-conformance.ts +448 -0
- package/ts/src/benchmark-environment-bridge.ts +348 -0
- package/ts/src/benchmark-headless-child-diagnostics.ts +184 -0
- package/ts/src/benchmark-tool-isolation.ts +166 -0
- package/ts/src/booking-surface/availability-policy-v2.ts +523 -0
- package/ts/src/booking-surface/canonical-schema.js +113 -0
- package/ts/src/booking-surface/contracts-v2.ts +118 -0
- package/ts/src/booking-surface/contracts.ts +380 -0
- package/ts/src/booking-surface/dsh-planner.ts +452 -0
- package/ts/src/booking-surface/dsh-plugin.js +93 -0
- package/ts/src/booking-surface/error-codes.ts +101 -0
- package/ts/src/booking-surface/index.ts +12 -0
- package/ts/src/booking-surface/profile.ts +42 -0
- package/ts/src/booking-surface/runtime-v2.ts +1466 -0
- package/ts/src/booking-surface/runtime.ts +483 -0
- package/ts/src/booking-surface/server-v2.ts +247 -0
- package/ts/src/booking-surface/server.ts +324 -0
- package/ts/src/booking-surface/startup.ts +196 -0
- package/ts/src/booking-surface/validation-v2.ts +205 -0
- package/ts/src/booking-surface/validation.ts +453 -0
- package/ts/src/index.ts +64 -11
- package/ts/src/state-ledger.ts +1 -0
- package/ts/src/tool-budget.ts +165 -0
- package/dist/scripts/wizard-bootstrap.js +0 -32
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime projection of the canonical booking.surface.v1 JSON Schema.
|
|
3
|
+
*
|
|
4
|
+
* dsh tools need self-contained JSON Schemas, while the canonical document is
|
|
5
|
+
* organized with local $refs. This helper derives each action branch directly
|
|
6
|
+
* from those canonical bytes and recursively inlines local references. No
|
|
7
|
+
* model-facing action schema is maintained by hand.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { readFileSync } from 'node:fs'
|
|
11
|
+
|
|
12
|
+
const schemaUrl = new URL('../../../schemas/booking.surface.v1.schema.json', import.meta.url)
|
|
13
|
+
export const canonicalBookingSurfaceSchemaV1 = JSON.parse(readFileSync(schemaUrl, 'utf8'))
|
|
14
|
+
const schemaV2Url = new URL('../../../schemas/booking.surface.v2.schema.json', import.meta.url)
|
|
15
|
+
export const canonicalBookingSurfaceSchemaV2 = JSON.parse(readFileSync(schemaV2Url, 'utf8'))
|
|
16
|
+
|
|
17
|
+
function clone(value) {
|
|
18
|
+
return JSON.parse(JSON.stringify(value))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function definitionFromRef(ref, schema) {
|
|
22
|
+
const prefix = '#/$defs/'
|
|
23
|
+
if (typeof ref !== 'string') {
|
|
24
|
+
throw new Error(`booking_schema_external_ref_forbidden:${String(ref)}`)
|
|
25
|
+
}
|
|
26
|
+
const externalV1 = 'https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/'
|
|
27
|
+
const definitionSchema = ref.startsWith(prefix) ? schema : ref.startsWith(externalV1) ? canonicalBookingSurfaceSchemaV1 : undefined
|
|
28
|
+
if (!definitionSchema) throw new Error(`booking_schema_external_ref_forbidden:${String(ref)}`)
|
|
29
|
+
const name = ref.startsWith(prefix) ? ref.slice(prefix.length) : ref.slice(externalV1.length)
|
|
30
|
+
const definition = definitionSchema.$defs?.[name]
|
|
31
|
+
if (!definition) throw new Error(`booking_schema_missing_definition:${name}`)
|
|
32
|
+
return definition
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function inlineLocalRefs(value, schema, stack = []) {
|
|
36
|
+
if (Array.isArray(value)) return value.map((item) => inlineLocalRefs(item, schema, stack))
|
|
37
|
+
if (typeof value !== 'object' || value === null) return value
|
|
38
|
+
if (typeof value.$ref === 'string') {
|
|
39
|
+
if (stack.includes(value.$ref)) throw new Error(`booking_schema_recursive_ref:${value.$ref}`)
|
|
40
|
+
const { $ref, ...siblings } = value
|
|
41
|
+
const definitionSchema = typeof $ref === 'string' && $ref.startsWith('https://gotry.dev/schemas/booking.surface.v1.schema.json#/$defs/') ? canonicalBookingSurfaceSchemaV1 : schema
|
|
42
|
+
return {
|
|
43
|
+
...inlineLocalRefs(definitionFromRef($ref, schema), definitionSchema, [...stack, $ref]),
|
|
44
|
+
...inlineLocalRefs(siblings, schema, stack),
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, inlineLocalRefs(item, schema, stack)]))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function canonicalActionSchemaForKind(kind, schema, definitionName) {
|
|
51
|
+
const action = schema.$defs?.[definitionName]
|
|
52
|
+
if (!action) throw new Error('booking_schema_action_union_missing')
|
|
53
|
+
if (Array.isArray(action.allOf)) {
|
|
54
|
+
const branch = action.allOf.find((candidate) => candidate?.if?.properties?.kind?.const === kind)
|
|
55
|
+
const input = branch?.then?.properties?.input
|
|
56
|
+
if (!input) throw new Error(`booking_schema_action_kind_missing:${kind}`)
|
|
57
|
+
return clone(inlineLocalRefs({
|
|
58
|
+
type: action.type,
|
|
59
|
+
required: action.required,
|
|
60
|
+
properties: { ...action.properties, kind: { type: 'string', const: kind }, input },
|
|
61
|
+
additionalProperties: action.additionalProperties,
|
|
62
|
+
}, schema))
|
|
63
|
+
}
|
|
64
|
+
if (!Array.isArray(action.oneOf)) throw new Error('booking_schema_action_union_missing')
|
|
65
|
+
const branch = action.oneOf.find((candidate) => candidate?.allOf?.some((part) => part?.properties?.kind?.const === kind))
|
|
66
|
+
const base = schema.$defs?.ActionBase
|
|
67
|
+
const input = branch?.allOf?.find((part) => part?.properties?.input)?.properties?.input
|
|
68
|
+
if (!base || !input) throw new Error(`booking_schema_action_kind_missing:${kind}`)
|
|
69
|
+
return clone(inlineLocalRefs({
|
|
70
|
+
...base,
|
|
71
|
+
properties: { ...base.properties, kind: { type: 'string', const: kind }, input },
|
|
72
|
+
}, schema))
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function canonicalBookingActionSchemaForKind(kind) {
|
|
76
|
+
return canonicalActionSchemaForKind(kind, canonicalBookingSurfaceSchemaV1, 'BookingReadActionV1')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function canonicalBookingActionSchemaForKindV2(kind) {
|
|
80
|
+
return canonicalActionSchemaForKind(kind, canonicalBookingSurfaceSchemaV2, 'Action')
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const DSH_JSON_SCHEMA_KEYS = new Set([
|
|
84
|
+
'type', 'oneOf', 'properties', 'required', 'additionalProperties', 'items',
|
|
85
|
+
'enum', 'const', 'description', 'title', 'default', 'examples',
|
|
86
|
+
])
|
|
87
|
+
|
|
88
|
+
function projectDshSchema(value) {
|
|
89
|
+
if (Array.isArray(value)) return value.map(projectDshSchema)
|
|
90
|
+
if (typeof value !== 'object' || value === null) return value
|
|
91
|
+
return Object.fromEntries(Object.entries(value)
|
|
92
|
+
.filter(([key]) => DSH_JSON_SCHEMA_KEYS.has(key))
|
|
93
|
+
.map(([key, item]) => {
|
|
94
|
+
if (key === 'properties') {
|
|
95
|
+
return [key, Object.fromEntries(Object.entries(item).map(([name, property]) => [name, projectDshSchema(property)]))]
|
|
96
|
+
}
|
|
97
|
+
return [key, projectDshSchema(item)]
|
|
98
|
+
}))
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* dsh-tools intentionally supports a smaller enforced JSON-Schema vocabulary.
|
|
103
|
+
* Keep the canonical shape/type/enum/closure guarantees at the model seam;
|
|
104
|
+
* the full canonical AJV validator remains the runtime authority for numeric,
|
|
105
|
+
* pattern, size and uniqueness constraints before an operation can be issued.
|
|
106
|
+
*/
|
|
107
|
+
export function dshBookingActionSchemaForKind(kind) {
|
|
108
|
+
return projectDshSchema(canonicalBookingActionSchemaForKind(kind))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function dshBookingActionSchemaForKindV2(kind) {
|
|
112
|
+
return projectDshSchema(canonicalBookingActionSchemaForKindV2(kind))
|
|
113
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import type { BookingReadActionKindV1, BookingWorkspaceSnapshotV1, SearchCriteriaPatchV1, ResultsViewPatchV1, OfferCriteriaV1, EvidenceLevelV1 } from './contracts.ts'
|
|
2
|
+
|
|
3
|
+
export const BOOKING_SURFACE_SCHEMA_VERSION_V2 = 'booking.surface.v2' as const
|
|
4
|
+
/**
|
|
5
|
+
* Process composition modes are deliberately separate from the payload
|
|
6
|
+
* schema. The default accepts turns already bound by HotelByte's BFF; the
|
|
7
|
+
* second mode is reserved for an in-process BFF binding seam.
|
|
8
|
+
*/
|
|
9
|
+
export const BOOKING_COPILOT_V2_INGRESS_MODES = ['bff-bound-turn-only', 'bff-ingress-binding'] as const
|
|
10
|
+
export type BookingCopilotV2IngressMode = typeof BOOKING_COPILOT_V2_INGRESS_MODES[number]
|
|
11
|
+
export const BOOKING_COPILOT_V2_ACCEPTED_TURN_KINDS = ['user.turn', 'action.receipt.continuation'] as const
|
|
12
|
+
export const BOOKING_COPILOT_V2_INGRESS_TURN_KIND = 'user.turn.ingress' as const
|
|
13
|
+
/** Hard task-level operation budget. The counter is persisted in the v2 ledger. */
|
|
14
|
+
export const BOOKING_COPILOT_MAX_OPERATIONS_V2 = 20 as const
|
|
15
|
+
export const BOOKING_SURFACE_SCHEMA_V2_SHA256 = '45df62db1b19d30a4fd22ddc94eb550e8ff32d8a225558b5ff13ba303588fc03' as const
|
|
16
|
+
export const BOOKING_READ_ACTION_KINDS_V2 = ['search.patch','search.run','results.view.patch','hotel.focus','hotel.select','offers.query','offers.view.patch','offers.compare','offer.select','offer.check','checkout.prepare','order.observe'] as const satisfies readonly BookingReadActionKindV1[]
|
|
17
|
+
export type BookingReadActionKindV2 = typeof BOOKING_READ_ACTION_KINDS_V2[number]
|
|
18
|
+
export type BookingSurfaceV2 = 'tenant' | 'customer_portal' | 'storefront' | 'payment_link'
|
|
19
|
+
/** Product-owned least-privilege action matrix. BFF bindings may narrow these lists, never expand them. */
|
|
20
|
+
export const BOOKING_SURFACE_ALLOWED_ACTIONS_V2: Record<BookingSurfaceV2, readonly BookingReadActionKindV2[]> = {
|
|
21
|
+
tenant: BOOKING_READ_ACTION_KINDS_V2,
|
|
22
|
+
customer_portal: BOOKING_READ_ACTION_KINDS_V2,
|
|
23
|
+
storefront: ['search.patch', 'search.run', 'results.view.patch', 'hotel.focus'],
|
|
24
|
+
payment_link: ['search.patch', 'search.run', 'results.view.patch', 'hotel.focus', 'hotel.select'],
|
|
25
|
+
}
|
|
26
|
+
/** Stable product-matrix observation for UAT and server readiness proofs. */
|
|
27
|
+
export function bookingSurfaceAllowedActionsV2(surface: BookingSurfaceV2): BookingReadActionKindV2[] {
|
|
28
|
+
return [...BOOKING_SURFACE_ALLOWED_ACTIONS_V2[surface]]
|
|
29
|
+
}
|
|
30
|
+
export type BookingRequestKeyV2 = string
|
|
31
|
+
/** Runtime-owned idempotency key; this is not a browser request key. */
|
|
32
|
+
export type BookingInternalDecisionKeyV2 = string
|
|
33
|
+
export const BOOKING_V2_BLOCKER_CODES = ['no_hotels_matched','hotel_not_visible','hotel_rates_failed','criterion_must_not_met','offer_target_not_reached','offer_unavailable'] as const
|
|
34
|
+
export type BookingV2BlockerCode = typeof BOOKING_V2_BLOCKER_CODES[number]
|
|
35
|
+
export const BOOKING_V2_GAP_CODES = ['byos_mapped_risk','check_avail_failed','check_avail_unverified','component_executor_unavailable','hotel_not_visible','hotel_rates_failed','offer_facts_changed','offer_not_loaded','offer_unavailable','order_not_found','order_outcome_not_observed','order_state_unknown','order_status_unavailable','requested_offers_not_loaded','search_failed','search_form_invalid','search_session_expired','search_terminal_timeout','stale_revision','surface_adapter_failed','undo_token_not_found','unhandled','unsupported','verified_offer_required','workspace_changed_during_action','criterion_must_not_met','no_hotels_matched','offer_target_not_reached'] as const
|
|
36
|
+
export type BookingV2GapCode = typeof BOOKING_V2_GAP_CODES[number]
|
|
37
|
+
export type BookingV2BlockerScope = 'search' | 'offer' | 'availability' | 'checkout'
|
|
38
|
+
export interface CriterionBlockerV2 { blockerId: string; sourceActionId: string; sourceReceiptDigest: string; scope: BookingV2BlockerScope; code: BookingV2BlockerCode; criterionPath: string; strength: 'must'; valueDigest: string; valueLabel?: string; evidence: { factRefs: string[]; gapCodes: BookingV2GapCode[]; requested?: number; actual?: number } }
|
|
39
|
+
export interface RelaxationApprovalV2 {
|
|
40
|
+
taskId: string
|
|
41
|
+
contextRef: string
|
|
42
|
+
sourceTurnId: string
|
|
43
|
+
presentationRequestKey: string
|
|
44
|
+
optionDigest: string
|
|
45
|
+
approvalId: string
|
|
46
|
+
deliveryNonce: string
|
|
47
|
+
blockerId: string
|
|
48
|
+
sourceActionId: string
|
|
49
|
+
sourceReceiptDigest: string
|
|
50
|
+
scope: BookingV2BlockerScope
|
|
51
|
+
code: BookingV2BlockerCode
|
|
52
|
+
criterionPath: string
|
|
53
|
+
valueDigest: string
|
|
54
|
+
from: 'must'
|
|
55
|
+
to: 'prefer' | 'drop'
|
|
56
|
+
approved: true
|
|
57
|
+
}
|
|
58
|
+
export interface RelaxationApprovalRefV2 { approvalId: string; blockerId: string; contextRef: string; sourceTurnId: string; presentationRequestKey: string; sourceActionId: string; targetActionId: string; sourceRevision: number; targetActionKind: BookingReadActionKindV2; to: 'prefer'|'drop'; expiresAt: string; nonce: string; sourceReceiptDigest: string; scope: BookingV2BlockerScope; code: BookingV2BlockerCode; criterionPath: string; valueDigest: string }
|
|
59
|
+
interface Base<K extends BookingReadActionKindV2, I> { schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION_V2; kind: K; actionId: string; contextRef: string; expectedRevision: number; reason: string; factRefs: string[]; input: I; relaxationApprovalRef?: RelaxationApprovalRefV2 }
|
|
60
|
+
export type SearchPatchActionV2 = Base<'search.patch', { patch: SearchCriteriaPatchV1 }>
|
|
61
|
+
export type SearchRunActionV2 = Base<'search.run', Record<string, never>>
|
|
62
|
+
export type ResultsViewPatchActionV2 = Base<'results.view.patch', { patch: ResultsViewPatchV1 }>
|
|
63
|
+
export type HotelFocusActionV2 = Base<'hotel.focus', { hotelRef: string }>
|
|
64
|
+
export type HotelSelectActionV2 = Base<'hotel.select', { hotelRef: string }>
|
|
65
|
+
export type OffersQueryActionV2 = Base<'offers.query', { hotelRefs: string[]; criteria: OfferCriteriaV1 }>
|
|
66
|
+
export type OffersViewPatchActionV2 = Base<'offers.view.patch', { hotelRef: string; criteria: OfferCriteriaV1 }>
|
|
67
|
+
export type OffersCompareActionV2 = Base<'offers.compare', { offerRefs: string[]; requestedCount: number }>
|
|
68
|
+
export interface LoadedOfferFactV2 { offerRef: string; offerVersionRef: string; hotelRef: string; evidenceLevel: EvidenceLevelV1; factRefs: string[] }
|
|
69
|
+
export interface VerifiedOfferCapabilityV2 { offerRef: string; offerVersionRef: string; verifiedOfferRef: string; expiresAt: string }
|
|
70
|
+
export type OfferSelectActionV2 = Base<'offer.select', { offerRef: string; offerVersionRef: string }>
|
|
71
|
+
export type OfferCheckActionV2 = Base<'offer.check', { offerRef: string; offerVersionRef: string }>
|
|
72
|
+
export type CheckoutPrepareActionV2 = Base<'checkout.prepare', { offerRef: string; offerVersionRef: string; verifiedOfferRef: string }>
|
|
73
|
+
export type OrderObserveActionV2 = Base<'order.observe', { orderRef: string }>
|
|
74
|
+
export type BookingReadActionV2=SearchPatchActionV2|SearchRunActionV2|ResultsViewPatchActionV2|HotelFocusActionV2|HotelSelectActionV2|OffersQueryActionV2|OffersViewPatchActionV2|OffersCompareActionV2|OfferSelectActionV2|OfferCheckActionV2|CheckoutPrepareActionV2|OrderObserveActionV2
|
|
75
|
+
export interface BookingWorkspaceSnapshotV2 extends Omit<BookingWorkspaceSnapshotV1,'schemaVersion'|'surface'|'capabilities'|'loadedOffers'|'verifiedOfferRef'>{schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;surface:BookingSurfaceV2;loadedOffers:LoadedOfferFactV2[];verifiedOffer?:VerifiedOfferCapabilityV2;capabilities:{surface:BookingSurfaceV2;allowedActions:BookingReadActionKindV2[]}}
|
|
76
|
+
export type BookingWorkspaceIngressSnapshotV2 = Pick<BookingWorkspaceSnapshotV2, 'schemaVersion'|'revision'|'locale'|'currency'|'searchDraft'|'results'|'visibleHotels'|'loadedOffers'|'focusedHotelRef'|'shortlistedOfferRefs'|'selectedOfferRef'>
|
|
77
|
+
export type ActionObservationV2 =
|
|
78
|
+
| { kind: 'search.state'; searchSessionRef?: string; resultCount?: number; gapCodes?: BookingV2GapCode[] }
|
|
79
|
+
| { kind: 'results.state'; matchedHotelRefs: string[]; visibleCount: number; gapCodes?: BookingV2GapCode[] }
|
|
80
|
+
| { kind: 'hotel.focus'; hotelRef: string }
|
|
81
|
+
| { kind: 'hotel.selection'; hotelRef: string }
|
|
82
|
+
| { kind: 'offers.state'; hotelRefs: string[]; offerRefs: string[]; loadedHotelCount: number; gapCodes?: BookingV2GapCode[] }
|
|
83
|
+
| { kind: 'offer.selection'; offerRef: string; offerVersionRef: string }
|
|
84
|
+
| { kind: 'offer.availability'; offerRef: string; checkedOfferVersionRef: string; currentOfferVersionRef?: string; verifiedOfferRef?: string; available: boolean; changedFactRefs: string[]; gapCodes?: BookingV2GapCode[] }
|
|
85
|
+
| { kind: 'checkout.handoff'; offerRef: string; offerVersionRef: string; verifiedOfferRef: string; handoffRef: string }
|
|
86
|
+
| { kind: 'order.state'; orderRef: string; state: 'pending'|'verified'|'failed'|'unknown'; gapCodes?: BookingV2GapCode[] }
|
|
87
|
+
| { kind: 'gap'; code: BookingV2GapCode; factRefs: string[] }
|
|
88
|
+
export interface ResultContractV2 {outcome:'complete'|'partial'|'empty';requestedCount?:number;actualCount?:number;hardCriteriaMet:boolean;factRefs:string[];gapCodes:BookingV2GapCode[];blockers:CriterionBlockerV2[];relaxationsApplied:RelaxationApprovalV2[]}
|
|
89
|
+
export interface ActionReceiptV2 {schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;kind:'action.receipt';actionId:string;contextRef:string;status:'applied'|'needs_input'|'partial'|'no_match'|'unavailable'|'changed'|'stale'|'unsupported'|'failed';revision:number;observation:ActionObservationV2;resultContract:ResultContractV2;undoToken?:string}
|
|
90
|
+
export interface UserTurnV2 {schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;kind:'user.turn';taskId:string;turnId:string;workspace:BookingWorkspaceSnapshotV2;request:{text:string;approval?:RelaxationApprovalV2}}
|
|
91
|
+
/** Browser-to-BFF ingress. Identity is deliberately absent from this shape. */
|
|
92
|
+
export interface IngressTurnV2 {schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;kind:'user.turn.ingress';requestKey:BookingRequestKeyV2;taskHandle?:string;surfaceHint:BookingSurfaceV2;workspace:BookingWorkspaceIngressSnapshotV2;request:{text:string}}
|
|
93
|
+
export interface ReceiptContinuationV2 {schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;kind:'action.receipt.continuation';taskId:string;workspace:BookingWorkspaceSnapshotV2;receipt:ActionReceiptV2}
|
|
94
|
+
export type BookingCopilotTurnV2=UserTurnV2|IngressTurnV2|ReceiptContinuationV2
|
|
95
|
+
/** Typed BFF seam: implementations authenticate ingress and return only
|
|
96
|
+
* server-issued identity. The HTTP adapter constructs the internal UserTurn. */
|
|
97
|
+
export interface BookingIngressIdentityBindingV2 {
|
|
98
|
+
taskId: string
|
|
99
|
+
turnId: string
|
|
100
|
+
contextRef: string
|
|
101
|
+
/** Authoritative BFF surface; never copied from the browser hint. */
|
|
102
|
+
surface: BookingSurfaceV2
|
|
103
|
+
/** BFF-authorized closed action subset for this surface. */
|
|
104
|
+
allowedActions: BookingReadActionKindV2[]
|
|
105
|
+
}
|
|
106
|
+
export interface BookingIngressPrincipalV2 { subject: string; scope: string }
|
|
107
|
+
export interface BookingIngressBindingV2 {
|
|
108
|
+
bind(input: IngressTurnV2, principal: BookingIngressPrincipalV2): BookingIngressIdentityBindingV2 | Promise<BookingIngressIdentityBindingV2>
|
|
109
|
+
}
|
|
110
|
+
export interface BookingQuestionEventV2 {schemaVersion:typeof BOOKING_SURFACE_SCHEMA_VERSION_V2;eventId:string;taskId:string;contextRef:string;sequence:number;emittedAt:string;kind:'question';question:{questionId:string;prompt:string;missingFields:string[];type:'relaxation_approval_required';blocker:CriterionBlockerV2;approvalOptions:Array<{approval:RelaxationApprovalV2}>}}
|
|
111
|
+
export interface BookingEventBaseV2 { schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION_V2; eventId: string; taskId: string; contextRef: string; sequence: number; emittedAt: string }
|
|
112
|
+
export type BookingSurfaceEventV2 =
|
|
113
|
+
| (BookingEventBaseV2 & { kind: 'status'; status: 'submitted'|'working'|'waiting_receipt'|'input_required' })
|
|
114
|
+
| BookingQuestionEventV2
|
|
115
|
+
| (BookingEventBaseV2 & { kind: 'operation'; action: BookingReadActionV2 })
|
|
116
|
+
| (BookingEventBaseV2 & { kind: 'explanation'; explanation: { text: string; factRefs: string[] } })
|
|
117
|
+
| (BookingEventBaseV2 & { kind: 'terminal'; terminal: { status: 'completed'|'stopped'; summary: string; factRefs: string[] } })
|
|
118
|
+
| (BookingEventBaseV2 & { kind: 'error'; error: { code: string; message: string; retryable: boolean } })
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical TypeScript contract for HotelByte's embedded Booking Copilot.
|
|
3
|
+
*
|
|
4
|
+
* Executable facts cross this boundary only as discriminated data. Human text
|
|
5
|
+
* is limited to a user turn or an explanation and is never parsed as an action.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export const BOOKING_SURFACE_SCHEMA_VERSION = 'booking.surface.v1' as const
|
|
9
|
+
/** SHA-256 of schemas/booking.surface.v1.schema.json; package proof pins drift. */
|
|
10
|
+
export const BOOKING_SURFACE_SCHEMA_SHA256 = 'd9c2194ec839bd1168e70e8a201581addc005039d9b299660e20650bbb65df81' as const
|
|
11
|
+
export const BOOKING_SURFACE_VERSION_HEADER = 'x-booking-surface-version' as const
|
|
12
|
+
export const BOOKING_SURFACE_SCHEMA_SHA256_HEADER = 'x-booking-surface-schema-sha256' as const
|
|
13
|
+
|
|
14
|
+
export const BOOKING_SURFACES = [
|
|
15
|
+
'tenant',
|
|
16
|
+
'customer_portal',
|
|
17
|
+
'storefront',
|
|
18
|
+
'payment_link',
|
|
19
|
+
] as const
|
|
20
|
+
export type BookingSurfaceV1 = (typeof BOOKING_SURFACES)[number]
|
|
21
|
+
|
|
22
|
+
export const BOOKING_READ_ACTION_KINDS = [
|
|
23
|
+
'search.patch',
|
|
24
|
+
'search.run',
|
|
25
|
+
'results.view.patch',
|
|
26
|
+
'hotel.focus',
|
|
27
|
+
'hotel.select',
|
|
28
|
+
'offers.query',
|
|
29
|
+
'offers.view.patch',
|
|
30
|
+
'offers.compare',
|
|
31
|
+
'offer.select',
|
|
32
|
+
'offer.check',
|
|
33
|
+
'checkout.prepare',
|
|
34
|
+
'order.observe',
|
|
35
|
+
] as const
|
|
36
|
+
export type BookingReadActionKindV1 = (typeof BOOKING_READ_ACTION_KINDS)[number]
|
|
37
|
+
|
|
38
|
+
export const BOOKING_RECEIPT_STATUSES = [
|
|
39
|
+
'applied',
|
|
40
|
+
'needs_input',
|
|
41
|
+
'partial',
|
|
42
|
+
'no_match',
|
|
43
|
+
'unavailable',
|
|
44
|
+
'changed',
|
|
45
|
+
'stale',
|
|
46
|
+
'unsupported',
|
|
47
|
+
'failed',
|
|
48
|
+
] as const
|
|
49
|
+
export type ActionReceiptStatusV1 = (typeof BOOKING_RECEIPT_STATUSES)[number]
|
|
50
|
+
|
|
51
|
+
export const BOOKING_SURFACE_EVENT_KINDS = [
|
|
52
|
+
'status',
|
|
53
|
+
'question',
|
|
54
|
+
'operation',
|
|
55
|
+
'explanation',
|
|
56
|
+
'terminal',
|
|
57
|
+
'error',
|
|
58
|
+
] as const
|
|
59
|
+
export type BookingSurfaceEventKindV1 = (typeof BOOKING_SURFACE_EVENT_KINDS)[number]
|
|
60
|
+
|
|
61
|
+
export type ContextRefV1 = string
|
|
62
|
+
export type FactRefV1 = string
|
|
63
|
+
export type HotelRefV1 = string
|
|
64
|
+
export type OfferRefV1 = string
|
|
65
|
+
export type VerifiedOfferRefV1 = string
|
|
66
|
+
export type OrderRefV1 = string
|
|
67
|
+
|
|
68
|
+
export type CriterionStrengthV1 = 'must' | 'prefer'
|
|
69
|
+
export interface CriterionV1<T> {
|
|
70
|
+
strength: CriterionStrengthV1
|
|
71
|
+
value: T
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface MoneyV1 {
|
|
75
|
+
/** Decimal string supplied by the authoritative page object; never recomputed by GoTry. */
|
|
76
|
+
amount: string
|
|
77
|
+
currency: string
|
|
78
|
+
sourceFactRef: FactRefV1
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface OccupancyRoomV1 {
|
|
82
|
+
adults: number
|
|
83
|
+
childAges: number[]
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export interface SearchCriteriaPatchV1 {
|
|
87
|
+
destination?: {
|
|
88
|
+
query?: string
|
|
89
|
+
placeRef?: string
|
|
90
|
+
}
|
|
91
|
+
hotel?: CriterionV1<{
|
|
92
|
+
name?: string
|
|
93
|
+
hotelRef?: HotelRefV1
|
|
94
|
+
}>
|
|
95
|
+
stay?: {
|
|
96
|
+
checkIn?: string
|
|
97
|
+
checkOut?: string
|
|
98
|
+
}
|
|
99
|
+
occupancy?: {
|
|
100
|
+
rooms: OccupancyRoomV1[]
|
|
101
|
+
}
|
|
102
|
+
budget?: CriterionV1<{
|
|
103
|
+
min?: MoneyV1
|
|
104
|
+
max?: MoneyV1
|
|
105
|
+
}>
|
|
106
|
+
starRating?: CriterionV1<{
|
|
107
|
+
min?: number
|
|
108
|
+
max?: number
|
|
109
|
+
}>
|
|
110
|
+
guestRating?: CriterionV1<{
|
|
111
|
+
min: number
|
|
112
|
+
}>
|
|
113
|
+
facilities?: CriterionV1<{
|
|
114
|
+
allOf: string[]
|
|
115
|
+
}>
|
|
116
|
+
distance?: CriterionV1<{
|
|
117
|
+
anchorLabel?: string
|
|
118
|
+
anchorRef?: string
|
|
119
|
+
maxKm: number
|
|
120
|
+
}>
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export type ResultSortV1 =
|
|
124
|
+
| 'recommended'
|
|
125
|
+
| 'price_asc'
|
|
126
|
+
| 'price_desc'
|
|
127
|
+
| 'rating_desc'
|
|
128
|
+
| 'distance_asc'
|
|
129
|
+
|
|
130
|
+
export interface ResultsViewPatchV1 {
|
|
131
|
+
starRating?: { min?: number; max?: number } | null
|
|
132
|
+
guestRatingMin?: number | null
|
|
133
|
+
facilitiesAllOf?: string[] | null
|
|
134
|
+
distance?: { anchorRef: string; maxKm: number } | null
|
|
135
|
+
price?: { min?: MoneyV1; max?: MoneyV1 } | null
|
|
136
|
+
sort?: ResultSortV1
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface OfferCriteriaV1 {
|
|
140
|
+
roomType?: CriterionV1<string[]>
|
|
141
|
+
bedType?: CriterionV1<string[]>
|
|
142
|
+
meals?: CriterionV1<string[]>
|
|
143
|
+
freeCancellation?: CriterionV1<boolean>
|
|
144
|
+
freeCancellationUntil?: CriterionV1<string>
|
|
145
|
+
totalPriceMax?: CriterionV1<MoneyV1>
|
|
146
|
+
roomsAvailableMin?: CriterionV1<number>
|
|
147
|
+
payAtProperty?: CriterionV1<boolean>
|
|
148
|
+
mobileRate?: CriterionV1<boolean>
|
|
149
|
+
targetCount?: number
|
|
150
|
+
sort?: 'best_match' | 'total_price_asc' | 'cancellation_latest'
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export type EvidenceLevelV1 = 'listed' | 'rate_loaded' | 'checked'
|
|
154
|
+
|
|
155
|
+
export interface SurfaceCapabilitiesV1 {
|
|
156
|
+
surface: BookingSurfaceV1
|
|
157
|
+
allowedActions: BookingReadActionKindV1[]
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface SearchDraftSnapshotV1 {
|
|
161
|
+
destination?: { query?: string; placeRef?: string }
|
|
162
|
+
stay?: { checkIn?: string; checkOut?: string }
|
|
163
|
+
occupancy?: { rooms: OccupancyRoomV1[] }
|
|
164
|
+
criteria?: SearchCriteriaPatchV1
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export interface ResultViewSnapshotV1 {
|
|
168
|
+
status: 'idle' | 'loading' | 'ready' | 'partial' | 'failed'
|
|
169
|
+
filters?: ResultsViewPatchV1
|
|
170
|
+
sort?: ResultSortV1
|
|
171
|
+
resultCount?: number
|
|
172
|
+
searchSessionRef?: string
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export interface VisibleHotelFactV1 {
|
|
176
|
+
hotelRef: HotelRefV1
|
|
177
|
+
name: string
|
|
178
|
+
starRating?: number
|
|
179
|
+
guestRating?: number
|
|
180
|
+
distanceKm?: number
|
|
181
|
+
facilityCodes?: string[]
|
|
182
|
+
factRefs: FactRefV1[]
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export interface LoadedOfferFactV1 {
|
|
186
|
+
offerRef: OfferRefV1
|
|
187
|
+
hotelRef: HotelRefV1
|
|
188
|
+
evidenceLevel: EvidenceLevelV1
|
|
189
|
+
factRefs: FactRefV1[]
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
export interface BookingWorkspaceSnapshotV1 {
|
|
193
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
194
|
+
contextRef: ContextRefV1
|
|
195
|
+
surface: BookingSurfaceV1
|
|
196
|
+
revision: number
|
|
197
|
+
locale: string
|
|
198
|
+
currency: string
|
|
199
|
+
searchDraft: SearchDraftSnapshotV1
|
|
200
|
+
results: ResultViewSnapshotV1
|
|
201
|
+
visibleHotels: VisibleHotelFactV1[]
|
|
202
|
+
loadedOffers: LoadedOfferFactV1[]
|
|
203
|
+
focusedHotelRef?: HotelRefV1
|
|
204
|
+
shortlistedOfferRefs: OfferRefV1[]
|
|
205
|
+
selectedOfferRef?: OfferRefV1
|
|
206
|
+
verifiedOfferRef?: VerifiedOfferRefV1
|
|
207
|
+
capabilities: SurfaceCapabilitiesV1
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Browser bootstrap snapshot before the same-origin BFF binds an actor and
|
|
212
|
+
* mints contextRef/capabilities. It deliberately cannot assert any identity or
|
|
213
|
+
* capability field.
|
|
214
|
+
*/
|
|
215
|
+
export type BookingWorkspaceIngressSnapshotV1 = Omit<
|
|
216
|
+
BookingWorkspaceSnapshotV1,
|
|
217
|
+
'contextRef' | 'surface' | 'capabilities'
|
|
218
|
+
>
|
|
219
|
+
|
|
220
|
+
interface BookingReadActionBaseV1<K extends BookingReadActionKindV1, I> {
|
|
221
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
222
|
+
kind: K
|
|
223
|
+
actionId: string
|
|
224
|
+
contextRef: ContextRefV1
|
|
225
|
+
expectedRevision: number
|
|
226
|
+
reason: string
|
|
227
|
+
factRefs: FactRefV1[]
|
|
228
|
+
input: I
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export type SearchPatchActionV1 = BookingReadActionBaseV1<'search.patch', { patch: SearchCriteriaPatchV1 }>
|
|
232
|
+
export type SearchRunActionV1 = BookingReadActionBaseV1<'search.run', Record<string, never>>
|
|
233
|
+
export type ResultsViewPatchActionV1 = BookingReadActionBaseV1<'results.view.patch', { patch: ResultsViewPatchV1 }>
|
|
234
|
+
export type HotelFocusActionV1 = BookingReadActionBaseV1<'hotel.focus', { hotelRef: HotelRefV1 }>
|
|
235
|
+
export type HotelSelectActionV1 = BookingReadActionBaseV1<'hotel.select', { hotelRef: HotelRefV1 }>
|
|
236
|
+
export type OffersQueryActionV1 = BookingReadActionBaseV1<'offers.query', { hotelRefs: HotelRefV1[]; criteria: OfferCriteriaV1 }>
|
|
237
|
+
export type OffersViewPatchActionV1 = BookingReadActionBaseV1<'offers.view.patch', { hotelRef: HotelRefV1; criteria: OfferCriteriaV1 }>
|
|
238
|
+
export type OffersCompareActionV1 = BookingReadActionBaseV1<'offers.compare', { offerRefs: OfferRefV1[]; requestedCount: number }>
|
|
239
|
+
export type OfferSelectActionV1 = BookingReadActionBaseV1<'offer.select', { offerRef: OfferRefV1 }>
|
|
240
|
+
export type OfferCheckActionV1 = BookingReadActionBaseV1<'offer.check', { offerRef: OfferRefV1 }>
|
|
241
|
+
export type CheckoutPrepareActionV1 = BookingReadActionBaseV1<'checkout.prepare', { offerRef: OfferRefV1; verifiedOfferRef: VerifiedOfferRefV1 }>
|
|
242
|
+
export type OrderObserveActionV1 = BookingReadActionBaseV1<'order.observe', { orderRef: OrderRefV1 }>
|
|
243
|
+
|
|
244
|
+
export type BookingReadActionV1 =
|
|
245
|
+
| SearchPatchActionV1
|
|
246
|
+
| SearchRunActionV1
|
|
247
|
+
| ResultsViewPatchActionV1
|
|
248
|
+
| HotelFocusActionV1
|
|
249
|
+
| HotelSelectActionV1
|
|
250
|
+
| OffersQueryActionV1
|
|
251
|
+
| OffersViewPatchActionV1
|
|
252
|
+
| OffersCompareActionV1
|
|
253
|
+
| OfferSelectActionV1
|
|
254
|
+
| OfferCheckActionV1
|
|
255
|
+
| CheckoutPrepareActionV1
|
|
256
|
+
| OrderObserveActionV1
|
|
257
|
+
|
|
258
|
+
export type ActionObservationV1 =
|
|
259
|
+
| { kind: 'search.state'; searchSessionRef?: string; resultCount?: number }
|
|
260
|
+
| { kind: 'results.state'; matchedHotelRefs: HotelRefV1[]; visibleCount: number }
|
|
261
|
+
| { kind: 'hotel.focus'; hotelRef: HotelRefV1 }
|
|
262
|
+
| { kind: 'hotel.selection'; hotelRef: HotelRefV1 }
|
|
263
|
+
| { kind: 'offers.state'; hotelRefs: HotelRefV1[]; offerRefs: OfferRefV1[]; loadedHotelCount: number }
|
|
264
|
+
| { kind: 'offer.selection'; offerRef: OfferRefV1 }
|
|
265
|
+
| { kind: 'offer.availability'; offerRef: OfferRefV1; verifiedOfferRef?: VerifiedOfferRefV1; available: boolean; changedFactRefs: FactRefV1[] }
|
|
266
|
+
| { kind: 'checkout.handoff'; offerRef: OfferRefV1; verifiedOfferRef: VerifiedOfferRefV1; handoffRef: string }
|
|
267
|
+
| { kind: 'order.state'; orderRef: OrderRefV1; state: 'pending' | 'verified' | 'failed' | 'unknown' }
|
|
268
|
+
| { kind: 'gap'; code: string; factRefs: FactRefV1[] }
|
|
269
|
+
|
|
270
|
+
export interface ResultContractV1 {
|
|
271
|
+
outcome: 'complete' | 'partial' | 'empty'
|
|
272
|
+
requestedCount?: number
|
|
273
|
+
actualCount?: number
|
|
274
|
+
hardCriteriaMet: boolean
|
|
275
|
+
factRefs: FactRefV1[]
|
|
276
|
+
gapCodes: string[]
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface ActionReceiptV1 {
|
|
280
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
281
|
+
kind: 'action.receipt'
|
|
282
|
+
actionId: string
|
|
283
|
+
contextRef: ContextRefV1
|
|
284
|
+
status: ActionReceiptStatusV1
|
|
285
|
+
revision: number
|
|
286
|
+
observation: ActionObservationV1
|
|
287
|
+
resultContract: ResultContractV1
|
|
288
|
+
undoToken?: string
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
export interface UserTurnV1 {
|
|
292
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
293
|
+
kind: 'user.turn'
|
|
294
|
+
taskId?: string
|
|
295
|
+
workspace: BookingWorkspaceSnapshotV1
|
|
296
|
+
request: {
|
|
297
|
+
/** Transport-only natural language. It must never be persisted as executable state. */
|
|
298
|
+
text: string
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
export interface BookingCopilotIngressTurnV1 {
|
|
303
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
304
|
+
kind: 'user.turn.ingress'
|
|
305
|
+
taskId?: string
|
|
306
|
+
/** Bootstrap may omit this field or send null. A browser cannot mint it. */
|
|
307
|
+
contextRef?: null
|
|
308
|
+
surfaceHint: BookingSurfaceV1
|
|
309
|
+
workspace: BookingWorkspaceIngressSnapshotV1
|
|
310
|
+
request: {
|
|
311
|
+
text: string
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
export interface ActionReceiptContinuationV1 {
|
|
316
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
317
|
+
kind: 'action.receipt.continuation'
|
|
318
|
+
taskId: string
|
|
319
|
+
workspace: BookingWorkspaceSnapshotV1
|
|
320
|
+
receipt: ActionReceiptV1
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
export type BookingCopilotTurnV1 = UserTurnV1 | ActionReceiptContinuationV1
|
|
324
|
+
|
|
325
|
+
interface BookingSurfaceEventBaseV1<K extends BookingSurfaceEventKindV1> {
|
|
326
|
+
schemaVersion: typeof BOOKING_SURFACE_SCHEMA_VERSION
|
|
327
|
+
eventId: string
|
|
328
|
+
taskId: string
|
|
329
|
+
contextRef: ContextRefV1
|
|
330
|
+
sequence: number
|
|
331
|
+
emittedAt: string
|
|
332
|
+
kind: K
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export type BookingStatusEventV1 = BookingSurfaceEventBaseV1<'status'> & {
|
|
336
|
+
status: 'submitted' | 'working' | 'waiting_receipt' | 'input_required'
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export type BookingQuestionEventV1 = BookingSurfaceEventBaseV1<'question'> & {
|
|
340
|
+
question: {
|
|
341
|
+
questionId: string
|
|
342
|
+
prompt: string
|
|
343
|
+
missingFields: string[]
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
export type BookingOperationEventV1 = BookingSurfaceEventBaseV1<'operation'> & {
|
|
348
|
+
action: BookingReadActionV1
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export type BookingExplanationEventV1 = BookingSurfaceEventBaseV1<'explanation'> & {
|
|
352
|
+
explanation: {
|
|
353
|
+
text: string
|
|
354
|
+
factRefs: FactRefV1[]
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export type BookingTerminalEventV1 = BookingSurfaceEventBaseV1<'terminal'> & {
|
|
359
|
+
terminal: {
|
|
360
|
+
status: 'completed' | 'stopped'
|
|
361
|
+
summary: string
|
|
362
|
+
factRefs: FactRefV1[]
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
export type BookingErrorEventV1 = BookingSurfaceEventBaseV1<'error'> & {
|
|
367
|
+
error: {
|
|
368
|
+
code: string
|
|
369
|
+
message: string
|
|
370
|
+
retryable: boolean
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
export type BookingSurfaceEventV1 =
|
|
375
|
+
| BookingStatusEventV1
|
|
376
|
+
| BookingQuestionEventV1
|
|
377
|
+
| BookingOperationEventV1
|
|
378
|
+
| BookingExplanationEventV1
|
|
379
|
+
| BookingTerminalEventV1
|
|
380
|
+
| BookingErrorEventV1
|