@sabstravtech/obtservices 0.2.2606091300 → 0.2.2606301620

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.
@@ -11,6 +11,12 @@ export interface CondensedResult {
11
11
  operator?: string;
12
12
  depart: string;
13
13
  arrive: string;
14
+ /** Raw ISO departure datetime (carries the calendar date). Used to detect
15
+ * next-day arrivals and filter overnight itineraries that the supplier
16
+ * returned despite an "arrive by" same-day constraint. */
17
+ departDateTime?: string;
18
+ /** Raw ISO arrival datetime (carries the calendar date). */
19
+ arriveDateTime?: string;
14
20
  stops: number;
15
21
  duration: string;
16
22
  price: number;
@@ -30,6 +36,8 @@ export interface CondensedResult {
30
36
  inbound?: {
31
37
  depart: string;
32
38
  arrive: string;
39
+ departDateTime?: string;
40
+ arriveDateTime?: string;
33
41
  stops: number;
34
42
  duration: string;
35
43
  flightNumbers?: string;
@@ -67,15 +75,20 @@ export interface ChatFlightSearchLeg {
67
75
  timeCriteria?: 'Depart' | 'Arrive';
68
76
  }
69
77
  export interface ChatSearchParameters {
70
- travelType: 'flight' | 'rail' | 'hotel' | 'eurostar' | 'taxi';
78
+ travelType: 'flight' | 'rail' | 'hotel' | 'eurostar' | 'taxi' | 'car-hire' | 'lounge';
71
79
  departure: string;
72
80
  arrival: string;
73
81
  departureCode?: string;
74
82
  arrivalCode?: string;
75
83
  departureDate: string;
76
84
  departureTime?: string;
85
+ /** Outbound arrival time (e.g. "arriving before 5pm"). Maps to the leg's
86
+ * time with "Arrive By" criteria. departureTime takes precedence if both. */
87
+ arrivalTime?: string;
77
88
  returnDate?: string;
78
89
  returnTime?: string;
90
+ /** Inbound arrival time, mirror of arrivalTime for the return leg. */
91
+ returnArrivalTime?: string;
79
92
  passengers: number;
80
93
  /**
81
94
  * Flight multi-city legs. When set with 2+ entries the search runs as
@@ -95,9 +108,21 @@ export interface ChatSearchParameters {
95
108
  propertyNumber?: string;
96
109
  country?: string;
97
110
  cabinClass?: string;
111
+ /** Eurostar return-leg cabin class. When set, overrides cabinClass on the
112
+ * return leg only (e.g. business outbound, standard return). Falls back to
113
+ * cabinClass when omitted. */
114
+ returnCabinClass?: string;
98
115
  maxConnections?: number;
99
116
  outboundTimeCriteria?: 'Depart' | 'Arrive';
100
117
  returnTimeCriteria?: 'Depart' | 'Arrive';
118
+ /** How a flight time target should shape the chat cards. `around` ranks cards
119
+ * by proximity to the time ("closest to / around / at 5pm"). `before`/`after`
120
+ * treat the time as a deadline/bound ("arrive by 11", "after 9am"): the cards
121
+ * are filtered to satisfy the bound but keep the normal results page's
122
+ * Preferred order. Omitted on an initial search (the supplier already
123
+ * windowed the results) so the cards just mirror the page's Preferred top. */
124
+ outboundTimeMode?: 'around' | 'before' | 'after';
125
+ returnTimeMode?: 'around' | 'before' | 'after';
101
126
  railClass?: 'Standard' | 'First' | 'All';
102
127
  viaStation?: string;
103
128
  viaCode?: string;
@@ -106,10 +131,22 @@ export interface ChatSearchParameters {
106
131
  children?: number;
107
132
  /** Railcard codes to apply to this search (e.g. "YNG", "SRN", "FAM"). */
108
133
  railcards?: string[];
134
+ isEuRail?: boolean;
109
135
  airline?: string;
110
136
  airlineCode?: string;
137
+ /** Sort field — values vary by travel type (flight: cheapest/fastest/shortest/most_direct/
138
+ * lowest_emissions/preferred/earliest_departure/latest_departure/earliest_arrival/latest_arrival;
139
+ * hotel: cheapest/distance/preferred/name). */
140
+ sortType?: 'cheapest' | 'fastest' | 'shortest' | 'most_direct' | 'lowest_emissions' | 'preferred' | 'earliest_departure' | 'latest_departure' | 'earliest_arrival' | 'latest_arrival' | 'distance' | 'name';
141
+ /** Up to four preferred airlines, mapped onto the form's carrier slots. When
142
+ * set this takes precedence over the singular airline/airlineCode. */
143
+ airlines?: {
144
+ name?: string;
145
+ code?: string;
146
+ }[];
111
147
  /** Sort field — values vary by travel type (flight: cheapest/fastest/shortest; hotel: cheapest/distance/preferred/name). */
112
- sortType?: 'cheapest' | 'fastest' | 'shortest' | 'distance' | 'preferred' | 'name';
148
+ /** When showing additional hotel results, the number of results already shown. */
149
+ resultOffset?: number;
113
150
  adults?: number;
114
151
  infants?: number;
115
152
  includeNearbyAirports?: boolean;
@@ -121,6 +158,25 @@ export interface ChatSearchParameters {
121
158
  pickupFlightNumber?: string;
122
159
  dropoffTerminal?: string;
123
160
  dropoffFlightNumber?: string;
161
+ locationCode?: string;
162
+ flight?: string;
163
+ terminal?: string;
164
+ carClass?: string;
165
+ carType?: string;
166
+ carTransmission?: string;
167
+ airCon?: boolean;
168
+ driverAge?: number;
169
+ carVendor?: string;
170
+ returnToPickup?: boolean;
171
+ /** Pickup postcode — when set, the car hire search runs in postcode mode
172
+ * instead of resolving a city/airport location. */
173
+ pickupPostcode?: string;
174
+ /** Dropoff postcode when different from the pickup postcode. */
175
+ dropoffPostcode?: string;
176
+ /** Enterprise-only — deliver the rental to the pickup location. */
177
+ delivery?: boolean;
178
+ /** Enterprise-only — collect the rental from the pickup location. */
179
+ collection?: boolean;
124
180
  }
125
181
  export interface ChatRailFareTicket {
126
182
  type: string;
@@ -188,6 +244,10 @@ export interface ChatFlightLeg {
188
244
  duration: string;
189
245
  /** 0 = direct, 1, 2+ */
190
246
  stops: number;
247
+ /** Calendar days the arrival falls after departure (0 = same day, 1 = next
248
+ * day, …). Lets the UI render a "+1" badge for overnight itineraries so a
249
+ * card like "20:50 → 15:35" isn't read as an impossible same-day flight. */
250
+ arrivalDayOffset?: number;
191
251
  /** Flight numbers joined e.g. "BA123/BA456" */
192
252
  flightNumbers: string;
193
253
  }
@@ -202,6 +262,9 @@ export interface ChatFlightFareTicket {
202
262
  currency: string;
203
263
  /** Index back into the underlying journeys array for select / navigate use */
204
264
  journeyIndex?: number;
265
+ /** True when this fare belongs to a separately-priced inbound (dual-single)
266
+ * leg, so the Fare Rules lookup reads the inbound raw journeys array. */
267
+ isReturnLeg?: boolean;
205
268
  }
206
269
  /** Flight fare breakdown for the expandable panel on a chat flight card. */
207
270
  export interface ChatFlightFareBreakdown {
@@ -250,6 +313,15 @@ export interface ChatFlightResults {
250
313
  /** How the results were sorted, used in the summary text */
251
314
  sort?: 'cheapest' | 'fastest' | 'shortest';
252
315
  }
316
+ export interface ChatHotelRoomPolicies {
317
+ cancellation?: string | null;
318
+ deposit?: string | null;
319
+ disabledAccess?: boolean | null;
320
+ general?: string | null;
321
+ guarantee?: string | null;
322
+ refundAvailable?: boolean | null;
323
+ cvvRequired?: boolean | null;
324
+ }
253
325
  export interface ChatHotelRoom {
254
326
  roomId: string;
255
327
  description: string;
@@ -258,6 +330,12 @@ export interface ChatHotelRoom {
258
330
  currencyCode: string;
259
331
  unavailable: boolean;
260
332
  policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
333
+ rateSource?: string | null;
334
+ rateCode?: string | null;
335
+ rateDescription?: string | null;
336
+ roomDescription?: string | null;
337
+ policies?: ChatHotelRoomPolicies;
338
+ additional?: any;
261
339
  }
262
340
  export interface ChatHotelResultCard {
263
341
  index: number;
@@ -273,6 +351,7 @@ export interface ChatHotelResultCard {
273
351
  policyMessages?: string[];
274
352
  co2?: number;
275
353
  currencyCode?: string;
354
+ source?: string;
276
355
  rooms?: ChatHotelRoom[];
277
356
  }
278
357
  export interface ChatHotelResults {
@@ -280,6 +359,53 @@ export interface ChatHotelResults {
280
359
  searchHeader: string;
281
360
  parameters: ChatSearchParameters;
282
361
  }
362
+ export interface ChatCarHireResultCard {
363
+ index: number;
364
+ vehicleDescription: string;
365
+ vendorName: string;
366
+ vendorCode?: string;
367
+ vendorLogoUrl?: string;
368
+ carClass?: string;
369
+ carType?: string;
370
+ transmission?: string;
371
+ airCon?: boolean;
372
+ doorsCount?: string;
373
+ price: number;
374
+ pricePerDay?: number;
375
+ currencyCode?: string;
376
+ pickupLocation: string;
377
+ dropoffLocation: string;
378
+ pickupDateTime: string;
379
+ dropoffDateTime: string;
380
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
381
+ policyMessages?: string[];
382
+ co2?: number;
383
+ }
384
+ export interface ChatCarHireResults {
385
+ cards: ChatCarHireResultCard[];
386
+ searchHeader: string;
387
+ parameters: ChatSearchParameters;
388
+ }
389
+ export interface ChatTaxiResultCard {
390
+ index: number;
391
+ supplierName: string;
392
+ vehicleType: string;
393
+ price: number;
394
+ currencyCode: string;
395
+ departs: string;
396
+ fromLocation: string;
397
+ toLocation: string;
398
+ tripDistanceMetres?: number;
399
+ tripDurationSeconds?: number;
400
+ policyStatus: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
401
+ policyMessages?: string[];
402
+ co2?: number;
403
+ }
404
+ export interface ChatTaxiResults {
405
+ cards: ChatTaxiResultCard[];
406
+ searchHeader: string;
407
+ parameters: ChatSearchParameters;
408
+ }
283
409
  export interface ChatEurostarFare {
284
410
  class: string;
285
411
  price: number;
@@ -302,10 +428,77 @@ export interface ChatEurostarResults {
302
428
  isReturn: boolean;
303
429
  parameters: ChatSearchParameters;
304
430
  }
431
+ /** One service leg within an upcoming trip (flight/rail/hotel/etc.). */
432
+ export interface ChatUpcomingTripLeg {
433
+ serviceType: string;
434
+ status: string;
435
+ pnrLocator: string | null;
436
+ supplierReference: string | null;
437
+ outboundDate: string | null;
438
+ inboundDate: string | null;
439
+ leadPassenger: string | null;
440
+ detail: unknown;
441
+ }
442
+ /** A single upcoming trip (basket) shown in a "show my trips" reply. */
443
+ export interface ChatUpcomingTrip {
444
+ basketId: string;
445
+ reference: string;
446
+ title: string | null;
447
+ status: string;
448
+ serviceTypes: string[];
449
+ earliestTravelDate: string | null;
450
+ items: ChatUpcomingTripLeg[];
451
+ }
452
+ export interface ChatLoungeResultCard {
453
+ index: number;
454
+ date: string;
455
+ name: string;
456
+ airport: string;
457
+ terminal?: string;
458
+ price: number;
459
+ currency: string;
460
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
461
+ policyMessages?: string[];
462
+ isPreferred: boolean;
463
+ unavailable: boolean;
464
+ unavailableMessage?: string;
465
+ openTime?: string;
466
+ closeTime?: string;
467
+ }
468
+ export interface ChatLoungeResults {
469
+ cards: ChatLoungeResultCard[];
470
+ searchHeader: string;
471
+ parameters: ChatSearchParameters;
472
+ }
305
473
  export interface ChatSuggestion {
306
- type: 'search_action' | 'select_action';
474
+ type: 'search_action' | 'select_action' | 'redirect_action';
307
475
  label: string;
308
- action: 'FILL_FORM' | 'FILL_AND_SEARCH' | 'SELECT_RESULT';
476
+ action: 'FILL_FORM' | 'FILL_AND_SEARCH' | 'SELECT_RESULT' | 'REDIRECT_TO_MY_BOOKINGS';
477
+ params?: {
478
+ statuses?: string[];
479
+ fromDate?: string;
480
+ travelDateFrom?: string;
481
+ travelDateTo?: string;
482
+ traveller?: string;
483
+ serviceTypes?: string[];
484
+ };
485
+ }
486
+ /**
487
+ * Filters handed off from the chat widget's "View My Bookings" button to the
488
+ * My Bookings screen. The explicit `statuses` / `travelDateFrom` /
489
+ * `travelDateTo` / `traveller` / `serviceTypes` fields let My Bookings
490
+ * reproduce the exact set the chatbot displayed; legacy callers may instead
491
+ * pass `departureDate` / `fromDate`, in which case My Bookings falls back to
492
+ * its default window.
493
+ */
494
+ export interface MyBookingsBaseParams {
495
+ statuses?: string[];
496
+ travelDateFrom?: string;
497
+ travelDateTo?: string;
498
+ traveller?: string;
499
+ fromDate?: string;
500
+ departureDate?: string;
501
+ serviceTypes?: string[];
309
502
  }
310
503
  export interface ChatRequest {
311
504
  message: string;
@@ -323,7 +516,7 @@ export interface ChatResponse {
323
516
  selectedIndex?: number;
324
517
  returnSelectedIndex?: number;
325
518
  alternativeIndex?: number;
326
- action?: 'search' | 'select' | 'navigate';
519
+ action?: 'search' | 'select' | 'navigate' | 'sort_results';
327
520
  riskFlag?: IRiskFlag | null;
328
521
  }
329
522
  export interface IRiskFlag {
@@ -331,6 +524,10 @@ export interface IRiskFlag {
331
524
  countryCode: string;
332
525
  breaking: boolean;
333
526
  }
527
+ export interface ChatDepotChoice {
528
+ index: number;
529
+ label: string;
530
+ }
334
531
  export type ChatMessageRole = 'user' | 'assistant';
335
532
  export interface ChatMessage {
336
533
  id: string;
@@ -344,20 +541,41 @@ export interface ChatMessage {
344
541
  selectedIndex?: number;
345
542
  returnSelectedIndex?: number;
346
543
  alternativeIndex?: number;
347
- action?: 'search' | 'select' | 'navigate';
544
+ action?: 'search' | 'select' | 'navigate' | 'sort_results';
348
545
  riskFlag?: IRiskFlag | null;
349
546
  railResults?: ChatRailResults;
350
547
  flightResults?: ChatFlightResults;
351
548
  hotelResults?: ChatHotelResults;
549
+ carHireResults?: ChatCarHireResults;
352
550
  eurostarResults?: ChatEurostarResults;
551
+ upcomingBookings?: ChatUpcomingTrip[];
552
+ hasMoreBookings?: boolean;
553
+ taxiResults?: ChatTaxiResults;
554
+ loungeResults?: ChatLoungeResults;
353
555
  searchResults?: CondensedResult[];
354
556
  searchHeader?: string;
557
+ depotChoices?: ChatDepotChoice[];
355
558
  }
559
+ export type ChatbotFlightCabinClass = 'Economy' | 'PremiumEconomy' | 'Business' | 'First';
356
560
  export interface UserCapabilities {
357
561
  isCrown: boolean;
358
562
  isAgent: boolean;
359
563
  uiConfigs: {
360
564
  hideHotelSearchOptions: boolean;
565
+ /** Cabin classes the user may search/book. Empty/absent = all allowed. */
566
+ allowedFlightCabins?: ChatbotFlightCabinClass[];
567
+ /** Whether the account can search "Any"/all cabin classes at once. When
568
+ * false the user must search a specific cabin (the form hides "Any"). */
569
+ flightAnyCabinAllowed?: boolean;
570
+ /** Whether multi-city flight itineraries are enabled for this account. */
571
+ flightMultiCityEnabled?: boolean;
572
+ /** Max legs allowed in a multi-city itinerary, when enabled. */
573
+ flightMultiCityMaxLegs?: number;
574
+ /** When true, routing via a specific transit airport is hidden. */
575
+ hideFlightVia?: boolean;
576
+ /** Minimum time-flexibility window (± hours) the account enforces. */
577
+ flightMinTimeFlexibilityHours?: number;
578
+ hideCarHireOptions?: boolean;
361
579
  };
362
580
  }
363
581
  /**
@@ -380,6 +598,12 @@ export interface ChatbotTravelHandler {
380
598
  readonly travelType: ChatSearchParameters['travelType'];
381
599
  /** Populate search state and (if requested) run the search. */
382
600
  handle(parameters: ChatSearchParameters, autoSearch: boolean): Promise<void>;
601
+ /**
602
+ * Re-rank the results already cached in the search session (no new backend
603
+ * search) and re-render the result cards for the new preference. Optional —
604
+ * only handlers that keep a re-rankable cached set implement it.
605
+ */
606
+ resort?(parameters: ChatSearchParameters): Promise<void>;
383
607
  }
384
608
  /**
385
609
  * Source of the feedback signal — matches the values accepted by the
@@ -85,6 +85,7 @@ export interface Return {
85
85
  isSplit?: boolean;
86
86
  fares?: RailBasketDetailFare[];
87
87
  composition?: RailSearchComposition[];
88
+ dualInbound?: boolean;
88
89
  }
89
90
  export interface RailBasketDetailFare {
90
91
  id: string;
@@ -1,5 +1,5 @@
1
1
  import { Socket } from 'socket.io-client';
2
- import { BotFaq, ChatConversationState, ChatFeedbackAck, ChatFeedbackExtras, ChatFeedbackSource, ChatMessage, ChatResponse, ChatSearchParameters, ChatTokenEvent, ChatToolEvent, CondensedResult, IRiskFlag, UserCapabilities } from '../interfaces/chatbot.types';
2
+ import { BotFaq, ChatConversationState, ChatFeedbackAck, ChatFeedbackExtras, ChatFeedbackSource, ChatMessage, ChatResponse, ChatSearchParameters, ChatTokenEvent, ChatToolEvent, ChatUpcomingTrip, CondensedResult, IRiskFlag, MyBookingsBaseParams, UserCapabilities } from '../interfaces/chatbot.types';
3
3
  export interface ChatWsResponse {
4
4
  sessionId: string;
5
5
  message: string;
@@ -14,6 +14,8 @@ export interface ChatWsResponse {
14
14
  returnSelectedIndex?: number;
15
15
  alternativeIndex?: number;
16
16
  action?: ChatResponse['action'];
17
+ upcomingBookings?: ChatUpcomingTrip[];
18
+ hasMoreBookings?: boolean;
17
19
  metadata?: {
18
20
  confidence?: number;
19
21
  vectorContext?: unknown;
@@ -42,8 +44,8 @@ export declare abstract class BaseChatbotService {
42
44
  protected messages: ChatMessage[];
43
45
  protected loading: boolean;
44
46
  private myBookingsBaseParams;
45
- getMyBookingsBaseParams(): any;
46
- setMyBookingsBaseParams(newParams: any): void;
47
+ getMyBookingsBaseParams(): MyBookingsBaseParams | null;
48
+ setMyBookingsBaseParams(newParams: MyBookingsBaseParams | null): void;
47
49
  /** Base URL of the request-handler (the GraphQL `requestURL` from env). */
48
50
  protected abstract getRequestUrl(): string | null;
49
51
  /** JWT to use for socket.io auth. Return null to abort connect. */
@@ -90,12 +92,20 @@ export declare abstract class BaseChatbotService {
90
92
  * Subclasses may return undefined when capabilities aren't applicable.
91
93
  */
92
94
  protected getUserCapabilities(): UserCapabilities | undefined;
95
+ protected getUserFirstName(): string | undefined;
93
96
  /**
94
97
  * Source tag included in chat:feedback emits. Derived from getSource()
95
98
  * (web → 'OBT', mobile → 'Mobile'); subclasses may override to send
96
99
  * 'Portal', 'App', etc.
97
100
  */
98
101
  protected getFeedbackSource(): ChatFeedbackSource;
102
+ /**
103
+ * Called after the user message is added to the UI but before it is emitted
104
+ * to the socket. Return `true` to short-circuit the emit (the message stays
105
+ * in the UI but the agent never sees it). Used by the Angular host to handle
106
+ * depot-selection replies locally without a round-trip to the AI agent.
107
+ */
108
+ protected beforeEmit(_text: string): Promise<boolean>;
99
109
  connect(): void;
100
110
  disconnect(): void;
101
111
  sendMessage(text: string): Promise<void>;
@@ -125,6 +135,8 @@ export declare abstract class BaseChatbotService {
125
135
  protected addAssistantMessage(text: string): void;
126
136
  /** Patch the most recent assistant message in-place (e.g. to attach rail results after search). */
127
137
  protected patchLastAssistantMessage(patch: Partial<ChatMessage>): void;
138
+ /** Remove the most recent assistant message from the UI. */
139
+ protected removeLastAssistantMessage(): void;
128
140
  protected setLoading(value: boolean): void;
129
141
  protected tearDownSocket(): void;
130
142
  protected generateId(): string;
@@ -3921,7 +3921,6 @@ export type ProcessTermsPriceResult = {
3921
3921
  __typename?: 'ProcessTermsPriceResult';
3922
3922
  amount: FieldWrapper<Scalars['String']['output']>;
3923
3923
  currency: FieldWrapper<Scalars['String']['output']>;
3924
- taxItemsWithoutCode: Array<FieldWrapper<ProcessTermsTaxItem>>;
3925
3924
  };
3926
3925
  export type ProcessTermsTaxItem = {
3927
3926
  __typename?: 'ProcessTermsTaxItem';
@@ -18987,12 +18986,6 @@ export type GetProcessTermsPriceQuery = {
18987
18986
  __typename?: 'ProcessTermsPriceResult';
18988
18987
  amount: string;
18989
18988
  currency: string;
18990
- taxItemsWithoutCode: Array<{
18991
- __typename?: 'ProcessTermsTaxItem';
18992
- name: string;
18993
- amount: string;
18994
- currency: string;
18995
- }>;
18996
18989
  };
18997
18990
  };
18998
18991
  export type GetRailLiveDeparturesQueryVariables = Exact<{
@@ -37432,7 +37425,6 @@ export declare namespace GetProcessTermsPrice {
37432
37425
  type Variables = GetProcessTermsPriceQueryVariables;
37433
37426
  type Query = GetProcessTermsPriceQuery;
37434
37427
  type GetProcessTermsPrice = GetProcessTermsPriceQuery['getProcessTermsPrice'];
37435
- type TaxItemsWithoutCode = GetProcessTermsPriceQuery['getProcessTermsPrice']['taxItemsWithoutCode'][number];
37436
37428
  }
37437
37429
  export declare namespace GetRailLiveDepartures {
37438
37430
  type Variables = GetRailLiveDeparturesQueryVariables;