@sinequa/assistant 3.1.1 → 3.2.0
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 +2 -0
- package/chat/chat-settings-v3/chat-settings-v3.component.d.ts +8 -3
- package/chat/chat.component.d.ts +164 -145
- package/chat/chat.service.d.ts +21 -914
- package/chat/prompt.component.d.ts +21 -0
- package/chat/public-api.d.ts +1 -0
- package/chat/rest-chat.service.d.ts +4 -2
- package/chat/saved-chats/saved-chats.component.d.ts +5 -3
- package/chat/styles/assistant.scss +21 -1
- package/chat/types.d.ts +284 -866
- package/chat/websocket-chat.service.d.ts +4 -2
- package/esm2020/chat/chat-message/chat-message.component.mjs +5 -3
- package/esm2020/chat/chat-reference/chat-reference.component.mjs +3 -3
- package/esm2020/chat/chat-settings-v3/chat-settings-v3.component.mjs +22 -24
- package/esm2020/chat/chat.component.mjs +88 -33
- package/esm2020/chat/chat.service.mjs +68 -24
- package/esm2020/chat/prompt.component.mjs +88 -0
- package/esm2020/chat/public-api.mjs +2 -1
- package/esm2020/chat/rest-chat.service.mjs +41 -18
- package/esm2020/chat/saved-chats/saved-chats.component.mjs +38 -7
- package/esm2020/chat/types.mjs +50 -54
- package/esm2020/chat/websocket-chat.service.mjs +46 -19
- package/fesm2015/sinequa-assistant-chat.mjs +428 -172
- package/fesm2015/sinequa-assistant-chat.mjs.map +1 -1
- package/fesm2020/sinequa-assistant-chat.mjs +429 -176
- package/fesm2020/sinequa-assistant-chat.mjs.map +1 -1
- package/package.json +4 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, EventEmitter, inject, Component, Input, Output, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ContentChild } from '@angular/core';
|
|
2
|
+
import { Injectable, EventEmitter, inject, Component, Input, Output, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, ContentChild, Inject } from '@angular/core';
|
|
3
3
|
import { Subscription, filter, tap, switchMap, BehaviorSubject, Subject, forkJoin, map, catchError, throwError, shareReplay, fromEvent, merge, takeUntil, 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';
|
|
7
7
|
import { CommonModule } from '@angular/common';
|
|
8
8
|
import * as i2 from '@angular/forms';
|
|
9
|
-
import { FormsModule } from '@angular/forms';
|
|
9
|
+
import { FormsModule, Validators, UntypedFormControl, ReactiveFormsModule } from '@angular/forms';
|
|
10
10
|
import { LoginService, AuthenticationService } from '@sinequa/core/login';
|
|
11
11
|
import { Action } from '@sinequa/components/action';
|
|
12
12
|
import { AbstractFacet } from '@sinequa/components/facet';
|
|
@@ -16,9 +16,12 @@ import { UserPreferences } from '@sinequa/components/user-settings';
|
|
|
16
16
|
import { NotificationsService } from '@sinequa/core/notification';
|
|
17
17
|
import { z } from 'zod';
|
|
18
18
|
import { AppService } from '@sinequa/core/app-utils';
|
|
19
|
-
import
|
|
19
|
+
import * as i6$1 from '@sinequa/core/intl';
|
|
20
|
+
import { IntlService, IntlModule } from '@sinequa/core/intl';
|
|
20
21
|
import get from 'lodash/get';
|
|
21
22
|
import { Utils } from '@sinequa/core/base';
|
|
23
|
+
import * as i1$2 from '@sinequa/core/modal';
|
|
24
|
+
import { ModalService, ModalButton, ModalModule, MODAL_MODEL } from '@sinequa/core/modal';
|
|
22
25
|
import { HttpTransportType, LogLevel } from '@microsoft/signalr';
|
|
23
26
|
import { unified } from 'unified';
|
|
24
27
|
import remarkParse from 'remark-parse';
|
|
@@ -31,8 +34,13 @@ import { CollapseModule } from '@sinequa/components/collapse';
|
|
|
31
34
|
import * as i6 from 'ngx-remark';
|
|
32
35
|
import { RemarkModule } from 'ngx-remark';
|
|
33
36
|
import SafeColor from 'safecolor';
|
|
34
|
-
import
|
|
37
|
+
import 'prismjs-components-importer/esm';
|
|
38
|
+
import 'prismjs/plugins/autoloader/prism-autoloader';
|
|
35
39
|
import { parseISO, isToday, isYesterday, isThisWeek, differenceInDays, endOfYesterday, isThisMonth, differenceInMonths, isThisQuarter, isThisYear, differenceInYears, format } from 'date-fns';
|
|
40
|
+
import * as i4 from '@sinequa/components/modal';
|
|
41
|
+
import { BsModalModule } from '@sinequa/components/modal';
|
|
42
|
+
import * as i5$1 from '@sinequa/core/validation';
|
|
43
|
+
import { ValidationModule } from '@sinequa/core/validation';
|
|
36
44
|
|
|
37
45
|
/**
|
|
38
46
|
* A service to create and manage instances of ChatService dynamically based on the provided component references and the implementation type (http or websocket)
|
|
@@ -83,6 +91,7 @@ class ChatSettingsV3Component {
|
|
|
83
91
|
this._update = new EventEmitter();
|
|
84
92
|
this._cancel = new EventEmitter();
|
|
85
93
|
this.subscription = new Subscription();
|
|
94
|
+
this.functions = [];
|
|
86
95
|
this.isAdmin = false;
|
|
87
96
|
this.loginService = inject(LoginService);
|
|
88
97
|
this.instanceManagerService = inject(InstanceManagerService);
|
|
@@ -93,8 +102,8 @@ class ChatSettingsV3Component {
|
|
|
93
102
|
this.isAdmin = this.principalService.principal.isAdministrator;
|
|
94
103
|
// Init config with a copy of the original chat config, so that it won't be modified by the user until he clicks on save
|
|
95
104
|
this.config = JSON.parse(JSON.stringify(this.chatService.chatConfig$.value));
|
|
96
|
-
this.selectedModel = this.chatService.getModel(this.config.
|
|
97
|
-
this.
|
|
105
|
+
this.selectedModel = this.chatService.getModel(this.config.defaultValues.service_id, this.config.defaultValues.model_id);
|
|
106
|
+
this.initFunctionsList();
|
|
98
107
|
}));
|
|
99
108
|
}
|
|
100
109
|
ngOnDestroy() {
|
|
@@ -102,14 +111,14 @@ class ChatSettingsV3Component {
|
|
|
102
111
|
}
|
|
103
112
|
get hasPrompts() {
|
|
104
113
|
return this.isAdmin
|
|
105
|
-
|| !!this.config.uiSettings.
|
|
106
|
-
|| !!this.config.uiSettings.
|
|
114
|
+
|| !!this.config.uiSettings.displaySystemPrompt
|
|
115
|
+
|| !!this.config.uiSettings.displayUserPrompt;
|
|
107
116
|
}
|
|
108
117
|
get hasAdvancedParameters() {
|
|
109
118
|
return this.isAdmin
|
|
110
119
|
|| !!this.config.uiSettings.temperature
|
|
111
120
|
|| !!this.config.uiSettings.top_p
|
|
112
|
-
|| !!this.config.uiSettings.
|
|
121
|
+
|| !!this.config.uiSettings.max_tokens;
|
|
113
122
|
}
|
|
114
123
|
get hasModel() {
|
|
115
124
|
return this.isAdmin
|
|
@@ -118,49 +127,47 @@ class ChatSettingsV3Component {
|
|
|
118
127
|
|| !!this.config.uiSettings.debug
|
|
119
128
|
|| !!this.config.uiSettings.temperature
|
|
120
129
|
|| !!this.config.uiSettings.top_p
|
|
121
|
-
|| !!this.config.uiSettings.
|
|
130
|
+
|| !!this.config.uiSettings.max_tokens;
|
|
122
131
|
}
|
|
123
132
|
instantiateChatService() {
|
|
124
133
|
this.chatService = this.instanceManagerService.getInstance(this.instanceId);
|
|
125
134
|
}
|
|
126
135
|
onChatModelChange(selectedModel) {
|
|
127
136
|
// Update properties based on the selected model
|
|
128
|
-
this.config.
|
|
129
|
-
this.config.
|
|
137
|
+
this.config.defaultValues.service_id = selectedModel.serviceId;
|
|
138
|
+
this.config.defaultValues.model_id = selectedModel.modelId;
|
|
139
|
+
}
|
|
140
|
+
getFunctionDescription(name) {
|
|
141
|
+
var _a, _b;
|
|
142
|
+
return ((_b = (_a = this.chatService.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.functionName === name)) === null || _b === void 0 ? void 0 : _b.description) || "";
|
|
130
143
|
}
|
|
131
144
|
toggleFunctionsSelection(name) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
else {
|
|
136
|
-
this.config.functions.push(name);
|
|
137
|
-
}
|
|
145
|
+
// Update the enabled property of the function
|
|
146
|
+
const index = this.config.defaultValues.functions.findIndex(func => func.name === name);
|
|
147
|
+
this.config.defaultValues.functions[index].enabled = this.functions[index].enabled;
|
|
138
148
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
(this.chatService.functions || []).forEach(item => {
|
|
142
|
-
item['selected'] = this.config.functions.includes(item.functionName);
|
|
143
|
-
});
|
|
149
|
+
initFunctionsList() {
|
|
150
|
+
this.functions = this.config.defaultValues.functions.filter(func => { var _a; return !!((_a = this.chatService.functions) === null || _a === void 0 ? void 0 : _a.find(fn => fn.functionName === func.name)); });
|
|
144
151
|
}
|
|
145
152
|
/**
|
|
146
153
|
* Save the new chat config in the chat service and the user preferences
|
|
147
154
|
*/
|
|
148
155
|
save() {
|
|
149
156
|
this.chatService.updateChatConfig(this.config);
|
|
150
|
-
this._update.emit();
|
|
157
|
+
this._update.emit(this.config);
|
|
151
158
|
}
|
|
152
159
|
/**
|
|
153
160
|
* Cancel the current changes
|
|
154
161
|
*/
|
|
155
162
|
cancel() {
|
|
156
|
-
this._cancel.emit();
|
|
163
|
+
this._cancel.emit(this.chatService.chatConfig$.value);
|
|
157
164
|
}
|
|
158
165
|
}
|
|
159
166
|
ChatSettingsV3Component.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatSettingsV3Component, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
160
|
-
ChatSettingsV3Component.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatSettingsV3Component, isStandalone: true, selector: "sq-chat-settings-v3", inputs: { instanceId: "instanceId" }, outputs: { _update: "update", _cancel: "cancel" }, ngImport: i0, template: "<div class=\"sq-chat-settings\">\n <div class=\"settings-panel card-body small\" *ngIf=\"config\">\n\n <h5 *ngIf=\"hasModel\">Model</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.servicesModels\">\n <label for=\"gllmModel\" class=\"form-label\">Model</label>\n <select class=\"form-select\" id=\"gllmModel\" [(ngModel)]=\"selectedModel\" (ngModelChange)=\"onChatModelChange($event)\">\n <option *ngFor=\"let model of chatService.models\" [ngValue]=\"model\">{{model.displayName}}</option>\n </select>\n </div>\n
|
|
167
|
+
ChatSettingsV3Component.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatSettingsV3Component, isStandalone: true, selector: "sq-chat-settings-v3", inputs: { instanceId: "instanceId" }, outputs: { _update: "update", _cancel: "cancel" }, ngImport: i0, template: "<div class=\"sq-chat-settings\" *ngIf=\"isAdmin || config.uiSettings.display\">\n <div class=\"settings-panel card-body small\" *ngIf=\"config\">\n\n <h5 *ngIf=\"hasModel\">Model</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.servicesModels\">\n <label for=\"gllmModel\" class=\"form-label\">Model</label>\n <select class=\"form-select\" id=\"gllmModel\" [(ngModel)]=\"selectedModel\" (ngModelChange)=\"onChatModelChange($event)\">\n <option *ngFor=\"let model of chatService.models\" [ngValue]=\"model\">{{model.displayName}}</option>\n </select>\n </div>\n\n <div class=\"mb-4\" *ngIf=\"isAdmin || config.uiSettings.functions\">\n <label for=\"gllmFunctions\" class=\"form-label\">Functions</label>\n <div id=\"gllmFunctions\" *ngFor=\"let func of functions\" class=\"multi-option form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" [id]=\"func.name\" [(ngModel)]=\"func.enabled\"\n (ngModelChange)=\"toggleFunctionsSelection(func.name)\">\n <label class=\"form-check-label\" [for]=\"func.name\" [title]=\"getFunctionDescription(func.name)\">{{ func.name }}</label>\n </div>\n </div>\n\n <div class=\"form-check form-switch mb-2\" *ngIf=\"isAdmin || config.uiSettings.debug\">\n <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"debug\" [(ngModel)]=\"config.defaultValues.debug\">\n <label class=\"form-check-label\" for=\"debug\">Debug</label>\n </div>\n\n <details *ngIf=\"hasAdvancedParameters\">\n <summary>Advanced parameters</summary>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.temperature\">\n <label for=\"temperature\" class=\"form-label\">Temperature: {{config.defaultValues.temperature}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"2\" step=\"0.1\" id=\"temperature\"\n [(ngModel)]=\"config.defaultValues.temperature\">\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.top_p\">\n <label for=\"top-p\" class=\"form-label\">Top P: {{config.defaultValues.top_p}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"1\" step=\"0.05\" id=\"top-p\"\n [(ngModel)]=\"config.defaultValues.top_p\">\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.max_tokens\">\n <label for=\"max-tokens\" class=\"form-label\">Max generated tokens per answer:\n {{config.defaultValues.max_tokens}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"1\" max=\"2048\" step=\"1\" id=\"max-tokens\"\n [(ngModel)]=\"config.defaultValues.max_tokens\">\n </div>\n </details>\n\n <hr>\n\n <h5 *ngIf=\"hasPrompts\">Prompts</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.displaySystemPrompt\">\n <label for=\"initialSystemPrompt\" class=\"form-label\">System prompt (hidden)</label>\n <textarea class=\"form-control\" id=\"initialSystemPrompt\" [(ngModel)]=\"config.defaultValues.systemPrompt\"></textarea>\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.displayUserPrompt\">\n <label for=\"initialUserPrompt\" class=\"form-label\">Initial user prompt</label>\n <textarea class=\"form-control\" id=\"initialUserPrompt\" [(ngModel)]=\"config.defaultValues.userPrompt\"></textarea>\n </div>\n\n </div>\n\n <div class=\"buttons-panel d-flex justify-content-end\">\n <button class=\"btn btn-light\" (click)=\"cancel()\">Cancel</button>\n <button class=\"btn btn-primary\" *ngIf=\"config\" (click)=\"save()\">Save</button>\n </div>\n\n</div>\n", styles: [":host{display:block;width:var(--ast-chat-settings-width, 100%);max-width:100%;height:100%;margin-left:auto;margin-right:auto;padding-top:var(--ast-chat-settings-padding-top, 0);padding-bottom:var(--ast-chat-settings-padding-bottom, 0)}.sq-chat-settings{display:flex;flex-direction:column;height:100%}.sq-chat-settings .settings-panel{flex-grow:1;overflow:auto}.sq-chat-settings .buttons-panel{padding-top:.5rem}\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: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.RangeValueAccessor, selector: "input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { 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"] }] });
|
|
161
168
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatSettingsV3Component, decorators: [{
|
|
162
169
|
type: Component,
|
|
163
|
-
args: [{ selector: 'sq-chat-settings-v3', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"sq-chat-settings\">\n <div class=\"settings-panel card-body small\" *ngIf=\"config\">\n\n <h5 *ngIf=\"hasModel\">Model</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.servicesModels\">\n <label for=\"gllmModel\" class=\"form-label\">Model</label>\n <select class=\"form-select\" id=\"gllmModel\" [(ngModel)]=\"selectedModel\" (ngModelChange)=\"onChatModelChange($event)\">\n <option *ngFor=\"let model of chatService.models\" [ngValue]=\"model\">{{model.displayName}}</option>\n </select>\n </div>\n
|
|
170
|
+
args: [{ selector: 'sq-chat-settings-v3', standalone: true, imports: [CommonModule, FormsModule], template: "<div class=\"sq-chat-settings\" *ngIf=\"isAdmin || config.uiSettings.display\">\n <div class=\"settings-panel card-body small\" *ngIf=\"config\">\n\n <h5 *ngIf=\"hasModel\">Model</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.servicesModels\">\n <label for=\"gllmModel\" class=\"form-label\">Model</label>\n <select class=\"form-select\" id=\"gllmModel\" [(ngModel)]=\"selectedModel\" (ngModelChange)=\"onChatModelChange($event)\">\n <option *ngFor=\"let model of chatService.models\" [ngValue]=\"model\">{{model.displayName}}</option>\n </select>\n </div>\n\n <div class=\"mb-4\" *ngIf=\"isAdmin || config.uiSettings.functions\">\n <label for=\"gllmFunctions\" class=\"form-label\">Functions</label>\n <div id=\"gllmFunctions\" *ngFor=\"let func of functions\" class=\"multi-option form-check form-switch\">\n <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" [id]=\"func.name\" [(ngModel)]=\"func.enabled\"\n (ngModelChange)=\"toggleFunctionsSelection(func.name)\">\n <label class=\"form-check-label\" [for]=\"func.name\" [title]=\"getFunctionDescription(func.name)\">{{ func.name }}</label>\n </div>\n </div>\n\n <div class=\"form-check form-switch mb-2\" *ngIf=\"isAdmin || config.uiSettings.debug\">\n <input class=\"form-check-input\" type=\"checkbox\" role=\"switch\" id=\"debug\" [(ngModel)]=\"config.defaultValues.debug\">\n <label class=\"form-check-label\" for=\"debug\">Debug</label>\n </div>\n\n <details *ngIf=\"hasAdvancedParameters\">\n <summary>Advanced parameters</summary>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.temperature\">\n <label for=\"temperature\" class=\"form-label\">Temperature: {{config.defaultValues.temperature}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"2\" step=\"0.1\" id=\"temperature\"\n [(ngModel)]=\"config.defaultValues.temperature\">\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.top_p\">\n <label for=\"top-p\" class=\"form-label\">Top P: {{config.defaultValues.top_p}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"0\" max=\"1\" step=\"0.05\" id=\"top-p\"\n [(ngModel)]=\"config.defaultValues.top_p\">\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.max_tokens\">\n <label for=\"max-tokens\" class=\"form-label\">Max generated tokens per answer:\n {{config.defaultValues.max_tokens}}</label>\n <input type=\"range\" class=\"form-range form-range-sm\" min=\"1\" max=\"2048\" step=\"1\" id=\"max-tokens\"\n [(ngModel)]=\"config.defaultValues.max_tokens\">\n </div>\n </details>\n\n <hr>\n\n <h5 *ngIf=\"hasPrompts\">Prompts</h5>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.displaySystemPrompt\">\n <label for=\"initialSystemPrompt\" class=\"form-label\">System prompt (hidden)</label>\n <textarea class=\"form-control\" id=\"initialSystemPrompt\" [(ngModel)]=\"config.defaultValues.systemPrompt\"></textarea>\n </div>\n <div class=\"mb-2\" *ngIf=\"isAdmin || config.uiSettings.displayUserPrompt\">\n <label for=\"initialUserPrompt\" class=\"form-label\">Initial user prompt</label>\n <textarea class=\"form-control\" id=\"initialUserPrompt\" [(ngModel)]=\"config.defaultValues.userPrompt\"></textarea>\n </div>\n\n </div>\n\n <div class=\"buttons-panel d-flex justify-content-end\">\n <button class=\"btn btn-light\" (click)=\"cancel()\">Cancel</button>\n <button class=\"btn btn-primary\" *ngIf=\"config\" (click)=\"save()\">Save</button>\n </div>\n\n</div>\n", styles: [":host{display:block;width:var(--ast-chat-settings-width, 100%);max-width:100%;height:100%;margin-left:auto;margin-right:auto;padding-top:var(--ast-chat-settings-padding-top, 0);padding-bottom:var(--ast-chat-settings-padding-bottom, 0)}.sq-chat-settings{display:flex;flex-direction:column;height:100%}.sq-chat-settings .settings-panel{flex-grow:1;overflow:auto}.sq-chat-settings .buttons-panel{padding-top:.5rem}\n"] }]
|
|
164
171
|
}], propDecorators: { instanceId: [{
|
|
165
172
|
type: Input
|
|
166
173
|
}], _update: [{
|
|
@@ -171,8 +178,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
171
178
|
args: ["cancel"]
|
|
172
179
|
}] } });
|
|
173
180
|
|
|
174
|
-
// Define the Zod representation for the
|
|
175
|
-
const
|
|
181
|
+
// Define the Zod representation for the connectionSettings object
|
|
182
|
+
const connectionSettingsSchema = z.object({
|
|
176
183
|
restEndpoint: z.string().optional(),
|
|
177
184
|
websocketEndpoint: z.string().optional(),
|
|
178
185
|
signalRTransport: z.enum(["WebSockets", "ServerSentEvents", "LongPolling", "None"]),
|
|
@@ -186,50 +193,10 @@ const serviceSettingsSchema = z.object({
|
|
|
186
193
|
model_id: z.string(),
|
|
187
194
|
temperature: z.number(),
|
|
188
195
|
top_p: z.number(),
|
|
189
|
-
|
|
190
|
-
results_per_prompt: z.number(),
|
|
191
|
-
presence_penalty: z.number(),
|
|
192
|
-
frequency_penalty: z.number(),
|
|
193
|
-
});
|
|
194
|
-
// Define the Zod representation for the TextChunksOptions interface
|
|
195
|
-
const textChunksOptionsSchema = z.object({
|
|
196
|
-
extendMode: z.enum(['None', 'Sentence', 'Chars']).optional(),
|
|
197
|
-
extendScope: z.number().optional(),
|
|
198
|
-
});
|
|
199
|
-
// Define the Zod representation for the contextOptions object
|
|
200
|
-
const contextOptionsSchema = z.object({
|
|
201
|
-
docColumns: z.array(z.string()),
|
|
202
|
-
textChunkFillGaps: z.number(),
|
|
203
|
-
html: z.boolean(),
|
|
204
|
-
topPassagesOptions: z.object({
|
|
205
|
-
topPassages: z.number(),
|
|
206
|
-
topPassagesMinScore: z.number(),
|
|
207
|
-
textChunkOptions: textChunksOptionsSchema,
|
|
208
|
-
}),
|
|
209
|
-
matchingPassagesOptions: z.object({
|
|
210
|
-
matchingPassagesPerDoc: z.number(),
|
|
211
|
-
fromTopDocuments: z.number(),
|
|
212
|
-
matchingPassagesMinScore: z.number(),
|
|
213
|
-
textChunkOptions: textChunksOptionsSchema,
|
|
214
|
-
}),
|
|
215
|
-
relevantExtractsOptions: z.object({
|
|
216
|
-
topRelevantExtractsPerDoc: z.number(),
|
|
217
|
-
fromTopDocuments: z.number(),
|
|
218
|
-
textChunkOptions: textChunksOptionsSchema,
|
|
219
|
-
}),
|
|
220
|
-
htmlOptions: z.object({
|
|
221
|
-
images: z.boolean(),
|
|
222
|
-
links: z.boolean(),
|
|
223
|
-
tables: z.boolean(),
|
|
224
|
-
extendTables: z.boolean(),
|
|
225
|
-
}),
|
|
226
|
-
});
|
|
227
|
-
// Define the Zod representation for the contextSettings object
|
|
228
|
-
const contextSettingsSchema = z.object({
|
|
229
|
-
app: z.string().optional(),
|
|
230
|
-
query: z.object({}).optional(),
|
|
231
|
-
contextOptions: contextOptionsSchema,
|
|
196
|
+
max_tokens: z.number()
|
|
232
197
|
});
|
|
198
|
+
// Define the Zod representation for the additionalServiceSettings object
|
|
199
|
+
const additionalServiceSettingsSchema = z.object({});
|
|
233
200
|
// Define the Zod representation for the uiSettings object
|
|
234
201
|
const uiSettingsSchema = z.object({
|
|
235
202
|
display: z.boolean(),
|
|
@@ -237,22 +204,58 @@ const uiSettingsSchema = z.object({
|
|
|
237
204
|
functions: z.boolean(),
|
|
238
205
|
temperature: z.boolean(),
|
|
239
206
|
top_p: z.boolean(),
|
|
240
|
-
|
|
207
|
+
max_tokens: z.boolean(),
|
|
241
208
|
debug: z.boolean(),
|
|
242
209
|
displaySystemPrompt: z.boolean(),
|
|
210
|
+
displayUserPrompt: z.boolean()
|
|
211
|
+
});
|
|
212
|
+
// Define the Zod representation for the defaultValues object
|
|
213
|
+
const defaultValuesSchema = z.object({
|
|
214
|
+
service_id: z.string(),
|
|
215
|
+
model_id: z.string(),
|
|
216
|
+
functions: z.array(z.object({
|
|
217
|
+
name: z.string(),
|
|
218
|
+
enabled: z.boolean()
|
|
219
|
+
})),
|
|
220
|
+
temperature: z.number(),
|
|
221
|
+
top_p: z.number(),
|
|
222
|
+
max_tokens: z.number(),
|
|
223
|
+
debug: z.boolean(),
|
|
243
224
|
systemPrompt: z.string(),
|
|
225
|
+
userPrompt: z.string()
|
|
226
|
+
});
|
|
227
|
+
// Define the Zod representation for the modeSettings object
|
|
228
|
+
const initializationSchema = z.object({
|
|
229
|
+
event: z.enum(['Query', 'Prompt']),
|
|
230
|
+
forcedWorkflow: z.string().optional(),
|
|
231
|
+
displayUserQuery: z.boolean().optional(), // Optional for event 'Prompt'
|
|
232
|
+
}).refine(data => ((data.event === "Query") ? (!!data.forcedWorkflow && data.displayUserQuery !== undefined && data.displayUserQuery !== null) : true), {
|
|
233
|
+
message: "The 'forcedWorkflow' and 'displayUserQuery' properties must be provided when the initialization's event is 'Query'.",
|
|
234
|
+
});
|
|
235
|
+
const modeSettingsSchema = z.object({
|
|
236
|
+
enabledUserInput: z.boolean(),
|
|
244
237
|
displayUserPrompt: z.boolean(),
|
|
245
|
-
|
|
238
|
+
sendUserPrompt: z.boolean(),
|
|
239
|
+
initialization: initializationSchema
|
|
240
|
+
});
|
|
241
|
+
// Define the Zod representation for the savedChatSettings object
|
|
242
|
+
const savedChatSettingsSchema = z.object({
|
|
243
|
+
enabled: z.boolean(),
|
|
244
|
+
display: z.boolean()
|
|
245
|
+
});
|
|
246
|
+
// Define the Zod representation for the globalSettings object
|
|
247
|
+
const globalSettingsSchema = z.object({
|
|
248
|
+
disclaimer: z.string().optional(),
|
|
246
249
|
});
|
|
247
250
|
// Define the Zod representation for the entire ChatConfig object
|
|
248
251
|
const chatConfigSchema = z.object({
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
connectionSettings: connectionSettingsSchema,
|
|
253
|
+
defaultValues: defaultValuesSchema,
|
|
254
|
+
modeSettings: modeSettingsSchema,
|
|
252
255
|
uiSettings: uiSettingsSchema,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
+
additionalServiceSettings: additionalServiceSettingsSchema,
|
|
257
|
+
savedChatSettings: savedChatSettingsSchema,
|
|
258
|
+
globalSettings: globalSettingsSchema
|
|
256
259
|
});
|
|
257
260
|
|
|
258
261
|
class ChatService {
|
|
@@ -269,7 +272,6 @@ class ChatService {
|
|
|
269
272
|
this.savedChats$ = new BehaviorSubject([]);
|
|
270
273
|
/** Emit the saved chat to load */
|
|
271
274
|
this.loadSavedChat$ = new BehaviorSubject(undefined);
|
|
272
|
-
this.searchService = inject(SearchService);
|
|
273
275
|
this.userSettingsService = inject(UserSettingsWebService);
|
|
274
276
|
this.notificationsService = inject(NotificationsService);
|
|
275
277
|
this.auditService = inject(AuditWebService);
|
|
@@ -277,6 +279,7 @@ class ChatService {
|
|
|
277
279
|
this.loginService = inject(LoginService);
|
|
278
280
|
this.appService = inject(AppService);
|
|
279
281
|
this.intlService = inject(IntlService);
|
|
282
|
+
this.modalService = inject(ModalService);
|
|
280
283
|
}
|
|
281
284
|
get assistants() {
|
|
282
285
|
if (!this.userSettingsService.userSettings)
|
|
@@ -314,22 +317,69 @@ class ChatService {
|
|
|
314
317
|
this._savedChatId = savedChatId;
|
|
315
318
|
}
|
|
316
319
|
/**
|
|
317
|
-
* Initialize the chat config by
|
|
318
|
-
*
|
|
320
|
+
* Initialize the chat config by managing ONLY sub-object **defaultValues** configs of the standard app config (defined in the customization json tab ) and the user preferences.
|
|
321
|
+
* To do so, a tracking mechanism is implemented to notify the user about the available updates in the defaultValues object of the standard app config.
|
|
322
|
+
* The rest of the config object coming from "standard app config" is used as it is without any override.
|
|
323
|
+
* Thus, the user preferences are used only for the defaultValues object.
|
|
324
|
+
* This provide a centralized way to manage the rest of the config object by admins and ensure a unique common behavior for all users.
|
|
319
325
|
*/
|
|
320
326
|
initChatConfig() {
|
|
321
|
-
var _a, _b, _c;
|
|
327
|
+
var _a, _b, _c, _d, _e;
|
|
322
328
|
const key = this.chatInstanceId;
|
|
323
329
|
const userSettingsConfig = this.assistants[key] || {};
|
|
324
|
-
const
|
|
325
|
-
// Validate the object against the schema
|
|
330
|
+
const standardChatConfig = (_c = (_b = (_a = this.appService.app) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.assistants) === null || _c === void 0 ? void 0 : _c[key];
|
|
326
331
|
try {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
332
|
+
// Validate the whole config object against the schema
|
|
333
|
+
chatConfigSchema.parse(standardChatConfig);
|
|
334
|
+
// If the user preferences do not contain a config's defaultValues object, keep using the standard app config and nothing to store in the user preferences
|
|
335
|
+
if (!userSettingsConfig.defaultValues) {
|
|
336
|
+
this.chatConfig$.next(Object.assign({}, standardChatConfig));
|
|
337
|
+
this.initConfig$.next(true);
|
|
338
|
+
}
|
|
339
|
+
else { // If the user has its own defaultValues in its userSettings, then we need to check for potential updates made by admins in the meantime and how he wants to manage them
|
|
340
|
+
// Retrieve already stored hashes in the user settings if exists
|
|
341
|
+
const appliedDefaultValuesHash = (_d = userSettingsConfig.hashes) === null || _d === void 0 ? void 0 : _d["applied-defaultValues-hash"];
|
|
342
|
+
const skippedDefaultValuesHash = (_e = userSettingsConfig.hashes) === null || _e === void 0 ? void 0 : _e["skipped-defaultValues-hash"];
|
|
343
|
+
// Create a hash of the current defaultValues of the standardChatConfig
|
|
344
|
+
const currentDefaultValuesHash = Utils.sha512(JSON.stringify(standardChatConfig.defaultValues));
|
|
345
|
+
// Implement the tracking mechanism to notify the user about the available updates in the defaultValues object of the standard app config
|
|
346
|
+
const condition = (currentDefaultValuesHash !== appliedDefaultValuesHash) && (currentDefaultValuesHash !== skippedDefaultValuesHash);
|
|
347
|
+
if (condition) {
|
|
348
|
+
this.modalService
|
|
349
|
+
.confirm({
|
|
350
|
+
title: "Available updates !",
|
|
351
|
+
message: "Changes have been made to the default configuration. Do you want to update your own version ?",
|
|
352
|
+
buttons: [
|
|
353
|
+
new ModalButton({ result: -4 /* ModalResult.No */, text: "See no more" }),
|
|
354
|
+
new ModalButton({ result: -7 /* ModalResult.Ignore */, text: "Remind me later" }),
|
|
355
|
+
new ModalButton({ result: -1 /* ModalResult.OK */, text: "Update", primary: true })
|
|
356
|
+
],
|
|
357
|
+
confirmType: 2 /* ConfirmType.Warning */
|
|
358
|
+
}).then(res => {
|
|
359
|
+
if (res === -1 /* ModalResult.OK */) {
|
|
360
|
+
const hashes = { "applied-defaultValues-hash": currentDefaultValuesHash, "skipped-defaultValues-hash": undefined };
|
|
361
|
+
// Update the chat config and store its defaultValues in the user preferences
|
|
362
|
+
this.updateChatConfig(Object.assign({}, standardChatConfig), hashes, true);
|
|
363
|
+
this.initConfig$.next(true);
|
|
364
|
+
}
|
|
365
|
+
else if (res === -4 /* ModalResult.No */) {
|
|
366
|
+
// Do not notify the user about changes while this skipped version is not updated
|
|
367
|
+
const hashes = Object.assign(Object.assign({}, userSettingsConfig.hashes), { "skipped-defaultValues-hash": currentDefaultValuesHash });
|
|
368
|
+
this.updateChatConfig(Object.assign(Object.assign({}, standardChatConfig), { defaultValues: userSettingsConfig.defaultValues }), hashes, false);
|
|
369
|
+
this.initConfig$.next(true);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
// Just pick the version in the user settings, nothing to be updated
|
|
373
|
+
this.chatConfig$.next(Object.assign(Object.assign({}, standardChatConfig), { defaultValues: userSettingsConfig.defaultValues }));
|
|
374
|
+
this.initConfig$.next(true);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
else { // No available updates Or updates has been already skipped, then just pick the version in the user settings
|
|
379
|
+
this.chatConfig$.next(Object.assign(Object.assign({}, standardChatConfig), { defaultValues: userSettingsConfig.defaultValues }));
|
|
380
|
+
this.initConfig$.next(true);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
333
383
|
}
|
|
334
384
|
catch (error) {
|
|
335
385
|
this.notificationsService.error(`Missing valid configuration for the assistant instance '${key}'`);
|
|
@@ -337,25 +387,25 @@ class ChatService {
|
|
|
337
387
|
}
|
|
338
388
|
}
|
|
339
389
|
/**
|
|
340
|
-
* Update the chat config and store
|
|
390
|
+
* Update the chat config and store its defaultValues in the user preferences
|
|
341
391
|
* @param config The updated chat config
|
|
342
392
|
* @param notify Whether to notify the user about the update
|
|
343
393
|
* @param successCallback The callback to execute if the update is successful
|
|
344
394
|
* @param errorCallback The callback to execute if the update fails
|
|
345
395
|
*/
|
|
346
|
-
updateChatConfig(config, notify = true, successCallback, errorCallback) {
|
|
396
|
+
updateChatConfig(config, hashes, notify = true, successCallback, errorCallback) {
|
|
347
397
|
this.chatConfig$.next(config);
|
|
348
398
|
const assistants = Object.assign({}, this.assistants);
|
|
349
|
-
assistants[this.chatInstanceId] = config;
|
|
350
|
-
this.userSettingsService.patch({ assistants }).subscribe(next => {
|
|
351
|
-
if (notify) {
|
|
352
|
-
successCallback ? successCallback() : this.notificationsService.success(`The configuration of the assistant instance '${this.chatInstanceId}' has been successfully updated`);
|
|
353
|
-
}
|
|
354
|
-
}, error => {
|
|
399
|
+
assistants[this.chatInstanceId] = Object.assign(Object.assign({}, assistants[this.chatInstanceId]), { defaultValues: config.defaultValues, hashes });
|
|
400
|
+
this.userSettingsService.patch({ assistants }).subscribe(next => { }, error => {
|
|
355
401
|
if (notify) {
|
|
356
402
|
errorCallback ? errorCallback() : this.notificationsService.error(`The update of the assistant instance '${this.chatInstanceId}' configuration failed`);
|
|
357
403
|
}
|
|
358
404
|
console.error("Could not patch assistants!", error);
|
|
405
|
+
}, () => {
|
|
406
|
+
if (notify) {
|
|
407
|
+
successCallback ? successCallback() : this.notificationsService.success(`The assistant instance '${this.chatInstanceId}' configuration has been successfully updated`);
|
|
408
|
+
}
|
|
359
409
|
});
|
|
360
410
|
}
|
|
361
411
|
/**
|
|
@@ -479,8 +529,8 @@ class WebSocketChatService extends ChatService {
|
|
|
479
529
|
* It can be overridden by the app config
|
|
480
530
|
*/
|
|
481
531
|
getRequestsUrl() {
|
|
482
|
-
if (this.chatConfig$.value.
|
|
483
|
-
this.REQUEST_URL = this.chatConfig$.value.
|
|
532
|
+
if (this.chatConfig$.value.connectionSettings.websocketEndpoint) {
|
|
533
|
+
this.REQUEST_URL = this.chatConfig$.value.connectionSettings.websocketEndpoint;
|
|
484
534
|
}
|
|
485
535
|
else {
|
|
486
536
|
throw new Error(`The property 'websocketEndpoint' must be provided when attempting to use 'WebSocket' in assistant instance`);
|
|
@@ -495,7 +545,7 @@ class WebSocketChatService extends ChatService {
|
|
|
495
545
|
modelsSubject.complete();
|
|
496
546
|
});
|
|
497
547
|
// Send the request to get the list of models
|
|
498
|
-
this.connection.invoke('ListModels', { debug: this.chatConfig$.value.debug })
|
|
548
|
+
this.connection.invoke('ListModels', { debug: this.chatConfig$.value.defaultValues.debug })
|
|
499
549
|
.catch(error => {
|
|
500
550
|
console.error('Error invoking ListModels:', error);
|
|
501
551
|
modelsSubject.complete();
|
|
@@ -506,12 +556,13 @@ class WebSocketChatService extends ChatService {
|
|
|
506
556
|
listFunctions() {
|
|
507
557
|
const functionsSubject = new Subject();
|
|
508
558
|
this.connection.on('ListFunctions', (res) => {
|
|
509
|
-
|
|
559
|
+
var _a;
|
|
560
|
+
this.functions = (_a = res.functions) === null || _a === void 0 ? void 0 : _a.filter(func => func.enabled);
|
|
510
561
|
functionsSubject.next(this.functions);
|
|
511
562
|
functionsSubject.complete();
|
|
512
563
|
});
|
|
513
564
|
// Send the request to get the list of functions
|
|
514
|
-
this.connection.invoke('ListFunctions', { debug: this.chatConfig$.value.debug })
|
|
565
|
+
this.connection.invoke('ListFunctions', { debug: this.chatConfig$.value.defaultValues.debug })
|
|
515
566
|
.catch(error => {
|
|
516
567
|
console.error('Error invoking ListFunctions:', error);
|
|
517
568
|
functionsSubject.complete();
|
|
@@ -519,18 +570,22 @@ class WebSocketChatService extends ChatService {
|
|
|
519
570
|
});
|
|
520
571
|
return functionsSubject.asObservable();
|
|
521
572
|
}
|
|
522
|
-
fetch(messages, query
|
|
573
|
+
fetch(messages, query) {
|
|
574
|
+
var _a;
|
|
523
575
|
// Start streaming by invoking the Chat method
|
|
524
576
|
this.streaming$.next(true);
|
|
525
577
|
// Prepare the payload to send to the Chat method
|
|
526
578
|
const data = {
|
|
527
579
|
history: messages,
|
|
528
|
-
functions: this.chatConfig$.value.functions,
|
|
529
|
-
debug: this.chatConfig$.value.debug,
|
|
530
|
-
serviceSettings: this.chatConfig$.value.
|
|
531
|
-
|
|
580
|
+
functions: (_a = this.chatConfig$.value.defaultValues.functions) === null || _a === void 0 ? void 0 : _a.filter(func => func.enabled).map(func => func.name),
|
|
581
|
+
debug: this.chatConfig$.value.defaultValues.debug,
|
|
582
|
+
serviceSettings: Object.assign({ service_id: this.chatConfig$.value.defaultValues.service_id, model_id: this.chatConfig$.value.defaultValues.model_id, top_p: this.chatConfig$.value.defaultValues.top_p, temperature: this.chatConfig$.value.defaultValues.temperature, max_tokens: this.chatConfig$.value.defaultValues.max_tokens }, this.chatConfig$.value.additionalServiceSettings),
|
|
583
|
+
appQuery: {
|
|
584
|
+
app: this.appService.appName,
|
|
585
|
+
query
|
|
586
|
+
}
|
|
532
587
|
};
|
|
533
|
-
if (this.chatConfig$.value.
|
|
588
|
+
if (this.chatConfig$.value.savedChatSettings.enabled) {
|
|
534
589
|
data.instanceId = this.chatInstanceId;
|
|
535
590
|
data.savedChatId = this.savedChatId;
|
|
536
591
|
}
|
|
@@ -550,7 +605,7 @@ class WebSocketChatService extends ChatService {
|
|
|
550
605
|
);
|
|
551
606
|
// Invoke the Chat method
|
|
552
607
|
this.connection.invoke('Chat', data)
|
|
553
|
-
.then(() => this.notifyAudit(this.chatHistory, this.chatConfig$.value.
|
|
608
|
+
.then(() => this.notifyAudit(this.chatHistory, this.chatConfig$.value.defaultValues.service_id)) // When the server indicates it has successfully finished invoking the method, notify the audit service with the recent chat history
|
|
554
609
|
.catch(error => {
|
|
555
610
|
console.error('Error invoking Chat:', error);
|
|
556
611
|
return Promise.resolve(); // Return a resolved promise to handle the error and prevent unhandled promise rejection
|
|
@@ -592,7 +647,7 @@ class WebSocketChatService extends ChatService {
|
|
|
592
647
|
listSavedChat() {
|
|
593
648
|
const data = {
|
|
594
649
|
instanceId: this.chatInstanceId,
|
|
595
|
-
debug: this.chatConfig$.value.debug
|
|
650
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
596
651
|
};
|
|
597
652
|
this.connection.on('SavedChatList', (res) => {
|
|
598
653
|
this.savedChats$.next(res.savedChats); // emits the result to the savedChats$ subject
|
|
@@ -609,7 +664,7 @@ class WebSocketChatService extends ChatService {
|
|
|
609
664
|
const data = {
|
|
610
665
|
instanceId: this.chatInstanceId,
|
|
611
666
|
savedChatId: id,
|
|
612
|
-
debug: this.chatConfig$.value.debug
|
|
667
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
613
668
|
};
|
|
614
669
|
this.connection.on('SavedChatGet', (res) => {
|
|
615
670
|
savedChatSubject.next(res.savedChat);
|
|
@@ -624,12 +679,33 @@ class WebSocketChatService extends ChatService {
|
|
|
624
679
|
});
|
|
625
680
|
return savedChatSubject.asObservable();
|
|
626
681
|
}
|
|
682
|
+
updateSavedChat(id, name) {
|
|
683
|
+
const updateSavedChatSubject = new Subject();
|
|
684
|
+
const data = {
|
|
685
|
+
instanceId: this.chatInstanceId,
|
|
686
|
+
savedChatId: id,
|
|
687
|
+
title: name,
|
|
688
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
689
|
+
};
|
|
690
|
+
this.connection.on('SavedChatUpdate', (res) => {
|
|
691
|
+
updateSavedChatSubject.next(res.savedChat);
|
|
692
|
+
updateSavedChatSubject.complete();
|
|
693
|
+
});
|
|
694
|
+
// Invoke the method SavedChatUpdate
|
|
695
|
+
this.connection.invoke('SavedChatUpdate', data)
|
|
696
|
+
.catch(error => {
|
|
697
|
+
console.error('Error invoking SavedChatUpdate:', error);
|
|
698
|
+
updateSavedChatSubject.complete();
|
|
699
|
+
return Promise.resolve();
|
|
700
|
+
});
|
|
701
|
+
return updateSavedChatSubject.asObservable();
|
|
702
|
+
}
|
|
627
703
|
deleteSavedChat(ids) {
|
|
628
704
|
const deleteSavedChatSubject = new Subject();
|
|
629
705
|
const data = {
|
|
630
706
|
instanceId: this.chatInstanceId,
|
|
631
707
|
SavedChatIds: ids,
|
|
632
|
-
debug: this.chatConfig$.value.debug
|
|
708
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
633
709
|
};
|
|
634
710
|
this.connection.on('SavedChatDelete', (res) => {
|
|
635
711
|
deleteSavedChatSubject.next(res.deleteCount);
|
|
@@ -792,7 +868,7 @@ class WebSocketChatService extends ChatService {
|
|
|
792
868
|
}
|
|
793
869
|
getTransports() {
|
|
794
870
|
var _a;
|
|
795
|
-
switch ((_a = this.chatConfig$.value) === null || _a === void 0 ? void 0 : _a.
|
|
871
|
+
switch ((_a = this.chatConfig$.value) === null || _a === void 0 ? void 0 : _a.connectionSettings.signalRTransport) {
|
|
796
872
|
case "WebSockets":
|
|
797
873
|
return HttpTransportType.WebSockets;
|
|
798
874
|
case "ServerSentEvents":
|
|
@@ -805,7 +881,7 @@ class WebSocketChatService extends ChatService {
|
|
|
805
881
|
}
|
|
806
882
|
getLogLevel() {
|
|
807
883
|
var _a;
|
|
808
|
-
switch ((_a = this.chatConfig$.value) === null || _a === void 0 ? void 0 : _a.
|
|
884
|
+
switch ((_a = this.chatConfig$.value) === null || _a === void 0 ? void 0 : _a.connectionSettings.signalRLogLevel) {
|
|
809
885
|
case "Critical":
|
|
810
886
|
return LogLevel.Critical; // Log level for diagnostic messages that indicate a failure that will terminate the entire application.
|
|
811
887
|
case "Debug":
|
|
@@ -1080,10 +1156,10 @@ class ChatReferenceComponent {
|
|
|
1080
1156
|
}
|
|
1081
1157
|
}
|
|
1082
1158
|
ChatReferenceComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatReferenceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1083
|
-
ChatReferenceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatReferenceComponent, isStandalone: true, selector: "sq-chat-reference", inputs: { reference: "reference", attachment: "attachment", partId: "partId" }, outputs: { openDocument: "openDocument", openPreview: "openPreview" }, ngImport: i0, template: "<div [class.reference-tooltip]=\"!!partId\">\n <div class=\"reference-data\" [class.expanded]=\"attachment['$expanded'] || !!partId\">\n <span class=\"reference me-1\">{{reference}}</span>\n <sq-format-icon [extension]=\"attachment.record.fileext\"></sq-format-icon>\n <a [id]=\"'attachment-'+attachment.recordId\" (click)=\"expandAttachment()\">\n {{attachment.record.title}}\n </a>\n <i class=\"fas fa-eye\" (click)=\"openPreview.emit(attachment)\" [sqTooltip]=\"!partId ? 'Preview document' : ''\"></i>\n <i class=\"fas fa-arrow-up-right-from-square\" *ngIf=\"attachment.record.url1 || attachment.record.originalUrl\"\n (click)=\"openDocument.emit(attachment.record)\" [sqTooltip]=\"!partId ? 'Open document' : ''\"></i>\n </div>\n <div class=\"reference-passages\" *ngIf=\"!!partId || (attachment['$expanded']) && parts.length\">\n <div class=\"reference-passage\" *ngFor=\"let part of parts\">\n <span class=\"reference me-1\">{{reference}}.{{part.partId}}</span>\n <span [innerHTML]=\"part.text\"></span>\n </div>\n </div>\n</div>", 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}: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{display:block}:host.expanded,:host:hover{background-color
|
|
1159
|
+
ChatReferenceComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatReferenceComponent, isStandalone: true, selector: "sq-chat-reference", inputs: { reference: "reference", attachment: "attachment", partId: "partId" }, outputs: { openDocument: "openDocument", openPreview: "openPreview" }, ngImport: i0, template: "<div [class.reference-tooltip]=\"!!partId\">\n <div class=\"reference-data\" [class.expanded]=\"attachment['$expanded'] || !!partId\">\n <span class=\"reference me-1\">{{reference}}</span>\n <sq-format-icon [extension]=\"attachment.record.fileext\"></sq-format-icon>\n <a [id]=\"'attachment-'+attachment.recordId\" (click)=\"expandAttachment()\">\n {{attachment.record.title}}\n </a>\n <i class=\"fas fa-eye\" (click)=\"openPreview.emit(attachment)\" [sqTooltip]=\"!partId ? 'Preview document' : ''\"></i>\n <i class=\"fas fa-arrow-up-right-from-square\" *ngIf=\"attachment.record.url1 || attachment.record.originalUrl\"\n (click)=\"openDocument.emit(attachment.record)\" [sqTooltip]=\"!partId ? 'Open document' : ''\"></i>\n </div>\n <div class=\"reference-passages\" *ngIf=\"!!partId || (attachment['$expanded']) && parts.length\">\n <div class=\"reference-passage\" *ngFor=\"let part of parts\">\n <span class=\"reference me-1\">{{reference}}.{{part.partId}}</span>\n <span [innerHTML]=\"part.text\"></span>\n </div>\n </div>\n</div>", 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{display:block}:host.expanded,:host:hover{background-color:var(--ast-reference-expanded-hover-bg, white)}.reference-data{display:flex;flex-direction:row;align-items:baseline;padding:var(--ast-size-1, .25rem)}.reference-data a{color:var(--ast-secondary-color, #FF732E);flex-grow:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:var(--font-weight-bold, 500);cursor:pointer}.reference-data i{padding:var(--ast-size-1, .25rem);margin-left:var(--ast-size-1, .25rem);cursor:pointer;color:var(--ast-reference-icon-color, black)}.reference-data i.active{color:var(--ast-reference-icon-active-color, white);background-color:var(--ast-secondary-color, #FF732E)}.reference-data:not(.expanded) i{opacity:0}.reference-data:not(.expanded):hover i{opacity:1}.reference-passages{white-space:normal;font-style:italic;font-weight:400;padding:1rem 0;color:var(--ast-reference-passages-color, black)}.reference-passages .reference-passage{display:flex;align-items:baseline;padding-left:2.5rem;padding-right:1rem;word-wrap:break-word}.reference-passages .reference-passage+.reference-passage{padding-top:1rem}.reference-passages .reference-passage .reference{margin-right:var(--ast-size-2, .5rem)}sq-format-icon{margin-left:var(--ast-size-1, .25rem);margin-right:var(--ast-size-2, .5rem);color:var(--ast-secondary-color, #FF732E)}.reference-tooltip{max-width:600px!important;box-shadow:0 .5rem 1rem #00000026;padding:.5rem;font-size:.875rem}\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: "ngmodule", type: UtilsModule }, { kind: "directive", type: i2$1.TooltipDirective, selector: "[sqTooltip]", inputs: ["sqTooltip", "sqTooltipData", "sqTooltipTemplate", "placement", "fallbackPlacements", "delay", "hoverableTooltip", "tooltipClass"] }, { kind: "component", type: FormatIconComponent, selector: "sq-format-icon", inputs: ["extension"] }] });
|
|
1084
1160
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatReferenceComponent, decorators: [{
|
|
1085
1161
|
type: Component,
|
|
1086
|
-
args: [{ selector: 'sq-chat-reference', standalone: true, imports: [CommonModule, UtilsModule, FormatIconComponent], template: "<div [class.reference-tooltip]=\"!!partId\">\n <div class=\"reference-data\" [class.expanded]=\"attachment['$expanded'] || !!partId\">\n <span class=\"reference me-1\">{{reference}}</span>\n <sq-format-icon [extension]=\"attachment.record.fileext\"></sq-format-icon>\n <a [id]=\"'attachment-'+attachment.recordId\" (click)=\"expandAttachment()\">\n {{attachment.record.title}}\n </a>\n <i class=\"fas fa-eye\" (click)=\"openPreview.emit(attachment)\" [sqTooltip]=\"!partId ? 'Preview document' : ''\"></i>\n <i class=\"fas fa-arrow-up-right-from-square\" *ngIf=\"attachment.record.url1 || attachment.record.originalUrl\"\n (click)=\"openDocument.emit(attachment.record)\" [sqTooltip]=\"!partId ? 'Open document' : ''\"></i>\n </div>\n <div class=\"reference-passages\" *ngIf=\"!!partId || (attachment['$expanded']) && parts.length\">\n <div class=\"reference-passage\" *ngFor=\"let part of parts\">\n <span class=\"reference me-1\">{{reference}}.{{part.partId}}</span>\n <span [innerHTML]=\"part.text\"></span>\n </div>\n </div>\n</div>", 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}: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{display:block}:host.expanded,:host:hover{background-color
|
|
1162
|
+
args: [{ selector: 'sq-chat-reference', standalone: true, imports: [CommonModule, UtilsModule, FormatIconComponent], template: "<div [class.reference-tooltip]=\"!!partId\">\n <div class=\"reference-data\" [class.expanded]=\"attachment['$expanded'] || !!partId\">\n <span class=\"reference me-1\">{{reference}}</span>\n <sq-format-icon [extension]=\"attachment.record.fileext\"></sq-format-icon>\n <a [id]=\"'attachment-'+attachment.recordId\" (click)=\"expandAttachment()\">\n {{attachment.record.title}}\n </a>\n <i class=\"fas fa-eye\" (click)=\"openPreview.emit(attachment)\" [sqTooltip]=\"!partId ? 'Preview document' : ''\"></i>\n <i class=\"fas fa-arrow-up-right-from-square\" *ngIf=\"attachment.record.url1 || attachment.record.originalUrl\"\n (click)=\"openDocument.emit(attachment.record)\" [sqTooltip]=\"!partId ? 'Open document' : ''\"></i>\n </div>\n <div class=\"reference-passages\" *ngIf=\"!!partId || (attachment['$expanded']) && parts.length\">\n <div class=\"reference-passage\" *ngFor=\"let part of parts\">\n <span class=\"reference me-1\">{{reference}}.{{part.partId}}</span>\n <span [innerHTML]=\"part.text\"></span>\n </div>\n </div>\n</div>", 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{display:block}:host.expanded,:host:hover{background-color:var(--ast-reference-expanded-hover-bg, white)}.reference-data{display:flex;flex-direction:row;align-items:baseline;padding:var(--ast-size-1, .25rem)}.reference-data a{color:var(--ast-secondary-color, #FF732E);flex-grow:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-weight:var(--font-weight-bold, 500);cursor:pointer}.reference-data i{padding:var(--ast-size-1, .25rem);margin-left:var(--ast-size-1, .25rem);cursor:pointer;color:var(--ast-reference-icon-color, black)}.reference-data i.active{color:var(--ast-reference-icon-active-color, white);background-color:var(--ast-secondary-color, #FF732E)}.reference-data:not(.expanded) i{opacity:0}.reference-data:not(.expanded):hover i{opacity:1}.reference-passages{white-space:normal;font-style:italic;font-weight:400;padding:1rem 0;color:var(--ast-reference-passages-color, black)}.reference-passages .reference-passage{display:flex;align-items:baseline;padding-left:2.5rem;padding-right:1rem;word-wrap:break-word}.reference-passages .reference-passage+.reference-passage{padding-top:1rem}.reference-passages .reference-passage .reference{margin-right:var(--ast-size-2, .5rem)}sq-format-icon{margin-left:var(--ast-size-1, .25rem);margin-right:var(--ast-size-2, .5rem);color:var(--ast-secondary-color, #FF732E)}.reference-tooltip{max-width:600px!important;box-shadow:0 .5rem 1rem #00000026;padding:.5rem;font-size:.875rem}\n"] }]
|
|
1087
1163
|
}], propDecorators: { reference: [{
|
|
1088
1164
|
type: Input
|
|
1089
1165
|
}], attachment: [{
|
|
@@ -1233,11 +1309,11 @@ class ChatMessageComponent {
|
|
|
1233
1309
|
}
|
|
1234
1310
|
}
|
|
1235
1311
|
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 });
|
|
1236
|
-
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\"
|
|
1312
|
+
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 });
|
|
1237
1313
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatMessageComponent, decorators: [{
|
|
1238
1314
|
type: Component,
|
|
1239
1315
|
args: [{ selector: "sq-chat-message", changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [CommonModule, UtilsModule, CollapseModule, RemarkModule,
|
|
1240
|
-
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\"
|
|
1316
|
+
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 \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"] }]
|
|
1241
1317
|
}], ctorParameters: function () { return [{ type: i1$1.SearchService }, { type: i2$1.UIService }, { type: i3.PrincipalWebService }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }]; }, propDecorators: { message: [{
|
|
1242
1318
|
type: Input
|
|
1243
1319
|
}], conversation: [{
|
|
@@ -1280,7 +1356,10 @@ class RestChatService extends ChatService {
|
|
|
1280
1356
|
this.listFunctions()
|
|
1281
1357
|
])),
|
|
1282
1358
|
// Map the results of parallel requests to a boolean indicating success
|
|
1283
|
-
map(([models, functions]) =>
|
|
1359
|
+
map(([models, functions]) => {
|
|
1360
|
+
this.initProcess$.next(true);
|
|
1361
|
+
return !!models && !!functions;
|
|
1362
|
+
}),
|
|
1284
1363
|
// Any errors during the process are caught, logged, and re-thrown to propagate the error further
|
|
1285
1364
|
catchError((error) => {
|
|
1286
1365
|
console.error('Error occurred:', error);
|
|
@@ -1294,8 +1373,8 @@ class RestChatService extends ChatService {
|
|
|
1294
1373
|
* It can be overridden by the app config
|
|
1295
1374
|
*/
|
|
1296
1375
|
getRequestsUrl() {
|
|
1297
|
-
if (this.chatConfig$.value.
|
|
1298
|
-
this.REQUEST_URL = this.chatConfig$.value.
|
|
1376
|
+
if (this.chatConfig$.value.connectionSettings.restEndpoint) {
|
|
1377
|
+
this.REQUEST_URL = this.chatConfig$.value.connectionSettings.restEndpoint;
|
|
1299
1378
|
}
|
|
1300
1379
|
else {
|
|
1301
1380
|
throw new Error(`The property 'restEndpoint' must be provided when attempting to use 'REST' in assistant instance`);
|
|
@@ -1304,7 +1383,7 @@ class RestChatService extends ChatService {
|
|
|
1304
1383
|
listModels() {
|
|
1305
1384
|
const data = {
|
|
1306
1385
|
action: "listmodels",
|
|
1307
|
-
debug: this.chatConfig$.value.debug
|
|
1386
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1308
1387
|
};
|
|
1309
1388
|
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.models), tap(models => this.models = models === null || models === void 0 ? void 0 : models.filter(model => !!model.enable)), catchError((error) => {
|
|
1310
1389
|
console.error('Error invoking listmodels:', error);
|
|
@@ -1314,26 +1393,30 @@ class RestChatService extends ChatService {
|
|
|
1314
1393
|
listFunctions() {
|
|
1315
1394
|
const data = {
|
|
1316
1395
|
action: "listfunctions",
|
|
1317
|
-
debug: this.chatConfig$.value.debug
|
|
1396
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1318
1397
|
};
|
|
1319
|
-
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.functions), tap(functions => this.functions = functions), catchError((error) => {
|
|
1398
|
+
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.functions), tap((functions) => this.functions = functions === null || functions === void 0 ? void 0 : functions.filter(func => func.enabled && !!this.chatConfig$.value.defaultValues.functions.find(fn => fn.name === func.functionName))), catchError((error) => {
|
|
1320
1399
|
console.error('Error invoking listfunctions:', error);
|
|
1321
1400
|
return throwError(() => error);
|
|
1322
1401
|
}));
|
|
1323
1402
|
}
|
|
1324
|
-
fetch(messages, query
|
|
1403
|
+
fetch(messages, query) {
|
|
1404
|
+
var _a;
|
|
1325
1405
|
// Start streaming by invoking the Chat method
|
|
1326
1406
|
this.streaming$.next(true);
|
|
1327
1407
|
// Prepare the payload to send to the Chat method
|
|
1328
1408
|
const data = {
|
|
1329
1409
|
action: "chat",
|
|
1330
1410
|
history: messages,
|
|
1331
|
-
functions: this.chatConfig$.value.functions,
|
|
1332
|
-
debug: this.chatConfig$.value.debug,
|
|
1333
|
-
serviceSettings: this.chatConfig$.value.
|
|
1334
|
-
|
|
1411
|
+
functions: (_a = this.chatConfig$.value.defaultValues.functions) === null || _a === void 0 ? void 0 : _a.filter(func => func.enabled).map(func => func.name),
|
|
1412
|
+
debug: this.chatConfig$.value.defaultValues.debug,
|
|
1413
|
+
serviceSettings: Object.assign({ service_id: this.chatConfig$.value.defaultValues.service_id, model_id: this.chatConfig$.value.defaultValues.model_id, top_p: this.chatConfig$.value.defaultValues.top_p, temperature: this.chatConfig$.value.defaultValues.temperature, max_tokens: this.chatConfig$.value.defaultValues.max_tokens }, this.chatConfig$.value.additionalServiceSettings),
|
|
1414
|
+
appQuery: {
|
|
1415
|
+
app: this.appService.appName,
|
|
1416
|
+
query
|
|
1417
|
+
}
|
|
1335
1418
|
};
|
|
1336
|
-
if (this.chatConfig$.value.
|
|
1419
|
+
if (this.chatConfig$.value.savedChatSettings.enabled) {
|
|
1337
1420
|
data.instanceId = this.chatInstanceId;
|
|
1338
1421
|
data.savedChatId = this.savedChatId;
|
|
1339
1422
|
}
|
|
@@ -1375,13 +1458,13 @@ class RestChatService extends ChatService {
|
|
|
1375
1458
|
this.chatHistory = res.history;
|
|
1376
1459
|
// Return the result
|
|
1377
1460
|
return { history: [...messages, response], executionTime: res.executionTime };
|
|
1378
|
-
}), tap(() => this.notifyAudit(this.chatHistory, this.chatConfig$.value.
|
|
1461
|
+
}), tap(() => this.notifyAudit(this.chatHistory, this.chatConfig$.value.defaultValues.service_id)), finalize(() => this.streaming$.next(false)));
|
|
1379
1462
|
}
|
|
1380
1463
|
listSavedChat() {
|
|
1381
1464
|
const data = {
|
|
1382
1465
|
action: "SavedChatList",
|
|
1383
1466
|
instanceId: this.chatInstanceId,
|
|
1384
|
-
debug: this.chatConfig$.value.debug
|
|
1467
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1385
1468
|
};
|
|
1386
1469
|
this.jsonMethodWebService.get(this.REQUEST_URL, data).subscribe(res => this.savedChats$.next(res.savedChats), error => {
|
|
1387
1470
|
console.error('Error occurred while calling the SavedChatList API:', error);
|
|
@@ -1393,7 +1476,7 @@ class RestChatService extends ChatService {
|
|
|
1393
1476
|
action: "SavedChatGet",
|
|
1394
1477
|
instanceId: this.chatInstanceId,
|
|
1395
1478
|
savedChatId: id,
|
|
1396
|
-
debug: this.chatConfig$.value.debug
|
|
1479
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1397
1480
|
};
|
|
1398
1481
|
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.savedChat), catchError((error) => {
|
|
1399
1482
|
console.error('Error occurred while calling the SavedChatGet API:', error);
|
|
@@ -1401,12 +1484,26 @@ class RestChatService extends ChatService {
|
|
|
1401
1484
|
return throwError(() => error);
|
|
1402
1485
|
}));
|
|
1403
1486
|
}
|
|
1487
|
+
updateSavedChat(id, name) {
|
|
1488
|
+
const data = {
|
|
1489
|
+
action: "SavedChatUpdate",
|
|
1490
|
+
instanceId: this.chatInstanceId,
|
|
1491
|
+
savedChatId: id,
|
|
1492
|
+
title: name,
|
|
1493
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1494
|
+
};
|
|
1495
|
+
return this.jsonMethodWebService.get(this.REQUEST_URL, data).pipe(map(res => res.savedChat), catchError((error) => {
|
|
1496
|
+
console.error('Error occurred while calling the SavedChatUpdate API:', error);
|
|
1497
|
+
this.notificationsService.error('Error occurred while calling the SavedChatUpdate API');
|
|
1498
|
+
return throwError(() => error);
|
|
1499
|
+
}));
|
|
1500
|
+
}
|
|
1404
1501
|
deleteSavedChat(ids) {
|
|
1405
1502
|
const data = {
|
|
1406
1503
|
action: "SavedChatDelete",
|
|
1407
1504
|
instanceId: this.chatInstanceId,
|
|
1408
1505
|
savedChatIds: ids,
|
|
1409
|
-
debug: this.chatConfig$.value.debug
|
|
1506
|
+
debug: this.chatConfig$.value.defaultValues.debug
|
|
1410
1507
|
};
|
|
1411
1508
|
return this.jsonMethodWebService.post(this.REQUEST_URL, data).pipe(map(res => res.deletedCount), catchError((error) => {
|
|
1412
1509
|
console.error('Error occurred while calling the SavedChatDelete API:', error);
|
|
@@ -1424,14 +1521,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
1424
1521
|
class ChatComponent extends AbstractFacet {
|
|
1425
1522
|
constructor() {
|
|
1426
1523
|
super();
|
|
1524
|
+
this.loginService = inject(LoginService);
|
|
1525
|
+
this.websocketService = inject(WebSocketChatService);
|
|
1526
|
+
this.restService = inject(RestChatService);
|
|
1527
|
+
this.instanceManagerService = inject(InstanceManagerService);
|
|
1528
|
+
this.searchService = inject(SearchService);
|
|
1529
|
+
this.principalService = inject(PrincipalWebService);
|
|
1530
|
+
this.cdr = inject(ChangeDetectorRef);
|
|
1531
|
+
/** Define the query to use to fetch answers */
|
|
1532
|
+
this.query = this.searchService.query;
|
|
1427
1533
|
/** Define the protocol to be used for this chat instance*/
|
|
1428
1534
|
this.protocol = "WEBSOCKET";
|
|
1429
1535
|
/** Map of listeners overriding default registered ones*/
|
|
1430
1536
|
this.messageHandlers = new Map();
|
|
1431
1537
|
/** When the assistant answer a user question, automatically scroll down to the bottom of the discussion */
|
|
1432
1538
|
this.automaticScrollToLastResponse = false;
|
|
1433
|
-
this.enableChat = true;
|
|
1434
|
-
this.showCredits = true;
|
|
1435
1539
|
this.customAssistantIcon = '';
|
|
1436
1540
|
this.data = new EventEmitter();
|
|
1437
1541
|
this.referenceClicked = new EventEmitter();
|
|
@@ -1444,16 +1548,10 @@ class ChatComponent extends AbstractFacet {
|
|
|
1444
1548
|
this._actions = [];
|
|
1445
1549
|
this.sub = new Subscription();
|
|
1446
1550
|
this.changes$ = new BehaviorSubject(undefined);
|
|
1447
|
-
this.
|
|
1551
|
+
this.firstChangesHandled = false;
|
|
1448
1552
|
this.isAtBottom = true;
|
|
1449
1553
|
this.initializationError = false;
|
|
1450
|
-
this.
|
|
1451
|
-
this.websocketService = inject(WebSocketChatService);
|
|
1452
|
-
this.restService = inject(RestChatService);
|
|
1453
|
-
this.instanceManagerService = inject(InstanceManagerService);
|
|
1454
|
-
this.searchService = inject(SearchService);
|
|
1455
|
-
this.principalService = inject(PrincipalWebService);
|
|
1456
|
-
this.cdr = inject(ChangeDetectorRef);
|
|
1554
|
+
this.enabledUserInput = false;
|
|
1457
1555
|
this._actions.push(new Action({
|
|
1458
1556
|
icon: 'fas fa-sync',
|
|
1459
1557
|
title: 'Reset chat',
|
|
@@ -1463,13 +1561,14 @@ class ChatComponent extends AbstractFacet {
|
|
|
1463
1561
|
ngOnInit() {
|
|
1464
1562
|
this.sub.add(this.loginService.events.pipe(filter(e => e.type === 'login-complete'), tap(_ => this.instantiateChatService()), map(_ => this.chatService.initChatConfig()), switchMap(() => this.chatService.initConfig$), filter(initConfig => !!initConfig), switchMap(_ => this.chatService.init()), filter(success => !!success), tap(_ => this.onLoadChat()), switchMap(_ => this.chatService.chatConfig$), tap(config => {
|
|
1465
1563
|
this.config = config;
|
|
1564
|
+
this.enabledUserInput = this.config.modeSettings.enabledUserInput;
|
|
1466
1565
|
this._config.emit(config);
|
|
1467
1566
|
try {
|
|
1468
1567
|
this.updateModelDescription();
|
|
1469
|
-
if (!this.
|
|
1568
|
+
if (!this.firstChangesHandled) {
|
|
1470
1569
|
this.handleChanges();
|
|
1471
1570
|
this.addScrollListener();
|
|
1472
|
-
this.
|
|
1571
|
+
this.firstChangesHandled = true;
|
|
1473
1572
|
}
|
|
1474
1573
|
}
|
|
1475
1574
|
catch (error) {
|
|
@@ -1506,12 +1605,35 @@ class ChatComponent extends AbstractFacet {
|
|
|
1506
1605
|
get actions() { return this._actions; }
|
|
1507
1606
|
handleChanges() {
|
|
1508
1607
|
const changes = this.changes$.value;
|
|
1608
|
+
// If the chat service is a WebSocketChatService, handle the override of the message handlers if exists
|
|
1509
1609
|
if ((changes === null || changes === void 0 ? void 0 : changes.messageHandlers) && this.messageHandlers && this.chatService instanceof WebSocketChatService) {
|
|
1510
1610
|
this.chatService.overrideMessageHandlers(this.messageHandlers);
|
|
1511
1611
|
}
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1612
|
+
// Initialize the chat with the provided chat messages if exists, otherwise load the default chat
|
|
1613
|
+
// Once the chat is initialized (firstChangesHandled is true), allow opening the chat with the new provided messages (if exists)
|
|
1614
|
+
if (!this.firstChangesHandled || (changes === null || changes === void 0 ? void 0 : changes.chat)) {
|
|
1615
|
+
const openChat = () => {
|
|
1616
|
+
if (this.messages$.value && this.config.savedChatSettings.enabled) {
|
|
1617
|
+
this.chatService.listSavedChat(); // Refresh the list of saved chats
|
|
1618
|
+
}
|
|
1619
|
+
this.openChat(this.chat.messages);
|
|
1620
|
+
};
|
|
1621
|
+
this.chat ? openChat() : this.loadDefaultChat();
|
|
1622
|
+
}
|
|
1623
|
+
// If the chat is initialized and the initialization event is "Query", then a fresh new chat should be started with the provided query
|
|
1624
|
+
if (this.firstChangesHandled && (changes === null || changes === void 0 ? void 0 : changes.query) && this.config.modeSettings.initialization.event === 'Query') {
|
|
1625
|
+
const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false } };
|
|
1626
|
+
const userMsg = { role: 'user', content: ChatService.formatPrompt(this.config.defaultValues.userPrompt, { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt } };
|
|
1627
|
+
// If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
|
|
1628
|
+
// Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
|
|
1629
|
+
if (!!this.query.text) {
|
|
1630
|
+
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 } };
|
|
1631
|
+
this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
|
|
1632
|
+
}
|
|
1633
|
+
else {
|
|
1634
|
+
const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
|
|
1635
|
+
this.openChat([warningMsg]);
|
|
1636
|
+
}
|
|
1515
1637
|
}
|
|
1516
1638
|
}
|
|
1517
1639
|
addScrollListener() {
|
|
@@ -1522,7 +1644,7 @@ class ChatComponent extends AbstractFacet {
|
|
|
1522
1644
|
}
|
|
1523
1645
|
updateModelDescription() {
|
|
1524
1646
|
var _a;
|
|
1525
|
-
this.modelDescription = this.chatService.getModel(this.config.
|
|
1647
|
+
this.modelDescription = this.chatService.getModel(this.config.defaultValues.service_id, this.config.defaultValues.model_id);
|
|
1526
1648
|
this.assistantIcon = !!this.customAssistantIcon ? this.customAssistantIcon : 'sq-sinequa';
|
|
1527
1649
|
switch ((_a = this.modelDescription) === null || _a === void 0 ? void 0 : _a.provider) {
|
|
1528
1650
|
case 'Google':
|
|
@@ -1559,7 +1681,7 @@ class ChatComponent extends AbstractFacet {
|
|
|
1559
1681
|
}
|
|
1560
1682
|
}
|
|
1561
1683
|
fetchAnswer(question, conversation) {
|
|
1562
|
-
const userMsg = { role: 'user', content: question, additionalProperties: { display: true } };
|
|
1684
|
+
const userMsg = { role: 'user', content: question, additionalProperties: { display: true, isUserInput: true } };
|
|
1563
1685
|
const messages = [...conversation, userMsg];
|
|
1564
1686
|
this.messages$.next(messages);
|
|
1565
1687
|
this.fetch(messages);
|
|
@@ -1619,16 +1741,46 @@ class ChatComponent extends AbstractFacet {
|
|
|
1619
1741
|
}
|
|
1620
1742
|
}, 10);
|
|
1621
1743
|
}
|
|
1744
|
+
/**
|
|
1745
|
+
* Start a new chat with the defaultValues settings
|
|
1746
|
+
* If the savedChat feature is enabled, the list of saved chats will be refreshed
|
|
1747
|
+
*/
|
|
1622
1748
|
newChat() {
|
|
1623
|
-
this.
|
|
1749
|
+
if (this.config.savedChatSettings.enabled) {
|
|
1750
|
+
this.chatService.listSavedChat(); // Refresh the list of saved chats
|
|
1751
|
+
}
|
|
1624
1752
|
this.loadDefaultChat(); // Start a new chat
|
|
1625
1753
|
}
|
|
1754
|
+
/**
|
|
1755
|
+
* Start the default chat with the defaultValues settings
|
|
1756
|
+
* If the chat is meant to be initialized with event === "Query", the corresponding user query message will be added to the chat history
|
|
1757
|
+
*/
|
|
1626
1758
|
loadDefaultChat() {
|
|
1627
|
-
this.
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1759
|
+
const systemMsg = { role: 'system', content: this.config.defaultValues.systemPrompt, additionalProperties: { display: false } };
|
|
1760
|
+
const userMsg = { role: 'user', content: ChatService.formatPrompt(this.config.defaultValues.userPrompt, { principal: this.principalService.principal }), additionalProperties: { display: this.config.modeSettings.displayUserPrompt } };
|
|
1761
|
+
if (this.config.modeSettings.initialization.event === 'Query') {
|
|
1762
|
+
// If the provided query text is not empty, then add the user query message to the chat history and invoke the assistant
|
|
1763
|
+
// Otherwise, just start a new chat with a warning message inviting the user to perform a full text search to retrieve some results
|
|
1764
|
+
if (!!this.query.text) {
|
|
1765
|
+
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 } };
|
|
1766
|
+
this.openChat(this.config.modeSettings.sendUserPrompt ? [systemMsg, userMsg, userQueryMsg] : [systemMsg, userQueryMsg]);
|
|
1767
|
+
}
|
|
1768
|
+
else {
|
|
1769
|
+
const warningMsg = { role: 'assistant', content: "You must perform a full text search to retrieve some results", additionalProperties: { display: true } };
|
|
1770
|
+
this.openChat([warningMsg]);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
else {
|
|
1774
|
+
this.openChat([systemMsg, userMsg]);
|
|
1775
|
+
}
|
|
1631
1776
|
}
|
|
1777
|
+
/**
|
|
1778
|
+
* Start/open a new chat with the provided messages and chatId
|
|
1779
|
+
* If the last message is from the user, a request to the assistant is made to get an answer
|
|
1780
|
+
* If the last message is from the assistant, the conversation is loaded right away
|
|
1781
|
+
* @param messages The list of messages of the chat
|
|
1782
|
+
* @param chatId The id of the chat. If not provided, a new id will be generated
|
|
1783
|
+
*/
|
|
1632
1784
|
openChat(messages, chatId) {
|
|
1633
1785
|
if (!messages || !Array.isArray(messages)) {
|
|
1634
1786
|
console.error('Error occurs while trying to load the chat discussion. Invalid messages received :', messages);
|
|
@@ -1647,6 +1799,11 @@ class ChatComponent extends AbstractFacet {
|
|
|
1647
1799
|
this.terminateFetch();
|
|
1648
1800
|
}
|
|
1649
1801
|
}
|
|
1802
|
+
/**
|
|
1803
|
+
* Reset the chat by clearing the messages and the chat history
|
|
1804
|
+
* The question input will be focused after the chat is reset
|
|
1805
|
+
* The fetch subscription will be terminated
|
|
1806
|
+
*/
|
|
1650
1807
|
resetChat() {
|
|
1651
1808
|
if (this.messages$.value) {
|
|
1652
1809
|
this.messages$.next(undefined); // Reset chat
|
|
@@ -1658,8 +1815,7 @@ class ChatComponent extends AbstractFacet {
|
|
|
1658
1815
|
onLoadChat() {
|
|
1659
1816
|
this.loading$.next(true);
|
|
1660
1817
|
this.sub.add(this.chatService.loadSavedChat$
|
|
1661
|
-
.pipe(filter(savedChat => !!savedChat), switchMap(savedChat => this.chatService.getSavedChat(savedChat.id)), filter(savedChatHistory => !!savedChatHistory), tap(savedChatHistory => this.openChat(savedChatHistory.
|
|
1662
|
-
).subscribe());
|
|
1818
|
+
.pipe(filter(savedChat => !!savedChat), switchMap(savedChat => this.chatService.getSavedChat(savedChat.id)), filter(savedChatHistory => !!savedChatHistory), tap(savedChatHistory => this.openChat(savedChatHistory.history, savedChatHistory.id))).subscribe());
|
|
1663
1819
|
}
|
|
1664
1820
|
terminateFetch() {
|
|
1665
1821
|
var _a;
|
|
@@ -1729,16 +1885,16 @@ class ChatComponent extends AbstractFacet {
|
|
|
1729
1885
|
}
|
|
1730
1886
|
}
|
|
1731
1887
|
ChatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1732
|
-
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",
|
|
1888
|
+
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: [
|
|
1733
1889
|
RestChatService,
|
|
1734
1890
|
WebSocketChatService
|
|
1735
|
-
], 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
|
|
1891
|
+
], 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 <input #questionInput\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\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:center;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 input{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem)}.ast-input-container input,.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 });
|
|
1736
1892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatComponent, decorators: [{
|
|
1737
1893
|
type: Component,
|
|
1738
1894
|
args: [{ selector: 'sq-chat-v3', providers: [
|
|
1739
1895
|
RestChatService,
|
|
1740
1896
|
WebSocketChatService
|
|
1741
|
-
], 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
|
|
1897
|
+
], 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 <input #questionInput\n type=\"text\" class=\"form-control\"\n placeholder=\"Ask something\" autofocus\n [(ngModel)]=\"question\"\n (keyup)=\"onKeyUp($event)\"\n [disabled]=\"(loading$ | async) || (chatService.streaming$ | async)\">\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:center;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 input{padding-left:var(--ast-size-3, .75rem);padding-right:var(--ast-size-3, .75rem)}.ast-input-container input,.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"] }]
|
|
1742
1898
|
}], ctorParameters: function () { return []; }, propDecorators: { instanceId: [{
|
|
1743
1899
|
type: Input
|
|
1744
1900
|
}], query: [{
|
|
@@ -1751,10 +1907,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImpor
|
|
|
1751
1907
|
type: Input
|
|
1752
1908
|
}], chat: [{
|
|
1753
1909
|
type: Input
|
|
1754
|
-
}], enableChat: [{
|
|
1755
|
-
type: Input
|
|
1756
|
-
}], showCredits: [{
|
|
1757
|
-
type: Input
|
|
1758
1910
|
}], customAssistantIcon: [{
|
|
1759
1911
|
type: Input
|
|
1760
1912
|
}], data: [{
|
|
@@ -1807,12 +1959,42 @@ class SavedChatsComponent {
|
|
|
1807
1959
|
this.chatService = this.instanceManagerService.getInstance(this.instanceId);
|
|
1808
1960
|
}
|
|
1809
1961
|
onListSavedChat() {
|
|
1810
|
-
this.subscription.add(this.chatService.savedChats$.subscribe((savedChats) =>
|
|
1962
|
+
this.subscription.add(this.chatService.savedChats$.subscribe((savedChats) => {
|
|
1963
|
+
this.currentChatId = undefined;
|
|
1964
|
+
this.groupedSavedChats$.next(this._groupSavedChatsByDate(savedChats));
|
|
1965
|
+
}));
|
|
1811
1966
|
}
|
|
1812
1967
|
onLoad(savedChat) {
|
|
1968
|
+
this.currentChatId = savedChat.id;
|
|
1813
1969
|
this.chatService.loadSavedChat$.next(savedChat);
|
|
1970
|
+
this.chatService.listSavedChat();
|
|
1814
1971
|
this.load.emit(savedChat);
|
|
1815
1972
|
}
|
|
1973
|
+
onRename(savedChat) {
|
|
1974
|
+
const model = {
|
|
1975
|
+
title: 'Rename saved discussion',
|
|
1976
|
+
message: `Please enter a new name for the discussion "${savedChat.title}".`,
|
|
1977
|
+
buttons: [
|
|
1978
|
+
new ModalButton({ result: -2 /* ModalResult.Cancel */ }),
|
|
1979
|
+
new ModalButton({ result: -1 /* ModalResult.OK */, text: "Rename", primary: true })
|
|
1980
|
+
],
|
|
1981
|
+
output: savedChat.title,
|
|
1982
|
+
validators: [Validators.required]
|
|
1983
|
+
};
|
|
1984
|
+
this.modalService.prompt(model).then(res => {
|
|
1985
|
+
if (res === -1 /* ModalResult.OK */) {
|
|
1986
|
+
this.subscription.add(this.chatService.updateSavedChat(savedChat.id, model.output)
|
|
1987
|
+
.pipe(tap(() => {
|
|
1988
|
+
this.notificationsService.success(`The saved discussion "${savedChat.title}" has been successfully renamed to "${model.output}".`);
|
|
1989
|
+
this.chatService.listSavedChat();
|
|
1990
|
+
}), catchError((error) => {
|
|
1991
|
+
console.error('Error occurred while updating the saved chat:', error);
|
|
1992
|
+
this.notificationsService.error(`Error occurred while updating the saved discussion "${savedChat.title}"`);
|
|
1993
|
+
return throwError(() => error);
|
|
1994
|
+
})).subscribe());
|
|
1995
|
+
}
|
|
1996
|
+
});
|
|
1997
|
+
}
|
|
1816
1998
|
onDelete(savedChat) {
|
|
1817
1999
|
this.modalService
|
|
1818
2000
|
.confirm({
|
|
@@ -1889,10 +2071,10 @@ class SavedChatsComponent {
|
|
|
1889
2071
|
}
|
|
1890
2072
|
}
|
|
1891
2073
|
SavedChatsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: SavedChatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1892
|
-
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: "<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\"
|
|
2074
|
+
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]=\"currentChatId === 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"] }] });
|
|
1893
2075
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: SavedChatsComponent, decorators: [{
|
|
1894
2076
|
type: Component,
|
|
1895
|
-
args: [{ selector: 'sq-saved-chats-v3', standalone: true, imports: [CommonModule, ModalModule, UtilsModule], template: "<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\"
|
|
2077
|
+
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]=\"currentChatId === 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"] }]
|
|
1896
2078
|
}], propDecorators: { instanceId: [{
|
|
1897
2079
|
type: Input
|
|
1898
2080
|
}], load: [{
|
|
@@ -1917,9 +2099,83 @@ const enAssistant = Utils.merge({}, _enAssistant);
|
|
|
1917
2099
|
const frAssistant = Utils.merge({}, _frAssistant);
|
|
1918
2100
|
const deAssistant = Utils.merge({}, _deAssistant);
|
|
1919
2101
|
|
|
2102
|
+
class ChatPrompt {
|
|
2103
|
+
constructor(model, modalRef, formBuilder) {
|
|
2104
|
+
this.model = model;
|
|
2105
|
+
this.modalRef = modalRef;
|
|
2106
|
+
this.formBuilder = formBuilder;
|
|
2107
|
+
this.defaultButtons = [
|
|
2108
|
+
new ModalButton({
|
|
2109
|
+
result: -1 /* ModalResult.OK */,
|
|
2110
|
+
primary: true,
|
|
2111
|
+
validation: this.form
|
|
2112
|
+
}),
|
|
2113
|
+
new ModalButton({
|
|
2114
|
+
result: -2 /* ModalResult.Cancel */
|
|
2115
|
+
})
|
|
2116
|
+
];
|
|
2117
|
+
}
|
|
2118
|
+
ngOnInit() {
|
|
2119
|
+
this.inputControl = new UntypedFormControl(this.model.output, this.model.validators || Validators.required);
|
|
2120
|
+
this.form = this.formBuilder.group({
|
|
2121
|
+
input: this.inputControl
|
|
2122
|
+
});
|
|
2123
|
+
this.formChanges = Utils.subscribe(this.form.valueChanges, (value) => {
|
|
2124
|
+
this.model.output = this.inputControl.value;
|
|
2125
|
+
});
|
|
2126
|
+
}
|
|
2127
|
+
ngOnDestroy() {
|
|
2128
|
+
this.formChanges.unsubscribe();
|
|
2129
|
+
}
|
|
2130
|
+
get title() {
|
|
2131
|
+
return this.model.title ? this.model.title : "msg#modal.prompt.title";
|
|
2132
|
+
}
|
|
2133
|
+
get buttons() {
|
|
2134
|
+
return (this.model.buttons && this.model.buttons.length > 0) ? this.model.buttons : this.defaultButtons;
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
ChatPrompt.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatPrompt, deps: [{ token: MODAL_MODEL }, { token: i1$2.ModalRef }, { token: i2.UntypedFormBuilder }], target: i0.ɵɵFactoryTarget.Component });
|
|
2138
|
+
ChatPrompt.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.0.6", type: ChatPrompt, isStandalone: true, selector: "sq-chat-prompt", ngImport: i0, template: `
|
|
2139
|
+
<form name="prompt" novalidate [formGroup]="form">
|
|
2140
|
+
<sq-modal [title]="title" [buttons]="buttons">
|
|
2141
|
+
<div class="mb-3 sq-form-group">
|
|
2142
|
+
<label class="form-label" for="input">{{model.message | sqMessage:model.messageParams}}</label>
|
|
2143
|
+
<input [sqValidation]="form" type="text" class="form-control" id="input" formControlName="input" spellcheck="off" sqAutofocus *ngIf="!model.rowCount">
|
|
2144
|
+
<textarea [sqValidation]="form" type="text" class="form-control" id="input" formControlName="input" spellcheck="on" rows="{{model.rowCount}}" sqAutofocus *ngIf="!!model.rowCount">
|
|
2145
|
+
</textarea>
|
|
2146
|
+
</div>
|
|
2147
|
+
</sq-modal>
|
|
2148
|
+
</form>
|
|
2149
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: BsModalModule }, { kind: "component", type: i4.BsModal, selector: "sq-modal", inputs: ["title", "buttons", "showHeader", "showFooter", "isProcessingState"] }, { kind: "ngmodule", type: ValidationModule }, { kind: "directive", type: i5$1.ValidationDirective, selector: "[sqValidation]", inputs: ["sqValidation"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { 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.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: IntlModule }, { kind: "pipe", type: i6$1.MessagePipe, name: "sqMessage" }] });
|
|
2150
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.6", ngImport: i0, type: ChatPrompt, decorators: [{
|
|
2151
|
+
type: Component,
|
|
2152
|
+
args: [{
|
|
2153
|
+
selector: "sq-chat-prompt",
|
|
2154
|
+
template: `
|
|
2155
|
+
<form name="prompt" novalidate [formGroup]="form">
|
|
2156
|
+
<sq-modal [title]="title" [buttons]="buttons">
|
|
2157
|
+
<div class="mb-3 sq-form-group">
|
|
2158
|
+
<label class="form-label" for="input">{{model.message | sqMessage:model.messageParams}}</label>
|
|
2159
|
+
<input [sqValidation]="form" type="text" class="form-control" id="input" formControlName="input" spellcheck="off" sqAutofocus *ngIf="!model.rowCount">
|
|
2160
|
+
<textarea [sqValidation]="form" type="text" class="form-control" id="input" formControlName="input" spellcheck="on" rows="{{model.rowCount}}" sqAutofocus *ngIf="!!model.rowCount">
|
|
2161
|
+
</textarea>
|
|
2162
|
+
</div>
|
|
2163
|
+
</sq-modal>
|
|
2164
|
+
</form>
|
|
2165
|
+
`,
|
|
2166
|
+
standalone: true,
|
|
2167
|
+
imports: [CommonModule, BsModalModule, ValidationModule, ReactiveFormsModule, IntlModule],
|
|
2168
|
+
}]
|
|
2169
|
+
}], ctorParameters: function () {
|
|
2170
|
+
return [{ type: undefined, decorators: [{
|
|
2171
|
+
type: Inject,
|
|
2172
|
+
args: [MODAL_MODEL]
|
|
2173
|
+
}] }, { type: i1$2.ModalRef }, { type: i2.UntypedFormBuilder }];
|
|
2174
|
+
} });
|
|
2175
|
+
|
|
1920
2176
|
/**
|
|
1921
2177
|
* Generated bundle index. Do not edit.
|
|
1922
2178
|
*/
|
|
1923
2179
|
|
|
1924
|
-
export { ChatComponent, ChatService, ChatSettingsV3Component, FormatIconComponent, InitialsAvatarComponent, InstanceManagerService, RestChatService, SavedChatsComponent, WebSocketChatService, chatConfigSchema, deAssistant, enAssistant, frAssistant
|
|
2180
|
+
export { ChatComponent, ChatPrompt, ChatService, ChatSettingsV3Component, FormatIconComponent, InitialsAvatarComponent, InstanceManagerService, RestChatService, SavedChatsComponent, WebSocketChatService, chatConfigSchema, connectionSettingsSchema, deAssistant, enAssistant, frAssistant };
|
|
1925
2181
|
//# sourceMappingURL=sinequa-assistant-chat.mjs.map
|