@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.
- package/angular/lib/vendor/services/chatbot-eurostar-search.service.d.ts +38 -0
- package/angular/lib/vendor/services/chatbot-flight-search.service.d.ts +100 -0
- package/angular/lib/vendor/services/chatbot-hotel-search.service.d.ts +32 -0
- package/angular/lib/vendor/services/chatbot-rail-search.service.d.ts +53 -0
- package/angular/lib/vendor/services/chatbot-search-dispatcher.service.d.ts +36 -0
- package/angular/lib/vendor/services/chatbot.service.d.ts +72 -0
- package/angular/lib/vendor/services/result-aware.service.d.ts +68 -0
- package/angular/lib/vendor/types/graphql.angular.types.d.ts +12 -0
- package/angular/services.d.ts +7 -0
- package/base/interfaces.d.ts +2 -0
- package/base/lib/vendor/interfaces/chatbot.types.d.ts +438 -0
- package/base/lib/vendor/services/chatbot.service.d.ts +145 -0
- package/base/lib/vendor/types/graphql.types.d.ts +12 -0
- package/base/services.d.ts +1 -0
- package/fesm2022/sabstravtech-obtservices-angular.mjs +2903 -4
- package/fesm2022/sabstravtech-obtservices-angular.mjs.map +1 -1
- package/fesm2022/sabstravtech-obtservices-base.mjs +356 -7
- package/fesm2022/sabstravtech-obtservices-base.mjs.map +1 -1
- package/package.json +3 -2
|
@@ -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;
|
package/base/services.d.ts
CHANGED
|
@@ -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';
|