@hivegpt/hiveai-angular 0.0.372 → 0.0.374

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 (87) hide show
  1. package/karma.conf.js +32 -0
  2. package/ng-package.json +7 -0
  3. package/package.json +10 -10
  4. package/src/environments/environment.ts +19 -0
  5. package/src/lib/components/NotificationSocket.ts +38 -0
  6. package/src/lib/components/bot-html-editor/bot-html-editor.component.css +10 -0
  7. package/src/lib/components/bot-html-editor/bot-html-editor.component.html +11 -0
  8. package/src/lib/components/bot-html-editor/bot-html-editor.component.spec.ts +25 -0
  9. package/src/lib/components/bot-html-editor/bot-html-editor.component.ts +152 -0
  10. package/src/lib/components/bot.service.ts +52 -0
  11. package/src/lib/components/chat-drawer/chat-drawer.component.html +1586 -0
  12. package/src/lib/components/chat-drawer/chat-drawer.component.scss +2907 -0
  13. package/src/lib/components/chat-drawer/chat-drawer.component.ts +2143 -0
  14. package/src/lib/components/chatbot/chatbot.component.html +37 -0
  15. package/src/lib/components/chatbot/chatbot.component.scss +97 -0
  16. package/src/lib/components/chatbot/chatbot.component.ts +44 -0
  17. package/src/lib/components/conversation.service.spec.ts +16 -0
  18. package/src/lib/components/conversation.service.ts +54 -0
  19. package/src/lib/components/socket-service.service.spec.ts +16 -0
  20. package/src/lib/components/socket-service.service.ts +77 -0
  21. package/src/lib/components/translations/translation.service.ts +254 -0
  22. package/src/lib/components/video-player/video-player.component.html +51 -0
  23. package/src/lib/components/video-player/video-player.component.scss +262 -0
  24. package/src/lib/components/video-player/video-player.component.ts +148 -0
  25. package/src/lib/hivegpt.module.ts +18 -0
  26. package/src/lib/models/video.ts +36 -0
  27. package/src/lib/pipes/safe-html.pipe.ts +16 -0
  28. package/src/lib/utils/utils.ts +37 -0
  29. package/{public-api.d.ts → src/public-api.ts} +4 -1
  30. package/tsconfig.lib.json +25 -0
  31. package/tsconfig.lib.prod.json +10 -0
  32. package/tsconfig.spec.json +17 -0
  33. package/tslint.json +17 -0
  34. package/bundles/hivegpt-hiveai-angular.umd.js +0 -3116
  35. package/bundles/hivegpt-hiveai-angular.umd.js.map +0 -1
  36. package/bundles/hivegpt-hiveai-angular.umd.min.js +0 -2
  37. package/bundles/hivegpt-hiveai-angular.umd.min.js.map +0 -1
  38. package/environments/environment.d.ts +0 -15
  39. package/environments/environment.d.ts.map +0 -1
  40. package/esm2015/environments/environment.js +0 -15
  41. package/esm2015/hivegpt-hiveai-angular.js +0 -13
  42. package/esm2015/lib/components/NotificationSocket.js +0 -39
  43. package/esm2015/lib/components/bot-html-editor/bot-html-editor.component.js +0 -112
  44. package/esm2015/lib/components/bot.service.js +0 -50
  45. package/esm2015/lib/components/chat-drawer/chat-drawer.component.js +0 -1743
  46. package/esm2015/lib/components/chatbot/chatbot.component.js +0 -50
  47. package/esm2015/lib/components/conversation.service.js +0 -49
  48. package/esm2015/lib/components/socket-service.service.js +0 -72
  49. package/esm2015/lib/components/translations/translation.service.js +0 -215
  50. package/esm2015/lib/components/video-player/video-player.component.js +0 -123
  51. package/esm2015/lib/hivegpt.module.js +0 -21
  52. package/esm2015/lib/models/video.js +0 -2
  53. package/esm2015/lib/pipes/safe-html.pipe.js +0 -19
  54. package/esm2015/lib/utils/utils.js +0 -36
  55. package/esm2015/public-api.js +0 -7
  56. package/fesm2015/hivegpt-hiveai-angular.js +0 -2512
  57. package/fesm2015/hivegpt-hiveai-angular.js.map +0 -1
  58. package/hivegpt-hiveai-angular.d.ts +0 -13
  59. package/hivegpt-hiveai-angular.d.ts.map +0 -1
  60. package/hivegpt-hiveai-angular.metadata.json +0 -1
  61. package/lib/components/NotificationSocket.d.ts +0 -5
  62. package/lib/components/NotificationSocket.d.ts.map +0 -1
  63. package/lib/components/bot-html-editor/bot-html-editor.component.d.ts +0 -36
  64. package/lib/components/bot-html-editor/bot-html-editor.component.d.ts.map +0 -1
  65. package/lib/components/bot.service.d.ts +0 -12
  66. package/lib/components/bot.service.d.ts.map +0 -1
  67. package/lib/components/chat-drawer/chat-drawer.component.d.ts +0 -255
  68. package/lib/components/chat-drawer/chat-drawer.component.d.ts.map +0 -1
  69. package/lib/components/chatbot/chatbot.component.d.ts +0 -36
  70. package/lib/components/chatbot/chatbot.component.d.ts.map +0 -1
  71. package/lib/components/conversation.service.d.ts +0 -13
  72. package/lib/components/conversation.service.d.ts.map +0 -1
  73. package/lib/components/socket-service.service.d.ts +0 -20
  74. package/lib/components/socket-service.service.d.ts.map +0 -1
  75. package/lib/components/translations/translation.service.d.ts +0 -8
  76. package/lib/components/translations/translation.service.d.ts.map +0 -1
  77. package/lib/components/video-player/video-player.component.d.ts +0 -36
  78. package/lib/components/video-player/video-player.component.d.ts.map +0 -1
  79. package/lib/hivegpt.module.d.ts +0 -3
  80. package/lib/hivegpt.module.d.ts.map +0 -1
  81. package/lib/models/video.d.ts +0 -35
  82. package/lib/models/video.d.ts.map +0 -1
  83. package/lib/pipes/safe-html.pipe.d.ts +0 -8
  84. package/lib/pipes/safe-html.pipe.d.ts.map +0 -1
  85. package/lib/utils/utils.d.ts +0 -3
  86. package/lib/utils/utils.d.ts.map +0 -1
  87. package/public-api.d.ts.map +0 -1
@@ -0,0 +1,2143 @@
1
+ // import { Platform } from '@angular/cdk/platform';
2
+ import { HttpClient, HttpHeaders } from '@angular/common/http';
3
+ import { TranslationService } from '../translations/translation.service';
4
+
5
+ import {
6
+ ChangeDetectionStrategy,
7
+ ChangeDetectorRef,
8
+ Component,
9
+ ElementRef,
10
+ EventEmitter,
11
+ HostListener,
12
+ Input,
13
+ OnChanges,
14
+ OnInit,
15
+ Output,
16
+ QueryList,
17
+ Renderer2,
18
+ SimpleChanges,
19
+ ViewChild,
20
+ ViewChildren,
21
+ } from '@angular/core';
22
+ import { MatDrawer } from '@angular/material/sidenav';
23
+ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
24
+ import { of, Subscription } from 'rxjs';
25
+ import { catchError, switchMap } from 'rxjs/operators';
26
+ import { formatNow, formatTimeStamps } from '../../utils/utils';
27
+ import {
28
+ dev_environment,
29
+ prod_environment,
30
+ } from '../../../environments/environment';
31
+ import { ConversationService } from '../conversation.service';
32
+ import { Observable } from 'rxjs';
33
+ import { SocketService } from '../socket-service.service';
34
+
35
+ import { FormBuilder, Validators } from '@angular/forms';
36
+ import * as SpeechSDK from 'microsoft-cognitiveservices-speech-sdk';
37
+ import { BotsService } from '../bot.service';
38
+ import * as marked from 'marked'; // Import marked
39
+
40
+ @Component({
41
+ selector: 'hivegpt-chat-drawer-package',
42
+ templateUrl: './chat-drawer.component.html',
43
+ styleUrls: ['./chat-drawer.component.scss'],
44
+ changeDetection: ChangeDetectionStrategy.OnPush,
45
+ })
46
+ export class ChatDrawerComponent implements OnInit, OnChanges {
47
+ @ViewChild('chatMain') private chatMain: ElementRef;
48
+ @ViewChild('myInput') private myInput: ElementRef;
49
+ @ViewChildren('closeplaygroundbutton')
50
+ closePlaygroundButtons: QueryList<ElementRef>;
51
+ @ViewChild('drawer') drawer!: MatDrawer;
52
+ @ViewChild('sourcesDrawer') sourcesDrawer!: MatDrawer;
53
+ @ViewChild('editorsDrawer') editorsDrawer!: MatDrawer;
54
+ private bodyOverflowClass = 'body-overflow-hidden';
55
+ @ViewChild('myTextarea', { static: false })
56
+ myTextarea!: ElementRef<HTMLTextAreaElement>; // Reference to the textarea
57
+ isCollapsedTrue = false;
58
+ @Input() copilotName: string = 'HiveXGPT';
59
+ @Input() firstName!: string;
60
+ @Input() lastName!: string;
61
+ @Input() apiKey!: string;
62
+ @Input() bgBubbleAi!: string;
63
+ @Input() bgBubbleUser!: string;
64
+ @Input() bgGradient!: string[];
65
+ @Input() botName!: string;
66
+ @Input() botSkills!: string;
67
+ @Input() botId!: string;
68
+ @Input() orgId!: string;
69
+ @Input() closeButtonColor!: string;
70
+ @Input() closeButtonbgColor!: string;
71
+ @Input() credentials!: [];
72
+ @Input() dateTimeColor!: string;
73
+ @Input() dateTextColor!: string;
74
+ @Input() eventId!: string;
75
+ @Input() s27Token!: string;
76
+ @Input() eventName!: string;
77
+ @Input() botIcon!: string;
78
+ @Input() formFieldBgColor!: string;
79
+ @Input() formFieldTextColor!: string;
80
+ @Input() fullView!: boolean;
81
+ @Input() gradientColors!: string[];
82
+ @Input() greeting!: string;
83
+ @Input() messageTextColorAi!: string;
84
+ @Input() messageTextColorUser!: string;
85
+ @Input() rules!: string;
86
+ @Input() sendButtonColor!: string;
87
+ @Input() sendButtonTextColor!: string;
88
+ @Input() showClose!: boolean;
89
+ @Input() thumbsDownMessages!: string[];
90
+ @Input() thumbsUpMessage!: string;
91
+ @Input() timezone!: string;
92
+ @Input() unknownResponses!: [];
93
+ @Input() useOpenAi!: boolean;
94
+ @Input() userId!: string;
95
+ @Input() isDev!: boolean;
96
+
97
+ @Input() againButtonColor!: string[];
98
+ @Input() againButtonTextColor!: string[];
99
+ @Output() feedbackEvent = new EventEmitter<string>();
100
+ @Output() onCloseEvent = new EventEmitter<void>();
101
+ @Output() openPage = new EventEmitter<any>();
102
+ @Output() sessionActions = new EventEmitter<any>();
103
+ @Output() closeBot = new EventEmitter<any>();
104
+ @Output() connectWithUser = new EventEmitter<any>();
105
+ @Output() scheduleMeeting = new EventEmitter<string>();
106
+ @Output() refreshToken = new EventEmitter<any>();
107
+ @Output() openSupport = new EventEmitter<any>();
108
+
109
+ autogenKey = 'Autogen_eDJTtEU-NB0RtIpzq1w';
110
+ addToMyAgendaAction = 'add_to_my_agenda';
111
+ myUpcomingSessionAction = 'my_upcomming_session';
112
+ connectOrFollowAction = 'connect_or_follow';
113
+ aiResponse: string = '';
114
+ chatLog: any[] = [];
115
+ decoder = new TextDecoder();
116
+ feedbackDone: boolean = false;
117
+ greetingMsg: string = '';
118
+ hasBackdropValue: boolean = false;
119
+ input: string = '';
120
+ listenerAdded = false;
121
+ loading: boolean = false;
122
+ mode: string = 'over';
123
+ quickPrompts: any[] = [];
124
+ thumbsDownMsgIndex = 0;
125
+ userName: string = '';
126
+ showStartAgain: boolean = false;
127
+ isIOSDevice: boolean = false;
128
+ showFeedBackIconsIndex: number | null = null;
129
+ temperature: number = 1;
130
+ speakers = [];
131
+ environment: {
132
+ USERS_API;
133
+ BASE_URL;
134
+ AGENTS_API;
135
+ };
136
+ pendingRequests: any;
137
+ myConnections: any;
138
+ conversationKey: string;
139
+ conSessionKey: string = '';
140
+ isFetchDataFor: boolean;
141
+ is401: boolean;
142
+ msg: any;
143
+ chat: any;
144
+ isWorkflowOpen: boolean;
145
+ orgWorkflows: any;
146
+ openWorkflowInput: boolean;
147
+ selectedWorkflow: any;
148
+ workflowForm: any;
149
+ currentWorkflowActionProgress: number = 0;
150
+ currentWorkflowAction: string = '';
151
+ executingWorkflow: boolean;
152
+ workflowExecutionDetails: any;
153
+ showWorkflowExecutionDetails: any;
154
+ currentWorkflowExecutionDetails: any;
155
+
156
+ speechConfig: SpeechSDK.SpeechConfig;
157
+ recognizer: SpeechSDK.SpeechRecognizer;
158
+ recognizedText: string = '';
159
+ authorizationToken: string = '';
160
+ region: string = 'westeurope'; // Set your Azure region here
161
+ isRecording: boolean;
162
+
163
+ constructor(
164
+ private fb: FormBuilder,
165
+ private botService: BotsService,
166
+ private cdr: ChangeDetectorRef,
167
+ private http: HttpClient,
168
+ private sanitizer: DomSanitizer,
169
+ private elementRef: ElementRef,
170
+ private renderer: Renderer2,
171
+ private socketService: SocketService,
172
+ private conversationService: ConversationService, // private platform: Platform
173
+ private translationService: TranslationService
174
+ ) {
175
+ this.chatMain = new ElementRef(null);
176
+
177
+ // if (this.platform.IOS) {
178
+ // this.isIOSDevice = true;
179
+ // }
180
+ }
181
+ getTranslation(key: string) {
182
+ return this.translationService.getTranslation(key);
183
+ }
184
+ ngOnChanges(changes: SimpleChanges): void {
185
+ // Handle eventId changes to update translation service
186
+ if (changes.eventId && changes.eventId.currentValue) {
187
+ this.translationService.setEventId(changes.eventId.currentValue);
188
+ }
189
+
190
+ if (changes.s27Token) {
191
+ if (changes.s27Token.currentValue != changes.s27Token.previousValue) {
192
+ this.s27Token = changes.s27Token.currentValue;
193
+
194
+ console.log('isFetchDataFor: ', this.isFetchDataFor);
195
+ console.log('msg: ', this.msg);
196
+ console.log('chat: ', this.chat);
197
+ if (this.is401) {
198
+ if (this.isFetchDataFor) {
199
+ this.fetchDataFor(this.msg, this.chat);
200
+ } else {
201
+ this.fetchData(this.msg);
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ if (changes.orgId) {
208
+ if (
209
+ changes.orgId.currentValue != changes.orgId.previousValue &&
210
+ changes.orgId.currentValue
211
+ ) {
212
+ this.initializeSocket();
213
+
214
+ }
215
+ }
216
+ }
217
+
218
+
219
+ domainAuthorityValue: any = "prod-lite";
220
+
221
+ ngOnInit(): void {
222
+ // Set the eventId in translation service to get the correct language from localStorage
223
+ if (this.eventId) {
224
+ this.translationService.setEventId(this.eventId);
225
+ }
226
+
227
+ this.environment = this.isDev ? dev_environment : prod_environment;
228
+
229
+ const domain = window.location.hostname;
230
+
231
+ // Determine the header value based on the domain
232
+
233
+
234
+ if (domain.includes('pre-app.social27.com')) {
235
+ this.domainAuthorityValue = 'pre-prod-lite';
236
+ } else if (domain.includes('app.social27.com')) {
237
+ this.domainAuthorityValue = 'prod-lite';
238
+ } else if (domain.includes('hivegpt.io')) {
239
+ this.domainAuthorityValue = 'hivegpt';
240
+ }
241
+
242
+ // this.fetchMyConnections().subscribe();
243
+ // this.fetchPendingRequests().subscribe();
244
+
245
+ this.changeTemperature(this.temperature);
246
+ this.fetchBotConfig().subscribe(
247
+ (res) => {
248
+ this.cdr.markForCheck();
249
+
250
+ this.fetchChatHistory().subscribe(
251
+ (response) => {
252
+ this.loading = false;
253
+ this.mapChatHistory(response);
254
+ this.cdr.markForCheck();
255
+ },
256
+ (err) => {
257
+ console.error('Error fetching chat history:', err);
258
+ }
259
+ );
260
+ },
261
+ (err) => {
262
+ console.error('Error fetching chat history:', err);
263
+ }
264
+ );
265
+ // this.fetchAgents();
266
+ // this.fetchEditorContent();
267
+ this.cdr.markForCheck();
268
+ // this.initializeSocket();
269
+ this.botService.fetchSpeechAuthorizationToken(this.botId, this.apiKey, this.domainAuthorityValue).subscribe((token) => {
270
+ this.authorizationToken = token;
271
+ this.initializeSpeechRecognizer(token);
272
+ });
273
+ }
274
+
275
+ private eventSubscription: Subscription;
276
+ initializeSocket() {
277
+ try {
278
+ this.socketService.disconnectSocketConnection();
279
+ } catch (error) { }
280
+ setTimeout(() => {
281
+ this.socketService.connectSocketConnection();
282
+ setTimeout(() => {
283
+ console.log('YES INIT');
284
+ const conversation_id = this.conversationService.getKey(this.botId);
285
+
286
+ this.socketService.registerUserSpecificHiveSocket(
287
+ this.botId,
288
+ conversation_id,
289
+ this.orgId
290
+ );
291
+ setTimeout(() => {
292
+ this.listenSockets();
293
+ }, 300);
294
+ }, 200);
295
+ }, 300);
296
+ }
297
+
298
+ subscriptionNew: any;
299
+ socketData: any;
300
+
301
+ listenSockets() {
302
+ if (this.eventSubscription) {
303
+ this.eventSubscription.unsubscribe();
304
+ }
305
+ console.log('Listen Socket');
306
+ this.eventSubscription = this.conversationService
307
+ .getUserSpecificNotification()
308
+ .subscribe(
309
+ (res) => {
310
+ console.log('Listen Socket response');
311
+ console.log(res);
312
+ // Check if OtherFields exists in the response
313
+ if (res?.m?.OtherFields?.workflow_id) {
314
+ const {
315
+ percentage,
316
+ output,
317
+ action_name,
318
+ current_action_name,
319
+ workflow_execution_id,
320
+ time_stamp,
321
+ } = res?.m?.OtherFields;
322
+
323
+ this.currentWorkflowActionProgress = percentage;
324
+ this.currentWorkflowAction = action_name;
325
+
326
+ const actionIndex = this.workflowExecutionDetails.Actions.findIndex(
327
+ (a) => a.Name == current_action_name
328
+ );
329
+
330
+ if (actionIndex !== -1) {
331
+ this.workflowExecutionDetails.Actions[actionIndex][
332
+ 'Output'
333
+ ] = output;
334
+ this.workflowExecutionDetails.Actions[actionIndex][
335
+ 'InsertTimeStamp'
336
+ ] = formatTimeStamps(this.timezone, time_stamp);
337
+ } else {
338
+ console.error(`Action with name ${action_name} not found`);
339
+ }
340
+
341
+ this.currentWorkflowExecutionDetails = this.workflowExecutionDetails;
342
+
343
+ if (this.currentWorkflowActionProgress == 100) {
344
+ this.chatLog[this.chatLog.length - 1][
345
+ 'WorkflowExecutionId'
346
+ ] = workflow_execution_id;
347
+ this.isChatingWithAi = false;
348
+ this.executingWorkflow = false;
349
+ }
350
+
351
+ this.cdr.detectChanges();
352
+ } else if (res?.m?.OtherFields) {
353
+ const {
354
+ conversation_id,
355
+ bot_id,
356
+ message_id,
357
+ answer,
358
+ web_results,
359
+ search_results,
360
+ graphs,
361
+ execution_graphs,
362
+ suggestions,
363
+ } = res?.m?.OtherFields;
364
+ console.log('message_id1');
365
+ console.log(res?.m?.OtherFields);
366
+ var currentChatMessage = this.chatLog.find(
367
+ (p) => p._id == message_id
368
+ );
369
+ console.log(this.chatLog);
370
+ if (!currentChatMessage) {
371
+ console.log('message_id2');
372
+ console.log(message_id);
373
+ currentChatMessage = {
374
+ _id: message_id,
375
+ type: 'ai',
376
+ time: formatNow(this.timezone),
377
+ };
378
+
379
+ this.chatLog.push(currentChatMessage);
380
+
381
+ this.showFeedBackIconsIndex = this.chatLog.length - 1;
382
+ console.log('message_id3');
383
+ console.log(message_id);
384
+ this.cdr.detectChanges();
385
+ }
386
+
387
+ // Handle the fields based on their presence
388
+ if (search_results && Array.isArray(search_results)) {
389
+ console.log('Online Search Terms:', search_results);
390
+ currentChatMessage.searchTerms = search_results;
391
+ this.cdr.detectChanges();
392
+ }
393
+
394
+ if (web_results && Array.isArray(web_results)) {
395
+ console.log('Web Results:', web_results);
396
+ currentChatMessage.sourcesList = web_results;
397
+ currentChatMessage.displayedSources = web_results?.slice(0, 3); // First 3 cards
398
+ currentChatMessage.remainingSources = web_results?.slice(3); // Remaining items
399
+ this.cdr.detectChanges();
400
+ }
401
+
402
+ if (answer) {
403
+ this.isChatingWithAi = false;
404
+ console.log('Answer:', answer);
405
+
406
+ currentChatMessage.message = this.processMessageForDisplay(
407
+ answer
408
+ );
409
+ this.cdr.detectChanges();
410
+ this.scrollToBottom();
411
+ }
412
+
413
+ if (graphs && Array.isArray(graphs)) {
414
+ console.log('Graphs:', graphs);
415
+ currentChatMessage.graphs = graphs;
416
+ this.cdr.detectChanges();
417
+ }
418
+
419
+ if (execution_graphs && Array.isArray(execution_graphs)) {
420
+ console.log('Execution Graphs:', execution_graphs);
421
+ currentChatMessage.executionGraphs = execution_graphs;
422
+ this.cdr.detectChanges();
423
+ }
424
+
425
+ if (suggestions && Array.isArray(suggestions)) {
426
+ console.log('suggestions:', suggestions);
427
+ currentChatMessage.relatedListItems = suggestions;
428
+ this.cdr.detectChanges();
429
+ // Process online search terms as needed
430
+ }
431
+
432
+ // Add any other fields and their processing here
433
+ } else {
434
+ console.warn('OtherFields is missing in the response');
435
+ }
436
+ },
437
+ (err) => {
438
+ this.eventSubscription.unsubscribe();
439
+ console.error('Error in fetching data from socket', err);
440
+ }
441
+ );
442
+ }
443
+
444
+ initializeSocketAndListen() { }
445
+ handleEvent(data: any, type: string) {
446
+ switch (type) {
447
+ case 'webresult':
448
+ break;
449
+ case 'answer':
450
+ break;
451
+ case 'graph':
452
+ break;
453
+ default:
454
+ break;
455
+ }
456
+ }
457
+ ngOnDestroy(): void {
458
+ if (this.eventSubscription) {
459
+ this.eventSubscription.unsubscribe();
460
+ }
461
+ this.socketService.disconnectSocketConnection();
462
+ //this.socketService.close();
463
+ }
464
+ changeTemperature(newTemperature: number) {
465
+ if (this.loading) return;
466
+ this.temperature = newTemperature;
467
+ const wrapper = document.querySelector('.hivegpt-chat-wrapper');
468
+ // Remove existing theme classes from body
469
+ wrapper?.classList.remove('creative', 'balanced', 'precise');
470
+
471
+ switch (newTemperature) {
472
+ case 0:
473
+ wrapper?.classList.add('creative');
474
+ break;
475
+ case 1:
476
+ wrapper?.classList.add('balanced');
477
+ break;
478
+ case 2:
479
+ wrapper?.classList.add('precise');
480
+ break;
481
+ default:
482
+ break;
483
+ }
484
+ }
485
+
486
+ onStartAgain() {
487
+ if (this.loading) return;
488
+ this.showStartAgain = false;
489
+ this.chatLog = [];
490
+ this.chatLog.push({
491
+ type: 'ai',
492
+ message: this.greetingMsg,
493
+
494
+ time: formatNow(this.timezone),
495
+ });
496
+ this.archieveMessages().subscribe();
497
+ }
498
+
499
+ archieveMessages() {
500
+ const headers = new HttpHeaders({
501
+ 'Content-Type': 'application/json',
502
+ 'x-api-key': this.apiKey,
503
+ 'hive-bot-id': this.botId,
504
+ 'domain-authority': this.domainAuthorityValue
505
+ });
506
+ const url = `${this.environment.BASE_URL}/bot/clear-history/${this.botId}/${this.userId}`;
507
+ return this.http.post(url, { headers }).pipe(
508
+ switchMap((res: any) => {
509
+ return of(res);
510
+ }),
511
+ catchError((error) => {
512
+ return of(null);
513
+ })
514
+ );
515
+ }
516
+
517
+ triggerSupport() {
518
+
519
+ this.openSupport.emit();
520
+ }
521
+ fetchBotConfig() {
522
+ this.loading = true;
523
+ const headers = new HttpHeaders({
524
+ 'x-api-key': this.apiKey,
525
+ 'hive-bot-id': this.botId,
526
+ 'domain-authority': this.domainAuthorityValue
527
+ });
528
+ const url = `${this.environment.BASE_URL}/bots?bot_id=${this.botId}`;
529
+ return this.http.get(url, { headers }).pipe(
530
+ switchMap((res: any) => {
531
+ this.botName =this.getTranslation( res.Name);
532
+ this.botIcon = res.Icon;
533
+ this.botSkills = res?.Skills;
534
+ this.greetingMsg = res.Greeting;
535
+
536
+ this.thumbsDownMessages = res?.NegativeResponses?.length
537
+ ? res.NegativeResponses
538
+ : [
539
+ this.getTranslation( `We are sorry we've not been able to answer your question`),
540
+ ];
541
+ this.quickPrompts = res.QuickPrompts;
542
+ this.cdr.markForCheck();
543
+ this.loading = false;
544
+ return of(res);
545
+ }),
546
+ catchError((error) => {
547
+ console.error('Error fetching chatbot config: ', error);
548
+ this.loading = false;
549
+ return of(null);
550
+ })
551
+ );
552
+ }
553
+
554
+ fetchChatHistory(): Observable<any> {
555
+ this.loading = true;
556
+
557
+ this.conversationKey = this.conversationService.getKey(this.botId, false);
558
+ this.conSessionKey = this.conversationService.getSessionKey(this.botId, false);
559
+ const url = `${this.environment.BASE_URL}/conversations/${this.conversationKey}?session_id=${this.conSessionKey}`;
560
+ const headers = new HttpHeaders({
561
+ accept: 'application/json',
562
+ 'x-api-key': this.apiKey,
563
+ 'hive-bot-id': this.botId,
564
+ 'domain-authority': this.domainAuthorityValue
565
+ });
566
+
567
+ return this.http
568
+ .get(url, { headers })
569
+ .pipe(catchError(this.handleError<any>('fetchConversation')));
570
+ }
571
+
572
+ private handleError<T>(operation = 'operation', result?: T) {
573
+ return (error: any): Observable<T> => {
574
+ console.error(`${operation} failed: ${error.message}`);
575
+ return of(result as T);
576
+ };
577
+ }
578
+ // fetchChatHistory() {
579
+ // this.loading = true;
580
+ // const headers = new HttpHeaders({
581
+ // 'Content-Type': 'application/json',
582
+ // 'x-api-key': this.apiKey,
583
+ // });
584
+ // return this.http
585
+ // .get(`${this.environment.BASE_URL}/conversations/${this.conversationKey}`, { headers })
586
+ // .pipe(
587
+ // switchMap((res: any) => {
588
+ // this.loading = false;
589
+ // return of(res);
590
+ // }),
591
+ // catchError((error: any) => {
592
+ // console.error('Error fetching chat history: ', error);
593
+ // this.loading = false;
594
+ // return of(null);
595
+ // })
596
+ // );
597
+ // }
598
+
599
+ mapChatHistory(chats: any) {
600
+ this.chatLog.push({
601
+ type: 'ai',
602
+ message: this.greetingMsg,
603
+ time: formatNow(this.timezone),
604
+ });
605
+ if (chats && chats?.Messages?.length) {
606
+ chats?.Messages.forEach((chat: any) => {
607
+ if (chat.Type == 'user') {
608
+ this.chatLog.push({
609
+ type: 'user',
610
+ message: this.processMessageForDisplay(chat.Text),
611
+ time: formatTimeStamps(this.timezone, chat.InsertTimestamp),
612
+ copied: false,
613
+ isCollapsedTrue: false,
614
+ WorkflowExecutionId: chat.WorkflowExecutionId,
615
+ _id: chat._id
616
+ });
617
+ }
618
+ if (chat.Type == 'ai') {
619
+ var sourcesList = chat.WebLinks || [];
620
+ var displayedSources = chat.WebLinks.slice(0, 3); // First 3 cards
621
+ var remainingSources = chat.WebLinks.slice(3); // Remaining items
622
+
623
+ this.chatLog.push({
624
+ type: 'ai',
625
+ message: this.processMessageForDisplay(chat.Text),
626
+ executionGraphs: chat.ExecutionGraphs,
627
+ graphs: chat.Graphs,
628
+ searchTerms: chat.SearchTerms,
629
+ sourcesList: sourcesList,
630
+ displayedSources: displayedSources,
631
+ remainingSources: remainingSources,
632
+ time: formatTimeStamps(this.timezone, chat.InsertTimestamp),
633
+ copied: false,
634
+ isCollapsedTrue: false,
635
+ _id: chat._id
636
+ });
637
+ this.showFeedBackIconsIndex = this.chatLog.length - 1;
638
+ }
639
+ });
640
+ this.showStartAgain = true;
641
+ }
642
+ this.scrollToBottom();
643
+ this.cdr.markForCheck();
644
+ }
645
+
646
+ processMessage(message: string): SafeHtml {
647
+ if (!message || !(message?.length > 0)) {
648
+ return '';
649
+ }
650
+
651
+ // console.log('here is my message')
652
+ // console.log(message);
653
+
654
+ message = message.trim();
655
+
656
+ const markdownLinkRegex = /\[([^[]+)]\(([^)]+)\)/g;
657
+ const urlRegex = /(?<!href=")\bhttps?:\/\/\S+(?<![.,])/gi;
658
+
659
+ if (markdownLinkRegex.test(message)) {
660
+ const html = message.replace(
661
+ markdownLinkRegex,
662
+ '<a href="$2" target="_blank">$1</a>'
663
+ );
664
+ //console.log('Sanitized message: ', message);
665
+ return this.sanitizeHtml(html);
666
+ }
667
+
668
+ if (urlRegex.test(message)) {
669
+ const html = message.replace(
670
+ urlRegex,
671
+ '<a href="$&" target="_blank">$&</a>'
672
+ );
673
+ // console.log('Sanitized message: ', message);
674
+ return this.sanitizeHtml(html);
675
+ }
676
+
677
+ message = message.replace(/(?:\r\n|\r|\n)/g, '<br>');
678
+
679
+ message = message.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
680
+ // Convert Markdown headers to HTML headers
681
+ message = message.replace(/^(#{1,6})\s+(.*)$/gm, (match, hashes, text) => {
682
+ const level = hashes.length;
683
+ return `<h${level}>${text}</h${level}>`;
684
+ });
685
+
686
+ this.cdr.markForCheck();
687
+ const sanitizedMessage = this.sanitizeHtml(message);
688
+ return sanitizedMessage;
689
+ }
690
+
691
+ ngAfterViewChecked() {
692
+ const feedbackLinks = this.elementRef.nativeElement.querySelectorAll(
693
+ '.feedback-link'
694
+ );
695
+ feedbackLinks.forEach((link: any) => {
696
+ link.addEventListener(
697
+ 'click',
698
+ this.onFeedbackClick.bind(this, 'zendesk')
699
+ );
700
+ });
701
+ // if (this.elementRef.nativeElement.querySelector('.feedback-link')) {
702
+ // this.elementRef.nativeElement
703
+ // .querySelector('.feedback-link')
704
+ // .addEventListener('click', this.onFeedbackClick.bind(this, 'zendesk'));
705
+ // }
706
+ }
707
+
708
+ sanitizeHtml(html: string): SafeHtml {
709
+ return this.sanitizer.bypassSecurityTrustHtml(html);
710
+ }
711
+
712
+ onFeedbackClick(value: string) {
713
+ this.feedbackEvent.emit(value);
714
+ }
715
+
716
+ onClose() {
717
+ this.renderer.removeClass(document.body, this.bodyOverflowClass);
718
+ this.onCloseEvent.emit();
719
+ }
720
+
721
+ sendMessageWithTile(prompt: string) {
722
+ this.input = prompt;
723
+ this.fetchData();
724
+ this.scrollToBottom();
725
+ }
726
+ isChatingWithAi = false;
727
+ fetchData(msg = null) {
728
+ this.input = msg || this.input?.trim();
729
+ this.msg = this.input;
730
+ if (!this.input || this.loading) {
731
+ return;
732
+ }
733
+
734
+ this.chatLog.push({
735
+ type: 'user',
736
+ message: this.processMessageForDisplay(this.input),
737
+ time: formatNow(this.timezone),
738
+ copied: false,
739
+ isCollapsedTrue: false,
740
+ });
741
+
742
+ try {
743
+ const textarea = this.myInput.nativeElement;
744
+ textarea.style.height = 'hidden'; // Reset the height
745
+ textarea.style.height = `62px`;
746
+ } catch (error) { }
747
+ this.cdr.markForCheck();
748
+
749
+ this.aiResponse = '';
750
+ this.isChatingWithAi = true;
751
+
752
+ this.makeAskRequest(this.input, this.agents, this.conversationKey);
753
+ }
754
+ fetchDataFor(msg, chat) {
755
+ const inputMsg = msg?.trim();
756
+ if (!inputMsg || this.loading) {
757
+ return;
758
+ }
759
+ try {
760
+ chat.relatedListItems = [];
761
+ this.cdr.detectChanges();
762
+ } catch (error) { }
763
+
764
+ this.scrollToBottom();
765
+ this.chatLog.push({
766
+ type: 'user',
767
+ message: this.processMessageForDisplay(inputMsg),
768
+ time: formatNow(this.timezone),
769
+ copied: false,
770
+ isCollapsedTrue: false,
771
+ });
772
+
773
+ this.cdr.markForCheck();
774
+
775
+ this.aiResponse = '';
776
+ this.isChatingWithAi = true;
777
+
778
+ this.makeAskRequest(inputMsg, this.agents, this.conversationKey, msg, chat);
779
+ }
780
+ fetchSmallTalk() {
781
+ this.loading = true;
782
+ this.cdr.markForCheck();
783
+
784
+ const url = `${this.environment.BASE_URL}/bot/small-talk/${this.botId}/${this.userId}`;
785
+
786
+ this.http
787
+ .get<{ smallTalk: string }>(url, {
788
+ headers: {
789
+ 'x-api-key': this.apiKey,
790
+ 'hive-bot-id': this.botId,
791
+ 'domain-authority': this.domainAuthorityValue
792
+ },
793
+ })
794
+ .pipe(
795
+ catchError((error) => {
796
+ console.error('Error while fetching small talk:', error);
797
+
798
+ return of(null);
799
+ })
800
+ )
801
+ .subscribe((response) => {
802
+ this.loading = false;
803
+ this.cdr.markForCheck();
804
+
805
+ if (!response) {
806
+ return;
807
+ }
808
+
809
+ if (response && response.smallTalk) {
810
+ this.chatLog.push({
811
+ type: 'ai',
812
+ message: this.processMessage(response.smallTalk),
813
+ time: formatNow(this.timezone),
814
+ isFeedbackMsg: true,
815
+ });
816
+ this.showFeedBackIconsIndex = this.chatLog.length - 2;
817
+ // this.scrollToBottom();
818
+ this.cdr.markForCheck();
819
+ }
820
+ });
821
+ }
822
+
823
+ readAllChunks = (stream: any) => {
824
+ const reader = stream.getReader();
825
+ const allSuggestions: string[] = [];
826
+
827
+ reader.closed.catch((err: any) => {
828
+ if (err) {
829
+ console.error('Error reading stream: ', err);
830
+ }
831
+
832
+ this.isChatingWithAi = false;
833
+ this.scrollToBottom();
834
+ return;
835
+ });
836
+
837
+ return new ReadableStream({
838
+ start: (controller) => {
839
+ return this.pump(controller, reader, allSuggestions);
840
+ },
841
+ });
842
+ };
843
+
844
+ pump(controller: any, reader: any, allSuggestions: string[]) {
845
+ reader.read().then(({ done, value }: any) => {
846
+ const lastItem = this.chatLog[this.chatLog.length - 1];
847
+
848
+ if (done) {
849
+ lastItem.message = this.processMessageForDisplay(lastItem.message);
850
+ this.chatLog.pop();
851
+ this.chatLog.push(lastItem);
852
+ if (allSuggestions?.length) {
853
+ this.chatLog.push({
854
+ type: 'suggestions',
855
+ suggestions: allSuggestions,
856
+ });
857
+ }
858
+
859
+ controller.close();
860
+ this.isChatingWithAi = false;
861
+ // this.scrollToBottom();
862
+ this.cdr.markForCheck();
863
+ this.showStartAgain = true;
864
+
865
+ // setTimeout(() => {
866
+ // this.fetchSmallTalk();
867
+ // },1000)
868
+ return;
869
+ }
870
+
871
+ let decodedChunk = this.decoder.decode(value, { stream: true });
872
+ this.aiResponse += decodedChunk;
873
+ if (lastItem.type === 'ai') {
874
+ const suggestionsMatch = this.aiResponse.match(/<sug>(.*?)<\/sug>/g);
875
+ if (suggestionsMatch) {
876
+ suggestionsMatch.forEach((match) => {
877
+ this.aiResponse = this.aiResponse.replace(match, '');
878
+ allSuggestions.push(match?.replace(/<\/?sug>/g, ''));
879
+ });
880
+ }
881
+
882
+ lastItem.message = this.aiResponse;
883
+ this.cdr.markForCheck();
884
+ } else {
885
+ this.isChatingWithAi = false;
886
+
887
+ let aiFormattedData: any;
888
+
889
+ try {
890
+ console.log('parsing json ');
891
+ aiFormattedData = JSON.parse(JSON.parse(this.aiResponse));
892
+ } catch (e) {
893
+ try {
894
+ console.log('parsing json 2');
895
+ aiFormattedData = JSON.parse(this.aiResponse);
896
+ } catch (e) { }
897
+ }
898
+
899
+ console.log('parsing json done');
900
+
901
+ if (aiFormattedData && aiFormattedData?.section_id?.length > 0) {
902
+ if (
903
+ aiFormattedData.section_id == 'company_search' ||
904
+ aiFormattedData.section_id == 'user_search' ||
905
+ aiFormattedData.section_id == 'industry_company_search'
906
+ ) {
907
+ this.fetchMyConnections().subscribe();
908
+ this.fetchPendingRequests().subscribe();
909
+ }
910
+
911
+ if (aiFormattedData.section_id == this.myUpcomingSessionAction) {
912
+ var speakerIds = [];
913
+ aiFormattedData.content?.forEach((session) => {
914
+ speakerIds = [...speakerIds, ...session.speakers];
915
+ });
916
+
917
+ if (speakerIds?.length > 0) this.getSpeakersByStaffIds(speakerIds);
918
+ }
919
+
920
+ if (
921
+ aiFormattedData.section_id == this.addToMyAgendaAction &&
922
+ aiFormattedData.content?.length > 0
923
+ ) {
924
+ this.openPage.next({
925
+ sectionId: aiFormattedData.section_id,
926
+ sessionIds: aiFormattedData.content,
927
+ });
928
+ }
929
+
930
+ if (aiFormattedData.section_id == this.connectOrFollowAction) {
931
+ let usersLen = aiFormattedData.content?.length;
932
+ if (usersLen > 1) {
933
+ this.openPage.next({
934
+ sectionId: 'open_networking_drawer',
935
+ search: aiFormattedData.content,
936
+ });
937
+ } else if (usersLen == 1) {
938
+ this.openPage.next({
939
+ sectionId: aiFormattedData.section_id,
940
+ connetUserIds: [aiFormattedData.content[0].userId],
941
+ });
942
+ }
943
+ }
944
+
945
+ if (aiFormattedData.is_open_page == 'true') {
946
+ this.openPage.next({
947
+ sectionId: aiFormattedData.section_id,
948
+ search: aiFormattedData.content,
949
+ });
950
+
951
+ if (this.isMobileBrowser()) {
952
+ aiFormattedData.message +=
953
+ '\n\n' + '<a id="closeBotNow">Click Here</a> to see results.';
954
+ }
955
+ }
956
+
957
+ this.chatLog.push({
958
+ type: 'ai',
959
+ message: aiFormattedData.message,
960
+ action: aiFormattedData,
961
+ time: formatNow(this.timezone),
962
+ });
963
+
964
+ if (this.isMobileBrowser()) {
965
+ setTimeout(() => {
966
+ this.addCloseBotClickEvent();
967
+ }, 500);
968
+ }
969
+
970
+ this.aiResponse = '';
971
+ } else {
972
+ this.chatLog.push({
973
+ type: 'ai',
974
+ message: this.aiResponse,
975
+ time: formatNow(this.timezone),
976
+ });
977
+ }
978
+
979
+ this.showFeedBackIconsIndex = this.chatLog.length - 1;
980
+ this.cdr.markForCheck();
981
+ }
982
+
983
+ this.scrollToBottom();
984
+
985
+ // Enqueue the next data chunk into our target stream
986
+ controller.enqueue(value);
987
+ this.pump(controller, reader, allSuggestions);
988
+ });
989
+ }
990
+
991
+ submitFeedback(flag: boolean, message) {
992
+ console.log(message);
993
+
994
+ this.feedbackDone = true;
995
+ this.showFeedBackIconsIndex = null;
996
+ const conversation_id = this.conversationService.getKey(this.botId);
997
+ const url = `${this.environment.AGENTS_API}/Conversation/coPilot/${this.botId}/conversation/${conversation_id}/helpful-response`;
998
+ fetch(url, {
999
+ method: 'POST',
1000
+ headers: {
1001
+ 'Content-Type': 'application/json',
1002
+ 'apiKey': 'Conversation_WIz/qAm+EEmfOkFaUA/weA==',
1003
+ 'hive-bot-id': this.botId,
1004
+ 'domain-authority': this.domainAuthorityValue
1005
+ },
1006
+ body: JSON.stringify({ messageId: message._id, isHelpful: flag }),
1007
+ }).then(() => {
1008
+ if (flag) {
1009
+ this.chatLog.push({
1010
+ type: 'ai',
1011
+ message:
1012
+ this.thumbsUpMessage ||
1013
+ this.getTranslation('May I assist you with anything else'),
1014
+ time: formatNow(this.timezone),
1015
+ isFeedbackMsg: true,
1016
+ });
1017
+
1018
+ this.scrollToBottom();
1019
+ this.cdr.markForCheck();
1020
+ this.feedbackDone = false;
1021
+ this.showFeedBackIconsIndex = null;
1022
+ return;
1023
+ }
1024
+
1025
+ this.chatLog.push({
1026
+ type: 'ai',
1027
+ message: this.processMessage(
1028
+ this.thumbsDownMessages[this.thumbsDownMsgIndex]
1029
+ ),
1030
+ time: formatNow(this.timezone),
1031
+ isFeedbackMsg: true,
1032
+ });
1033
+ this.thumbsDownMsgIndex =
1034
+ (this.thumbsDownMsgIndex + 1) % this.thumbsDownMessages.length;
1035
+ this.scrollToBottom();
1036
+ this.cdr.markForCheck();
1037
+ setTimeout(() => {
1038
+ const supportLink = document.getElementById('supportLink88');
1039
+ if (supportLink) {
1040
+ supportLink.addEventListener('click', this.triggerSupport.bind(this));
1041
+
1042
+ }
1043
+ }, 200);
1044
+ this.feedbackDone = false;
1045
+ this.showFeedBackIconsIndex = null;
1046
+ });
1047
+ }
1048
+ handleKeydown(event: KeyboardEvent) {
1049
+ if (event.key === 'Enter' && !event.shiftKey) {
1050
+ // Prevent default behavior (new line)
1051
+ event.preventDefault();
1052
+ // Call your submit function
1053
+ this.handleSubmit(event);
1054
+ }
1055
+ }
1056
+ handleSubmit(event) {
1057
+ this.fetchData();
1058
+ this.scrollToBottom();
1059
+
1060
+ }
1061
+
1062
+ handleUpClick(idx: any) {
1063
+ if (this.feedbackDone) {
1064
+ return;
1065
+ }
1066
+
1067
+ this.submitFeedback(true, this.chatLog[idx]);
1068
+ this.chatLog[idx].liked = !this.chatLog[idx].liked;
1069
+
1070
+ if (this.chatLog[idx].unliked) {
1071
+ this.chatLog[idx].unliked = !this.chatLog[idx].unliked;
1072
+ }
1073
+
1074
+ this.cdr.markForCheck();
1075
+ }
1076
+
1077
+ handleDownClick(idx: any) {
1078
+ if (this.feedbackDone) return;
1079
+ this.submitFeedback(false, this.chatLog[idx]);
1080
+ this.chatLog[idx].unliked = !this.chatLog[idx].unliked;
1081
+ if (this.chatLog[idx].liked)
1082
+ this.chatLog[idx].liked = !this.chatLog[idx].liked;
1083
+ }
1084
+ // handleCopyClick(index: any) {
1085
+ // // Copy the message to the clipboard
1086
+ // const contentToCopy = this.chatLog[index].message;
1087
+ // console.log('contentToCopy');
1088
+ // console.log(contentToCopy);
1089
+ // navigator.clipboard.writeText(contentToCopy).then(() => {
1090
+ // // Indicate that the message was copied
1091
+ // this.chatLog[index].copied = true;
1092
+ // this.cdr.detectChanges();
1093
+ // // Reset the copied state after a delay
1094
+ // setTimeout(() => {
1095
+ // this.chatLog[index].copied = false;
1096
+ // this.cdr.detectChanges();
1097
+ // }, 2000); // Reset after 2 seconds
1098
+ // });
1099
+ // }
1100
+ copyText(id, index) {
1101
+ // Get the text element
1102
+ var textElement = document.getElementById(id);
1103
+
1104
+ // Create a temporary textarea element to copy the text
1105
+ var tempTextArea = document.createElement('textarea');
1106
+ tempTextArea.value = textElement.innerText;
1107
+
1108
+ // Append the textarea to the body (necessary for the execCommand to work)
1109
+ document.body.appendChild(tempTextArea);
1110
+
1111
+ // Select the text inside the textarea
1112
+ tempTextArea.select();
1113
+
1114
+ // Copy the text to the clipboard
1115
+ document.execCommand('copy');
1116
+
1117
+ // Remove the temporary textarea
1118
+ document.body.removeChild(tempTextArea);
1119
+
1120
+ // Optionally, you can alert the user or change the button text to indicate the copy was successful
1121
+ // alert('Text copied to clipboard!');
1122
+
1123
+ this.chatLog[index].copied = true;
1124
+ this.cdr.detectChanges();
1125
+ // Reset the copied state after a delay
1126
+ setTimeout(() => {
1127
+ this.chatLog[index].copied = false;
1128
+ this.cdr.detectChanges();
1129
+ }, 2000); // Reset after 2 seconds
1130
+ }
1131
+ handleCopyClick(index: any) {
1132
+ // Copy the message to the clipboard
1133
+ const contentToCopy = this.chatLog[index].message;
1134
+ const resutlt = this.copyText('messageText_' + index, index);
1135
+ }
1136
+
1137
+ sanitizeHTML(html: string): string {
1138
+ const doc = new DOMParser().parseFromString(html, 'text/html');
1139
+
1140
+ // Create a new document fragment to hold the simplified content
1141
+ const fragment = document.createDocumentFragment();
1142
+
1143
+ // Append the children of the body of the parsed document to the fragment
1144
+ Array.from(doc.body.childNodes).forEach((node) => {
1145
+ fragment.appendChild(node.cloneNode(true));
1146
+ });
1147
+
1148
+ // Create a new div element to hold the simplified HTML
1149
+ const simplifiedDiv = document.createElement('div');
1150
+ simplifiedDiv.appendChild(fragment);
1151
+
1152
+ // Remove complex tags or attributes as needed
1153
+ // Example: remove scripts
1154
+ simplifiedDiv
1155
+ .querySelectorAll('script')
1156
+ .forEach((script) => script.remove());
1157
+
1158
+ // Return the simplified HTML as a string
1159
+ return simplifiedDiv.innerHTML;
1160
+ }
1161
+
1162
+ currentMessageForEditor: any = '';
1163
+ currentIndexForEditor: any = -1;
1164
+ handleEditorClick(index: any) {
1165
+ if (this.currentIndexForEditor == -1) {
1166
+ this.currentIndexForEditor = index;
1167
+ this.currentMessageForEditor = this.sanitizeHTML(
1168
+ this.chatLog[index].message
1169
+ );
1170
+ this.currentMessageForEditor = this.currentMessageForEditor.replace(
1171
+ 'SafeValue must use [property]=binding:',
1172
+ ''
1173
+ );
1174
+
1175
+ this.cdr.detectChanges();
1176
+ } else {
1177
+ if (this.currentIndexForEditor == index) {
1178
+ this.currentMessageForEditor += this.sanitizeHTML(
1179
+ this.chatLog[index].message
1180
+ );
1181
+ this.currentMessageForEditor = this.currentMessageForEditor.replace(
1182
+ 'SafeValue must use [property]=binding:',
1183
+ ''
1184
+ );
1185
+ this.cdr.detectChanges();
1186
+ } else {
1187
+ this.currentIndexForEditor = index;
1188
+ this.currentMessageForEditor = this.sanitizeHTML(
1189
+ this.chatLog[index].message
1190
+ );
1191
+ this.currentMessageForEditor = this.currentMessageForEditor.replace(
1192
+ 'SafeValue must use [property]=binding:',
1193
+ ''
1194
+ );
1195
+ this.cdr.detectChanges();
1196
+ }
1197
+ }
1198
+ this.chatLog[index].isEditor = true;
1199
+ this.cdr.detectChanges();
1200
+ // Reset the copied state after a delay
1201
+ setTimeout(() => {
1202
+ this.chatLog[index].isEditor = false;
1203
+ this.cdr.detectChanges();
1204
+ }, 2000); // Reset after 2 seconds
1205
+ this.editorsDrawer.open();
1206
+ const button = document.getElementById('botcloseplaygroundbutton');
1207
+ if (button) {
1208
+ button.style.display = 'none';
1209
+ }
1210
+ this.cdr.detectChanges();
1211
+ }
1212
+ scrollToBottom() {
1213
+ let counter = 0;
1214
+ const interval = setInterval(() => {
1215
+ this.chatMain.nativeElement.scrollTop = this.chatMain.nativeElement.scrollHeight;
1216
+ if (counter++ > 5) clearInterval(interval);
1217
+ }, 5);
1218
+ }
1219
+
1220
+ handleAction(action: any) {
1221
+ console.info('incoming action from the chatbot AI');
1222
+ console.info(action);
1223
+
1224
+ if (action?.content) {
1225
+ }
1226
+ }
1227
+
1228
+ ngAfterViewInit() {
1229
+ // Check if the drawer is initially open and apply overflow hidden to body if so
1230
+ if (this.drawer.opened) {
1231
+ this.setBodyOverflow();
1232
+ }
1233
+
1234
+ // Listen to changes in the drawer being opened or closed
1235
+ this.drawer.openedChange.subscribe((opened: boolean) => {
1236
+ if (opened) {
1237
+ this.setBodyOverflow();
1238
+ } else {
1239
+ this.removeBodyOverflow();
1240
+ }
1241
+ });
1242
+
1243
+ this.drawer.openedChange.subscribe((opened) => {
1244
+ if (opened) {
1245
+ setTimeout(() => {
1246
+ if (this.myTextarea && this.myTextarea.nativeElement) {
1247
+ this.myTextarea.nativeElement.focus(); // Focus on the textarea
1248
+ }
1249
+ });
1250
+ }
1251
+ });
1252
+
1253
+
1254
+
1255
+ }
1256
+
1257
+ private setBodyOverflow() {
1258
+ this.renderer.addClass(document.body, this.bodyOverflowClass);
1259
+ }
1260
+
1261
+ private removeBodyOverflow() {
1262
+ this.renderer.removeClass(document.body, this.bodyOverflowClass);
1263
+ }
1264
+
1265
+ getSpeakersByStaffIds(ids) {
1266
+ const url = `${this.environment.USERS_API}/events/${this.eventId}/users/get-by-staff-ids`;
1267
+ fetch(url, {
1268
+ method: 'POST',
1269
+ headers: {
1270
+ 'Content-Type': 'application/json',
1271
+ Authorization: 'Bearer ' + 'your_token_here',
1272
+ },
1273
+ body: JSON.stringify(ids),
1274
+ })
1275
+ .then((response) => {
1276
+ if (response.ok) {
1277
+ return response.json(); // Parse the JSON body of the response
1278
+ } else {
1279
+ throw new Error('Network response was not ok.');
1280
+ }
1281
+ })
1282
+ .then((data) => {
1283
+ if (data?.length > 0) {
1284
+ data.forEach((speaker) => {
1285
+ this.speakers[speaker.id] = speaker;
1286
+ });
1287
+
1288
+ this.cdr.markForCheck();
1289
+ }
1290
+ })
1291
+ .catch((err) => {
1292
+ console.error('Error fetching data:', err);
1293
+ this.loading = false;
1294
+ });
1295
+ }
1296
+
1297
+ performSessionAction(sessionId, action) {
1298
+ this.sessionActions.next({
1299
+ sessionId,
1300
+ action,
1301
+ });
1302
+ }
1303
+
1304
+ addCloseBotClickEvent() {
1305
+ const element = this.elementRef.nativeElement.querySelector('#closeBotNow');
1306
+ if (element) {
1307
+ this.renderer.listen(element, 'click', () => {
1308
+ this.closeBot.next();
1309
+ });
1310
+ }
1311
+ }
1312
+
1313
+ isMobileBrowser() {
1314
+ return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
1315
+ navigator.userAgent
1316
+ );
1317
+ }
1318
+
1319
+ connectToUser(userId) {
1320
+ this.connectWithUser.emit({
1321
+ connect: !this.canDisconnect(userId),
1322
+ userId,
1323
+ });
1324
+
1325
+ setTimeout(() => {
1326
+ this.fetchMyConnections().subscribe((res) => {
1327
+ this.cdr.markForCheck();
1328
+ });
1329
+ this.fetchPendingRequests().subscribe((res) => {
1330
+ this.cdr.markForCheck();
1331
+ });
1332
+ }, 500);
1333
+ }
1334
+
1335
+ scheduleMeetingWithUser(user) {
1336
+ this.scheduleMeeting.emit(user);
1337
+ }
1338
+
1339
+ canConnect(userId) {
1340
+ return !(
1341
+ this.canDisconnect(userId) ||
1342
+ this.pendingRequests.find((a) => a == userId)
1343
+ );
1344
+ }
1345
+
1346
+ canDisconnect(userId) {
1347
+ return this.myConnections.find((conn) => conn.userId == userId);
1348
+ }
1349
+
1350
+ fetchPendingRequests() {
1351
+ const headers = new HttpHeaders({
1352
+ 'Content-Type': 'application/json',
1353
+ apiKey: this.autogenKey,
1354
+ });
1355
+ return this.http
1356
+ .get(
1357
+ `${this.environment.USERS_API}/events/${this.eventId}/connection-requests/autogen/pending-sent-requests?userId=${this.userId}`,
1358
+ { headers }
1359
+ )
1360
+ .pipe(
1361
+ switchMap((res: any) => {
1362
+ this.pendingRequests = res;
1363
+ this.cdr.markForCheck();
1364
+ return of(res);
1365
+ }),
1366
+ catchError((error: any) => {
1367
+ console.error('Error fetching pending requests: ', error);
1368
+ return of(null);
1369
+ })
1370
+ );
1371
+ }
1372
+
1373
+ fetchMyConnections() {
1374
+ const headers = new HttpHeaders({
1375
+ 'Content-Type': 'application/json',
1376
+ apiKey: this.autogenKey,
1377
+ });
1378
+ return this.http
1379
+ .get(
1380
+ `${this.environment.USERS_API}/events/${this.eventId}/users-connections/autogen?userId=${this.userId}`,
1381
+ { headers }
1382
+ )
1383
+ .pipe(
1384
+ switchMap((res: any) => {
1385
+ this.myConnections = res;
1386
+ this.cdr.markForCheck();
1387
+ return of(res);
1388
+ }),
1389
+ catchError((error: any) => {
1390
+ console.error('Error fetching pending requests: ', error);
1391
+ return of(null);
1392
+ })
1393
+ );
1394
+ }
1395
+
1396
+ isDropdownOpen: boolean = false;
1397
+ agents: any;
1398
+ selectedAgents = [];
1399
+ allSelected = false;
1400
+ // Toggle the dropdown visibility
1401
+ toggleDropdown() {
1402
+ if (!this.agents)
1403
+ this.fetchAgents();
1404
+ this.isDropdownOpen = !this.isDropdownOpen;
1405
+ this.cdr.detectChanges();
1406
+ }
1407
+
1408
+ onSelectAll(event: Event): void {
1409
+ this.agents?.forEach((agent) => (agent.selected = false));
1410
+ this.cdr.detectChanges();
1411
+ }
1412
+
1413
+ onAgentChange(agent: any): void {
1414
+ //agent.selected = !agent.selected;
1415
+ //console.log(agent);
1416
+ let agentFound = this.agents.filter((p) => p.id == agent.id);
1417
+ if (agentFound && agentFound.length > 0) {
1418
+ agentFound[0].selected = !agentFound[0].selected;
1419
+ this.cdr.detectChanges();
1420
+ }
1421
+ this.cdr.detectChanges();
1422
+ }
1423
+
1424
+ areAllSelected(): boolean {
1425
+ return this.agents?.every((agent) => !agent.selected);
1426
+ }
1427
+
1428
+ getDropdownHeaderText(): string {
1429
+ const selectedAgents = this.agents?.filter((agent) => agent.selected);
1430
+ if (!selectedAgents) {
1431
+ return 'All Agents';
1432
+ } else {
1433
+ if (selectedAgents && selectedAgents?.length === 0) {
1434
+ return 'All Agents';
1435
+ } else {
1436
+ return selectedAgents?.length > 1
1437
+ ? `${selectedAgents?.length} Agents Selected`
1438
+ : `${selectedAgents?.length} Agent Selected`;
1439
+ }
1440
+ }
1441
+ }
1442
+ fetchAgents_http() {
1443
+ this.loading = true;
1444
+ const url = `${this.environment.AGENTS_API}/CoPilot/${this.botId}/active-agents`;
1445
+ const headers = new HttpHeaders({
1446
+ 'Content-Type': 'application/json',
1447
+ });
1448
+
1449
+ return this.http.post(url, {}, { headers }).pipe(
1450
+ switchMap((res: any) => {
1451
+ if (res) {
1452
+ this.agents = res.map((agent) => ({
1453
+ ...agent,
1454
+ selected: false,
1455
+ }));
1456
+ }
1457
+ this.cdr.markForCheck();
1458
+
1459
+ return of(res);
1460
+ }),
1461
+ catchError((error) => {
1462
+ console.error('Error fetching chatbot config: ', error);
1463
+
1464
+ return of(null);
1465
+ })
1466
+ );
1467
+ }
1468
+ isDocInEditMode = false;
1469
+ documentContent: any;
1470
+
1471
+ conversationId: any;
1472
+ isContentLoaded = false;
1473
+
1474
+ fetchContent_http() {
1475
+ this.isDocInEditMode = false;
1476
+ this.isContentLoaded = false;
1477
+ console.log('API call function');
1478
+ this.loading = true;
1479
+ const conversation_id = this.conversationService.getKey(this.botId);
1480
+ this.conversationId = conversation_id;
1481
+ const url = `${this.environment.AGENTS_API}/ConversationDocuments?conversationId=${conversation_id}&botId=${this.botId}`;
1482
+ const headers = new HttpHeaders({
1483
+ 'Content-Type': 'application/json',
1484
+ apiKey: 'WIz/qAm+EEmfOkFaUA/weA==',
1485
+ 'domain-authority': this.domainAuthorityValue
1486
+ });
1487
+
1488
+ return this.http.get(url, { headers }).pipe(
1489
+ switchMap((res: any) => {
1490
+ if (res) {
1491
+ this.isDocInEditMode = true;
1492
+ this.documentContent = res;
1493
+ console.log('Get API callled success');
1494
+ this.isContentLoaded = true;
1495
+ console.log(res);
1496
+ }
1497
+ this.cdr.markForCheck();
1498
+
1499
+ return of(res);
1500
+ }),
1501
+ catchError((error) => {
1502
+ console.error('Error fetching chatbot config DJ: ', error);
1503
+ this.isDocInEditMode = false;
1504
+ this.isContentLoaded = true;
1505
+
1506
+ if (error?.status == 404) {
1507
+ console.log('dash');
1508
+ this.isDocInEditMode = false;
1509
+ this.isContentLoaded = true;
1510
+ }
1511
+ return of(null);
1512
+ })
1513
+ );
1514
+ }
1515
+
1516
+ fetchAgents() {
1517
+ this.fetchAgents_http().subscribe();
1518
+ }
1519
+
1520
+ fetchEditorContent() {
1521
+ this.fetchContent_http().subscribe();
1522
+ }
1523
+
1524
+ // events/${eventId}/users-connections
1525
+ processMessageForDisplay(markdown: string): SafeHtml {
1526
+ try {
1527
+ // Create a custom renderer to modify <a> tags
1528
+ const renderer = new marked.Renderer();
1529
+
1530
+ // Customize anchor tags to include target="_blank"
1531
+ renderer.link = (href: string, title: string, text: string) => {
1532
+ return `<a href="${href}" title="${title || ''
1533
+ }" target="_blank">${text}</a>`;
1534
+ };
1535
+
1536
+ // Parse the markdown content to HTML using marked with the custom renderer
1537
+ const markdownContent = marked.parse(markdown, { renderer: renderer });
1538
+
1539
+ // Sanitize the parsed HTML using Angular's DomSanitizer
1540
+ const sanitizedHtml = this.sanitizer.bypassSecurityTrustHtml(
1541
+ markdownContent
1542
+ );
1543
+
1544
+ // Return the safe HTML content for display
1545
+ return sanitizedHtml;
1546
+ } catch (error) {
1547
+ console.error('Error processing markdown:', error);
1548
+ return ''; // Return an empty string or handle the error appropriately
1549
+ }
1550
+ }
1551
+
1552
+ prepareHtml(markdown: string): string {
1553
+ if (!markdown || !(markdown.length > 0)) {
1554
+ console.error('Input Markdown is null or empty');
1555
+ return '';
1556
+ }
1557
+
1558
+ // Convert Markdown headers (### or ##) to <strong> for bold headings
1559
+ let html = markdown.replace(/^(#{1,6})\s+(.*)$/gm, (match, hashes, text) => {
1560
+ const level = hashes.length;
1561
+ if (level === 3) {
1562
+ return `<h3><strong>${text}</strong></h3>`;
1563
+ } else if (level === 4) {
1564
+ return `<h4><strong>${text}</strong></h4>`;
1565
+ }
1566
+ return `<strong>${text}</strong>`;
1567
+ });
1568
+
1569
+ // Convert Markdown code blocks with language to preformatted HTML
1570
+ html = html.replace(/```(\w+)?\n([\s\S]*?)```/g, (match, lang, code) => {
1571
+ const escapedCode = this.escapeHtml(code);
1572
+ const language = lang || 'plaintext';
1573
+
1574
+ // Create a copy button for the code block
1575
+ return `
1576
+ <div class="code-container">
1577
+ <button id="copy-button" class="copy-button" (click)="copyToClipboard('\`${escapedCode}\`')">${this.getTranslation('Copy')}</button>
1578
+ <pre class="code_block diff"><code class="language-${language}">${escapedCode}</code></pre>
1579
+ </div>`;
1580
+ });
1581
+
1582
+ // Convert inline code (wrapped in `backticks`) to inline <code> tags
1583
+ html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
1584
+
1585
+ // Convert Markdown bold to HTML <strong>
1586
+ html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
1587
+
1588
+ // Convert numbered lists
1589
+ html = html.replace(/^\d+\.\s+(.*)$/gm, '<li>$1</li>');
1590
+
1591
+ // Convert bullet point lists
1592
+ html = html.replace(/^\-\s+(.*)$/gm, '<li>$1</li>');
1593
+
1594
+ // Convert Markdown links to HTML links
1595
+ html = html.replace(/\[([^\]]+)]\(([^)]+)\)/g, '<a href="$2" target="_blank">$1</a>');
1596
+
1597
+ // Convert new lines to <br> tags for paragraphs
1598
+ html = html.replace(/(?:\r\n|\r|\n)/g, '<br>');
1599
+
1600
+ return html;
1601
+ }
1602
+
1603
+ // Helper function to escape HTML characters for code blocks
1604
+ escapeHtml(code: string): string {
1605
+ return code
1606
+ .replace(/&/g, '&amp;')
1607
+ .replace(/</g, '&lt;')
1608
+ .replace(/>/g, '&gt;')
1609
+ .replace(/"/g, '&quot;')
1610
+ .replace(/'/g, '&#039;');
1611
+ }
1612
+
1613
+ // Function to copy text to clipboard
1614
+ public copyToClipboard(text: string) {
1615
+ navigator.clipboard.writeText(text).then(() => {
1616
+ alert('Code copied to clipboard!');
1617
+ }, (err) => {
1618
+ console.error('Could not copy text: ', err);
1619
+ });
1620
+ }
1621
+
1622
+
1623
+
1624
+
1625
+
1626
+
1627
+ isCollapsed = false;
1628
+ isCollapsedForGraph = false;
1629
+ isCollapsedForFGraph = false;
1630
+ toggleCollapse() {
1631
+ this.isCollapsed = !this.isCollapsed;
1632
+ this.cdr.detectChanges();
1633
+ }
1634
+
1635
+ toggleCollapseGraph() {
1636
+ this.isCollapsedForGraph = !this.isCollapsedForGraph;
1637
+ this.cdr.detectChanges();
1638
+ }
1639
+ toggleCollapseFGraph() {
1640
+ this.isCollapsedForFGraph = !this.isCollapsedForFGraph;
1641
+ this.cdr.detectChanges();
1642
+ }
1643
+ // [
1644
+ // {
1645
+ // "title": "AI News January 2024: In-Depth and Concise - The AI Track",
1646
+ // "desc": "Each month, we compile significant news, trends, and happenings in AI, providing detailed summaries with key points in bullet form for concise yet complete understanding.",
1647
+ // "link": "https://theaitrack.com/ai-news-january-2024/"
1648
+ // },
1649
+ // {
1650
+ // "title": "Top AI News, January 2024 - Everypixel Journal",
1651
+ // "desc": "In this monthly roundup, we spotlight the top AI news stories from January, including the OpenAI vs. The New York Times Lawsuit.",
1652
+ // "link": "https://journal.everypixel.com/top-ai-news-january-2024"
1653
+ // },
1654
+ // {
1655
+ // "title": "AI News July 2024: In-Depth and Concise - The AI Track",
1656
+ // "desc": "This page features AI News for July 2024, highlighting significant events such as Canva acquiring Leonardo AI.",
1657
+ // "link": "https://theaitrack.com/ai-news-july-2024-in-depth-and-concise/"
1658
+ // },
1659
+ // {
1660
+ // "title": "January news roundup: What's new in the world of AI? - Pluralsight",
1661
+ // "desc": "OpenAI’s new GPT store, business-ready ChatGPT plans, and a predicted rise in AI-powered cybercrime.",
1662
+ // "link": "https://www.pluralsight.com/resources/blog/data/ai-this-month-january-2024"
1663
+ // },
1664
+ // {
1665
+ // "title": "AI News August 2024: In-Depth and Concise - The AI Track",
1666
+ // "desc": "This page features AI News for August 2024, with highlights such as Nvidia delaying the “Blackwell” B200 AI chips delivery.",
1667
+ // "link": "https://theaitrack.com/ai-news-august-2024-in-depth-and-concise-duplicate/"
1668
+ // }
1669
+ // ]
1670
+ dateTime = { now: new Date().toISOString() };
1671
+ // Extracts the domain from a URL
1672
+ getDomainName(url: string): string {
1673
+ try {
1674
+ const { hostname } = new URL(url);
1675
+ return hostname.replace(/^www\./, ''); // Remove 'www.' if present
1676
+ } catch {
1677
+ return 'unknown';
1678
+ }
1679
+ }
1680
+
1681
+ // Generates the favicon URL
1682
+ getFaviconUrl(url: string): string {
1683
+ const domain = this.getDomainName(url);
1684
+ return `https://www.google.com/s2/favicons?sz=128&domain=${domain}`;
1685
+ }
1686
+ currentSourcesList: any = [];
1687
+ onCardClick(sources): void {
1688
+ this.currentSourcesList = sources;
1689
+ this.cdr.detectChanges();
1690
+ this.sourcesDrawer.open();
1691
+ const button = document.getElementById('botcloseplaygroundbutton');
1692
+ if (button) {
1693
+ button.style.display = 'none';
1694
+ }
1695
+ }
1696
+
1697
+ isShowEditorButton = true;
1698
+
1699
+ openOuterEditor() {
1700
+ this.fetchEditorContent();
1701
+ this.editorsDrawer.open();
1702
+ this.isDrawerOpen = true;
1703
+ this.isShowEditorButton = false;
1704
+ this.cdr.detectChanges();
1705
+
1706
+ const button = document.getElementById('botcloseplaygroundbutton');
1707
+ if (button) {
1708
+ button.style.display = 'none';
1709
+ }
1710
+ }
1711
+
1712
+ onCloseEditor() {
1713
+ this.editorsDrawer.close();
1714
+ this.isDrawerOpen = false;
1715
+ this.isShowEditorButton = true;
1716
+ this.cdr.detectChanges(); // Trigger change detection if needed
1717
+ this.onDrawerClosed();
1718
+ }
1719
+
1720
+ onCloseSource() {
1721
+ this.sourcesDrawer.close();
1722
+ this.isDrawerOpen = false;
1723
+ this.cdr.detectChanges(); // Trigger change detection if needed
1724
+ this.onDrawerClosed();
1725
+ }
1726
+ onDrawerClosed() {
1727
+ setTimeout(() => {
1728
+ this.isDrawerOpen = true;
1729
+ this.cdr.detectChanges(); // Trigger change detection if needed
1730
+ // Use ngClass to dynamically apply the class
1731
+ const button = document.getElementById('botcloseplaygroundbutton');
1732
+ if (button) {
1733
+ button.style.display = 'block';
1734
+ }
1735
+ }, 800);
1736
+ }
1737
+ isDrawerOpen = true;
1738
+
1739
+ toggleDrawer(todo) {
1740
+ this.isDrawerOpen = todo;
1741
+ this.cdr.detectChanges();
1742
+ this.updateButtonVisibility();
1743
+ }
1744
+ updateButtonVisibility() {
1745
+ const button = document.getElementById('botcloseplaygroundbutton');
1746
+ if (button) {
1747
+ button.style.display = this.isDrawerOpen ? 'block' : 'none';
1748
+ }
1749
+ }
1750
+ openLinkInNewTab(link: string): void {
1751
+ window.open(link, '_blank');
1752
+ }
1753
+ adjustTextareaHeight(event: any): void {
1754
+ try {
1755
+ if (event.key === 'Enter' && !event.shiftKey) {
1756
+ // Prevents a new line from being added
1757
+ event.preventDefault();
1758
+ }
1759
+ } catch (error) {
1760
+
1761
+ }
1762
+ const textarea = event.target as HTMLTextAreaElement;
1763
+ textarea.style.height = 'auto'; // Reset the height
1764
+ textarea.style.height = `${textarea.scrollHeight}px`; // Adjust height to match content
1765
+ // Ensure the height doesn't exceed the max-height set in CSS
1766
+ if (textarea.scrollHeight > 150) {
1767
+ textarea.style.height = `150px`; // Adjust height to match content
1768
+ textarea.style.overflowY = 'auto'; // Enable scrolling if content exceeds 400px
1769
+ } else {
1770
+ textarea.style.overflowY = 'hidden'; // Hide scrollbar if content is within limits
1771
+ }
1772
+ }
1773
+
1774
+ toggleWorkflows(value = null) {
1775
+
1776
+ if (!this.checkForCop29BotId()) {
1777
+ this.botService.getWorkflowsByOrgId(this.orgId).subscribe((res) => {
1778
+ this.orgWorkflows = res;
1779
+ this.isWorkflowOpen = value == null ? !this.isWorkflowOpen : value;
1780
+
1781
+ if (!this.isWorkflowOpen) {
1782
+ this.selectedWorkflow = null;
1783
+ this.openWorkflowInput = false;
1784
+ }
1785
+
1786
+ this.cdr.detectChanges();
1787
+ });
1788
+ }
1789
+
1790
+ }
1791
+
1792
+ initializeForm() {
1793
+ // Create form controls dynamically based on selectedWorkflow.Trigger.InputSchema
1794
+ const formControls = {};
1795
+ if (this.selectedWorkflow?.Trigger?.InputSchema) {
1796
+ this.selectedWorkflow.Trigger.InputSchema.forEach((input) => {
1797
+ formControls[input.InputId] = [
1798
+ input.Value || '',
1799
+ input.Required ? Validators.required : null,
1800
+ ];
1801
+ });
1802
+ }
1803
+
1804
+ // Initialize the form
1805
+ this.workflowForm = this.fb.group(formControls);
1806
+ }
1807
+
1808
+ onWorkflowSelected(workflow) {
1809
+ this.selectedWorkflow = workflow;
1810
+ this.initializeForm();
1811
+ this.isWorkflowOpen = false;
1812
+ this.openWorkflowInput = true;
1813
+ }
1814
+
1815
+ onWorkflowSubmit() {
1816
+ const container = document.getElementById('allChats');
1817
+ if (this.workflowForm.valid) {
1818
+ console.log(this.workflowForm.value);
1819
+
1820
+ var input = this.prepareHtml(
1821
+ this.generateMarkdown(
1822
+ this.selectedWorkflow.Name,
1823
+ this.workflowForm.value
1824
+ )
1825
+ );
1826
+
1827
+ // update last two chatLog entries, set showWorkflowExecutionLoader = false
1828
+ try {
1829
+ this.chatLog[this.chatLog.length - 1][
1830
+ 'showWorkflowExecutionLoader'
1831
+ ] = false;
1832
+ this.chatLog[this.chatLog.length - 2][
1833
+ 'showWorkflowExecutionLoader'
1834
+ ] = false;
1835
+ } catch (error) { }
1836
+
1837
+ this.chatLog.push({
1838
+ type: 'user',
1839
+ message: input,
1840
+ time: formatNow(this.timezone),
1841
+ copied: false,
1842
+ isCollapsedTrue: false,
1843
+ showWorkflowExecutionLoader: true,
1844
+ });
1845
+
1846
+ console.log(input);
1847
+
1848
+ this.currentWorkflowActionProgress = 0;
1849
+ this.currentWorkflowAction =
1850
+ 'Executing ' + this.selectedWorkflow.Actions[0].Name;
1851
+ this.isChatingWithAi = true;
1852
+ this.executingWorkflow = true;
1853
+ this.workflowExecutionDetails = {
1854
+ Actions: this.selectedWorkflow.Actions,
1855
+ Inputs: this.workflowForm.value,
1856
+ workflowInputs: this.workflowForm.value,
1857
+ WorkflowName: this.selectedWorkflow.Name,
1858
+ };
1859
+ this.currentWorkflowExecutionDetails = this.workflowExecutionDetails;
1860
+ this.scrollToBottom();
1861
+
1862
+ this.cdr.detectChanges();
1863
+
1864
+ // execute the ask endpoint with workflow input
1865
+ this.makeAskRequest(
1866
+ input,
1867
+ this.agents,
1868
+ this.conversationKey,
1869
+ '',
1870
+ null,
1871
+ this.selectedWorkflow['_id'],
1872
+ this.workflowForm.value
1873
+ );
1874
+ }
1875
+ }
1876
+
1877
+ makeAskRequest(
1878
+ inputMsg: string,
1879
+ agents: any[],
1880
+ conversationId: string,
1881
+ msg?: any,
1882
+ chat?: any,
1883
+ workflowId?: string,
1884
+ workflow_inputs?: any
1885
+ ): void {
1886
+ var url = `${this.environment.BASE_URL}/ai/ask`;
1887
+
1888
+ var body = {
1889
+ user_question: inputMsg,
1890
+ user_id: this.userId,
1891
+ bot_id: this.botId,
1892
+ message_id: this.conversationService.generateKey(),
1893
+ session_id: this.conSessionKey,
1894
+ agents: agents?.filter((p) => p.selected).map((p) => p.id) ?? [],
1895
+ conversation_id: conversationId,
1896
+ first_name: this.firstName,
1897
+ last_name: this.lastName
1898
+ };
1899
+
1900
+ if (workflowId) {
1901
+ body['workflow_id'] = workflowId;
1902
+ body['workflow_inputs'] = workflow_inputs;
1903
+ }
1904
+
1905
+
1906
+ fetch(url, {
1907
+ method: 'POST',
1908
+ headers: {
1909
+ 'Content-Type': 'application/json',
1910
+ Authorization: 'Bearer ' + this.s27Token,
1911
+ 'x-api-key': this.apiKey,
1912
+ 'hive-bot-id': this.botId,
1913
+ 'domain-authority': this.domainAuthorityValue
1914
+ },
1915
+ body: JSON.stringify(body),
1916
+ })
1917
+ .then((response) => {
1918
+ if (response.status === 401 || response.status === 403) {
1919
+ this.is401 = true;
1920
+ this.refreshToken.emit();
1921
+
1922
+ // If `msg` and `chat` exist, handle them
1923
+ if (msg && chat) {
1924
+ this.msg = msg;
1925
+ this.chat = chat;
1926
+ this.isFetchDataFor = true;
1927
+ }
1928
+ } else {
1929
+ this.is401 = false;
1930
+ }
1931
+ return response.json();
1932
+ })
1933
+ .then((data) => {
1934
+ console.log(data);
1935
+ // Additional response handling if needed
1936
+ })
1937
+ .catch((err) => {
1938
+ console.error('Error: ', err);
1939
+ this.isChatingWithAi = false;
1940
+ });
1941
+
1942
+ this.input = '';
1943
+ this.selectedWorkflow = null;
1944
+ this.openWorkflowInput = false;
1945
+ this.isWorkflowOpen = false;
1946
+ this.scrollToBottom();
1947
+ this.cdr.markForCheck();
1948
+ }
1949
+
1950
+
1951
+ makeAskRequestold(
1952
+ inputMsg: string,
1953
+ agents: any[],
1954
+ conversationId: string,
1955
+ msg?: any,
1956
+ chat?: any,
1957
+ workflowId?: string,
1958
+ workflow_inputs?: any
1959
+ ): void {
1960
+ const url = `${this.environment.BASE_URL}/ai/ask`;
1961
+
1962
+ const body: any = {
1963
+ user_question: inputMsg,
1964
+ user_id: this.userId,
1965
+ bot_id: this.botId,
1966
+ message_id: this.conversationService.generateKey(),
1967
+ agents: agents?.filter((p) => p.selected).map((p) => p.id) ?? [],
1968
+ conversation_id: conversationId,
1969
+ first_name: this.firstName,
1970
+ last_name: this.lastName,
1971
+ };
1972
+
1973
+ if (workflowId) {
1974
+ body['workflow_id'] = workflowId;
1975
+ body['workflow_inputs'] = workflow_inputs;
1976
+ }
1977
+
1978
+ const headers = new HttpHeaders({
1979
+ 'Content-Type': 'application/json',
1980
+ 'x-api-key': this.apiKey,
1981
+ 'hive-bot-id': this.botId,
1982
+ 'domain-authority': this.domainAuthorityValue,
1983
+ });
1984
+
1985
+ this.http.post(url, body, { headers })
1986
+ .subscribe({
1987
+ next: (data) => {
1988
+ console.log(data);
1989
+ // Additional response handling if needed
1990
+ },
1991
+ error: (err) => {
1992
+ console.error('Error: ', err);
1993
+ this.isChatingWithAi = false;
1994
+ },
1995
+ });
1996
+
1997
+ this.input = '';
1998
+ this.selectedWorkflow = null;
1999
+ this.openWorkflowInput = false;
2000
+ this.isWorkflowOpen = false;
2001
+ this.scrollToBottom();
2002
+ this.cdr.markForCheck();
2003
+
2004
+ }
2005
+
2006
+ generateMarkdown(title, obj) {
2007
+ // Initialize markdown with the title
2008
+ let markdown = `## ${title}\n`;
2009
+
2010
+ // Loop through the object and append the field names and values
2011
+ for (const [key, value] of Object.entries(obj)) {
2012
+ var key_label =
2013
+ this.selectedWorkflow.Trigger.InputSchema.find(
2014
+ (input) => input.InputId === key
2015
+ )?.Label || key;
2016
+ markdown += `- **${key_label}**: ${value}\n`;
2017
+ }
2018
+
2019
+ return markdown;
2020
+ }
2021
+
2022
+ showWorkflowHistoryDetails(workflow_id) {
2023
+ if (!workflow_id) {
2024
+ this.workflowExecutionDetails = this.currentWorkflowExecutionDetails;
2025
+ this.showWorkflowExecutionDetails = true;
2026
+ this.cdr.detectChanges();
2027
+ return;
2028
+ }
2029
+
2030
+ this.botService.getWorkflowExecutionById(workflow_id).subscribe((res) => {
2031
+ if (res && res.Actions && Array.isArray(res.Actions)) {
2032
+ res.Actions = res.Actions.map((action) => {
2033
+ if (action.InsertTimeStamp) {
2034
+ action.InsertTimeStamp = formatTimeStamps(
2035
+ this.timezone,
2036
+ action.InsertTimeStamp
2037
+ );
2038
+ }
2039
+ return action;
2040
+ });
2041
+ }
2042
+
2043
+ res.InsertTimeStamp = formatTimeStamps(
2044
+ this.timezone,
2045
+ res.InsertTimeStamp
2046
+ );
2047
+ this.workflowExecutionDetails = res;
2048
+ this.showWorkflowExecutionDetails = true;
2049
+ this.cdr.detectChanges();
2050
+ });
2051
+ }
2052
+
2053
+ closeModal() {
2054
+ this.showWorkflowExecutionDetails = false;
2055
+ }
2056
+
2057
+ objectToArray(obj: any): any[] {
2058
+ return Object.keys(obj).map((key) => ({ key, value: obj[key] }));
2059
+ }
2060
+
2061
+ startNewConversation() {
2062
+ this.conversationKey = this.conversationService.getKey(this.botId, true);
2063
+ this.chatLog = [this.chatLog[0]];
2064
+ this.isChatingWithAi = false;
2065
+ setTimeout(() => {
2066
+ this.initializeSocket();
2067
+ }, 200);
2068
+ this.scrollToBottom();
2069
+ this.cdr.detectChanges();
2070
+ }
2071
+
2072
+ initializeSpeechRecognizer(token: string) {
2073
+ this.speechConfig = SpeechSDK.SpeechConfig.fromAuthorizationToken(
2074
+ token,
2075
+ this.region
2076
+ );
2077
+ const audioConfig = SpeechSDK.AudioConfig.fromDefaultMicrophoneInput();
2078
+ this.recognizer = new SpeechSDK.SpeechRecognizer(
2079
+ this.speechConfig,
2080
+ audioConfig
2081
+ );
2082
+
2083
+ this.recognizer.recognizing = (s, e) => {
2084
+ if (e.result.reason === SpeechSDK.ResultReason.RecognizingSpeech) {
2085
+ this.input = e.result.text;
2086
+ console.log(`Recognizing: ${e.result.text}`);
2087
+ this.cdr.markForCheck();
2088
+ }
2089
+ };
2090
+
2091
+ this.recognizer.recognized = (s, e) => {
2092
+ if (e.result.reason === SpeechSDK.ResultReason.RecognizedSpeech) {
2093
+ this.input = e.result.text;
2094
+ console.log(`Recognized: ${e.result.text}`);
2095
+ this.toggleRecording();
2096
+ this.cdr.markForCheck();
2097
+ }
2098
+ };
2099
+
2100
+ this.recognizer.canceled = (s, e) => {
2101
+ console.error('Canceled: ', e.errorDetails);
2102
+ };
2103
+
2104
+ this.recognizer.sessionStopped = (s, e) => {
2105
+ console.log('Session stopped.');
2106
+ this.recognizer.stopContinuousRecognitionAsync();
2107
+ this.fetchData();
2108
+ };
2109
+ }
2110
+
2111
+ toggleRecording() {
2112
+ this.isRecording = !this.isRecording;
2113
+
2114
+ if (this.isRecording) {
2115
+ this.startRecognition();
2116
+ } else {
2117
+ this.stopRecognition();
2118
+ }
2119
+ }
2120
+
2121
+ startRecognition() {
2122
+ this.recognizer.startContinuousRecognitionAsync();
2123
+ }
2124
+
2125
+ stopRecognition() {
2126
+ this.recognizer.stopContinuousRecognitionAsync();
2127
+ }
2128
+
2129
+ checkForCop29BotId() {
2130
+ return this.botId == '66fa3f276c5d71e2717bfea8' || this.botId == '671633545652dd78efec848d';
2131
+
2132
+ }
2133
+
2134
+ getLatestTime(time): string {
2135
+ if (time) {
2136
+ return time;
2137
+ }
2138
+ return new Date().toLocaleTimeString([], {
2139
+ hour: '2-digit',
2140
+ minute: '2-digit',
2141
+ }); // returns current time in 'shortTime' format
2142
+ }
2143
+ }