@curless/hotel-storefront 0.35.3 → 0.36.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.
@@ -1 +1 @@
1
- {"version":3,"file":"card.generated.js","sourceRoot":"","sources":["../src/card.generated.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,wEAAwE;AACxE,gFAAgF;AAChF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAChD,kvwzBAAkvwzB,EAClvwzB,QAAQ,CACT,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAEnB,6GAA6G;AAC7G,MAAM,CAAC,MAAM,qBAAqB,GAChC,kEAAkE,CAAC"}
1
+ {"version":3,"file":"card.generated.js","sourceRoot":"","sources":["../src/card.generated.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,wEAAwE;AACxE,gFAAgF;AAChF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,eAAe,GAAW,MAAM,CAAC,IAAI,CAChD,82yzBAA82yzB,EAC92yzB,QAAQ,CACT,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAEnB,6GAA6G;AAC7G,MAAM,CAAC,MAAM,qBAAqB,GAChC,kEAAkE,CAAC"}
package/dist/server.d.ts CHANGED
@@ -28,7 +28,7 @@ export declare const INITIALIZE_PER_MINUTE = 300;
28
28
  * number. Found by reading the boot banner of a container that had just been
29
29
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
30
30
  */
31
- export declare const VERSION = "0.35.3";
31
+ export declare const VERSION = "0.36.0";
32
32
  /**
33
33
  * The card's resource URI.
34
34
  *
@@ -37,7 +37,7 @@ export declare const VERSION = "0.35.3";
37
37
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
38
38
  * this reason.
39
39
  */
40
- export declare const CARD_URI = "ui://curless/hotel/booking-v71.html";
40
+ export declare const CARD_URI = "ui://curless/hotel/booking-v72.html";
41
41
  /**
42
42
  * The URI one deployment names its card by: `CARD_URI` with a short hash of
43
43
  * everything a host caches under it - the card itself, and the hosts it may
package/dist/server.js CHANGED
@@ -46,7 +46,7 @@ export const INITIALIZE_PER_MINUTE = 300;
46
46
  * number. Found by reading the boot banner of a container that had just been
47
47
  * deployed (2026-09-22): seventeen tools listed, and "0.7.0" above them.
48
48
  */
49
- export const VERSION = '0.35.3';
49
+ export const VERSION = '0.36.0';
50
50
  /**
51
51
  * The card's resource URI.
52
52
  *
@@ -55,7 +55,7 @@ export const VERSION = '0.35.3';
55
55
  * connector went storefront-v35 → v40 in a single day of UI work for exactly
56
56
  * this reason.
57
57
  */
58
- export const CARD_URI = 'ui://curless/hotel/booking-v71.html';
58
+ export const CARD_URI = 'ui://curless/hotel/booking-v72.html';
59
59
  /** The card as it ships, hashed once - what a host caches under the URI. */
60
60
  const CARD_HTML_SHA = createHash('sha256').update(HOTEL_CARD_HTML).digest('hex');
61
61
  /**
package/dist/tools.d.ts CHANGED
@@ -890,7 +890,15 @@ export type ToolAnswer = {
890
890
  */
891
891
  export declare const CITY_PICKER_MIN = 4;
892
892
  /**
893
- * The answer when the card names a trip this connector no longer knows.
893
+ * The answer when the card names a trip this connector does not know.
894
+ *
895
+ * ⚠️ NOT "EXPIRED" (华住 / robin, 2026-10-15). A trip id lives as long as its
896
+ * conversation (trip-ids.ts, `ID_TTL_MS`), and a trip emptied after
897
+ * TRIP_TTL_MS starts over under the same id - so an id nobody knows is not a
898
+ * trip that lapsed. It is a card from before the service's state moved (the
899
+ * public Huazhu's went to a new directory when it switched to the test
900
+ * system), or from a conversation quiet for longer than its id is kept. "Kept
901
+ * for 4 hours" was said over a card drawn an hour before.
894
902
  *
895
903
  * ⚠️ SAID, NOT PAPERED OVER. An unknown id used to fall back to the card's own
896
904
  * connection - a DIFFERENT trip from the conversation's - and the card took
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -7,7 +7,7 @@ import { formatMoney, money, multiplyMoney, toMinor } from './money.js';
7
7
  import { withTraditional } from './names.js';
8
8
  import { MAX_COMPARED, MAX_CONS, MAX_DAYS, MAX_ITEMS_PER_DAY, MAX_MOMENTS, MAX_PROS, buildItinerary, candidatesFor, compareHotels, namesMoreThanOne, } from './present.js';
9
9
  import { regionOf } from './regions.js';
10
- import { MAX_EXTRA_QUANTITY, MAX_ROOMS_PER_LINE, TRIP_TTL_MS, clampCount, shownOf, tripKey, } from './trip.js';
10
+ import { MAX_EXTRA_QUANTITY, MAX_ROOMS_PER_LINE, clampCount, shownOf, tripKey, } from './trip.js';
11
11
  import { DEMO_NOTE, branded, catalogue, noteFor, upFirst } from './vocab.js';
12
12
  // The eleven things a guest can do: find hotels, look at one on dates, see what
13
13
  // else it offers, build a trip, ask for the rooms, and deal with a booking they
@@ -939,11 +939,33 @@ export const outputSchemasFor = (schemas, caps, lang, also = {}) => {
939
939
  return [name, { ...s, properties }];
940
940
  }));
941
941
  };
942
+ /** A hotel's page - what get_hotel answers, and the list too where a deployment has one hotel. */
943
+ const HOTEL_PAGE = {
944
+ hotel: HOTEL,
945
+ stay: OBJ,
946
+ rooms: ARR,
947
+ /** True when no dates were given: the card asks for them instead of showing rooms. */
948
+ needsDates: BOOL,
949
+ /** How many rooms of one type the list was filtered to. */
950
+ rooms_wanted: { type: 'number' },
951
+ noRooms: STR,
952
+ /** `noRooms` as a code (`NoRoomsCode`) and what it holds, for a card to say in the guest's language. */
953
+ noRoomsCode: STR,
954
+ noRoomsArgs: OBJ,
955
+ extras: ARR,
956
+ policies: ARR,
957
+ /** Arrivals a few days either side, each re-quoted for the same nights. */
958
+ dates: ARR,
959
+ };
942
960
  export const buildOutputSchemas = (n) => ({
943
961
  [n.listHotels]: {
944
962
  type: 'object',
945
963
  properties: {
946
- view: { enum: ['hotels', 'no-hotels', 'destinations'] },
964
+ // A deployment of one hotel answers an unnarrowed list with its page
965
+ // (`only`): 'hotel' or 'no-rooms', as get_hotel would.
966
+ view: {
967
+ enum: ['hotels', 'no-hotels', 'destinations', 'hotel', 'no-rooms', 'hotel-not-found'],
968
+ },
947
969
  brand: STR,
948
970
  toolNames: OBJ,
949
971
  bookingMode: STR,
@@ -966,6 +988,9 @@ export const buildOutputSchemas = (n) => ({
966
988
  currencies: STRS,
967
989
  /** Set when nothing matched and one wider search was tried instead. */
968
990
  widened: OBJ,
991
+ /** The deployment's only hotel, answered with its page - see HOTEL_PAGE. */
992
+ only: BOOL,
993
+ ...HOTEL_PAGE,
969
994
  },
970
995
  required: ['view'],
971
996
  },
@@ -979,21 +1004,7 @@ export const buildOutputSchemas = (n) => ({
979
1004
  vocab: OBJ,
980
1005
  demo: BOOL,
981
1006
  demoNote: STR,
982
- hotel: HOTEL,
983
- stay: OBJ,
984
- rooms: ARR,
985
- /** True when no dates were given: the card asks for them instead of showing rooms. */
986
- needsDates: BOOL,
987
- /** How many rooms of one type the list was filtered to. */
988
- rooms_wanted: { type: 'number' },
989
- noRooms: STR,
990
- /** `noRooms` as a code (`NoRoomsCode`) and what it holds, for a card to say in the guest's language. */
991
- noRoomsCode: STR,
992
- noRoomsArgs: OBJ,
993
- extras: ARR,
994
- policies: ARR,
995
- /** Arrivals a few days either side, each re-quoted for the same nights. */
996
- dates: ARR,
1007
+ ...HOTEL_PAGE,
997
1008
  /** A name that fits more than one hotel: the ones it fits (`namesLike`). */
998
1009
  candidates: ARR,
999
1010
  },
@@ -2346,7 +2357,15 @@ const suggestionsFor = async (deps, d) => {
2346
2357
  .slice(0, 3);
2347
2358
  };
2348
2359
  /**
2349
- * The answer when the card names a trip this connector no longer knows.
2360
+ * The answer when the card names a trip this connector does not know.
2361
+ *
2362
+ * ⚠️ NOT "EXPIRED" (华住 / robin, 2026-10-15). A trip id lives as long as its
2363
+ * conversation (trip-ids.ts, `ID_TTL_MS`), and a trip emptied after
2364
+ * TRIP_TTL_MS starts over under the same id - so an id nobody knows is not a
2365
+ * trip that lapsed. It is a card from before the service's state moved (the
2366
+ * public Huazhu's went to a new directory when it switched to the test
2367
+ * system), or from a conversation quiet for longer than its id is kept. "Kept
2368
+ * for 4 hours" was said over a card drawn an hour before.
2350
2369
  *
2351
2370
  * ⚠️ SAID, NOT PAPERED OVER. An unknown id used to fall back to the card's own
2352
2371
  * connection - a DIFFERENT trip from the conversation's - and the card took
@@ -2356,7 +2375,7 @@ const suggestionsFor = async (deps, d) => {
2356
2375
  * assistant's next answer hands the card.
2357
2376
  */
2358
2377
  export const tripGone = (deps) => {
2359
- const detail = `The trip this card was showing is no longer kept - a trip is kept for ${TRIP_TTL_MS / 3_600_000} hours after its last change. Ask the assistant to show the trip again.`;
2378
+ const detail = 'The trip this card was showing is not known here any more - the service may have been updated since the card was drawn, or the conversation has been quiet for a long time. Ask the assistant to show the trip again.';
2360
2379
  return {
2361
2380
  structured: { view: 'error', ...common(deps), error: 'trip-gone', detail },
2362
2381
  text: detail,
@@ -2576,6 +2595,23 @@ const answerTool = async (deps, name, rawArgs, ctx) => {
2576
2595
  .filter((x) => !!x)
2577
2596
  .sort();
2578
2597
  const today = days.length ? { min: days[0], max: days.at(-1) } : undefined;
2598
+ // ⚠️ ONE HOTEL IS NO CHOICE OF PLACES (robin, 2026-10-15: 「现在只有杭州一家
2599
+ // 了,首页也要改」). Huazhu's test system has one hotel, and "where to?" over
2600
+ // a search box, one city chip and "browse all 1 hotel" was a page of ways
2601
+ // to the only thing there is. Where the whole deployment is one hotel -
2602
+ // never a market, whose home is its groups - the home is that hotel's
2603
+ // page: for the nights asked, or asking for them. `only` tells the card it
2604
+ // is the home, so the home's own ways (my bookings, a booking by its code)
2605
+ // stay on it.
2606
+ const [sole] = hotels;
2607
+ if (choosing && total === 1 && sole && !deps.backend.suppliers) {
2608
+ const page = await answerTool(deps, t.getHotel, { hotel: sole.id, ...stayArgs }, ctx);
2609
+ return {
2610
+ ...page,
2611
+ structured: { ...page.structured, only: true },
2612
+ text: `${sole.name} is the only ${branded(deps.vocab, deps.vocab.noun)} here, so this is its page.\n\n${page.text}`,
2613
+ };
2614
+ }
2579
2615
  if (choosing && facets) {
2580
2616
  const countries = facets.countries.map((c) => ({
2581
2617
  name: c.name,