@sinequa/assistant 3.2.0 → 3.2.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.
- package/chat/chat-message/chat-message.component.d.ts +1 -0
- package/chat/chat.component.d.ts +13 -4
- package/chat/chat.service.d.ts +12 -5
- package/chat/rest-chat.service.d.ts +2 -1
- package/chat/saved-chats/saved-chats.component.d.ts +0 -1
- package/chat/websocket-chat.service.d.ts +13 -11
- package/esm2020/chat/chat-message/chat-message.component.mjs +23 -3
- package/esm2020/chat/chat.component.mjs +54 -53
- package/esm2020/chat/chat.service.mjs +1 -1
- package/esm2020/chat/rest-chat.service.mjs +38 -14
- package/esm2020/chat/saved-chats/saved-chats.component.mjs +4 -5
- package/esm2020/chat/websocket-chat.service.mjs +73 -40
- package/fesm2015/sinequa-assistant-chat.mjs +186 -110
- package/fesm2015/sinequa-assistant-chat.mjs.map +1 -1
- package/fesm2020/sinequa-assistant-chat.mjs +186 -109
- package/fesm2020/sinequa-assistant-chat.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, EventEmitter, inject, Component, Input, Output, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ContentChild, Inject } from '@angular/core';
|
|
3
|
-
import { Subscription, filter, tap, switchMap, BehaviorSubject, Subject, forkJoin, map, catchError, throwError, shareReplay, fromEvent, merge, takeUntil, finalize } from 'rxjs';
|
|
3
|
+
import { Subscription, filter, tap, switchMap, BehaviorSubject, Subject, forkJoin, map, catchError, throwError, shareReplay, fromEvent, merge, takeUntil, take, finalize } from 'rxjs';
|
|
4
4
|
import * as i3 from '@sinequa/core/web-services';
|
|
5
5
|
import { PrincipalWebService, UserSettingsWebService, AuditWebService, SignalRWebService, JsonMethodPluginService } from '@sinequa/core/web-services';
|
|
6
6
|
import * as i1 from '@angular/common';
|
|
@@ -478,10 +478,11 @@ class WebSocketChatService extends ChatService {
|
|
|
478
478
|
super();
|
|
479
479
|
this.connectionBuilt$ = new Subject(); // Emit when the connection is built
|
|
480
480
|
this.connectionStarted$ = new Subject(); // Emit when the connection is started
|
|
481
|
-
this.
|
|
482
|
-
this.
|
|
483
|
-
this.
|
|
484
|
-
this.
|
|
481
|
+
this._messageHandlers = new Map();
|
|
482
|
+
this._actionMap = new Map();
|
|
483
|
+
this._progress = undefined;
|
|
484
|
+
this._content = "";
|
|
485
|
+
this._attachments = [];
|
|
485
486
|
this.signalRService = inject(SignalRWebService);
|
|
486
487
|
this.authenticationService = inject(AuthenticationService);
|
|
487
488
|
}
|
|
@@ -593,9 +594,9 @@ class WebSocketChatService extends ChatService {
|
|
|
593
594
|
let response = { role: "assistant", content: "", additionalProperties: { display: true } }; // here display: true is needed in order to be able to show the progress
|
|
594
595
|
// Create a Subject to signal completion
|
|
595
596
|
const completion$ = new Subject();
|
|
596
|
-
// Create observables for each non-global handler in the
|
|
597
|
+
// Create observables for each non-global handler in the _messageHandlers map (default and eventual custom ones) once it is triggered by the hub connection
|
|
597
598
|
const observables = Array
|
|
598
|
-
.from(this.
|
|
599
|
+
.from(this._messageHandlers.entries())
|
|
599
600
|
.filter(([eventName, eventHandler]) => !eventHandler.isGlobalHandler)
|
|
600
601
|
.map(([eventName, eventHandler]) => {
|
|
601
602
|
return fromEvent(this.connection, eventName).pipe(map((event) => eventHandler.handler(event)) // Execute the corresponding handler
|
|
@@ -613,18 +614,19 @@ class WebSocketChatService extends ChatService {
|
|
|
613
614
|
})
|
|
614
615
|
.finally(() => {
|
|
615
616
|
this.streaming$.next(false); // Complete streaming regardless of success or error
|
|
616
|
-
this.
|
|
617
|
-
this.
|
|
618
|
-
this.
|
|
619
|
-
this.
|
|
617
|
+
this._actionMap.clear(); // Clear the _actionMap
|
|
618
|
+
this._content = ""; // Clear the _content
|
|
619
|
+
this._progress = undefined; // Clear the _progress
|
|
620
|
+
this._attachments = []; // Clear the _attachments
|
|
621
|
+
this._executionTime = ""; // Clear the _executionTime
|
|
620
622
|
completion$.next(); // Emit a signal to complete the observables
|
|
621
623
|
completion$.complete(); // Complete the subject
|
|
622
624
|
});
|
|
623
625
|
// Return the merged observables
|
|
624
626
|
return combined$.pipe(map(() => {
|
|
625
|
-
// Define $progress from the
|
|
626
|
-
const actions = Array.from(this.
|
|
627
|
-
|
|
627
|
+
// Define $progress from the _actionMap
|
|
628
|
+
const actions = Array.from(this._actionMap.values());
|
|
629
|
+
this._progress = actions.length > 0
|
|
628
630
|
? actions.map((a) => ({
|
|
629
631
|
title: a.displayName ?? "",
|
|
630
632
|
content: a.displayValue ?? "",
|
|
@@ -632,14 +634,12 @@ class WebSocketChatService extends ChatService {
|
|
|
632
634
|
time: a.executionTime,
|
|
633
635
|
}))
|
|
634
636
|
: undefined;
|
|
635
|
-
//
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
if (!!this.content || $progress || $attachment.length > 0) {
|
|
639
|
-
response = { ...response, content: this.content, additionalProperties: { ...response.additionalProperties, $progress, $attachment } };
|
|
637
|
+
// As soon as the first _content or $progress is defined, the assistant is considered as streaming
|
|
638
|
+
if (!!this._content || this._progress || this._attachments.length > 0) {
|
|
639
|
+
response = { ...response, content: this._content, additionalProperties: { ...response.additionalProperties, $progress: this._progress, $attachment: this._attachments } };
|
|
640
640
|
}
|
|
641
641
|
// Return the result
|
|
642
|
-
return { history: [...messages, response], executionTime: this.
|
|
642
|
+
return { history: [...messages, response], executionTime: this._executionTime };
|
|
643
643
|
}));
|
|
644
644
|
}
|
|
645
645
|
listSavedChat() {
|
|
@@ -677,14 +677,39 @@ class WebSocketChatService extends ChatService {
|
|
|
677
677
|
});
|
|
678
678
|
return savedChatSubject.asObservable();
|
|
679
679
|
}
|
|
680
|
-
|
|
680
|
+
addSavedChat(messages) {
|
|
681
|
+
const addSavedChatSubject = new Subject();
|
|
682
|
+
const data = {
|
|
683
|
+
instanceId: this.chatInstanceId,
|
|
684
|
+
savedChatId: ChatService.generateGUID(),
|
|
685
|
+
history: messages,
|
|
686
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
687
|
+
};
|
|
688
|
+
this.connection.on('SavedChatAdd', (res) => {
|
|
689
|
+
this.setSavedChatId(res.savedChat.id); // Persist the savedChatId
|
|
690
|
+
addSavedChatSubject.next(res.savedChat);
|
|
691
|
+
addSavedChatSubject.complete();
|
|
692
|
+
});
|
|
693
|
+
// Invoke the method SavedChatAdd
|
|
694
|
+
this.connection.invoke('SavedChatAdd', data)
|
|
695
|
+
.catch(error => {
|
|
696
|
+
console.error('Error invoking SavedChatAdd:', error);
|
|
697
|
+
addSavedChatSubject.complete();
|
|
698
|
+
return Promise.resolve();
|
|
699
|
+
});
|
|
700
|
+
return addSavedChatSubject.asObservable();
|
|
701
|
+
}
|
|
702
|
+
updateSavedChat(id, name, messages) {
|
|
681
703
|
const updateSavedChatSubject = new Subject();
|
|
682
704
|
const data = {
|
|
683
705
|
instanceId: this.chatInstanceId,
|
|
684
706
|
savedChatId: id,
|
|
685
|
-
title: name,
|
|
686
707
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
687
708
|
};
|
|
709
|
+
if (name)
|
|
710
|
+
data["title"] = name;
|
|
711
|
+
if (messages)
|
|
712
|
+
data["history"] = messages;
|
|
688
713
|
this.connection.on('SavedChatUpdate', (res) => {
|
|
689
714
|
updateSavedChatSubject.next(res.savedChat);
|
|
690
715
|
updateSavedChatSubject.complete();
|
|
@@ -725,28 +750,36 @@ class WebSocketChatService extends ChatService {
|
|
|
725
750
|
initMessageHandlers() {
|
|
726
751
|
this.addMessageHandler("Debug", { handler: (debug) => console.log(debug),
|
|
727
752
|
isGlobalHandler: true });
|
|
728
|
-
this.addMessageHandler("ActionStart", { handler: (action) => this.
|
|
753
|
+
this.addMessageHandler("ActionStart", { handler: (action) => this._actionMap.set(action.guid, action),
|
|
729
754
|
isGlobalHandler: false });
|
|
730
755
|
this.addMessageHandler("ActionResult", {
|
|
731
|
-
handler: (action) => this.
|
|
756
|
+
handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
|
|
732
757
|
isGlobalHandler: false
|
|
733
758
|
});
|
|
734
759
|
this.addMessageHandler("ActionStop", {
|
|
735
|
-
handler: (action) => this.
|
|
760
|
+
handler: (action) => this._actionMap.set(action.guid, { ...this._actionMap.get(action.guid), ...action }),
|
|
736
761
|
isGlobalHandler: false
|
|
737
762
|
});
|
|
738
763
|
this.addMessageHandler("ContextMessage", {
|
|
739
|
-
handler: (message) => this.
|
|
764
|
+
handler: (message) => this._attachments.push(message.metadata),
|
|
740
765
|
isGlobalHandler: false
|
|
741
766
|
});
|
|
742
767
|
this.addMessageHandler("Message", {
|
|
743
|
-
handler: (message) => this.
|
|
768
|
+
handler: (message) => this._content += message ?? "",
|
|
744
769
|
isGlobalHandler: false
|
|
745
770
|
});
|
|
746
771
|
this.addMessageHandler("History", {
|
|
747
772
|
handler: (history) => {
|
|
748
773
|
this.chatHistory = history.history;
|
|
749
|
-
|
|
774
|
+
// Re-attach the $progress and $attachment of the last response to the last assistant's response in the chat history
|
|
775
|
+
this.chatHistory.at(-1).additionalProperties.$progress = this._progress;
|
|
776
|
+
this.chatHistory.at(-1).additionalProperties.$attachment = this._attachments;
|
|
777
|
+
// Save/update the chat if savedChat enabled
|
|
778
|
+
if (this.chatConfig$.value.savedChatSettings.enabled && this.chatHistory.some((msg) => msg.additionalProperties?.isUserInput === true)) {
|
|
779
|
+
const action = !this.savedChatId ? this.addSavedChat(this.chatHistory) : this.updateSavedChat(this.savedChatId, undefined, this.chatHistory);
|
|
780
|
+
action.pipe(take(1)).subscribe();
|
|
781
|
+
}
|
|
782
|
+
this._executionTime = history.executionTime;
|
|
750
783
|
},
|
|
751
784
|
isGlobalHandler: false
|
|
752
785
|
});
|
|
@@ -769,20 +802,20 @@ class WebSocketChatService extends ChatService {
|
|
|
769
802
|
});
|
|
770
803
|
}
|
|
771
804
|
/**
|
|
772
|
-
* Override and register the entire
|
|
773
|
-
* @param
|
|
805
|
+
* Override and register the entire _messageHandlers map by merging the provided map with the default one
|
|
806
|
+
* @param _messageHandlers
|
|
774
807
|
*/
|
|
775
|
-
overrideMessageHandlers(
|
|
808
|
+
overrideMessageHandlers(_messageHandlers) {
|
|
776
809
|
// Clear the already registered global chat handlers before merging the new ones
|
|
777
|
-
this.
|
|
810
|
+
this._messageHandlers.forEach((eventHandler, eventName) => {
|
|
778
811
|
if (eventHandler.isGlobalHandler) {
|
|
779
812
|
this.unsubscribeMessageHandler(eventName);
|
|
780
813
|
}
|
|
781
814
|
});
|
|
782
815
|
// Merge the new event handlers with the existing ones
|
|
783
|
-
this.
|
|
816
|
+
this._messageHandlers = new Map([...this._messageHandlers, ..._messageHandlers]);
|
|
784
817
|
// Register the global chat handlers among the merged map
|
|
785
|
-
this.
|
|
818
|
+
this._messageHandlers.forEach((eventHandler, eventName) => {
|
|
786
819
|
if (eventHandler.isGlobalHandler) {
|
|
787
820
|
this.registerMessageHandler(eventName, eventHandler);
|
|
788
821
|
}
|
|
@@ -796,7 +829,7 @@ class WebSocketChatService extends ChatService {
|
|
|
796
829
|
* @param eventHandler The handler to be called when the event is received
|
|
797
830
|
*/
|
|
798
831
|
addMessageHandler(eventName, eventHandler) {
|
|
799
|
-
this.
|
|
832
|
+
this._messageHandlers.set(eventName, eventHandler);
|
|
800
833
|
if (eventHandler.isGlobalHandler) {
|
|
801
834
|
this.registerMessageHandler(eventName, eventHandler);
|
|
802
835
|
}
|
|
@@ -817,17 +850,17 @@ class WebSocketChatService extends ChatService {
|
|
|
817
850
|
});
|
|
818
851
|
}
|
|
819
852
|
/**
|
|
820
|
-
* Remove a listener for a specific event from the
|
|
853
|
+
* Remove a listener for a specific event from the _messageHandlers map and unsubscribe from receiving messages for this event from the SignalR hub.
|
|
821
854
|
* @param eventName Name of the event to remove the listener for
|
|
822
855
|
*/
|
|
823
856
|
removeMessageHandler(eventName) {
|
|
824
|
-
this.
|
|
857
|
+
this._messageHandlers.delete(eventName);
|
|
825
858
|
this.unsubscribeMessageHandler(eventName);
|
|
826
859
|
}
|
|
827
860
|
/**
|
|
828
861
|
* Unsubscribe from receiving messages for a specific event from the SignalR hub.
|
|
829
862
|
* ALL its related listeners will be removed from hub connection
|
|
830
|
-
* This is needed to prevent accumulating old listeners when overriding the entire
|
|
863
|
+
* This is needed to prevent accumulating old listeners when overriding the entire _messageHandlers map
|
|
831
864
|
* @param eventName Name of the event
|
|
832
865
|
*/
|
|
833
866
|
unsubscribeMessageHandler(eventName) {
|
|
@@ -846,7 +879,7 @@ class WebSocketChatService extends ChatService {
|
|
|
846
879
|
return;
|
|
847
880
|
}
|
|
848
881
|
const logLevel = this.getLogLevel();
|
|
849
|
-
this.connection = this.signalRService.buildConnection(this.REQUEST_URL, { ...this.defaultOptions, ...options }, logLevel);
|
|
882
|
+
this.connection = this.signalRService.buildConnection(this.REQUEST_URL, { ...this.defaultOptions, ...options }, logLevel, true);
|
|
850
883
|
resolve();
|
|
851
884
|
});
|
|
852
885
|
}
|
|
@@ -1284,6 +1317,26 @@ class ChatMessageComponent {
|
|
|
1284
1317
|
}
|
|
1285
1318
|
this.referenceClicked.emit(record);
|
|
1286
1319
|
}
|
|
1320
|
+
getLinkText(node) {
|
|
1321
|
+
if (node.text) {
|
|
1322
|
+
return node.text; // Return directly if text is provided in node.text ([Example link](https://example.com))
|
|
1323
|
+
}
|
|
1324
|
+
else if (node.children && node.children.length > 0) {
|
|
1325
|
+
// Recursively search for text content in child nodes
|
|
1326
|
+
for (const child of node.children) {
|
|
1327
|
+
if (child.type === 'text' && child.value) {
|
|
1328
|
+
return child.value; // Return the value of the first text node found ([**Emphasized Link Text**](https://example.com))
|
|
1329
|
+
}
|
|
1330
|
+
else if (child.children && child.children.length > 0) {
|
|
1331
|
+
const textContent = this.getLinkText(child); // Recursively search child nodes ([](https://example.com))
|
|
1332
|
+
if (textContent) {
|
|
1333
|
+
return textContent; // Return text content if found
|
|
1334
|
+
}
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
}
|
|
1338
|
+
return 'link'; // Return empty string if no text content is found
|
|
1339
|
+
}
|
|
1287
1340
|
/**
|
|
1288
1341
|
* Reformat [ids: 12.2, 42.5] to [12.2][42.5]
|
|
1289
1342
|
*/
|
|
@@ -1301,11 +1354,11 @@ class ChatMessageComponent {
|
|
|
1301
1354
|
}
|
|
1302
1355
|
}
|
|
1303
1356
|
ChatMessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatMessageComponent, deps: [{ token: i1$1.SearchService }, { token: i2$1.UIService }, { token: i3.PrincipalWebService }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1304
|
-
ChatMessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { message: "message", conversation: "conversation", assistantIcon: "assistantIcon", streaming: "streaming", canEdit: "canEdit", canRegenerate: "canRegenerate", canCopy: "canCopy" }, outputs: { referenceClicked: "referenceClicked", edit: "edit", regenerate: "regenerate", openPreview: "openPreview" }, usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message.role\">\n <i [ngClass]=\"assistantIcon\" [style.--sq-size.px]=\"24\" *ngIf=\"message.role === 'assistant'\"></i>\n <sq-initials-avatar [fullName]=\"name\" *ngIf=\"message.role !== 'assistant'\"></sq-initials-avatar>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <a href=\"#\" (click)=\"collapseProgress = !collapseProgress; false\" class=\"text-muted\">\n View progress\n <i class=\"fas fa-chevron-{{collapseProgress? 'right' : 'down'}}\"></i>\n </a>\n <sq-collapse [collapsed]=\"collapseProgress\">\n <ng-template>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-fw fa-spin fa-circle-notch\" *ngIf=\"!step.done\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\">: {{step.content}}</span>\n </li>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <remark *ngIf=\"message.role === 'assistant'\" [markdown]=\"message.content\" [processor]=\"processor\">\n\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n\n <a *ngIf=\"referenceMap.get(ref.refId) as attachment; else staticRefTpl\"\n (click)=\"openDocument(attachment.record)\"\n class=\"reference\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n >{{ref.refId}}</a>\n\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ref.refId}}</span>\n </ng-template>\n\n </ng-template>\n\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyToClipboard(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> Copy code</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message.role === 'user'\">{{message.content}}</p>\n\n <!-- List of reference, if any -->\n <div *ngIf=\"references?.length\" class=\"references\">\n <span class=\"references-title\">References</span> <i class=\"fas references-collapse\" [class.fa-chevron-down]=\"showReferences\" [class.fa-chevron-right]=\"!showReferences\" (click)=\"showReferences=!showReferences\"></i>\n <sq-collapse [collapsed]=\"!showReferences\">\n <ng-template>\n <ul>\n <ng-container *ngFor=\"let reference of references\">\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference [class.expanded]=\"attachment.$expanded\" [attachment]=\"attachment\" [reference]=\"reference\"\n (openPreview)=\"openPreview.emit($event)\" (openDocument)=\"openDocument($event)\"></sq-chat-reference>\n </li>\n </ng-container>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n \n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-action\">\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" sqTooltip=\"Edit message\"\n (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" sqTooltip=\"Copy to clipboard\"\n (click)=\"copyToClipboard(message.content)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" sqTooltip=\"Regenerate message\"\n (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n </div>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openPreview.emit($event)\"\n (openDocument)=\"openDocument($event)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host{display:flex}:host:not(:hover) .sq-chat-message-action{display:none}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content .references .references-collapse{cursor:pointer;margin-left:var(--ast-size-2, .5rem)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:block;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.sq-chat-message-action{position:absolute;right:calc(0rem - var(--ast-size-2, .5rem));top:var(--ast-size-2, .5rem);display:flex;flex-direction:column}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: UtilsModule }, { kind: "directive", type: i2$1.TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: i5.Collapse, selector: "sq-collapse", inputs: ["collapsed"] }, { kind: "ngmodule", type: RemarkModule }, { kind: "component", type: i6.RemarkComponent, selector: "remark", inputs: ["markdown", "processor", "debug"] }, { kind: "directive", type: i6.RemarkTemplateDirective, selector: "[remarkTemplate]", inputs: ["remarkTemplate"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId"], outputs: ["openDocument", "openPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1357
|
+
ChatMessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatMessageComponent, isStandalone: true, selector: "sq-chat-message", inputs: { message: "message", conversation: "conversation", assistantIcon: "assistantIcon", streaming: "streaming", canEdit: "canEdit", canRegenerate: "canRegenerate", canCopy: "canCopy" }, outputs: { referenceClicked: "referenceClicked", edit: "edit", regenerate: "regenerate", openPreview: "openPreview" }, usesOnChanges: true, ngImport: i0, template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message.role\">\n <i [ngClass]=\"assistantIcon\" [style.--sq-size.px]=\"24\" *ngIf=\"message.role === 'assistant'\"></i>\n <sq-initials-avatar [fullName]=\"name\" *ngIf=\"message.role !== 'assistant'\"></sq-initials-avatar>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <a href=\"#\" (click)=\"collapseProgress = !collapseProgress; false\" class=\"text-muted\">\n View progress\n <i class=\"fas fa-chevron-{{collapseProgress? 'right' : 'down'}}\"></i>\n </a>\n <sq-collapse [collapsed]=\"collapseProgress\">\n <ng-template>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-fw fa-spin fa-circle-notch\" *ngIf=\"!step.done\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\">: {{step.content}}</span>\n </li>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <remark *ngIf=\"message.role === 'assistant'\" [markdown]=\"message.content\" [processor]=\"processor\">\n\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n\n <a *ngIf=\"referenceMap.get(ref.refId) as attachment; else staticRefTpl\"\n (click)=\"openDocument(attachment.record)\"\n class=\"reference\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n >{{ref.refId}}</a>\n\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ref.refId}}</span>\n </ng-template>\n\n </ng-template>\n\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyToClipboard(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> Copy code</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message.role === 'user'\">{{message.content}}</p>\n\n <!-- List of reference, if any -->\n <div *ngIf=\"references?.length\" class=\"references\">\n <span class=\"references-title\">References</span> <i class=\"fas references-collapse\" [class.fa-chevron-down]=\"showReferences\" [class.fa-chevron-right]=\"!showReferences\" (click)=\"showReferences=!showReferences\"></i>\n <sq-collapse [collapsed]=\"!showReferences\">\n <ng-template>\n <ul>\n <ng-container *ngFor=\"let reference of references\">\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference [class.expanded]=\"attachment.$expanded\" [attachment]=\"attachment\" [reference]=\"reference\"\n (openPreview)=\"openPreview.emit($event)\" (openDocument)=\"openDocument($event)\"></sq-chat-reference>\n </li>\n </ng-container>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-action\">\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" sqTooltip=\"Edit message\"\n (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" sqTooltip=\"Copy to clipboard\"\n (click)=\"copyToClipboard(message.content)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" sqTooltip=\"Regenerate message\"\n (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n </div>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openPreview.emit($event)\"\n (openDocument)=\"openDocument($event)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host{display:flex}:host:not(:hover) .sq-chat-message-action{display:none}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content .references .references-collapse{cursor:pointer;margin-left:var(--ast-size-2, .5rem)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:block;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:-webkit-isolate;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p{margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.sq-chat-message-action{position:absolute;right:calc(0rem - var(--ast-size-2, .5rem));top:0;display:flex;flex-direction:column}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: UtilsModule }, { kind: "directive", type: i2$1.TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "ngmodule", type: CollapseModule }, { kind: "component", type: i5.Collapse, selector: "sq-collapse", inputs: ["collapsed"] }, { kind: "ngmodule", type: RemarkModule }, { kind: "component", type: i6.RemarkComponent, selector: "remark", inputs: ["markdown", "processor", "debug"] }, { kind: "directive", type: i6.RemarkTemplateDirective, selector: "[remarkTemplate]", inputs: ["remarkTemplate"] }, { kind: "component", type: InitialsAvatarComponent, selector: "sq-initials-avatar", inputs: ["fullName", "size"] }, { kind: "component", type: ChatReferenceComponent, selector: "sq-chat-reference", inputs: ["reference", "attachment", "partId"], outputs: ["openDocument", "openPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1305
1358
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatMessageComponent, decorators: [{
|
|
1306
1359
|
type: Component,
|
|
1307
1360
|
args: [{ selector: "sq-chat-message", changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, UtilsModule, CollapseModule, RemarkModule,
|
|
1308
|
-
InitialsAvatarComponent, ChatReferenceComponent], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message.role\">\n <i [ngClass]=\"assistantIcon\" [style.--sq-size.px]=\"24\" *ngIf=\"message.role === 'assistant'\"></i>\n <sq-initials-avatar [fullName]=\"name\" *ngIf=\"message.role !== 'assistant'\"></sq-initials-avatar>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <a href=\"#\" (click)=\"collapseProgress = !collapseProgress; false\" class=\"text-muted\">\n View progress\n <i class=\"fas fa-chevron-{{collapseProgress? 'right' : 'down'}}\"></i>\n </a>\n <sq-collapse [collapsed]=\"collapseProgress\">\n <ng-template>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-fw fa-spin fa-circle-notch\" *ngIf=\"!step.done\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\">: {{step.content}}</span>\n </li>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <remark *ngIf=\"message.role === 'assistant'\" [markdown]=\"message.content\" [processor]=\"processor\">\n\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n\n <a *ngIf=\"referenceMap.get(ref.refId) as attachment; else staticRefTpl\"\n (click)=\"openDocument(attachment.record)\"\n class=\"reference\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n >{{ref.refId}}</a>\n\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ref.refId}}</span>\n </ng-template>\n\n </ng-template>\n\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyToClipboard(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> Copy code</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message.role === 'user'\">{{message.content}}</p>\n\n <!-- List of reference, if any -->\n <div *ngIf=\"references?.length\" class=\"references\">\n <span class=\"references-title\">References</span> <i class=\"fas references-collapse\" [class.fa-chevron-down]=\"showReferences\" [class.fa-chevron-right]=\"!showReferences\" (click)=\"showReferences=!showReferences\"></i>\n <sq-collapse [collapsed]=\"!showReferences\">\n <ng-template>\n <ul>\n <ng-container *ngFor=\"let reference of references\">\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference [class.expanded]=\"attachment.$expanded\" [attachment]=\"attachment\" [reference]=\"reference\"\n (openPreview)=\"openPreview.emit($event)\" (openDocument)=\"openDocument($event)\"></sq-chat-reference>\n </li>\n </ng-container>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n
|
|
1361
|
+
InitialsAvatarComponent, ChatReferenceComponent], template: "<!-- Message icon -->\n<span class=\"message-icon\" [title]=\"message.role\">\n <i [ngClass]=\"assistantIcon\" [style.--sq-size.px]=\"24\" *ngIf=\"message.role === 'assistant'\"></i>\n <sq-initials-avatar [fullName]=\"name\" *ngIf=\"message.role !== 'assistant'\"></sq-initials-avatar>\n</span>\n\n<!-- Message body -->\n<div class=\"flex-grow-1\" style=\"min-width: 0;\" [ngClass]=\"'message-'+message.role\">\n\n <div *ngIf=\"message.additionalProperties.$progress as progress\" class=\"small ms-3 mb-2\">\n <a href=\"#\" (click)=\"collapseProgress = !collapseProgress; false\" class=\"text-muted\">\n View progress\n <i class=\"fas fa-chevron-{{collapseProgress? 'right' : 'down'}}\"></i>\n </a>\n <sq-collapse [collapsed]=\"collapseProgress\">\n <ng-template>\n <ul class=\"list-unstyled\">\n <li *ngFor=\"let step of progress\">\n <i class=\"fas fa-fw fa-check text-success\" *ngIf=\"step.done\"></i>\n <i class=\"fas fa-fw fa-spin fa-circle-notch\" *ngIf=\"!step.done\"></i>\n <span class=\"ms-2 fw-bold\">{{step.title}}</span>\n <span *ngIf=\"step.content\">: {{step.content}}</span>\n </li>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n <div class=\"message-content\" *ngIf=\"message.content\">\n\n <remark *ngIf=\"message.role === 'assistant'\" [markdown]=\"message.content\" [processor]=\"processor\">\n\n <ng-template remarkTemplate=\"chat-reference\" let-ref>\n\n <a *ngIf=\"referenceMap.get(ref.refId) as attachment; else staticRefTpl\"\n (click)=\"openDocument(attachment.record)\"\n class=\"reference\"\n [sqTooltip]=\"attachment\"\n [sqTooltipTemplate]=\"tooltipTpl\"\n [hoverableTooltip]=\"true\"\n >{{ref.refId}}</a>\n\n <ng-template #staticRefTpl>\n <span class=\"reference\">{{ref.refId}}</span>\n </ng-template>\n\n </ng-template>\n\n <ng-template remarkTemplate=\"streaming-placeholder\">\n <span class=\"placeholder-glow\" *ngIf=\"streaming\">\n <span class=\"placeholder ms-1\"></span>\n </span>\n </ng-template>\n\n <ng-template remarkTemplate=\"code\" let-node>\n <div class=\"card mb-2\">\n <div class=\"card-header d-flex justify-content-between align-items-center\">\n <span>{{node.lang}}</span>\n <button class=\"btn btn-light btn-sm\" (click)=\"copyToClipboard(node.value)\"><i class=\"far fa-fw fa-clipboard\"></i> Copy code</button>\n </div>\n <pre class=\"language-{{node.lang}} my-0 rounded-0 rounded-bottom\"><code class=\"language-{{node.lang}}\">{{node.value}}</code></pre>\n </div>\n </ng-template>\n\n <ng-template remarkTemplate=\"link\" let-node>\n <a [href]=\"node.url\" target=\"_blank\" rel=\"noopener noreferrer\">{{getLinkText(node)}}</a>\n </ng-template>\n\n </remark>\n\n <p *ngIf=\"message.role === 'user'\">{{message.content}}</p>\n\n <!-- List of reference, if any -->\n <div *ngIf=\"references?.length\" class=\"references\">\n <span class=\"references-title\">References</span> <i class=\"fas references-collapse\" [class.fa-chevron-down]=\"showReferences\" [class.fa-chevron-right]=\"!showReferences\" (click)=\"showReferences=!showReferences\"></i>\n <sq-collapse [collapsed]=\"!showReferences\">\n <ng-template>\n <ul>\n <ng-container *ngFor=\"let reference of references\">\n <li *ngIf=\"referenceMap.get(reference) as attachment\" class=\"text-truncate\">\n <sq-chat-reference [class.expanded]=\"attachment.$expanded\" [attachment]=\"attachment\" [reference]=\"reference\"\n (openPreview)=\"openPreview.emit($event)\" (openDocument)=\"openDocument($event)\"></sq-chat-reference>\n </li>\n </ng-container>\n </ul>\n </ng-template>\n </sq-collapse>\n </div>\n\n </div>\n\n <!-- Edit / Regenerate floating actions -->\n <div class=\"sq-chat-message-action\">\n <button class=\"btn btn-sm\" *ngIf=\"canEdit\" sqTooltip=\"Edit message\"\n (click)=\"edit.emit(message)\">\n <i class=\"fas fa-edit\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canCopy\" sqTooltip=\"Copy to clipboard\"\n (click)=\"copyToClipboard(message.content)\">\n <i class=\"far fa-clipboard\"></i>\n </button>\n <button class=\"btn btn-sm\" *ngIf=\"canRegenerate\" sqTooltip=\"Regenerate message\"\n (click)=\"regenerate.emit(message)\">\n <i class=\"fas fa-sync-alt\"></i>\n </button>\n </div>\n\n <ng-template #tooltipTpl let-ref>\n <sq-chat-reference class=\"expanded\"\n [attachment]=\"ref\"\n [reference]=\"ref.contextId\"\n [partId]=\"ref.$partId\"\n (openPreview)=\"openPreview.emit($event)\"\n (openDocument)=\"openDocument($event)\">\n </sq-chat-reference>\n </ng-template>\n\n</div>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host{display:flex}:host:not(:hover) .sq-chat-message-action{display:none}.message-content{padding:var(--ast-message-padding, var(--ast-size-3, .75rem));border-radius:var(--ast-message-border-radius, var(--ast-size-4, 1rem));display:inline-block;max-width:100%}.message-content .references{margin-top:var(--ast-size-5, 1.25rem)}.message-content .references ul{border-left:.2rem solid var(--ast-secondary-color, #FF732E);padding-left:var(--ast-size-5, 1.25rem);margin-top:var(--ast-size-2, .5rem)}.message-content .references .references-title{font-weight:var(--font-weight-bold, 500)}.message-content .references .references-collapse{cursor:pointer;margin-left:var(--ast-size-2, .5rem)}.message-content ::ng-deep p:last-child{margin-bottom:0}.message-content ::ng-deep .placeholder-glow .placeholder{animation-duration:.4s;width:12px;height:var(--ast-size-4, 1rem);vertical-align:text-bottom}.message-content ::ng-deep img{max-width:100%}.message-content ::ng-deep table{display:block;border:1px solid;border-color:var(--ast-message-table-border-color, #ccc);border-collapse:collapse;margin:0;padding:0;min-width:100%;overflow-x:auto;table-layout:fixed}.message-content ::ng-deep table tr{background-color:var(--ast-message-table-tr-bg, #f8f8f8);border:1px solid;border-color:var(--ast-message-table-tr-border-color, #ddd);padding:.35em}.message-content ::ng-deep table th,.message-content ::ng-deep table td{padding:.625em;text-align:center}.message-content ::ng-deep table th{font-size:.85em;letter-spacing:.1em;text-transform:uppercase}.message-content ::ng-deep .reference{color:var(--ast-message-reference-color, black)!important}.message-content ::ng-deep ul,.message-content ::ng-deep ol{display:flex;flex-direction:column;gap:.5rem;padding-right:2rem;margin-left:0;margin-right:0;padding-left:40px;unicode-bidi:-webkit-isolate;unicode-bidi:isolate;list-style:disc}.message-content ::ng-deep p{margin-top:.5rem}.message-assistant .message-content{background:var(--ast-secondary-bg, #FFF8F1)}.message-user .message-content{background:var(--ast-primary-bg, #f2f8fe);font-weight:var(--ast-user-font-weight, var(--font-weight-bold, 500))}.message-user .message-content p{white-space:pre-line}.sq-chat-message-action{position:absolute;right:calc(0rem - var(--ast-size-2, .5rem));top:0;display:flex;flex-direction:column}.message-icon{margin-top:var(--ast-size-3, .75rem);margin-right:var(--ast-size-4, 1rem)}\n"] }]
|
|
1309
1362
|
}], ctorParameters: function () { return [{ type: i1$1.SearchService }, { type: i2$1.UIService }, { type: i3.PrincipalWebService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { message: [{
|
|
1310
1363
|
type: Input
|
|
1311
1364
|
}], conversation: [{
|
|
@@ -1448,8 +1501,14 @@ class RestChatService extends ChatService {
|
|
|
1448
1501
|
if (res.context) {
|
|
1449
1502
|
response.additionalProperties.$attachment = res.context.map((ctx) => ctx.additionalProperties);
|
|
1450
1503
|
}
|
|
1451
|
-
// Update the chat history with the history property of the res
|
|
1504
|
+
// Update the chat history with the incoming history property of the res AND the processed response message
|
|
1452
1505
|
this.chatHistory = res.history;
|
|
1506
|
+
this.chatHistory[this.chatHistory.length - 1] = response;
|
|
1507
|
+
// Save/update the chat if savedChat enabled
|
|
1508
|
+
if (this.chatConfig$.value.savedChatSettings.enabled && this.chatHistory.some((msg) => msg.additionalProperties?.isUserInput === true)) {
|
|
1509
|
+
const action = !this.savedChatId ? this.addSavedChat(this.chatHistory) : this.updateSavedChat(this.savedChatId, undefined, this.chatHistory);
|
|
1510
|
+
action.pipe(take(1)).subscribe();
|
|
1511
|
+
}
|
|
1453
1512
|
// Return the result
|
|
1454
1513
|
return { history: [...messages, response], executionTime: res.executionTime };
|
|
1455
1514
|
}), tap(() => this.notifyAudit(this.chatHistory, this.chatConfig$.value.defaultValues.service_id)), finalize(() => this.streaming$.next(false)));
|
|
@@ -1461,10 +1520,25 @@ class RestChatService extends ChatService {
|
|
|
1461
1520
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
1462
1521
|
};
|
|
1463
1522
|
this.jsonMethodWebService.get(this.REQUEST_URL, data).subscribe(res => this.savedChats$.next(res.savedChats), error => {
|
|
1464
|
-
console.error('Error occurred while calling the SavedChatList API:', error);
|
|
1465
|
-
this.notificationsService.error('Error occurred while calling the SavedChatList API');
|
|
1523
|
+
console.error('Error occurred while calling the SavedChatList API:', error.error.errorMessage);
|
|
1524
|
+
this.notificationsService.error('Error occurred while calling the SavedChatList API:', error.error.errorMessage);
|
|
1466
1525
|
});
|
|
1467
1526
|
}
|
|
1527
|
+
addSavedChat(messages) {
|
|
1528
|
+
const data = {
|
|
1529
|
+
action: "SavedChatAdd",
|
|
1530
|
+
instanceId: this.chatInstanceId,
|
|
1531
|
+
savedChatId: ChatService.generateGUID(),
|
|
1532
|
+
history: messages,
|
|
1533
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1534
|
+
};
|
|
1535
|
+
return this.jsonMethodWebService.post(this.REQUEST_URL, data).pipe(map(res => res.savedChat), tap((savedChat) => this.setSavedChatId(savedChat.id)), // Persist the savedChatId
|
|
1536
|
+
catchError((error) => {
|
|
1537
|
+
console.error('Error occurred while calling the SavedChatAdd API:', error.error.errorMessage);
|
|
1538
|
+
this.notificationsService.error('Error occurred while calling the SavedChatAdd API:', error.error.errorMessage);
|
|
1539
|
+
return throwError(() => error);
|
|
1540
|
+
}));
|
|
1541
|
+
}
|
|
1468
1542
|
getSavedChat(id) {
|
|
1469
1543
|
const data = {
|
|
1470
1544
|
action: "SavedChatGet",
|
|
@@ -1473,22 +1547,25 @@ class RestChatService extends ChatService {
|
|
|
1473
1547
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
1474
1548
|
};
|
|
1475
1549
|
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.savedChat), catchError((error) => {
|
|
1476
|
-
console.error('Error occurred while calling the SavedChatGet API:', error);
|
|
1477
|
-
this.notificationsService.error('Error occurred while calling the SavedChatGet API');
|
|
1550
|
+
console.error('Error occurred while calling the SavedChatGet API:', error.error.errorMessage);
|
|
1551
|
+
this.notificationsService.error('Error occurred while calling the SavedChatGet API:', error.error.errorMessage);
|
|
1478
1552
|
return throwError(() => error);
|
|
1479
1553
|
}));
|
|
1480
1554
|
}
|
|
1481
|
-
updateSavedChat(id, name) {
|
|
1555
|
+
updateSavedChat(id, name, messages) {
|
|
1482
1556
|
const data = {
|
|
1483
1557
|
action: "SavedChatUpdate",
|
|
1484
1558
|
instanceId: this.chatInstanceId,
|
|
1485
1559
|
savedChatId: id,
|
|
1486
|
-
title: name,
|
|
1487
1560
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
1488
1561
|
};
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1562
|
+
if (name)
|
|
1563
|
+
data["title"] = name;
|
|
1564
|
+
if (messages)
|
|
1565
|
+
data["history"] = messages;
|
|
1566
|
+
return this.jsonMethodWebService.post(this.REQUEST_URL, data).pipe(map(res => res.savedChat), catchError((error) => {
|
|
1567
|
+
console.error('Error occurred while calling the SavedChatUpdate API:', error.error.errorMessage);
|
|
1568
|
+
this.notificationsService.error('Error occurred while calling the SavedChatUpdate API:', error.error.errorMessage);
|
|
1492
1569
|
return throwError(() => error);
|
|
1493
1570
|
}));
|
|
1494
1571
|
}
|
|
@@ -1500,8 +1577,8 @@ class RestChatService extends ChatService {
|
|
|
1500
1577
|
debug: this.chatConfig$.value.defaultValues.debug
|
|
1501
1578
|
};
|
|
1502
1579
|
return this.jsonMethodWebService.post(this.REQUEST_URL, data).pipe(map(res => res.deletedCount), catchError((error) => {
|
|
1503
|
-
console.error('Error occurred while calling the SavedChatDelete API:', error);
|
|
1504
|
-
this.notificationsService.error('Error occurred while calling the SavedChatDelete API
|
|
1580
|
+
console.error('Error occurred while calling the SavedChatDelete API:', error.error.errorMessage);
|
|
1581
|
+
this.notificationsService.error('Error occurred while calling the SavedChatDelete API:', error.error.errorMessage);
|
|
1505
1582
|
return throwError(() => error);
|
|
1506
1583
|
}));
|
|
1507
1584
|
}
|
|
@@ -1602,8 +1679,10 @@ class ChatComponent extends AbstractFacet {
|
|
|
1602
1679
|
if (changes?.messageHandlers && this.messageHandlers && this.chatService instanceof WebSocketChatService) {
|
|
1603
1680
|
this.chatService.overrideMessageHandlers(this.messageHandlers);
|
|
1604
1681
|
}
|
|
1605
|
-
|
|
1606
|
-
|
|
1682
|
+
/**
|
|
1683
|
+
* Initialize the chat with the provided chat messages if exists, otherwise load the default chat
|
|
1684
|
+
* Once the chat is initialized (firstChangesHandled is true), allow opening the chat with the new provided messages (if exists)
|
|
1685
|
+
*/
|
|
1607
1686
|
if (!this.firstChangesHandled || changes?.chat) {
|
|
1608
1687
|
const openChat = () => {
|
|
1609
1688
|
if (this.messages$.value && this.config.savedChatSettings.enabled) {
|
|
@@ -1613,22 +1692,35 @@ class ChatComponent extends AbstractFacet {
|
|
|
1613
1692
|
};
|
|
1614
1693
|
this.chat ? openChat() : this.loadDefaultChat();
|
|
1615
1694
|
}
|
|
1616
|
-
|
|
1695
|
+
/**
|
|
1696
|
+
* If the chat is initialized, the initialization event is "Query", the query changes and the queryChangeShouldTriggerReload function is provided,
|
|
1697
|
+
* then the chat should be reloaded if the function returns true
|
|
1698
|
+
* Otherwise, the chat should be reloaded by default
|
|
1699
|
+
*/
|
|
1617
1700
|
if (this.firstChangesHandled && changes?.query && this.config.modeSettings.initialization.event === 'Query') {
|
|
1618
|
-
const
|
|
1619
|
-
const
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
if (!!this.query.text) {
|
|
1623
|
-
const userQueryMsg = { role: 'user', content: this.query.text, additionalProperties: { display: this.config.modeSettings.initialization.displayUserQuery, query: this.query, forcedWorkflow: this.config.modeSettings.initialization.forcedWorkflow, isUserInput: true } };
|
|
1624
|
-
this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
|
|
1625
|
-
}
|
|
1626
|
-
else {
|
|
1627
|
-
const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
|
|
1628
|
-
this.openChat([warningMsg]);
|
|
1701
|
+
const previousQuery = changes.query.previousValue;
|
|
1702
|
+
const currentQuery = changes.query.currentValue;
|
|
1703
|
+
if (this.queryChangeShouldTriggerReload ? this.queryChangeShouldTriggerReload(previousQuery, currentQuery) : true) {
|
|
1704
|
+
this.triggerReloadAfterQueryChange(currentQuery);
|
|
1629
1705
|
}
|
|
1630
1706
|
}
|
|
1631
1707
|
}
|
|
1708
|
+
triggerReloadAfterQueryChange(query) {
|
|
1709
|
+
const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false } };
|
|
1710
|
+
const userMsg = { role: 'user', content: ChatService.formatPrompt(this.config.defaultValues.userPrompt, { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt } };
|
|
1711
|
+
/**
|
|
1712
|
+
* If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
|
|
1713
|
+
* Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
|
|
1714
|
+
*/
|
|
1715
|
+
if (!!this.query.text) {
|
|
1716
|
+
const userQueryMsg = { role: 'user', content: this.query.text, additionalProperties: { display: this.config.modeSettings.initialization.displayUserQuery, query: this.query, forcedWorkflow: this.config.modeSettings.initialization.forcedWorkflow, isUserInput: true } };
|
|
1717
|
+
this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
|
|
1718
|
+
}
|
|
1719
|
+
else {
|
|
1720
|
+
const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
|
|
1721
|
+
this.openChat([warningMsg]);
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1632
1724
|
addScrollListener() {
|
|
1633
1725
|
this.sub.add(merge(this.loading$, this.messages$, this.chatService.streaming$, fromEvent(this.messageList.nativeElement, 'scroll')).subscribe(() => {
|
|
1634
1726
|
this.isAtBottom = this.toggleScrollButtonVisibility();
|
|
@@ -1663,13 +1755,11 @@ class ChatComponent extends AbstractFacet {
|
|
|
1663
1755
|
this.chatService.chatHistory = this.chatService.chatHistory.slice(0, this.messageToEdit);
|
|
1664
1756
|
this.messageToEdit = undefined;
|
|
1665
1757
|
}
|
|
1666
|
-
// Re-attach the $progress and $attachment of the last response to the last assistant's response in the chat history
|
|
1667
|
-
this.chatService.chatHistory.at(-1).additionalProperties.$progress = this.messages$.value.at(-1).additionalProperties.$progress;
|
|
1668
|
-
this.chatService.chatHistory.at(-1).additionalProperties.$attachment = this.messages$.value.at(-1).additionalProperties.$attachment;
|
|
1669
1758
|
// Fetch the answer
|
|
1670
1759
|
this.fetchAnswer(this.question.trim(), this.chatService.chatHistory);
|
|
1671
1760
|
// Clear the input value in the UI
|
|
1672
1761
|
this.questionInput.nativeElement.value = '';
|
|
1762
|
+
this.questionInput.nativeElement.style.height = `auto`;
|
|
1673
1763
|
}
|
|
1674
1764
|
}
|
|
1675
1765
|
fetchAnswer(question, conversation) {
|
|
@@ -1732,9 +1822,11 @@ class ChatComponent extends AbstractFacet {
|
|
|
1732
1822
|
}
|
|
1733
1823
|
/**
|
|
1734
1824
|
* Start a new chat with the defaultValues settings
|
|
1825
|
+
* The savedChatId in the chat service will be reset, so that the upcoming saved chat operations will be performed on the fresh new chat
|
|
1735
1826
|
* If the savedChat feature is enabled, the list of saved chats will be refreshed
|
|
1736
1827
|
*/
|
|
1737
1828
|
newChat() {
|
|
1829
|
+
this.chatService.setSavedChatId(undefined); // Reset the savedChatId
|
|
1738
1830
|
if (this.config.savedChatSettings.enabled) {
|
|
1739
1831
|
this.chatService.listSavedChat(); // Refresh the list of saved chats
|
|
1740
1832
|
}
|
|
@@ -1768,14 +1860,16 @@ class ChatComponent extends AbstractFacet {
|
|
|
1768
1860
|
* If the last message is from the user, a request to the assistant is made to get an answer
|
|
1769
1861
|
* If the last message is from the assistant, the conversation is loaded right away
|
|
1770
1862
|
* @param messages The list of messages of the chat
|
|
1771
|
-
* @param chatId The id of the chat. If
|
|
1863
|
+
* @param chatId The id of the chat. If provided (ie. an existing discussion in the saved chat index), update the savedChatId in the chat service for the upcoming saved chat operations
|
|
1772
1864
|
*/
|
|
1773
1865
|
openChat(messages, chatId) {
|
|
1774
1866
|
if (!messages || !Array.isArray(messages)) {
|
|
1775
1867
|
console.error('Error occurs while trying to load the chat discussion. Invalid messages received :', messages);
|
|
1776
1868
|
return;
|
|
1777
1869
|
}
|
|
1778
|
-
|
|
1870
|
+
if (chatId) {
|
|
1871
|
+
this.chatService.setSavedChatId(chatId);
|
|
1872
|
+
}
|
|
1779
1873
|
this.resetChat();
|
|
1780
1874
|
this.messages$.next(messages);
|
|
1781
1875
|
this.chatService.chatHistory = messages;
|
|
@@ -1830,60 +1924,44 @@ class ChatComponent extends AbstractFacet {
|
|
|
1830
1924
|
}
|
|
1831
1925
|
onKeyUp(event) {
|
|
1832
1926
|
switch (event.key) {
|
|
1833
|
-
case '
|
|
1834
|
-
this.
|
|
1835
|
-
break;
|
|
1836
|
-
case 'ArrowDown':
|
|
1837
|
-
this.navigateMessage(1);
|
|
1927
|
+
case 'Backspace':
|
|
1928
|
+
this.calculateHeight();
|
|
1838
1929
|
break;
|
|
1839
1930
|
case 'Enter':
|
|
1840
|
-
|
|
1931
|
+
if (!event.shiftKey)
|
|
1932
|
+
this.submitQuestion();
|
|
1933
|
+
this.calculateHeight();
|
|
1841
1934
|
break;
|
|
1842
1935
|
default:
|
|
1843
1936
|
break;
|
|
1844
1937
|
}
|
|
1845
|
-
// Handle Shift + Enter
|
|
1846
|
-
if (event.shiftKey && event.key === 'Enter') {
|
|
1847
|
-
this.submitQuestion();
|
|
1848
|
-
}
|
|
1849
1938
|
}
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
}
|
|
1858
|
-
this.currentMessageIndex = (this.currentMessageIndex ?? userMessages.length) + direction;
|
|
1859
|
-
if (this.currentMessageIndex < 0) {
|
|
1860
|
-
// If the user presses up arrow on the first message, stay at the first message
|
|
1861
|
-
this.currentMessageIndex = 0;
|
|
1862
|
-
}
|
|
1863
|
-
else if (this.currentMessageIndex >= userMessages.length) {
|
|
1864
|
-
// If the user presses down arrow on the last previous message, clear the input
|
|
1865
|
-
this.currentMessageIndex = undefined;
|
|
1866
|
-
this.question = '';
|
|
1867
|
-
return;
|
|
1868
|
-
}
|
|
1869
|
-
this.question = userMessages[this.currentMessageIndex].content;
|
|
1939
|
+
calculateHeight() {
|
|
1940
|
+
const maxHeight = 170;
|
|
1941
|
+
const el = this.questionInput.nativeElement;
|
|
1942
|
+
el.style.maxHeight = `${maxHeight}px`;
|
|
1943
|
+
el.style.height = 'auto';
|
|
1944
|
+
el.style.height = `${el.scrollHeight}px`;
|
|
1945
|
+
el.style.overflowY = el.scrollHeight >= maxHeight ? 'scroll' : 'hidden';
|
|
1870
1946
|
}
|
|
1871
1947
|
}
|
|
1872
1948
|
ChatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1873
|
-
ChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", protocol: "protocol", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", chat: "chat", customAssistantIcon: "customAssistantIcon" }, outputs: { data: "data", referenceClicked: "referenceClicked", openPreview: "openPreview", loading$: "loading", error: "error", _config: "config" }, providers: [
|
|
1949
|
+
ChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatComponent, isStandalone: true, selector: "sq-chat-v3", inputs: { instanceId: "instanceId", query: "query", queryChangeShouldTriggerReload: "queryChangeShouldTriggerReload", protocol: "protocol", messageHandlers: "messageHandlers", automaticScrollToLastResponse: "automaticScrollToLastResponse", chat: "chat", customAssistantIcon: "customAssistantIcon" }, outputs: { data: "data", referenceClicked: "referenceClicked", openPreview: "openPreview", loading$: "loading", error: "error", _config: "config" }, providers: [
|
|
1874
1950
|
RestChatService,
|
|
1875
1951
|
WebSocketChatService
|
|
1876
|
-
], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <i class=\"fas fa-search\"></i>\n <
|
|
1952
|
+
], queries: [{ propertyName: "loadingTpl", first: true, predicate: ["loadingTpl"], descendants: true }], viewQueries: [{ propertyName: "messageList", first: true, predicate: ["messageList"], descendants: true }, { propertyName: "questionInput", first: true, predicate: ["questionInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2 pb-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight()\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n </textarea>\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:end;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: ChatMessageComponent, selector: "sq-chat-message", inputs: ["message", "conversation", "assistantIcon", "streaming", "canEdit", "canRegenerate", "canCopy"], outputs: ["referenceClicked", "edit", "regenerate", "openPreview"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1877
1953
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, decorators: [{
|
|
1878
1954
|
type: Component,
|
|
1879
1955
|
args: [{ selector: 'sq-chat-v3', providers: [
|
|
1880
1956
|
RestChatService,
|
|
1881
1957
|
WebSocketChatService
|
|
1882
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent], template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <i class=\"fas fa-search\"></i>\n <
|
|
1958
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, FormsModule, ChatMessageComponent], template: "\n<ng-container *ngIf=\"!initializationError\">\n <div *ngIf=\"messages$ | async as messages; else loadingTpl || loadingTplDefault\" class=\"h-100 d-flex flex-column\">\n\n <ul class=\"list-group list-group-flush overflow-auto pe-2 pb-2\" #messageList>\n <ng-container *ngFor=\"let message of messages; let index = index; let last = last\">\n <!-- Regular messages -->\n <li class=\"list-group-item\" *ngIf=\"message.additionalProperties.display\"\n [class.opacity-50]=\"messageToEdit && messageToEdit < index + 1\">\n <sq-chat-message\n [class.sq-user-message]=\"message.role !== 'assistant'\"\n [message]=\"message\"\n [conversation]=\"messages\"\n [assistantIcon]=\"customAssistantIcon || assistantIcon\"\n [streaming]=\"last && (chatService.streaming$ | async)\"\n [canEdit]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role !== 'assistant'\"\n [canRegenerate]=\"(loading$ | async) === false && (chatService.streaming$ | async) === false && messageToEdit === undefined && message.role === 'assistant' && last\"\n [canCopy]=\"!(last && (chatService.streaming$ | async)) && messageToEdit === undefined && message.role === 'assistant'\"\n (edit)=\"editMessage(index)\" (regenerate)=\"regenerateMessage(index)\"\n (referenceClicked)=\"referenceClicked.emit($event)\"\n (openPreview)=\"openPreview.emit($event)\">\n </sq-chat-message>\n </li>\n </ng-container>\n\n <li class=\"list-group-item\" *ngIf=\"(loading$ | async) === true\">\n <ng-container *ngTemplateOutlet=\"loadingTpl || loadingTplDefault\"></ng-container>\n </li>\n </ul>\n\n <div class=\"user-input mt-auto\" *ngIf=\"enabledUserInput\">\n <div class=\"py-2\">\n <ng-container *ngTemplateOutlet=\"inputTpl\"></ng-container>\n <div class=\"text-end small text-muted px-3\" *ngIf=\"!!config?.globalSettings?.disclaimer\">\n {{ config?.globalSettings?.disclaimer }}\n </div>\n </div>\n </div>\n </div>\n</ng-container>\n\n<!-- NG TEMPLATES-->\n\n<ng-template #loadingTplDefault>\n <div class=\"spinner-grow text-primary d-block mx-auto my-5\" role=\"status\">\n <span class=\"visually-hidden\">Loading...</span>\n </div>\n</ng-template>\n\n<ng-template #inputTpl>\n <div class=\"px-3 py-1\">\n <div class=\"ast-input-container\">\n <button disabled class=\"btn btn-light\">\n <i class=\"fas fa-search\"></i>\n </button>\n <textarea #questionInput rows=\"1\"\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n (keydown)=\"calculateHeight()\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\n </textarea>\n <button\n *ngIf=\"!(chatService.streaming$ | async) && !(loading$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Send message\"\n (click)=\"submitQuestion()\">\n <i class=\"fas fa-paper-plane\"></i>\n </button>\n <!--<button\n *ngIf=\"(chatService.streaming$ | async)\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Stop generating\"\n (click)=\"terminateFetch()\">\n <i class=\"fas fa-stop\"></i>\n </button>-->\n <button\n *ngIf=\"messageToEdit\"\n type=\"button\"\n class=\"btn btn-light ms-2\"\n title=\"Cancel edition\"\n (click)=\"messageToEdit = undefined; question = ''\">\n <i class=\"fas fa-undo-alt\"></i>\n </button>\n <div class=\"sq-floating-scroll\" *ngIf=\"!isAtBottom\">\n <button class=\"btn shadow\" (click)=\"scrollDown()\">\n <i class=\"fas fa-angle-double-down\"></i>\n </button>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference,:host ::ng-deep .attachment .reference{position:relative;bottom:var(--ast-reference-bottom, .3em);font-weight:var(--ast-reference-font-weight, bold);padding:var(--ast-reference-padding, 0 .2em);margin:var(--ast-reference-margin, 0 .1em);border-radius:var(--ast-reference-border-radius, .2em);background-color:var(--ast-reference-background-color, lightblue);color:var(--ast-reference-color, black)}:host ::ng-deep .reference,:host ::ng-deep .message-content .reference{font-size:var(--ast-reference-message-font-size, .7em)}:host ::ng-deep .attachment .reference{font-size:var(--ast-reference-attachment-font-size, 13px)}:host{font-size:.875rem}:host>div>.user-input>div:not(.progress),:host>div>ul>li{width:var(--ast-chat-container-width, 100%);max-width:100%;margin-left:auto;margin-right:auto}:host>div>ul{padding-top:var(--ast-chat-padding-top, 0);padding-bottom:var(--ast-chat-padding-bottom, 0)}li.attachment>p{display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:3}li.attachment.expanded>p{display:block}.progress{--bs-progress-height: 3px}.progress.disabled{--bs-progress-height: 20px;--bs-progress-bar-bg: var(--bs-danger)}.user-input{z-index:1}.user-input ul.list-group{max-height:30vh}.form-control:disabled{background-color:#ededed}a.disabled{cursor:default;opacity:.5}.no-max-height{max-height:initial!important}.sq-floating-scroll{position:absolute;right:50%;bottom:75px;text-align:center}.sq-floating-scroll .btn{background-color:#fff}.sq-floating-scroll .btn:hover{background-color:#fff;opacity:.9}.ast-input-container{display:flex;align-items:end;background-color:var(--ast-input-bg, #F8F8F8);border-radius:var(--ast-size-3, .75rem)}.ast-input-container>i{padding-left:var(--ast-size-3, .75rem);color:var(--ast-muted-color, rgba(33, 37, 41, .75))}.ast-input-container textarea{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem);resize:none}.ast-input-container textarea,.ast-input-container button,.ast-input-container button:hover{background-color:transparent;border:0}.ast-input-container button:hover{color:var(--ast-primary-color, #005DA7)}.ast-input-container button:not(:hover){color:var(--ast-muted-color, rgba(33, 37, 41, .75))}sq-chat-message.sq-user-message{float:var(--ast-user-message-float, none)}\n"] }]
|
|
1883
1959
|
}], ctorParameters: function () { return []; }, propDecorators: { instanceId: [{
|
|
1884
1960
|
type: Input
|
|
1885
1961
|
}], query: [{
|
|
1886
1962
|
type: Input
|
|
1963
|
+
}], queryChangeShouldTriggerReload: [{
|
|
1964
|
+
type: Input
|
|
1887
1965
|
}], protocol: [{
|
|
1888
1966
|
type: Input
|
|
1889
1967
|
}], messageHandlers: [{
|
|
@@ -1945,12 +2023,11 @@ class SavedChatsComponent {
|
|
|
1945
2023
|
}
|
|
1946
2024
|
onListSavedChat() {
|
|
1947
2025
|
this.subscription.add(this.chatService.savedChats$.subscribe((savedChats) => {
|
|
1948
|
-
this.currentChatId = undefined;
|
|
1949
2026
|
this.groupedSavedChats$.next(this._groupSavedChatsByDate(savedChats));
|
|
1950
2027
|
}));
|
|
1951
2028
|
}
|
|
1952
2029
|
onLoad(savedChat) {
|
|
1953
|
-
this.
|
|
2030
|
+
this.chatService.setSavedChatId(savedChat.id);
|
|
1954
2031
|
this.chatService.loadSavedChat$.next(savedChat);
|
|
1955
2032
|
this.chatService.listSavedChat();
|
|
1956
2033
|
this.load.emit(savedChat);
|
|
@@ -2056,10 +2133,10 @@ class SavedChatsComponent {
|
|
|
2056
2133
|
}
|
|
2057
2134
|
}
|
|
2058
2135
|
SavedChatsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: SavedChatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2059
|
-
SavedChatsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: SavedChatsComponent, isStandalone: true, selector: "sq-saved-chats-v3", inputs: { instanceId: "instanceId" }, outputs: { load: "load", delete: "delete" }, ngImport: i0, template: "<ng-container *ngIf=\"(chatService.chatConfig$ | async)?.savedChatSettings.display\">\n <div *ngFor=\"let group of (groupedSavedChats$ | async)\" class=\"saved-chats\">\n <div class=\"saved-chat-date\">{{group.key}}</div>\n <div *ngFor=\"let savedChat of group.value\" class=\"saved-chat p-2\" [class.active]=\"
|
|
2136
|
+
SavedChatsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: SavedChatsComponent, isStandalone: true, selector: "sq-saved-chats-v3", inputs: { instanceId: "instanceId" }, outputs: { load: "load", delete: "delete" }, ngImport: i0, template: "<ng-container *ngIf=\"(chatService.chatConfig$ | async)?.savedChatSettings.display\">\n <div *ngFor=\"let group of (groupedSavedChats$ | async)\" class=\"saved-chats\">\n <div class=\"saved-chat-date\">{{group.key}}</div>\n <div *ngFor=\"let savedChat of group.value\" class=\"saved-chat p-2\" [class.active]=\"chatService.savedChatId === savedChat.id\"\n (click)=\"onLoad(savedChat)\">\n <span class=\"title me-1\">{{savedChat.title}}</span>\n <i class=\"saved-chat-actions fas fa-pen mx-1\" [sqTooltip]=\"'Rename'\"\n (click)=\"$event.stopPropagation(); onRename(savedChat)\"></i>\n <i class=\"saved-chat-actions fas fa-trash ms-1\" [sqTooltip]=\"'Delete'\"\n (click)=\"$event.stopPropagation(); onDelete(savedChat)\"></i>\n </div>\n </div>\n</ng-container>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}.saved-chats .saved-chat-date{font-weight:500;color:#a9a9a9;margin-top:.5rem}.saved-chats .saved-chat{display:flex;align-items:center;cursor:pointer;margin-left:.25rem}.saved-chats .saved-chat span{flex-grow:1;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.saved-chats .saved-chat .saved-chat-actions{display:none}.saved-chats .saved-chat:hover,.saved-chats .saved-chat.active{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-saved-chat-hover-background, #FFF8F1)}.saved-chats .saved-chat:hover .saved-chat-actions{display:block}.saved-chats .title{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ModalModule }, { kind: "ngmodule", type: UtilsModule }, { kind: "directive", type: i2$1.TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }] });
|
|
2060
2137
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: SavedChatsComponent, decorators: [{
|
|
2061
2138
|
type: Component,
|
|
2062
|
-
args: [{ selector: 'sq-saved-chats-v3', standalone: true, imports: [CommonModule, ModalModule, UtilsModule], template: "<ng-container *ngIf=\"(chatService.chatConfig$ | async)?.savedChatSettings.display\">\n <div *ngFor=\"let group of (groupedSavedChats$ | async)\" class=\"saved-chats\">\n <div class=\"saved-chat-date\">{{group.key}}</div>\n <div *ngFor=\"let savedChat of group.value\" class=\"saved-chat p-2\" [class.active]=\"
|
|
2139
|
+
args: [{ selector: 'sq-saved-chats-v3', standalone: true, imports: [CommonModule, ModalModule, UtilsModule], template: "<ng-container *ngIf=\"(chatService.chatConfig$ | async)?.savedChatSettings.display\">\n <div *ngFor=\"let group of (groupedSavedChats$ | async)\" class=\"saved-chats\">\n <div class=\"saved-chat-date\">{{group.key}}</div>\n <div *ngFor=\"let savedChat of group.value\" class=\"saved-chat p-2\" [class.active]=\"chatService.savedChatId === savedChat.id\"\n (click)=\"onLoad(savedChat)\">\n <span class=\"title me-1\">{{savedChat.title}}</span>\n <i class=\"saved-chat-actions fas fa-pen mx-1\" [sqTooltip]=\"'Rename'\"\n (click)=\"$event.stopPropagation(); onRename(savedChat)\"></i>\n <i class=\"saved-chat-actions fas fa-trash ms-1\" [sqTooltip]=\"'Delete'\"\n (click)=\"$event.stopPropagation(); onDelete(savedChat)\"></i>\n </div>\n </div>\n</ng-container>\n", styles: [".ast-primary{color:var(--ast-primary-color, #005DA7);background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover{background-color:var(--ast-primary-bg, #f2f8fe)}.ast-primary-hover:hover{color:var(--ast-primary-color, #005DA7)}.ast-secondary{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-secondary-bg, #FFF8F1)}.ast-btn{border:0;text-align:left;padding-top:.5rem;padding-bottom:.5rem;display:flex;align-items:center}.dark{--ast-primary-bg: #0d0701;--ast-primary-color: #008cd1;--ast-secondary-bg: #00070e;--ast-secondary-color: #ffa258;--ast-input-bg: #070707;--ast-input-color: rgba(222, 218, 218, .75);--ast-muted-color: rgba(222, 218, 218, .75);--ast-saved-chat-hover-background: #262421;--ast-message-table-border-color: #333333;--ast-message-table-tr-bg: #070707;--ast-message-table-tr-border-color: #222222;--ast-reference-icon-color: white;--ast-reference-icon-active-color: black;--ast-reference-passages-color: white;--ast-reference-expanded-hover-bg: #262421;--ast-message-reference-color: black}.saved-chats .saved-chat-date{font-weight:500;color:#a9a9a9;margin-top:.5rem}.saved-chats .saved-chat{display:flex;align-items:center;cursor:pointer;margin-left:.25rem}.saved-chats .saved-chat span{flex-grow:1;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.saved-chats .saved-chat .saved-chat-actions{display:none}.saved-chats .saved-chat:hover,.saved-chats .saved-chat.active{color:var(--ast-secondary-color, #FF732E);background-color:var(--ast-saved-chat-hover-background, #FFF8F1)}.saved-chats .saved-chat:hover .saved-chat-actions{display:block}.saved-chats .title{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n"] }]
|
|
2063
2140
|
}], propDecorators: { instanceId: [{
|
|
2064
2141
|
type: Input
|
|
2065
2142
|
}], load: [{
|