@curless/hotel-storefront 0.1.0

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 (98) hide show
  1. package/README.md +63 -0
  2. package/dist/__tests__/card-contract.test.d.ts +2 -0
  3. package/dist/__tests__/card-contract.test.d.ts.map +1 -0
  4. package/dist/__tests__/card-contract.test.js +64 -0
  5. package/dist/__tests__/card-contract.test.js.map +1 -0
  6. package/dist/__tests__/data.test.d.ts +2 -0
  7. package/dist/__tests__/data.test.d.ts.map +1 -0
  8. package/dist/__tests__/data.test.js +89 -0
  9. package/dist/__tests__/data.test.js.map +1 -0
  10. package/dist/__tests__/dates.test.d.ts +2 -0
  11. package/dist/__tests__/dates.test.d.ts.map +1 -0
  12. package/dist/__tests__/dates.test.js +71 -0
  13. package/dist/__tests__/dates.test.js.map +1 -0
  14. package/dist/__tests__/demo-hotels.test.d.ts +2 -0
  15. package/dist/__tests__/demo-hotels.test.d.ts.map +1 -0
  16. package/dist/__tests__/demo-hotels.test.js +240 -0
  17. package/dist/__tests__/demo-hotels.test.js.map +1 -0
  18. package/dist/__tests__/server.test.d.ts +2 -0
  19. package/dist/__tests__/server.test.d.ts.map +1 -0
  20. package/dist/__tests__/server.test.js +209 -0
  21. package/dist/__tests__/server.test.js.map +1 -0
  22. package/dist/__tests__/tool-descriptions.test.d.ts +2 -0
  23. package/dist/__tests__/tool-descriptions.test.d.ts.map +1 -0
  24. package/dist/__tests__/tool-descriptions.test.js +139 -0
  25. package/dist/__tests__/tool-descriptions.test.js.map +1 -0
  26. package/dist/__tests__/tools.test.d.ts +2 -0
  27. package/dist/__tests__/tools.test.d.ts.map +1 -0
  28. package/dist/__tests__/tools.test.js +226 -0
  29. package/dist/__tests__/tools.test.js.map +1 -0
  30. package/dist/backend.d.ts +43 -0
  31. package/dist/backend.d.ts.map +1 -0
  32. package/dist/backend.js +2 -0
  33. package/dist/backend.js.map +1 -0
  34. package/dist/card.generated.d.ts +4 -0
  35. package/dist/card.generated.d.ts.map +1 -0
  36. package/dist/card.generated.js +8 -0
  37. package/dist/card.generated.js.map +1 -0
  38. package/dist/config.d.ts +122 -0
  39. package/dist/config.d.ts.map +1 -0
  40. package/dist/config.js +42 -0
  41. package/dist/config.js.map +1 -0
  42. package/dist/data.d.ts +5 -0
  43. package/dist/data.d.ts.map +1 -0
  44. package/dist/data.js +183 -0
  45. package/dist/data.js.map +1 -0
  46. package/dist/dates.d.ts +32 -0
  47. package/dist/dates.d.ts.map +1 -0
  48. package/dist/dates.js +75 -0
  49. package/dist/dates.js.map +1 -0
  50. package/dist/demo-hotels.d.ts +96 -0
  51. package/dist/demo-hotels.d.ts.map +1 -0
  52. package/dist/demo-hotels.js +446 -0
  53. package/dist/demo-hotels.js.map +1 -0
  54. package/dist/fence.d.ts +24 -0
  55. package/dist/fence.d.ts.map +1 -0
  56. package/dist/fence.js +0 -0
  57. package/dist/fence.js.map +1 -0
  58. package/dist/index.d.ts +3 -0
  59. package/dist/index.d.ts.map +1 -0
  60. package/dist/index.js +23 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/legal.d.ts +5 -0
  63. package/dist/legal.d.ts.map +1 -0
  64. package/dist/legal.js +111 -0
  65. package/dist/legal.js.map +1 -0
  66. package/dist/money.d.ts +13 -0
  67. package/dist/money.d.ts.map +1 -0
  68. package/dist/money.js +46 -0
  69. package/dist/money.js.map +1 -0
  70. package/dist/server.d.ts +85 -0
  71. package/dist/server.d.ts.map +1 -0
  72. package/dist/server.js +275 -0
  73. package/dist/server.js.map +1 -0
  74. package/dist/surface.d.ts +52 -0
  75. package/dist/surface.d.ts.map +1 -0
  76. package/dist/surface.js +99 -0
  77. package/dist/surface.js.map +1 -0
  78. package/dist/tools.d.ts +336 -0
  79. package/dist/tools.d.ts.map +1 -0
  80. package/dist/tools.js +862 -0
  81. package/dist/tools.js.map +1 -0
  82. package/dist/trip-ids.d.ts +16 -0
  83. package/dist/trip-ids.d.ts.map +1 -0
  84. package/dist/trip-ids.js +77 -0
  85. package/dist/trip-ids.js.map +1 -0
  86. package/dist/trip.d.ts +59 -0
  87. package/dist/trip.d.ts.map +1 -0
  88. package/dist/trip.js +149 -0
  89. package/dist/trip.js.map +1 -0
  90. package/dist/types.d.ts +193 -0
  91. package/dist/types.d.ts.map +1 -0
  92. package/dist/types.js +13 -0
  93. package/dist/types.js.map +1 -0
  94. package/dist/vocab.d.ts +33 -0
  95. package/dist/vocab.d.ts.map +1 -0
  96. package/dist/vocab.js +15 -0
  97. package/dist/vocab.js.map +1 -0
  98. package/package.json +44 -0
@@ -0,0 +1,99 @@
1
+ import { FENCE_RULE } from './fence.js';
2
+ import { DEMO_NOTE } from './vocab.js';
3
+ // What a host is told about this connector: the `instructions` it injects into
4
+ // the model's context, and the tool list with each tool's card metadata.
5
+ //
6
+ // ⚠️ THIS FILE CARRIES THE BEHAVIOUR. Tool descriptions say what a tool does;
7
+ // everything about HOW TO ACT - ask for dates rather than guess, show the whole
8
+ // shortlist, preview before cancelling, never say "booked" - is here, because
9
+ // both directory listings attest that tool descriptions contain no instructions
10
+ // about model behaviour. The shopping connector had to make that true after the
11
+ // fact on 2026-09-17; this one starts here.
12
+ /**
13
+ * How to BEHAVE, not just what the tools are.
14
+ *
15
+ * Most of these lines exist because the opposite behaviour is the natural one.
16
+ * An assistant handed hotel tools will: interview the guest about budget and
17
+ * view before showing anything; pick the "best" property in a city and quietly
18
+ * drop the other three; fill in "this weekend" for dates nobody gave; call a
19
+ * held room booked; and cancel when asked to cancel, discovering the fee
20
+ * afterwards. Each of those is one line below.
21
+ */
22
+ export const buildInstructions = (brand) => {
23
+ const { tools: t, vocab: v } = brand;
24
+ const takesPayment = brand.config.payment?.mode === 'wallet';
25
+ return [
26
+ `${v.brand} ${v.nounPlural}. The card IS the booking surface: it shows the ${v.nounPlural} with pictures, rooms with their nightly rate and stay total, the trip and its total, and the booking itself.`,
27
+ `These tools read ${v.brand}'s own ${v.noun} data: what each property offers, what a room costs on given nights, and what its cancellation terms are.`,
28
+ // Demonstration data is a fact about the answer, not a disclaimer to bury.
29
+ ...(v.demo
30
+ ? [
31
+ `⚠️ ${DEMO_NOTE} Say so the first time you quote a price, and never imply a room can actually be occupied.`,
32
+ ]
33
+ : []),
34
+ `FIRST TURN: call ${t.listHotels} ONCE and stop - with the guest's own words as \`query\`, or the city as \`city\`, when they have said where they are going, and with nothing when they have not. Do not interview them first, do not recommend, and do not describe the ${v.nounPlural} in prose; they are on the screen. Say at most one short line.`,
35
+ // ⚠️ A CITY IS NOT A HOTEL. The single most useful thing in the reference
36
+ // demo, and the easiest to lose: four Hong Kong properties under three
37
+ // brands, and an assistant that "helpfully" picks one has made the guest's
38
+ // choice for them.
39
+ `A city usually has several ${v.nounPlural}. Show all of them and let the guest choose - do not pick one for them, and do not drop the ones you would not have chosen.`,
40
+ // ⚠️ DATES ARE NOT YOURS TO GUESS.
41
+ `A room has no price until the nights are known. When the guest has not said their dates, ask - do not assume tonight, this weekend, or the dates of anything else in the conversation. ${t.getHotel} without dates returns the ${v.noun} and no rooms, which is the right answer to show while asking.`,
42
+ `${t.getHotel} with \`checkIn\` and \`checkOut\` gives the room types for those nights: nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many are left. Quote the stay total when comparing - a nightly rate hides the weekend and the tax.`,
43
+ `The card keeps a trip: room nights plus add-ons. ${t.addToTrip} and ${t.viewTrip} change and read it from the chat, and ${t.listExtras} shows what a ${v.noun} offers beside the room. To take a line out, set its \`rooms\` or \`quantity\` to 0; ${t.clearTrip} empties all of it, and only when the guest asks. To know what is in the trip, call ${t.viewTrip} rather than repeating it from memory - the guest may have changed it on the card.`,
44
+ ...(v.hints.hotel ? [v.hints.hotel] : []),
45
+ // ⚠️ HELD IS NOT BOOKED AND NOT PAID.
46
+ takesPayment
47
+ ? `${t.requestBooking} holds the rooms; payment follows. Do not describe a held booking as paid.`
48
+ : `${t.requestBooking} asks ${v.brand} to hold the rooms for a named guest and returns a confirmation code and the moment the hold lapses. IT TAKES NO MONEY AND COLLECTS NO CARD. Report it as requested and held, never as booked-and-paid, and tell the guest when the hold lapses and that a card is presented at check-in. Never ask for a card number, and never put one into any field - if the guest offers card details, tell them this connector does not take them.`,
49
+ `${t.requestBooking} needs the guest's own name and email. Ask for them - do not use a name or email you know from anywhere else, such as their account or profile, unless they have typed it in this conversation.`,
50
+ // ⚠️ PREVIEW, THEN CANCEL. The tool enforces this; the instruction is why.
51
+ `Before cancelling anything: ${t.previewCancellation} says what it would cost, what comes back, and the rule behind it. Show the guest that and get a yes before calling ${t.cancelBooking} with \`confirmed\` - it returns the preview and cancels nothing without it. A guest who says "cancel it" has not yet seen the fee.`,
52
+ `Questions about cancellation terms, check-in and check-out, children, pets, deposits or accessibility: call ${t.policies} with that topic and answer from what the ${v.noun} has published. If it does not say, tell the guest that and give the ${v.noun}'s link; do not fill in what hotels usually do.`,
53
+ `Availability is what the ${v.noun} says it has. Report a low room count as a fact if the guest asks; do not turn it into a reason to hurry.`,
54
+ FENCE_RULE,
55
+ ]
56
+ .filter(Boolean)
57
+ .join('\n');
58
+ };
59
+ /**
60
+ * The `tools/list` answer: each tool with its card metadata and the shape of
61
+ * what it returns.
62
+ *
63
+ * The schemas are merged on here rather than kept in the tool literals - that
64
+ * list is the contract a guest's assistant reads, and it stays legible without
65
+ * them inline.
66
+ */
67
+ export const listTools = (tools, outputSchemas, metaFor, tripTools = new Set()) => tools.map((t) => {
68
+ const outputSchema = outputSchemas[t.name];
69
+ const schema = t.inputSchema;
70
+ const named = tripTools.has(t.name) && schema
71
+ ? {
72
+ inputSchema: {
73
+ ...schema,
74
+ properties: { ...(schema.properties ?? {}), trip: TRIP_PARAM },
75
+ },
76
+ }
77
+ : {};
78
+ return { ...t, ...named, _meta: metaFor(t.name), ...(outputSchema ? { outputSchema } : {}) };
79
+ });
80
+ /**
81
+ * What the card fills in and the assistant leaves out: the id of the trip the
82
+ * card is showing. The card's calls reach the server on a different connection
83
+ * from the conversation's, so it names the trip instead of relying on the
84
+ * session.
85
+ */
86
+ export const TRIP_PARAM = {
87
+ type: 'string',
88
+ description: 'Set by the booking card: the id of the trip it is showing. Leave it out.',
89
+ };
90
+ /** Every tool the card calls about the trip or a booking. */
91
+ export const tripToolNames = (brand) => new Set([
92
+ brand.tools.addToTrip,
93
+ brand.tools.viewTrip,
94
+ brand.tools.clearTrip,
95
+ brand.tools.requestBooking,
96
+ brand.tools.previewCancellation,
97
+ brand.tools.cancelBooking,
98
+ ]);
99
+ //# sourceMappingURL=surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"surface.js","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,336 @@
1
+ import type { HotelBackend } from './backend.js';
2
+ import type { ToolNames } from './config.js';
3
+ import { type TripStore } from './trip.js';
4
+ import { type Vocabulary } from './vocab.js';
5
+ export declare const buildTools: (n: ToolNames, v: Vocabulary) => readonly [{
6
+ readonly name: `list_${string}${string}`;
7
+ readonly description: `${string} ${string}, shown as a card with a picture, the city and area, a rating where the ${string} publishes one, and a from-price for each. \`city\` or \`query\` narrows the list; a city usually holds several ${string}, and all of them are returned. Dates are not needed here and no stay is priced.${string}`;
8
+ readonly annotations: {
9
+ readonly title: string;
10
+ readonly readOnlyHint: true;
11
+ readonly destructiveHint: false;
12
+ readonly idempotentHint: true;
13
+ readonly openWorldHint: boolean;
14
+ };
15
+ readonly inputSchema: {
16
+ readonly type: "object";
17
+ readonly properties: {
18
+ readonly query: {
19
+ readonly type: "string";
20
+ readonly description: "Free text over the name, city, area, description and amenities - the guest's own words";
21
+ };
22
+ readonly city: {
23
+ readonly type: "string";
24
+ readonly description: "One city, e.g. \"Hong Kong\"";
25
+ };
26
+ readonly limit: {
27
+ readonly type: "number";
28
+ readonly description: "Default 20";
29
+ };
30
+ };
31
+ };
32
+ }, {
33
+ readonly name: `get_${string}${string}`;
34
+ readonly description: `One ${string} in full: description, amenities, address, check-in and check-out times. Given \`checkIn\` and \`checkOut\` it also returns the room types that can be booked for those nights, each with its nightly rate, the stay total including taxes and fees, whether it can be cancelled free and until when, and how many rooms are left. Without dates it returns the ${string} only, because a room has no price until the nights are known.${string}`;
35
+ readonly annotations: {
36
+ readonly title: string;
37
+ readonly readOnlyHint: true;
38
+ readonly destructiveHint: false;
39
+ readonly idempotentHint: true;
40
+ readonly openWorldHint: boolean;
41
+ };
42
+ readonly inputSchema: {
43
+ readonly type: "object";
44
+ readonly properties: {
45
+ readonly checkIn: {
46
+ readonly type: "string";
47
+ readonly description: `${string}, as YYYY-MM-DD`;
48
+ };
49
+ readonly checkOut: {
50
+ readonly type: "string";
51
+ readonly description: `${string}, as YYYY-MM-DD`;
52
+ };
53
+ readonly guests: {
54
+ readonly type: "number";
55
+ readonly description: "People in the room. Default 2";
56
+ };
57
+ readonly hotel: {
58
+ readonly type: "string";
59
+ readonly description: `The ${string}'s name or id${string}`;
60
+ };
61
+ };
62
+ readonly required: readonly ["hotel"];
63
+ };
64
+ }, {
65
+ readonly name: `list_${string}extras`;
66
+ readonly description: `What one ${string} offers beside the room: airport transfers, dinners, guided experiences, spa and family add-ons, each with its price and whether it is charged per stay, per person or per night.`;
67
+ readonly annotations: {
68
+ readonly title: string;
69
+ readonly readOnlyHint: true;
70
+ readonly destructiveHint: false;
71
+ readonly idempotentHint: true;
72
+ readonly openWorldHint: boolean;
73
+ };
74
+ readonly inputSchema: {
75
+ readonly type: "object";
76
+ readonly properties: {
77
+ readonly checkIn: {
78
+ readonly type: "string";
79
+ readonly description: `${string}, as YYYY-MM-DD`;
80
+ };
81
+ readonly checkOut: {
82
+ readonly type: "string";
83
+ readonly description: `${string}, as YYYY-MM-DD`;
84
+ };
85
+ readonly guests: {
86
+ readonly type: "number";
87
+ readonly description: "People in the room. Default 2";
88
+ };
89
+ readonly hotel: {
90
+ readonly type: "string";
91
+ readonly description: `The ${string}'s name or id`;
92
+ };
93
+ };
94
+ readonly required: readonly ["hotel"];
95
+ };
96
+ }, {
97
+ readonly name: `add_to_${string}trip`;
98
+ readonly description: `Puts room nights or an add-on into the trip and returns the whole trip, priced. A room line needs the ${string}, the room type and the dates; \`rooms\` books more than one of that room type. An add-on line needs the ${string} and the add-on. A line is replaced, not stacked: sending the same room and dates again sets that line's room count, and 0 removes it.`;
99
+ readonly annotations: {
100
+ readonly title: string;
101
+ readonly readOnlyHint: false;
102
+ readonly destructiveHint: false;
103
+ readonly idempotentHint: true;
104
+ readonly openWorldHint: boolean;
105
+ };
106
+ readonly inputSchema: {
107
+ readonly type: "object";
108
+ readonly properties: {
109
+ readonly rooms: {
110
+ readonly type: "number";
111
+ readonly description: "How many of that room type, 1 to 5. Default 1; 0 removes the line";
112
+ };
113
+ readonly quantity: {
114
+ readonly type: "number";
115
+ readonly description: "For an add-on: how many, 1 to 20. Default 1; 0 removes it";
116
+ };
117
+ readonly checkIn: {
118
+ readonly type: "string";
119
+ readonly description: `${string}, as YYYY-MM-DD`;
120
+ };
121
+ readonly checkOut: {
122
+ readonly type: "string";
123
+ readonly description: `${string}, as YYYY-MM-DD`;
124
+ };
125
+ readonly guests: {
126
+ readonly type: "number";
127
+ readonly description: "People in the room. Default 2";
128
+ };
129
+ readonly hotel: {
130
+ readonly type: "string";
131
+ readonly description: `The ${string}'s name or id`;
132
+ };
133
+ readonly room: {
134
+ readonly type: "string";
135
+ readonly description: "The room type id or name, as the hotel returned it";
136
+ };
137
+ readonly extra: {
138
+ readonly type: "string";
139
+ readonly description: "The add-on id or name. A line names either this or `room`";
140
+ };
141
+ };
142
+ readonly required: readonly ["hotel"];
143
+ };
144
+ }, {
145
+ readonly name: `view_${string}trip`;
146
+ readonly description: "The trip as it stands: every room line and add-on with its own total, the taxes and fees, and the all-in total, laid out day by day on the card.";
147
+ readonly annotations: {
148
+ readonly title: string;
149
+ readonly readOnlyHint: true;
150
+ readonly destructiveHint: false;
151
+ readonly idempotentHint: true;
152
+ readonly openWorldHint: boolean;
153
+ };
154
+ readonly inputSchema: {
155
+ readonly type: "object";
156
+ readonly properties: {};
157
+ };
158
+ }, {
159
+ readonly name: `clear_${string}trip`;
160
+ readonly description: "Empties the trip.";
161
+ readonly annotations: {
162
+ readonly title: string;
163
+ readonly readOnlyHint: false;
164
+ readonly destructiveHint: false;
165
+ readonly idempotentHint: true;
166
+ readonly openWorldHint: boolean;
167
+ };
168
+ readonly inputSchema: {
169
+ readonly type: "object";
170
+ readonly properties: {};
171
+ };
172
+ }, {
173
+ readonly name: `request_${string}booking`;
174
+ readonly description: `Asks ${string} to hold the trip's rooms for a named guest and returns a confirmation code and the moment the hold lapses. No payment is taken and no card is collected; the rooms are held, not paid for.`;
175
+ readonly annotations: {
176
+ readonly title: string;
177
+ readonly readOnlyHint: false;
178
+ readonly destructiveHint: false;
179
+ readonly idempotentHint: false;
180
+ readonly openWorldHint: boolean;
181
+ };
182
+ readonly inputSchema: {
183
+ readonly type: "object";
184
+ readonly properties: {
185
+ readonly name: {
186
+ readonly type: "string";
187
+ readonly description: "The guest's full name, as it should appear on the booking";
188
+ };
189
+ readonly email: {
190
+ readonly type: "string";
191
+ readonly description: "The email the confirmation goes to";
192
+ };
193
+ readonly phone: {
194
+ readonly type: "string";
195
+ readonly description: "Optional";
196
+ };
197
+ readonly notes: {
198
+ readonly type: "string";
199
+ readonly description: "Anything the hotel should know - a late arrival, a high floor";
200
+ };
201
+ };
202
+ readonly required: readonly ["name", "email"];
203
+ };
204
+ }, {
205
+ readonly name: `list_my_${string}bookings`;
206
+ readonly description: "The bookings made in this conversation, newest to oldest, with their status, dates and confirmation codes. Given an email it also finds bookings made with that email.";
207
+ readonly annotations: {
208
+ readonly title: string;
209
+ readonly readOnlyHint: true;
210
+ readonly destructiveHint: false;
211
+ readonly idempotentHint: true;
212
+ readonly openWorldHint: boolean;
213
+ };
214
+ readonly inputSchema: {
215
+ readonly type: "object";
216
+ readonly properties: {
217
+ readonly email: {
218
+ readonly type: "string";
219
+ readonly description: "The email a booking was made with";
220
+ };
221
+ readonly limit: {
222
+ readonly type: "number";
223
+ readonly description: "Default 10";
224
+ };
225
+ };
226
+ };
227
+ }, {
228
+ readonly name: `preview_${string}cancellation`;
229
+ readonly description: "What cancelling a booking would cost and what would be refunded, with the rule it was worked out from and the free-cancellation deadline where the rate has one. Nothing is cancelled.";
230
+ readonly annotations: {
231
+ readonly title: string;
232
+ readonly readOnlyHint: true;
233
+ readonly destructiveHint: false;
234
+ readonly idempotentHint: true;
235
+ readonly openWorldHint: boolean;
236
+ };
237
+ readonly inputSchema: {
238
+ readonly type: "object";
239
+ readonly properties: {
240
+ readonly booking: {
241
+ readonly type: "string";
242
+ readonly description: "The confirmation code or booking id";
243
+ };
244
+ readonly email: {
245
+ readonly type: "string";
246
+ readonly description: "The email the booking was made with, when it was made elsewhere";
247
+ };
248
+ };
249
+ readonly required: readonly ["booking"];
250
+ };
251
+ }, {
252
+ readonly name: `cancel_${string}booking`;
253
+ readonly description: "Cancels a booking. Called without `confirmed` it returns the cancellation preview - the fee, the refund and the rule behind them - and cancels nothing; it cancels only when `confirmed` is true.";
254
+ readonly annotations: {
255
+ readonly title: string;
256
+ readonly readOnlyHint: false;
257
+ readonly destructiveHint: true;
258
+ readonly idempotentHint: true;
259
+ readonly openWorldHint: boolean;
260
+ };
261
+ readonly inputSchema: {
262
+ readonly type: "object";
263
+ readonly properties: {
264
+ readonly booking: {
265
+ readonly type: "string";
266
+ readonly description: "The confirmation code or booking id";
267
+ };
268
+ readonly confirmed: {
269
+ readonly type: "boolean";
270
+ readonly description: "True cancels. Anything else returns the preview";
271
+ };
272
+ readonly reason: {
273
+ readonly type: "string";
274
+ readonly description: "Optional, kept on the booking";
275
+ };
276
+ readonly email: {
277
+ readonly type: "string";
278
+ readonly description: "The email the booking was made with, when it was made elsewhere";
279
+ };
280
+ };
281
+ readonly required: readonly ["booking"];
282
+ };
283
+ }, {
284
+ readonly name: `get_${string}${string}_policies`;
285
+ readonly description: `What one ${string} publishes about cancellation, check-in and check-out, children and extra beds, pets, deposits and accessibility. With \`topic\` it returns that topic; without, all of them.`;
286
+ readonly annotations: {
287
+ readonly title: string;
288
+ readonly readOnlyHint: true;
289
+ readonly destructiveHint: false;
290
+ readonly idempotentHint: true;
291
+ readonly openWorldHint: boolean;
292
+ };
293
+ readonly inputSchema: {
294
+ readonly type: "object";
295
+ readonly properties: {
296
+ readonly hotel: {
297
+ readonly type: "string";
298
+ readonly description: `The ${string}'s name or id`;
299
+ };
300
+ readonly topic: {
301
+ readonly type: "string";
302
+ readonly enum: readonly ["cancellation", "check-in", "children", "pets", "deposit", "accessibility"];
303
+ };
304
+ };
305
+ readonly required: readonly ["hotel"];
306
+ };
307
+ }];
308
+ export declare const buildOutputSchemas: (n: ToolNames) => Record<string, unknown>;
309
+ export type ToolDeps = {
310
+ backend: HotelBackend;
311
+ trips: TripStore;
312
+ tools: ToolNames;
313
+ vocab: Vocabulary;
314
+ logoUrl?: string;
315
+ /** The hotel group's own site, for a guest who wants to read more than we carry. */
316
+ websiteUrl?: string;
317
+ };
318
+ export type ToolContext = {
319
+ /** The host's `Mcp-Session-Id`, or a per-connection fallback. Never a shared constant. */
320
+ session: string;
321
+ /**
322
+ * The trip this call is about, when the caller named one.
323
+ *
324
+ * The card names it: its tool calls arrive on a different connection from the
325
+ * conversation's, so a key built from the session alone is a DIFFERENT key -
326
+ * which is how the shopping connector once told a buyer their card-filled
327
+ * cart was empty. See trip-ids.ts.
328
+ */
329
+ tripKey?: string;
330
+ };
331
+ export type ToolAnswer = {
332
+ structured: Record<string, unknown>;
333
+ text: string;
334
+ };
335
+ export declare const handleTool: (deps: ToolDeps, name: string, rawArgs: unknown, ctx: ToolContext) => Promise<ToolAnswer>;
336
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAI7C,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAa,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAkExD,eAAO,MAAM,UAAU,GAAI,GAAG,SAAS,EAAE,GAAG,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8LrD,CAAC;AAqDF,eAAO,MAAM,kBAAkB,GAAI,GAAG,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAoGtE,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG;IACrB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,SAAS,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAiF/E,eAAO,MAAM,UAAU,GACrB,MAAM,QAAQ,EACd,MAAM,MAAM,EACZ,SAAS,OAAO,EAChB,KAAK,WAAW,KACf,OAAO,CAAC,UAAU,CAgapB,CAAC"}