@cimulate/copilot-sdk 3.14.0 → 3.15.2

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 (39) hide show
  1. package/dist/bundle.cimulate.copilot-sdk.2fcdd90b.esm.js +2 -0
  2. package/dist/bundle.cimulate.copilot-sdk.2fcdd90b.esm.js.map +1 -0
  3. package/dist/bundle.cimulate.copilot-sdk.66c9b98c.umd.js +2 -0
  4. package/dist/bundle.cimulate.copilot-sdk.66c9b98c.umd.js.map +1 -0
  5. package/dist/bundle.cimulate.copilot-sdk.6effe8df.cjs.js +2 -0
  6. package/dist/bundle.cimulate.copilot-sdk.6effe8df.cjs.js.map +1 -0
  7. package/dist/bundle.cimulate.copilot-sdk.80c40ca6.esm.js +2 -0
  8. package/dist/bundle.cimulate.copilot-sdk.80c40ca6.esm.js.map +1 -0
  9. package/dist/bundle.cimulate.copilot-sdk.8cdab241.cjs.js +2 -0
  10. package/dist/bundle.cimulate.copilot-sdk.8cdab241.cjs.js.map +1 -0
  11. package/dist/bundle.cimulate.copilot-sdk.fe5dd664.umd.js +2 -0
  12. package/dist/bundle.cimulate.copilot-sdk.fe5dd664.umd.js.map +1 -0
  13. package/dist/index.cjs.js +1 -1
  14. package/dist/index.cjs.js.map +1 -1
  15. package/dist/index.esm.js +1 -1
  16. package/dist/index.esm.js.map +1 -1
  17. package/dist/index.umd.js +1 -1
  18. package/dist/index.umd.js.map +1 -1
  19. package/dist/types/copilot.d.ts +12 -2
  20. package/dist/types/model/AskCimSuggestionsAck.d.ts +10 -0
  21. package/dist/types/model/CopilotApiAck.d.ts +5 -1
  22. package/dist/types/model/CopilotBrowseSuggestionsAck.d.ts +10 -0
  23. package/dist/types/model/CopilotSearchSuggestionsAck.d.ts +10 -0
  24. package/dist/types/model/ProductViewSuggestionsAck.d.ts +10 -0
  25. package/dist/types/model/index.d.ts +4 -0
  26. package/package.json +5 -3
  27. package/src/copilot.ts +173 -77
  28. package/src/model/AskCimSuggestionsAck.ts +10 -0
  29. package/src/model/CopilotApiAck.ts +8 -0
  30. package/src/model/CopilotBrowseSuggestionsAck.ts +10 -0
  31. package/src/model/CopilotSearchSuggestionsAck.ts +10 -0
  32. package/src/model/ProductViewSuggestionsAck.ts +10 -0
  33. package/src/model/index.ts +4 -0
  34. package/dist/bundle.cimulate.copilot-sdk.7dbeb4d0.umd.js +0 -2
  35. package/dist/bundle.cimulate.copilot-sdk.7dbeb4d0.umd.js.map +0 -1
  36. package/dist/bundle.cimulate.copilot-sdk.a60898e7.esm.js +0 -2
  37. package/dist/bundle.cimulate.copilot-sdk.a60898e7.esm.js.map +0 -1
  38. package/dist/bundle.cimulate.copilot-sdk.ff5873e3.cjs.js +0 -2
  39. package/dist/bundle.cimulate.copilot-sdk.ff5873e3.cjs.js.map +0 -1
package/src/copilot.ts CHANGED
@@ -4,12 +4,16 @@ import deepmerge from "deepmerge";
4
4
  import type {
5
5
  AskCim,
6
6
  AskCimAck,
7
+ AskCimSuggestions,
8
+ AskCimSuggestionsAck,
7
9
  Cancel,
8
10
  CancelAck,
9
11
  CopilotAPIAck,
10
12
  ConnectAck,
11
13
  CopilotBrowse,
12
14
  CopilotBrowseAck,
15
+ CopilotBrowseSuggestions,
16
+ CopilotBrowseSuggestionsAck,
13
17
  ConnectError,
14
18
  ConversationEvents,
15
19
  CopilotAPIEvent,
@@ -17,10 +21,14 @@ import type {
17
21
  CopilotEventName,
18
22
  CopilotSearch,
19
23
  CopilotSearchAck,
24
+ CopilotSearchSuggestions,
25
+ CopilotSearchSuggestionsAck,
20
26
  FacetedNavigation,
21
27
  FacetedNavigationAck,
22
28
  ProductView,
23
29
  ProductViewAck,
30
+ ProductViewSuggestions,
31
+ ProductViewSuggestionsAck,
24
32
  ReturnedFields,
25
33
  SessionInformation,
26
34
  ConversationReset,
@@ -38,11 +46,13 @@ type ApiTokenAuth = { apiToken: string; apiKey?: never };
38
46
  interface CommonOptions {
39
47
  baseUrl: string;
40
48
  namespace?: string;
49
+ customerId?: string;
50
+ tenantId?: string;
41
51
  socketOptions?: Omit<SocketIOOptions, "withCredentials" | "parser">;
42
52
  }
43
53
 
44
54
  type CimulateCopilotOptions = (ApiKeyAuth | ApiTokenAuth) & CommonOptions;
45
- type CopilotEvents = CopilotEvent[]
55
+ type CopilotEvents = CopilotEvent[];
46
56
 
47
57
  const socketDefaults: SocketIOOptions = {
48
58
  path: "/api/v1/socket.io",
@@ -58,7 +68,7 @@ interface CopilotResult<T extends ReturnedFields, R> {
58
68
  }
59
69
 
60
70
  export default class CimulateCopilot<
61
- T extends ReturnedFields = ReturnedFields
71
+ T extends ReturnedFields = ReturnedFields,
62
72
  > {
63
73
  private socket: Socket;
64
74
  private sessionIdKey: string = "x-cimulate-copilot-session-id";
@@ -72,11 +82,14 @@ export default class CimulateCopilot<
72
82
  apiToken,
73
83
  baseUrl,
74
84
  namespace = "/copilot",
85
+ customerId,
86
+ tenantId,
75
87
  socketOptions = {},
76
88
  }: CimulateCopilotOptions) {
77
-
78
89
  if ((apiKey && apiToken) || (!apiKey && !apiToken)) {
79
- throw new Error("Provide exactly one authentication method: either 'apiKey' or 'apiToken', but not both.");
90
+ throw new Error(
91
+ "Provide exactly one authentication method: either 'apiKey' or 'apiToken', but not both.",
92
+ );
80
93
  }
81
94
 
82
95
  const socketioEndpoint = `${baseUrl}${namespace}`;
@@ -89,6 +102,14 @@ export default class CimulateCopilot<
89
102
  extraHeaders["Authorization"] = `Bearer ${apiToken}`;
90
103
  }
91
104
 
105
+ if (customerId) {
106
+ extraHeaders["x-cimulate-customer-id"] = customerId;
107
+ }
108
+
109
+ if (tenantId) {
110
+ extraHeaders["Tenant-ID"] = tenantId;
111
+ }
112
+
92
113
  const options: SocketIOOptions[] = [
93
114
  socketDefaults,
94
115
  socketOptions,
@@ -110,18 +131,20 @@ export default class CimulateCopilot<
110
131
  [this.sessionIdKey]: event.sessionId,
111
132
  };
112
133
  };
113
-
134
+
114
135
  private readonly handleDisconnect = (reason: Socket.DisconnectReason) => {
115
136
  console.warn(`[Copilot SDK] Disconnected: ${reason}`);
116
137
  if (reason !== "io client disconnect") {
117
- console.log(`[Copilot SDK] Disconnected due to ${reason}. Attempting reconnect...`);
138
+ console.log(
139
+ `[Copilot SDK] Disconnected due to ${reason}. Attempting reconnect...`,
140
+ );
118
141
  this.retryConnect();
119
142
  }
120
143
  };
121
-
144
+
122
145
  private readonly handleConnectError = (err: ConnectError) => {
123
146
  console.error(`[Copilot SDK] Connect error: ${err.message}`);
124
-
147
+
125
148
  const authErrors = ["InvalidApiKey", "InvalidToken", "BadRequest"];
126
149
 
127
150
  // Use regex to extract error type
@@ -142,10 +165,9 @@ export default class CimulateCopilot<
142
165
  this.socket.off("connect_ack", this.handleConnectAck);
143
166
  this.socket.off("disconnect", this.handleDisconnect);
144
167
  this.off("connect_error", this.handleConnectError);
145
- }
168
+ };
146
169
 
147
170
  connect() {
148
-
149
171
  if (this.reconnectTimeout) {
150
172
  clearTimeout(this.reconnectTimeout);
151
173
  this.reconnectTimeout = undefined;
@@ -154,35 +176,44 @@ export default class CimulateCopilot<
154
176
 
155
177
  // Clear old handlers to avoid duplicates
156
178
  this.offInternalHandlers();
157
-
179
+
158
180
  // Add fresh handlers
159
181
  this.on("connect_ack", this.handleConnectAck);
160
182
  this.socket.on("disconnect", this.handleDisconnect);
161
183
  this.on("connect_error", this.handleConnectError);
162
-
184
+
163
185
  // Clear old auth state
164
186
  if (this.socket.auth && this.sessionIdKey in this.socket.auth) {
165
187
  this.socket.auth = {};
166
188
  }
167
-
189
+
168
190
  this.socket.connect();
169
- }
191
+ }
170
192
 
171
193
  private retryConnect() {
172
194
  // Don't retry connect if connected or currently trying to connect
173
- if (this.socket.connected || this.socket.active || this.reconnectAttempts >= this.maxReconnectAttempts) {
195
+ if (
196
+ this.socket.connected ||
197
+ this.socket.active ||
198
+ this.reconnectAttempts >= this.maxReconnectAttempts
199
+ ) {
174
200
  return;
175
201
  }
176
-
202
+
177
203
  if (this.reconnectTimeout) {
178
204
  clearTimeout(this.reconnectTimeout);
179
205
  this.reconnectTimeout = undefined;
180
206
  }
181
207
 
182
208
  if (this.reconnectAttempts < this.maxReconnectAttempts) {
183
- const delay = Math.min(1000 * 2 ** this.reconnectAttempts, this.maxReconnectDelay);
184
- console.info(`[Copilot SDK] Retry #${this.reconnectAttempts + 1} in ${delay}ms...`);
185
-
209
+ const delay = Math.min(
210
+ 1000 * 2 ** this.reconnectAttempts,
211
+ this.maxReconnectDelay,
212
+ );
213
+ console.info(
214
+ `[Copilot SDK] Retry #${this.reconnectAttempts + 1} in ${delay}ms...`,
215
+ );
216
+
186
217
  this.reconnectTimeout = setTimeout(() => {
187
218
  if (!this.socket.connected && !this.socket.active) {
188
219
  this.reconnectAttempts++;
@@ -196,140 +227,204 @@ export default class CimulateCopilot<
196
227
 
197
228
  reconnect() {
198
229
  // Don't reconnect if connected or currently trying to connect
199
- if (this.socket.connected || this.socket.active || this.reconnectAttempts >= this.maxReconnectAttempts) {
230
+ if (
231
+ this.socket.connected ||
232
+ this.socket.active ||
233
+ this.reconnectAttempts >= this.maxReconnectAttempts
234
+ ) {
200
235
  return;
201
236
  }
202
-
237
+
203
238
  // Clear any existing scheduled reconnect to debounce
204
239
  if (this.reconnectTimeout) {
205
240
  clearTimeout(this.reconnectTimeout);
206
241
  this.reconnectTimeout = undefined;
207
242
  this.reconnectAttempts = 0;
208
243
  }
209
-
244
+
210
245
  this.socket.connect();
211
246
  }
212
247
 
213
248
  async browse(
214
- args: CopilotBrowse
249
+ args: CopilotBrowse,
215
250
  ): Promise<CopilotResult<T, CopilotBrowseAck>>;
216
251
  async browse(
217
252
  args: CopilotBrowse,
218
- callback?: (event: CopilotBrowseAck) => void
253
+ callback?: (event: CopilotBrowseAck) => void,
219
254
  ): Promise<void>;
220
255
  async browse(
221
256
  args: CopilotBrowse,
222
- callback?: (event: CopilotBrowseAck) => void
257
+ callback?: (event: CopilotBrowseAck) => void,
223
258
  ): Promise<CopilotResult<T, CopilotBrowseAck> | void> {
224
259
  return this.asyncResponse<CopilotBrowse, CopilotBrowseAck>(
225
260
  "copilot_browse",
226
261
  args,
227
- callback
262
+ callback,
228
263
  );
229
264
  }
230
265
 
266
+ async browseSuggestions(
267
+ args: CopilotBrowseSuggestions,
268
+ ): Promise<CopilotResult<T, CopilotBrowseSuggestionsAck>>;
269
+ async browseSuggestions(
270
+ args: CopilotBrowseSuggestions,
271
+ callback?: (event: CopilotBrowseSuggestionsAck) => void,
272
+ ): Promise<void>;
273
+ async browseSuggestions(
274
+ args: CopilotBrowseSuggestions,
275
+ callback?: (event: CopilotBrowseSuggestionsAck) => void,
276
+ ): Promise<CopilotResult<T, CopilotBrowseSuggestionsAck> | void> {
277
+ return this.asyncResponse<
278
+ CopilotBrowseSuggestions,
279
+ CopilotBrowseSuggestionsAck
280
+ >("copilot_browse_suggestions", args, callback);
281
+ }
231
282
 
232
283
  async search(
233
- args: CopilotSearch
284
+ args: CopilotSearch,
234
285
  ): Promise<CopilotResult<T, CopilotSearchAck>>;
235
286
  async search(
236
287
  args: CopilotSearch,
237
- callback?: (event: CopilotSearchAck) => void
288
+ callback?: (event: CopilotSearchAck) => void,
238
289
  ): Promise<void>;
239
290
  async search(
240
291
  args: CopilotSearch,
241
- callback?: (event: CopilotSearchAck) => void
292
+ callback?: (event: CopilotSearchAck) => void,
242
293
  ): Promise<CopilotResult<T, CopilotSearchAck> | void> {
243
294
  return this.asyncResponse<CopilotSearch, CopilotSearchAck>(
244
295
  "copilot_search",
245
296
  args,
246
- callback
297
+ callback,
247
298
  );
248
299
  }
249
300
 
301
+ async searchSuggestions(
302
+ args: CopilotSearchSuggestions,
303
+ ): Promise<CopilotResult<T, CopilotSearchSuggestionsAck>>;
304
+ async searchSuggestions(
305
+ args: CopilotSearchSuggestions,
306
+ callback?: (event: CopilotSearchSuggestionsAck) => void,
307
+ ): Promise<void>;
308
+ async searchSuggestions(
309
+ args: CopilotSearchSuggestions,
310
+ callback?: (event: CopilotSearchSuggestionsAck) => void,
311
+ ): Promise<CopilotResult<T, CopilotSearchSuggestionsAck> | void> {
312
+ return this.asyncResponse<
313
+ CopilotSearchSuggestions,
314
+ CopilotSearchSuggestionsAck
315
+ >("copilot_search_suggestions", args, callback);
316
+ }
317
+
250
318
  async facetedNavigation(
251
- args: FacetedNavigation
319
+ args: FacetedNavigation,
252
320
  ): Promise<CopilotResult<T, FacetedNavigationAck>>;
253
321
  async facetedNavigation(
254
322
  args: FacetedNavigation,
255
- callback?: (event: FacetedNavigationAck) => void
323
+ callback?: (event: FacetedNavigationAck) => void,
256
324
  ): Promise<void>;
257
325
  async facetedNavigation(
258
326
  args: FacetedNavigation,
259
- callback?: (event: FacetedNavigationAck) => void
327
+ callback?: (event: FacetedNavigationAck) => void,
260
328
  ): Promise<CopilotResult<T, FacetedNavigationAck> | void> {
261
329
  return this.asyncResponse<FacetedNavigation, FacetedNavigationAck>(
262
330
  "faceted_navigation",
263
331
  args,
264
- callback
332
+ callback,
265
333
  );
266
334
  }
267
335
 
268
336
  async cancelRequest(args: Cancel): Promise<CopilotResult<T, CancelAck>>;
269
337
  async cancelRequest(
270
338
  args: Cancel,
271
- callback?: (event: CancelAck) => void
339
+ callback?: (event: CancelAck) => void,
272
340
  ): Promise<void>;
273
341
  cancelRequest(
274
342
  args: Cancel,
275
- callback?: (event: CancelAck) => void
343
+ callback?: (event: CancelAck) => void,
276
344
  ): Promise<CopilotResult<T, CancelAck> | void> {
277
- return this.asyncResponse<Cancel, CancelAck>(
278
- "cancel",
279
- args,
280
- callback
281
- );
345
+ return this.asyncResponse<Cancel, CancelAck>("cancel", args, callback);
282
346
  }
283
347
 
284
- async conversationReset(args: ConversationReset): Promise<CopilotResult<T, ConversationResetAck>>;
285
348
  async conversationReset(
286
349
  args: ConversationReset,
287
- callback?: (event: ConversationResetAck) => void
350
+ ): Promise<CopilotResult<T, ConversationResetAck>>;
351
+ async conversationReset(
352
+ args: ConversationReset,
353
+ callback?: (event: ConversationResetAck) => void,
288
354
  ): Promise<void>;
289
355
  conversationReset(
290
356
  args: ConversationReset,
291
- callback?: (event: ConversationResetAck) => void
357
+ callback?: (event: ConversationResetAck) => void,
292
358
  ): Promise<CopilotResult<T, ConversationResetAck> | void> {
293
359
  return this.asyncResponse<ConversationReset, ConversationResetAck>(
294
360
  "conversation_reset",
295
361
  args,
296
- callback
362
+ callback,
297
363
  );
298
364
  }
299
365
 
300
366
  async productView(
301
- args: ProductView
367
+ args: ProductView,
302
368
  ): Promise<CopilotResult<T, ProductViewAck>>;
303
369
  async productView(
304
370
  args: ProductView,
305
- callback?: (event: ProductViewAck) => void
371
+ callback?: (event: ProductViewAck) => void,
306
372
  ): Promise<void>;
307
373
  async productView(
308
374
  args: ProductView,
309
- callback?: (event: ProductViewAck) => void
375
+ callback?: (event: ProductViewAck) => void,
310
376
  ): Promise<CopilotResult<T, ProductViewAck> | void> {
311
377
  return this.asyncResponse<ProductView, ProductViewAck>(
312
378
  "product_view",
313
379
  args,
314
- callback
380
+ callback,
315
381
  );
316
382
  }
317
383
 
318
- async askCim(
319
- args: AskCim
320
- ): Promise<CopilotResult<T, AskCimAck>>;
384
+ async productViewSuggestions(
385
+ args: ProductViewSuggestions,
386
+ ): Promise<CopilotResult<T, ProductViewSuggestionsAck>>;
387
+ async productViewSuggestions(
388
+ args: ProductViewSuggestions,
389
+ callback?: (event: ProductViewSuggestionsAck) => void,
390
+ ): Promise<void>;
391
+ async productViewSuggestions(
392
+ args: ProductViewSuggestions,
393
+ callback?: (event: ProductViewSuggestionsAck) => void,
394
+ ): Promise<CopilotResult<T, ProductViewSuggestionsAck> | void> {
395
+ return this.asyncResponse<
396
+ ProductViewSuggestions,
397
+ ProductViewSuggestionsAck
398
+ >("product_view_suggestions", args, callback);
399
+ }
400
+
401
+ async askCim(args: AskCim): Promise<CopilotResult<T, AskCimAck>>;
321
402
  async askCim(
322
403
  args: AskCim,
323
- callback?: (event: AskCimAck) => void
404
+ callback?: (event: AskCimAck) => void,
324
405
  ): Promise<void>;
325
406
  async askCim(
326
407
  args: AskCim,
327
- callback?: (event: AskCimAck) => void
408
+ callback?: (event: AskCimAck) => void,
328
409
  ): Promise<CopilotResult<T, AskCimAck> | void> {
329
- return this.asyncResponse<AskCim, AskCimAck>(
330
- "ask_cim",
410
+ return this.asyncResponse<AskCim, AskCimAck>("ask_cim", args, callback);
411
+ }
412
+
413
+ async askCimSuggestions(
414
+ args: AskCimSuggestions,
415
+ ): Promise<CopilotResult<T, AskCimSuggestionsAck>>;
416
+ async askCimSuggestions(
417
+ args: AskCimSuggestions,
418
+ callback?: (event: AskCimSuggestionsAck) => void,
419
+ ): Promise<void>;
420
+ async askCimSuggestions(
421
+ args: AskCimSuggestions,
422
+ callback?: (event: AskCimSuggestionsAck) => void,
423
+ ): Promise<CopilotResult<T, AskCimSuggestionsAck> | void> {
424
+ return this.asyncResponse<AskCimSuggestions, AskCimSuggestionsAck>(
425
+ "ask_cim_suggestions",
331
426
  args,
332
- callback
427
+ callback,
333
428
  );
334
429
  }
335
430
 
@@ -337,10 +432,10 @@ export default class CimulateCopilot<
337
432
  CopilotResult<T, SessionInformation>
338
433
  >;
339
434
  async requestSessionInformation(
340
- callback?: (sessionInformation: SessionInformation) => void
435
+ callback?: (sessionInformation: SessionInformation) => void,
341
436
  ): Promise<void>;
342
437
  async requestSessionInformation(
343
- callback?: (sessionInformation: SessionInformation) => void
438
+ callback?: (sessionInformation: SessionInformation) => void,
344
439
  ): Promise<CopilotResult<T, SessionInformation> | void> {
345
440
  return new Promise((resolve) => {
346
441
  this.socket.emit("session_info", (response: SessionInformation) => {
@@ -351,29 +446,31 @@ export default class CimulateCopilot<
351
446
  });
352
447
  }
353
448
 
354
- async getConversationEvents(
355
- args: ConversationEvents
356
- ): Promise<CopilotEvents>;
449
+ async getConversationEvents(args: ConversationEvents): Promise<CopilotEvents>;
357
450
  async getConversationEvents(
358
451
  args: ConversationEvents,
359
- callback?: (events: CopilotEvents) => void
452
+ callback?: (events: CopilotEvents) => void,
360
453
  ): Promise<void>;
361
454
  async getConversationEvents(
362
455
  args: ConversationEvents,
363
- callback?: (events: CopilotEvents) => void
456
+ callback?: (events: CopilotEvents) => void,
364
457
  ): Promise<CopilotEvents | void> {
365
458
  return new Promise((resolve) => {
366
- this.socket.emit("conversation_events", args, (response: CopilotEvents) => {
367
- if (callback) callback(response);
368
- // TODO - error handling
369
- resolve(response as CopilotEvents);
370
- });
459
+ this.socket.emit(
460
+ "conversation_events",
461
+ args,
462
+ (response: CopilotEvents) => {
463
+ if (callback) callback(response);
464
+ // TODO - error handling
465
+ resolve(response as CopilotEvents);
466
+ },
467
+ );
371
468
  });
372
469
  }
373
470
 
374
471
  on<E extends CopilotEventName>(
375
472
  name: E,
376
- handler: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void
473
+ handler: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void,
377
474
  ) {
378
475
  this.socket.on<CopilotEventName>(name, handler);
379
476
  return handler;
@@ -381,20 +478,19 @@ export default class CimulateCopilot<
381
478
 
382
479
  once<E extends CopilotEventName>(
383
480
  name: E,
384
- handler: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void
481
+ handler: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void,
385
482
  ) {
386
483
  this.socket.once<CopilotEventName>(name, handler);
387
484
  }
388
485
 
389
486
  off<E extends CopilotEventName>(
390
487
  name?: E,
391
- handler?: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void
488
+ handler?: (event: Extract<CopilotAPIEvent<T>, { name: E }>) => void,
392
489
  ) {
393
490
  this.socket.off(name, handler as any);
394
491
  }
395
492
 
396
493
  disconnect() {
397
-
398
494
  if (this.reconnectTimeout) {
399
495
  clearTimeout(this.reconnectTimeout);
400
496
  this.reconnectTimeout = undefined;
@@ -402,7 +498,7 @@ export default class CimulateCopilot<
402
498
 
403
499
  this.offInternalHandlers();
404
500
  this.socket.disconnect();
405
- }
501
+ }
406
502
 
407
503
  onDisconnect(handler: (reason: string) => void) {
408
504
  this.socket.on("disconnect", handler);
@@ -411,7 +507,7 @@ export default class CimulateCopilot<
411
507
  private async asyncResponse<P, A extends CopilotAPIAck>(
412
508
  operation: string,
413
509
  payload: P,
414
- handler?: (event: A) => void
510
+ handler?: (event: A) => void,
415
511
  ): Promise<CopilotResult<T, A> | void> {
416
512
  if (handler) {
417
513
  this.socket.emit(operation, payload, handler);
@@ -423,7 +519,7 @@ export default class CimulateCopilot<
423
519
  const events = asyncGenerator<CopilotAPIEvent<T>>(({ emit, cancel }) => {
424
520
  const handler = (
425
521
  event: string,
426
- payload: Exclude<CopilotAPIEvent<T>, ConnectAck | ConnectError>
522
+ payload: Exclude<CopilotAPIEvent<T>, ConnectAck | ConnectError>,
427
523
  ) => {
428
524
  if (["done", "error"].includes(payload.name)) {
429
525
  cancel();
@@ -446,7 +542,7 @@ export default class CimulateCopilot<
446
542
  eventSourceId = ack?.id;
447
543
  resolve(ack);
448
544
  }
449
- })
545
+ }),
450
546
  );
451
547
 
452
548
  return { result, events };
@@ -0,0 +1,10 @@
1
+ import { AskCimSuggestions } from './AskCimSuggestions';
2
+ interface AskCimSuggestionsAck {
3
+ name: 'ask_cim_suggestions';
4
+ request: AskCimSuggestions;
5
+ sessionId: string;
6
+ id: string;
7
+ createdAt: string;
8
+ status: number;
9
+ }
10
+ export { AskCimSuggestionsAck };
@@ -3,20 +3,28 @@
3
3
  For any new event, manually create an entry here.
4
4
  */
5
5
  import { AskCimAck } from "./AskCimAck";
6
+ import { AskCimSuggestionsAck } from "./AskCimSuggestionsAck";
6
7
  import { CancelAck } from "./CancelAck";
7
8
  import { ConversationResetAck } from "./ConversationResetAck";
8
9
  import { CopilotBrowseAck } from "./CopilotBrowseAck";
10
+ import { CopilotBrowseSuggestionsAck } from "./CopilotBrowseSuggestionsAck";
9
11
  import { CopilotError } from "./CopilotError";
10
12
  import { CopilotSearchAck } from "./CopilotSearchAck";
13
+ import { CopilotSearchSuggestionsAck } from "./CopilotSearchSuggestionsAck";
11
14
  import { FacetedNavigationAck } from "./FacetedNavigationAck";
12
15
  import { ProductViewAck } from "./ProductViewAck";
16
+ import { ProductViewSuggestionsAck } from "./ProductViewSuggestionsAck";
13
17
 
14
18
  export type CopilotAPIAck =
15
19
  | AskCimAck
20
+ | AskCimSuggestionsAck
16
21
  | CancelAck
17
22
  | CopilotBrowseAck
23
+ | CopilotBrowseSuggestionsAck
18
24
  | CopilotSearchAck
25
+ | CopilotSearchSuggestionsAck
19
26
  | ConversationResetAck
20
27
  | FacetedNavigationAck
21
28
  | ProductViewAck
29
+ | ProductViewSuggestionsAck
22
30
  | CopilotError;
@@ -0,0 +1,10 @@
1
+ import { CopilotBrowseSuggestions } from './CopilotBrowseSuggestions';
2
+ interface CopilotBrowseSuggestionsAck {
3
+ name: 'copilot_browse_suggestions';
4
+ request: CopilotBrowseSuggestions;
5
+ sessionId: string;
6
+ id: string;
7
+ createdAt: string;
8
+ status: number;
9
+ }
10
+ export { CopilotBrowseSuggestionsAck };
@@ -0,0 +1,10 @@
1
+ import { CopilotSearchSuggestions } from './CopilotSearchSuggestions';
2
+ interface CopilotSearchSuggestionsAck {
3
+ name: 'copilot_search_suggestions';
4
+ request: CopilotSearchSuggestions;
5
+ sessionId: string;
6
+ id: string;
7
+ createdAt: string;
8
+ status: number;
9
+ }
10
+ export { CopilotSearchSuggestionsAck };
@@ -0,0 +1,10 @@
1
+ import { ProductViewSuggestions } from './ProductViewSuggestions';
2
+ interface ProductViewSuggestionsAck {
3
+ name: 'product_view_suggestions';
4
+ request: ProductViewSuggestions;
5
+ sessionId: string;
6
+ id: string;
7
+ createdAt: string;
8
+ status: number;
9
+ }
10
+ export { ProductViewSuggestionsAck };
@@ -1,6 +1,7 @@
1
1
  export * from './AskCim';
2
2
  export * from './AskCimAck';
3
3
  export * from './AskCimSuggestions';
4
+ export * from './AskCimSuggestionsAck';
4
5
  export * from './Attachments';
5
6
  export * from './BrowseParams';
6
7
  export * from './Cancel';
@@ -20,12 +21,14 @@ export * from './CopilotBrowse';
20
21
  export * from './CopilotBrowseAck';
21
22
  export * from './CopilotBrowseSuggestion';
22
23
  export * from './CopilotBrowseSuggestions';
24
+ export * from './CopilotBrowseSuggestionsAck';
23
25
  export * from './CopilotError';
24
26
  export * from './CopilotEvent';
25
27
  export * from './CopilotSearch';
26
28
  export * from './CopilotSearchAck';
27
29
  export * from './CopilotSearchSuggestion';
28
30
  export * from './CopilotSearchSuggestions';
31
+ export * from './CopilotSearchSuggestionsAck';
29
32
  export * from './customization';
30
33
  export * from './DisplayProducts';
31
34
  export * from './Done';
@@ -42,6 +45,7 @@ export * from './ProductView';
42
45
  export * from './ProductViewAck';
43
46
  export * from './ProductViewSuggestion';
44
47
  export * from './ProductViewSuggestions';
48
+ export * from './ProductViewSuggestionsAck';
45
49
  export * from './Progress';
46
50
  export * from './ProgressToolKwargs';
47
51
  export * from './RefinedBrowse';
@@ -1,2 +0,0 @@
1
- !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("socket.io-client")):"function"==typeof define&&define.amd?define(["exports","socket.io-client"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).CimulateCopilot={},t.io)}(this,(function(t,e){"use strict";function n(t){return t&&"object"==typeof t&&"default"in t?t:{default:t}}var r=n(e),o=function(t){return function(t){return!!t&&"object"==typeof t}(t)&&!function(t){var e=Object.prototype.toString.call(t);return"[object RegExp]"===e||"[object Date]"===e||function(t){return t.$$typeof===s}(t)}(t)};var s="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function c(t,e){return!1!==e.clone&&e.isMergeableObject(t)?h((n=t,Array.isArray(n)?[]:{}),t,e):t;var n}function i(t,e,n){return t.concat(e).map((function(t){return c(t,n)}))}function a(t){return Object.keys(t).concat(function(t){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(t).filter((function(e){return Object.propertyIsEnumerable.call(t,e)})):[]}(t))}function l(t,e){try{return e in t}catch(t){return!1}}function u(t,e,n){var r={};return n.isMergeableObject(t)&&a(t).forEach((function(e){r[e]=c(t[e],n)})),a(e).forEach((function(o){(function(t,e){return l(t,e)&&!(Object.hasOwnProperty.call(t,e)&&Object.propertyIsEnumerable.call(t,e))})(t,o)||(l(t,o)&&n.isMergeableObject(e[o])?r[o]=function(t,e){if(!e.customMerge)return h;var n=e.customMerge(t);return"function"==typeof n?n:h}(o,n)(t[o],e[o],n):r[o]=c(e[o],n))})),r}function h(t,e,n){(n=n||{}).arrayMerge=n.arrayMerge||i,n.isMergeableObject=n.isMergeableObject||o,n.cloneUnlessOtherwiseSpecified=c;var r=Array.isArray(e);return r===Array.isArray(t)?r?n.arrayMerge(t,e,n):u(t,e,n):c(e,n)}h.all=function(t,e){if(!Array.isArray(t))throw new Error("first argument should be an array");return t.reduce((function(t,n){return h(t,n,e)}),{})};var f=h;class p{constructor(t){Object.assign(this,t)}}function y(t){if(t)return function(t){for(var e in y.prototype)t[e]=y.prototype[e];return t}(t)}y.prototype.on=y.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},y.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},y.prototype.off=y.prototype.removeListener=y.prototype.removeAllListeners=y.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n,r=this._callbacks["$"+t];if(!r)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var o=0;o<r.length;o++)if((n=r[o])===e||n.fn===e){r.splice(o,1);break}return 0===r.length&&delete this._callbacks["$"+t],this},y.prototype.emit=function(t){this._callbacks=this._callbacks||{};for(var e=new Array(arguments.length-1),n=this._callbacks["$"+t],r=1;r<arguments.length;r++)e[r-1]=arguments[r];if(n){r=0;for(var o=(n=n.slice(0)).length;r<o;++r)n[r].apply(this,e)}return this},y.prototype.emitReserved=y.prototype.emit,y.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},y.prototype.hasListeners=function(t){return!!this.listeners(t).length};const d="function"==typeof ArrayBuffer,m=Object.prototype.toString,b="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===m.call(Blob),A="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===m.call(File);function k(t){return d&&(t instanceof ArrayBuffer||(t=>"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer)(t))||b&&t instanceof Blob||A&&t instanceof File}function g(t,e){if(!t||"object"!=typeof t)return!1;if(Array.isArray(t)){for(let e=0,n=t.length;e<n;e++)if(g(t[e]))return!0;return!1}if(k(t))return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return g(t.toJSON(),!0);for(const e in t)if(Object.prototype.hasOwnProperty.call(t,e)&&g(t[e]))return!0;return!1}function E(t){const e=[],n=t.data,r=t;return r.data=C(n,e),r.attachments=e.length,{packet:r,buffers:e}}function C(t,e){if(!t)return t;if(k(t)){const n={_placeholder:!0,num:e.length};return e.push(t),n}if(Array.isArray(t)){const n=new Array(t.length);for(let r=0;r<t.length;r++)n[r]=C(t[r],e);return n}if("object"==typeof t&&!(t instanceof Date)){const n={};for(const r in t)Object.prototype.hasOwnProperty.call(t,r)&&(n[r]=C(t[r],e));return n}return t}function v(t,e){return t.data=N(t.data,e),delete t.attachments,t}function N(t,e){if(!t)return t;if(t&&!0===t._placeholder){if("number"==typeof t.num&&t.num>=0&&t.num<e.length)return e[t.num];throw new Error("illegal attachments")}if(Array.isArray(t))for(let n=0;n<t.length;n++)t[n]=N(t[n],e);else if("object"==typeof t)for(const n in t)Object.prototype.hasOwnProperty.call(t,n)&&(t[n]=N(t[n],e));return t}const w=["connect","connect_error","disconnect","disconnecting","newListener","removeListener"];var _;!function(t){t[t.CONNECT=0]="CONNECT",t[t.DISCONNECT=1]="DISCONNECT",t[t.EVENT=2]="EVENT",t[t.ACK=3]="ACK",t[t.CONNECT_ERROR=4]="CONNECT_ERROR",t[t.BINARY_EVENT=5]="BINARY_EVENT",t[t.BINARY_ACK=6]="BINARY_ACK"}(_||(_={}));class O{constructor(t){this.replacer=t}encode(t){return t.type!==_.EVENT&&t.type!==_.ACK||!g(t)?[this.encodeAsString(t)]:this.encodeAsBinary({type:t.type===_.EVENT?_.BINARY_EVENT:_.BINARY_ACK,nsp:t.nsp,data:t.data,id:t.id})}encodeAsString(t){let e=""+t.type;return t.type!==_.BINARY_EVENT&&t.type!==_.BINARY_ACK||(e+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(e+=t.nsp+","),null!=t.id&&(e+=t.id),null!=t.data&&(e+=JSON.stringify(t.data,this.replacer)),e}encodeAsBinary(t){const e=E(t),n=this.encodeAsString(e.packet),r=e.buffers;return r.unshift(n),r}}function R(t){return"[object Object]"===Object.prototype.toString.call(t)}class T extends y{constructor(t){super(),this.reviver=t}add(t){let e;if("string"==typeof t){if(this.reconstructor)throw new Error("got plaintext data when reconstructing a packet");e=this.decodeString(t);const n=e.type===_.BINARY_EVENT;n||e.type===_.BINARY_ACK?(e.type=n?_.EVENT:_.ACK,this.reconstructor=new j(e),0===e.attachments&&super.emitReserved("decoded",e)):super.emitReserved("decoded",e)}else{if(!k(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");e=this.reconstructor.takeBinaryData(t),e&&(this.reconstructor=null,super.emitReserved("decoded",e))}}decodeString(t){let e=0;const n={type:Number(t.charAt(0))};if(void 0===_[n.type])throw new Error("unknown packet type "+n.type);if(n.type===_.BINARY_EVENT||n.type===_.BINARY_ACK){const r=e+1;for(;"-"!==t.charAt(++e)&&e!=t.length;);const o=t.substring(r,e);if(o!=Number(o)||"-"!==t.charAt(e))throw new Error("Illegal attachments");n.attachments=Number(o)}if("/"===t.charAt(e+1)){const r=e+1;for(;++e;){if(","===t.charAt(e))break;if(e===t.length)break}n.nsp=t.substring(r,e)}else n.nsp="/";const r=t.charAt(e+1);if(""!==r&&Number(r)==r){const r=e+1;for(;++e;){const n=t.charAt(e);if(null==n||Number(n)!=n){--e;break}if(e===t.length)break}n.id=Number(t.substring(r,e+1))}if(t.charAt(++e)){const r=this.tryParse(t.substr(e));if(!T.isPayloadValid(n.type,r))throw new Error("invalid payload");n.data=r}return n}tryParse(t){try{return JSON.parse(t,this.reviver)}catch(t){return!1}}static isPayloadValid(t,e){switch(t){case _.CONNECT:return R(e);case _.DISCONNECT:return void 0===e;case _.CONNECT_ERROR:return"string"==typeof e||R(e);case _.EVENT:case _.BINARY_EVENT:return Array.isArray(e)&&("number"==typeof e[0]||"string"==typeof e[0]&&-1===w.indexOf(e[0]));case _.ACK:case _.BINARY_ACK:return Array.isArray(e)}}destroy(){this.reconstructor&&(this.reconstructor.finishedReconstruction(),this.reconstructor=null)}}class j{constructor(t){this.packet=t,this.buffers=[],this.reconPack=t}takeBinaryData(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){const t=v(this.reconPack,this.buffers);return this.finishedReconstruction(),t}return null}finishedReconstruction(){this.reconPack=null,this.buffers=[]}}const S=["searchParams.facetFilters","browseParams.facetFilters","hits","products"];const I=(t,e,n)=>function r(o,s=[]){const c=Object.entries(o).map((([o,c])=>{const i=[...s,e(o)];return[t(o),c instanceof Object&&!n?.includes(i.join("."))?r(c,i):c]}));return Array.isArray(o)?c.map((t=>t[1])):Object.fromEntries(c)},B=t=>t.replace(/_([a-z])/g,((t,e)=>e.toUpperCase())),K=I((t=>t.replace(/([A-Z])/g,"_$1").toLowerCase()),(t=>t),S),P=I(B,B,S),D={Encoder:class extends O{encode(t){return super.encode({...t,data:2==t.data?.length?[t.data[0],K(t.data[1])]:1==t.data?.length?[t.data[0]]:"object"==typeof t.data&&null!=t.data?t.data:void 0})}},Decoder:class extends T{constructor(){super(((t,e)=>""==t&&Array.isArray(e)?e.map((t=>Array.isArray(t)?t.map((t=>t instanceof Object?P(t):t)):t instanceof Object?P(t):t)):e))}}};const x={path:"/api/v1/socket.io",autoConnect:!1,transports:["polling","websocket"],upgrade:!0,timeout:1e4};t.CimulateCopilot=class{constructor({apiKey:t,apiToken:e,baseUrl:n,namespace:o="/copilot",socketOptions:s={}}){if(this.sessionIdKey="x-cimulate-copilot-session-id",this.reconnectAttempts=0,this.maxReconnectAttempts=5,this.maxReconnectDelay=3e4,this.handleConnectAck=t=>{console.log("[Copilot SDK] Connect Ack:",t),this.socket.auth={[this.sessionIdKey]:t.sessionId}},this.handleDisconnect=t=>{console.warn(`[Copilot SDK] Disconnected: ${t}`),"io client disconnect"!==t&&(console.log(`[Copilot SDK] Disconnected due to ${t}. Attempting reconnect...`),this.retryConnect())},this.handleConnectError=t=>{console.error(`[Copilot SDK] Connect error: ${t.message}`);const e=t.message.match(/['"]error['"]:\s*['"](\w+)['"]/),n=e?.[1];n&&["InvalidApiKey","InvalidToken","BadRequest"].includes(n)?this.disconnect():this.socket.connected||this.socket.active||(console.log("[Copilot SDK] Retrying connect attempt..."),this.retryConnect())},this.offInternalHandlers=()=>{this.socket.off("connect_ack",this.handleConnectAck),this.socket.off("disconnect",this.handleDisconnect),this.off("connect_error",this.handleConnectError)},t&&e||!t&&!e)throw new Error("Provide exactly one authentication method: either 'apiKey' or 'apiToken', but not both.");const c=`${n}${o}`,i={};t?i["x-cimulate-api-key"]=t:e&&(i.Authorization=`Bearer ${e}`);const a=[x,s,{parser:D,withCredentials:!0,transportOptions:{polling:{extraHeaders:i}}}];this.socket=r.default(c,f.all(a))}connect(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.reconnectAttempts=0),this.offInternalHandlers(),this.on("connect_ack",this.handleConnectAck),this.socket.on("disconnect",this.handleDisconnect),this.on("connect_error",this.handleConnectError),this.socket.auth&&this.sessionIdKey in this.socket.auth&&(this.socket.auth={}),this.socket.connect()}retryConnect(){if(!(this.socket.connected||this.socket.active||this.reconnectAttempts>=this.maxReconnectAttempts))if(this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0),this.reconnectAttempts<this.maxReconnectAttempts){const t=Math.min(1e3*2**this.reconnectAttempts,this.maxReconnectDelay);console.info(`[Copilot SDK] Retry #${this.reconnectAttempts+1} in ${t}ms...`),this.reconnectTimeout=setTimeout((()=>{this.socket.connected||this.socket.active||(this.reconnectAttempts++,this.reconnect())}),t)}else console.error("[Copilot SDK] Max reconnect attempts reached.")}reconnect(){this.socket.connected||this.socket.active||this.reconnectAttempts>=this.maxReconnectAttempts||(this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.reconnectAttempts=0),this.socket.connect())}async browse(t,e){return this.asyncResponse("copilot_browse",t,e)}async search(t,e){return this.asyncResponse("copilot_search",t,e)}async facetedNavigation(t,e){return this.asyncResponse("faceted_navigation",t,e)}cancelRequest(t,e){return this.asyncResponse("cancel",t,e)}conversationReset(t,e){return this.asyncResponse("conversation_reset",t,e)}async productView(t,e){return this.asyncResponse("product_view",t,e)}async askCim(t,e){return this.asyncResponse("ask_cim",t,e)}async requestSessionInformation(t){return new Promise((e=>{this.socket.emit("session_info",(n=>{t&&t(n),e(n)}))}))}async getConversationEvents(t,e){return new Promise((n=>{this.socket.emit("conversation_events",t,(t=>{e&&e(t),n(t)}))}))}on(t,e){return this.socket.on(t,e),e}once(t,e){this.socket.once(t,e)}off(t,e){this.socket.off(t,e)}disconnect(){this.reconnectTimeout&&(clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0),this.offInternalHandlers(),this.socket.disconnect()}onDisconnect(t){this.socket.on("disconnect",t)}async asyncResponse(t,e,n){if(n)return void this.socket.emit(t,e,n);let r="";const o=async function*(t){const e=[];let n=!1,r=null;const o=await t({emit:t=>{e.push(t),r&&(r(),r=null)},cancel:()=>{n=!0}});try{for(;!n;)e.length>0?yield e.shift():await new Promise((t=>{r=t}));for(;e.length>0;)yield e.shift()}finally{await(o?.())}}((({emit:t,cancel:e})=>{const n=(n,o)=>{["done","error"].includes(o.name)&&e(),o.eventSourceId==r&&t(o)};return this.socket.onAny(n),async()=>{this.socket.offAny(n)}}));return{result:await new Promise(((n,o)=>this.socket.emit(t,e,(t=>{"error"===t.name?o(new p(t)):(r=t?.id,n(t))})))),events:o}}},t.CimulateCopilotException=p,t.RAW_PROPERTY_VALUES=S,Object.defineProperty(t,"__esModule",{value:!0})}));
2
- //# sourceMappingURL=bundle.cimulate.copilot-sdk.7dbeb4d0.umd.js.map