convo-ai-sdk 1.2.5 → 1.2.7

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/dist/index.d.ts CHANGED
@@ -4,12 +4,14 @@ export declare class ChatClient {
4
4
  private listeners;
5
5
  status: ConnectionStatus;
6
6
  conversationStatus: ConversationStatus;
7
+ awaitingResponse: boolean;
7
8
  messages: ChatMessage[];
8
9
  config: Partial<ChatConfig>;
9
10
  constructor(options: ClientOptions);
10
11
  private _emit;
11
12
  private _setStatus;
12
13
  private _setConversationStatus;
14
+ private _setAwaitingResponse;
13
15
  private _addMessage;
14
16
  private _loadGreeting;
15
17
  private _loadHistory;
@@ -25,6 +27,8 @@ export declare class ChatClient {
25
27
  } | null>;
26
28
  sendTranscriptionMessage(transcriptionText: string, transcriptionKey: string, modified?: boolean): Promise<void>;
27
29
  sendMessage(text: string): Promise<void>;
30
+ sendActionMessage(text: string): Promise<void>;
31
+ submitDataActionMessage(submitType: string | undefined, data: Record<string, any>): Promise<void>;
28
32
  toolCall(tool_call: any): Promise<void>;
29
33
  sendStreamMessage(message: ChatMessage): Promise<void>;
30
34
  disconnect(): void;
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export class ChatClient {
4
4
  listeners = {};
5
5
  status = 'disconnected';
6
6
  conversationStatus = 'started';
7
+ awaitingResponse = false;
7
8
  messages = [];
8
9
  config = {};
9
10
  constructor(options) {
@@ -28,6 +29,10 @@ export class ChatClient {
28
29
  this.conversationStatus = newStatus;
29
30
  this._emit('conversationStatusChange', this.conversationStatus);
30
31
  }
32
+ _setAwaitingResponse(awaiting) {
33
+ this.awaitingResponse = awaiting;
34
+ this._emit('awaitingResponse', this.awaitingResponse);
35
+ }
31
36
  _addMessage(message) {
32
37
  this.messages.push(message);
33
38
  }
@@ -297,6 +302,28 @@ export class ChatClient {
297
302
  this._emit('message', userMessage);
298
303
  await this.sendStreamMessage(userMessage);
299
304
  }
305
+ async sendActionMessage(text) {
306
+ if (this.status !== 'connected') {
307
+ console.error('Cannot send message, not connected.');
308
+ return;
309
+ }
310
+ // TODO: Replace from user with from 'agent_wake_up'
311
+ const userMessage = {
312
+ id: `local-${Date.now()}`,
313
+ data: { content: text },
314
+ from: 'action',
315
+ timestamp: Date.now(),
316
+ };
317
+ await this.sendStreamMessage(userMessage);
318
+ }
319
+ async submitDataActionMessage(submitType = 'action', data) {
320
+ if (this.status !== 'connected') {
321
+ console.error('Cannot submit data, not connected.');
322
+ return;
323
+ }
324
+ const submitMessageContent = `<${submitType}>${JSON.stringify(data)}</${submitType}>`;
325
+ await this.sendActionMessage(submitMessageContent);
326
+ }
300
327
  async toolCall(tool_call) {
301
328
  this._emit('toolCall', tool_call);
302
329
  }
@@ -319,91 +346,100 @@ export class ChatClient {
319
346
  if (message.from === 'widget') {
320
347
  input.content = message.data.content;
321
348
  }
322
- const response = await fetch(this.config.streamApiEndpoint + 'conversation', {
323
- method: 'POST',
324
- headers: {
325
- 'Content-Type': 'application/json',
326
- 'Authorization': `Bearer ${this.config.sessionToken}`,
327
- 'Accept': 'text/event-stream'
328
- },
329
- body: JSON.stringify(input)
330
- });
331
- if (!response.ok) {
332
- throw new Error(`HTTP error! status: ${response.status}`);
333
- }
334
- if (!response.body) {
335
- throw new Error('Response body is null');
336
- }
337
- const reader = response.body.getReader();
338
- const decoder = new TextDecoder('utf-8');
339
- let buffer = '';
340
- let currentMessage = null;
341
- if (message.from === 'widget') {
342
- return;
343
- }
344
- while (true) {
345
- const { done, value } = await reader.read();
346
- if (done) {
347
- break;
349
+ try {
350
+ this._setAwaitingResponse(true);
351
+ const response = await fetch(this.config.streamApiEndpoint + 'conversation', {
352
+ method: 'POST',
353
+ headers: {
354
+ 'Content-Type': 'application/json',
355
+ 'Authorization': `Bearer ${this.config.sessionToken}`,
356
+ 'Accept': 'text/event-stream'
357
+ },
358
+ body: JSON.stringify(input)
359
+ });
360
+ if (!response.ok) {
361
+ throw new Error(`HTTP error! status: ${response.status}`);
348
362
  }
349
- buffer += decoder.decode(value, { stream: true });
350
- const lines = buffer.split('\n');
351
- buffer = lines.pop() || '';
352
- for (const line of lines) {
353
- try {
354
- if (line.startsWith('thought: ')) {
355
- const data = JSON.parse(line.substring(9));
356
- this._emit('thought', data);
357
- }
358
- else if (line.startsWith('start: ')) {
359
- if (currentMessage) {
360
- this._addMessage(currentMessage);
361
- this._emit('messageDone', currentMessage);
363
+ if (!response.body) {
364
+ throw new Error('Response body is null');
365
+ }
366
+ const reader = response.body.getReader();
367
+ const decoder = new TextDecoder('utf-8');
368
+ let buffer = '';
369
+ let currentMessage = null;
370
+ if (message.from === 'widget') {
371
+ return;
372
+ }
373
+ while (true) {
374
+ const { done, value } = await reader.read();
375
+ if (done) {
376
+ break;
377
+ }
378
+ buffer += decoder.decode(value, { stream: true });
379
+ const lines = buffer.split('\n');
380
+ buffer = lines.pop() || '';
381
+ for (const line of lines) {
382
+ try {
383
+ if (line.startsWith('thought: ')) {
384
+ const data = JSON.parse(line.substring(9));
385
+ this._emit('thought', data);
362
386
  }
363
- const data = JSON.parse(line.substring(7));
364
- currentMessage = {
365
- id: data.message.messageId,
366
- data: { content: data.message?.data?.content || '' },
367
- from: data.message.senderType,
368
- timestamp: data.message.timestamp || Date.now(),
369
- };
370
- this._emit('messageStart', currentMessage);
371
- }
372
- else if (line.startsWith('data: ') && currentMessage) {
373
- const data = JSON.parse(line.substring(6));
374
- currentMessage.data.content += data.p;
375
- if (data.p) {
376
- this._emit('messageData', data.p);
387
+ else if (line.startsWith('start: ')) {
388
+ if (currentMessage) {
389
+ this._addMessage(currentMessage);
390
+ this._emit('messageDone', currentMessage);
391
+ }
392
+ const data = JSON.parse(line.substring(7));
393
+ currentMessage = {
394
+ id: data.message.messageId,
395
+ data: { content: data.message?.data?.content || '' },
396
+ from: data.message.senderType,
397
+ timestamp: data.message.timestamp || Date.now(),
398
+ };
399
+ this._emit('messageStart', currentMessage);
377
400
  }
378
- }
379
- else if (line.startsWith('tool_call: ')) {
380
- const data = JSON.parse(line.substring(11));
381
- this._emit('toolCall', data);
382
- }
383
- else if (line.startsWith('error: ')) {
384
- const error = JSON.parse(line.substring(7));
385
- this._emit('messageError', error);
386
- currentMessage = null;
387
- break;
388
- }
389
- else if (line.startsWith('status: ')) {
390
- const data = JSON.parse(line.substring(8));
391
- if (data.value) {
392
- this._setConversationStatus(data.value);
401
+ else if (line.startsWith('data: ') && currentMessage) {
402
+ const data = JSON.parse(line.substring(6));
403
+ currentMessage.data.content += data.p;
404
+ if (data.p) {
405
+ this._emit('messageData', data.p);
406
+ }
407
+ }
408
+ else if (line.startsWith('tool_call: ')) {
409
+ const data = JSON.parse(line.substring(11));
410
+ this._emit('toolCall', data);
411
+ }
412
+ else if (line.startsWith('error: ')) {
413
+ const error = JSON.parse(line.substring(7));
414
+ this._emit('messageError', error);
415
+ currentMessage = null;
416
+ break;
417
+ }
418
+ else if (line.startsWith('status: ')) {
419
+ const data = JSON.parse(line.substring(8));
420
+ if (data.value) {
421
+ this._setConversationStatus(data.value);
422
+ }
423
+ }
424
+ else if (line.startsWith('done') && currentMessage) {
425
+ this._addMessage(currentMessage);
426
+ this._emit('messageDone', currentMessage);
427
+ currentMessage = null;
428
+ break;
393
429
  }
394
430
  }
395
- else if (line.startsWith('done') && currentMessage) {
396
- this._addMessage(currentMessage);
397
- this._emit('messageDone', currentMessage);
398
- currentMessage = null;
399
- break;
431
+ catch (e) {
432
+ console.warn('Could not parse event data as JSON:', line);
400
433
  }
401
434
  }
402
- catch (e) {
403
- console.warn('Could not parse event data as JSON:', line);
404
- }
405
435
  }
406
436
  }
437
+ catch (error) {
438
+ this._emit('messageError', error);
439
+ }
440
+ finally {
441
+ this._setAwaitingResponse(false);
442
+ }
407
443
  }
408
444
  disconnect() {
409
445
  this._setStatus('disconnected');
package/dist/types.d.ts CHANGED
@@ -3,7 +3,7 @@ export type ConversationStatus = 'started' | 'awaiting_user' | 'ended_by_system'
3
3
  export interface ChatMessage {
4
4
  id: string | number;
5
5
  data: any;
6
- from: 'user' | 'assistant' | 'system' | 'tool' | 'widget' | 'transcription';
6
+ from: 'user' | 'assistant' | 'system' | 'tool' | 'widget' | 'transcription' | 'action';
7
7
  timestamp: number;
8
8
  }
9
9
  export interface ChatConfig {
@@ -20,4 +20,4 @@ export interface ClientOptions {
20
20
  identifier?: string;
21
21
  dynamicVariables?: Record<string, any>;
22
22
  }
23
- export type ChatEvent = 'statusChange' | 'conversationStatusChange' | 'message' | 'configLoaded' | 'historyLoaded' | 'messageStart' | 'messageData' | 'messageDone' | 'messageError' | 'toolCall' | 'thought' | 'reset';
23
+ export type ChatEvent = 'statusChange' | 'conversationStatusChange' | 'message' | 'configLoaded' | 'historyLoaded' | 'messageStart' | 'messageData' | 'messageDone' | 'messageError' | 'toolCall' | 'thought' | 'reset' | 'awaitingResponse';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "convo-ai-sdk",
3
- "version": "1.2.5",
3
+ "version": "1.2.7",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",