@sabstravtech/obtservices 0.2.2605201100 → 0.2.2606091200

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.
@@ -0,0 +1,438 @@
1
+ export type ChatConversationState = 'GREETING' | 'COLLECTING_PARAMS' | 'PARAMS_COMPLETE' | 'SEARCHING' | 'RESULTS_READY' | 'HANDED_OFF' | 'SELECTING_RESULT' | 'BLOCKED';
2
+ /** A curated FAQ shown in the chat widget's browse-and-select view (no AI). */
3
+ export interface BotFaq {
4
+ id: number;
5
+ question: string;
6
+ answer: string;
7
+ }
8
+ export interface CondensedResult {
9
+ index: number;
10
+ airline?: string;
11
+ operator?: string;
12
+ depart: string;
13
+ arrive: string;
14
+ stops: number;
15
+ duration: string;
16
+ price: number;
17
+ cabin?: string;
18
+ class?: string;
19
+ co2?: number;
20
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
21
+ policyMessages?: string[];
22
+ from?: string;
23
+ to?: string;
24
+ flightNumbers?: string;
25
+ fares?: {
26
+ cabin: string;
27
+ price: number;
28
+ bags: number;
29
+ }[];
30
+ inbound?: {
31
+ depart: string;
32
+ arrive: string;
33
+ stops: number;
34
+ duration: string;
35
+ flightNumbers?: string;
36
+ };
37
+ returnOptions?: {
38
+ index: number;
39
+ depart: string;
40
+ arrive: string;
41
+ stops: number;
42
+ duration: string;
43
+ price: number;
44
+ operator?: string;
45
+ co2?: number;
46
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
47
+ }[];
48
+ singleOrReturn?: string;
49
+ name?: string;
50
+ address?: string;
51
+ rating?: number;
52
+ distance?: number;
53
+ distanceUnit?: string;
54
+ pricePerNight?: number;
55
+ }
56
+ /** One leg of a multi-city flight itinerary, as supplied to chatbot flight search. */
57
+ export interface ChatFlightSearchLeg {
58
+ departure: string;
59
+ arrival: string;
60
+ departureCode?: string;
61
+ arrivalCode?: string;
62
+ /** Travel date for this leg in YYYY-MM-DD format. */
63
+ date: string;
64
+ /** Optional preferred time in HH:mm. */
65
+ time?: string;
66
+ /** Optional Depart/Arrive criterion for this leg. */
67
+ timeCriteria?: 'Depart' | 'Arrive';
68
+ }
69
+ export interface ChatSearchParameters {
70
+ travelType: 'flight' | 'rail' | 'hotel' | 'eurostar' | 'taxi';
71
+ departure: string;
72
+ arrival: string;
73
+ departureCode?: string;
74
+ arrivalCode?: string;
75
+ departureDate: string;
76
+ departureTime?: string;
77
+ returnDate?: string;
78
+ returnTime?: string;
79
+ passengers: number;
80
+ /**
81
+ * Flight multi-city legs. When set with 2+ entries the search runs as
82
+ * multi-city (the top-level departure/arrival/date describe the first leg
83
+ * for back-compat). Each entry is one segment of the itinerary.
84
+ */
85
+ legs?: ChatFlightSearchLeg[];
86
+ /** Optional explicit journey type — usually inferred from legs/returnDate. */
87
+ journeyType?: 'single' | 'return' | 'multiCity';
88
+ rooms?: number;
89
+ hotelName?: string;
90
+ hotelChain?: string;
91
+ distance?: number;
92
+ preferredOnly?: boolean;
93
+ locationType?: 'address' | 'office' | 'shortlist' | 'airport' | 'trainstation';
94
+ crownRatesOnly?: boolean;
95
+ propertyNumber?: string;
96
+ country?: string;
97
+ cabinClass?: string;
98
+ maxConnections?: number;
99
+ outboundTimeCriteria?: 'Depart' | 'Arrive';
100
+ returnTimeCriteria?: 'Depart' | 'Arrive';
101
+ railClass?: 'Standard' | 'First' | 'All';
102
+ viaStation?: string;
103
+ viaCode?: string;
104
+ isAirportExpress?: boolean;
105
+ airportExpressRoute?: string;
106
+ children?: number;
107
+ /** Railcard codes to apply to this search (e.g. "YNG", "SRN", "FAM"). */
108
+ railcards?: string[];
109
+ airline?: string;
110
+ airlineCode?: string;
111
+ /** Sort field — values vary by travel type (flight: cheapest/fastest/shortest; hotel: cheapest/distance/preferred/name). */
112
+ sortType?: 'cheapest' | 'fastest' | 'shortest' | 'distance' | 'preferred' | 'name';
113
+ adults?: number;
114
+ infants?: number;
115
+ includeNearbyAirports?: boolean;
116
+ timeFlexibility?: number;
117
+ refundableOnly?: boolean;
118
+ via?: string;
119
+ vehicleType?: string;
120
+ pickupTerminal?: string;
121
+ pickupFlightNumber?: string;
122
+ dropoffTerminal?: string;
123
+ dropoffFlightNumber?: string;
124
+ }
125
+ export interface ChatRailFareTicket {
126
+ type: string;
127
+ classOfService?: string;
128
+ price: number;
129
+ currency: string;
130
+ /** Identifier needed to open the View Conditions dialog */
131
+ fareHash?: string;
132
+ /** Section the fare came from (e.g. singleJourneyFares) — needed to find the raw fare */
133
+ section?: string;
134
+ /** True if this ticket belongs to the inbound/return leg */
135
+ isReturnLeg?: boolean;
136
+ /** Index of the journey within rawResults / railReturnJourneys */
137
+ journeyIndex?: number;
138
+ }
139
+ export interface ChatRailFareSummary {
140
+ /** Cheapest single/one-way fare for this leg */
141
+ singlePrice?: number;
142
+ /** Cheapest return fare available (outbound only; absent for inbound cards) */
143
+ returnPrice?: number;
144
+ currency: string;
145
+ /** Full ticket list shown when a fare section is clicked, sorted cheapest first */
146
+ singleTickets?: ChatRailFareTicket[];
147
+ returnTickets?: ChatRailFareTicket[];
148
+ }
149
+ export interface ChatRailResultCard {
150
+ index: number;
151
+ departDate: string;
152
+ departTime: string;
153
+ arriveTime: string;
154
+ from: string;
155
+ to: string;
156
+ route: string;
157
+ duration: string;
158
+ changes: number;
159
+ fromPrice: number;
160
+ currency: string;
161
+ operator: string;
162
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
163
+ /** Fare breakdown shown when the card is expanded */
164
+ fares?: ChatRailFareSummary;
165
+ }
166
+ export interface ChatRailResults {
167
+ outbound: ChatRailResultCard[];
168
+ inbound?: ChatRailResultCard[];
169
+ isReturn: boolean;
170
+ parameters: ChatSearchParameters;
171
+ }
172
+ export interface ChatFlightLeg {
173
+ /** Departure airport code (e.g. "LHR") */
174
+ fromCode: string;
175
+ /** Departure airport display name */
176
+ fromName?: string;
177
+ /** Arrival airport code (e.g. "AMS") */
178
+ toCode: string;
179
+ /** Arrival airport display name */
180
+ toName?: string;
181
+ /** Date label e.g. "Wed 10 Jun 2026" */
182
+ departDate: string;
183
+ /** Time label e.g. "09:15" */
184
+ departTime: string;
185
+ /** Time label e.g. "11:42" */
186
+ arriveTime: string;
187
+ /** Duration label e.g. "2h 27m" */
188
+ duration: string;
189
+ /** 0 = direct, 1, 2+ */
190
+ stops: number;
191
+ /** Flight numbers joined e.g. "BA123/BA456" */
192
+ flightNumbers: string;
193
+ }
194
+ export interface ChatFlightFareTicket {
195
+ /** Display label, e.g. "Economy Saver", "Business Flex" */
196
+ type: string;
197
+ /** Cabin class group (Economy / PremiumEconomy / Business / First) */
198
+ cabin?: string;
199
+ /** Fare-brand name when present */
200
+ brand?: string;
201
+ price: number;
202
+ currency: string;
203
+ /** Index back into the underlying journeys array for select / navigate use */
204
+ journeyIndex?: number;
205
+ }
206
+ /** Flight fare breakdown for the expandable panel on a chat flight card. */
207
+ export interface ChatFlightFareBreakdown {
208
+ /** All bookable fares for the same outbound (+ inbound) flights, sorted cheapest first. */
209
+ tickets: ChatFlightFareTicket[];
210
+ currency: string;
211
+ }
212
+ export interface ChatFlightResultCard {
213
+ index: number;
214
+ /** Airline display name (cheapest fare's marketing carrier) */
215
+ airline: string;
216
+ /** Airline IATA code, used to derive a logo url */
217
+ airlineCode?: string;
218
+ /** Outbound leg (always present for single/return; first leg for multi-city) */
219
+ outbound: ChatFlightLeg;
220
+ /** Inbound leg (present for return itineraries) */
221
+ inbound?: ChatFlightLeg;
222
+ /**
223
+ * Full list of legs for multi-city itineraries. When set the card should
224
+ * render these stacked instead of outbound/inbound. `outbound` still mirrors
225
+ * `legs[0]` for back-compat with consumers that only read outbound.
226
+ */
227
+ legs?: ChatFlightLeg[];
228
+ /** Cheapest fare price for the whole itinerary */
229
+ fromPrice: number;
230
+ currency: string;
231
+ /** Cabin class label e.g. "Economy" */
232
+ cabin: string;
233
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
234
+ /** Expandable fare-options panel data (cabin/brand variants for the same flights). */
235
+ fares?: ChatFlightFareBreakdown;
236
+ }
237
+ export interface ChatFlightResults {
238
+ outbound: ChatFlightResultCard[];
239
+ /**
240
+ * Separate inbound cards when the backend returned dual-singles (i.e. the
241
+ * outbound and inbound legs are priced + selectable independently). For
242
+ * combined-return itineraries the inbound info lives inside each outbound
243
+ * card's `.inbound` and this array is left empty.
244
+ */
245
+ inbound?: ChatFlightResultCard[];
246
+ isReturn: boolean;
247
+ /** True when the search was a multi-city (3+ leg) itinerary. */
248
+ isMultiCity?: boolean;
249
+ parameters: ChatSearchParameters;
250
+ /** How the results were sorted, used in the summary text */
251
+ sort?: 'cheapest' | 'fastest' | 'shortest';
252
+ }
253
+ export interface ChatHotelRoom {
254
+ roomId: string;
255
+ description: string;
256
+ total: number;
257
+ prpn: number;
258
+ currencyCode: string;
259
+ unavailable: boolean;
260
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
261
+ }
262
+ export interface ChatHotelResultCard {
263
+ index: number;
264
+ name: string;
265
+ address: string;
266
+ rating: number;
267
+ distance: number;
268
+ distanceUnit: string;
269
+ price: number;
270
+ pricePerNight: number;
271
+ dateRange: string;
272
+ policyStatus?: 'IN_POLICY' | 'ALLOW_WITH_REASON' | 'UNAVAILABLE';
273
+ policyMessages?: string[];
274
+ co2?: number;
275
+ currencyCode?: string;
276
+ rooms?: ChatHotelRoom[];
277
+ }
278
+ export interface ChatHotelResults {
279
+ cards: ChatHotelResultCard[];
280
+ searchHeader: string;
281
+ parameters: ChatSearchParameters;
282
+ }
283
+ export interface ChatEurostarFare {
284
+ class: string;
285
+ price: number;
286
+ currency: string;
287
+ policyStatus: CondensedResult['policyStatus'];
288
+ policyMessages: string[];
289
+ unavailable: boolean;
290
+ }
291
+ export interface ChatEurostarResultCard {
292
+ index: number;
293
+ timeDeparture: string;
294
+ timeArrival: string;
295
+ duration: string;
296
+ fares: ChatEurostarFare[];
297
+ co2PerPassenger: number;
298
+ }
299
+ export interface ChatEurostarResults {
300
+ outbound: ChatEurostarResultCard[];
301
+ inbound?: ChatEurostarResultCard[];
302
+ isReturn: boolean;
303
+ parameters: ChatSearchParameters;
304
+ }
305
+ export interface ChatSuggestion {
306
+ type: 'search_action' | 'select_action';
307
+ label: string;
308
+ action: 'FILL_FORM' | 'FILL_AND_SEARCH' | 'SELECT_RESULT';
309
+ }
310
+ export interface ChatRequest {
311
+ message: string;
312
+ sessionId?: string;
313
+ searchResults?: CondensedResult[];
314
+ }
315
+ export interface ChatResponse {
316
+ sessionId: string;
317
+ text: string;
318
+ intent: string | null;
319
+ parameters: ChatSearchParameters | null;
320
+ policyHints: string[];
321
+ suggestions: ChatSuggestion[];
322
+ state: ChatConversationState;
323
+ selectedIndex?: number;
324
+ returnSelectedIndex?: number;
325
+ alternativeIndex?: number;
326
+ action?: 'search' | 'select' | 'navigate';
327
+ riskFlag?: IRiskFlag | null;
328
+ }
329
+ export interface IRiskFlag {
330
+ level: string;
331
+ countryCode: string;
332
+ breaking: boolean;
333
+ }
334
+ export type ChatMessageRole = 'user' | 'assistant';
335
+ export interface ChatMessage {
336
+ id: string;
337
+ role: ChatMessageRole;
338
+ text: string;
339
+ timestamp: Date;
340
+ parameters?: ChatSearchParameters | null;
341
+ policyHints?: string[];
342
+ suggestions?: ChatSuggestion[];
343
+ state?: ChatConversationState;
344
+ selectedIndex?: number;
345
+ returnSelectedIndex?: number;
346
+ alternativeIndex?: number;
347
+ action?: 'search' | 'select' | 'navigate';
348
+ riskFlag?: IRiskFlag | null;
349
+ railResults?: ChatRailResults;
350
+ flightResults?: ChatFlightResults;
351
+ hotelResults?: ChatHotelResults;
352
+ eurostarResults?: ChatEurostarResults;
353
+ searchResults?: CondensedResult[];
354
+ searchHeader?: string;
355
+ }
356
+ export interface UserCapabilities {
357
+ isCrown: boolean;
358
+ isAgent: boolean;
359
+ uiConfigs: {
360
+ hideHotelSearchOptions: boolean;
361
+ };
362
+ }
363
+ /**
364
+ * Travel-type-specific chatbot search handler. Implement one of these per
365
+ * travel type (rail, flight, hotel, eurostar, …) and register the service in
366
+ * `ChatbotSearchDispatcherService`'s constructor.
367
+ *
368
+ * The handler is responsible for:
369
+ * 1. Populating the corresponding `EnterpriseSearchService.searches[ServiceType.*]`
370
+ * state from the chatbot parameters (the same fields the search form would
371
+ * populate via two-way binding).
372
+ * 2. If `autoSearch` is true, kicking off the search and capturing results so
373
+ * the chatbot can render its in-chat cards.
374
+ *
375
+ * Handlers run independently of any component being mounted so the chatbot
376
+ * works from any page in the consuming app.
377
+ */
378
+ export interface ChatbotTravelHandler {
379
+ /** Travel type this handler accepts (matches `ChatSearchParameters.travelType`). */
380
+ readonly travelType: ChatSearchParameters['travelType'];
381
+ /** Populate search state and (if requested) run the search. */
382
+ handle(parameters: ChatSearchParameters, autoSearch: boolean): Promise<void>;
383
+ }
384
+ /**
385
+ * Source of the feedback signal — matches the values accepted by the
386
+ * request-handler chat:feedback gateway.
387
+ */
388
+ export type ChatFeedbackSource = 'OBT' | 'App' | 'Portal' | 'Mobile' | 'Other';
389
+ /**
390
+ * Reason chips offered after a positive (thumbs-up) rating. Shared between
391
+ * the web (lu-frontend) and mobile (new-ent-mobile-app) chat widgets so the
392
+ * recorded `chat_feedback.reason` strings stay consistent across surfaces.
393
+ */
394
+ export declare const POSITIVE_FEEDBACK_REASONS: readonly string[];
395
+ /** Reason chips offered after a negative (thumbs-down) rating. */
396
+ export declare const NEGATIVE_FEEDBACK_REASONS: readonly string[];
397
+ /** Convenience helper: returns the reason set for a given rating. */
398
+ export declare function feedbackReasonsForRating(rating: 'up' | 'down' | undefined): readonly string[];
399
+ /** Incremental LLM token chunk emitted while an assistant message is being generated. */
400
+ export interface ChatTokenEvent {
401
+ sessionId: string;
402
+ token: string;
403
+ agent?: string;
404
+ }
405
+ /** Tool execution lifecycle event emitted during a turn. */
406
+ export interface ChatToolEvent {
407
+ sessionId: string;
408
+ toolEvent: string;
409
+ name: string;
410
+ }
411
+ /** Single transcript entry attached to a `chat:feedback` emit. */
412
+ export interface ChatFeedbackTranscriptEntry {
413
+ id?: string;
414
+ role: 'user' | 'assistant';
415
+ text: string;
416
+ timestamp?: string;
417
+ }
418
+ /**
419
+ * Optional context attached to `submitFeedback()` — comment, reason chip and
420
+ * the surrounding transcript snapshot so the analytics team has enough to
421
+ * action a thumbs-down without replaying the whole session.
422
+ */
423
+ export interface ChatFeedbackExtras {
424
+ comment?: string;
425
+ reason?: string;
426
+ source?: ChatFeedbackSource;
427
+ userQuestion?: string;
428
+ assistantResponse?: string;
429
+ transcript?: ChatFeedbackTranscriptEntry[];
430
+ }
431
+ /** Server ack for a previously emitted `chat:feedback`. */
432
+ export interface ChatFeedbackAck {
433
+ sessionId: string;
434
+ messageId?: string;
435
+ rating?: 'up' | 'down';
436
+ success: boolean;
437
+ error?: string;
438
+ }
@@ -0,0 +1,145 @@
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';
3
+ export interface ChatWsResponse {
4
+ sessionId: string;
5
+ message: string;
6
+ timestamp?: string;
7
+ parameters?: ChatSearchParameters | null;
8
+ results?: CondensedResult[];
9
+ suggestions?: ChatResponse['suggestions'];
10
+ actions?: ChatResponse['suggestions'];
11
+ policyHints?: string[];
12
+ state?: string;
13
+ selectedIndex?: number;
14
+ returnSelectedIndex?: number;
15
+ alternativeIndex?: number;
16
+ action?: ChatResponse['action'];
17
+ metadata?: {
18
+ confidence?: number;
19
+ vectorContext?: unknown;
20
+ interrupted?: boolean;
21
+ interruptData?: unknown;
22
+ };
23
+ riskFlag?: IRiskFlag;
24
+ }
25
+ /**
26
+ * Platform-agnostic chat-over-websocket service.
27
+ *
28
+ * Owns the socket.io connection, session/message/loading state, response
29
+ * mapping, and HITL approval resume flow. Subclasses adapt it to a host
30
+ * framework by implementing the platform hooks below.
31
+ *
32
+ * Used by:
33
+ * - Angular `ChatbotService` (obtservices/angular) — pushes updates via RxJS
34
+ * subjects and delegates result-selection to `ResultAwareService`.
35
+ * - React Native `ChatbotService` (new-ent-mobile-app) — pushes updates via
36
+ * callback arrays and handles selection through chatbot-navigation.service.
37
+ */
38
+ export declare abstract class BaseChatbotService {
39
+ protected socket: Socket | null;
40
+ protected sessionId: string | null;
41
+ protected lastAssistantState: ChatConversationState | undefined;
42
+ protected messages: ChatMessage[];
43
+ protected loading: boolean;
44
+ private myBookingsBaseParams;
45
+ getMyBookingsBaseParams(): any;
46
+ setMyBookingsBaseParams(newParams: any): void;
47
+ /** Base URL of the request-handler (the GraphQL `requestURL` from env). */
48
+ protected abstract getRequestUrl(): string | null;
49
+ /** JWT to use for socket.io auth. Return null to abort connect. */
50
+ protected abstract getAuthToken(): string | null;
51
+ /** Push the latest messages array to the UI. */
52
+ protected abstract notifyMessages(messages: ChatMessage[]): void;
53
+ /** Push the loading flag to the UI. */
54
+ protected abstract notifyLoading(loading: boolean): void;
55
+ /** Push parsed search parameters to the host's search form. */
56
+ protected abstract notifyFillForm(parameters: ChatSearchParameters, autoSearch: boolean): void;
57
+ /** Notify the host that a risk flag was received. */
58
+ protected abstract notifyRiskFlag(flag: IRiskFlag): void;
59
+ /**
60
+ * Push the TMC's curated FAQ list (browse-and-select view) to the UI.
61
+ * Default no-op so platforms that don't surface the FAQ view (e.g. mobile)
62
+ * need not override it; the Angular host overrides to feed `faqs$`.
63
+ */
64
+ protected notifyFaqs(_faqs: BotFaq[]): void;
65
+ /**
66
+ * ENT-16247 — incoming token chunk for the in-flight assistant message.
67
+ * Default no-op; hosts that render token-by-token (web, mobile) override
68
+ * to fan out to their UI layer.
69
+ */
70
+ protected notifyToken(_event: ChatTokenEvent): void;
71
+ /** ENT-16247 — tool execution lifecycle event. Default no-op. */
72
+ protected notifyTool(_event: ChatToolEvent): void;
73
+ /** ENT-16247 — server ack for a previously emitted `chat:feedback`. Default no-op. */
74
+ protected notifyFeedbackAck(_ack: ChatFeedbackAck): void;
75
+ /** True when search results are in scope for selection. */
76
+ protected abstract hasResults(): boolean;
77
+ /** Returns the current search results (only called when hasResults()). */
78
+ protected abstract getCondensedResults(): CondensedResult[];
79
+ /**
80
+ * Selection requested by the assistant (action === 'select').
81
+ * Angular delegates to ResultAwareService; mobile is a no-op
82
+ * (chatbot-navigation handles selection on its own).
83
+ */
84
+ protected abstract executeSelection(selectedIndex: number, returnSelectedIndex?: number): Promise<void>;
85
+ /** Source tag included in the chat:message payload (e.g. 'web' | 'mobile'). */
86
+ protected abstract getSource(): string;
87
+ /**
88
+ * Optional user capabilities forwarded to the backend so the assistant can
89
+ * tailor responses (e.g. hide hotel-search options for restricted users).
90
+ * Subclasses may return undefined when capabilities aren't applicable.
91
+ */
92
+ protected getUserCapabilities(): UserCapabilities | undefined;
93
+ /**
94
+ * Source tag included in chat:feedback emits. Derived from getSource()
95
+ * (web → 'OBT', mobile → 'Mobile'); subclasses may override to send
96
+ * 'Portal', 'App', etc.
97
+ */
98
+ protected getFeedbackSource(): ChatFeedbackSource;
99
+ connect(): void;
100
+ disconnect(): void;
101
+ sendMessage(text: string): Promise<void>;
102
+ resume(approved: boolean): void;
103
+ /**
104
+ * ENT-16247 — submit thumbs up/down feedback for an assistant message.
105
+ * Reuses the already-authenticated /chat socket and the cached sessionId
106
+ * (refreshed on every chat:token / chat:response) so callers only need
107
+ * to pass the messageId + rating. Returns false if the socket isn't
108
+ * connected or there's no session yet (no-op rather than throw, to keep
109
+ * UI fire-and-forget friendly). The server replies on `chat:feedback-ack`,
110
+ * surfaced through `notifyFeedbackAck` to host-specific subjects/listeners.
111
+ */
112
+ submitFeedback(messageId: string, rating: 'up' | 'down', extras?: ChatFeedbackExtras): boolean;
113
+ /**
114
+ * Request the TMC's curated FAQ list for the browse-and-select view. Connects
115
+ * if needed; the list arrives via the `chat:faqs-response` handler → notifyFaqs.
116
+ */
117
+ requestFaqs(): void;
118
+ fillForm(parameters: ChatSearchParameters): void;
119
+ fillAndSearch(parameters: ChatSearchParameters): void;
120
+ clearSession(): void;
121
+ protected handleResponse(env: ChatWsResponse): void;
122
+ protected mapState(state: string | undefined): ChatConversationState | undefined;
123
+ protected shouldAttachSearchResults(): boolean;
124
+ protected addMessage(message: ChatMessage): void;
125
+ protected addAssistantMessage(text: string): void;
126
+ /** Patch the most recent assistant message in-place (e.g. to attach rail results after search). */
127
+ protected patchLastAssistantMessage(patch: Partial<ChatMessage>): void;
128
+ protected setLoading(value: boolean): void;
129
+ protected tearDownSocket(): void;
130
+ protected generateId(): string;
131
+ /**
132
+ * Derives socket.io connection config from the GraphQL `requestURL`.
133
+ * The request-handler base = requestURL with `/graphql` (or `/req`) stripped.
134
+ *
135
+ * Examples:
136
+ * "/graphql" → { url: "/chat", path: "/socket.io/" }
137
+ * "/rqh/graphql" → { url: "/chat", path: "/rqh/socket.io/" }
138
+ * "http://localhost:1234/rqh/graphql" → { url: "http://localhost:1234/chat", path: "/rqh/socket.io/" }
139
+ * "https://api.example.com/req/" → { url: "https://api.example.com/chat", path: "/socket.io/" }
140
+ */
141
+ protected buildSocketConfig(requestURL: string): {
142
+ url: string;
143
+ path: string;
144
+ };
145
+ }
@@ -3921,6 +3921,7 @@ 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>>;
3924
3925
  };
3925
3926
  export type ProcessTermsTaxItem = {
3926
3927
  __typename?: 'ProcessTermsTaxItem';
@@ -5839,6 +5840,7 @@ export type User = {
5839
5840
  admin?: Maybe<FieldWrapper<Scalars['Boolean']['output']>>;
5840
5841
  agentBooker: FieldWrapper<Scalars['Boolean']['output']>;
5841
5842
  agentId?: Maybe<FieldWrapper<Scalars['String']['output']>>;
5843
+ aiTravelAssistantEnabled?: Maybe<FieldWrapper<Scalars['Boolean']['output']>>;
5842
5844
  approver: FieldWrapper<Scalars['Boolean']['output']>;
5843
5845
  authMethods: Array<FieldWrapper<Scalars['String']['output']>>;
5844
5846
  availableLanguages: Array<FieldWrapper<Language>>;
@@ -12588,6 +12590,7 @@ export type EditUserMutation = {
12588
12590
  canSeeBookingsOfOthers: boolean;
12589
12591
  becomeUser: boolean;
12590
12592
  canOverrideApproval: boolean;
12593
+ aiTravelAssistantEnabled?: boolean | null;
12591
12594
  dob?: any | null;
12592
12595
  admin?: boolean | null;
12593
12596
  companyAdmin?: boolean | null;
@@ -18984,6 +18987,12 @@ export type GetProcessTermsPriceQuery = {
18984
18987
  __typename?: 'ProcessTermsPriceResult';
18985
18988
  amount: string;
18986
18989
  currency: string;
18990
+ taxItemsWithoutCode: Array<{
18991
+ __typename?: 'ProcessTermsTaxItem';
18992
+ name: string;
18993
+ amount: string;
18994
+ currency: string;
18995
+ }>;
18987
18996
  };
18988
18997
  };
18989
18998
  export type GetRailLiveDeparturesQueryVariables = Exact<{
@@ -35881,6 +35890,7 @@ export type UserFieldsFragment = {
35881
35890
  canSeeBookingsOfOthers: boolean;
35882
35891
  becomeUser: boolean;
35883
35892
  canOverrideApproval: boolean;
35893
+ aiTravelAssistantEnabled?: boolean | null;
35884
35894
  dob?: any | null;
35885
35895
  admin?: boolean | null;
35886
35896
  companyAdmin?: boolean | null;
@@ -36158,6 +36168,7 @@ export type GetUserQuery = {
36158
36168
  canSeeBookingsOfOthers: boolean;
36159
36169
  becomeUser: boolean;
36160
36170
  canOverrideApproval: boolean;
36171
+ aiTravelAssistantEnabled?: boolean | null;
36161
36172
  dob?: any | null;
36162
36173
  admin?: boolean | null;
36163
36174
  companyAdmin?: boolean | null;
@@ -37421,6 +37432,7 @@ export declare namespace GetProcessTermsPrice {
37421
37432
  type Variables = GetProcessTermsPriceQueryVariables;
37422
37433
  type Query = GetProcessTermsPriceQuery;
37423
37434
  type GetProcessTermsPrice = GetProcessTermsPriceQuery['getProcessTermsPrice'];
37435
+ type TaxItemsWithoutCode = GetProcessTermsPriceQuery['getProcessTermsPrice']['taxItemsWithoutCode'][number];
37424
37436
  }
37425
37437
  export declare namespace GetRailLiveDepartures {
37426
37438
  type Variables = GetRailLiveDeparturesQueryVariables;
@@ -13,3 +13,4 @@ export * from './lib/vendor/services/routehappy.service';
13
13
  export * from './lib/vendor/services/requires-reason.service';
14
14
  export * from './lib/vendor/services/http-cancel.service';
15
15
  export * from './lib/vendor/services/messages.service';
16
+ export * from './lib/vendor/services/chatbot.service';