@dataclouder/ngx-agent-cards 0.1.28 → 0.1.30
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/fesm2022/dataclouder-ngx-agent-cards.mjs +1207 -681
- package/fesm2022/dataclouder-ngx-agent-cards.mjs.map +1 -1
- package/lib/components/chat-container/chat-container.component.d.ts +3 -4
- package/lib/components/chat-container/chat-header/chat-header.component.d.ts +2 -0
- package/lib/components/{text-highlighter/text-highlighter.d.ts → chat-container/chat-messages-list/chat-message/chat-message-orchestrator/message-content-displayer/message-content-displayer.d.ts} +7 -16
- package/lib/components/chat-container/chat-messages-list/chat-message/chat-message-orchestrator/message-orchestrator.component.d.ts +16 -0
- package/lib/components/chat-container/chat-messages-list/chat-message/chat-message.component.d.ts +1 -2
- package/lib/components/chat-container/chat-messages-list/chat-messages-list.component.d.ts +1 -3
- package/lib/components/conversation-info/conversation-inspector.d.ts +23 -0
- package/lib/components/dc-agent-card-details/dc-agent-card-details.component.d.ts +5 -4
- package/lib/components/dc-agent-form/agent-task-form/agent-task-form.component.d.ts +1 -3
- package/lib/components/dc-agent-form/dc-agent-card-form.component.d.ts +30 -4
- package/lib/components/dc-agent-form/dc-conversation-flow-form/dc-conversation-flow-form.component.d.ts +4 -3
- package/lib/components/dc-agent-form/dc-do-action-form/dc-do-action-form.component.d.ts +4 -0
- package/lib/components/dc-agent-form/dc-dynamic-criteria-form/dc-dynamic-criteria-form.component.d.ts +19 -0
- package/lib/components/dc-agent-form/form-group.service.d.ts +32 -2
- package/lib/components/dc-agent-form/form-group.utils.d.ts +26 -4
- package/lib/components/feedback-evaluation/feedback-evaluation.component.d.ts +15 -0
- package/lib/components/translate-dialog/translate-dialog.component.d.ts +2 -2
- package/lib/models/agent.models.d.ts +29 -33
- package/lib/models/conversation-enums.d.ts +0 -7
- package/lib/pipes/format-key.pipe.d.ts +7 -0
- package/lib/prompts/dynamic-criteria.prompts.d.ts +2 -0
- package/lib/prompts/evaluation-performance-prompt.d.ts +38 -0
- package/lib/services/chat-monitor.service.d.ts +9 -0
- package/lib/services/context-engine.service.d.ts +16 -0
- package/lib/services/conversation-info.service.d.ts +12 -0
- package/lib/services/conversation.service.d.ts +6 -12
- package/lib/services/dc-conversation-builder.service.d.ts +3 -3
- package/lib/services/dynamic-criteria.service.d.ts +13 -0
- package/lib/services/dynamic-flow-task.service.d.ts +16 -0
- package/lib/services/dynamic-flow.service.d.ts +1 -0
- package/lib/services/evaluation.service.d.ts +12 -6
- package/lib/services/global-tools.service.d.ts +7 -0
- package/lib/services/message-orchestration.service.d.ts +29 -0
- package/package.json +4 -1
- package/public-api.d.ts +5 -3
- package/lib/components/chat-container/chat-messages-list/message-orchestrator/message-orchestrator.component.d.ts +0 -29
- package/lib/services/agent-user-progress.service.d.ts +0 -17
- package/lib/services/content-extractor.tool.d.ts +0 -2
- /package/lib/components/{text-highlighter → chat-container/chat-messages-list/chat-message/chat-message-orchestrator/message-content-displayer}/extract-tags.d.ts +0 -0
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, Injectable, inject, RendererFactory2, ApplicationRef, Injector, EnvironmentInjector, signal, createComponent,
|
|
3
|
-
import { formatCamelCaseString, LANGUAGES, EntityCommunicationService,
|
|
4
|
-
import * as i1
|
|
2
|
+
import { InjectionToken, Injectable, inject, RendererFactory2, ApplicationRef, Injector, EnvironmentInjector, signal, createComponent, ChangeDetectionStrategy, Component, input, output, Input, effect, ViewChild, computed, DestroyRef, ElementRef, Pipe, ChangeDetectorRef, EventEmitter, Output } from '@angular/core';
|
|
3
|
+
import { MoodStateOptions, formatCamelCaseString, LANGUAGES, EntityCommunicationService, TOAST_ALERTS_TOKEN, LoadingBarService, EModelQuality, AudioSpeed as AudioSpeed$1, AudioSpeedReverse, getSupportedLanguageOptions, EntityBaseFormComponent, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent } from '@dataclouder/ngx-core';
|
|
4
|
+
import * as i1 from '@angular/common';
|
|
5
5
|
import { DOCUMENT, CommonModule, DatePipe, DecimalPipe } from '@angular/common';
|
|
6
6
|
import { nanoid } from 'nanoid';
|
|
7
|
-
import {
|
|
8
|
-
import * as i1$3 from 'primeng/dialog';
|
|
9
|
-
import { DialogModule } from 'primeng/dialog';
|
|
7
|
+
import { UserService } from '@dataclouder/ngx-users';
|
|
10
8
|
import * as i2$1 from 'primeng/progressbar';
|
|
11
9
|
import { ProgressBarModule } from 'primeng/progressbar';
|
|
12
10
|
import * as i2 from 'primeng/button';
|
|
13
11
|
import { ButtonModule } from 'primeng/button';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
12
|
+
import { DynamicDialogRef, DynamicDialogConfig, DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
|
|
13
|
+
import * as i1$1 from '@angular/forms';
|
|
14
|
+
import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule, FormArray, FormGroup } from '@angular/forms';
|
|
16
15
|
import { DCMicComponent, MicVadComponent } from '@dataclouder/ngx-mic';
|
|
17
16
|
import * as i4 from 'primeng/textarea';
|
|
18
17
|
import { TextareaModule } from 'primeng/textarea';
|
|
@@ -22,8 +21,9 @@ import { takeUntil, map } from 'rxjs/operators';
|
|
|
22
21
|
import { DomSanitizer } from '@angular/platform-browser';
|
|
23
22
|
import * as i1$2 from 'primeng/skeleton';
|
|
24
23
|
import { SkeletonModule } from 'primeng/skeleton';
|
|
25
|
-
import * as
|
|
24
|
+
import * as i4$1 from 'primeng/checkbox';
|
|
26
25
|
import { CheckboxModule } from 'primeng/checkbox';
|
|
26
|
+
import * as i1$3 from 'primeng/slider';
|
|
27
27
|
import { SliderModule } from 'primeng/slider';
|
|
28
28
|
import * as i3 from 'primeng/radiobutton';
|
|
29
29
|
import { RadioButtonModule } from 'primeng/radiobutton';
|
|
@@ -34,39 +34,43 @@ import * as i5$1 from 'primeng/tooltip';
|
|
|
34
34
|
import { TooltipModule } from 'primeng/tooltip';
|
|
35
35
|
import * as i5 from 'primeng/select';
|
|
36
36
|
import { SelectModule } from 'primeng/select';
|
|
37
|
+
import * as i4$2 from 'primeng/divider';
|
|
38
|
+
import { DividerModule } from 'primeng/divider';
|
|
37
39
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
38
40
|
import { PortalModule } from '@angular/cdk/portal';
|
|
39
41
|
import * as i3$2 from 'primeng/inputtext';
|
|
40
42
|
import { InputTextModule } from 'primeng/inputtext';
|
|
41
43
|
import { MessageModule } from 'primeng/message';
|
|
42
|
-
import { ResolutionType, AspectType,
|
|
44
|
+
import { ResolutionType, AspectType, AssetsLoaderComponent } from '@dataclouder/ngx-cloud-storage';
|
|
45
|
+
import * as i5$2 from 'primeng/dialog';
|
|
46
|
+
import { DialogModule } from 'primeng/dialog';
|
|
43
47
|
import * as i8 from 'primeng/inputnumber';
|
|
44
48
|
import { InputNumberModule } from 'primeng/inputnumber';
|
|
45
49
|
import { FileUploadModule } from 'primeng/fileupload';
|
|
46
50
|
import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
|
|
47
51
|
import { ActivatedRoute, Router } from '@angular/router';
|
|
48
|
-
import * as i2$
|
|
52
|
+
import * as i2$2 from 'primeng/card';
|
|
49
53
|
import { CardModule } from 'primeng/card';
|
|
50
54
|
import * as i3$1 from 'primeng/dropdown';
|
|
51
55
|
import { DropdownModule } from 'primeng/dropdown';
|
|
52
56
|
import { ChipModule } from 'primeng/chip';
|
|
53
57
|
import * as i6 from 'primeng/togglebutton';
|
|
54
58
|
import { ToggleButtonModule } from 'primeng/togglebutton';
|
|
55
|
-
import * as i4$
|
|
59
|
+
import * as i4$4 from 'primeng/toggleswitch';
|
|
56
60
|
import { ToggleSwitchModule } from 'primeng/toggleswitch';
|
|
57
61
|
import * as i6$1 from 'primeng/popover';
|
|
58
62
|
import { PopoverModule } from 'primeng/popover';
|
|
59
63
|
import { VoiceSelectorComponent } from '@dataclouder/ngx-vertex';
|
|
60
64
|
import * as i3$3 from 'primeng/inputgroup';
|
|
61
65
|
import { InputGroupModule } from 'primeng/inputgroup';
|
|
62
|
-
import * as i4$
|
|
66
|
+
import * as i4$3 from 'primeng/inputgroupaddon';
|
|
63
67
|
import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
|
|
64
|
-
import * as i2$
|
|
68
|
+
import * as i2$3 from 'primeng/api';
|
|
65
69
|
import * as i1$4 from 'primeng/paginator';
|
|
66
70
|
import { PaginatorModule } from 'primeng/paginator';
|
|
67
|
-
import * as i2$
|
|
71
|
+
import * as i2$4 from 'primeng/speeddial';
|
|
68
72
|
import { SpeedDialModule } from 'primeng/speeddial';
|
|
69
|
-
import * as i4$
|
|
73
|
+
import * as i4$5 from 'primeng/tag';
|
|
70
74
|
import { TagModule } from 'primeng/tag';
|
|
71
75
|
|
|
72
76
|
const characterCardStringDataDefinition = `
|
|
@@ -80,38 +84,39 @@ interface CharacterCardData {
|
|
|
80
84
|
tags: string[]; // Array of descriptive tags
|
|
81
85
|
appearance: string; // Physical description including height, build, hair color/style, eye color, skin tone, distinctive marks, clothing style, current outfit
|
|
82
86
|
}`;
|
|
83
|
-
var
|
|
84
|
-
(function (
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
})(
|
|
87
|
+
var ConditionType;
|
|
88
|
+
(function (ConditionType) {
|
|
89
|
+
ConditionType["Goal"] = "goal";
|
|
90
|
+
ConditionType["Challenges"] = "challenges";
|
|
91
|
+
ConditionType["NumMessages"] = "numMessages";
|
|
92
|
+
ConditionType["Time"] = "time";
|
|
93
|
+
})(ConditionType || (ConditionType = {}));
|
|
90
94
|
const EntityWhatOptions = [
|
|
91
|
-
{ label: 'Goal', value:
|
|
92
|
-
{ label: '
|
|
93
|
-
{ label: 'NumMessages', value:
|
|
94
|
-
{ label: 'Time', value:
|
|
95
|
+
{ label: 'Goal', value: ConditionType.Goal },
|
|
96
|
+
{ label: 'Challenges', value: ConditionType.Challenges },
|
|
97
|
+
{ label: 'NumMessages', value: ConditionType.NumMessages },
|
|
98
|
+
{ label: 'Time', value: ConditionType.Time },
|
|
95
99
|
];
|
|
96
|
-
var
|
|
97
|
-
(function (
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
})(
|
|
100
|
+
var ConditionOperator;
|
|
101
|
+
(function (ConditionOperator) {
|
|
102
|
+
ConditionOperator["LowerThan"] = "<";
|
|
103
|
+
ConditionOperator["LowerThanOrEqual"] = "<=";
|
|
104
|
+
ConditionOperator["Equal"] = "=";
|
|
105
|
+
ConditionOperator["GreaterThanOrEqual"] = ">=";
|
|
106
|
+
ConditionOperator["GreaterThan"] = ">";
|
|
107
|
+
})(ConditionOperator || (ConditionOperator = {}));
|
|
104
108
|
const EntityWhenOptions = [
|
|
105
|
-
{ label: '<', value:
|
|
106
|
-
{ label: '<=', value:
|
|
107
|
-
{ label: '=', value:
|
|
108
|
-
{ label: '>=', value:
|
|
109
|
-
{ label: '>', value:
|
|
109
|
+
{ label: '<', value: ConditionOperator.LowerThan },
|
|
110
|
+
{ label: '<=', value: ConditionOperator.LowerThanOrEqual },
|
|
111
|
+
{ label: '=', value: ConditionOperator.Equal },
|
|
112
|
+
{ label: '>=', value: ConditionOperator.GreaterThanOrEqual },
|
|
113
|
+
{ label: '>', value: ConditionOperator.GreaterThan },
|
|
110
114
|
];
|
|
111
115
|
var EntityThen;
|
|
112
116
|
(function (EntityThen) {
|
|
113
117
|
EntityThen["ChangePrompt"] = "changePrompt";
|
|
114
118
|
})(EntityThen || (EntityThen = {}));
|
|
119
|
+
// Creo que esta @Deprecated porque feedback ahora es text.
|
|
115
120
|
const EvalResultStringDefinition = `
|
|
116
121
|
interface SimpleEvalResult {
|
|
117
122
|
score: number; // Score of the user's response 0 to 3
|
|
@@ -164,8 +169,10 @@ var ContextType;
|
|
|
164
169
|
ContextType["CurrentMessageContent"] = "MessageContent";
|
|
165
170
|
ContextType["LastAssistantMessage"] = "LastAssistantMessage";
|
|
166
171
|
ContextType["LastUserMessage"] = "LastUserMessage";
|
|
167
|
-
ContextType["
|
|
168
|
-
ContextType["
|
|
172
|
+
ContextType["LastMessage"] = "LastMessage";
|
|
173
|
+
ContextType["Last2Messages"] = "Last2Messages";
|
|
174
|
+
ContextType["Last3Messages"] = "Last3Messages";
|
|
175
|
+
ContextType["Last4Messages"] = "Last4Messages";
|
|
169
176
|
ContextType["LastUserAndPreviousAssistant"] = "LastUserAndPreviousAssistant";
|
|
170
177
|
ContextType["AllConversation"] = "AllConversation";
|
|
171
178
|
})(ContextType || (ContextType = {}));
|
|
@@ -181,13 +188,6 @@ function provideAgentCardService(serviceImplementation) {
|
|
|
181
188
|
];
|
|
182
189
|
}
|
|
183
190
|
|
|
184
|
-
const LangCodeDescriptionEs = {
|
|
185
|
-
es: 'Español',
|
|
186
|
-
en: 'Inglés',
|
|
187
|
-
it: 'Italiano',
|
|
188
|
-
pt: 'Portugués',
|
|
189
|
-
fr: 'Frances',
|
|
190
|
-
};
|
|
191
191
|
// TODO: use the default settings when the user is not set
|
|
192
192
|
const defaultconvUserSettings = {
|
|
193
193
|
realTime: false,
|
|
@@ -447,19 +447,51 @@ function extractJsonFromResponse(content) {
|
|
|
447
447
|
}
|
|
448
448
|
}
|
|
449
449
|
|
|
450
|
+
const getMoodStateLabelsAsString = () => {
|
|
451
|
+
return MoodStateOptions.map((option) => option.value).join('\n');
|
|
452
|
+
};
|
|
453
|
+
const MOOD_STATE_PROMPT = `
|
|
454
|
+
Analyze the provided conversation to identify the Assistant's mood, feelings, and emotions.
|
|
455
|
+
Return an array of 1 to 3 strings representing the Assistant's mood states, ordered from most to least relevant.
|
|
456
|
+
Each string must be one of the mood states listed below.
|
|
457
|
+
|
|
458
|
+
Example: ['guilty', 'ashamed', 'jealous']
|
|
459
|
+
|
|
460
|
+
${getMoodStateLabelsAsString()}
|
|
461
|
+
`;
|
|
462
|
+
|
|
450
463
|
var EDoActionType;
|
|
451
464
|
(function (EDoActionType) {
|
|
452
465
|
EDoActionType["ChangePrompt"] = "changePrompt";
|
|
453
|
-
EDoActionType["
|
|
466
|
+
EDoActionType["ChangeDynamicFlowTask"] = "changeDynamicFlowTask";
|
|
454
467
|
EDoActionType["ChangeModel"] = "changeModel";
|
|
455
468
|
EDoActionType["Summarize"] = "summarize";
|
|
456
469
|
})(EDoActionType || (EDoActionType = {}));
|
|
457
470
|
const DoActionTypeOptions = [
|
|
458
|
-
{ label: 'Cambiar Prompt', value: EDoActionType.ChangePrompt },
|
|
459
|
-
{ label: 'Cambiar
|
|
471
|
+
{ label: 'Cambiar Prompt del Contexto', value: EDoActionType.ChangePrompt },
|
|
472
|
+
{ label: 'Cambiar Dynamic flow Task', value: EDoActionType.ChangeDynamicFlowTask },
|
|
460
473
|
{ label: 'Cambiar Modelo (Pendiente)', value: EDoActionType.ChangeModel },
|
|
461
474
|
{ label: 'Resumir (Pendiente)', value: EDoActionType.Summarize },
|
|
462
475
|
];
|
|
476
|
+
// Este me confunde.
|
|
477
|
+
var EDynamicFlowTaskType;
|
|
478
|
+
(function (EDynamicFlowTaskType) {
|
|
479
|
+
EDynamicFlowTaskType["Goal"] = "goal";
|
|
480
|
+
EDynamicFlowTaskType["Tools"] = "tools";
|
|
481
|
+
EDynamicFlowTaskType["Challenges"] = "challenges";
|
|
482
|
+
// NEXT:Trigger tasks
|
|
483
|
+
EDynamicFlowTaskType["OnUserMessage"] = "onUserMessage";
|
|
484
|
+
EDynamicFlowTaskType["OnAssistantMessage"] = "onAssistantMessage";
|
|
485
|
+
EDynamicFlowTaskType["OnGoalCompleted"] = "onGoalCompleted";
|
|
486
|
+
})(EDynamicFlowTaskType || (EDynamicFlowTaskType = {}));
|
|
487
|
+
const DynamicFlowTaskTypeOptions = [
|
|
488
|
+
{ label: 'Goal', value: EDynamicFlowTaskType.Goal },
|
|
489
|
+
{ label: 'On User Message', value: EDynamicFlowTaskType.OnUserMessage },
|
|
490
|
+
{ label: 'On Assistant Message', value: EDynamicFlowTaskType.OnAssistantMessage },
|
|
491
|
+
{ label: 'On Goal Completed', value: EDynamicFlowTaskType.OnGoalCompleted },
|
|
492
|
+
{ label: 'Tools', value: EDynamicFlowTaskType.Tools },
|
|
493
|
+
{ label: 'Challenges', value: EDynamicFlowTaskType.Challenges },
|
|
494
|
+
];
|
|
463
495
|
var SystemPromptType;
|
|
464
496
|
(function (SystemPromptType) {
|
|
465
497
|
SystemPromptType["SystemPrompt"] = "systemPrompt";
|
|
@@ -791,7 +823,7 @@ function getDefaultPromptByType(conversationType) {
|
|
|
791
823
|
return prompt;
|
|
792
824
|
}
|
|
793
825
|
|
|
794
|
-
class
|
|
826
|
+
class ConversationPromptBuilderService {
|
|
795
827
|
constructor() {
|
|
796
828
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
797
829
|
}
|
|
@@ -943,10 +975,10 @@ class DCConversationPromptBuilderService {
|
|
|
943
975
|
};
|
|
944
976
|
return settings;
|
|
945
977
|
}
|
|
946
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
947
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
978
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationPromptBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
979
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationPromptBuilderService, providedIn: 'root' }); }
|
|
948
980
|
}
|
|
949
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
981
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationPromptBuilderService, decorators: [{
|
|
950
982
|
type: Injectable,
|
|
951
983
|
args: [{
|
|
952
984
|
providedIn: 'root',
|
|
@@ -959,8 +991,8 @@ const Endpoints = {
|
|
|
959
991
|
AgentChat: 'api/agent-cards/chat', // For callChatCompletion, callInstruction
|
|
960
992
|
UpdateAgentCard: 'api/agent-cards/partial-update', // For findById, getAll, save (POST/PUT), delete
|
|
961
993
|
// New
|
|
962
|
-
AgentCard: 'api/agent-cards
|
|
963
|
-
AgentCardQuery: 'api/agent-cards/
|
|
994
|
+
AgentCard: 'api/agent-cards', // For findById, getAll, save (POST/PUT), delete
|
|
995
|
+
AgentCardQuery: 'api/agent-cards/query', // For filterConversationCards, findAgentCardByTitle
|
|
964
996
|
UserCards: 'api/agent-cards/user-cards', // For findFilteredAgentCards
|
|
965
997
|
VertexTTS: 'api/vertex-adapter/tts/synthesize',
|
|
966
998
|
ListModels: 'api/agent-cards/models', // For getListModels
|
|
@@ -1196,37 +1228,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1196
1228
|
}]
|
|
1197
1229
|
}], ctorParameters: () => [] });
|
|
1198
1230
|
|
|
1199
|
-
// Change this on backend if i have more types
|
|
1200
|
-
var AgentCardProgressStatus;
|
|
1201
|
-
(function (AgentCardProgressStatus) {
|
|
1202
|
-
AgentCardProgressStatus["NotStarted"] = "not_started";
|
|
1203
|
-
AgentCardProgressStatus["Started"] = "started";
|
|
1204
|
-
AgentCardProgressStatus["Completed"] = "completed";
|
|
1205
|
-
})(AgentCardProgressStatus || (AgentCardProgressStatus = {}));
|
|
1206
|
-
const DefaultAPI = {
|
|
1207
|
-
Progress: 'api/agent-cards-progress',
|
|
1208
|
-
};
|
|
1209
|
-
class AgentUserProgressService {
|
|
1210
|
-
constructor() {
|
|
1211
|
-
// Services
|
|
1212
|
-
this.httpService = inject(HttpCoreService);
|
|
1213
|
-
}
|
|
1214
|
-
getProgress() {
|
|
1215
|
-
return this.httpService.get(DefaultAPI.Progress + '/user');
|
|
1216
|
-
}
|
|
1217
|
-
saveProgress(progress) {
|
|
1218
|
-
return this.httpService.put(DefaultAPI.Progress + '/user', progress);
|
|
1219
|
-
}
|
|
1220
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentUserProgressService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1221
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentUserProgressService, providedIn: 'root' }); }
|
|
1222
|
-
}
|
|
1223
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentUserProgressService, decorators: [{
|
|
1224
|
-
type: Injectable,
|
|
1225
|
-
args: [{
|
|
1226
|
-
providedIn: 'root',
|
|
1227
|
-
}]
|
|
1228
|
-
}] });
|
|
1229
|
-
|
|
1230
1231
|
class MessagesStateService {
|
|
1231
1232
|
constructor() {
|
|
1232
1233
|
this.messagesSignal = signal([]);
|
|
@@ -1239,7 +1240,6 @@ class MessagesStateService {
|
|
|
1239
1240
|
message.messageId = nanoid();
|
|
1240
1241
|
}
|
|
1241
1242
|
this.messagesSignal.update((messages) => [...messages, message]);
|
|
1242
|
-
console.log('Message added via MessagesStateService:', this.messagesSignal());
|
|
1243
1243
|
return message.messageId;
|
|
1244
1244
|
}
|
|
1245
1245
|
updateMessage(messageId, updatedMessage, insertIfNotFound = false) {
|
|
@@ -1290,23 +1290,36 @@ class DynamicFlowService {
|
|
|
1290
1290
|
case EDoActionType.ChangePrompt:
|
|
1291
1291
|
this.doActionPrompt(action);
|
|
1292
1292
|
break;
|
|
1293
|
-
case EDoActionType.
|
|
1294
|
-
|
|
1295
|
-
const newGoal = { ...this.conversationFlowState().goal, task: action.prompt };
|
|
1296
|
-
this.conversationFlowState.set({ ...this.conversationFlowState(), goal: newGoal });
|
|
1297
|
-
console.log('DynamicConditionsService: changeGoal called');
|
|
1293
|
+
case EDoActionType.ChangeDynamicFlowTask:
|
|
1294
|
+
this.changeDynamicFlowTask(action);
|
|
1298
1295
|
break;
|
|
1299
1296
|
default:
|
|
1300
1297
|
break;
|
|
1301
1298
|
}
|
|
1302
1299
|
});
|
|
1303
1300
|
}
|
|
1301
|
+
changeDynamicFlowTask(action) {
|
|
1302
|
+
if (action.dynamicFlowTaskType === EDynamicFlowTaskType.Goal) {
|
|
1303
|
+
const currentFlow = this.conversationFlowState();
|
|
1304
|
+
if (!currentFlow) {
|
|
1305
|
+
console.warn('DynamicFlowService: conversationFlowState is null, cannot change dynamic flow task.');
|
|
1306
|
+
return;
|
|
1307
|
+
}
|
|
1308
|
+
// Create a new state object to avoid direct mutation
|
|
1309
|
+
const newFlow = {
|
|
1310
|
+
...currentFlow,
|
|
1311
|
+
goal: { ...currentFlow.goal, enabled: action.enabled ?? currentFlow.goal.enabled },
|
|
1312
|
+
};
|
|
1313
|
+
this.conversationFlowState.set(newFlow);
|
|
1314
|
+
console.log('DynamicConditionsService: changeDynamicFlowTask called', newFlow.goal);
|
|
1315
|
+
return;
|
|
1316
|
+
}
|
|
1317
|
+
}
|
|
1304
1318
|
doActionPrompt(action) {
|
|
1305
1319
|
const prompt = action.prompt;
|
|
1306
1320
|
const messageId = action.systemPromptType;
|
|
1307
1321
|
this.messagesStateService.updateMessage(messageId, { content: prompt, role: ChatRole.System }, true);
|
|
1308
1322
|
console.log('DynamicConditionsService: doActionPrompt called', this.messagesStateService.getMessagesSignal()());
|
|
1309
|
-
console.log('DynamicConditionsService: doActionPrompt called');
|
|
1310
1323
|
}
|
|
1311
1324
|
removeSystemPrompts() {
|
|
1312
1325
|
const idsToRemove = [
|
|
@@ -1326,8 +1339,8 @@ class DynamicFlowService {
|
|
|
1326
1339
|
const dynamicConditions = this.conversationFlowState()?.dynamicConditions;
|
|
1327
1340
|
if (dynamicConditions) {
|
|
1328
1341
|
dynamicConditions.forEach((condition) => {
|
|
1329
|
-
if (condition.what ===
|
|
1330
|
-
if (condition.when ===
|
|
1342
|
+
if (condition.what === ConditionType.Goal) {
|
|
1343
|
+
if (condition.when === ConditionOperator.GreaterThanOrEqual) {
|
|
1331
1344
|
const conditionValue = Number(condition.value);
|
|
1332
1345
|
// Check if the condition was not met before but is met now
|
|
1333
1346
|
if (previousScore < conditionValue && currentScore >= conditionValue) {
|
|
@@ -1351,55 +1364,485 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
1351
1364
|
}]
|
|
1352
1365
|
}] });
|
|
1353
1366
|
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
*/
|
|
1358
|
-
class SafeJsonPipe {
|
|
1359
|
-
transform(value) {
|
|
1360
|
-
// Create a new object with only serializable properties
|
|
1361
|
-
return this.stringifySafely(value);
|
|
1367
|
+
class GlobalToolsService {
|
|
1368
|
+
useTool(tool, ...args) {
|
|
1369
|
+
return Promise.resolve({ success: true, message: `Tool ${tool} used with args: ${args}` });
|
|
1362
1370
|
}
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1371
|
+
getAvailibleTools() {
|
|
1372
|
+
return 'Implementar availible tools. ';
|
|
1373
|
+
}
|
|
1374
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: GlobalToolsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1375
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: GlobalToolsService, providedIn: 'root' }); }
|
|
1376
|
+
}
|
|
1377
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: GlobalToolsService, decorators: [{
|
|
1378
|
+
type: Injectable,
|
|
1379
|
+
args: [{
|
|
1380
|
+
providedIn: 'root',
|
|
1381
|
+
}]
|
|
1382
|
+
}] });
|
|
1383
|
+
|
|
1384
|
+
class ContextEngineService {
|
|
1385
|
+
constructor() {
|
|
1386
|
+
this.messagesStateSvc = inject(MessagesStateService);
|
|
1387
|
+
this.userService = inject(UserService);
|
|
1388
|
+
}
|
|
1389
|
+
getUserData() {
|
|
1390
|
+
return this.userService.getUserDataInformation();
|
|
1391
|
+
}
|
|
1392
|
+
// TODO: este me va a ayudar a sacar contexto a las entities solo necesito mejorarlo
|
|
1393
|
+
getEntityContext(entity) {
|
|
1394
|
+
return null;
|
|
1395
|
+
}
|
|
1396
|
+
getConversationContext(contextType) {
|
|
1397
|
+
const contextMessages = this.getContextMessages(contextType);
|
|
1398
|
+
return contextMessages.map((message) => `${message.role}: ${message.content}`).join('\n');
|
|
1399
|
+
}
|
|
1400
|
+
getContextMessages(contextType) {
|
|
1401
|
+
const messages = this.messagesStateSvc.getMessagesSignal()();
|
|
1402
|
+
const conversationMessages = messages.filter((message) => [ChatRole.User, ChatRole.Assistant].includes(message.role));
|
|
1403
|
+
if (conversationMessages.length === 0) {
|
|
1404
|
+
return [];
|
|
1405
|
+
}
|
|
1406
|
+
switch (contextType) {
|
|
1407
|
+
case ContextType.LastAssistantMessage: {
|
|
1408
|
+
const lastAssistant = conversationMessages
|
|
1409
|
+
.slice()
|
|
1410
|
+
.reverse()
|
|
1411
|
+
.find((m) => m.role === ChatRole.Assistant);
|
|
1412
|
+
return lastAssistant ? [lastAssistant] : [];
|
|
1372
1413
|
}
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1414
|
+
case ContextType.LastUserMessage: {
|
|
1415
|
+
const lastUser = conversationMessages
|
|
1416
|
+
.slice()
|
|
1417
|
+
.reverse()
|
|
1418
|
+
.find((m) => m.role === ChatRole.User);
|
|
1419
|
+
return lastUser ? [lastUser] : [];
|
|
1376
1420
|
}
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1421
|
+
case ContextType.LastMessage: {
|
|
1422
|
+
const lastUser = conversationMessages
|
|
1423
|
+
.slice()
|
|
1424
|
+
.reverse()
|
|
1425
|
+
.find((m) => m.role === ChatRole.User);
|
|
1426
|
+
const lastAssistant = conversationMessages
|
|
1427
|
+
.slice()
|
|
1428
|
+
.reverse()
|
|
1429
|
+
.find((m) => m.role === ChatRole.Assistant);
|
|
1430
|
+
const dialog = [];
|
|
1431
|
+
if (lastAssistant)
|
|
1432
|
+
dialog.push(lastAssistant);
|
|
1433
|
+
if (lastUser)
|
|
1434
|
+
dialog.push(lastUser);
|
|
1435
|
+
return dialog;
|
|
1380
1436
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
return '[Function]';
|
|
1437
|
+
case ContextType.Last2Messages: {
|
|
1438
|
+
return conversationMessages.slice(-2);
|
|
1384
1439
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1440
|
+
case ContextType.Last3Messages: {
|
|
1441
|
+
return conversationMessages.slice(-3);
|
|
1442
|
+
}
|
|
1443
|
+
case ContextType.Last4Messages: {
|
|
1444
|
+
return conversationMessages.slice(-4);
|
|
1445
|
+
}
|
|
1446
|
+
case ContextType.LastUserAndPreviousAssistant: {
|
|
1447
|
+
const lastUserIndex = conversationMessages.map((m) => m.role).lastIndexOf(ChatRole.User);
|
|
1448
|
+
if (lastUserIndex <= 0) {
|
|
1449
|
+
return [];
|
|
1389
1450
|
}
|
|
1390
|
-
|
|
1451
|
+
const messages = conversationMessages.slice(lastUserIndex - 1, lastUserIndex + 1);
|
|
1452
|
+
console.log('LastUserAndPreviousAssistant', messages);
|
|
1453
|
+
return messages;
|
|
1391
1454
|
}
|
|
1392
|
-
|
|
1393
|
-
|
|
1455
|
+
case ContextType.AllConversation:
|
|
1456
|
+
default:
|
|
1457
|
+
return conversationMessages;
|
|
1458
|
+
}
|
|
1394
1459
|
}
|
|
1395
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
1396
|
-
static { this.ɵ
|
|
1460
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ContextEngineService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1461
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ContextEngineService, providedIn: 'root' }); }
|
|
1397
1462
|
}
|
|
1398
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
1399
|
-
type:
|
|
1463
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ContextEngineService, decorators: [{
|
|
1464
|
+
type: Injectable,
|
|
1400
1465
|
args: [{
|
|
1401
|
-
|
|
1402
|
-
|
|
1466
|
+
providedIn: 'root',
|
|
1467
|
+
}]
|
|
1468
|
+
}] });
|
|
1469
|
+
|
|
1470
|
+
class FeedbackEvaluationComponent {
|
|
1471
|
+
constructor() {
|
|
1472
|
+
this.ref = inject(DynamicDialogRef);
|
|
1473
|
+
this.config = inject(DynamicDialogConfig);
|
|
1474
|
+
}
|
|
1475
|
+
ngOnInit() {
|
|
1476
|
+
if (this.config.data) {
|
|
1477
|
+
this.evaluationData = this.config.data;
|
|
1478
|
+
}
|
|
1479
|
+
else {
|
|
1480
|
+
this.evaluationData = this.getDummyEvaluationData();
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1483
|
+
getDummyEvaluationData() {
|
|
1484
|
+
return {
|
|
1485
|
+
overall_score: {
|
|
1486
|
+
rating: 85,
|
|
1487
|
+
level: 4,
|
|
1488
|
+
},
|
|
1489
|
+
assessments: {
|
|
1490
|
+
grammar: {
|
|
1491
|
+
score: 90,
|
|
1492
|
+
level: 5,
|
|
1493
|
+
feedback: 'Excellent grammar, with very few mistakes. Your sentence structures are complex and accurate.',
|
|
1494
|
+
suggestions: ['Review the use of subjunctive mood for hypothetical situations.'],
|
|
1495
|
+
},
|
|
1496
|
+
vocabulary: {
|
|
1497
|
+
score: 88,
|
|
1498
|
+
level: 4,
|
|
1499
|
+
feedback: 'You have a wide range of vocabulary and use it appropriately. You could try to incorporate more idiomatic expressions.',
|
|
1500
|
+
suggestions: ['Learn phrasal verbs related to business.', 'Practice using synonyms for common words.'],
|
|
1501
|
+
},
|
|
1502
|
+
communication_effectiveness: {
|
|
1503
|
+
score: 82,
|
|
1504
|
+
level: 'Advanced',
|
|
1505
|
+
feedback: 'Your communication is clear and effective. You are able to convey your ideas with precision.',
|
|
1506
|
+
suggestions: ['Work on your turn-taking skills in fast-paced conversations.'],
|
|
1507
|
+
},
|
|
1508
|
+
pragmatic_competence: {
|
|
1509
|
+
score: 80,
|
|
1510
|
+
level: 'Advanced',
|
|
1511
|
+
feedback: 'You show good awareness of social and cultural norms in communication.',
|
|
1512
|
+
suggestions: ['Study how humor is used in professional contexts.'],
|
|
1513
|
+
},
|
|
1514
|
+
},
|
|
1515
|
+
conversation_analysis: {
|
|
1516
|
+
dominant_register: 'formal',
|
|
1517
|
+
conversation_type: 'professional',
|
|
1518
|
+
key_observations: ['You maintained a professional tone throughout the conversation.', 'You used appropriate language for the context.'],
|
|
1519
|
+
notable_patterns: ['Consistent use of complex sentences.', 'Tendency to use direct questions.'],
|
|
1520
|
+
},
|
|
1521
|
+
actionable_feedback: {
|
|
1522
|
+
immediate_focus_areas: ['Using more varied intonation.'],
|
|
1523
|
+
practice_recommendations: [
|
|
1524
|
+
'Record yourself speaking and listen for intonation patterns.',
|
|
1525
|
+
'Engage in role-playing scenarios that require different emotional expressions.',
|
|
1526
|
+
],
|
|
1527
|
+
next_steps: ['Have a conversation with a native speaker focusing on expressing excitement and disappointment.'],
|
|
1528
|
+
},
|
|
1529
|
+
};
|
|
1530
|
+
}
|
|
1531
|
+
closeDialog() {
|
|
1532
|
+
this.ref.close();
|
|
1533
|
+
}
|
|
1534
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FeedbackEvaluationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1535
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: FeedbackEvaluationComponent, isStandalone: true, selector: "dc-feedback-evaluation", ngImport: i0, template: "<div class=\"feedback-container\">\n @if (evaluationData) {\n <h2 class=\"feedback-title\">Performance Evaluation</h2>\n\n <div class=\"feedback-content\">\n <div class=\"general-score\">\n <h3>Overall Score</h3>\n <p class=\"score\">{{ evaluationData.overall_score.rating }} / 100 (Level: {{ evaluationData.overall_score.level }})</p>\n </div>\n\n <div class=\"feedback-details\">\n <h3>Detailed Assessments</h3>\n @for (assessment of evaluationData.assessments | keyvalue; track assessment.key) {\n <div>\n <h4>{{ assessment.key.replace('_', ' ') | titlecase }}</h4>\n <p>\n <span class=\"score\">Score: {{ assessment.value.score }} / 100</span> |\n <span class=\"level\">Level: {{ assessment.value.level }}</span>\n </p>\n <p class=\"comment\"><strong>Feedback:</strong> {{ assessment.value.feedback }}</p>\n @if (assessment.value.suggestions?.length > 0) {\n <div>\n <strong>Suggestions:</strong>\n <ul>\n @for (suggestion of assessment.value.suggestions; track $index) {\n <li>{{ suggestion }}</li>\n }\n </ul>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"conversation-analysis\">\n <h3>Conversation Analysis</h3>\n <p><strong>Dominant Register:</strong> {{ evaluationData.conversation_analysis.dominant_register }}</p>\n <p><strong>Conversation Type:</strong> {{ evaluationData.conversation_analysis.conversation_type }}</p>\n @if (evaluationData.conversation_analysis.key_observations?.length > 0) {\n <div>\n <strong>Key Observations:</strong>\n <ul>\n @for (observation of evaluationData.conversation_analysis.key_observations; track $index) {\n <li>{{ observation }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.conversation_analysis.notable_patterns?.length > 0) {\n <div>\n <strong>Notable Patterns:</strong>\n <ul>\n @for (pattern of evaluationData.conversation_analysis.notable_patterns; track $index) {\n <li>{{ pattern }}</li>\n }\n </ul>\n </div>\n }\n </div>\n\n <div class=\"actionable-feedback\">\n <h3>Actionable Feedback</h3>\n @if (evaluationData.actionable_feedback.immediate_focus_areas?.length > 0) {\n <div>\n <strong>Immediate Focus Areas:</strong>\n <ul>\n @for (area of evaluationData.actionable_feedback.immediate_focus_areas; track $index) {\n <li>{{ area }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.actionable_feedback.practice_recommendations?.length > 0) {\n <div>\n <strong>Practice Recommendations:</strong>\n <ul>\n @for (recommendation of evaluationData.actionable_feedback.practice_recommendations; track $index) {\n <li>{{ recommendation }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.actionable_feedback.next_steps?.length > 0) {\n <div>\n <strong>Next Steps:</strong>\n <ul>\n @for (step of evaluationData.actionable_feedback.next_steps; track $index) {\n <li>{{ step }}</li>\n }\n </ul>\n </div>\n }\n </div>\n </div>\n\n <div class.bind=\"'feedback-footer'\">\n <p-button label=\"Close\" (onClick)=\"closeDialog()\"></p-button>\n </div>\n\n } @else {\n <div class=\"loading-container\">\n <p>Loading feedback...</p>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;max-height:85vh;overflow:auto}.feedback-container{display:flex;flex-direction:column;height:100%;background-color:#f9f9f9;border-radius:8px}.feedback-title{padding:1.5rem 1.5rem 0;font-size:1.5rem;font-weight:600;text-align:center;flex-shrink:0;color:#333}.feedback-content{flex:1 1 auto;overflow-y:auto;padding:1.5rem}.feedback-footer{flex-shrink:0;padding:1rem 1.5rem;text-align:right;border-top:1px solid #e9ecef;background-color:#fff;border-bottom-left-radius:8px;border-bottom-right-radius:8px}.general-score{text-align:center;margin-bottom:20px;background-color:#fff;padding:1rem;border-radius:6px;border:1px solid #e9ecef}.general-score .score{font-size:2em;font-weight:700;color:#4caf50}.feedback-details>div,.conversation-analysis>div,.actionable-feedback>div{margin-bottom:1rem}.feedback-details h4{margin-bottom:.75rem}.feedback-details p,.conversation-analysis p,.actionable-feedback ul{margin-bottom:.5rem}.comment{font-style:italic;color:#555}ul{list-style-position:inside;padding-left:0}h3{font-size:1.25rem;border-bottom:2px solid #eee;padding-bottom:.5rem;margin-top:1.5rem;margin-bottom:1rem;color:#333}h4{font-size:1.1rem;margin-top:1rem;margin-bottom:.5rem;color:#555}li{margin-bottom:.5rem}strong{color:#333}.loading-container{display:flex;justify-content:center;align-items:center;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i1.TitleCasePipe, name: "titlecase" }, { kind: "pipe", type: i1.KeyValuePipe, name: "keyvalue" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1536
|
+
}
|
|
1537
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FeedbackEvaluationComponent, decorators: [{
|
|
1538
|
+
type: Component,
|
|
1539
|
+
args: [{ selector: 'dc-feedback-evaluation', standalone: true, imports: [CommonModule, ButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"feedback-container\">\n @if (evaluationData) {\n <h2 class=\"feedback-title\">Performance Evaluation</h2>\n\n <div class=\"feedback-content\">\n <div class=\"general-score\">\n <h3>Overall Score</h3>\n <p class=\"score\">{{ evaluationData.overall_score.rating }} / 100 (Level: {{ evaluationData.overall_score.level }})</p>\n </div>\n\n <div class=\"feedback-details\">\n <h3>Detailed Assessments</h3>\n @for (assessment of evaluationData.assessments | keyvalue; track assessment.key) {\n <div>\n <h4>{{ assessment.key.replace('_', ' ') | titlecase }}</h4>\n <p>\n <span class=\"score\">Score: {{ assessment.value.score }} / 100</span> |\n <span class=\"level\">Level: {{ assessment.value.level }}</span>\n </p>\n <p class=\"comment\"><strong>Feedback:</strong> {{ assessment.value.feedback }}</p>\n @if (assessment.value.suggestions?.length > 0) {\n <div>\n <strong>Suggestions:</strong>\n <ul>\n @for (suggestion of assessment.value.suggestions; track $index) {\n <li>{{ suggestion }}</li>\n }\n </ul>\n </div>\n }\n </div>\n }\n </div>\n\n <div class=\"conversation-analysis\">\n <h3>Conversation Analysis</h3>\n <p><strong>Dominant Register:</strong> {{ evaluationData.conversation_analysis.dominant_register }}</p>\n <p><strong>Conversation Type:</strong> {{ evaluationData.conversation_analysis.conversation_type }}</p>\n @if (evaluationData.conversation_analysis.key_observations?.length > 0) {\n <div>\n <strong>Key Observations:</strong>\n <ul>\n @for (observation of evaluationData.conversation_analysis.key_observations; track $index) {\n <li>{{ observation }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.conversation_analysis.notable_patterns?.length > 0) {\n <div>\n <strong>Notable Patterns:</strong>\n <ul>\n @for (pattern of evaluationData.conversation_analysis.notable_patterns; track $index) {\n <li>{{ pattern }}</li>\n }\n </ul>\n </div>\n }\n </div>\n\n <div class=\"actionable-feedback\">\n <h3>Actionable Feedback</h3>\n @if (evaluationData.actionable_feedback.immediate_focus_areas?.length > 0) {\n <div>\n <strong>Immediate Focus Areas:</strong>\n <ul>\n @for (area of evaluationData.actionable_feedback.immediate_focus_areas; track $index) {\n <li>{{ area }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.actionable_feedback.practice_recommendations?.length > 0) {\n <div>\n <strong>Practice Recommendations:</strong>\n <ul>\n @for (recommendation of evaluationData.actionable_feedback.practice_recommendations; track $index) {\n <li>{{ recommendation }}</li>\n }\n </ul>\n </div>\n } @if (evaluationData.actionable_feedback.next_steps?.length > 0) {\n <div>\n <strong>Next Steps:</strong>\n <ul>\n @for (step of evaluationData.actionable_feedback.next_steps; track $index) {\n <li>{{ step }}</li>\n }\n </ul>\n </div>\n }\n </div>\n </div>\n\n <div class.bind=\"'feedback-footer'\">\n <p-button label=\"Close\" (onClick)=\"closeDialog()\"></p-button>\n </div>\n\n } @else {\n <div class=\"loading-container\">\n <p>Loading feedback...</p>\n </div>\n }\n</div>\n", styles: [":host{display:block;width:100%;height:100%;max-height:85vh;overflow:auto}.feedback-container{display:flex;flex-direction:column;height:100%;background-color:#f9f9f9;border-radius:8px}.feedback-title{padding:1.5rem 1.5rem 0;font-size:1.5rem;font-weight:600;text-align:center;flex-shrink:0;color:#333}.feedback-content{flex:1 1 auto;overflow-y:auto;padding:1.5rem}.feedback-footer{flex-shrink:0;padding:1rem 1.5rem;text-align:right;border-top:1px solid #e9ecef;background-color:#fff;border-bottom-left-radius:8px;border-bottom-right-radius:8px}.general-score{text-align:center;margin-bottom:20px;background-color:#fff;padding:1rem;border-radius:6px;border:1px solid #e9ecef}.general-score .score{font-size:2em;font-weight:700;color:#4caf50}.feedback-details>div,.conversation-analysis>div,.actionable-feedback>div{margin-bottom:1rem}.feedback-details h4{margin-bottom:.75rem}.feedback-details p,.conversation-analysis p,.actionable-feedback ul{margin-bottom:.5rem}.comment{font-style:italic;color:#555}ul{list-style-position:inside;padding-left:0}h3{font-size:1.25rem;border-bottom:2px solid #eee;padding-bottom:.5rem;margin-top:1.5rem;margin-bottom:1rem;color:#333}h4{font-size:1.1rem;margin-top:1rem;margin-bottom:.5rem;color:#555}li{margin-bottom:.5rem}strong{color:#333}.loading-container{display:flex;justify-content:center;align-items:center;height:100%}\n"] }]
|
|
1540
|
+
}], ctorParameters: () => [] });
|
|
1541
|
+
|
|
1542
|
+
const performanceAnalysisPromptTemplate = (language) => `
|
|
1543
|
+
You are an expert ${language} language evaluator. Analyze the following conversation and provide a detailed assessment focusing on these four key areas.
|
|
1544
|
+
Return your analysis in the exact JSON format specified below.
|
|
1545
|
+
|
|
1546
|
+
Assessment Categories & Evaluation Rules:
|
|
1547
|
+
1. GRAMMAR
|
|
1548
|
+
Evaluate the user's grammatical competence based on:
|
|
1549
|
+
|
|
1550
|
+
Sentence structure accuracy: Proper use of simple, compound, and complex sentences
|
|
1551
|
+
Verb tense consistency: Correct past, present, future tense usage and sequence
|
|
1552
|
+
Subject-verb agreement: Proper matching of subjects with verbs
|
|
1553
|
+
Article usage: Correct use of a, an, the, and zero articles
|
|
1554
|
+
Preposition accuracy: Proper use of prepositions (in, on, at, by, etc.)
|
|
1555
|
+
Pronoun reference: Clear and correct pronoun usage
|
|
1556
|
+
Question formation: Proper structure of questions and question tags
|
|
1557
|
+
Conditional structures: Correct use of if-clauses and conditional sentences
|
|
1558
|
+
Passive voice: Appropriate use when needed
|
|
1559
|
+
Modal verbs: Correct usage of can, could, should, would, must, etc.
|
|
1560
|
+
|
|
1561
|
+
2. VOCABULARY
|
|
1562
|
+
Evaluate the user's vocabulary proficiency based on:
|
|
1563
|
+
|
|
1564
|
+
Range of vocabulary: Breadth across different topics and domains
|
|
1565
|
+
Precise word choice: Selecting the most appropriate word for context
|
|
1566
|
+
Nuanced meanings: Understanding subtle differences between similar words
|
|
1567
|
+
Collocations: Natural word combinations (e.g., "strong coffee", "heavy rain")
|
|
1568
|
+
Idiomatic expressions: Use of phrases, metaphors, and cultural expressions
|
|
1569
|
+
Academic vs. conversational vocabulary: Appropriate register switching
|
|
1570
|
+
Synonyms and variety: Avoiding repetition, using diverse expressions
|
|
1571
|
+
Word formation: Understanding prefixes, suffixes, and word families
|
|
1572
|
+
Context-appropriate usage: Using words correctly in their proper contexts
|
|
1573
|
+
Frequency of vocabulary: Using both common and less common words appropriately
|
|
1574
|
+
|
|
1575
|
+
3. COMMUNICATION EFFECTIVENESS
|
|
1576
|
+
Evaluate the user's ability to communicate clearly and effectively based on:
|
|
1577
|
+
|
|
1578
|
+
Clarity of message delivery: Can the listener easily understand the intended meaning?
|
|
1579
|
+
Coherence and organization: Logical flow of ideas and smooth transitions
|
|
1580
|
+
Appropriate register: Matching formality level to the situation and audience
|
|
1581
|
+
Turn-taking skills: Proper conversational management and participation
|
|
1582
|
+
Repair strategies: Ability to clarify when misunderstood
|
|
1583
|
+
Engagement level: Active participation and responsiveness
|
|
1584
|
+
Topic development: How well ideas are expanded and elaborated
|
|
1585
|
+
Persuasion and argumentation: Logical reasoning and evidence presentation
|
|
1586
|
+
Narrative ability: Storytelling coherence and engagement
|
|
1587
|
+
Functional language use: Requests, apologies, complaints, compliments, etc.
|
|
1588
|
+
|
|
1589
|
+
4. PRAGMATIC COMPETENCE
|
|
1590
|
+
Evaluate the user's cultural and social language awareness based on:
|
|
1591
|
+
|
|
1592
|
+
Social norms understanding: Awareness of appropriate language for different contexts
|
|
1593
|
+
Politeness markers: Use of please, thank you, excuse me, and other courtesy expressions
|
|
1594
|
+
Cultural references: Understanding and using culturally appropriate expressions
|
|
1595
|
+
Audience adaptation: Adjusting language style for different listeners
|
|
1596
|
+
Implied meaning recognition: Understanding subtext, sarcasm, and indirect communication
|
|
1597
|
+
Speech acts: Appropriate use of requests, invitations, refusals, and suggestions
|
|
1598
|
+
Conversational conventions: Following cultural norms for conversation flow
|
|
1599
|
+
Humor and informal language: Appropriate use of jokes, slang, and casual expressions
|
|
1600
|
+
Power dynamics awareness: Using appropriate language with different social statuses
|
|
1601
|
+
Contextual sensitivity: Adapting language to formal vs. informal situations
|
|
1602
|
+
|
|
1603
|
+
Required JSON Response Format:
|
|
1604
|
+
json{
|
|
1605
|
+
"overall_score": {
|
|
1606
|
+
"rating": 0-100,
|
|
1607
|
+
"level": "1|2|3|4|5"
|
|
1608
|
+
},
|
|
1609
|
+
"assessments": {
|
|
1610
|
+
"grammar": {
|
|
1611
|
+
"score": 0-100,
|
|
1612
|
+
"level": "1|2|3|4|5",
|
|
1613
|
+
"feedback": "Comprehensive feedback covering strengths, weaknesses, specific observations, and examples from the conversation that demonstrate grammatical competence or areas for improvement",
|
|
1614
|
+
"suggestions": [
|
|
1615
|
+
"Grammar rule 1 to study (e.g., 'Present Perfect vs Simple Past')",
|
|
1616
|
+
"Grammar concept 2 to practice (e.g., 'Conditional sentences')",
|
|
1617
|
+
"Grammar topic 3 to review (e.g., 'Article usage with countable/uncountable nouns')"
|
|
1618
|
+
]
|
|
1619
|
+
},
|
|
1620
|
+
"vocabulary": {
|
|
1621
|
+
"score": 0-100,
|
|
1622
|
+
"level": "1|2|3|4|5",
|
|
1623
|
+
"feedback": "Comprehensive feedback covering vocabulary range, precision, strengths, weaknesses, and specific examples from the conversation showing vocabulary usage",
|
|
1624
|
+
"suggestions": [
|
|
1625
|
+
"Word 1 to learn (e.g., 'comprehensive')",
|
|
1626
|
+
"Word 2 to practice (e.g., 'elaborate')",
|
|
1627
|
+
"Word 3 to add to vocabulary (e.g., 'substantial')",
|
|
1628
|
+
"Phrase 1 to learn (e.g., 'take into account')",
|
|
1629
|
+
"Collocation 1 to practice (e.g., 'make progress')"
|
|
1630
|
+
]
|
|
1631
|
+
},
|
|
1632
|
+
"communication_effectiveness": {
|
|
1633
|
+
"score": 0-100,
|
|
1634
|
+
"level": "Beginner|Intermediate|Advanced|Native-like",
|
|
1635
|
+
"feedback": "Comprehensive feedback about clarity, coherence, register appropriateness, and overall communication skills with specific examples from the conversation",
|
|
1636
|
+
"suggestions": [
|
|
1637
|
+
"Communication skill 1 to practice (e.g., 'Using transition words')",
|
|
1638
|
+
"Strategy 1 to develop (e.g., 'Asking clarifying questions')",
|
|
1639
|
+
"Technique 1 to improve (e.g., 'Paraphrasing for clarity')"
|
|
1640
|
+
]
|
|
1641
|
+
},
|
|
1642
|
+
"pragmatic_competence": {
|
|
1643
|
+
"score": 0-100,
|
|
1644
|
+
"level": "Beginner|Intermediate|Advanced|Native-like",
|
|
1645
|
+
"feedback": "Comprehensive feedback about cultural awareness, social appropriateness, politeness, and contextual language use with specific examples from the conversation",
|
|
1646
|
+
"suggestions": [
|
|
1647
|
+
"Cultural concept 1 to learn (e.g., 'Indirect refusal strategies')",
|
|
1648
|
+
"Social skill 1 to practice (e.g., 'Small talk conventions')",
|
|
1649
|
+
"Pragmatic area 1 to study (e.g., 'Formal email etiquette')"
|
|
1650
|
+
]
|
|
1651
|
+
}
|
|
1652
|
+
},
|
|
1653
|
+
"conversation_analysis": {
|
|
1654
|
+
"dominant_register": "formal|informal|mixed",
|
|
1655
|
+
"conversation_type": "casual|academic|professional|social",
|
|
1656
|
+
"key_observations": ["observation1", "observation2", "observation3"],
|
|
1657
|
+
"notable_patterns": ["pattern1", "pattern2"]
|
|
1658
|
+
},
|
|
1659
|
+
"actionable_feedback": {
|
|
1660
|
+
"immediate_focus_areas": ["area1", "area2"],
|
|
1661
|
+
"practice_recommendations": ["recommendation1", "recommendation2", "recommendation3"],
|
|
1662
|
+
"next_steps": ["step1", "step2"]
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1665
|
+
Scoring Guidelines:
|
|
1666
|
+
|
|
1667
|
+
0-20: Beginner - Basic understanding, frequent errors, limited range
|
|
1668
|
+
20-40: Beginner Intermediate - Moderate competence, some errors, adequate range
|
|
1669
|
+
40-60: Intermediate - Good competence, minor errors, good range
|
|
1670
|
+
60-80: Intermediate Advanced - Exceptional competence, rare errors, sophisticated range
|
|
1671
|
+
80-100: Advanced - Exceptional competence, rare errors, sophisticated range
|
|
1672
|
+
|
|
1673
|
+
Important Notes:
|
|
1674
|
+
|
|
1675
|
+
Be specific and constructive in your feedback
|
|
1676
|
+
Use actual examples from the conversation provided
|
|
1677
|
+
Focus on observable language behaviors only
|
|
1678
|
+
Provide actionable improvement suggestions tailored to each category
|
|
1679
|
+
Consider the context and purpose of the conversation
|
|
1680
|
+
If multiple speakers are present, specify which speaker you're evaluating
|
|
1681
|
+
|
|
1682
|
+
`;
|
|
1683
|
+
|
|
1684
|
+
class AnalysisResult {
|
|
1685
|
+
}
|
|
1686
|
+
class EvaluationService {
|
|
1687
|
+
constructor() {
|
|
1688
|
+
// Services
|
|
1689
|
+
this.defaultAgentCardService = inject(DefaultAgentCardsService);
|
|
1690
|
+
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1691
|
+
this.dynamicFlowService = inject(DynamicFlowService);
|
|
1692
|
+
this.contextEngineService = inject(ContextEngineService);
|
|
1693
|
+
this.dialogService = inject(DialogService);
|
|
1694
|
+
this.loadingBarService = inject(LoadingBarService);
|
|
1695
|
+
// Signals
|
|
1696
|
+
this.scoreSignal = signal(0); // Only Score
|
|
1697
|
+
this.evaluationResultSignal = signal(null); // Not sure if ill give some use
|
|
1698
|
+
}
|
|
1699
|
+
async evaluateGoal(goalTask) {
|
|
1700
|
+
if (!goalTask.task) {
|
|
1701
|
+
goalTask.task = 'Evaluate this conversation the goal is keep the conversation on topic consistency.';
|
|
1702
|
+
}
|
|
1703
|
+
const evaluator = {
|
|
1704
|
+
task: goalTask.task,
|
|
1705
|
+
expectedResponseType: 'Response should be in next JSON format: {"score": number, "text": string}, score is a number between 0 and 3, text is concrete feedback in less than 25 words.',
|
|
1706
|
+
model: goalTask.model || { quality: EModelQuality.FAST },
|
|
1707
|
+
};
|
|
1708
|
+
const evaluationResult = await this.evaluateConversation(evaluator, ContextType.LastMessage);
|
|
1709
|
+
this.updateScore(evaluationResult.score || 0);
|
|
1710
|
+
console.log(' ♦️ Goal Evaluation Result:', evaluationResult, this.scoreSignal());
|
|
1711
|
+
// Evaluation can return evything check i can standarize this.
|
|
1712
|
+
this.toastService.info({
|
|
1713
|
+
title: 'Score ' + evaluationResult?.text,
|
|
1714
|
+
subtitle: `Added ${evaluationResult?.score} points`,
|
|
1715
|
+
});
|
|
1716
|
+
return evaluationResult;
|
|
1717
|
+
}
|
|
1718
|
+
async evaluateConversation(task, contextType = ContextType.AllConversation) {
|
|
1719
|
+
// Format conversation for evaluation
|
|
1720
|
+
const conversationMessagesString = this.contextEngineService.getConversationContext(contextType);
|
|
1721
|
+
const userDataString = this.contextEngineService.getUserData();
|
|
1722
|
+
// Create evaluation prompt
|
|
1723
|
+
let instructions = `
|
|
1724
|
+
Please replay to this task:
|
|
1725
|
+
${task.task}
|
|
1726
|
+
<UserData>
|
|
1727
|
+
${userDataString}
|
|
1728
|
+
</UserData>
|
|
1729
|
+
This is the conversation history:
|
|
1730
|
+
<Context>
|
|
1731
|
+
${conversationMessagesString}
|
|
1732
|
+
</Context>
|
|
1733
|
+
|
|
1734
|
+
`;
|
|
1735
|
+
if (task.expectedResponseType) {
|
|
1736
|
+
instructions += `\nExpected response type: ${task.expectedResponseType}`;
|
|
1737
|
+
}
|
|
1738
|
+
else {
|
|
1739
|
+
instructions += `\nExpected response type: {"score": number, "text": string}`;
|
|
1740
|
+
}
|
|
1741
|
+
// Send evaluation request
|
|
1742
|
+
const evaluationMessages = [{ content: instructions, role: ChatRole.User }];
|
|
1743
|
+
// Not sure what strategy use, if works types should be definied in definitions, generarally response will be score, and feedback.
|
|
1744
|
+
const response = await this.defaultAgentCardService.callChatCompletion({
|
|
1745
|
+
messages: evaluationMessages,
|
|
1746
|
+
returnJson: true,
|
|
1747
|
+
model: task.model || { quality: EModelQuality.FAST },
|
|
1748
|
+
});
|
|
1749
|
+
// Extract JSON from response
|
|
1750
|
+
const jsonData = response.content;
|
|
1751
|
+
jsonData.score = jsonData.score * 10;
|
|
1752
|
+
this.evaluationResultSignal.set(jsonData);
|
|
1753
|
+
return jsonData;
|
|
1754
|
+
}
|
|
1755
|
+
/**
|
|
1756
|
+
* Diference with evaluateConversation is task is already processed here.
|
|
1757
|
+
* Evaluates a conversation context based on a specific task and attaches the result to a designated message.
|
|
1758
|
+
* @param agentTask The task definition for the evaluation.
|
|
1759
|
+
* @param messageToUpdate The specific ChatMessage object (user or assistant) to attach the evaluation results to.
|
|
1760
|
+
* @param contextType Determines which part of the conversation history to send as context (default: AllConversation).
|
|
1761
|
+
* @returns The JSON result of the evaluation.
|
|
1762
|
+
*/
|
|
1763
|
+
async evaluateWithTask(agentTask) {
|
|
1764
|
+
// You Already Generate Task with all data needed..
|
|
1765
|
+
const requestMessages = [{ role: ChatRole.User, content: agentTask.task }];
|
|
1766
|
+
try {
|
|
1767
|
+
const response = await this.defaultAgentCardService.callChatCompletion({ messages: requestMessages, model: agentTask.model });
|
|
1768
|
+
// let jsonData = extractJsonFromResponse(response.content);
|
|
1769
|
+
let jsonData = response.content;
|
|
1770
|
+
if (typeof jsonData === 'string') {
|
|
1771
|
+
return { text: jsonData };
|
|
1772
|
+
}
|
|
1773
|
+
return jsonData;
|
|
1774
|
+
}
|
|
1775
|
+
catch (error) {
|
|
1776
|
+
console.error('Error during evaluateWithTask:', error);
|
|
1777
|
+
return null;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1780
|
+
updateScore(additionalScore) {
|
|
1781
|
+
// Aqui tengo que verificar que se cumple condición de goal!
|
|
1782
|
+
const previuesScore = this.scoreSignal();
|
|
1783
|
+
const newScore = previuesScore + additionalScore;
|
|
1784
|
+
// How to add the conditions dynamically?
|
|
1785
|
+
this.dynamicFlowService.checkDynamicConditions(previuesScore, newScore);
|
|
1786
|
+
if (newScore >= 100) {
|
|
1787
|
+
this.scoreSignal.set(100);
|
|
1788
|
+
this.analylizePerformance();
|
|
1789
|
+
}
|
|
1790
|
+
else {
|
|
1791
|
+
console.log('Score updated to:', newScore);
|
|
1792
|
+
this.scoreSignal.set(newScore);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
setScore(newScore) {
|
|
1796
|
+
this.dynamicFlowService.checkDynamicConditions(this.scoreSignal(), newScore);
|
|
1797
|
+
this.scoreSignal.set(newScore);
|
|
1798
|
+
if (newScore >= 100) {
|
|
1799
|
+
this.scoreSignal.set(100);
|
|
1800
|
+
this.analylizePerformance();
|
|
1801
|
+
}
|
|
1802
|
+
else {
|
|
1803
|
+
this.scoreSignal.set(newScore);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
resetScore() {
|
|
1807
|
+
this.scoreSignal.set(0);
|
|
1808
|
+
}
|
|
1809
|
+
async analylizePerformance() {
|
|
1810
|
+
console.log('Analylizing performance...');
|
|
1811
|
+
const conversationMessages = this.contextEngineService.getContextMessages(ContextType.AllConversation);
|
|
1812
|
+
if (conversationMessages.length < 6) {
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
const conversationContext = this.contextEngineService.getConversationContext(ContextType.AllConversation);
|
|
1816
|
+
// TODO change the english!
|
|
1817
|
+
let prompt = performanceAnalysisPromptTemplate('English');
|
|
1818
|
+
prompt += `\n\nHere the user conversation: <Context>${conversationContext}</Context>`;
|
|
1819
|
+
this.loadingBarService.showIndeterminate();
|
|
1820
|
+
const response = await this.defaultAgentCardService.callChatCompletion({
|
|
1821
|
+
messages: [{ role: ChatRole.User, content: prompt }],
|
|
1822
|
+
returnJson: true,
|
|
1823
|
+
});
|
|
1824
|
+
this.loadingBarService.successAndHide();
|
|
1825
|
+
this.openFeedbackEvaluation(response.content);
|
|
1826
|
+
console.log('Performance analysis response:', response);
|
|
1827
|
+
return response;
|
|
1828
|
+
}
|
|
1829
|
+
openFeedbackEvaluation(data) {
|
|
1830
|
+
this.dialogService.open(FeedbackEvaluationComponent, {
|
|
1831
|
+
data,
|
|
1832
|
+
header: 'Evaluation Feedback',
|
|
1833
|
+
width: '70%',
|
|
1834
|
+
contentStyle: { height: '80vh', overflow: 'auto' },
|
|
1835
|
+
baseZIndex: 10000,
|
|
1836
|
+
closable: true,
|
|
1837
|
+
});
|
|
1838
|
+
}
|
|
1839
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: EvaluationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1840
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: EvaluationService, providedIn: 'root' }); }
|
|
1841
|
+
}
|
|
1842
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: EvaluationService, decorators: [{
|
|
1843
|
+
type: Injectable,
|
|
1844
|
+
args: [{
|
|
1845
|
+
providedIn: 'root',
|
|
1403
1846
|
}]
|
|
1404
1847
|
}] });
|
|
1405
1848
|
|
|
@@ -1407,6 +1850,7 @@ class ChatHeaderComponent {
|
|
|
1407
1850
|
constructor() {
|
|
1408
1851
|
this.isAdmin = input(false);
|
|
1409
1852
|
this.alternativeConversation = [];
|
|
1853
|
+
this.evaluationService = inject(EvaluationService);
|
|
1410
1854
|
this.restartConversationEvent = output();
|
|
1411
1855
|
this.showInfoEvent = output();
|
|
1412
1856
|
this.settingsClickEvent = output();
|
|
@@ -1424,12 +1868,15 @@ class ChatHeaderComponent {
|
|
|
1424
1868
|
complete() {
|
|
1425
1869
|
this.completeEvent.emit();
|
|
1426
1870
|
}
|
|
1871
|
+
openFeedback() {
|
|
1872
|
+
this.evaluationService.openFeedbackEvaluation();
|
|
1873
|
+
}
|
|
1427
1874
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1428
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatHeaderComponent, isStandalone: true, selector: "dc-chat-header", inputs: { isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, alternativeConversation: { classPropertyName: "alternativeConversation", publicName: "alternativeConversation", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { restartConversationEvent: "restartConversationEvent", showInfoEvent: "showInfoEvent", settingsClickEvent: "settingsClickEvent", completeEvent: "completeEvent" }, ngImport: i0, template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.title) {\n {{ agentCard.title }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.title }} </span>\n }\n\n <div class=\"header-controls\">\n @if (isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <i (click)=\"complete()\">\u26A1\uFE0F </i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n\n <!-- <span class=\"pointer\" (click)=\"showInfo()\"> \u26A1\uFE0F </span> -->\n </div>\n }\n\n <div>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
|
|
1875
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatHeaderComponent, isStandalone: true, selector: "dc-chat-header", inputs: { isAdmin: { classPropertyName: "isAdmin", publicName: "isAdmin", isSignal: true, isRequired: false, transformFunction: null }, alternativeConversation: { classPropertyName: "alternativeConversation", publicName: "alternativeConversation", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { restartConversationEvent: "restartConversationEvent", showInfoEvent: "showInfoEvent", settingsClickEvent: "settingsClickEvent", completeEvent: "completeEvent" }, ngImport: i0, template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.title) {\n {{ agentCard.title }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.title }} </span>\n }\n\n <div class=\"header-controls\">\n @if (isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <i (click)=\"complete()\">\u26A1\uFE0F </i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n\n <!-- <span class=\"pointer\" (click)=\"showInfo()\"> \u26A1\uFE0F </span> -->\n </div>\n }\n\n <div>\n <span class=\"pointer\" (click)=\"openFeedback()\"> \uD83D\uDCDD </span>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }] }); }
|
|
1429
1876
|
}
|
|
1430
1877
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatHeaderComponent, decorators: [{
|
|
1431
1878
|
type: Component,
|
|
1432
|
-
args: [{ selector: 'dc-chat-header', standalone: true, imports: [ButtonModule], template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.title) {\n {{ agentCard.title }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.title }} </span>\n }\n\n <div class=\"header-controls\">\n @if (isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <i (click)=\"complete()\">\u26A1\uFE0F </i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n\n <!-- <span class=\"pointer\" (click)=\"showInfo()\"> \u26A1\uFE0F </span> -->\n </div>\n }\n\n <div>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"] }]
|
|
1879
|
+
args: [{ selector: 'dc-chat-header', standalone: true, imports: [ButtonModule], template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.title) {\n {{ agentCard.title }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.title }} </span>\n }\n\n <div class=\"header-controls\">\n @if (isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <i (click)=\"complete()\">\u26A1\uFE0F </i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n\n <!-- <span class=\"pointer\" (click)=\"showInfo()\"> \u26A1\uFE0F </span> -->\n </div>\n }\n\n <div>\n <span class=\"pointer\" (click)=\"openFeedback()\"> \uD83D\uDCDD </span>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"] }]
|
|
1433
1880
|
}], propDecorators: { alternativeConversation: [{
|
|
1434
1881
|
type: Input
|
|
1435
1882
|
}], agentCard: [{
|
|
@@ -1802,208 +2249,163 @@ function buildObjectTTSRequest(message, settings = {}) {
|
|
|
1802
2249
|
};
|
|
1803
2250
|
}
|
|
1804
2251
|
|
|
1805
|
-
|
|
1806
|
-
function getContextMessages(messages, contextType) {
|
|
1807
|
-
const conversationMessages = messages.filter((message) => [ChatRole.User, ChatRole.Assistant].includes(message.role));
|
|
1808
|
-
if (conversationMessages.length === 0) {
|
|
1809
|
-
return [];
|
|
1810
|
-
}
|
|
1811
|
-
switch (contextType) {
|
|
1812
|
-
case ContextType.LastAssistantMessage: {
|
|
1813
|
-
const lastAssistant = conversationMessages
|
|
1814
|
-
.slice()
|
|
1815
|
-
.reverse()
|
|
1816
|
-
.find((m) => m.role === ChatRole.Assistant);
|
|
1817
|
-
return lastAssistant ? [lastAssistant] : [];
|
|
1818
|
-
}
|
|
1819
|
-
case ContextType.LastUserMessage: {
|
|
1820
|
-
const lastUser = conversationMessages
|
|
1821
|
-
.slice()
|
|
1822
|
-
.reverse()
|
|
1823
|
-
.find((m) => m.role === ChatRole.User);
|
|
1824
|
-
return lastUser ? [lastUser] : [];
|
|
1825
|
-
}
|
|
1826
|
-
case ContextType.LastDialog: {
|
|
1827
|
-
const lastUser = conversationMessages
|
|
1828
|
-
.slice()
|
|
1829
|
-
.reverse()
|
|
1830
|
-
.find((m) => m.role === ChatRole.User);
|
|
1831
|
-
const lastAssistant = conversationMessages
|
|
1832
|
-
.slice()
|
|
1833
|
-
.reverse()
|
|
1834
|
-
.find((m) => m.role === ChatRole.Assistant);
|
|
1835
|
-
const dialog = [];
|
|
1836
|
-
if (lastAssistant)
|
|
1837
|
-
dialog.push(lastAssistant);
|
|
1838
|
-
if (lastUser)
|
|
1839
|
-
dialog.push(lastUser);
|
|
1840
|
-
// Sort by timestamp if available, otherwise keep order [Assistant, User] if both exist
|
|
1841
|
-
// Assuming messageId or a timestamp property exists and is comparable
|
|
1842
|
-
// dialog.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)); // Example sorting
|
|
1843
|
-
return dialog;
|
|
1844
|
-
}
|
|
1845
|
-
case ContextType.Last2Dialogs: {
|
|
1846
|
-
// I think i have an error with this.
|
|
1847
|
-
const users = conversationMessages.filter((m) => m.role === ChatRole.User);
|
|
1848
|
-
const assistants = conversationMessages.filter((m) => m.role === ChatRole.Assistant);
|
|
1849
|
-
const lastTwoUsers = users.slice(-2);
|
|
1850
|
-
const lastTwoAssistants = assistants.slice(-2);
|
|
1851
|
-
const dialogs = [...lastTwoAssistants, ...lastTwoUsers];
|
|
1852
|
-
// Sort by timestamp if available
|
|
1853
|
-
// dialogs.sort((a, b) => (a.timestamp || 0) - (b.timestamp || 0)); // Example sorting
|
|
1854
|
-
return dialogs;
|
|
1855
|
-
}
|
|
1856
|
-
case ContextType.LastUserAndPreviousAssistant: {
|
|
1857
|
-
const lastUserIndex = conversationMessages.map((m) => m.role).lastIndexOf(ChatRole.User);
|
|
1858
|
-
// Not exactrly getting the last assistant will depend if conversation is one and one.
|
|
1859
|
-
if (lastUserIndex <= 0) {
|
|
1860
|
-
return [];
|
|
1861
|
-
}
|
|
1862
|
-
const messages = conversationMessages.slice(lastUserIndex - 1, lastUserIndex + 1);
|
|
1863
|
-
console.log('LastUserAndPreviousAssistant', messages);
|
|
1864
|
-
return messages;
|
|
1865
|
-
}
|
|
1866
|
-
case ContextType.AllConversation:
|
|
1867
|
-
default:
|
|
1868
|
-
return conversationMessages;
|
|
1869
|
-
}
|
|
1870
|
-
}
|
|
1871
|
-
|
|
1872
|
-
class EvaluationService {
|
|
2252
|
+
class DynamicCriteriaService {
|
|
1873
2253
|
constructor() {
|
|
1874
|
-
// Services
|
|
1875
|
-
this.defaultAgentCardService = inject(DefaultAgentCardsService);
|
|
1876
|
-
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
1877
2254
|
this.dynamicFlowService = inject(DynamicFlowService);
|
|
1878
|
-
|
|
1879
|
-
this.
|
|
1880
|
-
this.
|
|
1881
|
-
|
|
1882
|
-
async evaluateGoal(goalTask, messages) {
|
|
1883
|
-
if (!goalTask.task) {
|
|
1884
|
-
goalTask.task = 'Evaluate this conversation the goal is keep the conversation on topic consistency.';
|
|
1885
|
-
}
|
|
1886
|
-
const evaluator = {
|
|
1887
|
-
task: goalTask.task,
|
|
1888
|
-
expectedResponseType: 'Response should be in next JSON format: {"score": number, "text": string}, score is a number between 0 and 3, text is concrete feedback in less than 25 words.',
|
|
1889
|
-
model: goalTask.model || { quality: EModelQuality.FAST },
|
|
1890
|
-
};
|
|
1891
|
-
const evaluationResult = await this.evaluateConversation(messages, evaluator, ContextType.AllConversation);
|
|
1892
|
-
this.updateScore(evaluationResult.score || 0);
|
|
1893
|
-
console.log(' ♦️ Goal Evaluation Result:', evaluationResult, this.scoreSignal());
|
|
1894
|
-
// Evaluation can return evything check i can standarize this.
|
|
1895
|
-
this.toastService.info({
|
|
1896
|
-
title: 'Score ' + evaluationResult?.text,
|
|
1897
|
-
subtitle: `Added ${evaluationResult?.score} points`,
|
|
1898
|
-
});
|
|
1899
|
-
return evaluationResult;
|
|
2255
|
+
this.contextEngineService = inject(ContextEngineService);
|
|
2256
|
+
this.defaultAgentCardService = inject(DefaultAgentCardsService);
|
|
2257
|
+
this.globalToolsService = inject(GlobalToolsService);
|
|
2258
|
+
this.messageState = inject(MessagesStateService);
|
|
1900
2259
|
}
|
|
1901
|
-
async
|
|
1902
|
-
|
|
1903
|
-
const
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
// Create evaluation prompt
|
|
1907
|
-
let instructions = `
|
|
1908
|
-
Please replay to this task:
|
|
1909
|
-
${task.task}
|
|
1910
|
-
This is the conversation history:
|
|
1911
|
-
<Context>
|
|
1912
|
-
${conversationMessagesString}
|
|
1913
|
-
<End Context>
|
|
1914
|
-
`;
|
|
1915
|
-
if (task.expectedResponseType) {
|
|
1916
|
-
instructions += `\nExpected response type: ${task.expectedResponseType}`;
|
|
2260
|
+
async evaluateUsingTools() {
|
|
2261
|
+
const tools = this.dynamicFlowService.conversationFlowState()?.tools || [];
|
|
2262
|
+
const enabledTools = tools.filter((tool) => tool?.enabled || false);
|
|
2263
|
+
if (!enabledTools.length) {
|
|
2264
|
+
return;
|
|
1917
2265
|
}
|
|
1918
|
-
|
|
1919
|
-
|
|
2266
|
+
let listString = '';
|
|
2267
|
+
for (const tool of enabledTools) {
|
|
2268
|
+
listString += `${tool.name}: ${tool.description}\n`;
|
|
1920
2269
|
}
|
|
1921
|
-
|
|
1922
|
-
const
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
2270
|
+
const conversationContext = this.contextEngineService.getConversationContext(ContextType.Last2Messages);
|
|
2271
|
+
const finalPrompt = `
|
|
2272
|
+
Evaluate using the context and return only JSON if condition is met similar to this:
|
|
2273
|
+
{
|
|
2274
|
+
"tool1": true,
|
|
2275
|
+
"tool2": false,
|
|
2276
|
+
}
|
|
2277
|
+
<Context>
|
|
2278
|
+
${conversationContext}
|
|
2279
|
+
</Context>
|
|
2280
|
+
<Tools>
|
|
2281
|
+
${listString}
|
|
2282
|
+
</Tools>
|
|
2283
|
+
return only JSON with true or false for the tools
|
|
2284
|
+
`;
|
|
2285
|
+
const result = await this.defaultAgentCardService.callChatCompletion({
|
|
2286
|
+
messages: [{ role: ChatRole.User, content: finalPrompt }],
|
|
1926
2287
|
returnJson: true,
|
|
1927
|
-
model: task.model || { quality: EModelQuality.FAST },
|
|
1928
2288
|
});
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
const
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
2289
|
+
if (result.content?.['ends']) {
|
|
2290
|
+
console.log('Tools result:', result.content);
|
|
2291
|
+
console.log('Using tool ends');
|
|
2292
|
+
this.globalToolsService.useTool('ends', result.content);
|
|
2293
|
+
}
|
|
2294
|
+
}
|
|
2295
|
+
getMoodEmoji(mood) {
|
|
2296
|
+
if (!mood) {
|
|
2297
|
+
return undefined;
|
|
2298
|
+
}
|
|
2299
|
+
const moodState = MoodStateOptions.find((option) => option.value === mood);
|
|
2300
|
+
return moodState?.emoji;
|
|
2301
|
+
}
|
|
2302
|
+
async evaluateMoodState() {
|
|
2303
|
+
// Se asume que esto ocurré después de que el asistente responde. entonces el ultimo mensaje debe ser del asistente.
|
|
2304
|
+
const last2Dialog = this.contextEngineService.getContextMessages(ContextType.Last2Messages);
|
|
2305
|
+
const conversationContext = last2Dialog.map((message) => `${message.role}: ${message.content}`).join('\n');
|
|
2306
|
+
const assistantMessage = last2Dialog.find((message) => message.role === ChatRole.Assistant);
|
|
2307
|
+
const prompt = `${MOOD_STATE_PROMPT}\n\n<Context>${conversationContext}</Context>`;
|
|
2308
|
+
const result = await this.defaultAgentCardService.callChatCompletion({
|
|
2309
|
+
messages: [{ role: ChatRole.User, content: prompt }],
|
|
2310
|
+
returnJson: true,
|
|
2311
|
+
});
|
|
2312
|
+
if (Array.isArray(result.content)) {
|
|
2313
|
+
console.log('Mood state result:', result.content, assistantMessage);
|
|
2314
|
+
if (assistantMessage?.messageId) {
|
|
2315
|
+
const moodEmojis = result.content.map((mood) => this.getMoodEmoji(mood)).filter((emoji) => !!emoji);
|
|
2316
|
+
this.messageState.updateMessage(assistantMessage.messageId, { tags: moodEmojis });
|
|
1955
2317
|
}
|
|
1956
|
-
return
|
|
2318
|
+
return result.content;
|
|
1957
2319
|
}
|
|
1958
|
-
|
|
1959
|
-
console.error('
|
|
1960
|
-
return
|
|
2320
|
+
else {
|
|
2321
|
+
console.error('Something is wrong with mood state result:', result.content);
|
|
2322
|
+
return [];
|
|
1961
2323
|
}
|
|
1962
2324
|
}
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
2325
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicCriteriaService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2326
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicCriteriaService, providedIn: 'root' }); }
|
|
2327
|
+
}
|
|
2328
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicCriteriaService, decorators: [{
|
|
2329
|
+
type: Injectable,
|
|
2330
|
+
args: [{
|
|
2331
|
+
providedIn: 'root',
|
|
2332
|
+
}]
|
|
2333
|
+
}] });
|
|
2334
|
+
|
|
2335
|
+
class DynamicFlowTaskService {
|
|
2336
|
+
constructor() {
|
|
2337
|
+
this.dynamicFlowService = inject(DynamicFlowService);
|
|
2338
|
+
this.evaluationService = inject(EvaluationService);
|
|
2339
|
+
this.messagesStateService = inject(MessagesStateService);
|
|
2340
|
+
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
2341
|
+
}
|
|
2342
|
+
async evaluateAssistantTaskTrigger(message) {
|
|
2343
|
+
const userChatSettings = this.userDataExchange.getUserChatSettings();
|
|
2344
|
+
if (!userChatSettings.assistantMessageTask) {
|
|
2345
|
+
return;
|
|
1971
2346
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
2347
|
+
const conversationFlow = this.dynamicFlowService.conversationFlowState();
|
|
2348
|
+
if (!conversationFlow)
|
|
2349
|
+
return;
|
|
2350
|
+
const dynamicFlowTask = conversationFlow.triggerTasks.onAssistantMessage;
|
|
2351
|
+
console.log('Trigger:', dynamicFlowTask);
|
|
2352
|
+
if (dynamicFlowTask && message.messageId) {
|
|
2353
|
+
const messageId = message.messageId;
|
|
2354
|
+
// const contextMessages = this.contextEngineService.getContextMessages(this.messagesStateService.getMessagesSignal()(), ContextType.LastAssistantMessage);
|
|
2355
|
+
// i cant override task in trigger.
|
|
2356
|
+
const task = dynamicFlowTask.task + ' Here is the text: ' + (message.text || message.content);
|
|
2357
|
+
const result = await this.evaluationService.evaluateWithTask({ model: dynamicFlowTask.model, task });
|
|
2358
|
+
console.log('Assistant trigger evaluation result:', result);
|
|
2359
|
+
message.evaluation = result;
|
|
2360
|
+
this.messagesStateService.updateMessage(messageId, message);
|
|
1975
2361
|
}
|
|
1976
2362
|
}
|
|
1977
|
-
|
|
1978
|
-
this.
|
|
2363
|
+
async evaluateUserTaskTrigger(message) {
|
|
2364
|
+
const conversationFlow = this.dynamicFlowService.conversationFlowState();
|
|
2365
|
+
if (!conversationFlow)
|
|
2366
|
+
return;
|
|
2367
|
+
const goal = conversationFlow.goal;
|
|
2368
|
+
// 1) Run Goal Evaluation
|
|
2369
|
+
// TODO probably i need a different method for the goal.
|
|
2370
|
+
this.evaluationService.evaluateGoal(goal);
|
|
2371
|
+
// 2) Run User Trigger Evaluation only if user allows it
|
|
2372
|
+
const chatUserSettings = this.userDataExchange.getUserChatSettings();
|
|
2373
|
+
if (chatUserSettings.userMessageTask) {
|
|
2374
|
+
const userTriggerTask = conversationFlow.triggerTasks.onUserMessage;
|
|
2375
|
+
// TODO: Siento MUY Forzado el utilizar evaluateConversation, ese es del goal, pero lo quize hacer general!
|
|
2376
|
+
if (userTriggerTask && message.messageId) {
|
|
2377
|
+
const messageId = message.messageId;
|
|
2378
|
+
userTriggerTask.task =
|
|
2379
|
+
'Evaluate User Conversation and give feedback in user native language, fix grammar remark improvements. do explanation in less than 25 words.';
|
|
2380
|
+
const evaluation = await this.evaluationService.evaluateConversation(userTriggerTask, ContextType.Last2Messages);
|
|
2381
|
+
message.evaluation = evaluation;
|
|
2382
|
+
this.messagesStateService.updateMessage(messageId, message);
|
|
2383
|
+
console.log('Trigger evaluation result:', evaluation);
|
|
2384
|
+
}
|
|
2385
|
+
}
|
|
1979
2386
|
}
|
|
1980
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
1981
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
2387
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicFlowTaskService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2388
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicFlowTaskService, providedIn: 'root' }); }
|
|
1982
2389
|
}
|
|
1983
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
2390
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DynamicFlowTaskService, decorators: [{
|
|
1984
2391
|
type: Injectable,
|
|
1985
2392
|
args: [{
|
|
1986
2393
|
providedIn: 'root',
|
|
1987
2394
|
}]
|
|
1988
2395
|
}] });
|
|
1989
2396
|
|
|
1990
|
-
const EvaluationStructureString = `
|
|
1991
|
-
{
|
|
1992
|
-
"text": "",
|
|
1993
|
-
"score": 0,
|
|
1994
|
-
}
|
|
1995
|
-
`;
|
|
1996
2397
|
class ConversationService {
|
|
1997
2398
|
constructor() {
|
|
1998
2399
|
this.defaultAgentCardService = inject(DefaultAgentCardsService);
|
|
1999
2400
|
// Services
|
|
2000
2401
|
this.toastAlerts = inject(TOAST_ALERTS_TOKEN);
|
|
2001
2402
|
this.messageProcessingService = inject(MessageProcessingService);
|
|
2002
|
-
this.conversationBuilder = inject(
|
|
2403
|
+
this.conversationBuilder = inject(ConversationPromptBuilderService);
|
|
2003
2404
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
2004
|
-
this.evaluationService = inject(EvaluationService);
|
|
2005
2405
|
this.messagesStateService = inject(MessagesStateService);
|
|
2006
2406
|
this.dynamicFlowService = inject(DynamicFlowService);
|
|
2407
|
+
this.dynamicCriteriaService = inject(DynamicCriteriaService);
|
|
2408
|
+
this.dynamicFlowTaskService = inject(DynamicFlowTaskService);
|
|
2007
2409
|
// State Signals
|
|
2008
2410
|
this.isThinkingSignal = signal(false);
|
|
2009
2411
|
this.conversationSettingsState = signal(null);
|
|
@@ -2048,7 +2450,7 @@ class ConversationService {
|
|
|
2048
2450
|
conversationSettings.model = userSettings.model;
|
|
2049
2451
|
}
|
|
2050
2452
|
}
|
|
2051
|
-
setupConversationWithAgentCard(agentCard, parseDict = null,
|
|
2453
|
+
setupConversationWithAgentCard(agentCard, parseDict = null, appConversationFlow = null) {
|
|
2052
2454
|
// Basically extract settings and flow from agent card, and overrider with user seetings is needed.
|
|
2053
2455
|
this.avatarImages.assistantImg = agentCard?.assets?.image?.url || this.avatarImages.assistantImg; // Set user AI avatar image
|
|
2054
2456
|
// Aqui es la parte crucial de los settings definir prioridad.
|
|
@@ -2056,31 +2458,35 @@ class ConversationService {
|
|
|
2056
2458
|
// Here i need some rules to see when i will override and what.
|
|
2057
2459
|
this.overrideSettingsByUserSettings(conversationSettings);
|
|
2058
2460
|
this.conversationSettingsState.set(conversationSettings);
|
|
2059
|
-
//
|
|
2060
|
-
|
|
2461
|
+
// 🙄 Puede que no me sirva esta estrategía, mezcla agentCard.conversationFlow con appConversationFlow, pero le da prioridad a agent card, si no existe toma el default
|
|
2462
|
+
// La otra estretegía es: tomar solo agentCard o appConversationFlow, pero no ambos
|
|
2463
|
+
if (appConversationFlow) {
|
|
2061
2464
|
// Just replace the default if agent card has a value
|
|
2062
2465
|
if (agentCard.conversationFlow) {
|
|
2063
2466
|
if (agentCard.conversationFlow?.goal?.task) {
|
|
2064
|
-
|
|
2467
|
+
appConversationFlow.goal = agentCard.conversationFlow.goal;
|
|
2065
2468
|
}
|
|
2066
2469
|
if (agentCard.conversationFlow?.dynamicConditions) {
|
|
2067
|
-
|
|
2470
|
+
appConversationFlow.dynamicConditions = agentCard.conversationFlow.dynamicConditions;
|
|
2068
2471
|
}
|
|
2069
2472
|
if (agentCard.conversationFlow?.triggerTasks) {
|
|
2070
2473
|
// Leave default if a concreate task is not provided.
|
|
2071
|
-
if (
|
|
2072
|
-
|
|
2474
|
+
if (appConversationFlow.triggerTasks?.onUserMessage?.task) {
|
|
2475
|
+
appConversationFlow.triggerTasks.onUserMessage = agentCard.conversationFlow.triggerTasks.onUserMessage;
|
|
2073
2476
|
}
|
|
2074
2477
|
if (agentCard.conversationFlow.triggerTasks?.onUserMessage?.task) {
|
|
2075
|
-
|
|
2478
|
+
appConversationFlow.triggerTasks.onUserMessage = agentCard.conversationFlow.triggerTasks.onUserMessage;
|
|
2076
2479
|
}
|
|
2077
|
-
|
|
2480
|
+
appConversationFlow.triggerTasks = { ...agentCard.conversationFlow.triggerTasks, ...appConversationFlow.triggerTasks };
|
|
2078
2481
|
}
|
|
2079
|
-
if (agentCard.conversationFlow?.
|
|
2080
|
-
|
|
2482
|
+
if (agentCard.conversationFlow?.challenges) {
|
|
2483
|
+
appConversationFlow.challenges = agentCard.conversationFlow.challenges;
|
|
2484
|
+
}
|
|
2485
|
+
if (agentCard.conversationFlow?.tools?.length) {
|
|
2486
|
+
appConversationFlow.tools = agentCard.conversationFlow.tools;
|
|
2081
2487
|
}
|
|
2082
2488
|
}
|
|
2083
|
-
this.dynamicFlowService.setConversationFlow(
|
|
2489
|
+
this.dynamicFlowService.setConversationFlow(appConversationFlow);
|
|
2084
2490
|
}
|
|
2085
2491
|
}
|
|
2086
2492
|
async initConversationWithSettings(conversationSettings, conversationFlow) {
|
|
@@ -2111,16 +2517,17 @@ class ConversationService {
|
|
|
2111
2517
|
if (messageIndex !== -1) {
|
|
2112
2518
|
conversationSettings.messages[messageIndex] = processedMessage;
|
|
2113
2519
|
}
|
|
2114
|
-
this.
|
|
2520
|
+
this.dynamicFlowTaskService.evaluateAssistantTaskTrigger(firstAssistantMsg);
|
|
2115
2521
|
}
|
|
2116
2522
|
else if (conversationSettings?.autoStart) {
|
|
2117
2523
|
// Auto-start conversation if configured
|
|
2118
|
-
await this.
|
|
2524
|
+
await this.requestAssistantConversationResponse();
|
|
2119
2525
|
}
|
|
2120
2526
|
}
|
|
2121
2527
|
// Initialize conversation
|
|
2122
|
-
async initConversationWithAgentCard(agentCard, parseDict = null,
|
|
2123
|
-
this
|
|
2528
|
+
async initConversationWithAgentCard(agentCard, parseDict = null, appConversationFlow = null) {
|
|
2529
|
+
// TODO: fix this agentCard appConversationFlow only applies if appConversationFlow is null, check later
|
|
2530
|
+
this.setupConversationWithAgentCard(agentCard, parseDict, appConversationFlow);
|
|
2124
2531
|
await this.initConversation();
|
|
2125
2532
|
}
|
|
2126
2533
|
/**
|
|
@@ -2160,9 +2567,9 @@ class ConversationService {
|
|
|
2160
2567
|
this.isThinkingSignal.set(true);
|
|
2161
2568
|
let assistantMessageId = null;
|
|
2162
2569
|
// Trigger are asyn Run triggers in background
|
|
2163
|
-
this.
|
|
2570
|
+
this.dynamicFlowTaskService.evaluateUserTaskTrigger({ messageId: userMessageId, role: ChatRole.User });
|
|
2164
2571
|
try {
|
|
2165
|
-
assistantMessageId = await this.
|
|
2572
|
+
assistantMessageId = await this.requestAssistantConversationResponse();
|
|
2166
2573
|
}
|
|
2167
2574
|
catch (error) {
|
|
2168
2575
|
console.error('Error sending conversation to AI:', error);
|
|
@@ -2174,12 +2581,11 @@ class ConversationService {
|
|
|
2174
2581
|
return { userMessageId, assistantMessageId };
|
|
2175
2582
|
}
|
|
2176
2583
|
// Send current conversation to AI
|
|
2177
|
-
async
|
|
2584
|
+
async requestAssistantConversationResponse() {
|
|
2178
2585
|
if (this.isDestroyedSignal()) {
|
|
2179
2586
|
return null;
|
|
2180
2587
|
}
|
|
2181
2588
|
const messages = this.messagesStateService.getMessagesSignal()();
|
|
2182
|
-
const conversationSettings = this.conversationSettingsState();
|
|
2183
2589
|
if (messages.length > 31) {
|
|
2184
2590
|
// Safety limit to prevent infinite conversations
|
|
2185
2591
|
this.toastAlerts.warn({
|
|
@@ -2188,8 +2594,9 @@ class ConversationService {
|
|
|
2188
2594
|
});
|
|
2189
2595
|
return null;
|
|
2190
2596
|
}
|
|
2597
|
+
const conversationSettings = this.conversationSettingsState();
|
|
2191
2598
|
let conversationMessages = messages;
|
|
2192
|
-
// Add last prompt if available
|
|
2599
|
+
// Add last prompt (JailBreak) if available
|
|
2193
2600
|
if (conversationSettings.last_prompt) {
|
|
2194
2601
|
conversationMessages = [...messages, { content: conversationSettings.last_prompt, role: ChatRole.System }];
|
|
2195
2602
|
}
|
|
@@ -2210,54 +2617,21 @@ class ConversationService {
|
|
|
2210
2617
|
const newMessage = this.messageProcessingService.processMessage({ content: response.content, role: ChatRole.Assistant }, conversationSettings, this.avatarImages);
|
|
2211
2618
|
this.messagesStateService.addMessage(newMessage);
|
|
2212
2619
|
this.isThinkingSignal.set(false);
|
|
2213
|
-
|
|
2620
|
+
// Run Dynamic Flow Evaluations
|
|
2621
|
+
this.dynamicFlowTaskService.evaluateAssistantTaskTrigger(newMessage); // Not waiting should be parallel.
|
|
2622
|
+
// this.dynamicCriteriaService.evaluateUsingTools();
|
|
2623
|
+
this.dynamicCriteriaService.evaluateMoodState();
|
|
2214
2624
|
return newMessage.messageId;
|
|
2215
2625
|
}
|
|
2216
2626
|
// Reset conversation
|
|
2217
|
-
async resetConversation(agentCard) {
|
|
2218
|
-
// Clear messages
|
|
2219
|
-
this.messagesStateService.clearMessages();
|
|
2220
|
-
}
|
|
2221
|
-
async getTTSFile(message) {
|
|
2222
|
-
const userChatSettings = await this.userDataExchange.getUserChatSettings();
|
|
2223
|
-
const ttsRequest = buildObjectTTSRequest(message, userChatSettings);
|
|
2224
|
-
return this.defaultAgentCardService.getTextAudioFile(ttsRequest);
|
|
2225
|
-
}
|
|
2226
|
-
async runAssistantTrigger(message) {
|
|
2227
|
-
const userChatSettings = this.userDataExchange.getUserChatSettings();
|
|
2228
|
-
if (!userChatSettings.assistantMessageTask) {
|
|
2229
|
-
return;
|
|
2230
|
-
}
|
|
2231
|
-
const trigger = this.dynamicFlowService.conversationFlowState().triggerTasks.onAssistantMessage;
|
|
2232
|
-
console.log('Trigger:', trigger);
|
|
2233
|
-
if (trigger) {
|
|
2234
|
-
// const contextMessages = getContextMessages(this.messagesSignal(), ContextType.LastAssistantMessage);
|
|
2235
|
-
// i cant override task in trigger.
|
|
2236
|
-
const task = trigger.task + ' Here is the text: ' + (message.text || message.content);
|
|
2237
|
-
const result = await this.evaluationService.evaluateWithTask({ model: trigger.model, task });
|
|
2238
|
-
console.log('Assistant trigger evaluation result:', result);
|
|
2239
|
-
message.evaluation = result;
|
|
2240
|
-
this.messagesStateService.updateMessage(message.messageId, message);
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
async runUserFlowEvaluations(message) {
|
|
2244
|
-
const goal = this.dynamicFlowService.conversationFlowState().goal;
|
|
2245
|
-
// 1) Run Goal Evaluation
|
|
2246
|
-
this.evaluationService.evaluateGoal(goal, this.messagesStateService.getMessagesSignal()());
|
|
2247
|
-
// 2) Run User Trigger Evaluation only if user allows it
|
|
2248
|
-
const chatUserSettings = this.userDataExchange.getUserChatSettings();
|
|
2249
|
-
if (chatUserSettings.userMessageTask) {
|
|
2250
|
-
const trigger = this.dynamicFlowService.conversationFlowState().triggerTasks.onUserMessage;
|
|
2251
|
-
if (trigger) {
|
|
2252
|
-
this.evaluationService
|
|
2253
|
-
.evaluateConversation(this.messagesStateService.getMessagesSignal()(), trigger, ContextType.LastUserAndPreviousAssistant)
|
|
2254
|
-
.then((evaluation) => {
|
|
2255
|
-
message.evaluation = evaluation;
|
|
2256
|
-
this.messagesStateService.updateMessage(message.messageId, message);
|
|
2257
|
-
console.log('Trigger evaluation result:', evaluation);
|
|
2258
|
-
});
|
|
2259
|
-
}
|
|
2260
|
-
}
|
|
2627
|
+
async resetConversation(agentCard) {
|
|
2628
|
+
// Clear messages
|
|
2629
|
+
this.messagesStateService.clearMessages();
|
|
2630
|
+
}
|
|
2631
|
+
async getTTSFile(message) {
|
|
2632
|
+
const userChatSettings = await this.userDataExchange.getUserChatSettings();
|
|
2633
|
+
const ttsRequest = buildObjectTTSRequest(message, userChatSettings);
|
|
2634
|
+
return this.defaultAgentCardService.getTextAudioFile(ttsRequest);
|
|
2261
2635
|
}
|
|
2262
2636
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2263
2637
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationService, providedIn: 'root' }); }
|
|
@@ -2400,7 +2774,7 @@ class ChatFooterComponent {
|
|
|
2400
2774
|
}
|
|
2401
2775
|
}
|
|
2402
2776
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2403
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", isSignal: true, isRequired: false, transformFunction: null }, flow: { classPropertyName: "flow", publicName: "flow", isSignal: true, isRequired: false, transformFunction: null }, micSettings: { classPropertyName: "micSettings", publicName: "micSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", textInputChanged: "textInputChanged" }, viewQueries: [{ propertyName: "micComponent", first: true, predicate: MicVadComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <dc-mic (onFinished)=\"handleAudioRecorded($event)\"></dc-mic>\n <!-- \n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" /> -->\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"prepareUserMsnAndSend()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"prepareUserMsnAndSend()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(flow()?.goal) {\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$1.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished"] }] }); }
|
|
2777
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", isSignal: true, isRequired: false, transformFunction: null }, flow: { classPropertyName: "flow", publicName: "flow", isSignal: true, isRequired: false, transformFunction: null }, micSettings: { classPropertyName: "micSettings", publicName: "micSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", textInputChanged: "textInputChanged" }, viewQueries: [{ propertyName: "micComponent", first: true, predicate: MicVadComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <dc-mic (onFinished)=\"handleAudioRecorded($event)\"></dc-mic>\n <!-- \n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" /> -->\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"prepareUserMsnAndSend()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"prepareUserMsnAndSend()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(flow()?.goal) {\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$1.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished"] }] }); }
|
|
2404
2778
|
}
|
|
2405
2779
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, decorators: [{
|
|
2406
2780
|
type: Component,
|
|
@@ -2538,70 +2912,55 @@ function extractTags(text) {
|
|
|
2538
2912
|
return result;
|
|
2539
2913
|
}
|
|
2540
2914
|
|
|
2541
|
-
class
|
|
2915
|
+
class MessageContentDisplayer {
|
|
2542
2916
|
constructor() {
|
|
2543
2917
|
// Inputs
|
|
2544
|
-
this.message = input.required();
|
|
2918
|
+
this.message = input.required();
|
|
2545
2919
|
// Outputs
|
|
2546
2920
|
this.playAudio = output();
|
|
2547
2921
|
this.audioCompleted = output();
|
|
2548
|
-
this.wordClicked = output();
|
|
2922
|
+
this.wordClicked = output();
|
|
2549
2923
|
// Signal States
|
|
2550
|
-
this.wordWithMeta = signal([]);
|
|
2551
|
-
this.
|
|
2924
|
+
this.wordWithMeta = signal([]);
|
|
2925
|
+
this.audioState = signal('idle');
|
|
2552
2926
|
this.alreadyPlayed = false;
|
|
2553
2927
|
// Signals State computed from the input message
|
|
2554
2928
|
this.wordsWithMetaState = [];
|
|
2555
2929
|
this.iconState = computed(() => {
|
|
2556
|
-
if (this.
|
|
2557
|
-
return '
|
|
2930
|
+
if (this.message()?.isLoading) {
|
|
2931
|
+
return 'loading';
|
|
2558
2932
|
}
|
|
2559
|
-
|
|
2560
|
-
|
|
2933
|
+
const state = this.audioState();
|
|
2934
|
+
if (state === 'playing' || state === 'paused') {
|
|
2935
|
+
return state;
|
|
2561
2936
|
}
|
|
2562
|
-
|
|
2937
|
+
if (this.message()?.audioUrl) {
|
|
2563
2938
|
return 'playable';
|
|
2564
2939
|
}
|
|
2565
|
-
|
|
2566
|
-
return 'idle';
|
|
2567
|
-
}
|
|
2940
|
+
return 'idle';
|
|
2568
2941
|
});
|
|
2569
|
-
this.isLoading = computed(() => this.message()?.isLoading);
|
|
2570
2942
|
this.shouldPlayAudio = computed(() => !!this.message() && this.message()?.shouldPlayAudio);
|
|
2571
|
-
// Computed signal for message text
|
|
2572
2943
|
this.messageText = computed(() => {
|
|
2573
|
-
const msg = this.message();
|
|
2944
|
+
const msg = this.message();
|
|
2574
2945
|
return msg?.text || msg?.content || 'N/A';
|
|
2575
2946
|
});
|
|
2576
|
-
this.classTag = computed(() => this.message()?.tag);
|
|
2577
|
-
// Computed signal for transcription availability
|
|
2947
|
+
this.classTag = computed(() => this.message()?.tag);
|
|
2578
2948
|
this.hasTranscription = computed(() => {
|
|
2579
|
-
|
|
2580
|
-
return hasTranscription;
|
|
2949
|
+
return !!this.message()?.transcriptionTimestamps && this.message()?.transcriptionTimestamps.length > 0;
|
|
2581
2950
|
});
|
|
2582
|
-
this.audioElement = null;
|
|
2583
|
-
this.destroy$ = new Subject();
|
|
2584
|
-
// Inject services
|
|
2951
|
+
this.audioElement = null;
|
|
2952
|
+
this.destroy$ = new Subject();
|
|
2585
2953
|
this.destroyRef = inject(DestroyRef);
|
|
2586
|
-
// Effect to react to message changes and re-initialize
|
|
2587
2954
|
effect(() => {
|
|
2588
|
-
const currentMsg = this.message();
|
|
2589
|
-
|
|
2590
|
-
if (currentMsg && !this.isPlaying() && !this.alreadyPlayed) {
|
|
2591
|
-
console.log('Cambio en message:', currentMsg);
|
|
2955
|
+
const currentMsg = this.message();
|
|
2956
|
+
if (currentMsg && this.audioState() !== 'playing' && !this.alreadyPlayed) {
|
|
2592
2957
|
this.initializeBasedOnMessage(currentMsg);
|
|
2593
|
-
// Check if shouldPlayAudio flag is set
|
|
2594
2958
|
if (currentMsg.shouldPlayAudio) {
|
|
2595
2959
|
this.startAudioPlayback();
|
|
2596
2960
|
}
|
|
2597
2961
|
}
|
|
2598
|
-
else {
|
|
2599
|
-
// this.cleanupAudio();
|
|
2600
|
-
}
|
|
2601
2962
|
});
|
|
2602
|
-
// Keep the effect for highlightedWords for now, might be redundant if template binds directly
|
|
2603
2963
|
effect(() => {
|
|
2604
|
-
// some how i need to isolate the reading, becouse reading in main effect is very dangerous since later is set and produces infinite loop
|
|
2605
2964
|
this.wordsWithMetaState = this.wordWithMeta();
|
|
2606
2965
|
});
|
|
2607
2966
|
}
|
|
@@ -2614,70 +2973,50 @@ class TextHighlighterComponent {
|
|
|
2614
2973
|
this.cleanupAudio();
|
|
2615
2974
|
}
|
|
2616
2975
|
initializeBasedOnMessage(msg) {
|
|
2617
|
-
console.log('Initializing based on message:', msg);
|
|
2618
|
-
// Initialize or cleanup audio based on URL presence and change
|
|
2619
2976
|
if (msg.audioUrl && (!this.audioElement || this.audioElement.src !== msg.audioUrl)) {
|
|
2620
|
-
this.initializeAudio(msg.audioUrl);
|
|
2977
|
+
this.initializeAudio(msg.audioUrl);
|
|
2621
2978
|
}
|
|
2622
2979
|
else if (!msg.audioUrl && this.audioElement) {
|
|
2623
2980
|
this.cleanupAudio();
|
|
2624
2981
|
}
|
|
2625
|
-
else if (!msg.audioUrl) {
|
|
2626
|
-
// No audio URL and no audio element - just log a warning instead of throwing an error
|
|
2627
|
-
console.warn('No audioUrl provided in the message. Audio playback will not be available.');
|
|
2628
|
-
}
|
|
2629
|
-
// Initialize words and sync based on transcription presence
|
|
2630
2982
|
if (this.hasTranscription()) {
|
|
2631
2983
|
const wordsAndTimestamps = [];
|
|
2632
|
-
// NOTE: This merge is only going to work if transcriptionTimestamps and wordsWithMetaState have the same length
|
|
2633
|
-
// wordsWithMetaState is initialized here in initializePlainTextWords but transcriptionTimestamps in the father, check later if i have bugs.
|
|
2634
2984
|
msg?.transcriptionTimestamps?.forEach((word, index) => {
|
|
2635
2985
|
wordsAndTimestamps.push({ ...word, ...this.wordsWithMetaState[index], index });
|
|
2636
2986
|
});
|
|
2637
|
-
|
|
2638
|
-
this.subcribeToAudioSync(wordsAndTimestamps); // Pass timestamps
|
|
2987
|
+
this.subcribeToAudioSync(wordsAndTimestamps);
|
|
2639
2988
|
}
|
|
2640
2989
|
else {
|
|
2641
2990
|
this.subscribeToEndAudio();
|
|
2642
|
-
this.initializePlainTextWords(msg.text || msg.content || '');
|
|
2991
|
+
this.initializePlainTextWords(msg.text || msg.content || '');
|
|
2643
2992
|
}
|
|
2644
2993
|
}
|
|
2645
2994
|
initializeAudio(audioUrl) {
|
|
2646
2995
|
this.cleanupAudio();
|
|
2647
|
-
this.audioElement = new Audio(audioUrl);
|
|
2996
|
+
this.audioElement = new Audio(audioUrl);
|
|
2997
|
+
this.audioState.set('playable');
|
|
2648
2998
|
}
|
|
2649
2999
|
subcribeToAudioSync(timestamps) {
|
|
2650
|
-
if (!this.audioElement)
|
|
2651
|
-
// Guard against missing audio element
|
|
3000
|
+
if (!this.audioElement)
|
|
2652
3001
|
return;
|
|
2653
|
-
|
|
2654
|
-
this.destroy$.next(); // Signal previous subscriptions to complete
|
|
2655
|
-
console.log('Subscribing to audio sync with timestamps:', timestamps);
|
|
3002
|
+
this.destroy$.next();
|
|
2656
3003
|
fromEvent(this.audioElement, 'timeupdate')
|
|
2657
|
-
.pipe(takeUntilDestroyed(this.destroyRef), takeUntil(this.destroy$),
|
|
2658
|
-
map(() => this.audioElement?.currentTime || 0))
|
|
3004
|
+
.pipe(takeUntilDestroyed(this.destroyRef), takeUntil(this.destroy$), map(() => this.audioElement?.currentTime || 0))
|
|
2659
3005
|
.subscribe((currentTime) => {
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
});
|
|
3006
|
+
const updatedWords = timestamps.map((word, index) => ({
|
|
3007
|
+
word: word.word,
|
|
3008
|
+
index,
|
|
3009
|
+
isHighlighted: currentTime >= word.start - 0.15 && currentTime < word.end + 0.15,
|
|
3010
|
+
tag: word.tag,
|
|
3011
|
+
}));
|
|
2666
3012
|
this.wordWithMeta.set(updatedWords);
|
|
2667
3013
|
});
|
|
2668
|
-
// Listen to ended event for cleanup
|
|
2669
3014
|
fromEvent(this.audioElement, 'ended')
|
|
2670
3015
|
.pipe(takeUntilDestroyed(this.destroyRef), takeUntil(this.destroy$))
|
|
2671
3016
|
.subscribe(() => {
|
|
2672
|
-
|
|
2673
|
-
const resetWords = this.wordWithMeta().map((word) => ({
|
|
2674
|
-
// Read current words signal
|
|
2675
|
-
...word,
|
|
2676
|
-
isHighlighted: false,
|
|
2677
|
-
}));
|
|
3017
|
+
const resetWords = this.wordWithMeta().map((word) => ({ ...word, isHighlighted: false }));
|
|
2678
3018
|
this.wordWithMeta.set(resetWords);
|
|
2679
|
-
|
|
2680
|
-
this.isPlaying.set(false);
|
|
3019
|
+
this.audioState.set('playable');
|
|
2681
3020
|
const currentMsg = this.message();
|
|
2682
3021
|
if (currentMsg) {
|
|
2683
3022
|
this.cleanupAudio();
|
|
@@ -2687,15 +3026,12 @@ class TextHighlighterComponent {
|
|
|
2687
3026
|
});
|
|
2688
3027
|
}
|
|
2689
3028
|
subscribeToEndAudio() {
|
|
2690
|
-
if (!this.audioElement)
|
|
3029
|
+
if (!this.audioElement)
|
|
2691
3030
|
return;
|
|
2692
|
-
}
|
|
2693
3031
|
fromEvent(this.audioElement, 'ended')
|
|
2694
3032
|
.pipe(takeUntilDestroyed(this.destroyRef), takeUntil(this.destroy$))
|
|
2695
3033
|
.subscribe(() => {
|
|
2696
|
-
|
|
2697
|
-
this.isPlaying.set(false);
|
|
2698
|
-
// Emit audio completed event with the current message
|
|
3034
|
+
this.audioState.set('playable');
|
|
2699
3035
|
const currentMsg = this.message();
|
|
2700
3036
|
if (currentMsg) {
|
|
2701
3037
|
this.cleanupAudio();
|
|
@@ -2704,53 +3040,36 @@ class TextHighlighterComponent {
|
|
|
2704
3040
|
}
|
|
2705
3041
|
});
|
|
2706
3042
|
}
|
|
2707
|
-
/**
|
|
2708
|
-
* Clean up audio element and event listeners
|
|
2709
|
-
*/
|
|
2710
3043
|
cleanupAudio() {
|
|
2711
3044
|
if (this.audioElement) {
|
|
2712
3045
|
this.audioElement.pause();
|
|
2713
|
-
this.audioElement.removeAttribute('src');
|
|
3046
|
+
this.audioElement.removeAttribute('src');
|
|
2714
3047
|
this.audioElement = null;
|
|
2715
|
-
this.destroy$.next();
|
|
2716
|
-
|
|
2717
|
-
const resetWords = this.wordWithMeta().map((word) => ({
|
|
2718
|
-
...word,
|
|
2719
|
-
isHighlighted: false,
|
|
2720
|
-
}));
|
|
3048
|
+
this.destroy$.next();
|
|
3049
|
+
const resetWords = this.wordWithMeta().map((word) => ({ ...word, isHighlighted: false }));
|
|
2721
3050
|
this.wordWithMeta.set(resetWords);
|
|
2722
3051
|
}
|
|
3052
|
+
this.audioState.set('idle');
|
|
2723
3053
|
}
|
|
2724
|
-
/**
|
|
2725
|
-
* Play or pause the audio
|
|
2726
|
-
*/
|
|
2727
3054
|
onPlayMessage() {
|
|
2728
|
-
|
|
2729
|
-
const currentMsg = this.message(); // Read signal
|
|
3055
|
+
const currentMsg = this.message();
|
|
2730
3056
|
if (this.audioElement) {
|
|
2731
3057
|
if (this.audioElement.paused) {
|
|
2732
3058
|
this.startAudioPlayback();
|
|
2733
3059
|
}
|
|
2734
3060
|
else {
|
|
2735
3061
|
this.audioElement.pause();
|
|
3062
|
+
this.audioState.set('paused');
|
|
2736
3063
|
}
|
|
2737
3064
|
}
|
|
2738
3065
|
else if (currentMsg?.audioUrl) {
|
|
2739
|
-
|
|
2740
|
-
// the effect should create it. Clicking play might need to ensure init runs.
|
|
2741
|
-
// For simplicity, let's re-call initializeAudio here if needed,
|
|
2742
|
-
// though ideally the effect handles it.
|
|
2743
|
-
this.initializeAudio(currentMsg.audioUrl); // Ensure it's created if somehow missed
|
|
3066
|
+
this.initializeAudio(currentMsg.audioUrl);
|
|
2744
3067
|
this.startAudioPlayback();
|
|
2745
3068
|
}
|
|
2746
3069
|
else if (currentMsg) {
|
|
2747
|
-
|
|
2748
|
-
this.playAudio.emit(currentMsg); // Emit the message value
|
|
3070
|
+
this.playAudio.emit(currentMsg);
|
|
2749
3071
|
}
|
|
2750
3072
|
}
|
|
2751
|
-
/**
|
|
2752
|
-
* Initialize plain text words by splitting the message text
|
|
2753
|
-
*/
|
|
2754
3073
|
initializePlainTextWords(text) {
|
|
2755
3074
|
const words = extractTags(text);
|
|
2756
3075
|
const plainWords = words.map((word, index) => ({
|
|
@@ -2763,11 +3082,8 @@ class TextHighlighterComponent {
|
|
|
2763
3082
|
}
|
|
2764
3083
|
onWordClick(wordData) {
|
|
2765
3084
|
const currentMsg = this.message();
|
|
2766
|
-
if (!currentMsg)
|
|
2767
|
-
console.warn('Cannot emit wordClicked: message input is not available.');
|
|
3085
|
+
if (!currentMsg)
|
|
2768
3086
|
return;
|
|
2769
|
-
}
|
|
2770
|
-
// Determine the correct data structure based on input type
|
|
2771
3087
|
const clickedWord = 'isHighlighted' in wordData
|
|
2772
3088
|
? { word: wordData.word, index: wordData.index, messageId: currentMsg.messageId }
|
|
2773
3089
|
: { ...wordData, messageId: currentMsg.messageId };
|
|
@@ -2776,80 +3092,94 @@ class TextHighlighterComponent {
|
|
|
2776
3092
|
startAudioPlayback() {
|
|
2777
3093
|
if (!this.audioElement)
|
|
2778
3094
|
return;
|
|
2779
|
-
this.audioElement.play().catch((error) =>
|
|
2780
|
-
|
|
2781
|
-
});
|
|
2782
|
-
this.isPlaying.set(true); // Set play state to true
|
|
3095
|
+
this.audioElement.play().catch((error) => console.error('Error playing audio:', error));
|
|
3096
|
+
this.audioState.set('playing');
|
|
2783
3097
|
this.alreadyPlayed = true;
|
|
2784
3098
|
}
|
|
2785
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
2786
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type:
|
|
3099
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MessageContentDisplayer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3100
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: MessageContentDisplayer, isStandalone: true, selector: "message-content-displayer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { playAudio: "playAudio", audioCompleted: "audioCompleted", wordClicked: "wordClicked" }, ngImport: i0, template: "<div class=\"audio-text-sync-container\">\n <i (click)=\"onPlayMessage()\" class=\"play-button\">\n @switch (iconState()) { @case ('loading') { <i class=\"spin-animation pi pi-spinner-dotted\"></i> } @case ('playing') { <i class=\"pi pi-volume-up\"></i> }\n @case ('paused') { <i class=\"pi pi-pause-circle\"></i> } @case ('playable') { <dc-icon name=\"play\"></dc-icon> } }\n </i>\n\n <!-- Display transcription with highlighting -->\n <p style=\"width: 100%\" [class]=\"'text-content ' + classTag()\">\n @for (word of wordWithMeta(); track trackByIndex($index, word)) {\n <span [class]=\"word.tag\" [class.highlight]=\"word.isHighlighted\" (click)=\"onWordClick(word)\" [attr.id]=\"'word-' + message().messageId + '-' + word.index\"\n >{{ word.word }}\n </span>\n }\n </p>\n</div>\n", styles: [":host{display:block}.audio-text-sync-container{display:flex;align-items:flex-start;gap:2px;align-items:center}.play-button{cursor:pointer;display:flex;align-items:center;justify-content:center;min-width:24px;margin-top:4px}.play-button:hover{opacity:.8}.text-content{flex:1}.highlight{background-color:#3cd8ff;border-radius:4px}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.em{font-style:italic;color:#6495ed}.strong{font-weight:700;color:inherit}.italic{font-style:italic;color:#6495ed}.em_strong{font-weight:700;font-style:italic;color:inherit}\n"], dependencies: [{ kind: "component", type: IconsComponent, selector: "dc-icon", inputs: ["name", "size", "color"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2787
3101
|
}
|
|
2788
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
3102
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MessageContentDisplayer, decorators: [{
|
|
2789
3103
|
type: Component,
|
|
2790
|
-
args: [{ selector: '
|
|
3104
|
+
args: [{ selector: 'message-content-displayer', standalone: true, imports: [IconsComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"audio-text-sync-container\">\n <i (click)=\"onPlayMessage()\" class=\"play-button\">\n @switch (iconState()) { @case ('loading') { <i class=\"spin-animation pi pi-spinner-dotted\"></i> } @case ('playing') { <i class=\"pi pi-volume-up\"></i> }\n @case ('paused') { <i class=\"pi pi-pause-circle\"></i> } @case ('playable') { <dc-icon name=\"play\"></dc-icon> } }\n </i>\n\n <!-- Display transcription with highlighting -->\n <p style=\"width: 100%\" [class]=\"'text-content ' + classTag()\">\n @for (word of wordWithMeta(); track trackByIndex($index, word)) {\n <span [class]=\"word.tag\" [class.highlight]=\"word.isHighlighted\" (click)=\"onWordClick(word)\" [attr.id]=\"'word-' + message().messageId + '-' + word.index\"\n >{{ word.word }}\n </span>\n }\n </p>\n</div>\n", styles: [":host{display:block}.audio-text-sync-container{display:flex;align-items:flex-start;gap:2px;align-items:center}.play-button{cursor:pointer;display:flex;align-items:center;justify-content:center;min-width:24px;margin-top:4px}.play-button:hover{opacity:.8}.text-content{flex:1}.highlight{background-color:#3cd8ff;border-radius:4px}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.em{font-style:italic;color:#6495ed}.strong{font-weight:700;color:inherit}.italic{font-style:italic;color:#6495ed}.em_strong{font-weight:700;font-style:italic;color:inherit}\n"] }]
|
|
2791
3105
|
}], ctorParameters: () => [] });
|
|
2792
3106
|
|
|
2793
|
-
class
|
|
3107
|
+
class ChatMonitorService {
|
|
3108
|
+
constructor() {
|
|
3109
|
+
this.messageAudioWillPlay = signal(null);
|
|
3110
|
+
this.messageAudioWillPlay$ = this.messageAudioWillPlay.asReadonly();
|
|
3111
|
+
}
|
|
3112
|
+
logMessageAudioWillPlay(message) {
|
|
3113
|
+
console.log('ChatMonitorService: Audio will play for message:', message);
|
|
3114
|
+
this.messageAudioWillPlay.set(message);
|
|
3115
|
+
}
|
|
3116
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMonitorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3117
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMonitorService, providedIn: 'root' }); }
|
|
3118
|
+
}
|
|
3119
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMonitorService, decorators: [{
|
|
3120
|
+
type: Injectable,
|
|
3121
|
+
args: [{
|
|
3122
|
+
providedIn: 'root',
|
|
3123
|
+
}]
|
|
3124
|
+
}] });
|
|
3125
|
+
|
|
3126
|
+
class MessageOrchestrationService {
|
|
2794
3127
|
constructor() {
|
|
2795
3128
|
// Services
|
|
2796
3129
|
this.conversationService = inject(ConversationService);
|
|
2797
3130
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
this.
|
|
2801
|
-
|
|
2802
|
-
this.
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
this.
|
|
2806
|
-
this.messagesEffect = effect(() => {
|
|
2807
|
-
// Get the latest messages from the input
|
|
2808
|
-
const currentMessages = this.messages();
|
|
2809
|
-
if (currentMessages && currentMessages.length > 0) {
|
|
2810
|
-
// Update our internal signal with a new array reference
|
|
2811
|
-
this.messagesSignal.set([...currentMessages]);
|
|
2812
|
-
}
|
|
2813
|
-
});
|
|
3131
|
+
this.chatMonitorService = inject(ChatMonitorService);
|
|
3132
|
+
// State Signals
|
|
3133
|
+
this.messages = signal([]);
|
|
3134
|
+
this.messageRole = signal(ChatRole.User);
|
|
3135
|
+
this.messageToPlay = signal(null);
|
|
3136
|
+
// Public Signals for components to consume
|
|
3137
|
+
this.messagesSignal = this.messages.asReadonly();
|
|
3138
|
+
this.messageToPlay$ = this.messageToPlay.asReadonly();
|
|
2814
3139
|
// Audio queue management
|
|
2815
3140
|
this.audioQueue = [];
|
|
2816
|
-
this.isGenerating = false;
|
|
2817
|
-
this.currentPlayingIndex = null;
|
|
2818
|
-
this.preGenerationInProgress = false;
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
3141
|
+
this.isGenerating = signal(false);
|
|
3142
|
+
this.currentPlayingIndex = signal(null);
|
|
3143
|
+
this.preGenerationInProgress = signal(false);
|
|
3144
|
+
console.log('MessageOrchestrationService initialized');
|
|
3145
|
+
}
|
|
3146
|
+
startOrchestration(messages, role) {
|
|
3147
|
+
this.messages.set([...messages]);
|
|
3148
|
+
this.messageRole.set(role);
|
|
3149
|
+
if (role === ChatRole.Assistant) {
|
|
2822
3150
|
const chatSettings = this.userDataExchange.getUserChatSettings();
|
|
2823
3151
|
if (chatSettings.synthVoice) {
|
|
2824
|
-
// Initialize the queue with all message indices
|
|
2825
3152
|
this.initializeAudioQueue();
|
|
2826
|
-
// Start processing the queue - generate the first audio
|
|
2827
3153
|
this.processNextInQueue();
|
|
2828
3154
|
}
|
|
2829
3155
|
}
|
|
2830
3156
|
else {
|
|
2831
|
-
// since user only have one message, just activate signal
|
|
2832
3157
|
this.changeStates(0, this.messages()[0]);
|
|
2833
3158
|
}
|
|
2834
3159
|
}
|
|
2835
|
-
|
|
3160
|
+
audioCompleted(message) {
|
|
3161
|
+
this.conversationService.currentAudioStatus.set({ message, completed: true });
|
|
3162
|
+
this.currentPlayingIndex.set(null);
|
|
3163
|
+
this.messageToPlay.set(null);
|
|
3164
|
+
if (this.audioQueue.length > 0) {
|
|
3165
|
+
this.processNextInQueue();
|
|
3166
|
+
}
|
|
3167
|
+
}
|
|
3168
|
+
wordClicked(wordData) {
|
|
3169
|
+
this.conversationService.notifyWordClicked(wordData);
|
|
3170
|
+
}
|
|
2836
3171
|
initializeAudioQueue() {
|
|
2837
3172
|
const messages = this.messages();
|
|
2838
3173
|
if (messages && messages.length > 0) {
|
|
2839
3174
|
this.audioQueue = messages.map((_, index) => index);
|
|
2840
3175
|
}
|
|
2841
3176
|
}
|
|
2842
|
-
// Process the next message in the queue
|
|
2843
3177
|
async processNextInQueue() {
|
|
2844
|
-
|
|
2845
|
-
if (this.audioQueue.length === 0 || this.isGenerating) {
|
|
3178
|
+
if (this.audioQueue.length === 0 || this.isGenerating()) {
|
|
2846
3179
|
return;
|
|
2847
3180
|
}
|
|
2848
|
-
// Get the next index from the queue
|
|
2849
3181
|
const nextIndex = this.audioQueue.shift();
|
|
2850
|
-
|
|
2851
|
-
this.isGenerating = true;
|
|
2852
|
-
// Generate audio for the current message
|
|
3182
|
+
this.isGenerating.set(true);
|
|
2853
3183
|
try {
|
|
2854
3184
|
await this.generateAudioForIndex(nextIndex);
|
|
2855
3185
|
}
|
|
@@ -2857,43 +3187,34 @@ class MessageOrchestratorComponent {
|
|
|
2857
3187
|
console.error('Error generating audio:', error);
|
|
2858
3188
|
}
|
|
2859
3189
|
finally {
|
|
2860
|
-
this.isGenerating
|
|
3190
|
+
this.isGenerating.set(false);
|
|
2861
3191
|
}
|
|
2862
|
-
// If there's another message in the queue, pre-generate it
|
|
2863
3192
|
this.preGenerateNextIfNeeded();
|
|
2864
3193
|
}
|
|
2865
|
-
// Pre-generate the next audio if available
|
|
2866
3194
|
async preGenerateNextIfNeeded() {
|
|
2867
|
-
if (this.audioQueue.length > 0 && !this.preGenerationInProgress) {
|
|
2868
|
-
const nextIndex = this.audioQueue[0];
|
|
2869
|
-
|
|
2870
|
-
// Mark pre-generation as in progress
|
|
2871
|
-
this.preGenerationInProgress = true;
|
|
2872
|
-
// Mark as loading but don't set shouldPlayAudio yet
|
|
3195
|
+
if (this.audioQueue.length > 0 && !this.preGenerationInProgress()) {
|
|
3196
|
+
const nextIndex = this.audioQueue[0];
|
|
3197
|
+
this.preGenerationInProgress.set(true);
|
|
2873
3198
|
const messages = this.messages();
|
|
2874
3199
|
const message = { ...messages[nextIndex], isLoading: true };
|
|
2875
3200
|
this.changeStates(nextIndex, message);
|
|
2876
|
-
// Generate in background
|
|
2877
3201
|
const messageAudio = await this.generateAudio(messages[nextIndex], null);
|
|
2878
3202
|
messageAudio.isLoading = false;
|
|
2879
|
-
messageAudio.shouldPlayAudio = false;
|
|
3203
|
+
messageAudio.shouldPlayAudio = false;
|
|
2880
3204
|
this.changeStates(nextIndex, messageAudio);
|
|
2881
|
-
|
|
2882
|
-
this.preGenerationInProgress = false;
|
|
3205
|
+
this.preGenerationInProgress.set(false);
|
|
2883
3206
|
}
|
|
2884
3207
|
}
|
|
2885
|
-
// Generate audio for a specific index
|
|
2886
3208
|
async generateAudioForIndex(index) {
|
|
2887
3209
|
const messages = this.messages();
|
|
2888
|
-
// Check if this message was already pre-generated (has audioUrl)
|
|
2889
3210
|
if (messages[index].audioUrl) {
|
|
2890
|
-
// If it was pre-generated, just set it to play
|
|
2891
3211
|
const messageAudio = { ...messages[index], shouldPlayAudio: true };
|
|
2892
3212
|
this.changeStates(index, messageAudio);
|
|
2893
|
-
this.
|
|
3213
|
+
this.chatMonitorService.logMessageAudioWillPlay(messageAudio);
|
|
3214
|
+
this.messageToPlay.set(messageAudio);
|
|
3215
|
+
this.currentPlayingIndex.set(index);
|
|
2894
3216
|
return;
|
|
2895
3217
|
}
|
|
2896
|
-
// Otherwise generate it now
|
|
2897
3218
|
const message = { ...messages[index], isLoading: true };
|
|
2898
3219
|
this.changeStates(index, message);
|
|
2899
3220
|
try {
|
|
@@ -2901,29 +3222,21 @@ class MessageOrchestratorComponent {
|
|
|
2901
3222
|
messageAudio.isLoading = false;
|
|
2902
3223
|
messageAudio.shouldPlayAudio = true;
|
|
2903
3224
|
this.changeStates(index, messageAudio);
|
|
3225
|
+
this.chatMonitorService.logMessageAudioWillPlay(messageAudio);
|
|
3226
|
+
this.messageToPlay.set(messageAudio);
|
|
2904
3227
|
}
|
|
2905
3228
|
finally {
|
|
2906
3229
|
const message = { ...messages[index], isLoading: false };
|
|
2907
3230
|
this.changeStates(index, message);
|
|
2908
3231
|
}
|
|
2909
|
-
this.currentPlayingIndex
|
|
2910
|
-
}
|
|
2911
|
-
// Handle audio completion event from text-highlighter
|
|
2912
|
-
onAudioCompleted(message) {
|
|
2913
|
-
// Forward the event
|
|
2914
|
-
this.audioCompleted.emit(message);
|
|
2915
|
-
this.conversationService.currentAudioStatus.set({ message, completed: true });
|
|
2916
|
-
// Reset current playing index
|
|
2917
|
-
this.currentPlayingIndex = null;
|
|
2918
|
-
// If there are more messages in the queue, process the next one
|
|
2919
|
-
if (this.audioQueue.length > 0) {
|
|
2920
|
-
this.processNextInQueue();
|
|
2921
|
-
}
|
|
3232
|
+
this.currentPlayingIndex.set(index);
|
|
2922
3233
|
}
|
|
2923
3234
|
changeStates(index, messageAudio) {
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
3235
|
+
this.messages.update((messages) => {
|
|
3236
|
+
const newMessages = [...messages];
|
|
3237
|
+
newMessages[index] = { ...messages[index], ...messageAudio };
|
|
3238
|
+
return newMessages;
|
|
3239
|
+
});
|
|
2927
3240
|
}
|
|
2928
3241
|
async generateAudio(message, overwriteText = null) {
|
|
2929
3242
|
try {
|
|
@@ -2934,19 +3247,44 @@ class MessageOrchestratorComponent {
|
|
|
2934
3247
|
return message;
|
|
2935
3248
|
}
|
|
2936
3249
|
finally {
|
|
2937
|
-
this.isGenerating
|
|
3250
|
+
this.isGenerating.set(false);
|
|
2938
3251
|
}
|
|
2939
3252
|
}
|
|
3253
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MessageOrchestrationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3254
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MessageOrchestrationService }); }
|
|
3255
|
+
}
|
|
3256
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: MessageOrchestrationService, decorators: [{
|
|
3257
|
+
type: Injectable
|
|
3258
|
+
}], ctorParameters: () => [] });
|
|
3259
|
+
|
|
3260
|
+
class ChatMessageOrchestratorComponent {
|
|
3261
|
+
constructor() {
|
|
3262
|
+
// Services
|
|
3263
|
+
this.orchestrationService = inject(MessageOrchestrationService);
|
|
3264
|
+
// Inputs
|
|
3265
|
+
this.messages = input.required();
|
|
3266
|
+
this.messageRole = input.required();
|
|
3267
|
+
// Outputs
|
|
3268
|
+
this.audioCompleted = output();
|
|
3269
|
+
// Signals
|
|
3270
|
+
this.messagesSignal = this.orchestrationService.messagesSignal;
|
|
3271
|
+
}
|
|
3272
|
+
ngOnInit() {
|
|
3273
|
+
this.orchestrationService.startOrchestration(this.messages(), this.messageRole());
|
|
3274
|
+
}
|
|
3275
|
+
onAudioCompleted(message) {
|
|
3276
|
+
this.orchestrationService.audioCompleted(message);
|
|
3277
|
+
this.audioCompleted.emit(message);
|
|
3278
|
+
}
|
|
2940
3279
|
onWordClicked(wordData) {
|
|
2941
|
-
|
|
2942
|
-
this.conversationService.notifyWordClicked(wordData);
|
|
3280
|
+
this.orchestrationService.wordClicked(wordData);
|
|
2943
3281
|
}
|
|
2944
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
2945
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type:
|
|
3282
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3283
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessageOrchestratorComponent, isStandalone: true, selector: "dc-message-orchestrator", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: true, transformFunction: null }, messageRole: { classPropertyName: "messageRole", publicName: "messageRole", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { audioCompleted: "audioCompleted" }, providers: [MessageOrchestrationService], ngImport: i0, template: "<div class=\"message-orchestrator-container\">\n @for (message of messagesSignal(); track $index) {\n <message-content-displayer [message]=\"message\" (audioCompleted)=\"onAudioCompleted($event)\" (wordClicked)=\"onWordClicked($event)\" />\n }\n</div>\n", styles: [":host{display:block}.word-options-popup{position:absolute;border:1px solid #ccc;background:#fff;padding:5px;z-index:1000}\n"], dependencies: [{ kind: "component", type: MessageContentDisplayer, selector: "message-content-displayer", inputs: ["message"], outputs: ["playAudio", "audioCompleted", "wordClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
2946
3284
|
}
|
|
2947
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type:
|
|
3285
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageOrchestratorComponent, decorators: [{
|
|
2948
3286
|
type: Component,
|
|
2949
|
-
args: [{ selector: 'dc-message-orchestrator', imports: [
|
|
3287
|
+
args: [{ selector: 'dc-message-orchestrator', imports: [MessageContentDisplayer], changeDetection: ChangeDetectionStrategy.OnPush, providers: [MessageOrchestrationService], template: "<div class=\"message-orchestrator-container\">\n @for (message of messagesSignal(); track $index) {\n <message-content-displayer [message]=\"message\" (audioCompleted)=\"onAudioCompleted($event)\" (wordClicked)=\"onWordClicked($event)\" />\n }\n</div>\n", styles: [":host{display:block}.word-options-popup{position:absolute;border:1px solid #ccc;background:#fff;padding:5px;z-index:1000}\n"] }]
|
|
2950
3288
|
}] });
|
|
2951
3289
|
|
|
2952
3290
|
const EVALUATION_EMOJIS = {
|
|
@@ -2965,34 +3303,19 @@ class ChatMessageComponent {
|
|
|
2965
3303
|
// Computed properties for easier access to signal values
|
|
2966
3304
|
this.hasMultiMessages = computed(() => !!this.chatMessage()?.multiMessages);
|
|
2967
3305
|
this.multiMessages = computed(() => this.chatMessage()?.multiMessages || []);
|
|
2968
|
-
this.messageTranslation = computed(() => this.chatMessage()?.translation);
|
|
2969
3306
|
this.isUserMessage = computed(() => this.chatMessage()?.role === ChatRole.User);
|
|
2970
3307
|
this.isAssistantMessage = computed(() => this.chatMessage()?.role === ChatRole.Assistant);
|
|
2971
3308
|
this.evaluationEmoji = computed(() => {
|
|
2972
3309
|
const score = this.chatMessage()?.evaluation?.['score'];
|
|
2973
|
-
|
|
2974
|
-
return '';
|
|
2975
|
-
}
|
|
2976
|
-
return EVALUATION_EMOJIS[+score] || '';
|
|
3310
|
+
return score !== null && score !== undefined ? EVALUATION_EMOJIS[+score] || '' : '';
|
|
2977
3311
|
});
|
|
2978
|
-
|
|
2979
|
-
this.messageEffect = effect(() => {
|
|
3312
|
+
effect(() => {
|
|
2980
3313
|
const message = this.chatMessage();
|
|
2981
|
-
if (!message)
|
|
3314
|
+
if (!message || message.role === ChatRole.AssistantHelper)
|
|
2982
3315
|
return;
|
|
2983
|
-
if (message.role === ChatRole.
|
|
2984
|
-
return;
|
|
2985
|
-
}
|
|
2986
|
-
if (message.role === ChatRole.User) {
|
|
3316
|
+
if (message.role === ChatRole.User || (message.role === ChatRole.Assistant && !this.hasMultiMessages())) {
|
|
2987
3317
|
this.audioMessage.set({ ...message });
|
|
2988
3318
|
}
|
|
2989
|
-
else if (message.role === ChatRole.Assistant) {
|
|
2990
|
-
if (this.multiMessages().length > 0) {
|
|
2991
|
-
}
|
|
2992
|
-
else {
|
|
2993
|
-
this.audioMessage.set({ ...message });
|
|
2994
|
-
}
|
|
2995
|
-
}
|
|
2996
3319
|
});
|
|
2997
3320
|
}
|
|
2998
3321
|
showEvaluation() {
|
|
@@ -3003,12 +3326,12 @@ class ChatMessageComponent {
|
|
|
3003
3326
|
console.log(this.chatMessage());
|
|
3004
3327
|
}
|
|
3005
3328
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3006
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessageComponent, isStandalone: true, selector: "dc-chat-message", inputs: { chatMessage: { classPropertyName: "chatMessage", publicName: "chatMessage", isSignal: true, isRequired: true, transformFunction: null }, chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar
|
|
3329
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatMessageComponent, isStandalone: true, selector: "dc-chat-message", inputs: { chatMessage: { classPropertyName: "chatMessage", publicName: "chatMessage", isSignal: true, isRequired: true, transformFunction: null }, chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar -->\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\" (click)=\"printData()\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"AI\" class=\"avatar-image\" />\n </div>\n </div>\n } @if (isUserMessage()) {\n <div class=\"avatar-container-right\" (click)=\"printData()\">\n <div class=\"avatar user-avatar\">\n <img [src]=\"chatMessage()?.imgUrl || '/assets/defaults/avatar_user.jpg'\" alt=\"User\" class=\"avatar-image\" />\n </div>\n </div>\n }\n\n <!-- Message Bubble -->\n <div class=\"message-bubble\">\n @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[audioMessage()]\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n }\n\n <!-- Translation -->\n @if (isAssistantMessage() && chatMessage().evaluation?.['text']) {\n <div class=\"translation\">\n <hr class=\"divider\" />\n\n {{ chatMessage().evaluation?.['text'] }}\n </div>\n } @if (isUserMessage() && chatMessage().evaluation) {\n <div class=\"translation\" style=\"color: white\">\n <hr class=\"divider\" />\n {{ chatMessage().evaluation?.['text'] }}\n </div>\n <div class=\"evaluation-footer\">\n <span>{{ evaluationEmoji() }}</span>\n <span class=\"pointer\" (click)=\"showEvaluation()\"> \uD83E\uDDD0 </span>\n </div>\n }\n </div>\n\n <!-- Tags -->\n @if (chatMessage().tags?.length) {\n <div class=\"tags\">\n @for (tag of chatMessage().tags; track tag) {\n <span class=\"tag\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: rgba(13, 88, 120, .8);--assistant-message-bg: rgba(240, 240, 240, .8);--user-text-color: white;--assistant-text-color: #333;--avatar-user-bg: #ffa77e;--divider-color: #ffa77e;--border-radius: 18px;--avatar-size: 36px;--shadow: 0 2px 8px rgba(0, 0, 0, .15);display:block;margin-bottom:16px}.message-wrapper{display:flex;width:100%;margin-bottom:12px}.message-container{display:flex;max-width:98%;line-height:1.5;position:relative}.user-message{justify-content:flex-end}.user-message .message-bubble{background-color:var(--user-message-bg);color:var(--user-text-color);border-radius:var(--border-radius) var(--border-radius) 0 var(--border-radius);margin-left:8px;min-width:150px}.user-message dc-message-orchestrator{margin-right:19px}.assistant-message{justify-content:flex-start}.assistant-message .message-bubble{background-color:var(--assistant-message-bg);color:var(--assistant-text-color);border-radius:var(--border-radius) var(--border-radius) var(--border-radius) 0;margin-left:8px}.message-bubble{padding:9px;box-shadow:var(--shadow);max-width:98%;min-width:0;position:relative;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.avatar-container,.avatar-container-right{position:absolute;bottom:-20px}.avatar-container{left:-7px;z-index:1}.avatar-container-right{right:-5px;z-index:1}.avatar{width:var(--avatar-size);height:var(--avatar-size);border-radius:50%;background-color:var(--user-message-bg);display:flex;align-items:center;justify-content:center;color:var(--user-text-color);font-weight:700;font-size:14px;overflow:hidden}.avatar-image{width:100%;height:100%;object-fit:cover}.user-avatar{background-color:var(--avatar-user-bg)}::ng-deep .em{color:inherit;font-style:italic}::ng-deep .strong{font-weight:700;color:inherit}::ng-deep .em_strong{font-weight:700;font-style:italic;color:inherit}.translation{margin-top:8px;font-size:small;line-height:1.6;color:#393744;font-style:italic}.divider{margin:.5rem 40px;border-top:1px solid var(--divider-color)}.evaluation-footer{position:absolute;bottom:-10px;left:20px;display:flex;align-items:center;gap:8px}.pointer{cursor:pointer}.tags{position:absolute;top:-10px;right:15px;display:flex;gap:5px;z-index:1}.tag{font-size:16px;transition:transform .3s ease-in-out;animation:float 6s ease-in-out infinite;cursor:default}.tag:hover{transform:scale(1.2)}@keyframes float{0%{transform:translateY(0)}50%{transform:translateY(-2px)}to{transform:translateY(0)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChatMessageOrchestratorComponent, selector: "dc-message-orchestrator", inputs: ["messages", "messageRole"], outputs: ["audioCompleted"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3007
3330
|
}
|
|
3008
3331
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatMessageComponent, decorators: [{
|
|
3009
3332
|
type: Component,
|
|
3010
|
-
args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule,
|
|
3011
|
-
}] });
|
|
3333
|
+
args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, ChatMessageOrchestratorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"message-wrapper\" [ngClass]=\"{ 'user-message': isUserMessage(), 'assistant-message': !isUserMessage() }\">\n <div class=\"message-container\">\n <!-- Avatar -->\n @if (!isUserMessage()) {\n <div class=\"avatar-container\">\n <div class=\"avatar\" (click)=\"printData()\">\n <img [src]=\"chatMessage().imgUrl\" alt=\"AI\" class=\"avatar-image\" />\n </div>\n </div>\n } @if (isUserMessage()) {\n <div class=\"avatar-container-right\" (click)=\"printData()\">\n <div class=\"avatar user-avatar\">\n <img [src]=\"chatMessage()?.imgUrl || '/assets/defaults/avatar_user.jpg'\" alt=\"User\" class=\"avatar-image\" />\n </div>\n </div>\n }\n\n <!-- Message Bubble -->\n <div class=\"message-bubble\">\n @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[audioMessage()]\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n }\n\n <!-- Translation -->\n @if (isAssistantMessage() && chatMessage().evaluation?.['text']) {\n <div class=\"translation\">\n <hr class=\"divider\" />\n\n {{ chatMessage().evaluation?.['text'] }}\n </div>\n } @if (isUserMessage() && chatMessage().evaluation) {\n <div class=\"translation\" style=\"color: white\">\n <hr class=\"divider\" />\n {{ chatMessage().evaluation?.['text'] }}\n </div>\n <div class=\"evaluation-footer\">\n <span>{{ evaluationEmoji() }}</span>\n <span class=\"pointer\" (click)=\"showEvaluation()\"> \uD83E\uDDD0 </span>\n </div>\n }\n </div>\n\n <!-- Tags -->\n @if (chatMessage().tags?.length) {\n <div class=\"tags\">\n @for (tag of chatMessage().tags; track tag) {\n <span class=\"tag\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: rgba(13, 88, 120, .8);--assistant-message-bg: rgba(240, 240, 240, .8);--user-text-color: white;--assistant-text-color: #333;--avatar-user-bg: #ffa77e;--divider-color: #ffa77e;--border-radius: 18px;--avatar-size: 36px;--shadow: 0 2px 8px rgba(0, 0, 0, .15);display:block;margin-bottom:16px}.message-wrapper{display:flex;width:100%;margin-bottom:12px}.message-container{display:flex;max-width:98%;line-height:1.5;position:relative}.user-message{justify-content:flex-end}.user-message .message-bubble{background-color:var(--user-message-bg);color:var(--user-text-color);border-radius:var(--border-radius) var(--border-radius) 0 var(--border-radius);margin-left:8px;min-width:150px}.user-message dc-message-orchestrator{margin-right:19px}.assistant-message{justify-content:flex-start}.assistant-message .message-bubble{background-color:var(--assistant-message-bg);color:var(--assistant-text-color);border-radius:var(--border-radius) var(--border-radius) var(--border-radius) 0;margin-left:8px}.message-bubble{padding:9px;box-shadow:var(--shadow);max-width:98%;min-width:0;position:relative;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}.avatar-container,.avatar-container-right{position:absolute;bottom:-20px}.avatar-container{left:-7px;z-index:1}.avatar-container-right{right:-5px;z-index:1}.avatar{width:var(--avatar-size);height:var(--avatar-size);border-radius:50%;background-color:var(--user-message-bg);display:flex;align-items:center;justify-content:center;color:var(--user-text-color);font-weight:700;font-size:14px;overflow:hidden}.avatar-image{width:100%;height:100%;object-fit:cover}.user-avatar{background-color:var(--avatar-user-bg)}::ng-deep .em{color:inherit;font-style:italic}::ng-deep .strong{font-weight:700;color:inherit}::ng-deep .em_strong{font-weight:700;font-style:italic;color:inherit}.translation{margin-top:8px;font-size:small;line-height:1.6;color:#393744;font-style:italic}.divider{margin:.5rem 40px;border-top:1px solid var(--divider-color)}.evaluation-footer{position:absolute;bottom:-10px;left:20px;display:flex;align-items:center;gap:8px}.pointer{cursor:pointer}.tags{position:absolute;top:-10px;right:15px;display:flex;gap:5px;z-index:1}.tag{font-size:16px;transition:transform .3s ease-in-out;animation:float 6s ease-in-out infinite;cursor:default}.tag:hover{transform:scale(1.2)}@keyframes float{0%{transform:translateY(0)}50%{transform:translateY(-2px)}to{transform:translateY(0)}}\n"] }]
|
|
3334
|
+
}], ctorParameters: () => [] });
|
|
3012
3335
|
|
|
3013
3336
|
class ChatMessagesListComponent {
|
|
3014
3337
|
constructor() {
|
|
@@ -3023,23 +3346,14 @@ class ChatMessagesListComponent {
|
|
|
3023
3346
|
this.aiIcon = 'assets/defaults/avatar_ai.webp';
|
|
3024
3347
|
this.isThinking = this.conversationService.isThinking();
|
|
3025
3348
|
this.messages = computed(() => {
|
|
3026
|
-
// Get the actual array of messages from the signal by calling it as a function
|
|
3027
3349
|
const allMessages = this.messagesStateService.getMessagesSignal()();
|
|
3028
|
-
console.log('Getting messages', allMessages);
|
|
3029
3350
|
return allMessages.filter((message) => message.role !== ChatRole.System);
|
|
3030
3351
|
});
|
|
3031
3352
|
effect(() => {
|
|
3032
|
-
//
|
|
3033
|
-
const messages = this.messages(); // just to subscribe
|
|
3034
|
-
// Schedule the scroll after the view has been updated
|
|
3353
|
+
this.messages(); // just to subscribe
|
|
3035
3354
|
setTimeout(() => this.scrollToBottom(), 0);
|
|
3036
3355
|
});
|
|
3037
3356
|
}
|
|
3038
|
-
// Note probably i don't need this.
|
|
3039
|
-
ngAfterViewInit() {
|
|
3040
|
-
// Initial scroll to bottom when view is initialized
|
|
3041
|
-
this.scrollToBottom();
|
|
3042
|
-
}
|
|
3043
3357
|
// Scroll to the bottom of the component itself with smooth animation
|
|
3044
3358
|
scrollToBottom() {
|
|
3045
3359
|
const element = this.elementRef.nativeElement;
|
|
@@ -3152,7 +3466,6 @@ class ModelSelectorComponent {
|
|
|
3152
3466
|
* and loading initial models if a provider is already selected.
|
|
3153
3467
|
*/
|
|
3154
3468
|
ngOnInit() {
|
|
3155
|
-
console.log('modelForm', this.modelForm);
|
|
3156
3469
|
const providerControl = this.modelForm.get('provider');
|
|
3157
3470
|
if (providerControl) {
|
|
3158
3471
|
providerControl.valueChanges.pipe(filter((value) => !!value)).subscribe(async (value) => {
|
|
@@ -3173,7 +3486,7 @@ class ModelSelectorComponent {
|
|
|
3173
3486
|
}
|
|
3174
3487
|
}
|
|
3175
3488
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3176
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ModelSelectorComponent, isStandalone: true, selector: "dc-model-selector", inputs: { modelForm: "modelForm", shortForm: "shortForm" }, ngImport: i0, template: "<div>\n <b>Selecci\u00F3n de modelo</b>\n\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Model Quality</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"modelQualityOptions\"\n [formControl]=\"modelForm.controls.quality\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n\n @if(!shortForm) {\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Provider</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"providersOptions\"\n [formControl]=\"modelForm.controls.provider\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n }\n\n <!-- <div style=\"display: flex; gap: 10px\" [formGroup]=\"modelForm\">\n <div class=\"space\">\n <p-radioButton value=\"groq\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Groq</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openai\" formControlName=\"provider\"></p-radioButton>\n <label>Open AI</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"google\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Google</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openrouter\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Open Router</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"ollama\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Ollama</label>\n </div>\n </div> -->\n\n <!-- <b>Modelo: </b>\n <span pTooltip=\"Modelo Seleccionado\">{{ modelForm.controls.modelName.value }}</span>\n @if (modelForm.controls.provider.value) { @if(isLoadingModels) {\n <p-skeleton height=\"200px\" width=\"100%\"></p-skeleton>\n } @else {\n <p-table [value]=\"modelnames\" stripedRows [size]=\"'small'\" [paginator]=\"true\" [rows]=\"12\" [formGroup]=\"modelForm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th></th>\n <th>Name</th>\n <th>$$Prompt M</th>\n <th>$$Completion M</th>\n <th>$$Cost 90/10 M</th>\n <th>Created</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-model>\n <tr [pTooltip]=\"model.description | truncate : 200\" tooltipPosition=\"top\">\n <td><p-radioButton [value]=\"model.id\" formControlName=\"modelName\"></p-radioButton></td>\n <td>{{ model.name || model.id }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.completion * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 * 0.9 + +model.pricing?.completion * 1000000 * 0.1 | number : '1.2-2' }}</td>\n <td>{{ model.created * 1000 | date : 'dd/MM/yyyy' }}</td>\n </tr>\n </ng-template>\n </p-table>\n } }\n</div> -->\n</div>\n", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3489
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ModelSelectorComponent, isStandalone: true, selector: "dc-model-selector", inputs: { modelForm: "modelForm", shortForm: "shortForm" }, ngImport: i0, template: "<div>\n <b>Selecci\u00F3n de modelo</b>\n\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Model Quality</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"modelQualityOptions\"\n [formControl]=\"modelForm.controls.quality\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n\n @if(!shortForm) {\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Provider</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"providersOptions\"\n [formControl]=\"modelForm.controls.provider\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n }\n\n <!-- <div style=\"display: flex; gap: 10px\" [formGroup]=\"modelForm\">\n <div class=\"space\">\n <p-radioButton value=\"groq\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Groq</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openai\" formControlName=\"provider\"></p-radioButton>\n <label>Open AI</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"google\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Google</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openrouter\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Open Router</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"ollama\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Ollama</label>\n </div>\n </div> -->\n\n <!-- <b>Modelo: </b>\n <span pTooltip=\"Modelo Seleccionado\">{{ modelForm.controls.modelName.value }}</span>\n @if (modelForm.controls.provider.value) { @if(isLoadingModels) {\n <p-skeleton height=\"200px\" width=\"100%\"></p-skeleton>\n } @else {\n <p-table [value]=\"modelnames\" stripedRows [size]=\"'small'\" [paginator]=\"true\" [rows]=\"12\" [formGroup]=\"modelForm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th></th>\n <th>Name</th>\n <th>$$Prompt M</th>\n <th>$$Completion M</th>\n <th>$$Cost 90/10 M</th>\n <th>Created</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-model>\n <tr [pTooltip]=\"model.description | truncate : 200\" tooltipPosition=\"top\">\n <td><p-radioButton [value]=\"model.id\" formControlName=\"modelName\"></p-radioButton></td>\n <td>{{ model.name || model.id }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.completion * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 * 0.9 + +model.pricing?.completion * 1000000 * 0.1 | number : '1.2-2' }}</td>\n <td>{{ model.created * 1000 | date : 'dd/MM/yyyy' }}</td>\n </tr>\n </ng-template>\n </p-table>\n } }\n</div> -->\n</div>\n", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3177
3490
|
}
|
|
3178
3491
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ModelSelectorComponent, decorators: [{
|
|
3179
3492
|
type: Component,
|
|
@@ -3257,7 +3570,7 @@ class DCConversationUserChatSettingsComponent {
|
|
|
3257
3570
|
}
|
|
3258
3571
|
}
|
|
3259
3572
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationUserChatSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3260
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationUserChatSettingsComponent, isStandalone: true, selector: "dc-chat-settings-dialog", inputs: { showFeature: { classPropertyName: "showFeature", publicName: "showFeature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSettingsChange: "onSettingsChange", closeClicked: "closeClicked", settingsApplied: "settingsApplied" }, viewQueries: [{ propertyName: "tooltipRef", first: true, predicate: ["tooltipRef"], descendants: true }], ngImport: i0, template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-model-selector [modelForm]=\"form.controls.model\"></dc-model-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$2.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i3.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }, { kind: "ngmodule", type: RatingModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: BadgeModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
|
|
3573
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationUserChatSettingsComponent, isStandalone: true, selector: "dc-chat-settings-dialog", inputs: { showFeature: { classPropertyName: "showFeature", publicName: "showFeature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSettingsChange: "onSettingsChange", closeClicked: "closeClicked", settingsApplied: "settingsApplied" }, viewQueries: [{ propertyName: "tooltipRef", first: true, predicate: ["tooltipRef"], descendants: true }], ngImport: i0, template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-model-selector [modelForm]=\"form.controls.model\"></dc-model-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px;max-height:80vh;overflow-y:auto}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i3.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }, { kind: "ngmodule", type: RatingModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: BadgeModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
|
|
3261
3574
|
}
|
|
3262
3575
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationUserChatSettingsComponent, decorators: [{
|
|
3263
3576
|
type: Component,
|
|
@@ -3275,21 +3588,123 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
3275
3588
|
TooltipModule,
|
|
3276
3589
|
ModelSelectorComponent,
|
|
3277
3590
|
SelectModule,
|
|
3278
|
-
], template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-model-selector [modelForm]=\"form.controls.model\"></dc-model-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"] }]
|
|
3591
|
+
], template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-model-selector [modelForm]=\"form.controls.model\"></dc-model-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px;max-height:80vh;overflow-y:auto}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"] }]
|
|
3279
3592
|
}], propDecorators: { tooltipRef: [{
|
|
3280
3593
|
type: ViewChild,
|
|
3281
3594
|
args: ['tooltipRef']
|
|
3282
3595
|
}] } });
|
|
3283
3596
|
|
|
3597
|
+
/**
|
|
3598
|
+
* SafeJsonPipe - A pipe that safely stringifies objects with circular references
|
|
3599
|
+
* This pipe handles circular references and DOM objects that can't be serialized
|
|
3600
|
+
*/
|
|
3601
|
+
class SafeJsonPipe {
|
|
3602
|
+
transform(value) {
|
|
3603
|
+
// Create a new object with only serializable properties
|
|
3604
|
+
return this.stringifySafely(value);
|
|
3605
|
+
}
|
|
3606
|
+
/**
|
|
3607
|
+
* Safely stringify an object, handling circular references
|
|
3608
|
+
*/
|
|
3609
|
+
stringifySafely(obj) {
|
|
3610
|
+
const seen = new WeakSet();
|
|
3611
|
+
return JSON.stringify(obj, (key, value) => {
|
|
3612
|
+
// Skip properties that start with underscore (often internal properties)
|
|
3613
|
+
if (key.startsWith('_')) {
|
|
3614
|
+
return undefined;
|
|
3615
|
+
}
|
|
3616
|
+
// Handle DOM elements and other non-serializable objects
|
|
3617
|
+
if (value instanceof HTMLElement || value instanceof Node) {
|
|
3618
|
+
return '[DOM Element]';
|
|
3619
|
+
}
|
|
3620
|
+
// Handle audio elements specifically
|
|
3621
|
+
if (key === 'audioHtml' || key === 'audioElement') {
|
|
3622
|
+
return '[Audio Element]';
|
|
3623
|
+
}
|
|
3624
|
+
// Handle functions
|
|
3625
|
+
if (typeof value === 'function') {
|
|
3626
|
+
return '[Function]';
|
|
3627
|
+
}
|
|
3628
|
+
// Handle circular references
|
|
3629
|
+
if (typeof value === 'object' && value !== null) {
|
|
3630
|
+
if (seen.has(value)) {
|
|
3631
|
+
return '[Circular Reference]';
|
|
3632
|
+
}
|
|
3633
|
+
seen.add(value);
|
|
3634
|
+
}
|
|
3635
|
+
return value;
|
|
3636
|
+
}, 2);
|
|
3637
|
+
}
|
|
3638
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SafeJsonPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
3639
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.4", ngImport: i0, type: SafeJsonPipe, isStandalone: true, name: "safeJson" }); }
|
|
3640
|
+
}
|
|
3641
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: SafeJsonPipe, decorators: [{
|
|
3642
|
+
type: Pipe,
|
|
3643
|
+
args: [{
|
|
3644
|
+
name: 'safeJson',
|
|
3645
|
+
standalone: true
|
|
3646
|
+
}]
|
|
3647
|
+
}] });
|
|
3648
|
+
|
|
3649
|
+
class ConversationInspector {
|
|
3650
|
+
constructor() {
|
|
3651
|
+
this.evaluationService = inject(EvaluationService);
|
|
3652
|
+
this.messageStateService = inject(MessagesStateService);
|
|
3653
|
+
this.dynamicFlowService = inject(DynamicFlowService);
|
|
3654
|
+
this.globalToolsService = inject(GlobalToolsService);
|
|
3655
|
+
this.config = inject(DynamicDialogConfig);
|
|
3656
|
+
this.value = 0;
|
|
3657
|
+
this.agentCard = this.config.data.agentCard;
|
|
3658
|
+
this.chatUserSettings = this.config.data.chatUserSettings;
|
|
3659
|
+
}
|
|
3660
|
+
setScore() {
|
|
3661
|
+
this.evaluationService.setScore(this.value);
|
|
3662
|
+
}
|
|
3663
|
+
callAgent() {
|
|
3664
|
+
this.globalToolsService.useTool('closeChatDrawer');
|
|
3665
|
+
}
|
|
3666
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationInspector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3667
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ConversationInspector, isStandalone: true, selector: "dc-conversation-info", ngImport: i0, template: "<p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n<div class=\"info-content\">\n <p-divider>Score</p-divider>\n\n <label for=\"slider\">Current Score : {{ evaluationService.scoreSignal() }}</label>\n\n <div class=\"flex flex gap-3\">\n <p-slider [(ngModel)]=\"value\" [step]=\"10\" class=\"w-56\" />\n <p-button label=\"Set Score to {{ value }}\" (onClick)=\"setScore()\" />\n </div>\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.goal?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Goal</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.goal?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Trigger User Message</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Trigger Assistant Message</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <h3>Herramientas</h3>\n @for (tool of dynamicFlowService.conversationFlowState()?.tools; track tool.name) {\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (tool.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">{{ tool.name }}</p>\n </div>\n @if(tool.description) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ tool.description }} </div>\n }\n </div>\n }\n\n <h3>Challenges Retos</h3>\n @for (challenge of dynamicFlowService.conversationFlowState()?.challenges; track challenge.name) {\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (challenge.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n\n <p class=\"font-semibold\"> {{ challenge.emoji }} {{ challenge.name }}</p>\n </div>\n @if(challenge.description) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ challenge.description }} </div>\n }\n </div>\n }\n <h5>Conditions</h5>\n\n @for (condition of dynamicFlowService.conversationFlowState()?.dynamicConditions; track $index) {\n <div class=\"pl-2 mt-1 text-sm text-gray-600 italic\"> When the {{ condition.what }} is {{ condition.when }} than {{ condition.value }} Do </div>\n <ol>\n @for (doAction of condition.do; track $index) {\n <li class=\"pl-5 mt-1 text-sm text-gray-600 italic\">\n {{ $index }})\n <span style=\"color: brown\"> {{ doAction.actionType }}</span>\n <span style=\"color: green\"> {{ doAction.systemPromptType }}</span>\n <span style=\"color: green\"> {{ doAction.dynamicFlowTaskType }}</span>\n\n to\n <span style=\"color: rgb(49, 23, 177)\"> {{ doAction.enabled }}</span>\n \"{{ doAction.prompt }}\"\n </li>\n }\n </ol>\n }\n\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.challenges | safeJson }}</pre>\n\n <details>\n <summary>Messages</summary>\n @for (message of messageStateService.getMessagesSignal()(); track message.messageId) {\n <h6>\n @if (message.role === 'system') {\n <b class=\"text-red-500\" style=\"text-transform: capitalize\">{{ message.role }}</b> - } @else {\n <b style=\"text-transform: capitalize\">{{ message.role }}</b> - }\n <b style=\"color: var(--info-color); text-transform: capitalize\">{{ message.messageId }}</b></h6\n >\n <p>{{ message.content }}</p>\n }\n </details>\n\n <details>\n <summary>Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Agent Card</summary>\n <pre>{{ agentCard | safeJson }}</pre>\n </details>\n\n <details>\n <summary>User Settings</summary>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </details>\n</div>\n", styles: [":host{overflow-y:scroll}.info-content{display:flex;flex-direction:column;gap:1rem;padding:1rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i1$3.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$2.Divider, selector: "p-divider", inputs: ["style", "styleClass", "layout", "type", "align"] }] }); }
|
|
3668
|
+
}
|
|
3669
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationInspector, decorators: [{
|
|
3670
|
+
type: Component,
|
|
3671
|
+
args: [{ selector: 'dc-conversation-info', standalone: true, imports: [CommonModule, SafeJsonPipe, SliderModule, ButtonModule, FormsModule, DividerModule], template: "<p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n<div class=\"info-content\">\n <p-divider>Score</p-divider>\n\n <label for=\"slider\">Current Score : {{ evaluationService.scoreSignal() }}</label>\n\n <div class=\"flex flex gap-3\">\n <p-slider [(ngModel)]=\"value\" [step]=\"10\" class=\"w-56\" />\n <p-button label=\"Set Score to {{ value }}\" (onClick)=\"setScore()\" />\n </div>\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.goal?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Goal</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.goal?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Trigger User Message</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">Trigger Assistant Message</p>\n </div>\n @if(dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage?.task; as task) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ task }} </div>\n }\n </div>\n\n <h3>Herramientas</h3>\n @for (tool of dynamicFlowService.conversationFlowState()?.tools; track tool.name) {\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (tool.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n <p class=\"font-semibold\">{{ tool.name }}</p>\n </div>\n @if(tool.description) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ tool.description }} </div>\n }\n </div>\n }\n\n <h3>Challenges Retos</h3>\n @for (challenge of dynamicFlowService.conversationFlowState()?.challenges; track challenge.name) {\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (challenge.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n }\n\n <p class=\"font-semibold\"> {{ challenge.emoji }} {{ challenge.name }}</p>\n </div>\n @if(challenge.description) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> {{ challenge.description }} </div>\n }\n </div>\n }\n <h5>Conditions</h5>\n\n @for (condition of dynamicFlowService.conversationFlowState()?.dynamicConditions; track $index) {\n <div class=\"pl-2 mt-1 text-sm text-gray-600 italic\"> When the {{ condition.what }} is {{ condition.when }} than {{ condition.value }} Do </div>\n <ol>\n @for (doAction of condition.do; track $index) {\n <li class=\"pl-5 mt-1 text-sm text-gray-600 italic\">\n {{ $index }})\n <span style=\"color: brown\"> {{ doAction.actionType }}</span>\n <span style=\"color: green\"> {{ doAction.systemPromptType }}</span>\n <span style=\"color: green\"> {{ doAction.dynamicFlowTaskType }}</span>\n\n to\n <span style=\"color: rgb(49, 23, 177)\"> {{ doAction.enabled }}</span>\n \"{{ doAction.prompt }}\"\n </li>\n }\n </ol>\n }\n\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.challenges | safeJson }}</pre>\n\n <details>\n <summary>Messages</summary>\n @for (message of messageStateService.getMessagesSignal()(); track message.messageId) {\n <h6>\n @if (message.role === 'system') {\n <b class=\"text-red-500\" style=\"text-transform: capitalize\">{{ message.role }}</b> - } @else {\n <b style=\"text-transform: capitalize\">{{ message.role }}</b> - }\n <b style=\"color: var(--info-color); text-transform: capitalize\">{{ message.messageId }}</b></h6\n >\n <p>{{ message.content }}</p>\n }\n </details>\n\n <details>\n <summary>Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowState()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Agent Card</summary>\n <pre>{{ agentCard | safeJson }}</pre>\n </details>\n\n <details>\n <summary>User Settings</summary>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </details>\n</div>\n", styles: [":host{overflow-y:scroll}.info-content{display:flex;flex-direction:column;gap:1rem;padding:1rem}\n"] }]
|
|
3672
|
+
}], ctorParameters: () => [] });
|
|
3673
|
+
|
|
3674
|
+
class ConversationInfoService {
|
|
3675
|
+
constructor() {
|
|
3676
|
+
this.dialogService = inject(DialogService);
|
|
3677
|
+
}
|
|
3678
|
+
openConversationInfo(data) {
|
|
3679
|
+
this.dialogService.open(ConversationInspector, {
|
|
3680
|
+
header: 'Conversation Inspection',
|
|
3681
|
+
width: '90vw',
|
|
3682
|
+
modal: true,
|
|
3683
|
+
draggable: false,
|
|
3684
|
+
closable: true,
|
|
3685
|
+
data,
|
|
3686
|
+
});
|
|
3687
|
+
}
|
|
3688
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationInfoService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3689
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationInfoService, providedIn: 'root' }); }
|
|
3690
|
+
}
|
|
3691
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ConversationInfoService, decorators: [{
|
|
3692
|
+
type: Injectable,
|
|
3693
|
+
args: [{
|
|
3694
|
+
providedIn: 'root',
|
|
3695
|
+
}]
|
|
3696
|
+
}] });
|
|
3697
|
+
|
|
3284
3698
|
class DCChatComponent {
|
|
3285
3699
|
constructor() {
|
|
3286
3700
|
// Services
|
|
3287
|
-
this.
|
|
3701
|
+
this.conversationInfoService = inject(ConversationInfoService);
|
|
3288
3702
|
this.conversationService = inject(ConversationService);
|
|
3289
3703
|
this.evaluationService = inject(EvaluationService);
|
|
3290
3704
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
3291
3705
|
this.messageStateService = inject(MessagesStateService);
|
|
3292
|
-
this.
|
|
3706
|
+
this.dialogService = inject(DialogService);
|
|
3707
|
+
this.chatMonitorService = inject(ChatMonitorService);
|
|
3293
3708
|
// 📥 Inputs
|
|
3294
3709
|
this.chatUserSettings = this.userDataExchange.getUserChatSettings(); // Default to user data exchange
|
|
3295
3710
|
this.conversationFlow = null;
|
|
@@ -3303,7 +3718,6 @@ class DCChatComponent {
|
|
|
3303
3718
|
this.messages = signal([]);
|
|
3304
3719
|
// States
|
|
3305
3720
|
this.micSettings = { micMode: 'recognition', lang: 'en' };
|
|
3306
|
-
this.isInfoVisible = false;
|
|
3307
3721
|
this.isAdmin = true;
|
|
3308
3722
|
// Subscribe to score updates using effect
|
|
3309
3723
|
effect(() => {
|
|
@@ -3322,6 +3736,12 @@ class DCChatComponent {
|
|
|
3322
3736
|
// this.conversationService.notifyWordClicked(null);
|
|
3323
3737
|
}
|
|
3324
3738
|
});
|
|
3739
|
+
effect(() => {
|
|
3740
|
+
const message = this.chatMonitorService.messageAudioWillPlay$();
|
|
3741
|
+
if (message) {
|
|
3742
|
+
console.log('DCChatComponent: Audio will play for message:', message);
|
|
3743
|
+
}
|
|
3744
|
+
});
|
|
3325
3745
|
}
|
|
3326
3746
|
async ngOnInit() {
|
|
3327
3747
|
this.conversationService.setDestroyed(false);
|
|
@@ -3338,6 +3758,7 @@ class DCChatComponent {
|
|
|
3338
3758
|
this.conversationService.setDestroyed(true);
|
|
3339
3759
|
// Ensure the microphone is stopped when the chat component is destroyed
|
|
3340
3760
|
this.chatFooterComponent?.stopMic();
|
|
3761
|
+
this.evaluationService.analylizePerformance();
|
|
3341
3762
|
}
|
|
3342
3763
|
/**
|
|
3343
3764
|
* Open chat settings dialog
|
|
@@ -3354,12 +3775,16 @@ class DCChatComponent {
|
|
|
3354
3775
|
.onClose.subscribe(async () => {
|
|
3355
3776
|
// TODO: Que hacer cuando cambie las configuraciones del usario?, creo que si existe en exchange no necesito guardarlo y leer desde el servicio.
|
|
3356
3777
|
});
|
|
3778
|
+
// TODO: Implement settings dialog
|
|
3357
3779
|
}
|
|
3358
3780
|
/**
|
|
3359
3781
|
* Show debug info
|
|
3360
3782
|
*/
|
|
3361
3783
|
showInfo() {
|
|
3362
|
-
this.
|
|
3784
|
+
this.conversationInfoService.openConversationInfo({
|
|
3785
|
+
agentCard: this.agentCard,
|
|
3786
|
+
chatUserSettings: this.chatUserSettings,
|
|
3787
|
+
});
|
|
3363
3788
|
}
|
|
3364
3789
|
/**
|
|
3365
3790
|
* Restart conversation
|
|
@@ -3374,11 +3799,11 @@ class DCChatComponent {
|
|
|
3374
3799
|
this.goalCompleted.emit();
|
|
3375
3800
|
}
|
|
3376
3801
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3377
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
3802
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationFlow: { classPropertyName: "conversationFlow", publicName: "conversationFlow", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", goalCompleted: "goalCompleted" }, viewQueries: [{ propertyName: "chatFooterComponent", first: true, predicate: ChatFooterComponent, descendants: true }], ngImport: i0, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [flow]=\"conversationFlow\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["isAdmin", "alternativeConversation", "agentCard"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent", "completeEvent"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "flow", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings", "inputMessages"] }, { kind: "ngmodule", type: ProgressBarModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3378
3803
|
}
|
|
3379
3804
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, decorators: [{
|
|
3380
3805
|
type: Component,
|
|
3381
|
-
args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent,
|
|
3806
|
+
args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, ProgressBarModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [flow]=\"conversationFlow\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"] }]
|
|
3382
3807
|
}], ctorParameters: () => [], propDecorators: { chatFooterComponent: [{
|
|
3383
3808
|
type: ViewChild,
|
|
3384
3809
|
args: [ChatFooterComponent]
|
|
@@ -3556,10 +3981,7 @@ class TranslateDialogComponent {
|
|
|
3556
3981
|
this.fb = inject(FormBuilder);
|
|
3557
3982
|
this.dialogRef = inject(DialogRef);
|
|
3558
3983
|
this.data = inject(DIALOG_DATA);
|
|
3559
|
-
this.languages =
|
|
3560
|
-
code,
|
|
3561
|
-
description,
|
|
3562
|
-
}));
|
|
3984
|
+
this.languages = getSupportedLanguageOptions('es');
|
|
3563
3985
|
console.log(this.data);
|
|
3564
3986
|
this.form = this.fb.group({
|
|
3565
3987
|
targetLang: [''],
|
|
@@ -3580,9 +4002,9 @@ class TranslateDialogComponent {
|
|
|
3580
4002
|
<select formControlName="targetLang">
|
|
3581
4003
|
<option value="">Select language...</option>
|
|
3582
4004
|
@for (lang of languages; track lang) {
|
|
3583
|
-
|
|
3584
|
-
|
|
3585
|
-
|
|
4005
|
+
<option [value]="lang.value">
|
|
4006
|
+
{{ lang.label }}
|
|
4007
|
+
</option>
|
|
3586
4008
|
}
|
|
3587
4009
|
</select>
|
|
3588
4010
|
</form>
|
|
@@ -3591,7 +4013,7 @@ class TranslateDialogComponent {
|
|
|
3591
4013
|
<button (click)="onConfirm()" [disabled]="!form.value.targetLang"> Translate </button>
|
|
3592
4014
|
</div>
|
|
3593
4015
|
</div>
|
|
3594
|
-
|
|
4016
|
+
`, isInline: true, styles: [".translate-dialog{padding:20px;background:#fff;border-radius:8px;box-shadow:0 2px 8px #00000026}.actions{margin-top:20px;display:flex;justify-content:flex-end;gap:10px}select{width:100%;padding:8px;margin-top:10px;border:1px solid #ccc;border-radius:4px}button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer}button:first-child{background:#f0f0f0}button:last-child{background:#007bff;color:#fff}button:disabled{background:#ccc;cursor:not-allowed}h2{margin:0 0 16px;color:#333}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1$1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] }); }
|
|
3595
4017
|
}
|
|
3596
4018
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: TranslateDialogComponent, decorators: [{
|
|
3597
4019
|
type: Component,
|
|
@@ -3603,9 +4025,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
3603
4025
|
<select formControlName="targetLang">
|
|
3604
4026
|
<option value="">Select language...</option>
|
|
3605
4027
|
@for (lang of languages; track lang) {
|
|
3606
|
-
|
|
3607
|
-
|
|
3608
|
-
|
|
4028
|
+
<option [value]="lang.value">
|
|
4029
|
+
{{ lang.label }}
|
|
4030
|
+
</option>
|
|
3609
4031
|
}
|
|
3610
4032
|
</select>
|
|
3611
4033
|
</form>
|
|
@@ -3614,7 +4036,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
3614
4036
|
<button (click)="onConfirm()" [disabled]="!form.value.targetLang"> Translate </button>
|
|
3615
4037
|
</div>
|
|
3616
4038
|
</div>
|
|
3617
|
-
|
|
4039
|
+
`, styles: [".translate-dialog{padding:20px;background:#fff;border-radius:8px;box-shadow:0 2px 8px #00000026}.actions{margin-top:20px;display:flex;justify-content:flex-end;gap:10px}select{width:100%;padding:8px;margin-top:10px;border:1px solid #ccc;border-radius:4px}button{padding:8px 16px;border:none;border-radius:4px;cursor:pointer}button:first-child{background:#f0f0f0}button:last-child{background:#007bff;color:#fff}button:disabled{background:#ccc;cursor:not-allowed}h2{margin:0 0 16px;color:#333}\n"] }]
|
|
3618
4040
|
}], ctorParameters: () => [] });
|
|
3619
4041
|
|
|
3620
4042
|
class AccountPlatformForm {
|
|
@@ -3678,7 +4100,7 @@ class AccountPlatformForm {
|
|
|
3678
4100
|
}
|
|
3679
4101
|
}
|
|
3680
4102
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AccountPlatformForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3681
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AccountPlatformForm, isStandalone: true, selector: "account-platform-form", inputs: { formArray: "formArray" }, ngImport: i0, template: "<div class=\"source-form-card\">\n <p-card header=\"Cuenta\">\n @for (formAccount of formArray.controls; track formAccount) {\n <form [formGroup]=\"$any(formAccount)\">\n <div class=\"form-field\">\n <label class=\"block\">Platform</label>\n <p-dropdown [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-dropdown>\n </div>\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Username</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field\">\n <label class=\"block\">Email</label>\n <input pInputText type=\"text\" formControlName=\"email\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n </form>\n }\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$
|
|
4103
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AccountPlatformForm, isStandalone: true, selector: "account-platform-form", inputs: { formArray: "formArray" }, ngImport: i0, template: "<div class=\"source-form-card\">\n <p-card header=\"Cuenta\">\n @for (formAccount of formArray.controls; track formAccount) {\n <form [formGroup]=\"$any(formAccount)\">\n <div class=\"form-field\">\n <label class=\"block\">Platform</label>\n <p-dropdown [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-dropdown>\n </div>\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Username</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field\">\n <label class=\"block\">Email</label>\n <input pInputText type=\"text\" formControlName=\"email\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n </form>\n }\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$2.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$1.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3682
4104
|
}
|
|
3683
4105
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AccountPlatformForm, decorators: [{
|
|
3684
4106
|
type: Component,
|
|
@@ -3715,7 +4137,7 @@ class FormGroupService {
|
|
|
3715
4137
|
// If not possible to patch arrays if control does not exist, that why they are created dinamycally depending on the data.
|
|
3716
4138
|
const alternateGreetingsFormArray = form.get('characterCard.data.alternate_greetings');
|
|
3717
4139
|
alternateGreetingsFormArray.clear();
|
|
3718
|
-
if (agentCard.characterCard
|
|
4140
|
+
if (agentCard.characterCard?.data?.alternate_greetings?.length) {
|
|
3719
4141
|
agentCard.characterCard.data.alternate_greetings.forEach((greeting) => {
|
|
3720
4142
|
alternateGreetingsFormArray.push(this.fb.control(greeting));
|
|
3721
4143
|
});
|
|
@@ -3733,6 +4155,20 @@ class FormGroupService {
|
|
|
3733
4155
|
}
|
|
3734
4156
|
});
|
|
3735
4157
|
}
|
|
4158
|
+
if (agentCard.conversationFlow?.tools?.length) {
|
|
4159
|
+
const toolsFormArray = form.get('conversationFlow.tools');
|
|
4160
|
+
toolsFormArray.clear();
|
|
4161
|
+
agentCard.conversationFlow.tools.forEach((tool) => {
|
|
4162
|
+
toolsFormArray.push(this.createDynamicCriteriaFormGroup(tool));
|
|
4163
|
+
});
|
|
4164
|
+
}
|
|
4165
|
+
if (agentCard.conversationFlow?.challenges?.length) {
|
|
4166
|
+
const challengesFormArray = form.get('conversationFlow.challenges');
|
|
4167
|
+
challengesFormArray.clear();
|
|
4168
|
+
agentCard.conversationFlow.challenges.forEach((challenge) => {
|
|
4169
|
+
challengesFormArray.push(this.createDynamicCriteriaFormGroup(challenge));
|
|
4170
|
+
});
|
|
4171
|
+
}
|
|
3736
4172
|
}
|
|
3737
4173
|
createCharacterCardFormGroup() {
|
|
3738
4174
|
return this.fb.group({
|
|
@@ -3781,7 +4217,7 @@ class FormGroupService {
|
|
|
3781
4217
|
id: this.fb.control(model?.id || ''),
|
|
3782
4218
|
modelName: this.fb.control(model?.modelName || ''),
|
|
3783
4219
|
provider: this.fb.control(model?.provider || ''),
|
|
3784
|
-
quality: this.fb.control(model?.quality || EModelQuality.
|
|
4220
|
+
quality: this.fb.control(model?.quality || EModelQuality.FAST),
|
|
3785
4221
|
});
|
|
3786
4222
|
}
|
|
3787
4223
|
createVoiceTTSFormGroup(tts) {
|
|
@@ -3799,7 +4235,8 @@ class FormGroupService {
|
|
|
3799
4235
|
return this.fb.group({
|
|
3800
4236
|
goal: this.createSimpleAgentTaskFormGroup(),
|
|
3801
4237
|
triggerTasks: this.createTriggerTasksFormGroup(),
|
|
3802
|
-
|
|
4238
|
+
challenges: this.fb.array([]),
|
|
4239
|
+
tools: this.fb.array([]),
|
|
3803
4240
|
dynamicConditions: this.fb.array([]),
|
|
3804
4241
|
});
|
|
3805
4242
|
}
|
|
@@ -3808,8 +4245,6 @@ class FormGroupService {
|
|
|
3808
4245
|
what: this.fb.control(condition?.what || ''),
|
|
3809
4246
|
when: this.fb.control(condition?.when || ''),
|
|
3810
4247
|
value: this.fb.control(condition?.value || ''),
|
|
3811
|
-
then: this.fb.control(condition?.then || ''),
|
|
3812
|
-
// task: this.createSimpleAgentTaskFormGroup(condition?.task),
|
|
3813
4248
|
do: this.fb.array([]), // Correctly typed FormArray
|
|
3814
4249
|
});
|
|
3815
4250
|
}
|
|
@@ -3817,7 +4252,9 @@ class FormGroupService {
|
|
|
3817
4252
|
return this.fb.group({
|
|
3818
4253
|
actionType: this.fb.control(action?.actionType || ''), // Default or from params
|
|
3819
4254
|
systemPromptType: this.fb.control(action?.systemPromptType || ''), // Default or from params
|
|
4255
|
+
dynamicFlowTaskType: this.fb.control(action?.dynamicFlowTaskType || ''), // Default or from params
|
|
3820
4256
|
prompt: this.fb.control(action?.prompt || ''), // Default or from params
|
|
4257
|
+
enabled: this.fb.control(action?.enabled ?? true), // Default or from params
|
|
3821
4258
|
});
|
|
3822
4259
|
}
|
|
3823
4260
|
createTriggerTasksFormGroup() {
|
|
@@ -3834,6 +4271,15 @@ class FormGroupService {
|
|
|
3834
4271
|
expectedResponseType: this.fb.control(task?.expectedResponseType || ''),
|
|
3835
4272
|
modelQuality: this.fb.control(task?.modelQuality || EModelQuality.FAST),
|
|
3836
4273
|
model: this.createModelFormGroup(task?.model),
|
|
4274
|
+
enabled: this.fb.control(task?.enabled ?? false),
|
|
4275
|
+
});
|
|
4276
|
+
}
|
|
4277
|
+
createDynamicCriteriaFormGroup(criteria) {
|
|
4278
|
+
return this.fb.group({
|
|
4279
|
+
name: [criteria?.name || ''],
|
|
4280
|
+
description: [criteria?.description || ''],
|
|
4281
|
+
enabled: [criteria?.enabled ?? true],
|
|
4282
|
+
emoji: [criteria?.emoji || ''],
|
|
3837
4283
|
});
|
|
3838
4284
|
}
|
|
3839
4285
|
// Operations with Array
|
|
@@ -3899,7 +4345,7 @@ function createAgentTaskFormGroup(task) {
|
|
|
3899
4345
|
task: [task?.task || ''],
|
|
3900
4346
|
expectedResponseType: [task?.expectedResponseType || ''],
|
|
3901
4347
|
model: fb.group({
|
|
3902
|
-
quality: [task?.model?.quality || EModelQuality.
|
|
4348
|
+
quality: [task?.model?.quality || EModelQuality.FAST],
|
|
3903
4349
|
modelName: [task?.model?.modelName || ''],
|
|
3904
4350
|
provider: [task?.model?.provider || 'google'],
|
|
3905
4351
|
}),
|
|
@@ -3911,15 +4357,12 @@ class AgentTaskFormComponent {
|
|
|
3911
4357
|
this.formGroup = this.formGroupService.createSimpleAgentTaskFormGroup();
|
|
3912
4358
|
this.shortForm = false; // is short means AITask else SimpleAgentTask AiTaks is shorter
|
|
3913
4359
|
}
|
|
3914
|
-
ngOnInit() {
|
|
3915
|
-
console.log(this.formGroup);
|
|
3916
|
-
}
|
|
3917
4360
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentTaskFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3918
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentTaskFormComponent, isStandalone: true, selector: "agent-task-form", inputs: { formGroup: "formGroup", shortForm: "shortForm" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n
|
|
4361
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentTaskFormComponent, isStandalone: true, selector: "agent-task-form", inputs: { formGroup: "formGroup", shortForm: "shortForm" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" class=\"w-full\" /> Activada </div>\n\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n\n <textarea pTextarea [autoResize]=\"true\" class=\"w-full\" [formControl]=\"formGroup.controls?.task\"></textarea>\n </div>\n } @if(!shortForm && formGroup.controls?.expectedResponseType) {\n <div class=\"form-field\">\n <label for=\"expectedResponseType\" class=\"block text-sm font-medium text-gray-700\">Expected Response Type</label>\n <input pInputText id=\"expectedResponseType\" type=\"text\" [formControl]=\"formGroup.controls?.expectedResponseType\" class=\"w-full\" />\n </div>\n } @if (formGroup.controls?.model) {\n\n <dc-model-selector [modelForm]=\"formGroup.controls.model\" [shortForm]=\"shortForm\"></dc-model-selector>\n } @if (!shortForm && formGroup.controls?.systemPrompt) {\n <div class=\"form-field\">\n <label for=\"systemPrompt\" class=\"block text-sm font-medium text-gray-700 mb-1\">System Prompt</label>\n <input pInputText id=\"systemPrompt\" [formControl]=\"formGroup.controls?.systemPrompt\" class=\"w-full\" />\n </div>\n }\n</div>\n", styles: [":host{display:block}.form-field{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
3919
4362
|
}
|
|
3920
4363
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentTaskFormComponent, decorators: [{
|
|
3921
4364
|
type: Component,
|
|
3922
|
-
args: [{ selector: 'agent-task-form', imports: [TextareaModule, InputTextModule, ReactiveFormsModule, DropdownModule, ModelSelectorComponent, ModelSelectorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n
|
|
4365
|
+
args: [{ selector: 'agent-task-form', imports: [TextareaModule, InputTextModule, ReactiveFormsModule, DropdownModule, ModelSelectorComponent, ModelSelectorComponent, CheckboxModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" class=\"w-full\" /> Activada </div>\n\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n\n <textarea pTextarea [autoResize]=\"true\" class=\"w-full\" [formControl]=\"formGroup.controls?.task\"></textarea>\n </div>\n } @if(!shortForm && formGroup.controls?.expectedResponseType) {\n <div class=\"form-field\">\n <label for=\"expectedResponseType\" class=\"block text-sm font-medium text-gray-700\">Expected Response Type</label>\n <input pInputText id=\"expectedResponseType\" type=\"text\" [formControl]=\"formGroup.controls?.expectedResponseType\" class=\"w-full\" />\n </div>\n } @if (formGroup.controls?.model) {\n\n <dc-model-selector [modelForm]=\"formGroup.controls.model\" [shortForm]=\"shortForm\"></dc-model-selector>\n } @if (!shortForm && formGroup.controls?.systemPrompt) {\n <div class=\"form-field\">\n <label for=\"systemPrompt\" class=\"block text-sm font-medium text-gray-700 mb-1\">System Prompt</label>\n <input pInputText id=\"systemPrompt\" [formControl]=\"formGroup.controls?.systemPrompt\" class=\"w-full\" />\n </div>\n }\n</div>\n", styles: [":host{display:block}.form-field{margin:0}\n"] }]
|
|
3923
4366
|
}], propDecorators: { formGroup: [{
|
|
3924
4367
|
type: Input
|
|
3925
4368
|
}], shortForm: [{
|
|
@@ -3930,17 +4373,18 @@ class DcDoActionFormComponent {
|
|
|
3930
4373
|
constructor() {
|
|
3931
4374
|
this.removeItem = new EventEmitter();
|
|
3932
4375
|
this.doActionTypeOptions = DoActionTypeOptions;
|
|
4376
|
+
this.dynamicFlowTaskTypeOptions = DynamicFlowTaskTypeOptions;
|
|
3933
4377
|
this.EDoActionType = EDoActionType;
|
|
3934
4378
|
}
|
|
3935
4379
|
onRemoveItem() {
|
|
3936
4380
|
this.removeItem.emit({ conditionIndex: this.conditionIndex, doItemIndex: this.doItemIndex });
|
|
3937
4381
|
}
|
|
3938
4382
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDoActionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3939
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcDoActionFormComponent, isStandalone: true, selector: "dc-do-action-form", inputs: { formGroup: "formGroup", conditionIndex: "conditionIndex", doItemIndex: "doItemIndex", systemPromptTypeOptions: "systemPromptTypeOptions" }, outputs: { removeItem: "removeItem" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"bg-white shadow-md rounded-lg p-
|
|
4383
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcDoActionFormComponent, isStandalone: true, selector: "dc-do-action-form", inputs: { formGroup: "formGroup", conditionIndex: "conditionIndex", doItemIndex: "doItemIndex", systemPromptTypeOptions: "systemPromptTypeOptions" }, outputs: { removeItem: "removeItem" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"bg-white shadow-md rounded-lg p-5 mb-4 border border-gray-200\">\n <div class=\"flex justify-between items-center\">\n <h5 class=\"text-lg font-semibold text-gray-700\">Task {{ doItemIndex + 1 }}</h5>\n <button pButton type=\"button\" severity=\"danger\" icon=\"pi pi-trash\" (click)=\"onRemoveItem()\" class=\"p-button-sm p-button-text p-button-rounded\"></button>\n </div>\n <div class=\"space-y-4\">\n <!-- Action Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'actionType_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Action Type</label>\n <p-select\n [options]=\"doActionTypeOptions\"\n formControlName=\"actionType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Action Type'\"\n [id]=\"'actionType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n @switch (formGroup.get('actionType')?.value) { @case (EDoActionType.ChangePrompt) {\n <!-- System Prompt Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'systemPromptType_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">System Prompt Type</label>\n <p-select\n [options]=\"systemPromptTypeOptions\"\n formControlName=\"systemPromptType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select System Prompt Type'\"\n [id]=\"'systemPromptType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n <!-- Prompt -->\n <div class=\"flex flex-col\">\n <label [for]=\"'prompt_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Prompt</label>\n <textarea\n pTextarea\n [autoResize]=\"true\"\n [id]=\"'prompt_' + conditionIndex + '_' + doItemIndex\"\n formControlName=\"prompt\"\n rows=\"3\"\n class=\"w-full p-inputtext p-component rounded-md border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50\"></textarea>\n </div>\n } @case (EDoActionType.ChangeDynamicFlowTask) {\n <!-- Dynamic Flow Task Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'dynamicFlowTaskType_' + conditionIndex + '_' + doItemIndex\" class=\"mb-1 text-sm font-medium text-gray-600\">Dynamic Flow Task Type</label>\n <p-select\n [options]=\"dynamicFlowTaskTypeOptions\"\n formControlName=\"dynamicFlowTaskType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Dynamic Flow Task Type'\"\n [id]=\"'dynamicFlowTaskType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n <!-- Prompt -->\n <div class=\"flex flex-col\">\n <label [for]=\"'prompt_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Prompt</label>\n <textarea\n pTextarea\n [autoResize]=\"true\"\n [id]=\"'prompt_' + conditionIndex + '_' + doItemIndex\"\n formControlName=\"prompt\"\n rows=\"3\"\n class=\"w-full p-inputtext p-component rounded-md border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50\"></textarea>\n </div>\n\n <!-- Enabled -->\n <div class=\"flex items-center\">\n <p-checkbox [formControlName]=\"'enabled'\" [binary]=\"true\" [inputId]=\"'enabled_' + conditionIndex + '_' + doItemIndex\"></p-checkbox>\n <label [for]=\"'enabled_' + conditionIndex + '_' + doItemIndex\" class=\"ml-2 text-sm font-medium text-gray-700\">Enabled</label>\n </div>\n } }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
|
|
3940
4384
|
}
|
|
3941
4385
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDoActionFormComponent, decorators: [{
|
|
3942
4386
|
type: Component,
|
|
3943
|
-
args: [{ selector: 'dc-do-action-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, ButtonModule, SelectModule, TextareaModule, TooltipModule], template: "<div [formGroup]=\"formGroup\" class=\"bg-white shadow-md rounded-lg p-
|
|
4387
|
+
args: [{ selector: 'dc-do-action-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, ButtonModule, SelectModule, TextareaModule, TooltipModule, CheckboxModule], template: "<div [formGroup]=\"formGroup\" class=\"bg-white shadow-md rounded-lg p-5 mb-4 border border-gray-200\">\n <div class=\"flex justify-between items-center\">\n <h5 class=\"text-lg font-semibold text-gray-700\">Task {{ doItemIndex + 1 }}</h5>\n <button pButton type=\"button\" severity=\"danger\" icon=\"pi pi-trash\" (click)=\"onRemoveItem()\" class=\"p-button-sm p-button-text p-button-rounded\"></button>\n </div>\n <div class=\"space-y-4\">\n <!-- Action Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'actionType_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Action Type</label>\n <p-select\n [options]=\"doActionTypeOptions\"\n formControlName=\"actionType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Action Type'\"\n [id]=\"'actionType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n @switch (formGroup.get('actionType')?.value) { @case (EDoActionType.ChangePrompt) {\n <!-- System Prompt Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'systemPromptType_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">System Prompt Type</label>\n <p-select\n [options]=\"systemPromptTypeOptions\"\n formControlName=\"systemPromptType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select System Prompt Type'\"\n [id]=\"'systemPromptType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n <!-- Prompt -->\n <div class=\"flex flex-col\">\n <label [for]=\"'prompt_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Prompt</label>\n <textarea\n pTextarea\n [autoResize]=\"true\"\n [id]=\"'prompt_' + conditionIndex + '_' + doItemIndex\"\n formControlName=\"prompt\"\n rows=\"3\"\n class=\"w-full p-inputtext p-component rounded-md border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50\"></textarea>\n </div>\n } @case (EDoActionType.ChangeDynamicFlowTask) {\n <!-- Dynamic Flow Task Type -->\n <div class=\"flex flex-col\">\n <label [for]=\"'dynamicFlowTaskType_' + conditionIndex + '_' + doItemIndex\" class=\"mb-1 text-sm font-medium text-gray-600\">Dynamic Flow Task Type</label>\n <p-select\n [options]=\"dynamicFlowTaskTypeOptions\"\n formControlName=\"dynamicFlowTaskType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Dynamic Flow Task Type'\"\n [id]=\"'dynamicFlowTaskType_' + conditionIndex + '_' + doItemIndex\"\n styleClass=\"w-full\"\n [panelStyle]=\"{ width: '100%' }\"></p-select>\n </div>\n\n <!-- Prompt -->\n <div class=\"flex flex-col\">\n <label [for]=\"'prompt_' + conditionIndex + '_' + doItemIndex\" class=\"text-sm font-medium text-gray-600\">Prompt</label>\n <textarea\n pTextarea\n [autoResize]=\"true\"\n [id]=\"'prompt_' + conditionIndex + '_' + doItemIndex\"\n formControlName=\"prompt\"\n rows=\"3\"\n class=\"w-full p-inputtext p-component rounded-md border-gray-300 focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50\"></textarea>\n </div>\n\n <!-- Enabled -->\n <div class=\"flex items-center\">\n <p-checkbox [formControlName]=\"'enabled'\" [binary]=\"true\" [inputId]=\"'enabled_' + conditionIndex + '_' + doItemIndex\"></p-checkbox>\n <label [for]=\"'enabled_' + conditionIndex + '_' + doItemIndex\" class=\"ml-2 text-sm font-medium text-gray-700\">Enabled</label>\n </div>\n } }\n </div>\n</div>\n" }]
|
|
3944
4388
|
}], propDecorators: { formGroup: [{
|
|
3945
4389
|
type: Input,
|
|
3946
4390
|
args: [{ required: true }]
|
|
@@ -3997,7 +4441,7 @@ class DcDynamicConditionsFormComponent {
|
|
|
3997
4441
|
return control;
|
|
3998
4442
|
}
|
|
3999
4443
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDynamicConditionsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4000
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcDynamicConditionsFormComponent, isStandalone: true, selector: "dc-dynamic-conditions-form", inputs: { dynamicConditionsArray: "dynamicConditionsArray", dynamicConditionsPath: "dynamicConditionsPath", entityWhatOptions: "entityWhatOptions", entityWhenOptions: "entityWhenOptions", systemPromptTypeOptions: "systemPromptTypeOptions" }, ngImport: i0, template: "<div class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of dynamicConditionsArray.controls; track conditionControl; let i = $index) {\n <div class=\"group nested-group dynamic-condition-item\">\n <div class=\"flex justify-between items-center mb-4\">\n <h5>Condition {{ i + 1 }}</h5>\n <button\n pTooltip=\"Remove Condition\"\n variant=\"outlined\"\n [raised]=\"true\"\n pButton\n severity=\"danger\"\n icon=\"pi pi-trash\"\n (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhat' + i\"\n [options]=\"entityWhatOptions\"\n [formControl]=\"conditionControl.controls.what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhen' + i\"\n [options]=\"entityWhenOptions\"\n [formControl]=\"conditionControl.controls.when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionValue' + i\">Value <span pTooltip=\"Value to compare against\">\u2139\uFE0F</span></label>\n <input pInputText [id]=\"'conditionValue' + i\" type=\"text\" [formControl]=\"conditionControl.controls.value\" />\n </div>\n\n <div class=\"group very-nested-group\">\n <h6>DO THIS <span pTooltip=\"Tasks to execute if this condition is met\">\u2139\uFE0F</span></h6>\n @for (doControl of conditionControl.controls.do.controls; track doControl; let j = $index) {\n <dc-do-action-form\n [formGroup]=\"doControl\"\n [conditionIndex]=\"i\"\n [doItemIndex]=\"j\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\"\n (removeItem)=\"removeDoItem(i, j)\">\n </dc-do-action-form>\n }\n <button\n pButton\n type=\"button\"\n label=\"Add 'Do' Task\"\n icon=\"pi pi-plus\"\n (click)=\"addDoControl(conditionControl.controls.do)\"\n class=\"p-button-outlined p-button-sm\"\n style=\"margin-top: 10px\"></button>\n </div>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
|
|
4444
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcDynamicConditionsFormComponent, isStandalone: true, selector: "dc-dynamic-conditions-form", inputs: { dynamicConditionsArray: "dynamicConditionsArray", dynamicConditionsPath: "dynamicConditionsPath", entityWhatOptions: "entityWhatOptions", entityWhenOptions: "entityWhenOptions", systemPromptTypeOptions: "systemPromptTypeOptions" }, ngImport: i0, template: "<div class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of dynamicConditionsArray.controls; track conditionControl; let i = $index) {\n <div class=\"group nested-group dynamic-condition-item\">\n <div class=\"flex justify-between items-center mb-4\">\n <h5>Condition {{ i + 1 }}</h5>\n <button\n pTooltip=\"Remove Condition\"\n variant=\"outlined\"\n [raised]=\"true\"\n pButton\n severity=\"danger\"\n icon=\"pi pi-trash\"\n (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhat' + i\"\n [options]=\"entityWhatOptions\"\n [formControl]=\"conditionControl.controls.what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhen' + i\"\n [options]=\"entityWhenOptions\"\n [formControl]=\"conditionControl.controls.when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionValue' + i\">Value <span pTooltip=\"Value to compare against\">\u2139\uFE0F</span></label>\n <input pInputText [id]=\"'conditionValue' + i\" type=\"text\" [formControl]=\"conditionControl.controls.value\" />\n </div>\n\n <div class=\"group very-nested-group\">\n <h6>DO THIS <span pTooltip=\"Tasks to execute if this condition is met\">\u2139\uFE0F</span></h6>\n @for (doControl of conditionControl.controls.do.controls; track doControl; let j = $index) {\n <dc-do-action-form\n [formGroup]=\"doControl\"\n [conditionIndex]=\"i\"\n [doItemIndex]=\"j\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\"\n (removeItem)=\"removeDoItem(i, j)\">\n </dc-do-action-form>\n }\n <button\n pButton\n type=\"button\"\n label=\"Add 'Do' Task\"\n icon=\"pi pi-plus\"\n (click)=\"addDoControl(conditionControl.controls.do)\"\n class=\"p-button-outlined p-button-sm\"\n style=\"margin-top: 10px\"></button>\n </div>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
|
|
4001
4445
|
}
|
|
4002
4446
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDynamicConditionsFormComponent, decorators: [{
|
|
4003
4447
|
type: Component,
|
|
@@ -4019,6 +4463,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4019
4463
|
args: [{ required: true }]
|
|
4020
4464
|
}] } });
|
|
4021
4465
|
|
|
4466
|
+
class DcDynamicCriteriaFormComponent {
|
|
4467
|
+
constructor() {
|
|
4468
|
+
this.formGroupService = inject(FormGroupService);
|
|
4469
|
+
this.mode = 'free-text';
|
|
4470
|
+
this.availableItems = [];
|
|
4471
|
+
this.displayDialog = false;
|
|
4472
|
+
}
|
|
4473
|
+
openDialog() {
|
|
4474
|
+
if (this.mode === 'free-text') {
|
|
4475
|
+
this.addItem();
|
|
4476
|
+
}
|
|
4477
|
+
else {
|
|
4478
|
+
this.displayDialog = true;
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4481
|
+
addItem(item) {
|
|
4482
|
+
// In 'select' mode, an item is passed. In 'free-text', it's a new empty group.
|
|
4483
|
+
const newItem = this.formGroupService.createDynamicCriteriaFormGroup(item);
|
|
4484
|
+
this.formArray.push(newItem);
|
|
4485
|
+
this.displayDialog = false; // Close dialog if it was open
|
|
4486
|
+
}
|
|
4487
|
+
removeItem(index) {
|
|
4488
|
+
this.formArray.removeAt(index);
|
|
4489
|
+
}
|
|
4490
|
+
getItemFormGroup(index) {
|
|
4491
|
+
return this.formArray.at(index);
|
|
4492
|
+
}
|
|
4493
|
+
// Helper to safely cast to FormControl for the template
|
|
4494
|
+
getFormControl(control) {
|
|
4495
|
+
if (!(control instanceof FormControl)) {
|
|
4496
|
+
console.error('Expected a FormControl, but received:', control);
|
|
4497
|
+
return new FormControl(null);
|
|
4498
|
+
}
|
|
4499
|
+
return control;
|
|
4500
|
+
}
|
|
4501
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDynamicCriteriaFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4502
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcDynamicCriteriaFormComponent, isStandalone: true, selector: "dc-dynamic-criteria-form", inputs: { formArray: "formArray", title: "title", mode: "mode", availableItems: "availableItems" }, ngImport: i0, template: "<div class=\"\">\n <div class=\"flex justify-content-between align-items-center mb-4\">\n <h4 class=\"m-0 text-xl font-semibold\">{{ title }}</h4>\n <button pButton type=\"button\" (click)=\"openDialog()\" [label]=\"'Add ' + title\" class=\"p-button-sm\"></button>\n </div>\n\n @for (item of formArray.controls; track $index) {\n <div [formGroup]=\"getItemFormGroup($index)\" class=\"border-1 surface-border border-round p-4 mb-3\">\n <div class=\"grid formgrid\">\n <div class=\"col-12 mb-2 lg:col-6 lg:mb-0\">\n <label for=\"name-{{ $index }}\" class=\"block mb-2\">Name</label>\n <input id=\"name-{{ $index }}\" type=\"text\" pInputText formControlName=\"name\" class=\"w-full\" />\n </div>\n <div class=\"col-12 mb-2 lg:col-6 lg:mb-0\">\n <label for=\"emoji-{{ $index }}\" class=\"block mb-2\">Emoji</label>\n <input id=\"emoji-{{ $index }}\" type=\"text\" pInputText formControlName=\"emoji\" class=\"w-full\" />\n </div>\n\n <div class=\"col-12\">\n <label for=\"description-{{ $index }}\" class=\"block mb-2\">Description</label>\n <input id=\"description-{{ $index }}\" type=\"text\" pInputText formControlName=\"description\" class=\"w-full\" />\n </div>\n </div>\n\n <div class=\"col-12 flex justify-content-between items-center mt-2\">\n <div class=\"field-checkbox flex items-center\">\n <p-checkbox formControlName=\"enabled\" [binary]=\"true\" inputId=\"enabled-{{ $index }}\"></p-checkbox>\n <label for=\"enabled-{{ $index }}\" class=\"ml-2\">Enabled</label>\n </div>\n <button pButton type=\"button\" icon=\"pi pi-trash\" (click)=\"removeItem($index)\" class=\"p-button-danger p-button-sm\"></button>\n </div>\n </div>\n }\n\n <p-dialog [header]=\"'Select ' + title\" [(visible)]=\"displayDialog\" [modal]=\"true\" [style]=\"{ width: '50vw' }\">\n <div class=\"flex flex-col gap-3\">\n @for (item of availableItems; track $index) {\n <div class=\"flex justify-content-between align-items-center py-2 border-bottom-1 surface-border\">\n <div>\n <span class=\"font-semibold\">{{ item.emoji }} {{ item.name }}:</span>\n {{ item.description }}\n </div>\n <button pButton type=\"button\" label=\"Add\" (click)=\"addItem(item)\" class=\"p-button-sm\"></button>\n </div>\n }\n </div>\n </p-dialog>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$2.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }] }); }
|
|
4503
|
+
}
|
|
4504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcDynamicCriteriaFormComponent, decorators: [{
|
|
4505
|
+
type: Component,
|
|
4506
|
+
args: [{ selector: 'dc-dynamic-criteria-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, ButtonModule, InputTextModule, CheckboxModule, DialogModule], template: "<div class=\"\">\n <div class=\"flex justify-content-between align-items-center mb-4\">\n <h4 class=\"m-0 text-xl font-semibold\">{{ title }}</h4>\n <button pButton type=\"button\" (click)=\"openDialog()\" [label]=\"'Add ' + title\" class=\"p-button-sm\"></button>\n </div>\n\n @for (item of formArray.controls; track $index) {\n <div [formGroup]=\"getItemFormGroup($index)\" class=\"border-1 surface-border border-round p-4 mb-3\">\n <div class=\"grid formgrid\">\n <div class=\"col-12 mb-2 lg:col-6 lg:mb-0\">\n <label for=\"name-{{ $index }}\" class=\"block mb-2\">Name</label>\n <input id=\"name-{{ $index }}\" type=\"text\" pInputText formControlName=\"name\" class=\"w-full\" />\n </div>\n <div class=\"col-12 mb-2 lg:col-6 lg:mb-0\">\n <label for=\"emoji-{{ $index }}\" class=\"block mb-2\">Emoji</label>\n <input id=\"emoji-{{ $index }}\" type=\"text\" pInputText formControlName=\"emoji\" class=\"w-full\" />\n </div>\n\n <div class=\"col-12\">\n <label for=\"description-{{ $index }}\" class=\"block mb-2\">Description</label>\n <input id=\"description-{{ $index }}\" type=\"text\" pInputText formControlName=\"description\" class=\"w-full\" />\n </div>\n </div>\n\n <div class=\"col-12 flex justify-content-between items-center mt-2\">\n <div class=\"field-checkbox flex items-center\">\n <p-checkbox formControlName=\"enabled\" [binary]=\"true\" inputId=\"enabled-{{ $index }}\"></p-checkbox>\n <label for=\"enabled-{{ $index }}\" class=\"ml-2\">Enabled</label>\n </div>\n <button pButton type=\"button\" icon=\"pi pi-trash\" (click)=\"removeItem($index)\" class=\"p-button-danger p-button-sm\"></button>\n </div>\n </div>\n }\n\n <p-dialog [header]=\"'Select ' + title\" [(visible)]=\"displayDialog\" [modal]=\"true\" [style]=\"{ width: '50vw' }\">\n <div class=\"flex flex-col gap-3\">\n @for (item of availableItems; track $index) {\n <div class=\"flex justify-content-between align-items-center py-2 border-bottom-1 surface-border\">\n <div>\n <span class=\"font-semibold\">{{ item.emoji }} {{ item.name }}:</span>\n {{ item.description }}\n </div>\n <button pButton type=\"button\" label=\"Add\" (click)=\"addItem(item)\" class=\"p-button-sm\"></button>\n </div>\n }\n </div>\n </p-dialog>\n</div>\n" }]
|
|
4507
|
+
}], propDecorators: { formArray: [{
|
|
4508
|
+
type: Input,
|
|
4509
|
+
args: [{ required: true }]
|
|
4510
|
+
}], title: [{
|
|
4511
|
+
type: Input,
|
|
4512
|
+
args: [{ required: true }]
|
|
4513
|
+
}], mode: [{
|
|
4514
|
+
type: Input
|
|
4515
|
+
}], availableItems: [{
|
|
4516
|
+
type: Input
|
|
4517
|
+
}] } });
|
|
4518
|
+
|
|
4519
|
+
class FormatKeyPipe {
|
|
4520
|
+
transform(value) {
|
|
4521
|
+
if (!value) {
|
|
4522
|
+
return '';
|
|
4523
|
+
}
|
|
4524
|
+
// Converts camelCase or PascalCase to Title Case
|
|
4525
|
+
const result = value.replace(/([A-Z])/g, ' $1');
|
|
4526
|
+
return result.charAt(0).toUpperCase() + result.slice(1).trim();
|
|
4527
|
+
}
|
|
4528
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FormatKeyPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
4529
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.4", ngImport: i0, type: FormatKeyPipe, isStandalone: true, name: "formatKey" }); }
|
|
4530
|
+
}
|
|
4531
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FormatKeyPipe, decorators: [{
|
|
4532
|
+
type: Pipe,
|
|
4533
|
+
args: [{
|
|
4534
|
+
name: 'formatKey',
|
|
4535
|
+
standalone: true,
|
|
4536
|
+
}]
|
|
4537
|
+
}] });
|
|
4538
|
+
|
|
4022
4539
|
class DCConversationFlowFormComponent {
|
|
4023
4540
|
constructor() {
|
|
4024
4541
|
// Services
|
|
@@ -4026,23 +4543,30 @@ class DCConversationFlowFormComponent {
|
|
|
4026
4543
|
// Options vars
|
|
4027
4544
|
this.entityWhatOptions = EntityWhatOptions;
|
|
4028
4545
|
this.entityWhenOptions = EntityWhenOptions;
|
|
4546
|
+
this.validTools = [
|
|
4547
|
+
{
|
|
4548
|
+
name: 'ends',
|
|
4549
|
+
description: 'Enabled when the assistant ends the conversation by saying bye or something like that',
|
|
4550
|
+
enabled: true,
|
|
4551
|
+
},
|
|
4552
|
+
{
|
|
4553
|
+
name: 'getPerformance',
|
|
4554
|
+
description: 'Enabled when the agent gets the performance',
|
|
4555
|
+
enabled: true,
|
|
4556
|
+
},
|
|
4557
|
+
];
|
|
4029
4558
|
// FORM GROUP
|
|
4030
4559
|
this.formGroup = this.formGroupService.createConversationFlowFormGroup();
|
|
4031
4560
|
this.conversationEvents = ConversationEvents;
|
|
4032
4561
|
this.objectKeys = Object.keys;
|
|
4033
|
-
this.doActionTypeOptions = Object.values(EDoActionType).map((value) => ({ label:
|
|
4034
|
-
this.systemPromptTypeOptions = Object.values(SystemPromptType).map((value) => ({ label:
|
|
4562
|
+
this.doActionTypeOptions = Object.values(EDoActionType).map((value) => ({ label: value, value }));
|
|
4563
|
+
this.systemPromptTypeOptions = Object.values(SystemPromptType).map((value) => ({ label: value, value }));
|
|
4035
4564
|
}
|
|
4036
4565
|
ngOnInit() {
|
|
4037
4566
|
if (!this.formGroup) {
|
|
4038
4567
|
throw new Error('DCConversationFlowFormComponent requires a formGroup input.');
|
|
4039
4568
|
}
|
|
4040
4569
|
}
|
|
4041
|
-
formatEnumKey(key) {
|
|
4042
|
-
// Converts camelCase or PascalCase to Title Case
|
|
4043
|
-
const result = key.replace(/([A-Z])/g, ' $1');
|
|
4044
|
-
return result.charAt(0).toUpperCase() + result.slice(1).trim();
|
|
4045
|
-
}
|
|
4046
4570
|
removeArrayItem(controlPath, index) {
|
|
4047
4571
|
this.formGroupService.removeArrayItem(this.formGroup, controlPath, index);
|
|
4048
4572
|
}
|
|
@@ -4050,7 +4574,7 @@ class DCConversationFlowFormComponent {
|
|
|
4050
4574
|
console.log(this.formGroup.value);
|
|
4051
4575
|
}
|
|
4052
4576
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationFlowFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4053
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationFlowFormComponent, isStandalone: true, selector: "dc-conversation-flow-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"group
|
|
4577
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationFlowFormComponent, isStandalone: true, selector: "dc-conversation-flow-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"group\">\n <h3>Conversation Flow <span pTooltip=\"Define the flow and logic of the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\">Goal <span pTooltip=\"Aqu\u00ED se especifican las reglas de como se progresa en la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n\n <agent-task-form [formGroup]=\"formGroup.controls.goal\" [shortForm]=\"true\"></agent-task-form>\n </div>\n\n <details>\n <summary>Trigger Task (Tareas autom\u00E1ticas que se activan al conversar)</summary>\n\n <div formGroupName=\"triggerTasks\" class=\"group\">\n <h4\n >Trigger Tasks\n <span\n (click)=\"showData()\"\n pTooltip=\"Tareas que se ejecutan en eventos espec\u00EDficos de la conversaci\u00F3n como cuando el usuario env\u00EDa un mensaje, cuando el agente responde, etc. se visualizan normalmente en la secci\u00F3n de retro\"\n >\u2139\uFE0F</span\n ></h4\n >\n @for (eventKey of objectKeys(formGroup.controls.triggerTasks.controls); track eventKey) {\n <div class=\"form-field\">\n <label [for]=\"eventKey\">\n <b>{{ eventKey | formatKey }}</b>\n </label>\n <agent-task-form [formGroup]=\"formGroup.controls.triggerTasks.controls[eventKey]\" [shortForm]=\"true\"></agent-task-form>\n </div>\n }\n </div>\n </details>\n <details>\n <summary>Tools (Herramientas que usa la APP al ocurrir eventos)</summary>\n <dc-dynamic-criteria-form [formArray]=\"formGroup.controls.tools\" title=\"Tool\" mode=\"select\" [availableItems]=\"validTools\"> </dc-dynamic-criteria-form>\n </details>\n <details>\n <summary>Challenges (Mini Desafios al conversar)</summary>\n <dc-dynamic-criteria-form [formArray]=\"formGroup.controls.challenges\" title=\"Challenge\" mode=\"free-text\"> </dc-dynamic-criteria-form>\n </details>\n\n <dc-dynamic-conditions-form\n [dynamicConditionsArray]=\"formGroup.controls.dynamicConditions\"\n [dynamicConditionsPath]=\"'formGroup.controls.dynamicConditions'\"\n [entityWhatOptions]=\"entityWhatOptions\"\n [entityWhenOptions]=\"entityWhenOptions\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\">\n </dc-dynamic-conditions-form>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: AgentTaskFormComponent, selector: "agent-task-form", inputs: ["formGroup", "shortForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: DcDynamicConditionsFormComponent, selector: "dc-dynamic-conditions-form", inputs: ["dynamicConditionsArray", "dynamicConditionsPath", "entityWhatOptions", "entityWhenOptions", "systemPromptTypeOptions"] }, { kind: "component", type: DcDynamicCriteriaFormComponent, selector: "dc-dynamic-criteria-form", inputs: ["formArray", "title", "mode", "availableItems"] }, { kind: "pipe", type: FormatKeyPipe, name: "formatKey" }] }); }
|
|
4054
4578
|
}
|
|
4055
4579
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationFlowFormComponent, decorators: [{
|
|
4056
4580
|
type: Component,
|
|
@@ -4063,9 +4587,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4063
4587
|
TooltipModule,
|
|
4064
4588
|
AgentTaskFormComponent,
|
|
4065
4589
|
SelectModule,
|
|
4066
|
-
DcDoActionFormComponent,
|
|
4067
4590
|
DcDynamicConditionsFormComponent,
|
|
4068
|
-
|
|
4591
|
+
DcDynamicCriteriaFormComponent,
|
|
4592
|
+
FormatKeyPipe,
|
|
4593
|
+
], template: "<div [formGroup]=\"formGroup\" class=\"group\">\n <h3>Conversation Flow <span pTooltip=\"Define the flow and logic of the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\">Goal <span pTooltip=\"Aqu\u00ED se especifican las reglas de como se progresa en la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n\n <agent-task-form [formGroup]=\"formGroup.controls.goal\" [shortForm]=\"true\"></agent-task-form>\n </div>\n\n <details>\n <summary>Trigger Task (Tareas autom\u00E1ticas que se activan al conversar)</summary>\n\n <div formGroupName=\"triggerTasks\" class=\"group\">\n <h4\n >Trigger Tasks\n <span\n (click)=\"showData()\"\n pTooltip=\"Tareas que se ejecutan en eventos espec\u00EDficos de la conversaci\u00F3n como cuando el usuario env\u00EDa un mensaje, cuando el agente responde, etc. se visualizan normalmente en la secci\u00F3n de retro\"\n >\u2139\uFE0F</span\n ></h4\n >\n @for (eventKey of objectKeys(formGroup.controls.triggerTasks.controls); track eventKey) {\n <div class=\"form-field\">\n <label [for]=\"eventKey\">\n <b>{{ eventKey | formatKey }}</b>\n </label>\n <agent-task-form [formGroup]=\"formGroup.controls.triggerTasks.controls[eventKey]\" [shortForm]=\"true\"></agent-task-form>\n </div>\n }\n </div>\n </details>\n <details>\n <summary>Tools (Herramientas que usa la APP al ocurrir eventos)</summary>\n <dc-dynamic-criteria-form [formArray]=\"formGroup.controls.tools\" title=\"Tool\" mode=\"select\" [availableItems]=\"validTools\"> </dc-dynamic-criteria-form>\n </details>\n <details>\n <summary>Challenges (Mini Desafios al conversar)</summary>\n <dc-dynamic-criteria-form [formArray]=\"formGroup.controls.challenges\" title=\"Challenge\" mode=\"free-text\"> </dc-dynamic-criteria-form>\n </details>\n\n <dc-dynamic-conditions-form\n [dynamicConditionsArray]=\"formGroup.controls.dynamicConditions\"\n [dynamicConditionsPath]=\"'formGroup.controls.dynamicConditions'\"\n [entityWhatOptions]=\"entityWhatOptions\"\n [entityWhenOptions]=\"entityWhenOptions\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\">\n </dc-dynamic-conditions-form>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"] }]
|
|
4069
4594
|
}], ctorParameters: () => [], propDecorators: { formGroup: [{
|
|
4070
4595
|
type: Input
|
|
4071
4596
|
}] } });
|
|
@@ -4234,7 +4759,7 @@ Improve the following first message:`;
|
|
|
4234
4759
|
return control;
|
|
4235
4760
|
}
|
|
4236
4761
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcCharacterCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4237
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcCharacterCardFormComponent, isStandalone: true, selector: "dc-character-card-form", inputs: { characterCardForm: "characterCardForm" }, outputs: { generateMissingDataRequest: "generateMissingDataRequest" }, ngImport: i0, template: "<div [formGroup]=\"characterCardForm\" class=\"p-6 bg-teal-50 min-h-screen\">\n <div formGroupName=\"data\" class=\"card-group space-y-6 bg-white p-8 rounded-lg shadow-md\">\n <div class=\"flex justify-end\">\n <p-button\n (click)=\"generateMissingDataRequest.emit()\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\"\n label=\"Arreglar Campos\"\n styleClass=\"p-button-sm\" />\n </div>\n\n <h3 class=\"text-2xl font-semibold text-gray-700 mb-6\"\n >Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></h3\n >\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Name <span pTooltip=\"El nombre del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <input\n pInputText\n id=\"cardName\"\n type=\"text\"\n formControlName=\"name\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" />\n @if (dataGroup.controls['name']?.errors?.['required'] && dataGroup.controls['name']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardDescription\" class=\"block text-sm font-medium text-gray-700\"\n >Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n class=\"textmin mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"\n rows=\"3\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardDescription\"\n formControlName=\"description\"></textarea>\n @if (dataGroup.controls['description']?.errors?.['required'] && dataGroup.controls['description']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardScenario\" class=\"block text-sm font-medium text-gray-700\"\n >Scenario <span pTooltip=\"Describe the context or setting for the conversation\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardScenario\"\n formControlName=\"scenario\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >First Message\n <span\n pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></span\n >\n <div class=\"flex items-center space-x-2\">\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown'\"\n size=\"small\"\n styleClass=\"min-w-16 p-button-sm\"\n (onChange)=\"checkCdr()\" />\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\" styleClass=\"p-button-sm p-button-outlined\"></p-button>\n </div>\n </div>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"dataGroup.controls['first_mes'].value | mdToHtmlArray\" class=\"prose mt-1 p-3 border border-gray-200 rounded-md\"></div>\n }@else{\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardFirstMessage\"\n formControlName=\"first_mes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\">\n </textarea>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"mes_example\" class=\"block text-sm font-medium text-gray-700\"\n >Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"mes_example\"\n formControlName=\"mes_example\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardCreatorNotes\" class=\"block text-sm font-medium text-gray-700\"\n >Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardCreatorNotes\"\n formControlName=\"creator_notes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardSystemPrompt\" class=\"block text-sm font-medium text-gray-700\"\n >System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardSystemPrompt\"\n formControlName=\"system_prompt\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n @if (dataGroup.controls['system_prompt']?.errors?.['required'] && dataGroup.controls['system_prompt']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> System prompt is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label class=\"block text-sm font-medium text-gray-700\">Image Description</label>\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"picture_description\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardPostHistoryInstructions\" class=\"block text-sm font-medium text-gray-700\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"post_history_instructions\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field space-y-2\">\n @for (greeting of alternateGreetingsArray.controls; track greeting; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"asFormControl(greeting)\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\">\n </textarea>\n <button\n pButton\n severity=\"danger\"\n icon=\"pi pi-times\"\n class=\"remove-button p-button-sm p-button-rounded p-button-danger\"\n (click)=\"removeArrayItem('alternate_greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('alternate_greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium text-gray-700\">Tags \u2139\uFE0F</label>\n <div class=\"array-field space-y-2\">\n @for (tag of tagsArray.controls; track tag; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\">\n <input\n pInputText\n [id]=\"'cardTag' + i\"\n type=\"text\"\n [formControl]=\"asFormControl(tag)\"\n (input)=\"updateArrayField('tags', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\" />\n <button pButton severity=\"danger\" label=\"Remove\" icon=\"pi pi-times\" (click)=\"removeArrayItem('tags', i)\" class=\"p-button-sm\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Tag\" icon=\"pi pi-plus\" (click)=\"addArrayItem('tags')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".textmin{min-height:40px}.array-field{display:flex;flex-direction:column;gap:8px}.array-item{display:flex;align-items:center;gap:8px;position:relative}.array-item textarea,.array-item input[type=text]{flex-grow:1}.remove-button{position:absolute;right:5px;top:5px;min-width:auto!important;width:2rem;height:2rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "disabled", "style", "styleClass", "inputId", "tabindex", "size", "iconPos", "autofocus", "allowEmpty"], outputs: ["onChange"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }] }); }
|
|
4762
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcCharacterCardFormComponent, isStandalone: true, selector: "dc-character-card-form", inputs: { characterCardForm: "characterCardForm" }, outputs: { generateMissingDataRequest: "generateMissingDataRequest" }, ngImport: i0, template: "<div [formGroup]=\"characterCardForm\" class=\"p-6 bg-teal-50 min-h-screen\">\n <div formGroupName=\"data\" class=\"card-group space-y-6 bg-white p-8 rounded-lg shadow-md\">\n <div class=\"flex justify-end\">\n <p-button\n (click)=\"generateMissingDataRequest.emit()\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\"\n label=\"Arreglar Campos\"\n styleClass=\"p-button-sm\" />\n </div>\n\n <h3 class=\"text-2xl font-semibold text-gray-700 mb-6\"\n >Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></h3\n >\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Name <span pTooltip=\"El nombre del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <input\n pInputText\n id=\"cardName\"\n type=\"text\"\n formControlName=\"name\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" />\n @if (dataGroup.controls['name']?.errors?.['required'] && dataGroup.controls['name']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardDescription\" class=\"block text-sm font-medium text-gray-700\"\n >Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n class=\"textmin mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"\n rows=\"3\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardDescription\"\n formControlName=\"description\"></textarea>\n @if (dataGroup.controls['description']?.errors?.['required'] && dataGroup.controls['description']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardScenario\" class=\"block text-sm font-medium text-gray-700\"\n >Scenario <span pTooltip=\"Describe the context or setting for the conversation\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardScenario\"\n formControlName=\"scenario\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >First Message\n <span\n pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></span\n >\n <div class=\"flex items-center space-x-2\">\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown'\"\n size=\"small\"\n styleClass=\"min-w-16 p-button-sm\"\n (onChange)=\"checkCdr()\" />\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\" styleClass=\"p-button-sm p-button-outlined\"></p-button>\n </div>\n </div>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"dataGroup.controls['first_mes'].value | mdToHtmlArray\" class=\"prose mt-1 p-3 border border-gray-200 rounded-md\"></div>\n }@else{\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardFirstMessage\"\n formControlName=\"first_mes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\">\n </textarea>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"mes_example\" class=\"block text-sm font-medium text-gray-700\"\n >Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"mes_example\"\n formControlName=\"mes_example\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardCreatorNotes\" class=\"block text-sm font-medium text-gray-700\"\n >Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardCreatorNotes\"\n formControlName=\"creator_notes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardSystemPrompt\" class=\"block text-sm font-medium text-gray-700\"\n >System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardSystemPrompt\"\n formControlName=\"system_prompt\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n @if (dataGroup.controls['system_prompt']?.errors?.['required'] && dataGroup.controls['system_prompt']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> System prompt is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label class=\"block text-sm font-medium text-gray-700\">Image Description</label>\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"picture_description\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardPostHistoryInstructions\" class=\"block text-sm font-medium text-gray-700\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"post_history_instructions\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field space-y-2\">\n @for (greeting of alternateGreetingsArray.controls; track greeting; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"asFormControl(greeting)\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\">\n </textarea>\n <button\n pButton\n severity=\"danger\"\n icon=\"pi pi-times\"\n class=\"remove-button p-button-sm p-button-rounded p-button-danger\"\n (click)=\"removeArrayItem('alternate_greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('alternate_greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium text-gray-700\">Tags \u2139\uFE0F</label>\n <div class=\"array-field space-y-2\">\n @for (tag of tagsArray.controls; track tag; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\">\n <input\n pInputText\n [id]=\"'cardTag' + i\"\n type=\"text\"\n [formControl]=\"asFormControl(tag)\"\n (input)=\"updateArrayField('tags', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\" />\n <button pButton severity=\"danger\" label=\"Remove\" icon=\"pi pi-times\" (click)=\"removeArrayItem('tags', i)\" class=\"p-button-sm\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Tag\" icon=\"pi pi-plus\" (click)=\"addArrayItem('tags')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".textmin{min-height:40px}.array-field{display:flex;flex-direction:column;gap:8px}.array-item{display:flex;align-items:center;gap:8px;position:relative}.array-item textarea,.array-item input[type=text]{flex-grow:1}.remove-button{position:absolute;right:5px;top:5px;min-width:auto!important;width:2rem;height:2rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "disabled", "style", "styleClass", "inputId", "tabindex", "size", "iconPos", "autofocus", "allowEmpty"], outputs: ["onChange"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }] }); }
|
|
4238
4763
|
}
|
|
4239
4764
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcCharacterCardFormComponent, decorators: [{
|
|
4240
4765
|
type: Component,
|
|
@@ -4274,7 +4799,7 @@ class DcVoiceTtsFormComponent {
|
|
|
4274
4799
|
});
|
|
4275
4800
|
}
|
|
4276
4801
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcVoiceTtsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4277
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DcVoiceTtsFormComponent, isStandalone: true, selector: "dc-voice-tts-form", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, voiceTTSOptions: { classPropertyName: "voiceTTSOptions", publicName: "voiceTTSOptions", isSignal: true, isRequired: false, transformFunction: null } }, providers: [DialogService], ngImport: i0, template: "<h3> {{ title() }}</h3>\n<div [formGroup]=\"form()\" class=\"form-grid\">\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the voice for text-to-speech\">\u2139\uFE0F</span></label>\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector()\" />\n </p-inputgroup-addon>\n <p-select\n id=\"voice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions()\"\n formControlName=\"voice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Voice'\" />\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speedRate\">Speed Rate <span pTooltip=\"Adjust the rate of speech delivery\">\u2139\uFE0F</span></label>\n <br />\n <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.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: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i3$3.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i4$
|
|
4802
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DcVoiceTtsFormComponent, isStandalone: true, selector: "dc-voice-tts-form", inputs: { form: { classPropertyName: "form", publicName: "form", isSignal: true, isRequired: true, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, voiceTTSOptions: { classPropertyName: "voiceTTSOptions", publicName: "voiceTTSOptions", isSignal: true, isRequired: false, transformFunction: null } }, providers: [DialogService], ngImport: i0, template: "<h3> {{ title() }}</h3>\n<div [formGroup]=\"form()\" class=\"form-grid\">\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the voice for text-to-speech\">\u2139\uFE0F</span></label>\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector()\" />\n </p-inputgroup-addon>\n <p-select\n id=\"voice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions()\"\n formControlName=\"voice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Voice'\" />\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speedRate\">Speed Rate <span pTooltip=\"Adjust the rate of speech delivery\">\u2139\uFE0F</span></label>\n <br />\n <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i3$3.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i4$3.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CardModule }] }); }
|
|
4278
4803
|
}
|
|
4279
4804
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcVoiceTtsFormComponent, decorators: [{
|
|
4280
4805
|
type: Component,
|
|
@@ -4350,7 +4875,7 @@ class DcConversationSettingsFormComponent {
|
|
|
4350
4875
|
});
|
|
4351
4876
|
}
|
|
4352
4877
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcConversationSettingsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4353
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: DcConversationSettingsFormComponent, isStandalone: true, selector: "dc-conversation-settings-form", inputs: { form: "form", textEngineOptions: "textEngineOptions", conversationOptions: "conversationOptions", voiceTTSOptions: "voiceTTSOptions" }, providers: [DialogService], ngImport: i0, template: "<div [formGroup]=\"form\" class=\"p-6 bg-white rounded-lg shadow-md space-y-6\">\n <h3 class=\"text-xl font-bold text-gray-900 border-b pb-2\">\n Conversation Settings\n <span pTooltip=\"Additional information about the conversation\" class=\"text-blue-500 cursor-help text-sm\">\u2139\uFE0F</span>\n </h3>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label for=\"conversationType\" class=\"block text-sm font-medium text-gray-700\">\n Conversation Type\n <span class=\"cursor-pointer text-blue-500\" (click)=\"openConversationTypeDialog()\" pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"\n styleClass=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium text-gray-700\">\n Text Engine\n <span\n class=\"cursor-pointer text-blue-500\"\n (click)=\"textEngineDialog.toggle($event)\"\n pTooltip=\"Sistema de generaci\u00F3n de texto y audios. Client: el cliente llama al servidor en cada dialogo de voz/personaje, es optimo para historias, Server SSML: se sintetiza todo el audio en uno solo con los distintos cambios de voz/personaje, util para la reflexi\u00F3n porque es bilingue, utiliza dialogos en ingles y espa\u00F1ol en el mismo dialogo/audio\"\n >\u2139\uFE0F</span\n >\n </label>\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"\n styleClass=\"w-full mt-1\"></p-select>\n </div>\n\n <div class=\"flex items-center justify-between md:col-span-2\">\n <label class=\"text-sm font-medium text-gray-700\">\n Auto Start\n <span pTooltip=\"Start conversation automatically\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"autoStart\"></p-toggleSwitch>\n </div>\n </div>\n\n <hr />\n\n <dc-voice-tts-form [form]=\"mainVoiceFormGroup\" [title]=\"'Main Voice TTS Settings'\" [voiceTTSOptions]=\"voiceTTSOptions\"></dc-voice-tts-form>\n\n <dc-voice-tts-form [form]=\"secondaryVoiceFormGroup\" [title]=\"'Secondary Voice TTS Settings'\" [voiceTTSOptions]=\"voiceTTSOptions\"></dc-voice-tts-form>\n\n <hr />\n\n <dc-model-selector [modelForm]=\"modelFormGroup\" [shortForm]=\"true\"></dc-model-selector>\n</div>\n\n<p-popover #textEngineDialog [style]=\"{ width: '350px' }\" header=\"Text Engine Information\">\n <ng-template pTemplate=\"content\">\n <div class=\"p-4\">\n <h3 class=\"text-md font-semibold mb-3 text-gray-800\">Text Engine Types</h3>\n <ul class=\"space-y-3 text-sm text-gray-600\">\n <li>\n <strong class=\"font-semibold text-gray-900\">Texto Simple:</strong>\n La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">Multi Mensajes:</strong>\n Utiliza markdown (recomendable entenderlo), para dar formato al texto. El sistema puede partir dialogos con distinto formato (normal, cursiva,\n negritas) para generar distintas voces y estilos para el narrador y personaje.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">MD SSML:</strong>\n Markdown con SSML. Similar a Multi Mensajes, pero se presenta en un solo mensaje y la voz se genera para toda la linea. \u00DAtil para conversaciones\n biling\u00FCes.\n </li>\n </ul>\n </div>\n </ng-template>\n</p-popover>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$
|
|
4878
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: DcConversationSettingsFormComponent, isStandalone: true, selector: "dc-conversation-settings-form", inputs: { form: "form", textEngineOptions: "textEngineOptions", conversationOptions: "conversationOptions", voiceTTSOptions: "voiceTTSOptions" }, providers: [DialogService], ngImport: i0, template: "<div [formGroup]=\"form\" class=\"p-6 bg-white rounded-lg shadow-md space-y-6\">\n <h3 class=\"text-xl font-bold text-gray-900 border-b pb-2\">\n Conversation Settings\n <span pTooltip=\"Additional information about the conversation\" class=\"text-blue-500 cursor-help text-sm\">\u2139\uFE0F</span>\n </h3>\n\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-6\">\n <div>\n <label for=\"conversationType\" class=\"block text-sm font-medium text-gray-700\">\n Conversation Type\n <span class=\"cursor-pointer text-blue-500\" (click)=\"openConversationTypeDialog()\" pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"\n styleClass=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium text-gray-700\">\n Text Engine\n <span\n class=\"cursor-pointer text-blue-500\"\n (click)=\"textEngineDialog.toggle($event)\"\n pTooltip=\"Sistema de generaci\u00F3n de texto y audios. Client: el cliente llama al servidor en cada dialogo de voz/personaje, es optimo para historias, Server SSML: se sintetiza todo el audio en uno solo con los distintos cambios de voz/personaje, util para la reflexi\u00F3n porque es bilingue, utiliza dialogos en ingles y espa\u00F1ol en el mismo dialogo/audio\"\n >\u2139\uFE0F</span\n >\n </label>\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"\n styleClass=\"w-full mt-1\"></p-select>\n </div>\n\n <div class=\"flex items-center justify-between md:col-span-2\">\n <label class=\"text-sm font-medium text-gray-700\">\n Auto Start\n <span pTooltip=\"Start conversation automatically\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"autoStart\"></p-toggleSwitch>\n </div>\n </div>\n\n <hr />\n\n <dc-voice-tts-form [form]=\"mainVoiceFormGroup\" [title]=\"'Main Voice TTS Settings'\" [voiceTTSOptions]=\"voiceTTSOptions\"></dc-voice-tts-form>\n\n <dc-voice-tts-form [form]=\"secondaryVoiceFormGroup\" [title]=\"'Secondary Voice TTS Settings'\" [voiceTTSOptions]=\"voiceTTSOptions\"></dc-voice-tts-form>\n\n <hr />\n\n <dc-model-selector [modelForm]=\"modelFormGroup\" [shortForm]=\"true\"></dc-model-selector>\n</div>\n\n<p-popover #textEngineDialog [style]=\"{ width: '350px' }\" header=\"Text Engine Information\">\n <ng-template pTemplate=\"content\">\n <div class=\"p-4\">\n <h3 class=\"text-md font-semibold mb-3 text-gray-800\">Text Engine Types</h3>\n <ul class=\"space-y-3 text-sm text-gray-600\">\n <li>\n <strong class=\"font-semibold text-gray-900\">Texto Simple:</strong>\n La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">Multi Mensajes:</strong>\n Utiliza markdown (recomendable entenderlo), para dar formato al texto. El sistema puede partir dialogos con distinto formato (normal, cursiva,\n negritas) para generar distintas voces y estilos para el narrador y personaje.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">MD SSML:</strong>\n Markdown con SSML. Similar a Multi Mensajes, pero se presenta en un solo mensaje y la voz se genera para toda la linea. \u00DAtil para conversaciones\n biling\u00FCes.\n </li>\n </ul>\n </div>\n </ng-template>\n</p-popover>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$3.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["style", "styleClass", "tabindex", "inputId", "name", "disabled", "readonly", "trueValue", "falseValue", "ariaLabel", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i6$1.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }, { kind: "component", type: DcVoiceTtsFormComponent, selector: "dc-voice-tts-form", inputs: ["form", "title", "voiceTTSOptions"] }] }); }
|
|
4354
4879
|
}
|
|
4355
4880
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcConversationSettingsFormComponent, decorators: [{
|
|
4356
4881
|
type: Component,
|
|
@@ -4391,14 +4916,14 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
|
|
|
4391
4916
|
this.fb = inject(FormBuilder);
|
|
4392
4917
|
this.entityCommunicationService = inject(CONVERSATION_AI_TOKEN);
|
|
4393
4918
|
this.dialogService = inject(DialogService);
|
|
4394
|
-
this.promptBuilder = inject(
|
|
4919
|
+
this.promptBuilder = inject(ConversationPromptBuilderService);
|
|
4395
4920
|
this.toastService = inject(TOAST_ALERTS_TOKEN, { optional: true });
|
|
4396
4921
|
this.formGroupService = inject(FormGroupService);
|
|
4397
4922
|
// select options
|
|
4398
4923
|
this.conversationOptions = ConversationTypeOptions;
|
|
4399
4924
|
this.voiceTTSOptions = Object.values(VoiceTTSOptions);
|
|
4400
4925
|
this.textEngineOptions = TextEngineOptions;
|
|
4401
|
-
this.languageOptions =
|
|
4926
|
+
this.languageOptions = getSupportedLanguageOptions('es');
|
|
4402
4927
|
this.storageSettings = input(this.getSettings());
|
|
4403
4928
|
this.onSave = output();
|
|
4404
4929
|
this.onGoDetails = output();
|
|
@@ -4414,15 +4939,6 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
|
|
|
4414
4939
|
get conversationSettings() {
|
|
4415
4940
|
return this.form.get('conversationSettings');
|
|
4416
4941
|
}
|
|
4417
|
-
get characterCard() {
|
|
4418
|
-
return this.form.get('characterCard');
|
|
4419
|
-
}
|
|
4420
|
-
get conversationFlow() {
|
|
4421
|
-
return this.form.get('conversationFlow');
|
|
4422
|
-
}
|
|
4423
|
-
get accounts() {
|
|
4424
|
-
return this.form.get('accounts');
|
|
4425
|
-
}
|
|
4426
4942
|
async save() {
|
|
4427
4943
|
const result = await super.save();
|
|
4428
4944
|
if (result) {
|
|
@@ -4574,7 +5090,7 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
|
|
|
4574
5090
|
const jsonData = response.content;
|
|
4575
5091
|
if (jsonData) {
|
|
4576
5092
|
this.toastService.success({ title: 'Character generated', subtitle: 'No te olvides de guardar cambios si estas seguro' });
|
|
4577
|
-
this.characterCard.patchValue({ data: jsonData });
|
|
5093
|
+
this.form.controls.characterCard.patchValue({ data: jsonData });
|
|
4578
5094
|
}
|
|
4579
5095
|
else {
|
|
4580
5096
|
this.toastService.error({
|
|
@@ -4594,13 +5110,13 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
|
|
|
4594
5110
|
this.entity.update((card) => ({ ...card, assets: event }));
|
|
4595
5111
|
}
|
|
4596
5112
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCAgentCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4597
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", inputs: { storageSettings: { classPropertyName: "storageSettings", publicName: "storageSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSave: "onSave", onGoDetails: "onGoDetails", onTranslate: "onTranslate" }, providers: [DialogService], usesInheritance: true, ngImport: i0, template: "<p-card>\n <div class=\"top-buttons\">\n <button pButton severity=\"info\" (click)=\"checkPrompt()\" label=\"\uD83D\uDC41\uFE0F Ver instrucciones finales \uD83D\uDCD3\"></button>\n\n <button pButton severity=\"info\" (click)=\"goToDetails()\" label=\"\uD83D\uDCAC Conversar\"></button>\n <button pButton severity=\"primary\" (click)=\"save()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating()\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div title=\"Main data\" style=\"border: 1px dashed #0c138e1f; padding: 4px; border-radius: 15px\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.get('title').errors?.['required'] && form.get('title').touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\">Description <span pTooltip=\"Description of the conversation\">\u2139\uFE0F</span></label>\n <input pInputText id=\"description\" type=\"text\" formControlName=\"description\" />\n @if(form.get('description').errors?.['required'] && form.get('description').touched){\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"conversationSettings\"\n [textEngineOptions]=\"textEngineOptions\"\n [conversationOptions]=\"conversationOptions\"\n [voiceTTSOptions]=\"voiceTTSOptions\">\n </dc-conversation-settings-form>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(accounts){\n <account-platform-form [formArray]=\"accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(conversationFlow){\n <div class=\"group\">\n <dc-conversation-flow-form [formGroup]=\"conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n @if(entity() && entityId()){\n <assets-loader\n [assets]=\"entity().assets\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onUpdateAsset($event)\"\n (onFileSelected)=\"onImageSelected($event)\"></assets-loader>\n } @if(characterCard){\n <dc-character-card-form [characterCardForm]=\"characterCard\" (generateMissingDataRequest)=\"generateMissingData()\"> </dc-character-card-form>\n }\n </div>\n </div>\n </form>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"save()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{padding:1rem;border-radius:4px;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.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: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: CsaAssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "ngmodule", type: PortalModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$2.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "component", type: AccountPlatformForm, selector: "account-platform-form", inputs: ["formArray"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$3.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: DCConversationFlowFormComponent, selector: "dc-conversation-flow-form", inputs: ["formGroup"] }, { kind: "component", type: DcCharacterCardFormComponent, selector: "dc-character-card-form", inputs: ["characterCardForm"], outputs: ["generateMissingDataRequest"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i8.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled", "fluid"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: DcConversationSettingsFormComponent, selector: "dc-conversation-settings-form", inputs: ["form", "textEngineOptions", "conversationOptions", "voiceTTSOptions"] }] }); }
|
|
5113
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", inputs: { storageSettings: { classPropertyName: "storageSettings", publicName: "storageSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSave: "onSave", onGoDetails: "onGoDetails", onTranslate: "onTranslate" }, providers: [DialogService], usesInheritance: true, ngImport: i0, template: "<p-card>\n <div class=\"top-buttons\">\n <button pButton severity=\"info\" (click)=\"checkPrompt()\" label=\"\uD83D\uDC41\uFE0F Ver instrucciones finales \uD83D\uDCD3\"></button>\n\n <button pButton severity=\"info\" (click)=\"goToDetails()\" label=\"\uD83D\uDCAC Conversar\"></button>\n <button pButton severity=\"primary\" (click)=\"save()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating()\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div title=\"Main data\" style=\"border: 1px dashed #0c138e1f; padding: 4px; border-radius: 15px\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.get('title').errors?.['required'] && form.get('title').touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\">Description <span pTooltip=\"Description of the conversation\">\u2139\uFE0F</span></label>\n <input pInputText id=\"description\" type=\"text\" formControlName=\"description\" />\n @if(form.get('description').errors?.['required'] && form.get('description').touched){\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"conversationSettings\"\n [textEngineOptions]=\"textEngineOptions\"\n [conversationOptions]=\"conversationOptions\"\n [voiceTTSOptions]=\"voiceTTSOptions\">\n </dc-conversation-settings-form>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(form.controls.conversationFlow){\n <div class=\"group rounded-lg shadow-lg\">\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n @if(entity() && entityId()){\n <assets-loader\n [assets]=\"entity().assets\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onUpdateAsset($event)\"\n (onFileSelected)=\"onImageSelected($event)\"></assets-loader>\n } @if(form.controls.characterCard){\n <dc-character-card-form [characterCardForm]=\"form.controls.characterCard\" (generateMissingDataRequest)=\"generateMissingData()\">\n </dc-character-card-form>\n }\n </div>\n </div>\n </form>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"save()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{padding:1rem;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.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: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: AssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "ngmodule", type: PortalModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5$1.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "component", type: AccountPlatformForm, selector: "account-platform-form", inputs: ["formArray"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$2.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: DCConversationFlowFormComponent, selector: "dc-conversation-flow-form", inputs: ["formGroup"] }, { kind: "component", type: DcCharacterCardFormComponent, selector: "dc-character-card-form", inputs: ["characterCardForm"], outputs: ["generateMissingDataRequest"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i8.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled", "fluid"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: DcConversationSettingsFormComponent, selector: "dc-conversation-settings-form", inputs: ["form", "textEngineOptions", "conversationOptions", "voiceTTSOptions"] }] }); }
|
|
4598
5114
|
}
|
|
4599
5115
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCAgentCardFormComponent, decorators: [{
|
|
4600
5116
|
type: Component,
|
|
4601
5117
|
args: [{ selector: 'dc-agent-form', standalone: true, providers: [DialogService], imports: [
|
|
4602
5118
|
ReactiveFormsModule,
|
|
4603
|
-
|
|
5119
|
+
AssetsLoaderComponent,
|
|
4604
5120
|
OverlayModule,
|
|
4605
5121
|
PortalModule,
|
|
4606
5122
|
ButtonModule,
|
|
@@ -4619,7 +5135,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4619
5135
|
FileUploadModule,
|
|
4620
5136
|
MessageModule,
|
|
4621
5137
|
DcConversationSettingsFormComponent,
|
|
4622
|
-
], template: "<p-card>\n <div class=\"top-buttons\">\n <button pButton severity=\"info\" (click)=\"checkPrompt()\" label=\"\uD83D\uDC41\uFE0F Ver instrucciones finales \uD83D\uDCD3\"></button>\n\n <button pButton severity=\"info\" (click)=\"goToDetails()\" label=\"\uD83D\uDCAC Conversar\"></button>\n <button pButton severity=\"primary\" (click)=\"save()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating()\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div title=\"Main data\" style=\"border: 1px dashed #0c138e1f; padding: 4px; border-radius: 15px\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.get('title').errors?.['required'] && form.get('title').touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\">Description <span pTooltip=\"Description of the conversation\">\u2139\uFE0F</span></label>\n <input pInputText id=\"description\" type=\"text\" formControlName=\"description\" />\n @if(form.get('description').errors?.['required'] && form.get('description').touched){\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"conversationSettings\"\n [textEngineOptions]=\"textEngineOptions\"\n [conversationOptions]=\"conversationOptions\"\n [voiceTTSOptions]=\"voiceTTSOptions\">\n </dc-conversation-settings-form>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(accounts){\n <account-platform-form [formArray]=\"accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(conversationFlow){\n <div class=\"group\">\n <dc-conversation-flow-form [formGroup]=\"conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n @if(entity() && entityId()){\n <assets-loader\n [assets]=\"entity().assets\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onUpdateAsset($event)\"\n (onFileSelected)=\"onImageSelected($event)\"></assets-loader>\n } @if(characterCard){\n <dc-character-card-form [characterCardForm]=\"characterCard\" (generateMissingDataRequest)=\"generateMissingData()\"
|
|
5138
|
+
], template: "<p-card>\n <div class=\"top-buttons\">\n <button pButton severity=\"info\" (click)=\"checkPrompt()\" label=\"\uD83D\uDC41\uFE0F Ver instrucciones finales \uD83D\uDCD3\"></button>\n\n <button pButton severity=\"info\" (click)=\"goToDetails()\" label=\"\uD83D\uDCAC Conversar\"></button>\n <button pButton severity=\"primary\" (click)=\"save()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating()\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div title=\"Main data\" style=\"border: 1px dashed #0c138e1f; padding: 4px; border-radius: 15px\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.get('title').errors?.['required'] && form.get('title').touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\">Description <span pTooltip=\"Description of the conversation\">\u2139\uFE0F</span></label>\n <input pInputText id=\"description\" type=\"text\" formControlName=\"description\" />\n @if(form.get('description').errors?.['required'] && form.get('description').touched){\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"conversationSettings\"\n [textEngineOptions]=\"textEngineOptions\"\n [conversationOptions]=\"conversationOptions\"\n [voiceTTSOptions]=\"voiceTTSOptions\">\n </dc-conversation-settings-form>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(form.controls.conversationFlow){\n <div class=\"group rounded-lg shadow-lg\">\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n @if(entity() && entityId()){\n <assets-loader\n [assets]=\"entity().assets\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (assetsChange)=\"onAssetsChange($event)\"\n (assetUpdate)=\"onUpdateAsset($event)\"\n (onFileSelected)=\"onImageSelected($event)\"></assets-loader>\n } @if(form.controls.characterCard){\n <dc-character-card-form [characterCardForm]=\"form.controls.characterCard\" (generateMissingDataRequest)=\"generateMissingData()\">\n </dc-character-card-form>\n }\n </div>\n </div>\n </form>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"save()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{padding:1rem;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"] }]
|
|
4623
5139
|
}], ctorParameters: () => [] });
|
|
4624
5140
|
|
|
4625
5141
|
var EventCard;
|
|
@@ -4652,7 +5168,7 @@ class AgentCardUI {
|
|
|
4652
5168
|
this.onAction.emit({ action: eventType, item: this.card() });
|
|
4653
5169
|
}
|
|
4654
5170
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardUI, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4655
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardUI, isStandalone: true, selector: "dc-agent-card-ui", inputs: { card: { classPropertyName: "card", publicName: "card", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<p-card class=\"card-image\">\n @if(showOptions()) {\n <div style=\"position: absolute; top: 5px; right: 5px; z-index: 1000\">\n <p-speeddial\n [model]=\"speedDialModel\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [tooltipOptions]=\"{ tooltipPosition: 'top' }\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n </div>\n }\n\n <img [src]=\"card()?.assets?.image?.url || 'assets/defaults/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div (click)=\"eventCard(eventType.Select)\" class=\"content\">\n <p class=\"text-xl font-bold text-shadow-lg/30\">{{ card().title }}</p>\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"card().description || card().characterCard?.data.creator_notes | truncate : 200\"></span>\n </p>\n\n @if(card()?.['taken']){\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-tag icon=\"pi pi-check-circle\" severity=\"secondary\" value=\"Tomada\" [rounded]=\"true\" />\n </div>\n }\n <p-button\n (click)=\"eventCard(eventType.Select)\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\"\n icon=\"pi pi-comment\"\n [rounded]=\"true\"\n severity=\"info\"\n [outlined]=\"true\"\n [raised]=\"true\" />\n </div>\n</p-card>\n", styles: [":host{display:block}:host ::ng-deep .p-card{height:100%}:host ::ng-deep .p-card-body{height:100%;padding:0!important}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block;padding:-10px}.card-image img{position:absolute;z-index:3;width:100%;height:100%;opacity:.75;object-fit:cover;transition:opacity .5s}.content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0003,#0000001a);height:100%;display:flex;flex-direction:column;justify-content:space-between}.content:hover{background:linear-gradient(to bottom,color-mix(in srgb,var(--p-primary-color) 20%,transparent),color-mix(in srgb,black 10%,transparent));cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: PopoverModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$
|
|
5171
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardUI, isStandalone: true, selector: "dc-agent-card-ui", inputs: { card: { classPropertyName: "card", publicName: "card", isSignal: true, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onAction: "onAction" }, ngImport: i0, template: "<p-card class=\"card-image\">\n @if(showOptions()) {\n <div style=\"position: absolute; top: 5px; right: 5px; z-index: 1000\">\n <p-speeddial\n [model]=\"speedDialModel\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [tooltipOptions]=\"{ tooltipPosition: 'top' }\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n </div>\n }\n\n <img [src]=\"card()?.assets?.image?.url || 'assets/defaults/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div (click)=\"eventCard(eventType.Select)\" class=\"content\">\n <p class=\"text-xl font-bold text-shadow-lg/30\">{{ card().title }}</p>\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"card().description || card().characterCard?.data.creator_notes | truncate : 200\"></span>\n </p>\n\n @if(card()?.['taken']){\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-tag icon=\"pi pi-check-circle\" severity=\"secondary\" value=\"Tomada\" [rounded]=\"true\" />\n </div>\n }\n <p-button\n (click)=\"eventCard(eventType.Select)\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\"\n icon=\"pi pi-comment\"\n [rounded]=\"true\"\n severity=\"info\"\n [outlined]=\"true\"\n [raised]=\"true\" />\n </div>\n</p-card>\n", styles: [":host{display:block}:host ::ng-deep .p-card{height:100%}:host ::ng-deep .p-card-body{height:100%;padding:0!important}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block;padding:-10px}.card-image img{position:absolute;z-index:3;width:100%;height:100%;opacity:.75;object-fit:cover;transition:opacity .5s}.content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0003,#0000001a);height:100%;display:flex;flex-direction:column;justify-content:space-between}.content:hover{background:linear-gradient(to bottom,color-mix(in srgb,var(--p-primary-color) 20%,transparent),color-mix(in srgb,black 10%,transparent));cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: PopoverModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$4.SpeedDial, selector: "p-speeddial, p-speedDial, p-speed-dial", inputs: ["id", "model", "visible", "style", "className", "direction", "transitionDelay", "type", "radius", "mask", "disabled", "hideOnClickOutside", "buttonStyle", "buttonClassName", "maskStyle", "maskClassName", "showIcon", "hideIcon", "rotateAnimation", "ariaLabel", "ariaLabelledBy", "tooltipOptions", "buttonProps"], outputs: ["onVisibleChange", "visibleChange", "onClick", "onShow", "onHide"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$2.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$5.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
4656
5172
|
}
|
|
4657
5173
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardUI, decorators: [{
|
|
4658
5174
|
type: Component,
|
|
@@ -4729,7 +5245,7 @@ class AgentCardListComponent extends EntityBaseListComponent {
|
|
|
4729
5245
|
this.loadData();
|
|
4730
5246
|
}
|
|
4731
5247
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4732
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { customFilters: { classPropertyName: "customFilters", publicName: "customFilters", isSignal: false, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, customGetButtons: { classPropertyName: "customGetButtons", publicName: "customGetButtons", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<dc-filter-bar [options]=\"filterBarOptions\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"getCardMeta(card)\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(items().length === 0 && !isLoading) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<!-- Mobile Paginator -->\n<p-paginator\n class=\"hidden md:block\"\n currentPageReportTemplate=\"{{
|
|
5248
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { customFilters: { classPropertyName: "customFilters", publicName: "customFilters", isSignal: false, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, customGetButtons: { classPropertyName: "customGetButtons", publicName: "customGetButtons", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<dc-filter-bar [options]=\"filterBarOptions\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"getCardMeta(card)\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(items().length === 0 && !isLoading) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<!-- Mobile Paginator -->\n<p-paginator\n class=\"hidden md:block\"\n [first]=\"first\"\n [rows]=\"rows\"\n currentPageReportTemplate=\"{first}-{last} de {totalRecords} \"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [totalRecords]=\"totalRecordsSignal()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n\n<!-- Desktop Paginator -->\n<p-paginator\n class=\"block md:hidden\"\n [first]=\"first\"\n [rows]=\"rows\"\n [totalRecords]=\"totalRecordsSignal()\"\n (onPageChange)=\"onPageChange($event)\"\n [showCurrentPageReport]=\"true\"\n [showPageLinks]=\"false\"\n [showFirstLastIcon]=\"false\"\n [rowsPerPageOptions]=\"[10, 20, 30]\"\n currentPageReportTemplate=\" {first}- {last} de {totalRecords} \" />\n", styles: [":host{display:flex;flex-direction:column;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:1.5rem;width:100%;flex:1;min-height:0;display:flex;flex-direction:column}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}::ng-deep p-paginator .p-paginator{padding:0!important;background:transparent!important}\n"], dependencies: [{ kind: "component", type: AgentCardUI, selector: "dc-agent-card-ui", inputs: ["card", "showOptions"], outputs: ["onAction"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i1$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "style", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "appendTo", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first"], outputs: ["onPageChange"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters"], outputs: ["onFilterAction", "onChangeSort", "onNew"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
4733
5249
|
}
|
|
4734
5250
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentCardListComponent, decorators: [{
|
|
4735
5251
|
type: Component,
|
|
@@ -4743,7 +5259,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4743
5259
|
SpeedDialModule,
|
|
4744
5260
|
QuickTableComponent,
|
|
4745
5261
|
CommonModule,
|
|
4746
|
-
], standalone: true, template: "<dc-filter-bar [options]=\"filterBarOptions\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"getCardMeta(card)\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(items().length === 0 && !isLoading) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<!-- Mobile Paginator -->\n<p-paginator\n class=\"hidden md:block\"\n currentPageReportTemplate=\"{{
|
|
5262
|
+
], standalone: true, template: "<dc-filter-bar [options]=\"filterBarOptions\" (onFilterAction)=\"applyFilterBarEvent($event)\" (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n}@else{\n\n<div class=\"conversation-card-lists\">\n @if(!isLoading) {\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"getCardMeta(card)\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n }\n </div>\n }\n</div>\n\n@if(isLoading) {\n<div>\n <p-skeleton styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"5rem\" styleClass=\"mb-2\" />\n <p-skeleton height=\"2rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"10rem\" height=\"4rem\" />\n</div>\n} @if(items().length === 0 && !isLoading) {\n<div>\n <p>No conversations found or no connection with server</p>\n</div>\n} }\n\n<!-- Mobile Paginator -->\n<p-paginator\n class=\"hidden md:block\"\n [first]=\"first\"\n [rows]=\"rows\"\n currentPageReportTemplate=\"{first}-{last} de {totalRecords} \"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [totalRecords]=\"totalRecordsSignal()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n</p-paginator>\n\n<!-- Desktop Paginator -->\n<p-paginator\n class=\"block md:hidden\"\n [first]=\"first\"\n [rows]=\"rows\"\n [totalRecords]=\"totalRecordsSignal()\"\n (onPageChange)=\"onPageChange($event)\"\n [showCurrentPageReport]=\"true\"\n [showPageLinks]=\"false\"\n [showFirstLastIcon]=\"false\"\n [rowsPerPageOptions]=\"[10, 20, 30]\"\n currentPageReportTemplate=\" {first}- {last} de {totalRecords} \" />\n", styles: [":host{display:flex;flex-direction:column;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:1.5rem;width:100%;flex:1;min-height:0;display:flex;flex-direction:column}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}::ng-deep p-paginator .p-paginator{padding:0!important;background:transparent!important}\n"] }]
|
|
4747
5263
|
}], ctorParameters: () => [], propDecorators: { customFilters: [{
|
|
4748
5264
|
type: Input
|
|
4749
5265
|
}] } });
|
|
@@ -4751,7 +5267,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4751
5267
|
class ParseCardPipe {
|
|
4752
5268
|
constructor() {
|
|
4753
5269
|
this.userDataExchange = inject(USER_DATA_EXCHANGE);
|
|
4754
|
-
this.builderConversation = inject(
|
|
5270
|
+
this.builderConversation = inject(ConversationPromptBuilderService);
|
|
4755
5271
|
}
|
|
4756
5272
|
transform(text, card = null) {
|
|
4757
5273
|
let parseDict = this.userDataExchange.getParseDict();
|
|
@@ -4777,47 +5293,57 @@ class DcAgentCardDetailsComponent {
|
|
|
4777
5293
|
constructor() {
|
|
4778
5294
|
this.agentCardService = inject(CONVERSATION_AI_TOKEN);
|
|
4779
5295
|
this.route = inject(ActivatedRoute);
|
|
4780
|
-
this.cdr = inject(ChangeDetectorRef);
|
|
4781
5296
|
this.toastService = inject(TOAST_ALERTS_TOKEN);
|
|
4782
5297
|
this.agentCardId = '';
|
|
4783
5298
|
this.onStartConversation = output();
|
|
4784
|
-
this.
|
|
5299
|
+
this.agentCard = signal(undefined);
|
|
5300
|
+
this.showInfoLayer = signal(false);
|
|
5301
|
+
this.mediaType = computed(() => {
|
|
5302
|
+
const card = this.agentCard();
|
|
5303
|
+
if (card?.assets?.motion?.url) {
|
|
5304
|
+
return 'video';
|
|
5305
|
+
}
|
|
5306
|
+
return 'image';
|
|
5307
|
+
});
|
|
5308
|
+
this.mediaUrl = computed(() => {
|
|
5309
|
+
const card = this.agentCard();
|
|
5310
|
+
if (this.mediaType() === 'video') {
|
|
5311
|
+
return card?.assets?.motion?.url;
|
|
5312
|
+
}
|
|
5313
|
+
return card?.assets?.image?.url || 'assets/defaults/images/default_conversation_card.webp';
|
|
5314
|
+
});
|
|
4785
5315
|
}
|
|
4786
5316
|
async ngOnInit() {
|
|
4787
|
-
console.log('DcAgentCardDetailsComponent', this.agentCardId);
|
|
4788
5317
|
const id = this.route.snapshot.paramMap.get('id');
|
|
4789
5318
|
if (id) {
|
|
4790
5319
|
this.agentCardId = id;
|
|
4791
|
-
console.log(this.agentCardId);
|
|
4792
5320
|
}
|
|
4793
|
-
|
|
4794
|
-
if (!
|
|
5321
|
+
const card = await this.agentCardService.findOne(this.agentCardId);
|
|
5322
|
+
if (!card) {
|
|
4795
5323
|
this.toastService.error({
|
|
4796
5324
|
title: 'Conversation card not found',
|
|
4797
5325
|
subtitle: 'Probablemente tienes el id incorrecto, o estas en una sección errónea.',
|
|
4798
5326
|
});
|
|
4799
5327
|
return;
|
|
4800
5328
|
}
|
|
4801
|
-
if (!
|
|
5329
|
+
if (!card.conversationSettings) {
|
|
4802
5330
|
console.warn('⚠️ Conversation settings not found ⚠️ probably is an old version of the card.');
|
|
4803
|
-
|
|
5331
|
+
card.conversationSettings = {};
|
|
4804
5332
|
}
|
|
4805
|
-
|
|
4806
|
-
this.cdr.detectChanges();
|
|
5333
|
+
this.agentCard.set(card);
|
|
4807
5334
|
}
|
|
4808
5335
|
startConversation() {
|
|
4809
|
-
this.onStartConversation.emit(this.agentCard);
|
|
5336
|
+
this.onStartConversation.emit(this.agentCard());
|
|
4810
5337
|
}
|
|
4811
5338
|
toggleInfoLayer() {
|
|
4812
|
-
this.showInfoLayer
|
|
4813
|
-
this.cdr.markForCheck();
|
|
5339
|
+
this.showInfoLayer.update((value) => !value);
|
|
4814
5340
|
}
|
|
4815
5341
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcAgentCardDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
4816
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcAgentCardDetailsComponent, isStandalone: true, selector: "dc-agent-card-details", inputs: { agentCardId: "agentCardId" }, outputs: { onStartConversation: "onStartConversation" }, ngImport: i0, template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <
|
|
5342
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcAgentCardDetailsComponent, isStandalone: true, selector: "dc-agent-card-details", inputs: { agentCardId: "agentCardId" }, outputs: { onStartConversation: "onStartConversation" }, ngImport: i0, template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n @switch (mediaType()) { @case ('video') {\n <video class=\"card-image\" [src]=\"mediaUrl()\" autoplay loop muted playsinline></video>\n } @case ('image') {\n <img class=\"card-image\" [src]=\"mediaUrl()\" alt=\"\" />\n } }\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer()\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard()?.title }}</strong></h1\n >\n <p>{{ agentCard()?.characterCard.data?.name }}</p>\n\n @if (agentCard()?.characterCard.data?.scenario) {\n <div class=\"scenario\">\n <h4>Scenario</h4>\n <p>{{ agentCard()?.characterCard.data.scenario | parseCard : agentCard() }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}.info-button{position:absolute;top:15px;right:15px;z-index:3}.info-button:hover{transform:scale(1.1)}.info-layer{height:100%;width:100%;position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;z-index:2;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:#ed122833;color:#fff;opacity:1;clip-path:circle(0% at top right);transition:clip-path .5s cubic-bezier(.25,1,.5,1);pointer-events:none}.info-layer.active{clip-path:circle(150% at top right);pointer-events:auto}.info-content{padding:15px;text-align:center;max-width:90%}.info-content h1{margin-top:0;font-size:18px;margin-bottom:10px}.info-content p{font-size:12px;margin:0}::ng-deep .info-button .p-button{background-color:#ffffff47}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$2.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }] }); }
|
|
4817
5343
|
}
|
|
4818
5344
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcAgentCardDetailsComponent, decorators: [{
|
|
4819
5345
|
type: Component,
|
|
4820
|
-
args: [{ selector: 'dc-agent-card-details', standalone: true, imports: [ButtonModule, CardModule, ParseCardPipe], template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <
|
|
5346
|
+
args: [{ selector: 'dc-agent-card-details', standalone: true, imports: [ButtonModule, CardModule, ParseCardPipe], template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n @switch (mediaType()) { @case ('video') {\n <video class=\"card-image\" [src]=\"mediaUrl()\" autoplay loop muted playsinline></video>\n } @case ('image') {\n <img class=\"card-image\" [src]=\"mediaUrl()\" alt=\"\" />\n } }\n\n <div class=\"info-button\" (click)=\"toggleInfoLayer()\">\n <p-button icon=\"pi pi-arrow-down-left\" [rounded]=\"true\" [raised]=\"true\" severity=\"primary\" [outlined]=\"true\" />\n </div>\n\n <div style=\"position: absolute; bottom: 20px; right: 50%; transform: translateX(50%); z-index: 3\">\n <p-button size=\"large\" label=\"Iniciar Conversaci\u00F3n\" [rounded]=\"true\" (click)=\"startConversation()\" />\n </div>\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer()\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard()?.title }}</strong></h1\n >\n <p>{{ agentCard()?.characterCard.data?.name }}</p>\n\n @if (agentCard()?.characterCard.data?.scenario) {\n <div class=\"scenario\">\n <h4>Scenario</h4>\n <p>{{ agentCard()?.characterCard.data.scenario | parseCard : agentCard() }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n </p-card>\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}.info-button{position:absolute;top:15px;right:15px;z-index:3}.info-button:hover{transform:scale(1.1)}.info-layer{height:100%;width:100%;position:absolute;top:0;left:0;display:flex;justify-content:center;align-items:center;z-index:2;-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);background-color:#ed122833;color:#fff;opacity:1;clip-path:circle(0% at top right);transition:clip-path .5s cubic-bezier(.25,1,.5,1);pointer-events:none}.info-layer.active{clip-path:circle(150% at top right);pointer-events:auto}.info-content{padding:15px;text-align:center;max-width:90%}.info-content h1{margin-top:0;font-size:18px;margin-bottom:10px}.info-content p{font-size:12px;margin:0}::ng-deep .info-button .p-button{background-color:#ffffff47}\n"] }]
|
|
4821
5347
|
}], propDecorators: { agentCardId: [{
|
|
4822
5348
|
type: Input
|
|
4823
5349
|
}] } });
|
|
@@ -4831,5 +5357,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
|
|
|
4831
5357
|
* Generated bundle index. Do not edit.
|
|
4832
5358
|
*/
|
|
4833
5359
|
|
|
4834
|
-
export { AgentCardListComponent,
|
|
5360
|
+
export { AgentCardListComponent, AgentCardUI, AudioService, AudioSpeed, CONVERSATION_AI_TOKEN, ChatEventType, ChatMessage, ChatMessageOrchestratorComponent, ChatRole, ConditionOperator, ConditionType, ContextEngineService, ContextType, ConversationDTO, ConversationEvents, ConversationMessagesDTO, ConversationPromptBuilderService, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationUserChatSettingsComponent, DcAgentCardDetailsComponent, DefaultAgentCardsService, DoActionTypeOptions, DynamicFlowService, DynamicFlowTaskTypeOptions, EAccountsPlatform, EDoActionType, EDynamicFlowTaskType, EntityThen, EntityWhatOptions, EntityWhenOptions, EvalResultStringDefinition, GlobalToolsService, MOOD_STATE_PROMPT, MessageContent, MessageContentDisplayer, ModelSelectorComponent, PopupService, SystemPromptType, TextEngineOptions, TextEngines, USER_DATA_EXCHANGE, UserDataExchangeAbstractService, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, createAIModelFormGroup, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, getMoodStateLabelsAsString, markdownBasicToHTML, markdownToHTML$1 as markdownToHTML, markdownToHTML2, markdownToHtml, matchTranscription, provideAgentCardService, provideUserDataExchange, removeAllEmojis, removeEmojis, removeEmojisAndSpecialCharacters, removeSpecialCharacters };
|
|
4835
5361
|
//# sourceMappingURL=dataclouder-ngx-agent-cards.mjs.map
|