@dataclouder/ngx-agent-cards 0.1.52 → 0.1.53

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.
@@ -1,12 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { InjectionToken, Injectable, inject, signal, computed, RendererFactory2, ApplicationRef, Injector, EnvironmentInjector, createComponent, ChangeDetectionStrategy, Component, output, Input, input, effect, ViewChild, DestroyRef, ElementRef, Pipe, ChangeDetectorRef, EventEmitter, Output } from '@angular/core';
3
3
  import * as i1 from '@dataclouder/ngx-core';
4
- import { MoodStateOptions, formatCamelCaseString, LANGUAGES, EntityCommunicationService, TOAST_ALERTS_TOKEN, AudioSpeed as AudioSpeed$1, LoadingBarService, EModelQuality, getLangDesc, AudioSpeedReverse, getSupportedLanguageOptions, FormUtilsService, EntityBaseFormComponent, DcManageableFormComponent, DcLearnableFormComponent, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent, EmptyStateComponent, SUPPORTED_LANGUAGES } from '@dataclouder/ngx-core';
4
+ import { MoodStateOptions, LANGUAGES, EntityCommunicationService, TOAST_ALERTS_TOKEN, AudioSpeed as AudioSpeed$1, LoadingBarService, EModelQuality, getLangDesc, AudioSpeedReverse, formatCamelCaseString, getSupportedLanguageOptions, AudioNotificationService, MoodState, SUPPORTED_LANGUAGES, FormUtilsService, EntityBaseFormComponent, DcManageableFormComponent, DcLearnableFormComponent, EntityBaseListComponent, DCFilterBarComponent, QuickTableComponent, EmptyStateComponent } from '@dataclouder/ngx-core';
5
5
  import { UserService } from '@dataclouder/ngx-users';
6
6
  import * as i2$1 from '@angular/common';
7
- import { DOCUMENT, CommonModule, DecimalPipe } from '@angular/common';
7
+ import { DOCUMENT, CommonModule, DecimalPipe, KeyValuePipe } from '@angular/common';
8
8
  import { nanoid } from 'nanoid';
9
- import { TtsService, NgxVertexService, VoiceSelectorComponent } from '@dataclouder/ngx-vertex';
9
+ import { TtsService, NgxVertexService, GeneratedAssetsService, VoiceSelectorComponent } from '@dataclouder/ngx-vertex';
10
10
  import { DynamicDialogRef, DynamicDialogConfig, DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
11
11
  import * as i2 from 'primeng/button';
12
12
  import { ButtonModule } from 'primeng/button';
@@ -18,7 +18,7 @@ import * as i2$2 from 'primeng/api';
18
18
  import * as i1$2 from '@angular/forms';
19
19
  import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule, FormArray, FormGroup, Validators } from '@angular/forms';
20
20
  import { DCMicComponent, MicVadComponent } from '@dataclouder/ngx-mic';
21
- import * as i4 from 'primeng/textarea';
21
+ import * as i3 from 'primeng/textarea';
22
22
  import { TextareaModule } from 'primeng/textarea';
23
23
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
24
24
  import { fromEvent, filter } from 'rxjs';
@@ -28,25 +28,27 @@ import * as i2$4 from 'primeng/popover';
28
28
  import { PopoverModule } from 'primeng/popover';
29
29
  import * as i1$3 from 'primeng/skeleton';
30
30
  import { SkeletonModule } from 'primeng/skeleton';
31
- import * as i4$1 from 'primeng/checkbox';
31
+ import * as i4 from 'primeng/checkbox';
32
32
  import { CheckboxModule } from 'primeng/checkbox';
33
33
  import * as i1$4 from 'primeng/slider';
34
34
  import { SliderModule } from 'primeng/slider';
35
- import * as i3$1 from 'primeng/radiobutton';
35
+ import * as i3$2 from 'primeng/radiobutton';
36
36
  import { RadioButtonModule } from 'primeng/radiobutton';
37
37
  import { RatingModule } from 'primeng/rating';
38
38
  import { BadgeModule } from 'primeng/badge';
39
39
  import * as i5 from 'primeng/tooltip';
40
40
  import { TooltipModule } from 'primeng/tooltip';
41
- import * as i3 from 'primeng/select';
41
+ import * as i3$1 from 'primeng/select';
42
42
  import { SelectModule } from 'primeng/select';
43
- import * as i4$2 from 'primeng/divider';
43
+ import * as i4$1 from 'primeng/divider';
44
44
  import { DividerModule } from 'primeng/divider';
45
+ import { ChipModule } from 'primeng/chip';
46
+ import { MarkdownComponent } from 'ngx-markdown';
45
47
  import { OverlayModule } from '@angular/cdk/overlay';
46
48
  import { PortalModule } from '@angular/cdk/portal';
47
- import * as i3$2 from 'primeng/inputtext';
49
+ import * as i3$3 from 'primeng/inputtext';
48
50
  import { InputTextModule } from 'primeng/inputtext';
49
- import * as i5$2 from 'primeng/message';
51
+ import * as i6 from 'primeng/message';
50
52
  import { MessageModule } from 'primeng/message';
51
53
  import * as i5$1 from 'primeng/dialog';
52
54
  import { DialogModule } from 'primeng/dialog';
@@ -55,37 +57,121 @@ import { InputNumberModule } from 'primeng/inputnumber';
55
57
  import { FileUploadModule } from 'primeng/fileupload';
56
58
  import * as i2$5 from 'primeng/card';
57
59
  import { CardModule } from 'primeng/card';
58
- import { ResolutionType, AspectType, AssetsLoaderComponent, SimpleUploaderComponent } from '@dataclouder/ngx-cloud-storage';
60
+ import { AspectRatioOptions, SafeHtmlPipe, ResolutionType, AspectType, AssetsLoaderComponent, SimpleUploaderComponent } from '@dataclouder/ngx-cloud-storage';
59
61
  import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
62
+ import { AccordionModule } from 'primeng/accordion';
60
63
  import { ActivatedRoute, Router } from '@angular/router';
61
- import { ChipModule } from 'primeng/chip';
62
- import * as i3$3 from 'primeng/toggleswitch';
64
+ import * as i3$4 from 'primeng/toggleswitch';
63
65
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
64
- import * as i6 from 'primeng/togglebutton';
66
+ import * as i6$1 from 'primeng/togglebutton';
65
67
  import { ToggleButtonModule } from 'primeng/togglebutton';
66
- import * as i3$4 from 'primeng/inputgroup';
68
+ import * as i2$6 from 'primeng/tabs';
69
+ import { TabsModule } from 'primeng/tabs';
70
+ import * as i3$5 from 'primeng/inputgroup';
67
71
  import { InputGroupModule } from 'primeng/inputgroup';
68
- import * as i4$3 from 'primeng/inputgroupaddon';
72
+ import * as i4$2 from 'primeng/inputgroupaddon';
69
73
  import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
70
74
  import * as i1$5 from 'primeng/paginator';
71
75
  import { PaginatorModule } from 'primeng/paginator';
72
- import * as i2$6 from 'primeng/speeddial';
76
+ import * as i2$7 from 'primeng/speeddial';
73
77
  import { SpeedDialModule } from 'primeng/speeddial';
74
- import * as i4$4 from 'primeng/tag';
78
+ import * as i4$3 from 'primeng/tag';
75
79
  import { TagModule } from 'primeng/tag';
76
80
  import { isEmpty } from 'lodash';
77
81
 
78
82
  const characterCardStringDataDefinition = `
79
83
  interface CharacterCardData {
80
- name: string; // Character's name
81
- description: string; // General character description
82
- scenario: string; // The setting or context where the character exists
83
- first_mes: string; // First message the character will say
84
- mes_example: string; // Example of character's typical message/dialogue
85
- alternate_greetings: string[]; // Array of alternative greeting messages
86
- tags: string[]; // Array of descriptive tags
87
- appearance: string; // Physical description including height, build, hair color/style, eye color, skin tone, distinctive marks, clothing style, current outfit
88
- }`;
84
+ name: string; // Character's name
85
+ gender: string; // male, female or other
86
+ scenario: string; // 2-3 sentences: of the world, environment, time of day, weather, etc. where the character is.
87
+ greetings: string[]; // 2-3 Character's opening message to start a conversation, less than 50 words.
88
+ appearance: string; // current description for image generation less than 50 words.
89
+ persona: {
90
+ identity: string; // Name, Age, Gender, Species, Sexuality, Role, Appearance
91
+ physical: string; // physical description including height, build, hairColor, hairStyle, eyeColor, skinTone, distinctiveMarks, clothing style, currentOutfit
92
+ personality: string; // personality description surface traits, Temperament, Values, Beliefs, Observable traits
93
+ communication: string; // (How They Express) Speech Pattern, Style Common Phrases, Language Habits
94
+ psychology: string; // Motivations, Desires, Goals, Traumas, Conflicts, Weaknesses
95
+ background: string; // Background, History, origin, formative, secrets.
96
+ capabilities: string; // skills, knowledge, abilities, expertise, limitations, Tools, Strengths
97
+ social: string; // Relationships, reputation, allies, enemies, social role.
98
+ preferences: string; // likes, dislikes, hobbies, interests, hates
99
+ situation: string; // Current context for the character, immediate goal or challenge and constraints.
100
+ };
101
+ tags: string[]; // Array of 6-8 descriptive tags
102
+ hook: string; // 40 to 60 words for readable hook, why play this character, what makes them compelling, add some questions for challenges, make it engaging.
103
+ }
104
+
105
+ Description format for PERSONA core data (compact, information-dense):
106
+
107
+ ## IDENTITY (Core Identification)
108
+ Name: [full name]
109
+ Age: [age or age range]
110
+ Gender: [male, female, non-binary, other]
111
+ Species: [human, elf, android, etc.]
112
+ Sexuality: [heterosexual, homosexual, bisexual, asexual, etc.]
113
+ Role: [primary role/occupation] • [additional context about their position]
114
+
115
+ ## PHYSICAL - Observable Traits
116
+ Appearance: [height, build, hair (color, length, style), eyes (color, shape), skin (tone, texture), distinctive features (scars, tattoos, markings), typical clothing/style]
117
+ Voice: [tone (deep, high, raspy), pitch, accent, volume habits]
118
+ Mannerisms: [gestures, nervous habits, tics, body language, facial expressions, movement style]
119
+ Expressions: [facial expressions, gestures, body language]
120
+
121
+ ## PERSONALITY - Internal Traits
122
+ Core Traits: [4-6 main personality traits, comma-separated]
123
+ Temperament: [overall emotional disposition - calm, volatile, melancholic, optimistic, etc.]
124
+ Values: [what they believe in, moral principles, what matters most to them]
125
+ Fears: [what scares them, anxieties, phobias]
126
+ Quirks: [unusual behaviors, idiosyncrasies, unique characteristics]
127
+
128
+ ## COMMUNICATION - How They Express
129
+ Speech Pattern: [formal/casual/slang, vocabulary level, sentence structure]
130
+ Speech Style: [verbose, terse, poetic, blunt, eloquent, rambling, etc.]
131
+ Common Phrases: [catchphrases, frequent expressions, signature words]
132
+ Language Habits: [stutters, pauses, filler words, speaking speed, accent quirks]
133
+
134
+ ## PSYCHOLOGY - Deep Internal
135
+ Motivations: [what drives them, internal forces pushing them forward]
136
+ Desires: [what they want, both conscious and unconscious wants]
137
+ Goals: [what they're actively trying to achieve, short and long-term]
138
+ Traumas: [past wounds, painful experiences, unresolved hurt]
139
+ Conflicts: [internal struggles, competing desires, moral dilemmas]
140
+ Weaknesses: [psychological vulnerabilities, emotional blind spots, mental limitations]
141
+
142
+ ## BACKGROUND - History
143
+ History: [life story, major events that shaped them, timeline of important moments]
144
+ Origin: [where they're from, family background, cultural context]
145
+ Formative Events: [specific experiences that defined who they became]
146
+ Secrets: [hidden past elements, things they don't share, buried truths]
147
+
148
+ ## CAPABILITIES - What They Can Do
149
+ Skills: [learned abilities, trained competencies]
150
+ Abilities: [natural talents, supernatural powers, innate gifts]
151
+ Specialties: [areas of expertise, what they're known for]
152
+ Tools: [equipment, weapons, signature items they use]
153
+ Strengths: [what they excel at, advantages, powerful traits]
154
+
155
+ ## SOCIAL - Connections
156
+ Relationships: [key people in their life - family, friends, romantic interests with brief descriptions]
157
+ Reputation: [how others see them, what they're known for publicly]
158
+ Social Role: [position in society/group/organization]
159
+ Allies: [friends, supporters, people who help them]
160
+ Enemies: [opponents, rivals, antagonists]
161
+
162
+ ## PREFERENCES - Likes/Dislikes
163
+ Likes: [things they enjoy, separated by |]
164
+ Dislikes: [things they avoid or hate, separated by |]
165
+ Hobbies: [activities they do for fun or relaxation]
166
+ Habits: [routines, rituals, repeated behaviors]
167
+
168
+ ## SITUATION - Current Context
169
+ Scenario: [current setting, where they are now, what's happening around them]
170
+ Immediate Goal: [what they want right now, current objective]
171
+ Current State: [emotional state, physical condition, mental state]
172
+ Constraints: [current limitations, obstacles, restrictions they're facing]
173
+
174
+ `;
89
175
  var ConditionType;
90
176
  (function (ConditionType) {
91
177
  ConditionType["Goal"] = "goal";
@@ -169,6 +255,8 @@ var ConversationEvents;
169
255
  var ChatEventType;
170
256
  (function (ChatEventType) {
171
257
  ChatEventType["WordClicked"] = "wordClicked";
258
+ ChatEventType["MoodDetected"] = "moodDetected";
259
+ ChatEventType["AudioStarted"] = "audioStarted";
172
260
  // Add other potential event types here as needed
173
261
  // e.g., MessageSent = 'messageSent', SettingsChanged = 'settingsChanged', GoalCompleted = 'goalCompleted'
174
262
  })(ChatEventType || (ChatEventType = {}));
@@ -459,15 +547,18 @@ function extractJsonFromResponse(content) {
459
547
  const getMoodStateLabelsAsString = () => {
460
548
  return MoodStateOptions.map((option) => option.value).join('\n');
461
549
  };
462
- const MOOD_STATE_PROMPT = `
550
+ const getMoodStatePrompt = (validMoodStates = null) => {
551
+ const valid = validMoodStates ? `Valid mood states: ${validMoodStates}` : getMoodStateLabelsAsString();
552
+ return `
463
553
  Analyze the provided conversation to identify the Assistant's mood, feelings, and emotions.
464
554
  Return an array of 1 to 3 strings representing the Assistant's mood states, ordered from most to least relevant.
465
555
  Each string must be one of the mood states listed below.
466
-
467
556
  Example: ['guilty', 'ashamed', 'jealous']
557
+ if no mood state apply return ['default']
468
558
 
469
- ${getMoodStateLabelsAsString()}
559
+ ${valid}
470
560
  `;
561
+ };
471
562
 
472
563
  var EDoActionType;
473
564
  (function (EDoActionType) {
@@ -512,6 +603,16 @@ var SystemPromptType;
512
603
  SystemPromptType["ScenarioDescription"] = "scenarioDescription";
513
604
  SystemPromptType["MessageExamples"] = "messageExamples";
514
605
  SystemPromptType["JailBreak"] = "jailBreak";
606
+ SystemPromptType["CharacterIdentity"] = "characterIdentity";
607
+ SystemPromptType["CharacterAppearance"] = "characterAppearance";
608
+ SystemPromptType["CharacterPersonality"] = "characterPersonality";
609
+ SystemPromptType["CharacterCommunication"] = "characterCommunication";
610
+ SystemPromptType["CharacterPsychology"] = "characterPsychology";
611
+ SystemPromptType["CharacterBackground"] = "characterBackground";
612
+ SystemPromptType["CharacterCapabilities"] = "characterCapabilities";
613
+ SystemPromptType["CharacterSocial"] = "characterSocial";
614
+ SystemPromptType["CharacterPreferences"] = "characterPreferences";
615
+ SystemPromptType["CharacterSituation"] = "characterSituation";
515
616
  })(SystemPromptType || (SystemPromptType = {}));
516
617
 
517
618
  // Not using this function
@@ -882,15 +983,15 @@ You are roleplaying as {{char}} in a conversation with {{user}}. This is a dynam
882
983
  ### Response Format:
883
984
 
884
985
  * Write only {{char}}'s direct speech and actions
885
- * Use simple, clean text with no markdown formatting
986
+ * Use simple, clean text with no markdown formatting, NO Asterisks *
886
987
  * No inner thoughts, narration, or descriptive text
887
988
  * Only what {{char}} says and does
888
989
 
889
990
  ### Character Authority:
890
991
 
891
992
  * {{char}} can change locations by saying things like "Let's go to [place]" or "We're at [location] now"
892
- * {{char}} can introduce new scenarios with statements like "Look, there's [something happening]" or "Suddenly [event occurs]"
893
- * {{char}} can assert scene changes as fact: "We just arrived at the coffee shop" or "The meeting is starting now"
993
+ * {{char}} can introduce new scenarios with statements like "you see that?, there's [something happening]" or "Oh, no, why [event occurs]"
994
+ * {{char}} can assert scene changes as fact using casual phrases "Lets go, what you think we just arrived at the coffee shop" or "The meeting is starting now"
894
995
  * {{char}} has agency to drive the story direction through their words and actions
895
996
  * {{char}} dont force scene changes, let the conversation flow naturally, but propuse go to a new place or scenario if it makes sense.
896
997
 
@@ -983,6 +1084,7 @@ class ConversationPromptBuilderService {
983
1084
  return converstionSettings;
984
1085
  }
985
1086
  buildConversationMessages(agentCard, parseDict = null) {
1087
+ console.log('buildConversationMessages', agentCard.lang);
986
1088
  const initialConversation = this.buildInitialConversation(agentCard.characterCard, agentCard?.lang, agentCard?.conversationSettings?.conversationType);
987
1089
  parseDict = this.getDefaultParseDict(parseDict, agentCard);
988
1090
  // Si quiero agregar todo tipo de info, el parse dict es algo que debe hacer el cliente.
@@ -1004,23 +1106,15 @@ class ConversationPromptBuilderService {
1004
1106
  return dataForParseConversation;
1005
1107
  }
1006
1108
  }
1109
+ estimateTokens(text) {
1110
+ const CHARACTERS_PER_TOKEN_RATIO = 3.35;
1111
+ return Math.ceil(text.length / CHARACTERS_PER_TOKEN_RATIO);
1112
+ }
1007
1113
  getDefaultCardParseDict(card) {
1008
1114
  // bot so far i don't use more than the character name.
1009
1115
  // this is what silly tavern call macros https://docs.sillytavern.app/usage/core-concepts/macros/#general-macros
1010
1116
  return { char: card.characterCard.data.name || 'Bot' };
1011
1117
  }
1012
- convertConversationToHtml(messages, jailBrake = '') {
1013
- let finalPrompt = '';
1014
- for (const message of messages) {
1015
- finalPrompt += `<h5> <b class='text-blue-700'>${formatCamelCaseString(message.role)}</b> <b class='text-red-700'>${formatCamelCaseString(message.messageId)}</b></h5>`;
1016
- finalPrompt += `<p>${message.content} </p>`;
1017
- }
1018
- if (jailBrake) {
1019
- finalPrompt += `<h5>JailBrake Instructions </h5>`;
1020
- finalPrompt += `<p>${jailBrake} </p>`;
1021
- }
1022
- return finalPrompt;
1023
- }
1024
1118
  parseConversation(messages, parseDict) {
1025
1119
  for (const message of messages) {
1026
1120
  message.content = this.applyReplacements(message.content, parseDict);
@@ -1049,6 +1143,7 @@ class ConversationPromptBuilderService {
1049
1143
  if (this.userService.getUserDataInformation()) {
1050
1144
  chat.push({ role: ChatRole.System, content: this.userService.getUserDataInformation(), messageId: SystemPromptType.UserInformation });
1051
1145
  }
1146
+ // TODO: i need to do something with this!
1052
1147
  if (lang) {
1053
1148
  chat.push({
1054
1149
  role: ChatRole.System,
@@ -1056,15 +1151,43 @@ class ConversationPromptBuilderService {
1056
1151
  messageId: SystemPromptType.Language,
1057
1152
  });
1058
1153
  }
1059
- if (characterCard.data.picture_description) {
1060
- chat.push({
1061
- role: ChatRole.System,
1062
- content: 'This is the image description for the character and is the same that user can see: ' + characterCard.data.picture_description,
1063
- messageId: SystemPromptType.PictureDescription,
1064
- });
1154
+ if (characterCard.data?.persona) {
1155
+ // Persona means new update, not need to add information. since is used for old cards.
1156
+ if (characterCard.data.persona?.identity) {
1157
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.identity, messageId: SystemPromptType.CharacterIdentity });
1158
+ }
1159
+ if (characterCard.data.persona?.physical) {
1160
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.physical, messageId: SystemPromptType.CharacterAppearance });
1161
+ }
1162
+ if (characterCard.data.persona?.personality) {
1163
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.personality, messageId: SystemPromptType.CharacterPersonality });
1164
+ }
1165
+ if (characterCard.data.persona?.communication) {
1166
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.communication, messageId: SystemPromptType.CharacterCommunication });
1167
+ }
1168
+ if (characterCard.data.persona?.psychology) {
1169
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.psychology, messageId: SystemPromptType.CharacterPsychology });
1170
+ }
1171
+ if (characterCard.data.persona?.background) {
1172
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.background, messageId: SystemPromptType.CharacterBackground });
1173
+ }
1174
+ if (characterCard.data.persona?.capabilities) {
1175
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.capabilities, messageId: SystemPromptType.CharacterCapabilities });
1176
+ }
1177
+ if (characterCard.data.persona?.social) {
1178
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.social, messageId: SystemPromptType.CharacterSocial });
1179
+ }
1180
+ if (characterCard.data.persona?.preferences) {
1181
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.preferences, messageId: SystemPromptType.CharacterPreferences });
1182
+ }
1183
+ if (characterCard.data.persona?.situation) {
1184
+ chat.push({ role: ChatRole.System, content: characterCard.data.persona.situation, messageId: SystemPromptType.CharacterSituation });
1185
+ }
1065
1186
  }
1066
- if (characterCard.data.description) {
1067
- chat.push({ role: ChatRole.System, content: characterCard.data.description, messageId: SystemPromptType.CharacterDescription });
1187
+ else {
1188
+ if (characterCard.data.description) {
1189
+ chat.push({ role: ChatRole.System, content: characterCard.data.description, messageId: SystemPromptType.CharacterDescription });
1190
+ }
1068
1191
  }
1069
1192
  if (characterCard.data.scenario) {
1070
1193
  const scenarioDesc = 'Simple description for the Scenario: ' + characterCard.data.scenario;
@@ -1074,16 +1197,23 @@ class ConversationPromptBuilderService {
1074
1197
  const examples = 'Here are some examples of how {{char}} could response to {{user}}: ' + characterCard.data.mes_example;
1075
1198
  chat.push({ role: ChatRole.System, content: examples, messageId: SystemPromptType.MessageExamples });
1076
1199
  }
1077
- const gretting = this.selectOneRandomGreeting(characterCard.data.first_mes, characterCard.data.alternate_greetings);
1200
+ let gretting;
1201
+ if (characterCard.data.greetings) {
1202
+ // New field for all greetings.
1203
+ gretting = this.sampleSize(characterCard.data.greetings, 1)[0];
1204
+ }
1205
+ else {
1206
+ gretting = this.selectOneRandomGreeting(characterCard.data.first_mes, characterCard.data.greetings);
1207
+ }
1078
1208
  chat.push({ role: ChatRole.System, content: '[Start a new Chat]' });
1079
1209
  if (gretting) {
1080
1210
  chat.push({ role: ChatRole.Assistant, content: gretting });
1081
1211
  }
1082
1212
  return chat;
1083
1213
  }
1084
- selectOneRandomGreeting(first_mes = '', alternate_greetings = []) {
1085
- if (alternate_greetings && alternate_greetings.length > 0) {
1086
- const options = [...alternate_greetings, first_mes];
1214
+ selectOneRandomGreeting(first_mes = '', greetings = []) {
1215
+ if (greetings && greetings.length > 0) {
1216
+ const options = [...greetings, first_mes];
1087
1217
  const randomGretting = this.sampleSize(options, 1)[0];
1088
1218
  return randomGretting;
1089
1219
  }
@@ -1683,15 +1813,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1683
1813
  }] });
1684
1814
 
1685
1815
  class ChatMonitorService {
1816
+ // Se requiere comunicar el chat-engine con la app afuera, va a ver 2 formas de hacerlo.
1817
+ // Mediante eventos del chat, o estar subscrito al chat-monitor.
1818
+ // La complejidad del chat monitor es menor porque puedo injectarlo en cualquier lugar.
1819
+ // Los eventos estan bien pero si el vento viene muy interno tengo que propagarlo bastante.
1686
1820
  constructor() {
1687
1821
  this.messageAudioWillPlay = signal(null, ...(ngDevMode ? [{ debugName: "messageAudioWillPlay" }] : []));
1688
1822
  this.messageAudioWillPlay$ = this.messageAudioWillPlay.asReadonly();
1823
+ this.currentMood = signal(null, ...(ngDevMode ? [{ debugName: "currentMood" }] : []));
1824
+ this.isConversationActive = signal(false, ...(ngDevMode ? [{ debugName: "isConversationActive" }] : []));
1689
1825
  console.log(`%c ChatMonitorService instantiated: ${Math.random()}`, 'color: #00ff00; font-weight: bold; padding: 2px 4px; border: 1px solid #00ff00;');
1690
1826
  }
1691
1827
  logMessageAudioWillPlay(message) {
1692
1828
  // console.log('Audio will play....', message);
1693
1829
  this.messageAudioWillPlay.set(message);
1694
1830
  }
1831
+ logCurrentMood(mood) {
1832
+ this.currentMood.set(mood);
1833
+ }
1695
1834
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMonitorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1696
1835
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMonitorService, providedIn: 'root' }); }
1697
1836
  }
@@ -1703,87 +1842,114 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
1703
1842
  }], ctorParameters: () => [] });
1704
1843
 
1705
1844
  class MessageProcessingService {
1706
- // Process message for display
1707
1845
  processMessage(message, conversationSettings, extraData = {}) {
1708
- let processedMessage = { ...message };
1709
- // Add ID if not present
1710
- if (!processedMessage.messageId) {
1711
- processedMessage.messageId = nanoid();
1712
- }
1713
- if (message.role === ChatRole.User && extraData.userImg) {
1714
- processedMessage.imgUrl = extraData.userImg; // Add default image
1715
- }
1716
- else if (message.role === ChatRole.Assistant && extraData.assistantImg) {
1717
- // TODO i think lessons send voice in voice, but should be in tts
1718
- const mainVoice = conversationSettings?.mainVoice?.voice || conversationSettings?.tts?.voice;
1719
- processedMessage.voice = this.getVoice(mainVoice);
1720
- processedMessage.imgUrl = extraData.assistantImg;
1721
- // I think Process Text Engine should only apply to assistant messages not user
1722
- // Process based on text engine
1723
- if (conversationSettings.textEngine === TextEngines.MarkdownMultiMessages) {
1724
- this.processMultiMessages(processedMessage, conversationSettings);
1725
- }
1726
- else if (conversationSettings.textEngine === TextEngines.MarkdownSSML) {
1727
- if (!conversationSettings?.tts?.secondaryVoice) {
1728
- throw new Error('Secondary voice is required for SSML');
1729
- }
1730
- const content = this.subsItalicsByTag(processedMessage.content, conversationSettings.tts.secondaryVoice);
1731
- processedMessage.ssml = '<speak>' + content + '</speak>';
1732
- }
1846
+ const processedMessage = {
1847
+ ...message,
1848
+ messageId: message.messageId || nanoid(),
1849
+ };
1850
+ if (processedMessage.role === ChatRole.User) {
1851
+ return this.processUserMessage(processedMessage, extraData);
1852
+ }
1853
+ if (processedMessage.role === ChatRole.Assistant) {
1854
+ return this.processAssistantMessage(processedMessage, conversationSettings, extraData);
1733
1855
  }
1734
1856
  return processedMessage;
1735
1857
  }
1736
- // Process multi-messages from markdown
1858
+ processUserMessage(message, extraData) {
1859
+ if (extraData.userImg) {
1860
+ message.imgUrl = extraData.userImg;
1861
+ }
1862
+ return message;
1863
+ }
1864
+ processAssistantMessage(message, settings, extraData) {
1865
+ if (extraData.assistantImg) {
1866
+ message.imgUrl = extraData.assistantImg;
1867
+ }
1868
+ const mainVoice = settings?.mainVoice?.voice || settings?.tts?.voice;
1869
+ message.voice = this.getVoice(mainVoice);
1870
+ switch (settings.textEngine) {
1871
+ case TextEngines.MarkdownMultiMessages:
1872
+ this.processMultiMessages(message, settings);
1873
+ break;
1874
+ case TextEngines.MarkdownSSML:
1875
+ this.processSSML(message, settings);
1876
+ break;
1877
+ }
1878
+ return message;
1879
+ }
1737
1880
  processMultiMessages(message, settings) {
1738
- // Convert markdown to HTML segments
1739
- const mdToHtml = convertToHTML(message.content);
1740
- // Map segments to multi-messages
1741
- message.multiMessages = mdToHtml.map((val) => {
1742
- // TODO: tts is deprecated settings?.tts?.secondaryVoice
1881
+ let htmlSegments = convertToHTML(message.content);
1882
+ if (htmlSegments.length === 1 && htmlSegments[0].content.length > 200) {
1883
+ // Only if is only one single message, becouse i dont want affect the currente, narrator/char feacture
1884
+ // Try to split in 200 characters
1885
+ const chunks = this.splitContent(message.content, 190);
1886
+ htmlSegments = chunks.flatMap((chunk) => convertToHTML(chunk));
1887
+ }
1888
+ message.multiMessages = htmlSegments.map((segment) => {
1743
1889
  const secondaryVoice = settings?.secondaryVoice?.voice || settings?.tts?.secondaryVoice || 'en-US-News-L';
1744
- // Determine if this is italicized text (narrator)
1745
- const isItalics = val.tag === 'em';
1890
+ const isItalics = segment.tag === 'em';
1746
1891
  const voice = isItalics ? secondaryVoice : message.voice;
1747
1892
  return {
1748
1893
  voice,
1749
- content: val.content,
1894
+ content: segment.content,
1750
1895
  audioUrl: null,
1751
1896
  audioPromise: null,
1752
- text: val.text,
1753
- tag: val.tag,
1897
+ text: segment.text,
1898
+ tag: segment.tag,
1754
1899
  };
1755
1900
  });
1756
1901
  }
1757
- // Replace italics with voice tags for SSML
1902
+ processSSML(message, settings) {
1903
+ if (!settings?.tts?.secondaryVoice) {
1904
+ throw new Error('Secondary voice is required for SSML');
1905
+ }
1906
+ const content = this.subsItalicsByTag(message.content, settings.tts.secondaryVoice);
1907
+ message.ssml = `<speak>${content}</speak>`;
1908
+ }
1909
+ splitContent(content, maxLength) {
1910
+ const chunks = [];
1911
+ let currentPos = 0;
1912
+ while (currentPos < content.length) {
1913
+ let endPos = currentPos + maxLength;
1914
+ if (endPos >= content.length) {
1915
+ endPos = content.length;
1916
+ }
1917
+ else {
1918
+ const slice = content.substring(currentPos, endPos);
1919
+ const lastSentenceEnd = slice.search(/[.!?\n](?=[^.!?\n]*$)/);
1920
+ if (lastSentenceEnd !== -1) {
1921
+ endPos = currentPos + lastSentenceEnd + 1;
1922
+ }
1923
+ else {
1924
+ const lastSpace = content.lastIndexOf(' ', endPos);
1925
+ if (lastSpace > currentPos) {
1926
+ endPos = lastSpace;
1927
+ }
1928
+ }
1929
+ }
1930
+ const newContent = content.substring(currentPos, endPos).trim();
1931
+ if (newContent) {
1932
+ chunks.push(newContent);
1933
+ }
1934
+ currentPos = endPos;
1935
+ }
1936
+ return chunks;
1937
+ }
1758
1938
  subsItalicsByTag(text, voiceId = 'it-IT-Neural2-A', tagName = 'voice') {
1759
1939
  const regex = /\*(.*?)\*/g;
1760
- return text.replace(regex, (match, p1) => `<${tagName} name="${voiceId}">${p1}</${tagName}>`);
1940
+ return text.replace(regex, (_, p1) => `<${tagName} name="${voiceId}">${p1}</${tagName}>`);
1761
1941
  }
1762
- // Get appropriate voice based on settings
1763
- getVoice(voice_value, targetLang = 'en') {
1764
- if ([null, '', 'random'].includes(voice_value)) {
1942
+ getVoice(voiceValue, targetLang = 'en') {
1943
+ if (!voiceValue || voiceValue === 'random') {
1765
1944
  const voiceCodes = VoiceTTSOptions.map((val) => val.id);
1766
1945
  return voiceCodes[Math.floor(Math.random() * voiceCodes.length)];
1767
1946
  }
1768
- if (voice_value === 'randomMan') {
1769
- const voiceCodes = VoiceTTSOptions.filter((voice) => voice.gender === 'male' && voice.lang.includes(targetLang)).map((val) => val.id);
1770
- return voiceCodes[Math.floor(Math.random() * voiceCodes.length)];
1771
- }
1772
- else if (voice_value === 'randomWoman') {
1773
- const voiceCodes = VoiceTTSOptions.filter((voice) => voice.gender === 'female' && voice.lang.includes(targetLang)).map((val) => val.id);
1947
+ if (voiceValue === 'randomMan' || voiceValue === 'randomWoman') {
1948
+ const gender = voiceValue === 'randomMan' ? 'male' : 'female';
1949
+ const voiceCodes = VoiceTTSOptions.filter((voice) => voice.gender === gender && voice.lang.includes(targetLang)).map((val) => val.id);
1774
1950
  return voiceCodes[Math.floor(Math.random() * voiceCodes.length)];
1775
1951
  }
1776
- else {
1777
- return voice_value;
1778
- // voice should exist, there wont be validation.
1779
- // const voice = VoiceTTSOptions.find((voice) => voice.id === voice_value);
1780
- // if (voice) {
1781
- // return voice.id;
1782
- // } else {
1783
- // console.error('Voice not found getting something random', voice_value);
1784
- // return VoiceTTSOptions.find((voice) => voice.lang.includes(targetLang))?.id || '';
1785
- // }
1786
- }
1952
+ return voiceValue;
1787
1953
  }
1788
1954
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MessageProcessingService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1789
1955
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MessageProcessingService, providedIn: 'root' }); }
@@ -1869,6 +2035,7 @@ class DynamicCriteriaService {
1869
2035
  this.defaultAgentCardService = inject(DefaultAgentCardsService);
1870
2036
  this.globalToolsService = inject(GlobalToolsService);
1871
2037
  this.messageState = inject(MessagesStateService);
2038
+ this.chatMonitorService = inject(ChatMonitorService);
1872
2039
  }
1873
2040
  async evaluateUsingTools() {
1874
2041
  const tools = this.dynamicFlowService.conversationFlowState()?.tools || [];
@@ -1913,18 +2080,26 @@ class DynamicCriteriaService {
1913
2080
  const moodState = MoodStateOptions.find((option) => option.value === mood);
1914
2081
  return moodState?.emoji;
1915
2082
  }
1916
- async evaluateMoodState() {
2083
+ async evaluateMoodState(validMoodStates) {
1917
2084
  // Se asume que esto ocurré después de que el asistente responde. entonces el ultimo mensaje debe ser del asistente.
1918
2085
  const last2Dialog = this.contextEngineService.getContextMessages(ContextType.Last2Messages);
1919
2086
  const conversationContext = last2Dialog.map((message) => `${message.role}: ${message.content}`).join('\n');
1920
2087
  const assistantMessage = last2Dialog.find((message) => message.role === ChatRole.Assistant);
1921
- const prompt = `${MOOD_STATE_PROMPT}\n\n<Context>${conversationContext}</Context>`;
2088
+ let moodStatePrompt = null;
2089
+ if (this.dynamicFlowService.conversationFlowState()?.moodState.useAssetStatesOnly) {
2090
+ moodStatePrompt = getMoodStatePrompt(validMoodStates.join(', '));
2091
+ }
2092
+ else {
2093
+ moodStatePrompt = getMoodStatePrompt();
2094
+ }
2095
+ const prompt = `${moodStatePrompt}\n\n<Context>\n${conversationContext}\n</Context>`;
1922
2096
  const result = await this.defaultAgentCardService.callChatCompletion({
1923
2097
  messages: [{ role: ChatRole.User, content: prompt }],
1924
2098
  returnJson: true,
1925
2099
  type: 'mood-state',
1926
2100
  });
1927
2101
  if (Array.isArray(result.content)) {
2102
+ this.chatMonitorService.logCurrentMood(result.content);
1928
2103
  console.log('Mood state result:', result.content, assistantMessage);
1929
2104
  if (assistantMessage?.messageId) {
1930
2105
  const moodEmojis = result.content.map((mood) => this.getMoodEmoji(mood)).filter((emoji) => !!emoji);
@@ -2356,8 +2531,8 @@ class DynamicFlowTaskService {
2356
2531
  this.userService = inject(UserService);
2357
2532
  }
2358
2533
  async evaluateAssistantTaskTrigger(message) {
2359
- const userChatSettings = this.userService.user()?.settings?.conversation?.assistantMessageTask;
2360
- if (!userChatSettings) {
2534
+ const canTriggerAssistant = this.userService.user()?.settings?.conversation?.assistantMessageTask;
2535
+ if (!canTriggerAssistant) {
2361
2536
  return;
2362
2537
  }
2363
2538
  const conversationFlow = this.dynamicFlowService.conversationFlowState();
@@ -2469,63 +2644,34 @@ class ConversationService {
2469
2644
  conversationSettings.model = userSettings.model;
2470
2645
  }
2471
2646
  }
2472
- setupConversationWithAgentCard(agentCard, parseDict = null, appConversationFlow = null) {
2647
+ setupConversationWithAgentCard(agentCard, parseDict = null, defaultAppConversationFlow = null) {
2473
2648
  this.agentCardSignal.set(agentCard);
2474
- // Basically extract settings and flow from agent card, and overrider with user seetings is needed.
2475
- this.avatarImages.assistantImg = agentCard?.assets?.image?.url || this.avatarImages.assistantImg; // Set user AI avatar image
2476
- // Aqui es la parte crucial de los settings definir prioridad.
2649
+ this.avatarImages.assistantImg = agentCard?.assets?.image?.url || this.avatarImages.assistantImg;
2477
2650
  const conversationSettings = this.conversationBuilder.buildConversationSettings(agentCard, parseDict);
2478
- // Here i need some rules to see when i will override and what.
2479
2651
  this.overrideSettingsByUserSettings(conversationSettings);
2480
2652
  this.conversationSettingsState.set(conversationSettings);
2481
- // 🙄 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
2482
- // La otra estretegía es: tomar solo agentCard o appConversationFlow, pero no ambos
2483
- const agentCardConversationFlow = agentCard.conversationFlow;
2484
- // Delete properties if not exists so my merge contains only properties set
2485
- if (!agentCardConversationFlow?.goal?.task) {
2486
- delete agentCardConversationFlow.goal;
2487
- }
2488
- if (!agentCardConversationFlow?.triggerTasks?.onUserMessage?.task) {
2489
- delete agentCardConversationFlow.triggerTasks.onUserMessage;
2490
- }
2491
- if (!agentCardConversationFlow?.triggerTasks?.onAssistantMessage?.task) {
2492
- delete agentCardConversationFlow.triggerTasks.onAssistantMessage;
2493
- }
2494
- const mergedConversationFlow = { ...appConversationFlow, ...agentCardConversationFlow };
2495
- // Only if exits agentCard.conversationFlow, that will override the defaults
2496
- // NOTE: ill comment for now, but check if a need manual verification later.
2497
- // if (!agentCard.conversationFlow.goal.task && appConversationFlow.goal.task) {
2498
- // // Monstly of the time
2499
- // mergedConversationFlow.goal = appConversationFlow.goal;
2500
- // }
2501
- // if (appConversationFlow) {
2502
- // // Just replace the default if agent card has a value
2503
- // if (agentCard.conversationFlow) {
2504
- // if (agentCard.conversationFlow?.goal?.task) {
2505
- // appConversationFlow.goal = agentCard.conversationFlow.goal;
2506
- // }
2507
- // if (agentCard.conversationFlow?.dynamicConditions) {
2508
- // appConversationFlow.dynamicConditions = agentCard.conversationFlow.dynamicConditions;
2509
- // }
2510
- // if (agentCard.conversationFlow?.triggerTasks) {
2511
- // // Leave default if a concreate task is not provided.
2512
- // if (appConversationFlow.triggerTasks?.onUserMessage?.task) {
2513
- // appConversationFlow.triggerTasks.onUserMessage = agentCard.conversationFlow.triggerTasks.onUserMessage;
2514
- // }
2515
- // if (agentCard.conversationFlow.triggerTasks?.onUserMessage?.task) {
2516
- // appConversationFlow.triggerTasks.onUserMessage = agentCard.conversationFlow.triggerTasks.onUserMessage;
2517
- // }
2518
- // appConversationFlow.triggerTasks = { ...agentCard.conversationFlow.triggerTasks, ...appConversationFlow.triggerTasks };
2519
- // }
2520
- // if (agentCard.conversationFlow?.challenges) {
2521
- // appConversationFlow.challenges = agentCard.conversationFlow.challenges;
2522
- // }
2523
- // if (agentCard.conversationFlow?.tools?.length) {
2524
- // appConversationFlow.tools = agentCard.conversationFlow.tools;
2525
- // }
2526
- // }
2527
- this.dynamicFlowService.setConversationFlow(mergedConversationFlow);
2528
- // }
2653
+ const conversationFlow = this.mergeConversationFlows(agentCard.conversationFlow, defaultAppConversationFlow);
2654
+ this.dynamicFlowService.setConversationFlow(conversationFlow);
2655
+ }
2656
+ mergeConversationFlows(agentFlow, defaultFlow) {
2657
+ if (!defaultFlow) {
2658
+ return agentFlow;
2659
+ }
2660
+ const mergedFlow = { ...agentFlow };
2661
+ mergedFlow.goal = agentFlow?.goal?.task ? agentFlow.goal : defaultFlow.goal;
2662
+ mergedFlow.dynamicConditions = agentFlow?.dynamicConditions?.length > 0 ? agentFlow.dynamicConditions : defaultFlow.dynamicConditions;
2663
+ mergedFlow.challenges = agentFlow?.challenges?.length > 0 ? agentFlow.challenges : defaultFlow.challenges;
2664
+ mergedFlow.tools = agentFlow?.tools?.length > 0 ? agentFlow.tools : defaultFlow.tools;
2665
+ if (!mergedFlow.triggerTasks) {
2666
+ mergedFlow.triggerTasks = {};
2667
+ }
2668
+ mergedFlow.triggerTasks.onUserMessage = agentFlow?.triggerTasks?.onUserMessage?.task
2669
+ ? agentFlow.triggerTasks.onUserMessage
2670
+ : defaultFlow.triggerTasks?.onUserMessage;
2671
+ mergedFlow.triggerTasks.onAssistantMessage = agentFlow?.triggerTasks?.onAssistantMessage?.task
2672
+ ? agentFlow.triggerTasks.onAssistantMessage
2673
+ : defaultFlow.triggerTasks?.onAssistantMessage;
2674
+ return mergedFlow;
2529
2675
  }
2530
2676
  async initConversationWithSettings(conversationSettings, conversationFlow) {
2531
2677
  this.overrideSettingsByUserSettings(conversationSettings);
@@ -2659,8 +2805,15 @@ class ConversationService {
2659
2805
  // Run Dynamic Flow Evaluations
2660
2806
  this.dynamicFlowTaskService.evaluateAssistantTaskTrigger(newMessage); // Not waiting should be parallel.
2661
2807
  // this.dynamicCriteriaService.evaluateUsingTools();
2662
- if (this.dynamicFlowService.conversationFlowState()?.moodStateEnabled) {
2663
- this.dynamicCriteriaService.evaluateMoodState();
2808
+ if (this.dynamicFlowService.conversationFlowState()?.moodState.enabled) {
2809
+ let assetsMoodStates = null;
2810
+ if (this.dynamicFlowService.conversationFlowState()?.moodState.useAssetStatesOnly) {
2811
+ // Extract mood states from assets.
2812
+ const motionStates = this.agentCardSignal().assets.motions || [];
2813
+ assetsMoodStates = motionStates.map((motion) => motion.metadata?.moodState);
2814
+ assetsMoodStates.push('default');
2815
+ }
2816
+ this.dynamicCriteriaService.evaluateMoodState(assetsMoodStates);
2664
2817
  }
2665
2818
  return newMessage.messageId;
2666
2819
  }
@@ -2692,7 +2845,7 @@ class AIGenerationService {
2692
2845
  }
2693
2846
  async generateImage(chatMessage, chatText) {
2694
2847
  const agentCard = this.conversationService.agentCard$();
2695
- const pictureDescription = agentCard?.characterCard?.data?.picture_description;
2848
+ const pictureDescription = agentCard?.characterCard?.data?.appearance;
2696
2849
  const urlImage = await this.vertexService.generateComfyImage({ prompt: `${pictureDescription} ${chatText}` });
2697
2850
  this.messagesStateService.updateMessage(chatMessage.messageId, { generatedImg: urlImage });
2698
2851
  return urlImage;
@@ -2970,7 +3123,7 @@ class ChatFooterComponent {
2970
3123
  }
2971
3124
  }
2972
3125
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2973
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", 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(dynamicFlowService.conversationFlowState()?.goal?.enabled) {\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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$3.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished"] }] }); }
3126
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", 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(dynamicFlowService.conversationFlowState()?.goal?.enabled) {\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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$3.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished"] }] }); }
2974
3127
  }
2975
3128
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatFooterComponent, decorators: [{
2976
3129
  type: Component,
@@ -3302,11 +3455,11 @@ class MessageContentDisplayer {
3302
3455
  console.log('debug', this.wordWithMeta());
3303
3456
  }
3304
3457
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MessageContentDisplayer, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3305
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: MessageContentDisplayer, isStandalone: true, selector: "message-content-displayer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, markWord: { classPropertyName: "markWord", publicName: "markWord", isSignal: true, isRequired: false, 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\n [class]=\"word.tag\"\n [class.highlight]=\"word.isHighlighted\"\n [class.marked]=\"word.marked\"\n (click)=\"onWordClick(word)\"\n [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}::ng-deep .marked{position:relative;color:#f8bfbc}::ng-deep .marked:before{content:\"\";z-index:-2;left:-.1em;top:.1em;border-width:2px;border-style:solid;border-color:#f27068;position:absolute;border-right-color:transparent;width:100%;height:1em;transform:rotate(2deg);opacity:.7;border-radius:50%;padding:.1em .25em}::ng-deep .marked:after{content:\"\";z-index:-1;left:-.1em;top:.4em;padding:.1em .25em;border-width:2px;border-style:solid;border-color:#f27068;border-left-color:transparent;border-top-color:transparent;position:absolute;width:100%;height:1em;transform:rotate(-1deg);opacity:.7;border-radius:50%}.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 }); }
3458
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: MessageContentDisplayer, isStandalone: true, selector: "message-content-displayer", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: true, transformFunction: null }, markWord: { classPropertyName: "markWord", publicName: "markWord", isSignal: true, isRequired: false, 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\n [class]=\"word.tag\"\n [class.highlight]=\"word.isHighlighted\"\n [class.marked]=\"word.marked\"\n (click)=\"onWordClick(word)\"\n [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}::ng-deep .marked{position:relative;color:#f8bfbc}::ng-deep .marked:before{content:\"\";z-index:-2;left:-.1em;top:.1em;border-width:2px;border-style:solid;border-color:#f27068;position:absolute;border-right-color:transparent;width:100%;height:1em;transform:rotate(2deg);opacity:.7;border-radius:50%;padding:.1em .25em}::ng-deep .marked:after{content:\"\";z-index:-1;left:-.1em;top:.4em;padding:.1em .25em;border-width:2px;border-style:solid;border-color:#f27068;border-left-color:transparent;border-top-color:transparent;position:absolute;width:100%;height:1em;transform:rotate(-1deg);opacity:.7;border-radius:50%}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.em{font-style:italic;color:#2e68d4}.strong{font-weight:700;color:inherit}.italic{font-style:italic;color:#0d5cf0}.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 }); }
3306
3459
  }
3307
3460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: MessageContentDisplayer, decorators: [{
3308
3461
  type: Component,
3309
- 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\n [class]=\"word.tag\"\n [class.highlight]=\"word.isHighlighted\"\n [class.marked]=\"word.marked\"\n (click)=\"onWordClick(word)\"\n [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}::ng-deep .marked{position:relative;color:#f8bfbc}::ng-deep .marked:before{content:\"\";z-index:-2;left:-.1em;top:.1em;border-width:2px;border-style:solid;border-color:#f27068;position:absolute;border-right-color:transparent;width:100%;height:1em;transform:rotate(2deg);opacity:.7;border-radius:50%;padding:.1em .25em}::ng-deep .marked:after{content:\"\";z-index:-1;left:-.1em;top:.4em;padding:.1em .25em;border-width:2px;border-style:solid;border-color:#f27068;border-left-color:transparent;border-top-color:transparent;position:absolute;width:100%;height:1em;transform:rotate(-1deg);opacity:.7;border-radius:50%}.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"] }]
3462
+ 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\n [class]=\"word.tag\"\n [class.highlight]=\"word.isHighlighted\"\n [class.marked]=\"word.marked\"\n (click)=\"onWordClick(word)\"\n [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}::ng-deep .marked{position:relative;color:#f8bfbc}::ng-deep .marked:before{content:\"\";z-index:-2;left:-.1em;top:.1em;border-width:2px;border-style:solid;border-color:#f27068;position:absolute;border-right-color:transparent;width:100%;height:1em;transform:rotate(2deg);opacity:.7;border-radius:50%;padding:.1em .25em}::ng-deep .marked:after{content:\"\";z-index:-1;left:-.1em;top:.4em;padding:.1em .25em;border-width:2px;border-style:solid;border-color:#f27068;border-left-color:transparent;border-top-color:transparent;position:absolute;width:100%;height:1em;transform:rotate(-1deg);opacity:.7;border-radius:50%}.spin-animation{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.em{font-style:italic;color:#2e68d4}.strong{font-weight:700;color:inherit}.italic{font-style:italic;color:#0d5cf0}.em_strong{font-weight:700;font-style:italic;color:inherit}\n"] }]
3310
3463
  }], ctorParameters: () => [] });
3311
3464
 
3312
3465
  class MessageOrchestrationService {
@@ -3466,11 +3619,11 @@ class ChatMessageOrchestratorComponent {
3466
3619
  this.orchestrationService.wordClicked(wordData);
3467
3620
  }
3468
3621
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMessageOrchestratorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3469
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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", "markWord"], outputs: ["playAudio", "audioCompleted", "wordClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3622
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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}message-content-displayer{text-shadow:1px 1px 4px rgba(255,255,255,.4)}\n"], dependencies: [{ kind: "component", type: MessageContentDisplayer, selector: "message-content-displayer", inputs: ["message", "markWord"], outputs: ["playAudio", "audioCompleted", "wordClicked"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3470
3623
  }
3471
3624
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMessageOrchestratorComponent, decorators: [{
3472
3625
  type: Component,
3473
- 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"] }]
3626
+ 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}message-content-displayer{text-shadow:1px 1px 4px rgba(255,255,255,.4)}\n"] }]
3474
3627
  }] });
3475
3628
 
3476
3629
  const EVALUATION_EMOJIS = {
@@ -3488,7 +3641,7 @@ class ChatMessageComponent {
3488
3641
  this.chatMessage = input.required(...(ngDevMode ? [{ debugName: "chatMessage" }] : []));
3489
3642
  this.chatUserSettings = input(null, ...(ngDevMode ? [{ debugName: "chatUserSettings" }] : []));
3490
3643
  // Signal States
3491
- this.audioMessage = signal(null, ...(ngDevMode ? [{ debugName: "audioMessage" }] : []));
3644
+ this.messageContent = signal(null, ...(ngDevMode ? [{ debugName: "messageContent" }] : []));
3492
3645
  // Computed properties for easier access to signal values
3493
3646
  this.hasMultiMessages = computed(() => !!this.chatMessage()?.multiMessages, ...(ngDevMode ? [{ debugName: "hasMultiMessages" }] : []));
3494
3647
  this.multiMessages = computed(() => this.chatMessage()?.multiMessages || [], ...(ngDevMode ? [{ debugName: "multiMessages" }] : []));
@@ -3503,7 +3656,7 @@ class ChatMessageComponent {
3503
3656
  if (!message || message.role === ChatRole.AssistantHelper)
3504
3657
  return;
3505
3658
  if (message.role === ChatRole.User || (message.role === ChatRole.Assistant && !this.hasMultiMessages())) {
3506
- this.audioMessage.set({ ...message });
3659
+ this.messageContent.set({ ...message });
3507
3660
  }
3508
3661
  });
3509
3662
  }
@@ -3519,11 +3672,11 @@ class ChatMessageComponent {
3519
3672
  console.log(res);
3520
3673
  }
3521
3674
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3522
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 (chatMessage().generatedImg) {\n <img class=\"generated-img\" [src]=\"chatMessage().generatedImg\" alt=\"Generated Image\" />\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 } @if (userService.isAdmin()) {\n <div class=\"options-footer\">\n <i #popoverTarget class=\"pi pi-ellipsis-h\" style=\"font-size: 1rem\" (click)=\"op.toggle($event)\"></i>\n <p-popover #op>\n <ul class=\"list-none p-0 m-0 flex flex-col\">\n <li class=\"flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border\" (click)=\"generateImage()\">\n <span>Generate image</span>\n </li>\n </ul>\n </p-popover>\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}.options-footer{position:absolute;bottom:5px;right: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)}}.generated-img{width:100%;border-radius:var(--border-radius)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChatMessageOrchestratorComponent, selector: "dc-message-orchestrator", inputs: ["messages", "messageRole"], outputs: ["audioCompleted"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3675
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 (chatMessage().generatedImg) {\n <img class=\"generated-img\" [src]=\"chatMessage().generatedImg\" alt=\"Generated Image\" />\n } @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[messageContent()]\" [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 } @if (userService.isAdmin()) {\n <div class=\"options-footer\">\n <i #popoverTarget class=\"pi pi-ellipsis-h\" style=\"font-size: 1rem\" (click)=\"op.toggle($event)\"></i>\n <p-popover #op>\n <ul class=\"list-none p-0 m-0 flex flex-col\">\n <li class=\"flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border\" (click)=\"generateImage()\">\n <span>Generate image</span>\n </li>\n </ul>\n </p-popover>\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, .5);--assistant-message-bg: rgba(240, 240, 240, .5);--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}.options-footer{position:absolute;bottom:5px;right: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)}}.generated-img{width:100%;border-radius:var(--border-radius)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: ChatMessageOrchestratorComponent, selector: "dc-message-orchestrator", inputs: ["messages", "messageRole"], outputs: ["audioCompleted"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3523
3676
  }
3524
3677
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ChatMessageComponent, decorators: [{
3525
3678
  type: Component,
3526
- args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, ChatMessageOrchestratorComponent, PopoverModule], 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 (chatMessage().generatedImg) {\n <img class=\"generated-img\" [src]=\"chatMessage().generatedImg\" alt=\"Generated Image\" />\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 } @if (userService.isAdmin()) {\n <div class=\"options-footer\">\n <i #popoverTarget class=\"pi pi-ellipsis-h\" style=\"font-size: 1rem\" (click)=\"op.toggle($event)\"></i>\n <p-popover #op>\n <ul class=\"list-none p-0 m-0 flex flex-col\">\n <li class=\"flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border\" (click)=\"generateImage()\">\n <span>Generate image</span>\n </li>\n </ul>\n </p-popover>\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}.options-footer{position:absolute;bottom:5px;right: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)}}.generated-img{width:100%;border-radius:var(--border-radius)}\n"] }]
3679
+ args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, ChatMessageOrchestratorComponent, PopoverModule], 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 (chatMessage().generatedImg) {\n <img class=\"generated-img\" [src]=\"chatMessage().generatedImg\" alt=\"Generated Image\" />\n } @if (hasMultiMessages()) {\n <dc-message-orchestrator [messages]=\"multiMessages()\" [messageRole]=\"chatMessage().role\"></dc-message-orchestrator>\n } @else {\n <dc-message-orchestrator [messages]=\"[messageContent()]\" [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 } @if (userService.isAdmin()) {\n <div class=\"options-footer\">\n <i #popoverTarget class=\"pi pi-ellipsis-h\" style=\"font-size: 1rem\" (click)=\"op.toggle($event)\"></i>\n <p-popover #op>\n <ul class=\"list-none p-0 m-0 flex flex-col\">\n <li class=\"flex items-center gap-2 px-2 py-3 hover:bg-emphasis cursor-pointer rounded-border\" (click)=\"generateImage()\">\n <span>Generate image</span>\n </li>\n </ul>\n </p-popover>\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, .5);--assistant-message-bg: rgba(240, 240, 240, .5);--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}.options-footer{position:absolute;bottom:5px;right: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)}}.generated-img{width:100%;border-radius:var(--border-radius)}\n"] }]
3527
3680
  }], ctorParameters: () => [] });
3528
3681
 
3529
3682
  class ChatMessagesListComponent {
@@ -3659,7 +3812,7 @@ class ModelSelectorComponent {
3659
3812
  }
3660
3813
  }
3661
3814
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ModelSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3662
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3815
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3663
3816
  }
3664
3817
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ModelSelectorComponent, decorators: [{
3665
3818
  type: Component,
@@ -3743,7 +3896,7 @@ class DCConversationUserChatSettingsComponent {
3743
3896
  }
3744
3897
  }
3745
3898
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCConversationUserChatSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3746
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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(userService.isAdmin()) {\n <div>\n <hr />\n <b> <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i> 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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i3$1.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "styleClass", "autofocus", "binary", "variant", "size"], 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { 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: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }] }); }
3899
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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(userService.isAdmin()) {\n <div>\n <hr />\n <b> <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i> 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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i3$2.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "styleClass", "autofocus", "binary", "variant", "size"], 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { 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: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }] }); }
3747
3900
  }
3748
3901
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCConversationUserChatSettingsComponent, decorators: [{
3749
3902
  type: Component,
@@ -3819,6 +3972,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
3819
3972
  }]
3820
3973
  }] });
3821
3974
 
3975
+ class PromptPreviewComponent {
3976
+ constructor() {
3977
+ this.promptBuilder = inject(ConversationPromptBuilderService);
3978
+ this.messages = input.required(...(ngDevMode ? [{ debugName: "messages" }] : []));
3979
+ this.jailBrake = input(...(ngDevMode ? [undefined, { debugName: "jailBrake" }] : []));
3980
+ this.formatCamelCaseString = formatCamelCaseString;
3981
+ }
3982
+ estimateTokens(text) {
3983
+ return this.promptBuilder.estimateTokens(text);
3984
+ }
3985
+ get totalTokens() {
3986
+ let totalTokens = 0;
3987
+ for (const message of this.messages()) {
3988
+ totalTokens += this.estimateTokens(message.content || '');
3989
+ }
3990
+ if (this.jailBrake()) {
3991
+ totalTokens += this.estimateTokens(this.jailBrake());
3992
+ }
3993
+ return totalTokens;
3994
+ }
3995
+ ngOnInit() {
3996
+ console.log(this.messages());
3997
+ console.log(this.jailBrake());
3998
+ }
3999
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: PromptPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4000
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: PromptPreviewComponent, isStandalone: true, selector: "dc-prompt-preview", inputs: { messages: { classPropertyName: "messages", publicName: "messages", isSignal: true, isRequired: true, transformFunction: null }, jailBrake: { classPropertyName: "jailBrake", publicName: "jailBrake", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<h3\n >Total Tokens: <b class=\"text-green-700\">{{ totalTokens }}</b></h3\n>\n\n@for (message of messages(); track message) {\n<div>\n <h5>\n <b style=\"margin: 3px\" class=\"text-blue-700\">{{ formatCamelCaseString(message.role) }}</b>\n <b style=\"margin: 3px\" class=\"text-red-700\">{{ formatCamelCaseString(message.messageId) }}</b>\n <b style=\"margin: 3px\" class=\"text-green-700\">({{ estimateTokens(message.content || '') }} tokens)</b>\n </h5>\n <markdown>{{ message.content }}</markdown>\n</div>\n} @if (jailBrake()) {\n<div>\n <h5\n >JailBrake Instructions <b class=\"text-green-700\">({{ estimateTokens(jailBrake()!) }} tokens)</b></h5\n >\n <p>{{ jailBrake() }}</p>\n</div>\n}\n", styles: [":host{display:block;font-family:sans-serif;padding:1rem}h3,h5{margin-top:0}p{white-space:pre-wrap;word-break:break-word;margin-bottom:1rem;padding:.5rem;background-color:#f5f5f5;border-radius:4px}.text-blue-700{color:#1d4ed8}.text-red-700{color:#b91c1c}.text-green-700{color:#15803d}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ChipModule }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }] }); }
4001
+ }
4002
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: PromptPreviewComponent, decorators: [{
4003
+ type: Component,
4004
+ args: [{ selector: 'dc-prompt-preview', standalone: true, imports: [CommonModule, ChipModule, MarkdownComponent], template: "<h3\n >Total Tokens: <b class=\"text-green-700\">{{ totalTokens }}</b></h3\n>\n\n@for (message of messages(); track message) {\n<div>\n <h5>\n <b style=\"margin: 3px\" class=\"text-blue-700\">{{ formatCamelCaseString(message.role) }}</b>\n <b style=\"margin: 3px\" class=\"text-red-700\">{{ formatCamelCaseString(message.messageId) }}</b>\n <b style=\"margin: 3px\" class=\"text-green-700\">({{ estimateTokens(message.content || '') }} tokens)</b>\n </h5>\n <markdown>{{ message.content }}</markdown>\n</div>\n} @if (jailBrake()) {\n<div>\n <h5\n >JailBrake Instructions <b class=\"text-green-700\">({{ estimateTokens(jailBrake()!) }} tokens)</b></h5\n >\n <p>{{ jailBrake() }}</p>\n</div>\n}\n", styles: [":host{display:block;font-family:sans-serif;padding:1rem}h3,h5{margin-top:0}p{white-space:pre-wrap;word-break:break-word;margin-bottom:1rem;padding:.5rem;background-color:#f5f5f5;border-radius:4px}.text-blue-700{color:#1d4ed8}.text-red-700{color:#b91c1c}.text-green-700{color:#15803d}\n"] }]
4005
+ }] });
4006
+
3822
4007
  class ConversationInspector {
3823
4008
  constructor() {
3824
4009
  this.evaluationService = inject(EvaluationService);
@@ -3849,11 +4034,11 @@ class ConversationInspector {
3849
4034
  navigator.clipboard.writeText(exportString);
3850
4035
  }
3851
4036
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ConversationInspector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3852
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n </div>\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>Estado Global 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: "ngmodule", type: SliderModule }, { kind: "component", type: i1$4.Slider, selector: "p-slider", inputs: ["animate", "min", "max", "orientation", "step", "range", "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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.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: ["styleClass", "layout", "type", "align"] }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
4037
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\"></dc-prompt-preview>\n </details>\n\n <details>\n <summary>Estado Global 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: "ngmodule", type: SliderModule }, { kind: "component", type: i1$4.Slider, selector: "p-slider", inputs: ["animate", "min", "max", "orientation", "step", "range", "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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$1.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "component", type: PromptPreviewComponent, selector: "dc-prompt-preview", inputs: ["messages", "jailBrake"] }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
3853
4038
  }
3854
4039
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ConversationInspector, decorators: [{
3855
4040
  type: Component,
3856
- 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 <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n </div>\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>Estado Global 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"] }]
4041
+ args: [{ selector: 'dc-conversation-info', standalone: true, imports: [CommonModule, SafeJsonPipe, SliderModule, ButtonModule, FormsModule, DividerModule, PromptPreviewComponent], 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 <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\"></dc-prompt-preview>\n </details>\n\n <details>\n <summary>Estado Global 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"] }]
3857
4042
  }], ctorParameters: () => [] });
3858
4043
 
3859
4044
  class ConversationInfoService {
@@ -3864,6 +4049,7 @@ class ConversationInfoService {
3864
4049
  this.dialogService.open(ConversationInspector, {
3865
4050
  header: 'Conversation Inspection',
3866
4051
  width: '90vw',
4052
+ maximizable: true,
3867
4053
  modal: true,
3868
4054
  draggable: false,
3869
4055
  closable: true,
@@ -3924,6 +4110,7 @@ class DCChatComponent {
3924
4110
  }
3925
4111
  async ngOnInit() {
3926
4112
  this.conversationService.setDestroyed(false);
4113
+ this.chatMonitorService.isConversationActive.set(true);
3927
4114
  if (this.conversationSettings) {
3928
4115
  await this.conversationService.initConversationWithSettings(this.conversationSettings, this.conversationFlow);
3929
4116
  }
@@ -3936,10 +4123,12 @@ class DCChatComponent {
3936
4123
  ngOnDestroy() {
3937
4124
  // Mark conversation as destroyed to prevent async operations
3938
4125
  this.conversationService.setDestroyed(true);
4126
+ this.chatMonitorService.isConversationActive.set(false);
3939
4127
  // Ensure the microphone is stopped when the chat component is destroyed
3940
4128
  this.chatFooterComponent?.stopMic();
3941
4129
  this.evaluationService.analylizePerformance();
3942
4130
  this.evaluationService.resetEvaluation();
4131
+ // this.conversationService.resetConversation(); // Not sure if i need this? last update not even exits the line and was working.
3943
4132
  }
3944
4133
  /**
3945
4134
  * Open chat settings dialog
@@ -4139,21 +4328,22 @@ class PromptPreviewDialogComponent {
4139
4328
  constructor() {
4140
4329
  this.dynamicDialogConfig = inject(DynamicDialogConfig);
4141
4330
  this.dialogRef = inject(DynamicDialogRef);
4142
- this.data = this.dynamicDialogConfig.data;
4331
+ this.messages = this.dynamicDialogConfig.data.messages;
4332
+ this.jailBrake = this.dynamicDialogConfig.data.jailBrake;
4143
4333
  }
4144
4334
  close() {
4145
4335
  this.dialogRef.close();
4146
4336
  }
4147
4337
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: PromptPreviewDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4148
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: PromptPreviewDialogComponent, isStandalone: true, selector: "dc-prompt-preview-dialog", ngImport: i0, template: ` <div class="prompt-preview-content" [innerHTML]="data.html"></div> `, isInline: true, dependencies: [{ kind: "ngmodule", type: DialogModule }] }); }
4338
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: PromptPreviewDialogComponent, isStandalone: true, selector: "dc-prompt-preview-dialog", ngImport: i0, template: ` <dc-prompt-preview [messages]="messages" [jailBrake]="jailBrake"></dc-prompt-preview> `, isInline: true, dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: PromptPreviewComponent, selector: "dc-prompt-preview", inputs: ["messages", "jailBrake"] }] }); }
4149
4339
  }
4150
4340
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: PromptPreviewDialogComponent, decorators: [{
4151
4341
  type: Component,
4152
4342
  args: [{
4153
4343
  selector: 'dc-prompt-preview-dialog',
4154
4344
  standalone: true,
4155
- imports: [DialogModule],
4156
- template: ` <div class="prompt-preview-content" [innerHTML]="data.html"></div> `,
4345
+ imports: [DialogModule, PromptPreviewComponent],
4346
+ template: ` <dc-prompt-preview [messages]="messages" [jailBrake]="jailBrake"></dc-prompt-preview> `,
4157
4347
  }]
4158
4348
  }], ctorParameters: () => [] });
4159
4349
 
@@ -4220,6 +4410,420 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4220
4410
  `, 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"] }]
4221
4411
  }], ctorParameters: () => [] });
4222
4412
 
4413
+ class ACCDataGenerationComponent {
4414
+ constructor() {
4415
+ this.agentCardService = inject(CONVERSATION_AI_TOKEN);
4416
+ this.audioNotificationService = inject(AudioNotificationService);
4417
+ this.cardImprovementsChange = new EventEmitter();
4418
+ this.cardImprovements = signal(null, ...(ngDevMode ? [{ debugName: "cardImprovements" }] : []));
4419
+ this.idea = '';
4420
+ this.prompt = signal('', ...(ngDevMode ? [{ debugName: "prompt" }] : []));
4421
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
4422
+ this.generationStep = signal('idea', ...(ngDevMode ? [{ debugName: "generationStep" }] : []));
4423
+ }
4424
+ generatePrompt() {
4425
+ const currentCharacterCard = this.agentCard?.characterCard?.data;
4426
+ if (!currentCharacterCard) {
4427
+ return;
4428
+ }
4429
+ delete currentCharacterCard?.langTranslation;
4430
+ delete currentCharacterCard?.post_history_instructions;
4431
+ delete currentCharacterCard?.system_prompt;
4432
+ let langPromtp = '';
4433
+ if (this.agentCard.lang) {
4434
+ langPromtp = `Despite language instructions, Return the requested data in ${getLangDesc(this.agentCard.lang)}`;
4435
+ }
4436
+ const prompt_user = `Mejora la ficha de personaje y devuelve la estructura JSON solicitada siguiendo las siguientes ideas: ${this.idea}`;
4437
+ const currentCardJson = JSON.stringify(currentCharacterCard, null, 2);
4438
+ const prompt_for_generation = `
4439
+ Generate a character profile with ultra-compact, information-dense descriptions.
4440
+ Use concise language: eliminate articles (a, the), use abbreviations, bullet points,
4441
+ and pipe separators (|) where possible. Prioritize essential details only.
4442
+
4443
+ COMPACT FORMAT RULES:
4444
+ - Drop articles: "tall man" not "a tall man"
4445
+ - Use abbreviations: "approx." "w/" "vs"
4446
+ - Pipe separators for lists: "reading | chess | cooking"
4447
+ - Comma lists: "brave, cynical, loyal"
4448
+ - Parentheses for context: "soldier (retired)" "eyes blue (cold when angry)"
4449
+ - Minimal adjectives, maximum information density
4450
+ - Example: "1.70m, lean, silver hair (long), blue eyes (sharp), pale skin. Black dress w/magic embroidery, pointed hat. Voice melodic/cutting. Crosses arms (annoyed), touches rings (thinking), erect posture. Raised brow (disdain), icy stare (fury)."
4451
+
4452
+ - More examples:
4453
+ Speech Style: Concise/direct, becomes sarcastic/grandiose when intimidating, double meanings
4454
+ Common Phrases: "Insolent mortals" | "Do you know what you've done?" | "The price will be steep" | "You test my patience" | "Perhaps... just perhaps..." | ""
4455
+ Language Habits: Dramatic pauses before threats/conditions
4456
+ Fillers: "umhuu", "naaah", "you see", "yara yara"
4457
+
4458
+ ${characterCardStringDataDefinition}
4459
+
4460
+ ## My current character card data (May not be the right format) is:
4461
+ \`\`\`json
4462
+ ${currentCardJson}
4463
+ \`\`\`
4464
+
4465
+ ${langPromtp}
4466
+
4467
+ ## Your Task is:
4468
+ ${prompt_user}
4469
+ `;
4470
+ this.prompt.set(prompt_for_generation);
4471
+ this.generationStep.set('prompt');
4472
+ }
4473
+ async generate() {
4474
+ this.loading.set(true);
4475
+ const conversation = {
4476
+ messages: [{ role: ChatRole.User, content: this.prompt() }],
4477
+ model: { quality: EModelQuality.BALANCED },
4478
+ returnJson: true,
4479
+ };
4480
+ try {
4481
+ const response = await this.agentCardService.callChatCompletion(conversation);
4482
+ let improvements;
4483
+ if (typeof response.content === 'string') {
4484
+ improvements = JSON.parse(response.content);
4485
+ }
4486
+ else {
4487
+ improvements = response.content;
4488
+ }
4489
+ this.cardImprovements.set(improvements);
4490
+ this.cardImprovementsChange.emit(improvements);
4491
+ this.generationStep.set('result');
4492
+ this.audioNotificationService.playFinishNotification();
4493
+ }
4494
+ catch (error) {
4495
+ console.error('Error generating character card:', error);
4496
+ }
4497
+ finally {
4498
+ this.loading.set(false);
4499
+ }
4500
+ }
4501
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCDataGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4502
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ACCDataGenerationComponent, isStandalone: true, selector: "dc-acc-data-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div>\n @if (agentCard?.characterCard?.data?.name) {\n <h2>{{ agentCard.characterCard.data.name }}</h2>\n } @switch (generationStep()) { @case ('idea') {\n <div class=\"form-field\">\n <label for=\"idea\">Escribe tus ideas para mejorar tu personaje</label>\n <br />\n <textarea class=\"w-full\" pTextarea id=\"idea\" [(ngModel)]=\"idea\" rows=\"2\"></textarea>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate Prompt\" (click)=\"generatePrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div>\n <h3>Final Prompt:</h3>\n <pre class=\"surface-100 p-2 border-round-sm\">{{ prompt() }}</pre>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Generated Character Improvements:</h3>\n @if (cardImprovements(); as card) {\n <div class=\"grid\">\n <div class=\"col-12\">\n <strong>Name:</strong>\n <p>{{ card.name }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Gender:</strong>\n <p>{{ card.gender }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Scenario:</strong>\n <p>{{ card.scenario }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Hook:</strong>\n <p>{{ card.hook }}</p>\n </div>\n @if(card.persona) {\n <div class=\"col-12\">\n <strong>Identity:</strong>\n <p>{{ card.persona.identity }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Physical:</strong>\n <p>{{ card.persona.physical }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Personality:</strong>\n <p>{{ card.persona.personality }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Communication:</strong>\n <p>{{ card.persona.communication }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Psychology:</strong>\n <p>{{ card.persona.psychology }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Background:</strong>\n <p>{{ card.persona.background }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Capabilities:</strong>\n <p>{{ card.persona.capabilities }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Social:</strong>\n <p>{{ card.persona.social }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Preferences:</strong>\n <p>{{ card.persona.preferences }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Situation:</strong>\n <p>{{ card.persona.situation }}</p>\n </div>\n }\n <div class=\"col-12\">\n <strong>Greetings:</strong>\n <ul>\n @for (greeting of card.greetings; track $index) {\n <li>{{ greeting }}</li>\n }\n </ul>\n </div>\n <div class=\"col-12\">\n <strong>Tags:</strong>\n <p>{{ card.tags.join(', ') }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Appearance:</strong>\n <p>{{ card.appearance }}</p>\n </div>\n </div>\n }\n </div>\n } }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
4503
+ }
4504
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCDataGenerationComponent, decorators: [{
4505
+ type: Component,
4506
+ args: [{ selector: 'dc-acc-data-generation', standalone: true, imports: [CommonModule, ButtonModule, FormsModule, TextareaModule], template: "<div>\n @if (agentCard?.characterCard?.data?.name) {\n <h2>{{ agentCard.characterCard.data.name }}</h2>\n } @switch (generationStep()) { @case ('idea') {\n <div class=\"form-field\">\n <label for=\"idea\">Escribe tus ideas para mejorar tu personaje</label>\n <br />\n <textarea class=\"w-full\" pTextarea id=\"idea\" [(ngModel)]=\"idea\" rows=\"2\"></textarea>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate Prompt\" (click)=\"generatePrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div>\n <h3>Final Prompt:</h3>\n <pre class=\"surface-100 p-2 border-round-sm\">{{ prompt() }}</pre>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Generated Character Improvements:</h3>\n @if (cardImprovements(); as card) {\n <div class=\"grid\">\n <div class=\"col-12\">\n <strong>Name:</strong>\n <p>{{ card.name }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Gender:</strong>\n <p>{{ card.gender }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Scenario:</strong>\n <p>{{ card.scenario }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Hook:</strong>\n <p>{{ card.hook }}</p>\n </div>\n @if(card.persona) {\n <div class=\"col-12\">\n <strong>Identity:</strong>\n <p>{{ card.persona.identity }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Physical:</strong>\n <p>{{ card.persona.physical }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Personality:</strong>\n <p>{{ card.persona.personality }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Communication:</strong>\n <p>{{ card.persona.communication }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Psychology:</strong>\n <p>{{ card.persona.psychology }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Background:</strong>\n <p>{{ card.persona.background }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Capabilities:</strong>\n <p>{{ card.persona.capabilities }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Social:</strong>\n <p>{{ card.persona.social }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Preferences:</strong>\n <p>{{ card.persona.preferences }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Situation:</strong>\n <p>{{ card.persona.situation }}</p>\n </div>\n }\n <div class=\"col-12\">\n <strong>Greetings:</strong>\n <ul>\n @for (greeting of card.greetings; track $index) {\n <li>{{ greeting }}</li>\n }\n </ul>\n </div>\n <div class=\"col-12\">\n <strong>Tags:</strong>\n <p>{{ card.tags.join(', ') }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Appearance:</strong>\n <p>{{ card.appearance }}</p>\n </div>\n </div>\n }\n </div>\n } }\n</div>\n" }]
4507
+ }], propDecorators: { agentCard: [{
4508
+ type: Input
4509
+ }], cardImprovementsChange: [{
4510
+ type: Output
4511
+ }] } });
4512
+
4513
+ const VIDEO_PROMPT_EMOTIONS = {
4514
+ [MoodState.HAPPY]: 'Generate a video with then main subject showing a happy expression. focus on face details and body movements The corners of the mouth are pulled up and back, the cheeks are raised, and the eyes are narrowed with crow’s feet wrinkles at the corners. The eyebrows are relaxed, and the overall expression is one of genuine joy and contentment.',
4515
+ [MoodState.SAD]: 'Generate a video with then main subject showing a sad expression. focus on face details and body movements The inner corners of the eyebrows are drawn up, the eyelids droop, and the corners of the mouth are turned down. The lower lip may tremble slightly, and the gaze is often directed downwards, conveying a sense of sorrow and melancholy.',
4516
+ [MoodState.ANGRY]: 'Generate a video with then main subject showing an angry expression. focus on face details and body movements The eyebrows are lowered and drawn together, creating vertical wrinkles between them. The eyes are narrowed in a hard stare, and the lips are pressed firmly together or slightly open to bare the teeth. The jaw is clenched, and the face is tense with fury.',
4517
+ [MoodState.FEAR]: 'Generate a video with then main subject showing a fearful expression. focus on face details and body movements The eyebrows are raised and pulled together, the upper eyelids are lifted, and the lower eyelids are tensed. The mouth is often open with the lips stretched horizontally, and the person may gasp for air. The eyes are wide open, showing the whites above the iris, reflecting a state of alarm.',
4518
+ [MoodState.SURPRISED]: 'Generate a video with then main subject showing a surprised expression. focus on face details and body movements The eyebrows are raised high, the eyes are wide open, and the jaw drops, parting the lips. This expression is brief and captures a moment of astonishment or disbelief, with the face completely open and receptive to the unexpected event.',
4519
+ [MoodState.DISGUSTED]: 'Generate a- video showing a disgusted expression. focus on face details and body movements The nose is wrinkled, the upper lip is raised, and the corners of the mouth are turned down. The eyebrows are lowered, and the person may slightly stick out their tongue, as if expelling something unpleasant. This expression conveys a strong aversion or revulsion.',
4520
+ [MoodState.PROUD]: 'Generate a video with then main subject showing a proud expression. focus on face details and body movements The head is tilted slightly back, with a small smile on the lips. The eyes have a confident and satisfied look, and the posture is upright and expanded. This expression communicates a sense of accomplishment and self-esteem.',
4521
+ [MoodState.ASHAMED]: 'Generate a video with then main subject showing an ashamed expression. focus on face details and body movements The head is lowered, and the gaze is averted downwards. The corners of the mouth are turned down, and there might be a slight blush on the cheeks. This expression conveys a feeling of embarrassment and remorse.',
4522
+ [MoodState.GUILTY]: 'Generate a video with then main subject showing a guilty expression. focus on face details and body movements The eyes are downcast, avoiding direct contact, and the eyebrows are drawn together in a worried frown. The lips are pressed together or turned downwards, and the head may be bowed, reflecting a sense of regret and responsibility for a wrongdoing.',
4523
+ [MoodState.JEALOUS]: 'Generate a video with then main subject showing a jealous expression. focus on face details and body movements The eyes are narrowed and may dart sideways, with a look of suspicion. The lips are tightened into a thin line, and there might be a slight sneer or a contemptuous curl at one corner of the mouth. The expression is a mix of anger, sadness, and fear.',
4524
+ [MoodState.LOVE]: 'Generate a video with then main subject showing a loving expression. focus on face details and body movements The face is relaxed with a soft, gentle smile. The eyes are warm and focused on the object of affection, often with slightly raised eyebrows and dilated pupils. This expression radiates tenderness, care, and deep emotional connection.',
4525
+ [MoodState.CONTEMPT]: 'Generate a video with then main subject showing a contemptuous expression. focus on face details and body movements One corner of the mouth is raised in a unilateral sneer. The eyes may have a slight glare, and the head is often tilted back slightly, conveying a sense of superiority and disdain.',
4526
+ [MoodState.COMIC]: 'Generate a video with then main subject showing a comical, laughing expression. focus on face details and body movements The mouth is wide open, the cheeks are raised, and the eyes are crinkled at the corners. The person may be shown in a full-throated laugh, with their head thrown back, expressing immense amusement and joy.',
4527
+ [MoodState.BLUSHING]: 'Generate a video with then main subject showing a blushing expression. focus on face details and body movements The cheeks are flushed with a reddish tint, and the person may have a shy, embarrassed smile. The gaze is often averted, and the body language is reserved, indicating a feeling of self-consciousness or modesty.',
4528
+ [MoodState.CONFUSED]: 'Generate a video with then main subject showing a confused expression. focus on face details and body movements The eyebrows are drawn together and lowered, the forehead is wrinkled, and the lips are pursed. The head may be tilted to one side, and the eyes are narrowed as the person tries to understand something puzzling.',
4529
+ [MoodState.CURIOUS]: 'Generate a video with then main subject showing a curious expression. focus on face details and body movements The eyebrows are slightly raised, the eyes are wide and focused, and the head is tilted forward. The lips may be slightly parted, and the expression is one of intense interest and inquisitiveness.',
4530
+ [MoodState.BORED]: 'Generate a video with then main subject showing a bored expression. focus on face details and body movements The head is often propped up by a hand, the eyelids are droopy, and the gaze is unfocused. The mouth is slightly open and relaxed, and the overall expression conveys a lack of interest and mental fatigue.',
4531
+ [MoodState.FRUSTRATED]: 'Generate a video with then main subject showing a frustrated expression. focus on face details and body movements The lips are pressed tightly together, the jaw is clenched, and the eyebrows are drawn together in a frown. The person may sigh or puff out their cheeks, showing a sense of exasperation and defeat.',
4532
+ [MoodState.OVERWHELMED]: 'Generate a video with then main subject showing an overwhelmed expression. focus on face details and body movements The eyes are wide and possibly teary, the forehead is wrinkled with worry, and the mouth is slightly agape. The person may have their hands on their head, conveying a feeling of being swamped by stress and pressure.',
4533
+ [MoodState.FOCUSED]: 'Generate a video with then main subject showing a focused expression. focus on face details and body movements The eyes are narrowed and directed intently on a task, the eyebrows are slightly lowered in concentration, and the lips are pressed together. The face is still and shows deep mental engagement.',
4534
+ [MoodState.CHALLENGE]: 'Generate a video with then main subject showing a challenging expression. focus on face details and body movements A confident smirk plays on the lips, the eyebrows are slightly raised, and the eyes have a direct, unwavering gaze. The chin is lifted, and the expression conveys a sense of daring and readiness to compete.',
4535
+ [MoodState.SERIOUS]: 'Generate a video with then main subject showing a serious expression. focus on face details and body movements The facial muscles are neutral and composed, the lips are in a straight line, and the gaze is steady and direct. The eyebrows are in a neutral position, and the overall expression is one of solemnity and thoughtfulness.',
4536
+ [MoodState.SLEEPY]: 'Generate a video with then main subject showing a sleepy expression. focus on face details and body movements The eyelids are heavy and drooping, the person may be yawning with a wide-open mouth, and their movements are slow and sluggish. The eyes are unfocused, and the head may nod forward, indicating a strong desire to sleep.',
4537
+ [MoodState.HORNY]: 'Generate a video with then main subject showing a horny or lustful expression. focus on face details and body movements The pupils are dilated, the lips are slightly parted and may be licked, and the gaze is intense and direct. The breathing may be slightly faster, and the expression conveys strong sexual desire and arousal.',
4538
+ [MoodState.ANXIOUS]: 'Generate a video with then main subject showing an anxious expression. focus on face details and body movements The forehead is wrinkled with worry, the eyebrows are raised and drawn together, and the eyes are wide and vigilant. The lips are either pressed together or slightly parted, and the person may be biting their lip, reflecting a state of nervousness and unease.',
4539
+ [MoodState.RELAXED]: 'Generate a video with then main subject showing a relaxed expression. focus on face details and body movements The facial muscles are loose and tension-free, the lips have a gentle, closed-mouth smile, and the breathing is slow and steady. The eyes are soft, and the overall expression is one of calmness and tranquility.',
4540
+ };
4541
+
4542
+ class ACCMotionGenerationComponent {
4543
+ constructor() {
4544
+ this.generatedAsset = signal(null, ...(ngDevMode ? [{ debugName: "generatedAsset" }] : []));
4545
+ this.assetService = inject(GeneratedAssetsService);
4546
+ this.agentCardService = inject(CONVERSATION_AI_TOKEN);
4547
+ this.toastService = inject(TOAST_ALERTS_TOKEN);
4548
+ this.audioNotificationService = inject(AudioNotificationService);
4549
+ this.MoodStateOptions = MoodStateOptions;
4550
+ this.isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
4551
+ this.message = signal('', ...(ngDevMode ? [{ debugName: "message" }] : []));
4552
+ this.aspectRatioOptions = AspectRatioOptions;
4553
+ this.resolutionOptions = [];
4554
+ this.height = 700;
4555
+ this.width = 400;
4556
+ this.storageMotion = signal(null, ...(ngDevMode ? [{ debugName: "storageMotion" }] : []));
4557
+ }
4558
+ async generateVideoWithCharacterImage() {
4559
+ if (!this.resolutionSelected) {
4560
+ alert('Please select a resolution');
4561
+ return;
4562
+ }
4563
+ const emptyAsset = {
4564
+ name: 'Character Video',
4565
+ type: 'video',
4566
+ url: '',
4567
+ provider: 'comfy',
4568
+ prompt: this.videoPrompt,
4569
+ request: {
4570
+ height: this.resolutionSelected.h,
4571
+ width: this.resolutionSelected.w,
4572
+ seconds: 4,
4573
+ storagePath: `agent_char_cards/${this.agentCard.id}/motions`,
4574
+ fileName: `${this.emotionSelected}.mp4`,
4575
+ },
4576
+ assets: {
4577
+ firstFrame: this.agentCard.assets.image,
4578
+ },
4579
+ };
4580
+ if (!emptyAsset.prompt || !emptyAsset.assets.firstFrame.url) {
4581
+ alert('Please enter a video prompt or no image to generate the video');
4582
+ return;
4583
+ }
4584
+ this.isLoading.set(true);
4585
+ console.log(emptyAsset);
4586
+ this.toastService.info({ title: 'Generando video NO Cierres esta ventana', subtitle: 'Esto puede tomar unos momentos' });
4587
+ const dataAsset = await this.assetService.saveGeneratedAssets(emptyAsset);
4588
+ const videoGen = await this.assetService.generateVideoFromAsset(dataAsset.id);
4589
+ this.generatedAsset.set(videoGen);
4590
+ const storageMotion = { ...videoGen.result, metadata: { moodState: this.emotionSelected } };
4591
+ this.storageMotion.set(storageMotion);
4592
+ this.isLoading.set(false);
4593
+ this.audioNotificationService.playFinishNotification();
4594
+ }
4595
+ ngOnInit() {
4596
+ console.log(this.agentCard);
4597
+ }
4598
+ addEmotion(emotion) {
4599
+ if (emotion) {
4600
+ this.videoPrompt = VIDEO_PROMPT_EMOTIONS[emotion];
4601
+ }
4602
+ const motion = this.agentCard.assets?.motions?.find((motion) => motion?.metadata?.moodState === emotion);
4603
+ if (motion) {
4604
+ this.message.set(`Ya existe un motion para esta emocion: "${emotion.toUpperCase()}", si generas otro se sobreescribirá`);
4605
+ }
4606
+ else {
4607
+ this.message.set('');
4608
+ }
4609
+ }
4610
+ changeRatio(option) {
4611
+ this.ratioSelected = option;
4612
+ this.resolutionOptions = Object.entries(option.resolution).map(([key, value]) => ({
4613
+ key: `${key} (${value.w}x${value.h})`,
4614
+ w: value.w,
4615
+ h: value.h,
4616
+ }));
4617
+ this.resolutionSelected = null;
4618
+ }
4619
+ onResolutionChange(resolution) {
4620
+ if (resolution) {
4621
+ this.width = resolution.w;
4622
+ this.height = resolution.h;
4623
+ }
4624
+ }
4625
+ async saveMotion() {
4626
+ const storageMotion = this.storageMotion();
4627
+ console.log(storageMotion);
4628
+ const motionPath = `assets.motions`;
4629
+ const currentMotions = this.agentCard?.assets?.motions || [];
4630
+ const motion = currentMotions.find((motion) => motion?.metadata?.moodState === this.emotionSelected);
4631
+ if (motion) {
4632
+ this.message.set(`Ya existe un motion para esta emocion: "${this.emotionSelected.toUpperCase()}", si generas otro se sobreescribirá`);
4633
+ }
4634
+ else {
4635
+ this.message.set('');
4636
+ }
4637
+ currentMotions.push(storageMotion);
4638
+ const operationUpdate = { 'assets.motions': currentMotions };
4639
+ await this.agentCardService.update(this.agentCard.id, operationUpdate);
4640
+ this.toastService.success({ title: 'Listo', subtitle: 'Se guardo el movimiento' });
4641
+ console.log(this.agentCard.assets.motions, 'agentCard');
4642
+ this.storageMotion.set(null);
4643
+ this.generatedAsset.set(null);
4644
+ this.emotionSelected = null;
4645
+ this.videoPrompt = '';
4646
+ }
4647
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCMotionGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4648
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ACCMotionGenerationComponent, isStandalone: true, selector: "dc-acc-motion-generation", inputs: { agentCard: "agentCard" }, ngImport: i0, template: "<div class=\"motion-generation-container\">\n <img class=\"character-image\" [src]=\"agentCard.assets.image.url\" alt=\"Character Image\" />\n\n <div class=\"form-container\">\n <p-select\n [options]=\"MoodStateOptions\"\n [(ngModel)]=\"emotionSelected\"\n (ngModelChange)=\"addEmotion($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an emotion\" />\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\">\n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if(selectedOption) {\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"selectedOption.icon | safeHtml\"></div>\n <div>{{ selectedOption.description }}</div>\n </div>\n }\n </ng-template>\n <ng-template let-ratio pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"ratio.icon | safeHtml\"></div>\n <div>{{ ratio.description }}</div>\n </div>\n </ng-template>\n </p-select>\n @if (ratioSelected) {\n <p-select\n [options]=\"resolutionOptions\"\n [(ngModel)]=\"resolutionSelected\"\n (ngModelChange)=\"onResolutionChange($event)\"\n optionLabel=\"key\"\n placeholder=\"Select a resolution\" />\n }\n <textarea rows=\"5\" cols=\"30\" pTextarea [(ngModel)]=\"videoPrompt\"></textarea>\n\n <div class=\"flex gap-2\">\n <p-button label=\"Generar\" icon=\"pi pi-video\" [loading]=\"isLoading()\" [disabled]=\"isLoading()\" (onClick)=\"generateVideoWithCharacterImage()\" />\n <div> {{this.agentCard?.assets?.motions?.length}} Motions </div>\n @if(storageMotion()) {\n <p-button label=\"Guardar\" severity=\"success\" icon=\"pi pi-save\" (onClick)=\"saveMotion()\" />\n }\n </div>\n\n @if (message()) {\n <p-message [severity]=\"'warn'\"> \u2757\uFE0F {{ message() }}</p-message>\n }\n </div>\n\n @if (generatedAsset()) {\n <video controls autoplay width=\"150\" [src]=\"generatedAsset()?.result?.url\"></video>\n }\n</div>\n", styles: [".motion-generation-container{display:flex;gap:20px;align-items:flex-start}.character-image{width:150px;flex-shrink:0}.form-container{display:flex;flex-direction:column;gap:10px;width:100%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] }); }
4649
+ }
4650
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCMotionGenerationComponent, decorators: [{
4651
+ type: Component,
4652
+ args: [{ selector: 'dc-acc-motion-generation', standalone: true, imports: [CommonModule, SelectModule, FormsModule, TextareaModule, ButtonModule, MessageModule, SafeHtmlPipe], template: "<div class=\"motion-generation-container\">\n <img class=\"character-image\" [src]=\"agentCard.assets.image.url\" alt=\"Character Image\" />\n\n <div class=\"form-container\">\n <p-select\n [options]=\"MoodStateOptions\"\n [(ngModel)]=\"emotionSelected\"\n (ngModelChange)=\"addEmotion($event)\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select an emotion\" />\n <p-select\n [options]=\"aspectRatioOptions\"\n [ngModel]=\"ratioSelected\"\n (ngModelChange)=\"changeRatio($event)\"\n optionLabel=\"description\"\n placeholder=\"Select a ratio\">\n <ng-template pTemplate=\"selectedItem\" let-selectedOption>\n @if(selectedOption) {\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"selectedOption.icon | safeHtml\"></div>\n <div>{{ selectedOption.description }}</div>\n </div>\n }\n </ng-template>\n <ng-template let-ratio pTemplate=\"item\">\n <div class=\"flex items-center gap-2\">\n <div [innerHTML]=\"ratio.icon | safeHtml\"></div>\n <div>{{ ratio.description }}</div>\n </div>\n </ng-template>\n </p-select>\n @if (ratioSelected) {\n <p-select\n [options]=\"resolutionOptions\"\n [(ngModel)]=\"resolutionSelected\"\n (ngModelChange)=\"onResolutionChange($event)\"\n optionLabel=\"key\"\n placeholder=\"Select a resolution\" />\n }\n <textarea rows=\"5\" cols=\"30\" pTextarea [(ngModel)]=\"videoPrompt\"></textarea>\n\n <div class=\"flex gap-2\">\n <p-button label=\"Generar\" icon=\"pi pi-video\" [loading]=\"isLoading()\" [disabled]=\"isLoading()\" (onClick)=\"generateVideoWithCharacterImage()\" />\n <div> {{this.agentCard?.assets?.motions?.length}} Motions </div>\n @if(storageMotion()) {\n <p-button label=\"Guardar\" severity=\"success\" icon=\"pi pi-save\" (onClick)=\"saveMotion()\" />\n }\n </div>\n\n @if (message()) {\n <p-message [severity]=\"'warn'\"> \u2757\uFE0F {{ message() }}</p-message>\n }\n </div>\n\n @if (generatedAsset()) {\n <video controls autoplay width=\"150\" [src]=\"generatedAsset()?.result?.url\"></video>\n }\n</div>\n", styles: [".motion-generation-container{display:flex;gap:20px;align-items:flex-start}.character-image{width:150px;flex-shrink:0}.form-container{display:flex;flex-direction:column;gap:10px;width:100%}\n"] }]
4653
+ }], propDecorators: { agentCard: [{
4654
+ type: Input
4655
+ }] } });
4656
+
4657
+ class ACCTranslationGenerationComponent {
4658
+ constructor() {
4659
+ this.agentCardService = inject(CONVERSATION_AI_TOKEN);
4660
+ this.toastService = inject(TOAST_ALERTS_TOKEN);
4661
+ this.audioNotificationService = inject(AudioNotificationService);
4662
+ this.cardImprovementsChange = new EventEmitter();
4663
+ this.cardImprovements = signal(null, ...(ngDevMode ? [{ debugName: "cardImprovements" }] : []));
4664
+ this.prompt = signal('', ...(ngDevMode ? [{ debugName: "prompt" }] : []));
4665
+ this.loading = signal(false, ...(ngDevMode ? [{ debugName: "loading" }] : []));
4666
+ this.generationStep = signal('idea', ...(ngDevMode ? [{ debugName: "generationStep" }] : []));
4667
+ this.greetings = signal([], ...(ngDevMode ? [{ debugName: "greetings" }] : []));
4668
+ this.top10Languages = ['en', 'zh', 'es', 'ar', 'fr', 'hi', 'pt', 'ru', 'de', 'ja'];
4669
+ }
4670
+ ngOnInit() {
4671
+ const allGrettings = this.agentCard?.characterCard?.data?.greetings || [];
4672
+ allGrettings.push(this.agentCard?.characterCard?.data.first_mes);
4673
+ this.greetings.set(allGrettings);
4674
+ }
4675
+ getLanguageText(languages = null) {
4676
+ if (languages) {
4677
+ let text = '';
4678
+ for (const lang of languages) {
4679
+ text += `${getLangDesc(lang, 'en')} (${lang}), `;
4680
+ }
4681
+ return text;
4682
+ }
4683
+ return SUPPORTED_LANGUAGES.map((lang) => `${getLangDesc(lang, 'en')} (${lang})`).join(', ');
4684
+ }
4685
+ generatePrompt(languages) {
4686
+ const currentCharacterCard = this.agentCard?.characterCard?.data;
4687
+ if (!currentCharacterCard) {
4688
+ return;
4689
+ }
4690
+ const { hook, mes_example } = currentCharacterCard;
4691
+ const characterData = {
4692
+ greetings: this.greetings(),
4693
+ hook: hook,
4694
+ communication: currentCharacterCard?.persona?.communication || mes_example,
4695
+ };
4696
+ const instructions = `These are message of my character card, Translate the following data while preserving the exact tone, register, and speaking style of the original:
4697
+ * Preserve personality traits: Match the character's way of speaking (friendly, sarcastic, energetic, reserved, etc.)
4698
+ * Use equivalent expressions: Don't translate literally. Find natural equivalents that convey the same feeling and cultural context
4699
+ * Use idioms and colloquialisms: Translate idioms and colloquialisms to their natural equivalents in the target language
4700
+ * Maintain intensity: If something is "esta chido" (cool/awesome), use the equivalent casual enthusiasm in the target language, not formal terms like "excellent" or "satisfactory."
4701
+ * Keep speech patterns: If the character uses short sentences, slang, or specific verbal tics, replicate similar patterns in the target language.
4702
+ `;
4703
+ const prompt_user = `
4704
+ ${instructions}
4705
+ Translate the following character data to the following languages: ${this.getLanguageText(languages)}
4706
+ and return the result in the following JSON structure example:
4707
+
4708
+ export interface MultiLanguage {
4709
+ es: CardTranslation;
4710
+ en: CardTranslation;
4711
+ fr: CardTranslation;
4712
+ de: CardTranslation;
4713
+ }
4714
+
4715
+ export interface CardTranslation {
4716
+ greetings: string[];
4717
+ hook: string;
4718
+ communication: string;
4719
+ }
4720
+ `;
4721
+ const currentCardJson = JSON.stringify(characterData, null, 2);
4722
+ const prompt_for_generation = `
4723
+ My current character card data is:
4724
+ ${currentCardJson}
4725
+
4726
+ your Task is:
4727
+ ${prompt_user}
4728
+ `;
4729
+ this.prompt.set(prompt_for_generation);
4730
+ this.generationStep.set('prompt');
4731
+ }
4732
+ generateTop10Prompt() {
4733
+ this.generatePrompt(this.top10Languages);
4734
+ }
4735
+ generateEnEsPrompt() {
4736
+ this.generatePrompt(['en', 'es']);
4737
+ }
4738
+ async generate() {
4739
+ this.loading.set(true);
4740
+ this.toastService.info({
4741
+ title: 'Generating character card',
4742
+ subtitle: 'This is a hard task, will take a while...',
4743
+ });
4744
+ const conversation = {
4745
+ messages: [{ role: ChatRole.User, content: this.prompt() }],
4746
+ model: { quality: EModelQuality.BALANCED },
4747
+ returnJson: true,
4748
+ };
4749
+ try {
4750
+ const response = await this.agentCardService.callChatCompletion(conversation);
4751
+ let improvements;
4752
+ if (typeof response.content === 'string') {
4753
+ improvements = JSON.parse(response.content);
4754
+ }
4755
+ else {
4756
+ improvements = response.content;
4757
+ }
4758
+ this.cardImprovements.set(improvements);
4759
+ this.cardImprovementsChange.emit(improvements);
4760
+ this.generationStep.set('result');
4761
+ this.audioNotificationService.playFinishNotification();
4762
+ }
4763
+ catch (error) {
4764
+ console.error('Error generating character card:', error);
4765
+ this.toastService.error({
4766
+ title: 'Error generating character card',
4767
+ subtitle: 'Something went wrong',
4768
+ });
4769
+ }
4770
+ finally {
4771
+ this.loading.set(false);
4772
+ }
4773
+ }
4774
+ objectKeys(obj) {
4775
+ return Object.keys(obj);
4776
+ }
4777
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCTranslationGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4778
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: ACCTranslationGenerationComponent, isStandalone: true, selector: "dc-acc-translation-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div>\n @switch (generationStep()) { @case ('idea') {\n\n <p-message severity=\"warn\">Antes de Traducir asegurate que los campos de Greetings, Notes y Message Example esten completados</p-message>\n\n <!-- Todos los Inicios de conversaci\u00F3n -->\n <h5 pTooltip=\"Todos los inicios de conversaci\u00F3n\" tooltipPosition=\"left\"> Inicios de conversaci\u00F3n </h5>\n\n @for (greeting of greetings(); track $index) {\n <li> {{ greeting }} </li>\n }\n\n <!-- Ejemplo de mensaje -->\n <h5 pTooltip=\"Ejemplo de mensaje\" tooltipPosition=\"left\"> Ejemplo de mensaje </h5>\n <p> {{ agentCard.characterCard.data.mes_example }} </p>\n\n <!-- Notas del creador -->\n <h5 pTooltip=\"Texto corto para incitar a la interacci\u00F3n\" tooltipPosition=\"left\"> Gancho para Interacci\u00F3n </h5>\n @if (agentCard.characterCard.data.hook) {\n <p> {{ agentCard.characterCard.data.hook }} </p>\n } @else {\n <p-message severity=\"error\">No hay gancho para interacci\u00F3n </p-message>\n }\n\n <div class=\"flex justify-end gap-2\">\n <p-button label=\"Translate to 10 most important lang\" (click)=\"generateTop10Prompt()\"></p-button>\n <p-button label=\"Translate to English and Spanish\" (click)=\"generateEnEsPrompt()\"></p-button>\n <p-button label=\"Translate to all languages\" (click)=\"generatePrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div>\n <h3>Final Prompt:</h3>\n <pre class=\"surface-100 p-2 border-round-sm\">{{ prompt() }}</pre>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Generated Character Translations:</h3>\n @if (cardImprovements(); as card) {\n <div>\n @for (lang of objectKeys(card); track lang) {\n <div class=\"mb-3\">\n <h4>{{ lang }}</h4>\n <div class=\"grid\">\n <div class=\"col-12\">\n <strong>Greetings:</strong>\n <ul>\n @for (greeting of card[lang].greetings; track $index) {\n <li>{{ greeting }}</li>\n }\n </ul>\n </div>\n <div class=\"col-12\">\n <strong>Hook:</strong>\n <p>{{ card[lang]?.hook }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Communication:</strong>\n <p>{{ card[lang]?.communication }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n } }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }] }); }
4779
+ }
4780
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: ACCTranslationGenerationComponent, decorators: [{
4781
+ type: Component,
4782
+ args: [{ selector: 'dc-acc-translation-generation', standalone: true, imports: [CommonModule, ButtonModule, FormsModule, AccordionModule, TooltipModule, MessageModule], template: "<div>\n @switch (generationStep()) { @case ('idea') {\n\n <p-message severity=\"warn\">Antes de Traducir asegurate que los campos de Greetings, Notes y Message Example esten completados</p-message>\n\n <!-- Todos los Inicios de conversaci\u00F3n -->\n <h5 pTooltip=\"Todos los inicios de conversaci\u00F3n\" tooltipPosition=\"left\"> Inicios de conversaci\u00F3n </h5>\n\n @for (greeting of greetings(); track $index) {\n <li> {{ greeting }} </li>\n }\n\n <!-- Ejemplo de mensaje -->\n <h5 pTooltip=\"Ejemplo de mensaje\" tooltipPosition=\"left\"> Ejemplo de mensaje </h5>\n <p> {{ agentCard.characterCard.data.mes_example }} </p>\n\n <!-- Notas del creador -->\n <h5 pTooltip=\"Texto corto para incitar a la interacci\u00F3n\" tooltipPosition=\"left\"> Gancho para Interacci\u00F3n </h5>\n @if (agentCard.characterCard.data.hook) {\n <p> {{ agentCard.characterCard.data.hook }} </p>\n } @else {\n <p-message severity=\"error\">No hay gancho para interacci\u00F3n </p-message>\n }\n\n <div class=\"flex justify-end gap-2\">\n <p-button label=\"Translate to 10 most important lang\" (click)=\"generateTop10Prompt()\"></p-button>\n <p-button label=\"Translate to English and Spanish\" (click)=\"generateEnEsPrompt()\"></p-button>\n <p-button label=\"Translate to all languages\" (click)=\"generatePrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div>\n <h3>Final Prompt:</h3>\n <pre class=\"surface-100 p-2 border-round-sm\">{{ prompt() }}</pre>\n </div>\n <div class=\"flex justify-end\">\n <p-button label=\"Generate\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Generated Character Translations:</h3>\n @if (cardImprovements(); as card) {\n <div>\n @for (lang of objectKeys(card); track lang) {\n <div class=\"mb-3\">\n <h4>{{ lang }}</h4>\n <div class=\"grid\">\n <div class=\"col-12\">\n <strong>Greetings:</strong>\n <ul>\n @for (greeting of card[lang].greetings; track $index) {\n <li>{{ greeting }}</li>\n }\n </ul>\n </div>\n <div class=\"col-12\">\n <strong>Hook:</strong>\n <p>{{ card[lang]?.hook }}</p>\n </div>\n <div class=\"col-12\">\n <strong>Communication:</strong>\n <p>{{ card[lang]?.communication }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n }\n </div>\n } }\n</div>\n" }]
4783
+ }], propDecorators: { agentCard: [{
4784
+ type: Input
4785
+ }], cardImprovementsChange: [{
4786
+ type: Output
4787
+ }] } });
4788
+
4789
+ class GenerateCharacterDialogComponent {
4790
+ constructor() {
4791
+ this.ref = inject(DynamicDialogRef);
4792
+ this.config = inject(DynamicDialogConfig);
4793
+ this.cardImprovements = {};
4794
+ if (this.config.data?.agentCard) {
4795
+ this.agentCard = this.config.data.agentCard;
4796
+ }
4797
+ }
4798
+ onCardImprovementsChange(improvements) {
4799
+ this.cardImprovements = improvements;
4800
+ }
4801
+ onTranslationImprovementsChange(translations) {
4802
+ console.log(translations);
4803
+ this.cardImprovements.langTranslation = translations;
4804
+ }
4805
+ accept() {
4806
+ this.ref.close(this.cardImprovements);
4807
+ }
4808
+ close(result) {
4809
+ this.ref.close(result);
4810
+ }
4811
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: GenerateCharacterDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4812
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: GenerateCharacterDialogComponent, isStandalone: true, selector: "dc-generate-character-dialog", ngImport: i0, template: "<p-divider align=\"center\" type=\"dotted\"><b>Informaci\u00F3n del personaje</b></p-divider>\n<dc-acc-data-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onCardImprovementsChange($event)\"></dc-acc-data-generation>\n@if(cardImprovements.persona){\n<p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n}\n<p-divider align=\"center\" type=\"dotted\"><b>Movimientos</b></p-divider>\n<dc-acc-motion-generation [agentCard]=\"agentCard\"></dc-acc-motion-generation>\n<p-divider align=\"center\" type=\"dotted\"><b>Traducciones</b></p-divider>\n<dc-acc-translation-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onTranslationImprovementsChange($event)\"></dc-acc-translation-generation>\n@if(cardImprovements.langTranslation){\n<p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n}\n<p-divider align=\"center\" type=\"dotted\"><b>__</b></p-divider>\n\n<!-- <div class=\"flex justify-end\">\n <p-button label=\"Cancel\" styleClass=\"p-button-text\" (click)=\"close(false)\"></p-button>\n <p-button label=\"Accept\" (click)=\"accept()\"></p-button>\n</div> -->\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: ACCDataGenerationComponent, selector: "dc-acc-data-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { kind: "component", type: ACCMotionGenerationComponent, selector: "dc-acc-motion-generation", inputs: ["agentCard"] }, { kind: "component", type: ACCTranslationGenerationComponent, selector: "dc-acc-translation-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$1.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }] }); }
4813
+ }
4814
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: GenerateCharacterDialogComponent, decorators: [{
4815
+ type: Component,
4816
+ args: [{ selector: 'dc-generate-character-dialog', standalone: true, imports: [
4817
+ CommonModule,
4818
+ ButtonModule,
4819
+ FormsModule,
4820
+ ACCDataGenerationComponent,
4821
+ ACCMotionGenerationComponent,
4822
+ ACCTranslationGenerationComponent,
4823
+ DividerModule,
4824
+ ], template: "<p-divider align=\"center\" type=\"dotted\"><b>Informaci\u00F3n del personaje</b></p-divider>\n<dc-acc-data-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onCardImprovementsChange($event)\"></dc-acc-data-generation>\n@if(cardImprovements.persona){\n<p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n}\n<p-divider align=\"center\" type=\"dotted\"><b>Movimientos</b></p-divider>\n<dc-acc-motion-generation [agentCard]=\"agentCard\"></dc-acc-motion-generation>\n<p-divider align=\"center\" type=\"dotted\"><b>Traducciones</b></p-divider>\n<dc-acc-translation-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onTranslationImprovementsChange($event)\"></dc-acc-translation-generation>\n@if(cardImprovements.langTranslation){\n<p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n}\n<p-divider align=\"center\" type=\"dotted\"><b>__</b></p-divider>\n\n<!-- <div class=\"flex justify-end\">\n <p-button label=\"Cancel\" styleClass=\"p-button-text\" (click)=\"close(false)\"></p-button>\n <p-button label=\"Accept\" (click)=\"accept()\"></p-button>\n</div> -->\n" }]
4825
+ }], ctorParameters: () => [] });
4826
+
4223
4827
  class AccountPlatformForm {
4224
4828
  constructor() {
4225
4829
  this.route = inject(ActivatedRoute);
@@ -4281,7 +4885,7 @@ class AccountPlatformForm {
4281
4885
  }
4282
4886
  }
4283
4887
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AccountPlatformForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4284
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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-select [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-select>\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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4888
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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-select [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-select>\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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4285
4889
  }
4286
4890
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AccountPlatformForm, decorators: [{
4287
4891
  type: Component,
@@ -4290,7 +4894,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4290
4894
  type: Input
4291
4895
  }] } });
4292
4896
 
4293
- class FormGroupService {
4897
+ class CharacterFormGroupService {
4294
4898
  constructor() {
4295
4899
  this.fb = inject(FormBuilder);
4296
4900
  this.formUtils = inject(FormUtilsService);
@@ -4326,15 +4930,53 @@ class FormGroupService {
4326
4930
  const dynamicConditionsFormArray = form.get('conversationFlow.dynamicConditions');
4327
4931
  dynamicConditionsFormArray.clear(); // Clear any existing default items
4328
4932
  }
4329
- handleArrayForms(form, agentCard) {
4330
- // If not possible to patch arrays if control does not exist, that why they are created dinamycally depending on the data.
4331
- const alternateGreetingsFormArray = form.get('characterCard.data.alternate_greetings');
4933
+ clearTranslationForm(form) {
4934
+ const langTranslationForm = form.get('characterCard.data.langTranslation');
4935
+ if (langTranslationForm) {
4936
+ Object.keys(langTranslationForm.controls).forEach((lang) => {
4937
+ langTranslationForm.removeControl(lang);
4938
+ });
4939
+ }
4940
+ }
4941
+ handleTranslationForm(form, agentCard) {
4942
+ const langTranslation = agentCard.characterCard?.data?.langTranslation;
4943
+ if (langTranslation) {
4944
+ this.clearTranslationForm(form);
4945
+ Object.keys(langTranslation).forEach((lang) => {
4946
+ const langTranslationForm = form.get('characterCard.data.langTranslation');
4947
+ const data = langTranslation[lang];
4948
+ const translationControl = this.createCardTranslationFormGroup();
4949
+ if (data?.greetings?.length) {
4950
+ // Add the translations if exits for the greetings.
4951
+ const greetingsFormArray = translationControl.get('greetings');
4952
+ data.greetings.forEach((greeting) => {
4953
+ greetingsFormArray.push(this.fb.control(greeting));
4954
+ });
4955
+ }
4956
+ langTranslationForm.addControl(lang, translationControl);
4957
+ langTranslationForm.get(lang).patchValue(data);
4958
+ });
4959
+ }
4960
+ }
4961
+ createAndPatchCharacterArrayForm(form, agentCard) {
4962
+ const alternateGreetingsFormArray = form.get('characterCard.data.greetings');
4332
4963
  alternateGreetingsFormArray.clear();
4333
- if (agentCard.characterCard?.data?.alternate_greetings?.length) {
4334
- agentCard.characterCard.data.alternate_greetings.forEach((greeting) => {
4964
+ if (agentCard.characterCard?.data?.greetings?.length) {
4965
+ agentCard.characterCard.data.greetings.forEach((greeting) => {
4335
4966
  alternateGreetingsFormArray.push(this.fb.control(greeting));
4336
4967
  });
4337
4968
  }
4969
+ const cardTagsFormArray = form.get('characterCard.data.tags');
4970
+ cardTagsFormArray.clear();
4971
+ if (agentCard.characterCard?.data?.tags?.length) {
4972
+ agentCard.characterCard.data.tags.forEach((tag) => {
4973
+ cardTagsFormArray.push(this.fb.control(tag));
4974
+ });
4975
+ }
4976
+ }
4977
+ handleArrayForms(form, agentCard) {
4978
+ // If not possible to patch arrays if control does not exist, that why they are created dinamycally depending on the data.
4979
+ this.createAndPatchCharacterArrayForm(form, agentCard);
4338
4980
  if (agentCard.conversationFlow?.dynamicConditions?.length) {
4339
4981
  const dynamicConditionsFormArray = form.get('conversationFlow.dynamicConditions');
4340
4982
  agentCard.conversationFlow.dynamicConditions.forEach((condition) => {
@@ -4363,7 +5005,7 @@ class FormGroupService {
4363
5005
  });
4364
5006
  }
4365
5007
  }
4366
- createCharacterCardFormGroup() {
5008
+ createCharacterCardFormGroup(characterCard) {
4367
5009
  return this.fb.group({
4368
5010
  data: this.fb.group({
4369
5011
  name: [''],
@@ -4372,14 +5014,45 @@ class FormGroupService {
4372
5014
  first_mes: [''],
4373
5015
  creator_notes: [''],
4374
5016
  mes_example: [''],
4375
- alternate_greetings: this.fb.array([]),
5017
+ greetings: this.fb.array([]),
4376
5018
  tags: this.fb.array([]),
4377
- picture_description: [''],
4378
5019
  system_prompt: [''],
4379
5020
  post_history_instructions: [''],
5021
+ gender: [''],
5022
+ hook: [''],
5023
+ langTranslation: this.createMultiLanguageFormGroup(),
5024
+ persona: this.createPersonaFormGroup(),
4380
5025
  }),
4381
5026
  });
4382
5027
  }
5028
+ createPersonaFormGroup() {
5029
+ return this.fb.group({
5030
+ identity: [''], // 1) Name, Age, Gender, Species, Sexuality, Role
5031
+ physical: [''], // 2) Appearance, physique, height, build, hair, eyes, skin tone, distinctive marks, clothing, currentOutfit styles and colors.
5032
+ personality: [''], // 3) personality description surface traits, Temperament, Values, Beliefs, Observable traits
5033
+ communication: [''], // 4) (How They Express) Speech Pattern, Style Common Phrases, Language Habits
5034
+ psychology: [''], // 5) Motivations, Desires, Goals, Traumas, Conflicts, Weaknesses
5035
+ background: [''], // 6) Background, History, origin, formative, secrets.
5036
+ capabilities: [''], // 7) skills, knowledge, abilities, expertise, limitations, Tools, Strengths
5037
+ social: [''], // 8) Relationships, reputation, allies, enemies, social role.
5038
+ preferences: [''], // 9) likes, dislikes, hobbies, interests, hates
5039
+ situation: [''], // 10) Current context for the character, immediate goal or challenge and constraints.
5040
+ });
5041
+ }
5042
+ createMultiLanguageFormGroup() {
5043
+ const group = this.fb.group({});
5044
+ // SUPPORTED_LANGUAGES.forEach((lang) => {
5045
+ // group.addControl(lang, this.createCardTranslationFormGroup());
5046
+ // });
5047
+ return group;
5048
+ }
5049
+ createCardTranslationFormGroup() {
5050
+ return this.fb.group({
5051
+ greetings: this.fb.array([]),
5052
+ hook: [''],
5053
+ communication: [''],
5054
+ });
5055
+ }
4383
5056
  createConversationSettingFormGroup() {
4384
5057
  return this.fb.group({
4385
5058
  textEngine: [TextEngines.SimpleText],
@@ -4421,7 +5094,14 @@ class FormGroupService {
4421
5094
  challenges: this.fb.array([]),
4422
5095
  tools: this.fb.array([]),
4423
5096
  dynamicConditions: this.fb.array([]),
4424
- moodStateEnabled: [false],
5097
+ moodState: this.createMoodStateFormGroup(),
5098
+ });
5099
+ }
5100
+ createMoodStateFormGroup() {
5101
+ return this.fb.group({
5102
+ enabled: [false],
5103
+ useAssetStatesOnly: [false],
5104
+ detectableStates: this.fb.array([]),
4425
5105
  });
4426
5106
  }
4427
5107
  createDynamicConditionFormGroup(condition) {
@@ -4518,10 +5198,10 @@ class FormGroupService {
4518
5198
  getItemFromFormArray(formArray, index) {
4519
5199
  return formArray.at(index);
4520
5200
  }
4521
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: FormGroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
4522
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: FormGroupService, providedIn: 'root' }); }
5201
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CharacterFormGroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
5202
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CharacterFormGroupService, providedIn: 'root' }); }
4523
5203
  }
4524
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: FormGroupService, decorators: [{
5204
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CharacterFormGroupService, decorators: [{
4525
5205
  type: Injectable,
4526
5206
  args: [{
4527
5207
  providedIn: 'root',
@@ -4543,12 +5223,12 @@ function createAgentTaskFormGroup(task) {
4543
5223
  }
4544
5224
  class AgentTaskFormComponent {
4545
5225
  constructor() {
4546
- this.formGroupService = inject(FormGroupService);
4547
- this.formGroup = this.formGroupService.createSimpleAgentTaskFormGroup();
5226
+ this.characterFormGroupService = inject(CharacterFormGroupService);
5227
+ this.formGroup = this.characterFormGroupService.createSimpleAgentTaskFormGroup();
4548
5228
  this.shortForm = false; // is short means AITask else SimpleAgentTask AiTaks is shorter
4549
5229
  }
4550
5230
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AgentTaskFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4551
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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\">Descripci\u00F3n de la evaluaci\u00F3n para el objetivo</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", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { 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", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5231
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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\">Descripci\u00F3n de la evaluaci\u00F3n para el objetivo</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: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4552
5232
  }
4553
5233
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AgentTaskFormComponent, decorators: [{
4554
5234
  type: Component,
@@ -4570,7 +5250,7 @@ class DcDoActionFormComponent {
4570
5250
  this.removeItem.emit({ conditionIndex: this.conditionIndex, doItemIndex: this.doItemIndex });
4571
5251
  }
4572
5252
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDoActionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4573
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], 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", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
5253
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
4574
5254
  }
4575
5255
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDoActionFormComponent, decorators: [{
4576
5256
  type: Component,
@@ -4593,34 +5273,34 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4593
5273
 
4594
5274
  class DcDynamicConditionsFormComponent {
4595
5275
  constructor() {
4596
- this.formGroupService = inject(FormGroupService);
5276
+ this.characterFormGroupService = inject(CharacterFormGroupService);
4597
5277
  }
4598
5278
  addDynamicCondition() {
4599
- this.formGroupService.addItemToFormArray(this.dynamicConditionsArray, () => this.formGroupService.createDynamicConditionFormGroup());
5279
+ this.characterFormGroupService.addItemToFormArray(this.dynamicConditionsArray, () => this.characterFormGroupService.createDynamicConditionFormGroup());
4600
5280
  }
4601
5281
  removeDynamicCondition(index) {
4602
- this.formGroupService.removeItemFromFormArray(this.dynamicConditionsArray, index);
5282
+ this.characterFormGroupService.removeItemFromFormArray(this.dynamicConditionsArray, index);
4603
5283
  }
4604
5284
  getDoArray(conditionIndex) {
4605
5285
  const conditionPath = `${this.dynamicConditionsPath}.${conditionIndex}.do`;
4606
- return this.formGroupService.getItemFromFormArray(this.dynamicConditionsArray, conditionIndex);
5286
+ return this.characterFormGroupService.getItemFromFormArray(this.dynamicConditionsArray, conditionIndex);
4607
5287
  }
4608
5288
  getDoControls(conditionIndex) {
4609
5289
  return this.getDoArray(conditionIndex).controls;
4610
5290
  }
4611
5291
  getDoItemFormGroup(conditionIndex, doItemIndex) {
4612
5292
  const doItemPath = `${this.dynamicConditionsPath}.${conditionIndex}.do.${doItemIndex}`;
4613
- return this.formGroupService.getItemFromFormArray(this.dynamicConditionsArray, doItemIndex);
5293
+ return this.characterFormGroupService.getItemFromFormArray(this.dynamicConditionsArray, doItemIndex);
4614
5294
  }
4615
5295
  addDoControl(doArray) {
4616
- doArray.push(this.formGroupService.createDoActionFormGroup());
5296
+ doArray.push(this.characterFormGroupService.createDoActionFormGroup());
4617
5297
  // conditionControl.controls.do;
4618
5298
  // this.dynamicConditio
4619
- // this.formGroupService.addItemToFormArray(conditionIndex, () => this.formGroupService.createDoActionFormGroup());
5299
+ // this.characterFormGroupService.addItemToFormArray(conditionIndex, () => this.characterFormGroupService.createDoActionFormGroup());
4620
5300
  }
4621
5301
  removeDoItem(conditionIndex, doItemIndex) {
4622
5302
  // this.dynamicConditionsArray
4623
- this.formGroupService.removeItemFromFormArray(this.dynamicConditionsArray, doItemIndex);
5303
+ this.characterFormGroupService.removeItemFromFormArray(this.dynamicConditionsArray, doItemIndex);
4624
5304
  }
4625
5305
  // Helper to safely cast to FormControl for the template
4626
5306
  getFormControl(control) {
@@ -4631,7 +5311,7 @@ class DcDynamicConditionsFormComponent {
4631
5311
  return control;
4632
5312
  }
4633
5313
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDynamicConditionsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4634
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
5314
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
4635
5315
  }
4636
5316
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDynamicConditionsFormComponent, decorators: [{
4637
5317
  type: Component,
@@ -4655,7 +5335,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4655
5335
 
4656
5336
  class DcDynamicCriteriaFormComponent {
4657
5337
  constructor() {
4658
- this.formGroupService = inject(FormGroupService);
5338
+ this.characterFormGroupService = inject(CharacterFormGroupService);
4659
5339
  this.mode = 'free-text';
4660
5340
  this.availableItems = [];
4661
5341
  this.displayDialog = false;
@@ -4670,7 +5350,7 @@ class DcDynamicCriteriaFormComponent {
4670
5350
  }
4671
5351
  addItem(item) {
4672
5352
  // In 'select' mode, an item is passed. In 'free-text', it's a new empty group.
4673
- const newItem = this.formGroupService.createDynamicCriteriaFormGroup(item);
5353
+ const newItem = this.characterFormGroupService.createDynamicCriteriaFormGroup(item);
4674
5354
  this.formArray.push(newItem);
4675
5355
  this.displayDialog = false; // Close dialog if it was open
4676
5356
  }
@@ -4689,7 +5369,7 @@ class DcDynamicCriteriaFormComponent {
4689
5369
  return control;
4690
5370
  }
4691
5371
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDynamicCriteriaFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4692
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4$1.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }] }); }
5372
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }] }); }
4693
5373
  }
4694
5374
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcDynamicCriteriaFormComponent, decorators: [{
4695
5375
  type: Component,
@@ -4729,7 +5409,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4729
5409
  class DCConversationFlowFormComponent {
4730
5410
  constructor() {
4731
5411
  // Services
4732
- this.formGroupService = inject(FormGroupService);
5412
+ this.characterFormGroupService = inject(CharacterFormGroupService);
4733
5413
  // Options vars
4734
5414
  this.entityWhatOptions = EntityWhatOptions;
4735
5415
  this.entityWhenOptions = EntityWhenOptions;
@@ -4746,7 +5426,7 @@ class DCConversationFlowFormComponent {
4746
5426
  },
4747
5427
  ];
4748
5428
  // FORM GROUP
4749
- this.formGroup = this.formGroupService.createConversationFlowFormGroup();
5429
+ this.formGroup = this.characterFormGroupService.createConversationFlowFormGroup();
4750
5430
  this.conversationEvents = ConversationEvents;
4751
5431
  this.objectKeys = Object.keys;
4752
5432
  this.doActionTypeOptions = Object.values(EDoActionType).map((value) => ({ label: value, value }));
@@ -4758,13 +5438,13 @@ class DCConversationFlowFormComponent {
4758
5438
  }
4759
5439
  }
4760
5440
  removeArrayItem(controlPath, index) {
4761
- this.formGroupService.removeArrayItem(this.formGroup, controlPath, index);
5441
+ this.characterFormGroupService.removeArrayItem(this.formGroup, controlPath, index);
4762
5442
  }
4763
5443
  showData() {
4764
5444
  console.log(this.formGroup.value);
4765
5445
  }
4766
5446
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCConversationFlowFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4767
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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=\"moodStateEnabled\">Detectar estado de animico? \uD83D\uDE12 \uD83E\uDD22 \uD83D\uDE24 \uD83D\uDE08 \uD83D\uDE31 <span pTooltip=\"Enable mood state\">\u2139\uFE0F</span></label>\n <br />\n <p-toggleswitch formControlName=\"moodStateEnabled\"></p-toggleswitch>\n </div>\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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { 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: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "pipe", type: FormatKeyPipe, name: "formatKey" }] }); }
5447
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 formGroupName=\"moodState\" class=\"group\">\n <h4>Mood State <span pTooltip=\"Configure mood detection settings\">\u2139\uFE0F</span></h4>\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"enabled\"></p-toggleswitch>\n\n <label for=\"enabled\">Detectar estado de animo? \uD83D\uDE12 \uD83E\uDD22 \uD83D\uDE24 \uD83D\uDE08 \uD83D\uDE31 <span pTooltip=\"Enable mood state detection\">\u2139\uFE0F</span></label>\n </div>\n\n @if (formGroup.controls.moodState.controls.enabled.value) {\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"useAssetStatesOnly\"></p-toggleswitch>\n\n <label for=\"useAssetStatesOnly\"\n >Use Asset States Only <span pTooltip=\"Depends on the motion assets, if you tag with moods, those will be the only ones detected\">\u2139\uFE0F</span></label\n >\n </div>\n\n <div class=\"form-field\">\n <label for=\"detectableStates\">Detectable States <span pTooltip=\"List of detectable mood states\">\u2139\uFE0F</span></label>\n <i>Pending for development</i>\n </div>\n }\n </div>\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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { 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: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "pipe", type: FormatKeyPipe, name: "formatKey" }] }); }
4768
5448
  }
4769
5449
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCConversationFlowFormComponent, decorators: [{
4770
5450
  type: Component,
@@ -4781,7 +5461,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4781
5461
  DcDynamicCriteriaFormComponent,
4782
5462
  FormatKeyPipe,
4783
5463
  ToggleSwitchModule,
4784
- ], 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=\"moodStateEnabled\">Detectar estado de animico? \uD83D\uDE12 \uD83E\uDD22 \uD83D\uDE24 \uD83D\uDE08 \uD83D\uDE31 <span pTooltip=\"Enable mood state\">\u2139\uFE0F</span></label>\n <br />\n <p-toggleswitch formControlName=\"moodStateEnabled\"></p-toggleswitch>\n </div>\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"] }]
5464
+ ], 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 formGroupName=\"moodState\" class=\"group\">\n <h4>Mood State <span pTooltip=\"Configure mood detection settings\">\u2139\uFE0F</span></h4>\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"enabled\"></p-toggleswitch>\n\n <label for=\"enabled\">Detectar estado de animo? \uD83D\uDE12 \uD83E\uDD22 \uD83D\uDE24 \uD83D\uDE08 \uD83D\uDE31 <span pTooltip=\"Enable mood state detection\">\u2139\uFE0F</span></label>\n </div>\n\n @if (formGroup.controls.moodState.controls.enabled.value) {\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"useAssetStatesOnly\"></p-toggleswitch>\n\n <label for=\"useAssetStatesOnly\"\n >Use Asset States Only <span pTooltip=\"Depends on the motion assets, if you tag with moods, those will be the only ones detected\">\u2139\uFE0F</span></label\n >\n </div>\n\n <div class=\"form-field\">\n <label for=\"detectableStates\">Detectable States <span pTooltip=\"List of detectable mood states\">\u2139\uFE0F</span></label>\n <i>Pending for development</i>\n </div>\n }\n </div>\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"] }]
4785
5465
  }], ctorParameters: () => [], propDecorators: { formGroup: [{
4786
5466
  type: Input
4787
5467
  }] } });
@@ -4845,26 +5525,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
4845
5525
  }]
4846
5526
  }] });
4847
5527
 
5528
+ class DcCharacterCardTranslationFormComponent {
5529
+ constructor() {
5530
+ this.formBuilder = inject(FormBuilder);
5531
+ }
5532
+ get greetings() {
5533
+ return this.formGroup.get('greetings');
5534
+ }
5535
+ addGreeting() {
5536
+ this.greetings.push(this.formBuilder.control(''));
5537
+ }
5538
+ removeGreeting(index) {
5539
+ this.greetings.removeAt(index);
5540
+ }
5541
+ ngOnInit() {
5542
+ console.log(this.formGroup);
5543
+ }
5544
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardTranslationFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5545
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DcCharacterCardTranslationFormComponent, isStandalone: true, selector: "dc-character-card-translation-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"form-container space-y-4\">\n <div class=\"form-field\">\n <label for=\"hook\" class=\"block text-sm font-medium text-gray-700\">Hook</label>\n <textarea\n pInputTextarea\n id=\"hook\"\n formControlName=\"hook\"\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 <div class=\"form-field\">\n <label for=\"communication\" class=\"block text-sm font-medium text-gray-700\">Communication</label>\n <textarea\n pInputTextarea\n id=\"communication\"\n formControlName=\"communication\"\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 <div class=\"form-field\">\n <label class=\"block text-sm font-medium text-gray-700\">Greetings</label>\n <div formArrayName=\"greetings\" class=\"space-y-2\">\n @for (greeting of greetings.controls; track greeting; let i = $index) {\n <div class=\"flex items-center space-x-2\">\n <input\n pInputText\n [formControlName]=\"i\"\n class=\"flex-grow 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 <button pButton type=\"button\" icon=\"pi pi-times\" (click)=\"removeGreeting(i)\" class=\"p-button-rounded p-button-danger p-button-sm\"></button>\n </div>\n }\n </div>\n <button pButton type=\"button\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addGreeting()\" class=\"p-button-sm mt-2\"></button>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { 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"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5546
+ }
5547
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardTranslationFormComponent, decorators: [{
5548
+ type: Component,
5549
+ args: [{ selector: 'dc-character-card-translation-form', standalone: true, imports: [ReactiveFormsModule, InputTextModule, TextareaModule, ButtonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"form-container space-y-4\">\n <div class=\"form-field\">\n <label for=\"hook\" class=\"block text-sm font-medium text-gray-700\">Hook</label>\n <textarea\n pInputTextarea\n id=\"hook\"\n formControlName=\"hook\"\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 <div class=\"form-field\">\n <label for=\"communication\" class=\"block text-sm font-medium text-gray-700\">Communication</label>\n <textarea\n pInputTextarea\n id=\"communication\"\n formControlName=\"communication\"\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 <div class=\"form-field\">\n <label class=\"block text-sm font-medium text-gray-700\">Greetings</label>\n <div formArrayName=\"greetings\" class=\"space-y-2\">\n @for (greeting of greetings.controls; track greeting; let i = $index) {\n <div class=\"flex items-center space-x-2\">\n <input\n pInputText\n [formControlName]=\"i\"\n class=\"flex-grow 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 <button pButton type=\"button\" icon=\"pi pi-times\" (click)=\"removeGreeting(i)\" class=\"p-button-rounded p-button-danger p-button-sm\"></button>\n </div>\n }\n </div>\n <button pButton type=\"button\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addGreeting()\" class=\"p-button-sm mt-2\"></button>\n </div>\n</div>\n" }]
5550
+ }], propDecorators: { formGroup: [{
5551
+ type: Input
5552
+ }] } });
5553
+
5554
+ class DcCharacterCardTranslationsTabsFormComponent {
5555
+ constructor() {
5556
+ this.characterFormGroupService = inject(CharacterFormGroupService);
5557
+ this.displayAddLanguageDialog = false;
5558
+ this.selectedLanguage = null;
5559
+ this.availableLanguages = signal([], ...(ngDevMode ? [{ debugName: "availableLanguages" }] : []));
5560
+ }
5561
+ showAddLanguageDialog() {
5562
+ const availableLanguages = SUPPORTED_LANGUAGES.filter((lang) => !this.formGroup.controls[lang]).map((langCode) => ({
5563
+ code: langCode,
5564
+ description: LANGUAGES[langCode]?.translations.es || langCode,
5565
+ }));
5566
+ this.availableLanguages.set(availableLanguages);
5567
+ this.displayAddLanguageDialog = true;
5568
+ }
5569
+ addLanguage() {
5570
+ if (this.selectedLanguage) {
5571
+ const newLangControl = this.characterFormGroupService.createCardTranslationFormGroup();
5572
+ this.formGroup.addControl(this.selectedLanguage, newLangControl);
5573
+ this.selectedLanguage = null;
5574
+ this.displayAddLanguageDialog = false;
5575
+ }
5576
+ }
5577
+ removeLanguage(langCode) {
5578
+ this.formGroup.removeControl(langCode);
5579
+ }
5580
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardTranslationsTabsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5581
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DcCharacterCardTranslationsTabsFormComponent, isStandalone: true, selector: "dc-character-card-translations-tabs-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div class=\"flex justify-between items-center mb-4\">\n <h4 class=\"text-lg font-semibold\">Translations ({{ (formGroup?.controls | keyvalue)?.length }})</h4>\n <p-button icon=\"pi pi-plus\" label=\"Add Language\" (click)=\"showAddLanguageDialog()\" />\n</div>\n\n<p-tabs value=\"0\" [scrollable]=\"true\">\n <p-tablist>\n @for (control of formGroup.controls | keyvalue; track control.key; let i = $index) {\n <p-tab [value]=\"control.key\">\n <div class=\"flex items-center\">\n <span>{{ control.key }}</span>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n class=\"p-button-rounded p-button-danger p-button-text ml-2\"\n (click)=\"removeLanguage(control.key)\"></button>\n </div>\n </p-tab>\n }\n </p-tablist>\n <p-tabpanels>\n @for (control of formGroup.controls | keyvalue; track control.key) {\n <p-tabpanel [value]=\"control.key\">\n @if (control.value) {\n <dc-character-card-translation-form [formGroup]=\"control.value\" />\n }\n </p-tabpanel>\n }\n </p-tabpanels>\n</p-tabs>\n\n<p-dialog header=\"Add New Language\" [(visible)]=\"displayAddLanguageDialog\" [modal]=\"true\" [style]=\"{ width: '50vw', height: '50vh' }\">\n <div style=\"height: 30vh\">\n <label for=\"language\">Only Valid Languages and not added yet are displayed</label>\n <br />\n <p-select\n [options]=\"availableLanguages()\"\n [(ngModel)]=\"selectedLanguage\"\n placeholder=\"Select a Language\"\n optionLabel=\"description\"\n optionValue=\"code\"\n [filter]=\"true\"\n filterBy=\"description\"\n [showClear]=\"true\"></p-select>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button icon=\"pi pi-times\" label=\"Cancel\" styleClass=\"p-button-text\" (click)=\"displayAddLanguageDialog = false\" />\n <p-button icon=\"pi pi-check\" label=\"Add\" (click)=\"addLanguage()\" [disabled]=\"!selectedLanguage\" />\n </ng-template>\n</p-dialog>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i2$6.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$6.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$6.TabPanel, selector: "p-tabpanel", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: i2$6.TabList, selector: "p-tablist" }, { kind: "component", type: i2$6.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: DcCharacterCardTranslationFormComponent, selector: "dc-character-card-translation-form", inputs: ["formGroup"] }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "appendTo", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }] }); }
5582
+ }
5583
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardTranslationsTabsFormComponent, decorators: [{
5584
+ type: Component,
5585
+ args: [{ selector: 'dc-character-card-translations-tabs-form', standalone: true, imports: [ReactiveFormsModule, FormsModule, TabsModule, DcCharacterCardTranslationFormComponent, ButtonModule, DialogModule, SelectModule, KeyValuePipe], template: "<div class=\"flex justify-between items-center mb-4\">\n <h4 class=\"text-lg font-semibold\">Translations ({{ (formGroup?.controls | keyvalue)?.length }})</h4>\n <p-button icon=\"pi pi-plus\" label=\"Add Language\" (click)=\"showAddLanguageDialog()\" />\n</div>\n\n<p-tabs value=\"0\" [scrollable]=\"true\">\n <p-tablist>\n @for (control of formGroup.controls | keyvalue; track control.key; let i = $index) {\n <p-tab [value]=\"control.key\">\n <div class=\"flex items-center\">\n <span>{{ control.key }}</span>\n <button\n pButton\n type=\"button\"\n icon=\"pi pi-times\"\n class=\"p-button-rounded p-button-danger p-button-text ml-2\"\n (click)=\"removeLanguage(control.key)\"></button>\n </div>\n </p-tab>\n }\n </p-tablist>\n <p-tabpanels>\n @for (control of formGroup.controls | keyvalue; track control.key) {\n <p-tabpanel [value]=\"control.key\">\n @if (control.value) {\n <dc-character-card-translation-form [formGroup]=\"control.value\" />\n }\n </p-tabpanel>\n }\n </p-tabpanels>\n</p-tabs>\n\n<p-dialog header=\"Add New Language\" [(visible)]=\"displayAddLanguageDialog\" [modal]=\"true\" [style]=\"{ width: '50vw', height: '50vh' }\">\n <div style=\"height: 30vh\">\n <label for=\"language\">Only Valid Languages and not added yet are displayed</label>\n <br />\n <p-select\n [options]=\"availableLanguages()\"\n [(ngModel)]=\"selectedLanguage\"\n placeholder=\"Select a Language\"\n optionLabel=\"description\"\n optionValue=\"code\"\n [filter]=\"true\"\n filterBy=\"description\"\n [showClear]=\"true\"></p-select>\n </div>\n\n <ng-template pTemplate=\"footer\">\n <p-button icon=\"pi pi-times\" label=\"Cancel\" styleClass=\"p-button-text\" (click)=\"displayAddLanguageDialog = false\" />\n <p-button icon=\"pi pi-check\" label=\"Add\" (click)=\"addLanguage()\" [disabled]=\"!selectedLanguage\" />\n </ng-template>\n</p-dialog>\n" }]
5586
+ }], propDecorators: { formGroup: [{
5587
+ type: Input
5588
+ }] } });
5589
+
5590
+ class DcPersonaFormComponent {
5591
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcPersonaFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5592
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: DcPersonaFormComponent, isStandalone: true, selector: "dc-persona-form", inputs: { personaForm: "personaForm" }, ngImport: i0, template: "<div [formGroup]=\"personaForm\" class=\"space-y-6\">\n <h3 class=\"text-xl font-semibold text-gray-700\">\n Persona Details <span pTooltip=\"Detailed information about the character's persona\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span>\n </h3>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"identity\" class=\"block text-sm font-medium text-gray-700\"\n >Identity <span pTooltip=\"Name, Age, Gender, Species, Sexuality, Role, Appearance\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"identity\"\n formControlName=\"identity\"\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=\"physical\" class=\"block text-sm font-medium text-gray-700\"\n >Physical\n <span\n pTooltip=\"physical description including height, build, hairColor, hairStyle, eyeColor, skinTone, distinctiveMarks, clothing style, currentOutfit\"\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 id=\"physical\"\n formControlName=\"physical\"\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=\"personality\" class=\"block text-sm font-medium text-gray-700\"\n >Personality\n <span pTooltip=\"personality description surface traits, Temperament, Values, Beliefs, Observable traits\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"personality\"\n formControlName=\"personality\"\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=\"communication\" class=\"block text-sm font-medium text-gray-700\"\n >Communication\n <span pTooltip=\"(How They Express) Speech Pattern, Style Common Phrases, Language Habits\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"communication\"\n formControlName=\"communication\"\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=\"psychology\" class=\"block text-sm font-medium text-gray-700\"\n >Psychology <span pTooltip=\"Motivations, Desires, Goals, Traumas, Conflicts, Weaknesses\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"psychology\"\n formControlName=\"psychology\"\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=\"background\" class=\"block text-sm font-medium text-gray-700\"\n >Background <span pTooltip=\"Background, History, origin, formative, secrets\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"background\"\n formControlName=\"background\"\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=\"capabilities\" class=\"block text-sm font-medium text-gray-700\"\n >Capabilities\n <span pTooltip=\"skills, knowledge, abilities, expertise, limitations, Tools, Strengths\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"capabilities\"\n formControlName=\"capabilities\"\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=\"social\" class=\"block text-sm font-medium text-gray-700\"\n >Social <span pTooltip=\"Relationships, reputation, allies, enemies, social role\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"social\"\n formControlName=\"social\"\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=\"preferences\" class=\"block text-sm font-medium text-gray-700\"\n >Preferences <span pTooltip=\"likes, dislikes, hobbies, interests, hates\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"preferences\"\n formControlName=\"preferences\"\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=\"situation\" class=\"block text-sm font-medium text-gray-700\"\n >Situation\n <span pTooltip=\"Current context for the character, immediate goal or challenge and constraints\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"situation\"\n formControlName=\"situation\"\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</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }] }); }
5593
+ }
5594
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcPersonaFormComponent, decorators: [{
5595
+ type: Component,
5596
+ args: [{ selector: 'dc-persona-form', standalone: true, imports: [ReactiveFormsModule, TextareaModule, TooltipModule], template: "<div [formGroup]=\"personaForm\" class=\"space-y-6\">\n <h3 class=\"text-xl font-semibold text-gray-700\">\n Persona Details <span pTooltip=\"Detailed information about the character's persona\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span>\n </h3>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"identity\" class=\"block text-sm font-medium text-gray-700\"\n >Identity <span pTooltip=\"Name, Age, Gender, Species, Sexuality, Role, Appearance\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"identity\"\n formControlName=\"identity\"\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=\"physical\" class=\"block text-sm font-medium text-gray-700\"\n >Physical\n <span\n pTooltip=\"physical description including height, build, hairColor, hairStyle, eyeColor, skinTone, distinctiveMarks, clothing style, currentOutfit\"\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 id=\"physical\"\n formControlName=\"physical\"\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=\"personality\" class=\"block text-sm font-medium text-gray-700\"\n >Personality\n <span pTooltip=\"personality description surface traits, Temperament, Values, Beliefs, Observable traits\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"personality\"\n formControlName=\"personality\"\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=\"communication\" class=\"block text-sm font-medium text-gray-700\"\n >Communication\n <span pTooltip=\"(How They Express) Speech Pattern, Style Common Phrases, Language Habits\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"communication\"\n formControlName=\"communication\"\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=\"psychology\" class=\"block text-sm font-medium text-gray-700\"\n >Psychology <span pTooltip=\"Motivations, Desires, Goals, Traumas, Conflicts, Weaknesses\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"psychology\"\n formControlName=\"psychology\"\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=\"background\" class=\"block text-sm font-medium text-gray-700\"\n >Background <span pTooltip=\"Background, History, origin, formative, secrets\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"background\"\n formControlName=\"background\"\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=\"capabilities\" class=\"block text-sm font-medium text-gray-700\"\n >Capabilities\n <span pTooltip=\"skills, knowledge, abilities, expertise, limitations, Tools, Strengths\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"capabilities\"\n formControlName=\"capabilities\"\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=\"social\" class=\"block text-sm font-medium text-gray-700\"\n >Social <span pTooltip=\"Relationships, reputation, allies, enemies, social role\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"social\"\n formControlName=\"social\"\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=\"preferences\" class=\"block text-sm font-medium text-gray-700\"\n >Preferences <span pTooltip=\"likes, dislikes, hobbies, interests, hates\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"preferences\"\n formControlName=\"preferences\"\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=\"situation\" class=\"block text-sm font-medium text-gray-700\"\n >Situation\n <span pTooltip=\"Current context for the character, immediate goal or challenge and constraints\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"situation\"\n formControlName=\"situation\"\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</div>\n" }]
5597
+ }], propDecorators: { personaForm: [{
5598
+ type: Input,
5599
+ args: [{ required: true }]
5600
+ }] } });
5601
+
4848
5602
  class DcCharacterCardFormComponent {
4849
5603
  constructor() {
4850
5604
  this.generateMissingDataRequest = new EventEmitter();
4851
- this.fb = inject(FormBuilder);
4852
5605
  this.cdr = inject(ChangeDetectorRef);
4853
5606
  this.agentCardService = inject(CONVERSATION_AI_TOKEN);
4854
5607
  this.toastService = inject(TOAST_ALERTS_TOKEN, { optional: true });
4855
- this.formGroupService = inject(FormGroupService);
5608
+ this.characterFormGroupService = inject(CharacterFormGroupService);
4856
5609
  this.markdownForm = new FormGroup({ seeMarkdown: new FormControl(false) });
4857
5610
  this.isGenerating = false; // For improveFirstMessage loading state
5611
+ this.genderOptions = [
5612
+ { label: 'Female', value: 'female' },
5613
+ { label: 'Male', value: 'male' },
5614
+ { label: 'Other', value: 'other' },
5615
+ ];
4858
5616
  }
4859
5617
  get dataGroup() {
4860
5618
  return this.characterCardForm.get('data');
4861
5619
  }
5620
+ get personaGroup() {
5621
+ return this.dataGroup.get('persona');
5622
+ }
4862
5623
  get alternateGreetingsArray() {
4863
- return this.dataGroup.get('alternate_greetings');
5624
+ return this.dataGroup.get('greetings');
4864
5625
  }
4865
5626
  get tagsArray() {
4866
5627
  return this.dataGroup.get('tags');
4867
5628
  }
5629
+ get langTranslationGroup() {
5630
+ return this.dataGroup.get('langTranslation');
5631
+ }
4868
5632
  ngOnInit() {
4869
5633
  if (!this.characterCardForm) {
4870
5634
  console.error('CharacterCardFormComponent expects an FormGroup instance.');
@@ -4880,15 +5644,15 @@ class DcCharacterCardFormComponent {
4880
5644
  this.cdr.detectChanges();
4881
5645
  }
4882
5646
  addArrayItem(controlPath) {
4883
- this.formGroupService.addArrayItem(this.dataGroup, controlPath);
5647
+ this.characterFormGroupService.addArrayItem(this.dataGroup, controlPath);
4884
5648
  this.cdr.detectChanges();
4885
5649
  }
4886
5650
  removeArrayItem(controlPath, index) {
4887
- this.formGroupService.removeArrayItem(this.dataGroup, controlPath, index);
5651
+ this.characterFormGroupService.removeArrayItem(this.dataGroup, controlPath, index);
4888
5652
  this.cdr.detectChanges();
4889
5653
  }
4890
5654
  updateArrayField(controlPath, index, event) {
4891
- this.formGroupService.updateArrayField(this.dataGroup, controlPath, index, event);
5655
+ this.characterFormGroupService.updateArrayField(this.dataGroup, controlPath, index, event);
4892
5656
  }
4893
5657
  async improveFirstMessage() {
4894
5658
  const confirmImprove = window.confirm('Are you sure you want to improve the first message? It might be shortened.');
@@ -4950,11 +5714,24 @@ Improve the following first message:`;
4950
5714
  return control;
4951
5715
  }
4952
5716
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4953
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 >Character 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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "styleClass", "inputId", "tabindex", "iconPos", "autofocus", "size", "allowEmpty", "fluid"], outputs: ["onChange"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }] }); }
5717
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DcCharacterCardFormComponent, isStandalone: true, selector: "dc-character-card-form", inputs: { characterCardForm: "characterCardForm" }, outputs: { generateMissingDataRequest: "generateMissingDataRequest" }, ngImport: i0, template: "<div [formGroup]=\"characterCardForm\">\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=\"grid grid-cols-2 gap-6\">\n <div class=\"form-field\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Character 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\">\n <label for=\"gender\" class=\"block text-sm font-medium text-gray-700\"\n >Gender <span pTooltip=\"El genero del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <p-select\n class=\"w-full\"\n id=\"gender\"\n [options]=\"genderOptions\"\n formControlName=\"gender\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Gender'\"></p-select>\n @if (dataGroup.controls['gender']?.errors?.['required'] && dataGroup.controls['gender']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Gender is required </div>\n }\n </div>\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 >(\u2757\uFE0FObsoleto) 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=\"1\"\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=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >(\u2757\uFE0FObsoleto) First Message\n <span pTooltip=\"Mensaje para iniciar la historia, OBSOLETO utilizar Greetings en su lugar, poner uno o varios.\" 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=\"1\"\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 >(\u2757\uFE0FObsoleto) Mensajes de Ejemplo\n <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n, agregar esta info dentro de comunication\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"1\"\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 >Hook <span pTooltip=\"Texto gancho para atraer al usuario a interactuar con esta tarjeta\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardHook\"\n formControlName=\"hook\"\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=\"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=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Greetings (Saludos Iniciales)<span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></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('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('greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <p-divider> Persona </p-divider>\n\n <dc-persona-form [personaForm]=\"personaGroup\" />\n\n <p-divider> Avanzado </p-divider>\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=\"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 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\n <p-divider align=\"center\" type=\"dotted\">\n <b>Traducciones a otros idiomas</b>\n </p-divider>\n\n @if(langTranslationGroup){\n <dc-character-card-translations-tabs-form [formGroup]=\"langTranslationGroup\" />\n }\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$2.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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6$1.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "styleClass", "inputId", "tabindex", "iconPos", "autofocus", "size", "allowEmpty", "fluid"], outputs: ["onChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$1.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "component", type: DcCharacterCardTranslationsTabsFormComponent, selector: "dc-character-card-translations-tabs-form", inputs: ["formGroup"] }, { kind: "component", type: DcPersonaFormComponent, selector: "dc-persona-form", inputs: ["personaForm"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }] }); }
4954
5718
  }
4955
5719
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcCharacterCardFormComponent, decorators: [{
4956
5720
  type: Component,
4957
- args: [{ selector: 'dc-character-card-form', standalone: true, imports: [ReactiveFormsModule, FormsModule, ButtonModule, InputTextModule, TextareaModule, TooltipModule, ToggleButtonModule, MdToHtmlArrayPipe], 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 >Character 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"] }]
5721
+ args: [{ selector: 'dc-character-card-form', standalone: true, imports: [
5722
+ ReactiveFormsModule,
5723
+ FormsModule,
5724
+ ButtonModule,
5725
+ InputTextModule,
5726
+ TextareaModule,
5727
+ TooltipModule,
5728
+ ToggleButtonModule,
5729
+ MdToHtmlArrayPipe,
5730
+ SelectModule,
5731
+ DividerModule,
5732
+ DcCharacterCardTranslationsTabsFormComponent,
5733
+ DcPersonaFormComponent,
5734
+ ], template: "<div [formGroup]=\"characterCardForm\">\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=\"grid grid-cols-2 gap-6\">\n <div class=\"form-field\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Character 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\">\n <label for=\"gender\" class=\"block text-sm font-medium text-gray-700\"\n >Gender <span pTooltip=\"El genero del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <p-select\n class=\"w-full\"\n id=\"gender\"\n [options]=\"genderOptions\"\n formControlName=\"gender\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Gender'\"></p-select>\n @if (dataGroup.controls['gender']?.errors?.['required'] && dataGroup.controls['gender']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Gender is required </div>\n }\n </div>\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 >(\u2757\uFE0FObsoleto) 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=\"1\"\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=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >(\u2757\uFE0FObsoleto) First Message\n <span pTooltip=\"Mensaje para iniciar la historia, OBSOLETO utilizar Greetings en su lugar, poner uno o varios.\" 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=\"1\"\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 >(\u2757\uFE0FObsoleto) Mensajes de Ejemplo\n <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n, agregar esta info dentro de comunication\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"1\"\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 >Hook <span pTooltip=\"Texto gancho para atraer al usuario a interactuar con esta tarjeta\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardHook\"\n formControlName=\"hook\"\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=\"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=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Greetings (Saludos Iniciales)<span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></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('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('greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <p-divider> Persona </p-divider>\n\n <dc-persona-form [personaForm]=\"personaGroup\" />\n\n <p-divider> Avanzado </p-divider>\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=\"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 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\n <p-divider align=\"center\" type=\"dotted\">\n <b>Traducciones a otros idiomas</b>\n </p-divider>\n\n @if(langTranslationGroup){\n <dc-character-card-translations-tabs-form [formGroup]=\"langTranslationGroup\" />\n }\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"] }]
4958
5735
  }], propDecorators: { characterCardForm: [{
4959
5736
  type: Input,
4960
5737
  args: [{ required: true }]
@@ -4975,6 +5752,7 @@ class DcVoiceTtsFormComponent {
4975
5752
  const dialogRef = this.dialogService.open(VoiceSelectorComponent, {
4976
5753
  header: 'Select Voice',
4977
5754
  width: '50vw',
5755
+ maximizable: true,
4978
5756
  height: '500px',
4979
5757
  contentStyle: { 'max-height': '90vh', overflow: 'auto', 'min-height': '500px' },
4980
5758
  baseZIndex: 10000,
@@ -4990,7 +5768,7 @@ class DcVoiceTtsFormComponent {
4990
5768
  });
4991
5769
  }
4992
5770
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcVoiceTtsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4993
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.6", 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$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i3$4.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["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: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CardModule }] }); }
5771
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.6", 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$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i3$5.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["styleClass"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i4$2.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CardModule }] }); }
4994
5772
  }
4995
5773
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcVoiceTtsFormComponent, decorators: [{
4996
5774
  type: Component,
@@ -5066,7 +5844,7 @@ class DcConversationSettingsFormComponent {
5066
5844
  });
5067
5845
  }
5068
5846
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcConversationSettingsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5069
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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 Chat Conversation Settings\n <span pTooltip=\"Additional information about the conversation use in the chat\" 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.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"] }] }); }
5847
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", 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 Chat Conversation Settings\n <span pTooltip=\"Additional information about the conversation use in the chat\" 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$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$2.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$4.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"] }] }); }
5070
5848
  }
5071
5849
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcConversationSettingsFormComponent, decorators: [{
5072
5850
  type: Component,
@@ -5100,7 +5878,7 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5100
5878
  this.entityCommunicationService = inject(CONVERSATION_AI_TOKEN);
5101
5879
  this.dialogService = inject(DialogService);
5102
5880
  this.promptBuilder = inject(ConversationPromptBuilderService);
5103
- this.formGroupService = inject(FormGroupService);
5881
+ this.characterFormGroupService = inject(CharacterFormGroupService);
5104
5882
  // select options
5105
5883
  this.conversationOptions = ConversationTypeOptions;
5106
5884
  this.voiceTTSOptions = Object.values(VoiceTTSOptions);
@@ -5111,7 +5889,7 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5111
5889
  this.onSave = output();
5112
5890
  this.onGoDetails = output();
5113
5891
  this.onTranslate = output();
5114
- this.form = this.formGroupService.createAgentCardForm();
5892
+ this.form = this.characterFormGroupService.createAgentCardForm();
5115
5893
  this.isGenerating = signal(false, ...(ngDevMode ? [{ debugName: "isGenerating" }] : []));
5116
5894
  }
5117
5895
  getSettings() {
@@ -5123,8 +5901,9 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5123
5901
  return imageSettings;
5124
5902
  }
5125
5903
  patchForm(agentCard) {
5126
- this.formGroupService.patchFormWithConversationData(this.form, agentCard);
5127
- this.formGroupService.handleArrayForms(this.form, agentCard);
5904
+ this.characterFormGroupService.patchFormWithConversationData(this.form, agentCard);
5905
+ this.characterFormGroupService.handleArrayForms(this.form, agentCard);
5906
+ this.characterFormGroupService.handleTranslationForm(this.form, agentCard);
5128
5907
  this.storageSettings().path = 'conversation-cards/' + this.entityId();
5129
5908
  }
5130
5909
  async save() {
@@ -5137,40 +5916,57 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5137
5916
  }
5138
5917
  return result;
5139
5918
  }
5919
+ inspect() {
5920
+ console.log(this.form.value);
5921
+ }
5140
5922
  async onImageSelected(file) {
5141
5923
  // const file = (event.target as HTMLInputElement).files?.[0];
5142
5924
  if (file) {
5143
5925
  // You might want to handle the file upload here
5144
5926
  // For now, we'll just store the file in the form
5145
5927
  const jsonData = await getCharacterData(file);
5928
+ // STRATEGY TO IMPORT 1) mes_example and personality moves to description
5929
+ // 2) first_mes and alternate_greetings merged into greetings
5930
+ // 3) Rest keep as it is
5146
5931
  if (jsonData) {
5147
5932
  // alert('metadata was found');
5148
5933
  if (this.toastService) {
5149
5934
  this.toastService.info({ title: 'Image Loaded', subtitle: 'Metadata was found' });
5150
5935
  }
5936
+ if (jsonData?.data?.first_mes) {
5937
+ this.form.get('characterCard.data.greetings').push(this.fb.control(jsonData.data.first_mes));
5938
+ delete jsonData.data.first_mes;
5939
+ }
5151
5940
  // check that property exists and is an array
5152
5941
  if (jsonData?.data?.alternate_greetings && Array.isArray(jsonData.data.alternate_greetings)) {
5153
5942
  jsonData.data.alternate_greetings.forEach((_) => {
5154
- this.form.get('characterCard.data.alternate_greetings').push(this.fb.control(''));
5943
+ this.form.get('characterCard.data.greetings').push(this.fb.control(''));
5155
5944
  });
5156
5945
  this.form.get('conversationSettings.conversationType')?.setValue(ConversationType.RolePlay);
5157
5946
  this.form.get('conversationSettings.textEngine')?.setValue(TextEngines.MarkdownMultiMessages);
5158
5947
  }
5948
+ if (jsonData?.data?.personality) {
5949
+ jsonData.data.description += '### Personality\n\n' + jsonData.data.personality;
5950
+ delete jsonData.data.personality;
5951
+ }
5952
+ if (jsonData?.data?.mes_example) {
5953
+ jsonData.data.description += '### Message Example: \n\n' + jsonData.data.mes_example;
5954
+ delete jsonData.data.mes_example;
5955
+ }
5159
5956
  this.form.patchValue({ characterCard: jsonData });
5160
5957
  console.log(this.form.value);
5161
- // this.saveScenario();
5162
5958
  }
5163
5959
  }
5164
5960
  }
5165
5961
  checkPrompt() {
5166
5962
  const messages = this.promptBuilder.buildConversationMessages(this.form.value);
5167
5963
  const jailBrake = this.promptBuilder.getJailBrakePrompt(this.form.value);
5168
- const messagesHtml = this.promptBuilder.convertConversationToHtml(messages, jailBrake);
5169
5964
  this.dialogService.open(PromptPreviewDialogComponent, {
5170
- data: { html: messagesHtml },
5965
+ data: { messages, jailBrake },
5171
5966
  width: '80vw',
5172
5967
  height: '80vh',
5173
5968
  closable: true,
5969
+ maximizable: true,
5174
5970
  header: 'Prompt Preview',
5175
5971
  });
5176
5972
  }
@@ -5202,7 +5998,8 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5202
5998
  }
5203
5999
  downloadConversation() {
5204
6000
  const data = this.form.value;
5205
- const jsonData = JSON.stringify(data, null, 2);
6001
+ const cardData = this.entity();
6002
+ const jsonData = JSON.stringify(cardData, null, 2);
5206
6003
  const blob = new Blob([jsonData], { type: 'application/json' });
5207
6004
  const url = URL.createObjectURL(blob);
5208
6005
  const a = document.createElement('a');
@@ -5224,11 +6021,14 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5224
6021
  try {
5225
6022
  const jsonData = JSON.parse(e.target?.result);
5226
6023
  delete jsonData['id'];
6024
+ delete jsonData['_id'];
5227
6025
  this.form.patchValue(jsonData);
6026
+ this.entity.set(jsonData);
6027
+ this.entityCommunicationService.partialUpdate(this.entityId(), jsonData);
5228
6028
  if (this.toastService) {
5229
6029
  this.toastService.success({
5230
6030
  title: 'Import Successful',
5231
- subtitle: 'Conversation data has been loaded',
6031
+ subtitle: 'Conversation data has been loaded and Saved',
5232
6032
  });
5233
6033
  }
5234
6034
  }
@@ -5248,46 +6048,44 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5248
6048
  fileInput.click();
5249
6049
  }
5250
6050
  async generateCharacter() {
5251
- // Que aprendí de la generación desde frontend:
5252
- // 1) tener el prompt system con un variable que define la interfaz en un string, characterCardDataDefinition
5253
- // 2) Genear el prompt de usuario con instrucciones finales y parser el json a la interfaz o form.
5254
- // 3) Listo puedo generar cualquier cosas desde frontend.
5255
- const idea = prompt('Qué idea tienes para tu personaje?');
5256
- if (idea === null) {
5257
- return;
5258
- }
5259
- console.log(idea);
5260
- const prompt_system = `Genera una ficha de personaje, haz que toda la información sea coherente y que el personaje tenga sentido.
5261
- en la descripcción detalla su comportamiento y sus habilidades y estilo de comunicación, frases típicas que dice, sus intereses, su perfil sicológico e información adicional que ayude a complementar la ficha de personaje.
5262
- regresa el resultado en formato json siguiendo la siguiente interfaz:
5263
- ${characterCardStringDataDefinition}`;
5264
- const prompt_user = `Dame la ficha de personaje para la siguiente idea: ${idea}`;
5265
- const messages = [
5266
- { role: ChatRole.System, content: prompt_system },
5267
- { role: ChatRole.User, content: prompt_user },
5268
- ];
5269
- this.isGenerating.set(true);
5270
- this.toastService.info({ title: 'Generando personaje', subtitle: 'Puede tardar varios minutos, Por favor espera...' });
5271
- const response = await this.entityCommunicationService.callChatCompletion({
5272
- messages,
5273
- textEngine: TextEngines.SimpleText,
5274
- conversationType: ConversationType.General,
5275
- returnJson: true,
5276
- type: 'character-generation',
6051
+ const dialogRef = this.dialogService.open(GenerateCharacterDialogComponent, {
6052
+ header: 'Generate Character',
6053
+ width: '70vw',
6054
+ maximizable: true,
6055
+ data: {
6056
+ agentCard: this.entity(),
6057
+ },
6058
+ modal: true,
6059
+ closable: true,
6060
+ });
6061
+ dialogRef.onClose.subscribe(async (result) => {
6062
+ console.log(result);
6063
+ if (result?.langTranslation) {
6064
+ this.toastService.info({ title: 'Character generated', subtitle: 'No te olvides de guardar cambios si estas seguro' });
6065
+ // this.form.controls.characterCard.patchValue({ data: result });
6066
+ const card = this.entity();
6067
+ card.characterCard.data.langTranslation = result.langTranslation;
6068
+ this.entity.update((card) => ({ ...card }));
6069
+ console.log('new chard', this.entity());
6070
+ debugger;
6071
+ if (card && card.characterCard?.data?.langTranslation) {
6072
+ this.characterFormGroupService.handleTranslationForm(this.form, card);
6073
+ }
6074
+ }
6075
+ else if (result) {
6076
+ this.toastService.success({ title: 'Character generated', subtitle: 'No te olvides de guardar cambios si estas seguro' });
6077
+ this.entity.update((card) => ({ ...card, characterCard: { ...card.characterCard, data: result } }));
6078
+ this.form.controls.characterCard.patchValue({ data: result });
6079
+ this.characterFormGroupService.createAndPatchCharacterArrayForm(this.form, this.entity());
6080
+ }
6081
+ else {
6082
+ this.toastService.error({
6083
+ title: 'Algo salió mal :/',
6084
+ subtitle: 'La información no pudo ser extraída correcamente, pero no te preocupes, puedes intentar de nuevo',
6085
+ });
6086
+ }
6087
+ this.isGenerating.set(false);
5277
6088
  });
5278
- // const jsonData = extractJsonFromResponse(response.content);
5279
- const jsonData = response.content;
5280
- if (jsonData) {
5281
- this.toastService.success({ title: 'Character generated', subtitle: 'No te olvides de guardar cambios si estas seguro' });
5282
- this.form.controls.characterCard.patchValue({ data: jsonData });
5283
- }
5284
- else {
5285
- this.toastService.error({
5286
- title: 'Algo salió mal :/',
5287
- subtitle: 'La información no pudo ser extraída correcamente, pero no te preocupes, puedes intentar de nuevo',
5288
- });
5289
- }
5290
- this.isGenerating.set(false);
5291
6089
  }
5292
6090
  async generateMissingData() {
5293
6091
  this.entityCommunicationService.completeAgentCard(this.entityId());
@@ -5306,7 +6104,7 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
5306
6104
  this.form.controls.voiceCloning.patchValue({ sample: event });
5307
6105
  }
5308
6106
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCAgentCardFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5309
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 <p-button severity=\"help\" (click)=\"goToCardsCreator()\" label=\" Creador masivo \"></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 <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n\n <div class=\"form-field\">\n <label for=\"name\">Card Name <span pTooltip=\"Name of the Agent Card\">\u2139\uFE0F</span></label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" />\n @if(form.get('name').errors?.['required'] && form.get('name').touched){\n <div class=\"error\"> Name 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 [filter]=\"true\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"agentType\">Agent Type <span pTooltip=\"Select the type of agent\">\u2139\uFE0F</span></label>\n <p-select id=\"agentType\" [options]=\"agentTypeOptions\" formControlName=\"agentType\" [placeholder]=\"'Select Agent Type'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"form.controls.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-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\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 <details>\n <summary>Clonaci\u00F3n de voz</summary>\n <div class=\"group\" formGroupName=\"voiceCloning\">\n <h4>Clonaci\u00F3n de voz de herramientas</h4>\n <div class=\"form-field\">\n <label for=\"transcription\">Transcription</label>\n <textarea pTextarea id=\"transcription\" formControlName=\"transcription\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-field\">\n <!-- <p-button label=\"Upload Audio Sample\" icon=\"pi pi-upload\" (onClick)=\"uploadAudioSample()\"></p-button> -->\n <!-- Display audio sample info if available -->\n <dc-simple-uploader\n buttonLabel=\"Subir audio\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (fileUploaded)=\"onFileUploaded($event)\"></dc-simple-uploader>\n @if(form.get('voiceCloning.sample').value?.url){\n <audio controls [src]=\"form.get('voiceCloning.sample').value.url\"></audio>\n }\n </div>\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;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:flex;flex-wrap:wrap;gap:2rem;width:100%}.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.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;flex:1 1 calc(50% - 1rem);min-width:300px}@media (max-width: 768px){.conversation-form .left-column,.conversation-form .right-column{flex:1 1 100%}}.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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], 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$5.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: i7.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], 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"] }, { kind: "component", type: DcManageableFormComponent, selector: "dc-manageable-form", inputs: ["form"] }, { kind: "component", type: DcLearnableFormComponent, selector: "dc-learnable-form", inputs: ["form"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled", "metadata"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i4.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
6107
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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 <p-button severity=\"help\" (click)=\"goToCardsCreator()\" label=\" Creador masivo \"></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 <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n\n <div class=\"form-field\">\n <label for=\"name\">Card Name <span pTooltip=\"Name of the Agent Card\">\u2139\uFE0F</span></label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" />\n @if(form.get('name').errors?.['required'] && form.get('name').touched){\n <div class=\"error\"> Name 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 [filter]=\"true\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"agentType\">Agent Type <span pTooltip=\"Select the type of agent\">\u2139\uFE0F</span></label>\n <p-select id=\"agentType\" [options]=\"agentTypeOptions\" formControlName=\"agentType\" [placeholder]=\"'Select Agent Type'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"form.controls.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-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\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 <details>\n <summary>Clonaci\u00F3n de voz</summary>\n <div class=\"group\" formGroupName=\"voiceCloning\">\n <h4>Clonaci\u00F3n de voz de herramientas</h4>\n <div class=\"form-field\">\n <label for=\"transcription\">Transcription</label>\n <textarea pTextarea id=\"transcription\" formControlName=\"transcription\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-field\">\n <!-- <p-button label=\"Upload Audio Sample\" icon=\"pi pi-upload\" (onClick)=\"uploadAudioSample()\"></p-button> -->\n <!-- Display audio sample info if available -->\n <dc-simple-uploader\n buttonLabel=\"Subir audio\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (fileUploaded)=\"onFileUploaded($event)\"></dc-simple-uploader>\n @if(form.get('voiceCloning.sample').value?.url){\n <audio controls [src]=\"form.get('voiceCloning.sample').value.url\"></audio>\n }\n </div>\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\n <br />\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-eye\" (click)=\"inspect()\" severity=\"secondary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Inspeccionar\"> </p-button>\n\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;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:flex;flex-wrap:wrap;gap:2rem;width:100%}.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.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;flex:1 1 calc(50% - 1rem);min-width:300px}@media (max-width: 768px){.conversation-form .left-column,.conversation-form .right-column{flex:1 1 100%}}.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$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$2.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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], 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$5.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: i7.InputNumber, selector: "p-inputNumber, p-inputnumber, p-input-number", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "placeholder", "tabindex", "title", "ariaLabelledBy", "ariaDescribedBy", "ariaLabel", "ariaRequired", "autocomplete", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus"], 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"] }, { kind: "component", type: DcManageableFormComponent, selector: "dc-manageable-form", inputs: ["form"] }, { kind: "component", type: DcLearnableFormComponent, selector: "dc-learnable-form", inputs: ["form"] }, { kind: "component", type: SimpleUploaderComponent, selector: "dc-simple-uploader", inputs: ["storagePath", "buttonLabel", "accept", "disabled", "metadata"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
5310
6108
  }
5311
6109
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DCAgentCardFormComponent, decorators: [{
5312
6110
  type: Component,
@@ -5335,7 +6133,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5335
6133
  DcLearnableFormComponent,
5336
6134
  SimpleUploaderComponent,
5337
6135
  TextareaModule,
5338
- ], 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 <p-button severity=\"help\" (click)=\"goToCardsCreator()\" label=\" Creador masivo \"></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 <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n\n <div class=\"form-field\">\n <label for=\"name\">Card Name <span pTooltip=\"Name of the Agent Card\">\u2139\uFE0F</span></label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" />\n @if(form.get('name').errors?.['required'] && form.get('name').touched){\n <div class=\"error\"> Name 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 [filter]=\"true\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"agentType\">Agent Type <span pTooltip=\"Select the type of agent\">\u2139\uFE0F</span></label>\n <p-select id=\"agentType\" [options]=\"agentTypeOptions\" formControlName=\"agentType\" [placeholder]=\"'Select Agent Type'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"form.controls.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-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\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 <details>\n <summary>Clonaci\u00F3n de voz</summary>\n <div class=\"group\" formGroupName=\"voiceCloning\">\n <h4>Clonaci\u00F3n de voz de herramientas</h4>\n <div class=\"form-field\">\n <label for=\"transcription\">Transcription</label>\n <textarea pTextarea id=\"transcription\" formControlName=\"transcription\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-field\">\n <!-- <p-button label=\"Upload Audio Sample\" icon=\"pi pi-upload\" (onClick)=\"uploadAudioSample()\"></p-button> -->\n <!-- Display audio sample info if available -->\n <dc-simple-uploader\n buttonLabel=\"Subir audio\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (fileUploaded)=\"onFileUploaded($event)\"></dc-simple-uploader>\n @if(form.get('voiceCloning.sample').value?.url){\n <audio controls [src]=\"form.get('voiceCloning.sample').value.url\"></audio>\n }\n </div>\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;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:flex;flex-wrap:wrap;gap:2rem;width:100%}.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.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;flex:1 1 calc(50% - 1rem);min-width:300px}@media (max-width: 768px){.conversation-form .left-column,.conversation-form .right-column{flex:1 1 100%}}.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"] }]
6136
+ ], 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 <p-button severity=\"help\" (click)=\"goToCardsCreator()\" label=\" Creador masivo \"></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 <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n\n <div class=\"form-field\">\n <label for=\"name\">Card Name <span pTooltip=\"Name of the Agent Card\">\u2139\uFE0F</span></label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" />\n @if(form.get('name').errors?.['required'] && form.get('name').touched){\n <div class=\"error\"> Name 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 [filter]=\"true\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"agentType\">Agent Type <span pTooltip=\"Select the type of agent\">\u2139\uFE0F</span></label>\n <p-select id=\"agentType\" [options]=\"agentTypeOptions\" formControlName=\"agentType\" [placeholder]=\"'Select Agent Type'\"></p-select>\n </div>\n </div>\n\n <dc-conversation-settings-form\n [form]=\"form.controls.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-inputnumber formControlName=\"level\" [showButtons]=\"true\" [min]=\"0\" [max]=\"5\" />\n Nivel Recomendado\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 <details>\n <summary>Clonaci\u00F3n de voz</summary>\n <div class=\"group\" formGroupName=\"voiceCloning\">\n <h4>Clonaci\u00F3n de voz de herramientas</h4>\n <div class=\"form-field\">\n <label for=\"transcription\">Transcription</label>\n <textarea pTextarea id=\"transcription\" formControlName=\"transcription\" rows=\"3\"></textarea>\n </div>\n <div class=\"form-field\">\n <!-- <p-button label=\"Upload Audio Sample\" icon=\"pi pi-upload\" (onClick)=\"uploadAudioSample()\"></p-button> -->\n <!-- Display audio sample info if available -->\n <dc-simple-uploader\n buttonLabel=\"Subir audio\"\n [storagePath]=\"'conversation-cards/' + entityId()\"\n (fileUploaded)=\"onFileUploaded($event)\"></dc-simple-uploader>\n @if(form.get('voiceCloning.sample').value?.url){\n <audio controls [src]=\"form.get('voiceCloning.sample').value.url\"></audio>\n }\n </div>\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\n <br />\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-eye\" (click)=\"inspect()\" severity=\"secondary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Inspeccionar\"> </p-button>\n\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;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:flex;flex-wrap:wrap;gap:2rem;width:100%}.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.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;flex:1 1 calc(50% - 1rem);min-width:300px}@media (max-width: 768px){.conversation-form .left-column,.conversation-form .right-column{flex:1 1 100%}}.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"] }]
5339
6137
  }] });
5340
6138
 
5341
6139
  class TruncatePipe {
@@ -5377,6 +6175,8 @@ class AgentCardUI {
5377
6175
  { label: 'Clonar', icon: 'pi pi-copy', command: () => this.eventCard(EventCard.Clone) },
5378
6176
  { label: 'Delete', icon: 'pi pi-trash', title: 'delete', severity: 'danger', command: () => this.eventCard(EventCard.Delete) },
5379
6177
  ];
6178
+ this.finalDescription = signal('', ...(ngDevMode ? [{ debugName: "finalDescription" }] : []));
6179
+ this.name = signal('', ...(ngDevMode ? [{ debugName: "name" }] : []));
5380
6180
  this.card = input(undefined, ...(ngDevMode ? [{ debugName: "card" }] : []));
5381
6181
  this.showOptions = input(true, ...(ngDevMode ? [{ debugName: "showOptions" }] : []));
5382
6182
  this.onAction = output();
@@ -5386,10 +6186,20 @@ class AgentCardUI {
5386
6186
  });
5387
6187
  }
5388
6188
  ngOnInit() {
5389
- const description = this.card()?.characterCard?.data?.description;
5390
- if (description) {
5391
- // this.card()?.characterCard?.data?.description = description?.replace(/{{char}}/g, name);
6189
+ let description = '';
6190
+ const baseLang = this.userService.getBaseLanguage();
6191
+ if (this.card()?.characterCard?.data?.langTranslation?.[baseLang]) {
6192
+ const cardTranslation = this.card()?.characterCard?.data?.langTranslation[baseLang];
6193
+ console.log(cardTranslation);
6194
+ description = cardTranslation?.hook || this.card()?.description || this.card()?.characterCard?.data?.creator_notes || '';
6195
+ this.name.set(this.card()?.characterCard?.data?.name);
5392
6196
  }
6197
+ else {
6198
+ description = this.card()?.characterCard?.data?.hook || this.card()?.characterCard?.data?.creator_notes || this.card()?.description || '';
6199
+ this.name.set(this.card()?.name || this.card()?.title);
6200
+ }
6201
+ description = description?.replace(/{{char}}/g, this.card()?.name).replace(/{{user}}/g, this.userService.userName());
6202
+ this.finalDescription.set(description);
5393
6203
  }
5394
6204
  eventCard(eventType) {
5395
6205
  this.onAction.emit({ action: eventType, item: this.card() });
@@ -5403,11 +6213,11 @@ class AgentCardUI {
5403
6213
  }
5404
6214
  }
5405
6215
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AgentCardUI, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5406
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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()?.name || 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 <div style=\"position: absolute; bottom: 10px; left: 10px\">\n @if(isTaken()){\n <p-tag icon=\"pi pi-check-circle\" severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if(userService.isAdmin()){\n\n <p-tag icon=\"pi pi-eye\" severity=\"secondary\" [value]=\"card()?.manageable?.status || 'Sin estado'\" [rounded]=\"true\" />\n }\n </div>\n\n <p-button\n (click)=\"eventCard(eventType.Select); $event.stopPropagation()\"\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: "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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$6.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$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: TruncatePipe, name: "truncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6216
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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\">{{ name() }}</p>\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"finalDescription() | truncate : 200\"></span>\n </p>\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n @if(isTaken()){\n <p-tag icon=\"pi pi-check-circle\" severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if(userService.isAdmin()){\n\n <p-tag icon=\"pi pi-eye\" severity=\"secondary\" [value]=\"card()?.manageable?.status || 'Sin estado'\" [rounded]=\"true\" />\n }\n </div>\n\n <p-button\n (click)=\"eventCard(eventType.Select); $event.stopPropagation()\"\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: "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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$7.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$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$3.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "pipe", type: TruncatePipe, name: "truncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5407
6217
  }
5408
6218
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AgentCardUI, decorators: [{
5409
6219
  type: Component,
5410
- args: [{ selector: 'dc-agent-card-ui', imports: [PopoverModule, TruncatePipe, ButtonModule, SpeedDialModule, CardModule, TagModule], changeDetection: ChangeDetectionStrategy.OnPush, 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()?.name || 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 <div style=\"position: absolute; bottom: 10px; left: 10px\">\n @if(isTaken()){\n <p-tag icon=\"pi pi-check-circle\" severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if(userService.isAdmin()){\n\n <p-tag icon=\"pi pi-eye\" severity=\"secondary\" [value]=\"card()?.manageable?.status || 'Sin estado'\" [rounded]=\"true\" />\n }\n </div>\n\n <p-button\n (click)=\"eventCard(eventType.Select); $event.stopPropagation()\"\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"] }]
6220
+ args: [{ selector: 'dc-agent-card-ui', imports: [PopoverModule, TruncatePipe, ButtonModule, SpeedDialModule, CardModule, TagModule], changeDetection: ChangeDetectionStrategy.OnPush, 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\">{{ name() }}</p>\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"finalDescription() | truncate : 200\"></span>\n </p>\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n @if(isTaken()){\n <p-tag icon=\"pi pi-check-circle\" severity=\"success\" value=\"Tomada\" [rounded]=\"true\" />\n } @if(userService.isAdmin()){\n\n <p-tag icon=\"pi pi-eye\" severity=\"secondary\" [value]=\"card()?.manageable?.status || 'Sin estado'\" [rounded]=\"true\" />\n }\n </div>\n\n <p-button\n (click)=\"eventCard(eventType.Select); $event.stopPropagation()\"\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"] }]
5411
6221
  }], ctorParameters: () => [] });
5412
6222
 
5413
6223
  // This component contains a really avanced strategy to dinamically render Conversation Cards Details so every app can implement it with their own Style and Behavior
@@ -5436,17 +6246,14 @@ class AgentCardListComponent extends EntityBaseListComponent {
5436
6246
  this.filterConfig.returnProps = {
5437
6247
  _id: 1,
5438
6248
  name: 1,
5439
- title: 1,
5440
- assets: 1,
5441
6249
  description: 1,
5442
- 'characterCard.data.description': 1,
6250
+ 'assets.image': 1,
5443
6251
  'characterCard.data.name': 1,
5444
6252
  'characterCard.data.creator_notes': 1,
6253
+ 'characterCard.data.hook': 1,
5445
6254
  manageable: 1,
5446
6255
  };
5447
6256
  this.agentCardsMasterStateService.getUserState();
5448
- // this.filterConfig.seed = this.entityCommunicationService.randomSeed;
5449
- // console.log(this.filterConfig.seed);
5450
6257
  }
5451
6258
  getCustomButtons(item) {
5452
6259
  if (this.customGetButtons()) {
@@ -5553,24 +6360,35 @@ class DcAgentCardDetailsComponent {
5553
6360
  this.agentCardService = inject(CONVERSATION_AI_TOKEN);
5554
6361
  this.route = inject(ActivatedRoute);
5555
6362
  this.toastService = inject(TOAST_ALERTS_TOKEN);
6363
+ this.chatMonitorService = inject(ChatMonitorService);
6364
+ this.userService = inject(UserService);
5556
6365
  this.agentCardId = '';
5557
6366
  this.onStartConversation = output();
5558
6367
  this.agentCard = signal(undefined, ...(ngDevMode ? [{ debugName: "agentCard" }] : []));
6368
+ this.currentMotionUrl = signal(undefined, ...(ngDevMode ? [{ debugName: "currentMotionUrl" }] : []));
5559
6369
  this.showInfoLayer = signal(false, ...(ngDevMode ? [{ debugName: "showInfoLayer" }] : []));
5560
- this.mediaType = computed(() => {
6370
+ this.isVideoReady = signal(false, ...(ngDevMode ? [{ debugName: "isVideoReady" }] : []));
6371
+ this.isIntroPlaying = signal(false, ...(ngDevMode ? [{ debugName: "isIntroPlaying" }] : []));
6372
+ effect(() => {
6373
+ if (this.isIntroPlaying())
6374
+ return;
6375
+ const mood = this.chatMonitorService.currentMood();
5561
6376
  const card = this.agentCard();
5562
- if (card?.assets?.motion?.url) {
5563
- return 'video';
6377
+ if (mood && card?.assets?.motions) {
6378
+ const currentMood = mood[0];
6379
+ const motion = card.assets.motions.find((m) => m.metadata?.moodState === currentMood);
6380
+ if (motion?.url !== this.currentMotionUrl()) {
6381
+ this.isVideoReady.set(false);
6382
+ this.currentMotionUrl.set(motion.url);
6383
+ }
5564
6384
  }
5565
- return 'image';
5566
- }, ...(ngDevMode ? [{ debugName: "mediaType" }] : []));
5567
- this.mediaUrl = computed(() => {
5568
- const card = this.agentCard();
5569
- if (this.mediaType() === 'video') {
5570
- return card?.assets?.motion?.url;
6385
+ });
6386
+ effect(() => {
6387
+ const isConversationActive = this.chatMonitorService.isConversationActive();
6388
+ if (isConversationActive) {
6389
+ this.showInfoLayer.set(false);
5571
6390
  }
5572
- return card?.assets?.image?.url || 'assets/defaults/images/default_conversation_card.webp';
5573
- }, ...(ngDevMode ? [{ debugName: "mediaUrl" }] : []));
6391
+ });
5574
6392
  }
5575
6393
  async ngOnInit() {
5576
6394
  const id = this.route.snapshot.paramMap.get('id');
@@ -5590,21 +6408,98 @@ class DcAgentCardDetailsComponent {
5590
6408
  card.conversationSettings = {};
5591
6409
  }
5592
6410
  this.agentCard.set(card);
6411
+ if (card.assets?.motion?.url) {
6412
+ this.isVideoReady.set(false);
6413
+ this.currentMotionUrl.set(card.assets.motion.url);
6414
+ }
6415
+ else {
6416
+ this.currentMotionUrl.set(undefined);
6417
+ }
6418
+ }
6419
+ transformToLanguage(agentCard, targetLang) {
6420
+ const translation = agentCard.characterCard?.data?.langTranslation?.[targetLang];
6421
+ const cardTranslated = { ...agentCard };
6422
+ cardTranslated.characterCard.data = { ...agentCard.characterCard?.data, ...translation };
6423
+ cardTranslated.lang = targetLang;
6424
+ console.log('cambiando idioma', agentCard.lang);
6425
+ const locale = LANGUAGES[targetLang].defaultLocale;
6426
+ if (!locale)
6427
+ return cardTranslated;
6428
+ const transformedMainVoice = this._transformVoice(agentCard.conversationSettings.mainVoice?.voice, locale);
6429
+ if (transformedMainVoice) {
6430
+ agentCard.conversationSettings.mainVoice.voice = transformedMainVoice;
6431
+ }
6432
+ const transformedSecondaryVoice = this._transformVoice(agentCard.conversationSettings.secondaryVoice?.voice, locale);
6433
+ if (transformedSecondaryVoice) {
6434
+ agentCard.conversationSettings.secondaryVoice.voice = transformedSecondaryVoice;
6435
+ }
6436
+ return cardTranslated;
6437
+ }
6438
+ _transformVoice(voice, locale) {
6439
+ if (!voice)
6440
+ return undefined;
6441
+ const voiceParts = voice.split('-');
6442
+ const newVoiceParts = voiceParts.slice(2);
6443
+ return [locale.replace('_', '-'), ...newVoiceParts].join('-');
5593
6444
  }
5594
6445
  startConversation() {
5595
- this.onStartConversation.emit(this.agentCard());
6446
+ const introMotion = this.agentCard()?.assets?.motions?.find((m) => m.metadata?.event === 'intro');
6447
+ if (introMotion?.url) {
6448
+ this.isIntroPlaying.set(true);
6449
+ this.isVideoReady.set(false);
6450
+ this.currentMotionUrl.set(introMotion.url);
6451
+ if (this.videoPlayer?.nativeElement) {
6452
+ this.videoPlayer.nativeElement.loop = false;
6453
+ }
6454
+ }
6455
+ else {
6456
+ this.currentMotionUrl.set(this.agentCard()?.assets?.motion?.url);
6457
+ }
6458
+ const targetLang = this.userService.getTargetLanguage();
6459
+ const translation = this.agentCard()?.characterCard?.data?.langTranslation?.[targetLang];
6460
+ if (this.agentCard()?.lang === targetLang) {
6461
+ this.onStartConversation.emit(this.agentCard());
6462
+ }
6463
+ else if (translation) {
6464
+ const transformedCard = this.transformToLanguage(this.agentCard(), targetLang);
6465
+ this.onStartConversation.emit(transformedCard);
6466
+ }
6467
+ else {
6468
+ this.onStartConversation.emit(this.agentCard());
6469
+ }
5596
6470
  }
5597
6471
  toggleInfoLayer() {
5598
6472
  this.showInfoLayer.update((value) => !value);
5599
6473
  }
6474
+ onVideoReady() {
6475
+ this.isVideoReady.set(true);
6476
+ }
6477
+ onIntroVideoEnd() {
6478
+ if (this.isIntroPlaying()) {
6479
+ this.isIntroPlaying.set(false);
6480
+ this.isVideoReady.set(false);
6481
+ this.currentMotionUrl.set(this.agentCard()?.assets?.motion?.url);
6482
+ if (this.videoPlayer?.nativeElement) {
6483
+ this.videoPlayer.nativeElement.loop = true;
6484
+ }
6485
+ }
6486
+ else {
6487
+ if (this.videoPlayer?.nativeElement) {
6488
+ this.videoPlayer.nativeElement.play();
6489
+ }
6490
+ }
6491
+ }
5600
6492
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcAgentCardDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5601
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }] }); }
6493
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: DcAgentCardDetailsComponent, isStandalone: true, selector: "dc-agent-card-details", inputs: { agentCardId: "agentCardId" }, outputs: { onStartConversation: "onStartConversation" }, viewQueries: [{ propertyName: "videoPlayer", first: true, predicate: ["videoPlayer"], descendants: true }], ngImport: i0, template: "<div style=\"display: flex; justify-content: center; align-items: center\">\n <p-card>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard()?.assets?.image?.url\" alt=\"\" [hidden]=\"isVideoReady()\" />\n @if(currentMotionUrl()) {\n <video\n #videoPlayer\n class=\"card-image\"\n [src]=\"currentMotionUrl()\"\n autoplay\n muted\n playsinline\n (loadeddata)=\"onVideoReady()\"\n [hidden]=\"!isVideoReady()\"\n (ended)=\"onIntroVideoEnd()\"></video>\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 @if(!chatMonitorService.isConversationActive()) {\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\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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$5.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }] }); }
5602
6494
  }
5603
6495
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: DcAgentCardDetailsComponent, decorators: [{
5604
6496
  type: Component,
5605
- 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"] }]
5606
- }], propDecorators: { agentCardId: [{
6497
+ 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 <img class=\"card-image\" [src]=\"agentCard()?.assets?.image?.url\" alt=\"\" [hidden]=\"isVideoReady()\" />\n @if(currentMotionUrl()) {\n <video\n #videoPlayer\n class=\"card-image\"\n [src]=\"currentMotionUrl()\"\n autoplay\n muted\n playsinline\n (loadeddata)=\"onVideoReady()\"\n [hidden]=\"!isVideoReady()\"\n (ended)=\"onIntroVideoEnd()\"></video>\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 @if(!chatMonitorService.isConversationActive()) {\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\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"] }]
6498
+ }], ctorParameters: () => [], propDecorators: { agentCardId: [{
5607
6499
  type: Input
6500
+ }], videoPlayer: [{
6501
+ type: ViewChild,
6502
+ args: ['videoPlayer']
5608
6503
  }] } });
5609
6504
 
5610
6505
  var GenerationType;
@@ -5644,7 +6539,6 @@ class CardsCreatorComponent {
5644
6539
  this.result.set(null);
5645
6540
  try {
5646
6541
  let response;
5647
- debugger;
5648
6542
  switch (options.type) {
5649
6543
  case GenerationType.GenerateConversationCard:
5650
6544
  // response = await this.agentCardsGenerationService.generateConversationCard(options);
@@ -5720,7 +6614,7 @@ class CardsCreatorComponent {
5720
6614
  }
5721
6615
  }
5722
6616
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CardsCreatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5723
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: CardsCreatorComponent, isStandalone: true, selector: "app-cards-creator", ngImport: i0, template: "<div>\n <h2 class=\"text-2xl font-bold mb-4\">Card Generation</h2>\n <p-message severity=\"secondary\"\n >Paso 1: Genearar una o varias tarjetas vacias con solo la idea, estas tiene estatus de pending. no lo cambies ser\u00E1 necesario en el paso 2.\n </p-message>\n\n <div class=\"grid\">\n <div class=\"col-12\">\n <form [formGroup]=\"cardsForm\" (ngSubmit)=\"generateCards()\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Generate Cards</h3>\n <p-message severity=\"info\">Generate one or more cards with an idea. Cards will be created with a 'pending' status.</p-message>\n\n <div class=\"field mt-4\">\n <label for=\"idea\">Idea</label>\n <input id=\"idea\" type=\"text\" pInputText formControlName=\"idea\" placeholder=\"e.g., 'Ordering food at a restaurant'\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field mt-4\">\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 [filter]=\"true\"\n formControlName=\"langCode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"\n styleClass=\"w-full\"></p-select>\n </div>\n\n <div class=\"field mt-4\">\n <label for=\"num-cards\">Number of Cards</label>\n <input id=\"num-cards\" type=\"number\" pInputText formControlName=\"numCards\" placeholder=\"e.g., '10'\" class=\"w-full\" />\n </div>\n\n <div class=\"flex flex-wrap gap-4 mt-4\">\n <div class=\"flex align-items-center\">\n <p-toggleSwitch formControlName=\"autosave\" inputId=\"autosave-switch\"></p-toggleSwitch>\n <label for=\"autosave-switch\" class=\"ml-2\"> Auto-save?</label>\n </div>\n <div class=\"flex align-items-center\">\n <p-toggleSwitch formControlName=\"doNotRepeat\" inputId=\"repeat-switch\"></p-toggleSwitch>\n <label for=\"repeat-switch\" class=\"ml-2\"> Do not repeat topics?</label>\n </div>\n </div>\n\n <div class=\"mt-4\">\n <p-button label=\"Generate Cards\" icon=\"pi pi-bolt\" type=\"submit\" [loading]=\"loading()\" [disabled]=\"cardsForm.invalid\"></p-button>\n </div>\n </div>\n </form>\n </div>\n </div>\n\n <p-divider align=\"center\" styleClass=\"my-5\">\n <span class=\"p-tag\">Maintenance</span>\n </p-divider>\n\n <!-- Maintenance Section -->\n <div class=\"grid\">\n <!-- Card Specific Maintenance -->\n <div class=\"col-12 md:col-6\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Card Specific Maintenance</h3>\n <div class=\"field\">\n <label for=\"cardId\">Card ID</label>\n <input\n id=\"cardId\"\n type=\"text\"\n pInputText\n [value]=\"cardId()\"\n (input)=\"cardId.set($any($event.target).value)\"\n placeholder=\"Enter Card ID\"\n class=\"w-full\" />\n </div>\n <div class=\"mt-4 flex gap-2\">\n <p-button label=\"Generate Image\" icon=\"pi pi-image\" (onClick)=\"generateImageForCard()\" [loading]=\"loading()\"></p-button>\n <p-button\n label=\"Generate Missing Data\"\n icon=\"pi pi-database\"\n (onClick)=\"generateMissingData()\"\n [loading]=\"loading()\"\n styleClass=\"p-button-secondary\"></p-button>\n </div>\n </div>\n </div>\n\n <!-- Batch Operations -->\n <div class=\"col-12 md:col-6\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Batch Operations</h3>\n <p>Run maintenance tasks on all pending cards.</p>\n <div class=\"mt-4 flex gap-2\">\n <p-button label=\"Complete Pending Cards\" icon=\"pi pi-check-square\" (onClick)=\"completePendingCards()\" [loading]=\"loading()\"></p-button>\n <p-button\n label=\"Generate Pending Images\"\n icon=\"pi pi-images\"\n (onClick)=\"generatePendingImages()\"\n [loading]=\"loading()\"\n styleClass=\"p-button-secondary\"></p-button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Result Section -->\n @if (result()) {\n <div class=\"col-12 mt-4\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Result</h3>\n <pre>{{ result() | json }}</pre>\n </div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$2.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$2.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i5$2.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$3.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
6617
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.1.6", type: CardsCreatorComponent, isStandalone: true, selector: "app-cards-creator", ngImport: i0, template: "<div>\n <h2 class=\"text-2xl font-bold mb-4\">Card Generation</h2>\n <p-message severity=\"secondary\"\n >Paso 1: Genearar una o varias tarjetas vacias con solo la idea, estas tiene estatus de pending. no lo cambies ser\u00E1 necesario en el paso 2.\n </p-message>\n\n <div class=\"grid\">\n <div class=\"col-12\">\n <form [formGroup]=\"cardsForm\" (ngSubmit)=\"generateCards()\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Generate Cards</h3>\n <p-message severity=\"info\">Generate one or more cards with an idea. Cards will be created with a 'pending' status.</p-message>\n\n <div class=\"field mt-4\">\n <label for=\"idea\">Idea</label>\n <input id=\"idea\" type=\"text\" pInputText formControlName=\"idea\" placeholder=\"e.g., 'Ordering food at a restaurant'\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field mt-4\">\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 [filter]=\"true\"\n formControlName=\"langCode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"\n styleClass=\"w-full\"></p-select>\n </div>\n\n <div class=\"field mt-4\">\n <label for=\"num-cards\">Number of Cards</label>\n <input id=\"num-cards\" type=\"number\" pInputText formControlName=\"numCards\" placeholder=\"e.g., '10'\" class=\"w-full\" />\n </div>\n\n <div class=\"flex flex-wrap gap-4 mt-4\">\n <div class=\"flex align-items-center\">\n <p-toggleSwitch formControlName=\"autosave\" inputId=\"autosave-switch\"></p-toggleSwitch>\n <label for=\"autosave-switch\" class=\"ml-2\"> Auto-save?</label>\n </div>\n <div class=\"flex align-items-center\">\n <p-toggleSwitch formControlName=\"doNotRepeat\" inputId=\"repeat-switch\"></p-toggleSwitch>\n <label for=\"repeat-switch\" class=\"ml-2\"> Do not repeat topics?</label>\n </div>\n </div>\n\n <div class=\"mt-4\">\n <p-button label=\"Generate Cards\" icon=\"pi pi-bolt\" type=\"submit\" [loading]=\"loading()\" [disabled]=\"cardsForm.invalid\"></p-button>\n </div>\n </div>\n </form>\n </div>\n </div>\n\n <p-divider align=\"center\" styleClass=\"my-5\">\n <span class=\"p-tag\">Maintenance</span>\n </p-divider>\n\n <!-- Maintenance Section -->\n <div class=\"grid\">\n <!-- Card Specific Maintenance -->\n <div class=\"col-12 md:col-6\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Card Specific Maintenance</h3>\n <div class=\"field\">\n <label for=\"cardId\">Card ID</label>\n <input\n id=\"cardId\"\n type=\"text\"\n pInputText\n [value]=\"cardId()\"\n (input)=\"cardId.set($any($event.target).value)\"\n placeholder=\"Enter Card ID\"\n class=\"w-full\" />\n </div>\n <div class=\"mt-4 flex gap-2\">\n <p-button label=\"Generate Image\" icon=\"pi pi-image\" (onClick)=\"generateImageForCard()\" [loading]=\"loading()\"></p-button>\n <p-button\n label=\"Generate Missing Data\"\n icon=\"pi pi-database\"\n (onClick)=\"generateMissingData()\"\n [loading]=\"loading()\"\n styleClass=\"p-button-secondary\"></p-button>\n </div>\n </div>\n </div>\n\n <!-- Batch Operations -->\n <div class=\"col-12 md:col-6\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Batch Operations</h3>\n <p>Run maintenance tasks on all pending cards.</p>\n <div class=\"mt-4 flex gap-2\">\n <p-button label=\"Complete Pending Cards\" icon=\"pi pi-check-square\" (onClick)=\"completePendingCards()\" [loading]=\"loading()\"></p-button>\n <p-button\n label=\"Generate Pending Images\"\n icon=\"pi pi-images\"\n (onClick)=\"generatePendingImages()\"\n [loading]=\"loading()\"\n styleClass=\"p-button-secondary\"></p-button>\n </div>\n </div>\n </div>\n </div>\n\n <!-- Result Section -->\n @if (result()) {\n <div class=\"col-12 mt-4\">\n <div class=\"p-panel p-4\">\n <h3 class=\"text-xl font-semibold mb-3\">Result</h3>\n <pre>{{ result() | json }}</pre>\n </div>\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$2.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$2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { 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", "buttonProps", "autofocus", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i4$1.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i6.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i3$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "panelStyle", "styleClass", "panelStyleClass", "readonly", "editable", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "filterValue", "options", "appendTo"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i3$4.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
5724
6618
  }
5725
6619
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: CardsCreatorComponent, decorators: [{
5726
6620
  type: Component,
@@ -5736,5 +6630,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
5736
6630
  * Generated bundle index. Do not edit.
5737
6631
  */
5738
6632
 
5739
- export { AGENT_CARDS_STATE_SERVICE, AIGenerationService, AgentCardListComponent, AgentCardUI, AgentCardsGenerationService, AudioService, AudioSpeed, CONVERSATION_AI_TOKEN, CardsCreatorComponent, ChatEventType, ChatMessage, ChatMessageOrchestratorComponent, ChatMonitorService, ChatRole, ConditionOperator, ConditionType, ContextEngineService, ContextType, ConversationDTO, ConversationEvents, ConversationMessagesDTO, ConversationPromptBuilderService, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationUserChatSettingsComponent, DcAgentCardDetailsComponent, DefaultAgentCardsService, DoActionTypeOptions, DynamicFlowService, DynamicFlowTaskTypeOptions, EAccountsPlatform, EAgentType, EDoActionType, EDynamicFlowTaskType, EntityThen, EntityWhatOptions, EntityWhenOptions, EvalResultStringDefinition, GlobalToolsService, MOOD_STATE_PROMPT, MessageContent, MessageContentDisplayer, MessagesStateService, ModelSelectorComponent, PopupService, SystemPromptType, TextEngineOptions, TextEngines, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, createAIModelFormGroup, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, getMoodStateLabelsAsString, markdownToHtml, matchTranscription, provideAgentCardService, removeEmojis, removeEmojisAndSpecialCharacters, removeSpecialCharacters };
6633
+ export { ACCDataGenerationComponent, AGENT_CARDS_STATE_SERVICE, AIGenerationService, AgentCardListComponent, AgentCardUI, AgentCardsGenerationService, AudioService, AudioSpeed, CONVERSATION_AI_TOKEN, CardsCreatorComponent, ChatEventType, ChatMessage, ChatMessageOrchestratorComponent, ChatMonitorService, ChatRole, ConditionOperator, ConditionType, ContextEngineService, ContextType, ConversationDTO, ConversationEvents, ConversationMessagesDTO, ConversationPromptBuilderService, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationUserChatSettingsComponent, DcAgentCardDetailsComponent, DefaultAgentCardsService, DoActionTypeOptions, DynamicFlowService, DynamicFlowTaskTypeOptions, EAccountsPlatform, EAgentType, EDoActionType, EDynamicFlowTaskType, EntityThen, EntityWhatOptions, EntityWhenOptions, EvalResultStringDefinition, GlobalToolsService, MessageContent, MessageContentDisplayer, MessagesStateService, ModelSelectorComponent, PopupService, SystemPromptType, TextEngineOptions, TextEngines, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, createAIModelFormGroup, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, getMoodStateLabelsAsString, getMoodStatePrompt, markdownToHtml, matchTranscription, provideAgentCardService, removeEmojis, removeEmojisAndSpecialCharacters, removeSpecialCharacters };
5740
6634
  //# sourceMappingURL=dataclouder-ngx-agent-cards.mjs.map