@dataclouder/ngx-agent-cards 0.2.3 → 0.2.5

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,13 +1,14 @@
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, HostBinding, untracked, ElementRef, Pipe, ChangeDetectorRef, EventEmitter, Output, viewChild } from '@angular/core';
3
3
  import * as i1 from '@dataclouder/ngx-core';
4
- import { MoodStateOptions, LANGUAGES, EntityCommunicationService, TOAST_ALERTS_TOKEN, APP_CONFIG, MoodState, AudioSpeed as AudioSpeed$1, LoadingBarService, EModelQuality, getLangDesc, AudioSpeedReverse, formatCamelCaseString, EntityBaseDetailComponent, AudioNotificationService, SUPPORTED_LANGUAGES, FormUtilsService, DcTagsFormComponent, EntityBaseFormComponent, getSupportedLanguageOptions, DcManageableFormComponent, DcLearnableFormComponent, EntityBaseListV2Component, DCFilterBarComponent, QuickTableComponent, EmptyStateComponent, EntityBaseListComponent, EntityBaseSignalFormComponent } from '@dataclouder/ngx-core';
4
+ import { MoodStateOptions, LANGUAGES, EntityCommunicationService, TOAST_ALERTS_TOKEN, APP_CONFIG, MoodState, AudioSpeed as AudioSpeed$1, LoadingBarService, EModelQuality, getLangDesc, AudioSpeedReverse, formatCamelCaseString, EntityBaseDetailComponent, AudioNotificationService, SUPPORTED_LANGUAGES, FormUtilsService, LangDescTranslation, FlagPipe, FlagImgPipe, DcTagsFormComponent, EntityBaseFormComponent, getSupportedLanguageOptions, DcManageableFormComponent, DcLearnableFormComponent, EntityBaseListV2Component, DCFilterBarComponent, QuickTableComponent, EmptyStateComponent, EntityBaseSignalFormComponent } from '@dataclouder/ngx-core';
5
5
  import { UserService } from '@dataclouder/ngx-users';
6
6
  import { AiWhisperService, TtsService, NgxAiServicesService, GeneratedAssetsService, VoiceSelectorComponent } from '@dataclouder/ngx-ai-services';
7
+ import { FirebaseAuthService } from '@dataclouder/ngx-auth';
8
+ import { firstValueFrom, Subject, fromEvent, filter, BehaviorSubject, Subscription } from 'rxjs';
7
9
  import * as i2$1 from '@angular/common';
8
10
  import { DOCUMENT, CommonModule, KeyValuePipe, NgTemplateOutlet, DatePipe, SlicePipe, JsonPipe } from '@angular/common';
9
11
  import { nanoid } from 'nanoid';
10
- import { Subject, fromEvent, filter, BehaviorSubject } from 'rxjs';
11
12
  import { DynamicDialogRef, DynamicDialogConfig, DialogService, DynamicDialogModule } from 'primeng/dynamicdialog';
12
13
  import * as i2 from 'primeng/button';
13
14
  import { ButtonModule } from 'primeng/button';
@@ -15,12 +16,12 @@ import { MarkdownComponent } from 'ngx-markdown';
15
16
  import * as Plyr from 'plyr';
16
17
  import * as i2$2 from 'primeng/progressbar';
17
18
  import { ProgressBarModule } from 'primeng/progressbar';
18
- import * as i3 from 'primeng/tooltip';
19
+ import * as i5 from 'primeng/tooltip';
19
20
  import { TooltipModule } from 'primeng/tooltip';
20
21
  import * as i1$1 from '@angular/forms';
21
22
  import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule, FormArray, FormGroup, Validators } from '@angular/forms';
22
23
  import { DCMicComponent } from '@dataclouder/ngx-mic';
23
- import * as i3$1 from 'primeng/textarea';
24
+ import * as i3 from 'primeng/textarea';
24
25
  import { TextareaModule } from 'primeng/textarea';
25
26
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
26
27
  import { map, takeUntil } from 'rxjs/operators';
@@ -30,54 +31,54 @@ import * as i1$2 from 'primeng/skeleton';
30
31
  import { SkeletonModule, Skeleton } from 'primeng/skeleton';
31
32
  import * as i4 from 'primeng/checkbox';
32
33
  import { CheckboxModule } from 'primeng/checkbox';
33
- import * as i1$6 from 'primeng/slider';
34
+ import * as i4$1 from 'primeng/slider';
34
35
  import { SliderModule } from 'primeng/slider';
35
- import * as i3$2 from 'primeng/radiobutton';
36
+ import * as i3$1 from 'primeng/radiobutton';
36
37
  import { RadioButtonModule } from 'primeng/radiobutton';
37
38
  import { RatingModule } from 'primeng/rating';
38
- import * as i1$5 from 'primeng/table';
39
+ import * as i1$4 from 'primeng/table';
39
40
  import { TableModule } from 'primeng/table';
40
41
  import { BadgeModule } from 'primeng/badge';
41
- import * as i5 from 'primeng/select';
42
+ import * as i6 from 'primeng/select';
42
43
  import { SelectModule } from 'primeng/select';
43
- import * as i1$3 from 'primeng/divider';
44
+ import * as i2$4 from 'primeng/divider';
44
45
  import { DividerModule } from 'primeng/divider';
45
- import * as i2$5 from 'primeng/tabs';
46
+ import * as i2$6 from 'primeng/tabs';
46
47
  import { TabsModule } from 'primeng/tabs';
47
48
  import { ChipModule } from 'primeng/chip';
48
- import * as i1$4 from 'primeng/tag';
49
+ import * as i1$3 from 'primeng/tag';
49
50
  import { TagModule } from 'primeng/tag';
50
- import * as i2$4 from 'primeng/api';
51
- import * as i2$6 from 'primeng/card';
51
+ import * as i2$5 from 'primeng/api';
52
+ import * as i2$7 from 'primeng/card';
52
53
  import { CardModule } from 'primeng/card';
53
- import * as i3$3 from 'primeng/progressspinner';
54
+ import * as i3$2 from 'primeng/progressspinner';
54
55
  import { ProgressSpinnerModule } from 'primeng/progressspinner';
55
56
  import * as i5$1 from 'primeng/dialog';
56
57
  import { DialogModule } from 'primeng/dialog';
57
- import * as i3$5 from 'primeng/inputtext';
58
+ import * as i3$4 from 'primeng/inputtext';
58
59
  import { InputTextModule } from 'primeng/inputtext';
59
- import * as i3$4 from 'primeng/message';
60
+ import * as i3$3 from 'primeng/message';
60
61
  import { MessageModule } from 'primeng/message';
61
- import * as i7 from 'primeng/accordion';
62
+ import * as i8 from 'primeng/accordion';
62
63
  import { AccordionModule } from 'primeng/accordion';
63
64
  import { AspectRatioOptions, SafeHtmlPipe, AssetsLoaderComponent, SimpleUploaderComponent, ResolutionType, AspectType, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
64
- import * as i1$7 from '@angular/router';
65
+ import * as i1$5 from '@angular/router';
65
66
  import { ActivatedRoute, Router, RouterModule } from '@angular/router';
66
- import * as i4$1 from 'primeng/toggleswitch';
67
+ import * as i4$2 from 'primeng/toggleswitch';
67
68
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
68
69
  import * as i5$2 from 'primeng/inputnumber';
69
70
  import { InputNumberModule } from 'primeng/inputnumber';
70
71
  import { ToggleButtonModule } from 'primeng/togglebutton';
71
- import * as i3$6 from 'primeng/inputgroup';
72
+ import * as i3$5 from 'primeng/inputgroup';
72
73
  import { InputGroupModule } from 'primeng/inputgroup';
73
- import * as i4$2 from 'primeng/inputgroupaddon';
74
+ import * as i4$3 from 'primeng/inputgroupaddon';
74
75
  import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
75
- import * as i4$3 from 'primeng/paginator';
76
+ import * as i4$4 from 'primeng/paginator';
76
77
  import { PaginatorModule } from 'primeng/paginator';
77
- import * as i3$7 from 'primeng/speeddial';
78
+ import * as i3$6 from 'primeng/speeddial';
78
79
  import { SpeedDialModule } from 'primeng/speeddial';
79
80
  import { isEmpty } from 'es-toolkit/compat';
80
- import * as i3$8 from '@ngx-translate/core';
81
+ import * as i3$7 from '@ngx-translate/core';
81
82
  import { TranslateModule } from '@ngx-translate/core';
82
83
  import { form, required, submit, FormField } from '@angular/forms/signals';
83
84
 
@@ -213,6 +214,18 @@ var EAgentType;
213
214
  EAgentType["Social"] = "social";
214
215
  EAgentType["Character"] = "character";
215
216
  })(EAgentType || (EAgentType = {}));
217
+ var AgenticEngine;
218
+ (function (AgenticEngine) {
219
+ AgenticEngine["SERVER_SDK"] = "server_sdk";
220
+ AgenticEngine["OS_HERMES"] = "os_hermes";
221
+ })(AgenticEngine || (AgenticEngine = {}));
222
+ var AgenticPattern;
223
+ (function (AgenticPattern) {
224
+ AgenticPattern["DIRECT"] = "direct";
225
+ AgenticPattern["REACT"] = "react";
226
+ AgenticPattern["REFLECTION"] = "reflection";
227
+ AgenticPattern["PLAN_AND_EXECUTE"] = "plan_execute"; // Planificar sub-tareas -> Ejecutar
228
+ })(AgenticPattern || (AgenticPattern = {}));
216
229
  // Creo que esta @Deprecated porque feedback ahora es text.
217
230
  const EvalResultStringDefinition = `
218
231
  interface SimpleEvalResult {
@@ -1310,9 +1323,6 @@ class ConversationPromptBuilderService {
1310
1323
  // New field for all greetings.
1311
1324
  gretting = this.sampleSize(characterCard.data.greetings, 1)[0];
1312
1325
  }
1313
- else {
1314
- gretting = this.selectOneRandomGreeting(characterCard.data.first_mes, characterCard.data.greetings);
1315
- }
1316
1326
  chat.push({ role: ChatRole.System, content: '[Start a new Chat]' });
1317
1327
  if (gretting) {
1318
1328
  chat.push({ role: ChatRole.Assistant, content: gretting });
@@ -1462,6 +1472,7 @@ class DefaultAgentCardsService extends EntityCommunicationService {
1462
1472
  this.toastService = inject(TOAST_ALERTS_TOKEN);
1463
1473
  this.appConfig = inject(APP_CONFIG);
1464
1474
  this.whisperService = inject(AiWhisperService);
1475
+ this.fbAuthService = inject(FirebaseAuthService, { optional: true });
1465
1476
  this.randomSeed = Math.floor(Math.random() * 100000);
1466
1477
  }
1467
1478
  partialUpdateAgentCard(agentCard) {
@@ -1494,6 +1505,66 @@ class DefaultAgentCardsService extends EntityCommunicationService {
1494
1505
  }
1495
1506
  return response;
1496
1507
  }
1508
+ async *callChatCompletionStream(conversation) {
1509
+ let messages = conversation.messages.map((m) => ({ content: m.content, role: m.role }));
1510
+ const conversationFiltered = { ...conversation, messages };
1511
+ const host = this.appConfig?.aiServicesUrl || this.appConfig?.backendNodeUrl || '';
1512
+ const baseUrl = host.endsWith('/') ? host.slice(0, -1) : host;
1513
+ const service = `api/ai-services/gemini/chat/stream`;
1514
+ const url = `${baseUrl}/${service}`;
1515
+ let token = null;
1516
+ if (this.fbAuthService) {
1517
+ try {
1518
+ token = (await firstValueFrom(this.fbAuthService.tokenId$));
1519
+ }
1520
+ catch (err) {
1521
+ console.warn('Failed to retrieve Firebase ID token:', err);
1522
+ }
1523
+ }
1524
+ const response = await fetch(url, {
1525
+ method: 'POST',
1526
+ headers: {
1527
+ 'Content-Type': 'application/json',
1528
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
1529
+ },
1530
+ body: JSON.stringify(conversationFiltered),
1531
+ });
1532
+ if (!response.ok || !response.body) {
1533
+ throw new Error(`HTTP error: ${response.status} ${response.statusText}`);
1534
+ }
1535
+ const reader = response.body.getReader();
1536
+ const decoder = new TextDecoder();
1537
+ let buffer = '';
1538
+ try {
1539
+ while (true) {
1540
+ const { done, value } = await reader.read();
1541
+ if (done)
1542
+ break;
1543
+ buffer += decoder.decode(value, { stream: true });
1544
+ const lines = buffer.split('\n');
1545
+ buffer = lines.pop() ?? '';
1546
+ for (const line of lines) {
1547
+ if (!line.startsWith('data: '))
1548
+ continue;
1549
+ const data = line.slice(6).trim();
1550
+ if (data === '[DONE]')
1551
+ return;
1552
+ try {
1553
+ const parsed = JSON.parse(data);
1554
+ if (parsed.content) {
1555
+ yield parsed.content;
1556
+ }
1557
+ }
1558
+ catch {
1559
+ // ignore malformed lines
1560
+ }
1561
+ }
1562
+ }
1563
+ }
1564
+ finally {
1565
+ reader.cancel();
1566
+ }
1567
+ }
1497
1568
  async filterConversationCards(filters) {
1498
1569
  return this.httpService.post(`api/${this.serviceName}/query`, filters, 'primary');
1499
1570
  }
@@ -1812,6 +1883,8 @@ class ConversationFlowStateService {
1812
1883
  this.currentMood = computed(() => this.flowState().moodState.value, ...(ngDevMode ? [{ debugName: "currentMood" }] : /* istanbul ignore next */ []));
1813
1884
  this.moodUpdated = new Subject();
1814
1885
  this.moodUpdated$ = this.moodUpdated.asObservable();
1886
+ this.goalEvaluationUpdated = new Subject();
1887
+ this.goalEvaluationUpdated$ = this.goalEvaluationUpdated.asObservable();
1815
1888
  }
1816
1889
  /**
1817
1890
  * @description
@@ -1831,6 +1904,12 @@ class ConversationFlowStateService {
1831
1904
  if (newState.moodState?.value) {
1832
1905
  this.moodUpdated.next(newState.moodState.value);
1833
1906
  }
1907
+ if (newState.goal && newState.goal.deltaPoints !== undefined && newState.goal.deltaPoints !== 0) {
1908
+ this.goalEvaluationUpdated.next({
1909
+ deltaPoints: newState.goal.deltaPoints,
1910
+ feedback: newState.goal.feedback,
1911
+ });
1912
+ }
1834
1913
  }
1835
1914
  /**
1836
1915
  * @description
@@ -1931,6 +2010,7 @@ class DynamicFlowService {
1931
2010
  this.messagesStateService = inject(MessagesStateService);
1932
2011
  this.conversationFlowStateService = inject(ConversationFlowStateService);
1933
2012
  this.agentCardStateService = inject(AgentCardStateService);
2013
+ this.userService = inject(UserService);
1934
2014
  /** Derived from AgentCardStateService — single source of truth for the conversation flow config. */
1935
2015
  this.conversationFlowConfig = this.agentCardStateService.conversationFlow$;
1936
2016
  /**
@@ -1988,11 +2068,15 @@ class DynamicFlowService {
1988
2068
  updateStateFromAI(aiResponse) {
1989
2069
  const currentState = this.flowState();
1990
2070
  const updatedState = { ...aiResponse };
2071
+ let previousGoalValue;
2072
+ let newGoalValueComputed;
1991
2073
  // Goal: Add deltaPoints to current value
1992
2074
  if (aiResponse.goal && typeof aiResponse.goal.deltaPoints === 'number') {
1993
2075
  const currentGoalValue = currentState.goal?.value || 0;
1994
2076
  const deltaPoints = aiResponse.goal.deltaPoints;
1995
2077
  const newGoalValue = Math.min(100, Math.max(0, currentGoalValue + deltaPoints));
2078
+ previousGoalValue = currentGoalValue;
2079
+ newGoalValueComputed = newGoalValue;
1996
2080
  updatedState.goal = {
1997
2081
  ...currentState.goal,
1998
2082
  value: newGoalValue,
@@ -2015,8 +2099,33 @@ class DynamicFlowService {
2015
2099
  updatedState.challenges = mergedChallenges;
2016
2100
  }
2017
2101
  this.conversationFlowStateService.updateState(updatedState);
2102
+ this.attachFlowEvaluationToLastUserMessage(aiResponse, previousGoalValue, newGoalValueComputed);
2018
2103
  this.syncMoodToLatestMessage();
2019
2104
  }
2105
+ attachFlowEvaluationToLastUserMessage(aiResponse, previousGoalValue, newGoalValue) {
2106
+ const messages = this.messagesStateService.getMessagesSignal()();
2107
+ const lastUserMessage = messages.slice().reverse().find((m) => m.role === ChatRole.User);
2108
+ if (!lastUserMessage?.messageId)
2109
+ return;
2110
+ const flowEvaluation = { evaluatedAt: new Date().toISOString() };
2111
+ if (aiResponse.goal) {
2112
+ flowEvaluation['goal'] = {
2113
+ deltaPoints: aiResponse.goal.deltaPoints,
2114
+ feedback: aiResponse.goal.feedback,
2115
+ previousValue: previousGoalValue,
2116
+ newValue: newGoalValue,
2117
+ };
2118
+ }
2119
+ if (aiResponse.challenges?.length) {
2120
+ flowEvaluation['challenges'] = aiResponse.challenges;
2121
+ }
2122
+ if (aiResponse.moodState) {
2123
+ flowEvaluation['moodState'] = aiResponse.moodState;
2124
+ }
2125
+ this.messagesStateService.updateMessage(lastUserMessage.messageId, {
2126
+ evaluation: { ...(lastUserMessage.evaluation || {}), flow: flowEvaluation },
2127
+ });
2128
+ }
2020
2129
  syncMoodToLatestMessage(messageId) {
2021
2130
  const currentState = this.flowState();
2022
2131
  if (!currentState?.moodState?.value)
@@ -2058,9 +2167,21 @@ class DynamicFlowService {
2058
2167
  */
2059
2168
  generateSystemPromptForFlow(messages) {
2060
2169
  const config = this.agentCardStateService.conversationFlow$();
2061
- const currentState = this.flowState();
2062
2170
  if (!config)
2063
2171
  return '';
2172
+ debugger;
2173
+ const hasGoal = config.goal?.enabled && !config.goal.disableFeature;
2174
+ const currentState = this.flowState();
2175
+ const completedChallengeNames = new Set((currentState.challenges || []).filter((c) => c.value === true).map((c) => c.name));
2176
+ const activeChallenges = (config.challenges || []).filter((c) => c.enabled && !completedChallengeNames.has(c.name));
2177
+ const hasChallenges = activeChallenges.length > 0;
2178
+ const hasMood = config.moodState?.enabled;
2179
+ if (!hasGoal && !hasChallenges && !hasMood) {
2180
+ return '';
2181
+ }
2182
+ // I do this as test, lets see how it goes. so ai is not influenced by previous delta points value.
2183
+ currentState.goal.deltaPoints = 0;
2184
+ // debugger;
2064
2185
  let prompt = `You are an AI managing the conversation flow. Your task is to update the current state based on the conversation context.
2065
2186
 
2066
2187
  Current State:
@@ -2071,7 +2192,7 @@ Instructions per Component:
2071
2192
  if (config.goal?.enabled) {
2072
2193
  prompt += `
2073
2194
  - Goal: ${config.goal.task}
2074
- Evaluate the interaction and provide an integer value for "deltaPoints" representing points to ADD or SUBTRACT from the current goal value (usually 1-15 points), and "feedback" explaining why.
2195
+ Evaluate the interaction and provide an integer value for "deltaPoints" representing points to ADD or SUBTRACT from the current goal value (don't Subtract more than 10 points), and "feedback" explaining why you took this decision.
2075
2196
  `;
2076
2197
  }
2077
2198
  if (config.challenges && config.challenges.length > 0) {
@@ -2110,6 +2231,14 @@ Mark challenges as completed (true) ONLY if the user has satisfied the condition
2110
2231
  - Mood: Detect the agent's mood based on the conversation.
2111
2232
  Stricly use one of these Detectable states: ${detectableStates.join(', ')}
2112
2233
  If really not posible to fit into one then use neutral.
2234
+ `;
2235
+ }
2236
+ const userContext = this.userService.getUserDataInformation();
2237
+ if (userContext) {
2238
+ prompt += `
2239
+ - User Context: Take into consideration the user profile when evaluating.
2240
+ ${userContext}
2241
+ IMPORTANT: If the user level is basic or beginner, be extremely generous and encouraging when assigning deltaPoints. Do not demotivate them with negative points for minor mistakes. Focus on positive reinforcement.
2113
2242
  `;
2114
2243
  }
2115
2244
  const lastMessages = messages.slice(-4);
@@ -2119,10 +2248,10 @@ Context (Last Messages):
2119
2248
  ${lastMessages.map((m) => `${m.role}: ${m.content}`).join('\n')}
2120
2249
 
2121
2250
  Instructions:
2122
- 1. Analyze the context, that is a partial conversation, evaluate the last user interaction only.
2123
- 2. Update the goal state: provide "deltaPoints" and "feedback" (less than 80 words) inside the goal object.
2251
+ 1. Analyze the context, that is a partial conversation, last 4 dialogs (2 user, 2 agent).
2252
+ 2. Update the goal state: focous on last user message, provide "deltaPoints" and "feedback" (less than 80 words) inside the goal object.
2124
2253
  3. Mark challenges as completed if met.
2125
- 4. Update the mood state.
2254
+ 4. Update the mood state according to last agent message.
2126
2255
  5. Return ONLY a valid JSON object matching the IConversationFlowState structure with updated values.
2127
2256
  Do not return markdown formatting.
2128
2257
  `;
@@ -3112,6 +3241,110 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
3112
3241
  }]
3113
3242
  }], ctorParameters: () => [] });
3114
3243
 
3244
+ class SentenceStreamParser {
3245
+ constructor() {
3246
+ this.buffer = '';
3247
+ this.currentTag = 'p';
3248
+ }
3249
+ append(chunk) {
3250
+ this.buffer += chunk;
3251
+ return this.parse(false);
3252
+ }
3253
+ finish() {
3254
+ return this.parse(true);
3255
+ }
3256
+ parse(isFinished) {
3257
+ const completed = [];
3258
+ let i = 0;
3259
+ while (i < this.buffer.length) {
3260
+ // Check for code tag `
3261
+ if (this.buffer[i] === '`') {
3262
+ this.currentTag = this.currentTag === 'code' ? 'p' : 'code';
3263
+ this.buffer = this.buffer.substring(i + 1);
3264
+ i = 0;
3265
+ continue;
3266
+ }
3267
+ // Check for asterisks
3268
+ if (this.buffer[i] === '*') {
3269
+ let count = 0;
3270
+ while (i + count < this.buffer.length && this.buffer[i + count] === '*') {
3271
+ count++;
3272
+ }
3273
+ if (count === 3) {
3274
+ this.currentTag = this.currentTag === 'em_strong' ? 'p' : 'em_strong';
3275
+ }
3276
+ else if (count === 2) {
3277
+ this.currentTag = this.currentTag === 'strong' ? 'p' : 'strong';
3278
+ }
3279
+ else if (count === 1) {
3280
+ this.currentTag = this.currentTag === 'em' ? 'p' : 'em';
3281
+ }
3282
+ this.buffer = this.buffer.substring(i + count);
3283
+ i = 0;
3284
+ continue;
3285
+ }
3286
+ // Find next sentence boundary or tag token or end
3287
+ let boundaryIndex = -1;
3288
+ let nextTagIndex = -1;
3289
+ for (let j = i; j < this.buffer.length; j++) {
3290
+ const char = this.buffer[j];
3291
+ if (char === '*' || char === '`') {
3292
+ nextTagIndex = j;
3293
+ break;
3294
+ }
3295
+ if (char === '.' || char === '?' || char === '!' || char === '\n') {
3296
+ const nextChar = j + 1 < this.buffer.length ? this.buffer[j + 1] : '';
3297
+ const isFollowedByWhitespace = !nextChar || nextChar === ' ' || nextChar === '\n' || nextChar === '\r';
3298
+ let isAbbreviation = false;
3299
+ if (char === '.') {
3300
+ const wordStart = this.buffer.substring(0, j).lastIndexOf(' ') + 1;
3301
+ const word = this.buffer.substring(wordStart, j).toLowerCase();
3302
+ const abbreviations = ['mr', 'mrs', 'ms', 'dr', 'sr', 'sra', 'srta', 'etc', 'eg', 'ie'];
3303
+ if (abbreviations.includes(word)) {
3304
+ isAbbreviation = true;
3305
+ }
3306
+ }
3307
+ if (isFollowedByWhitespace && !isAbbreviation) {
3308
+ boundaryIndex = j;
3309
+ break;
3310
+ }
3311
+ }
3312
+ }
3313
+ if (boundaryIndex !== -1) {
3314
+ const sentenceText = this.buffer.substring(i, boundaryIndex + 1);
3315
+ completed.push({
3316
+ text: sentenceText,
3317
+ tag: this.currentTag
3318
+ });
3319
+ this.buffer = this.buffer.substring(boundaryIndex + 1);
3320
+ i = 0;
3321
+ }
3322
+ else if (nextTagIndex !== -1) {
3323
+ const segmentText = this.buffer.substring(i, nextTagIndex);
3324
+ if (segmentText) {
3325
+ completed.push({
3326
+ text: segmentText,
3327
+ tag: this.currentTag
3328
+ });
3329
+ }
3330
+ this.buffer = this.buffer.substring(nextTagIndex);
3331
+ i = 0;
3332
+ }
3333
+ else {
3334
+ break;
3335
+ }
3336
+ }
3337
+ if (isFinished && this.buffer) {
3338
+ completed.push({
3339
+ text: this.buffer,
3340
+ tag: this.currentTag
3341
+ });
3342
+ this.buffer = '';
3343
+ }
3344
+ return completed.filter(c => c.text !== '');
3345
+ }
3346
+ }
3347
+
3115
3348
  const DEFUALT_USER_AVATAR = 'defaults/avatar_user.jpg';
3116
3349
  const DEFUALT_ASSISTANT_AVATAR = 'defaults/avatar_ai.webp';
3117
3350
  class ConversationService {
@@ -3189,7 +3422,14 @@ class ConversationService {
3189
3422
  return agentFlow;
3190
3423
  }
3191
3424
  const mergedFlow = { ...agentFlow };
3192
- mergedFlow.goal = agentFlow?.goal?.task ? agentFlow.goal : defaultFlow.goal;
3425
+ debugger;
3426
+ if (agentFlow?.goal?.disableFeature ||
3427
+ (agentFlow?.goal?.task && agentFlow?.goal?.enabled === false)) {
3428
+ mergedFlow.goal = agentFlow.goal;
3429
+ }
3430
+ else {
3431
+ mergedFlow.goal = agentFlow?.goal?.task ? agentFlow.goal : defaultFlow.goal;
3432
+ }
3193
3433
  mergedFlow.dynamicConditions = agentFlow?.dynamicConditions?.length > 0 ? agentFlow.dynamicConditions : defaultFlow.dynamicConditions;
3194
3434
  mergedFlow.challenges = agentFlow?.challenges?.length > 0 ? agentFlow.challenges : defaultFlow.challenges;
3195
3435
  mergedFlow.tools = agentFlow?.tools?.length > 0 ? agentFlow.tools : defaultFlow.tools;
@@ -3204,7 +3444,8 @@ class ConversationService {
3204
3444
  if (!mergedFlow.triggerTasks) {
3205
3445
  mergedFlow.triggerTasks = {};
3206
3446
  }
3207
- if (agentFlow?.triggerTasks?.onUserMessage?.disableFeature) {
3447
+ if (agentFlow?.triggerTasks?.onUserMessage?.disableFeature ||
3448
+ (agentFlow?.triggerTasks?.onUserMessage?.task && agentFlow?.triggerTasks?.onUserMessage?.enabled === false)) {
3208
3449
  // just setting to null disables de feature, this is is card demands.
3209
3450
  mergedFlow.triggerTasks.onUserMessage = null;
3210
3451
  }
@@ -3213,7 +3454,8 @@ class ConversationService {
3213
3454
  ? agentFlow.triggerTasks.onUserMessage
3214
3455
  : defaultFlow.triggerTasks?.onUserMessage;
3215
3456
  }
3216
- if (agentFlow?.triggerTasks?.onAssistantMessage?.disableFeature) {
3457
+ if (agentFlow?.triggerTasks?.onAssistantMessage?.disableFeature ||
3458
+ (agentFlow?.triggerTasks?.onAssistantMessage?.task && agentFlow?.triggerTasks?.onAssistantMessage?.enabled === false)) {
3217
3459
  mergedFlow.triggerTasks.onAssistantMessage = null;
3218
3460
  }
3219
3461
  else {
@@ -3361,6 +3603,14 @@ class ConversationService {
3361
3603
  type: 'rp-conversation',
3362
3604
  };
3363
3605
  this.isThinkingSignal.set(true);
3606
+ if (conversationSettings.streamResponses) {
3607
+ return this.handleStreamingResponse(conversation, conversationSettings);
3608
+ }
3609
+ else {
3610
+ return this.handleBlockingResponse(conversation, conversationSettings);
3611
+ }
3612
+ }
3613
+ async handleBlockingResponse(conversation, conversationSettings) {
3364
3614
  const response = await this.defaultAgentCardService.callChatCompletion(conversation);
3365
3615
  if (!response) {
3366
3616
  console.error('No message returned from AI, is your service working?');
@@ -3372,10 +3622,116 @@ class ConversationService {
3372
3622
  this.isThinkingSignal.set(false);
3373
3623
  // Run Dynamic Flow Evaluations
3374
3624
  this.dynamicFlowTaskService.triggerAfterAssistantMessage(newMessage); // Not waiting should be parallel.
3375
- // Persist conversation Not for now, only when conversation is finish.
3376
- // this.persistCurrentSession();
3377
3625
  return newMessage.messageId;
3378
3626
  }
3627
+ async handleStreamingResponse(conversation, conversationSettings) {
3628
+ const messageId = nanoid();
3629
+ const mainVoice = conversationSettings?.mainVoice?.voice || conversationSettings?.tts?.voice;
3630
+ const assistantVoice = this.messageProcessingService.getVoice(mainVoice);
3631
+ const secondaryVoice = conversationSettings?.secondaryVoice?.voice || conversationSettings?.tts?.secondaryVoice || 'en-US-News-L';
3632
+ let assistantMessage = {
3633
+ messageId,
3634
+ role: ChatRole.Assistant,
3635
+ content: '',
3636
+ text: '',
3637
+ voice: assistantVoice,
3638
+ imgUrl: conversationSettings.avatarImages?.assistant || undefined,
3639
+ multiMessages: [],
3640
+ isLoading: true,
3641
+ };
3642
+ this.messagesStateService.addMessage(assistantMessage);
3643
+ let stream;
3644
+ try {
3645
+ stream = this.defaultAgentCardService.callChatCompletionStream(conversation);
3646
+ }
3647
+ catch (error) {
3648
+ this.isThinkingSignal.set(false);
3649
+ this.messagesStateService.updateMessage(messageId, {
3650
+ isLoading: false,
3651
+ content: 'Error: Failed to initiate stream connection.',
3652
+ });
3653
+ throw error;
3654
+ }
3655
+ const parser = new SentenceStreamParser();
3656
+ let accumulatedText = '';
3657
+ let isFirstChunk = true;
3658
+ try {
3659
+ for await (const chunk of stream) {
3660
+ if (isFirstChunk) {
3661
+ isFirstChunk = false;
3662
+ this.isThinkingSignal.set(false);
3663
+ assistantMessage = {
3664
+ ...assistantMessage,
3665
+ isLoading: false,
3666
+ };
3667
+ }
3668
+ accumulatedText += chunk;
3669
+ // Feed the chunk into the sentence parser
3670
+ const parsedChunks = parser.append(chunk);
3671
+ if (parsedChunks.length > 0) {
3672
+ const newSegments = parsedChunks.map((c) => {
3673
+ const isItalics = c.tag === 'em';
3674
+ const voice = isItalics ? secondaryVoice : assistantVoice;
3675
+ return {
3676
+ voice,
3677
+ content: this.messageProcessingService.wrapContentWithTag(c.text, c.tag),
3678
+ text: c.text,
3679
+ audioUrl: null,
3680
+ audioPromise: null,
3681
+ audioStatus: 'pending',
3682
+ tag: c.tag,
3683
+ messageId,
3684
+ };
3685
+ });
3686
+ assistantMessage.multiMessages = [
3687
+ ...(assistantMessage.multiMessages || []),
3688
+ ...newSegments,
3689
+ ];
3690
+ }
3691
+ assistantMessage.content = accumulatedText;
3692
+ assistantMessage.text = accumulatedText;
3693
+ this.messagesStateService.updateMessage(messageId, { ...assistantMessage });
3694
+ }
3695
+ // Finish the parser stream
3696
+ const finalParsedChunks = parser.finish();
3697
+ if (finalParsedChunks.length > 0) {
3698
+ const newSegments = finalParsedChunks.map((c) => {
3699
+ const isItalics = c.tag === 'em';
3700
+ const voice = isItalics ? secondaryVoice : assistantVoice;
3701
+ return {
3702
+ voice,
3703
+ content: this.messageProcessingService.wrapContentWithTag(c.text, c.tag),
3704
+ text: c.text,
3705
+ audioUrl: null,
3706
+ audioPromise: null,
3707
+ audioStatus: 'pending',
3708
+ tag: c.tag,
3709
+ messageId,
3710
+ };
3711
+ });
3712
+ assistantMessage.multiMessages = [
3713
+ ...(assistantMessage.multiMessages || []),
3714
+ ...newSegments,
3715
+ ];
3716
+ }
3717
+ assistantMessage.content = accumulatedText;
3718
+ assistantMessage.text = accumulatedText;
3719
+ assistantMessage.isLoading = false;
3720
+ this.messagesStateService.updateMessage(messageId, { ...assistantMessage });
3721
+ }
3722
+ catch (err) {
3723
+ console.error('Error during chat completion stream:', err);
3724
+ this.isThinkingSignal.set(false);
3725
+ this.messagesStateService.updateMessage(messageId, {
3726
+ isLoading: false,
3727
+ content: 'Error: Connection lost during stream generation.',
3728
+ });
3729
+ throw err;
3730
+ }
3731
+ // Run Dynamic Flow Evaluations
3732
+ this.dynamicFlowTaskService.triggerAfterAssistantMessage(assistantMessage);
3733
+ return messageId;
3734
+ }
3379
3735
  /**
3380
3736
  * Persists the current conversation session to the database.
3381
3737
  * @param status The status of the session.
@@ -4025,11 +4381,11 @@ class ChatHeaderComponent {
4025
4381
  this.viewModeChanged.emit(newMode);
4026
4382
  }
4027
4383
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatHeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4028
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ChatHeaderComponent, isStandalone: true, selector: "dc-chat-header", inputs: { alternativeConversation: "alternativeConversation", agentCard: "agentCard", viewMode: "viewMode" }, outputs: { restartConversationEvent: "restartConversationEvent", showInfoEvent: "showInfoEvent", settingsClickEvent: "settingsClickEvent", viewModeChanged: "viewModeChanged" }, ngImport: i0, template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.name) {\n {{ agentCard.name }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.name }} </span>\n }\n\n <div class=\"header-controls\">\n @if (userService.isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n </div>\n\n }\n\n <div>\n <p-button\n variant=\"text\"\n [raised]=\"true\"\n [icon]=\"viewMode === 'chat' ? 'pi pi-tablet' : 'pi pi-comments'\"\n (click)=\"toggleViewMode()\"\n [pTooltip]=\"viewMode === 'chat' ? 'Modo Inmersivo' : 'Modo Chat'\"\n tooltipPosition=\"bottom\">\n </p-button>\n </div>\n\n <div>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
4384
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ChatHeaderComponent, isStandalone: true, selector: "dc-chat-header", inputs: { alternativeConversation: "alternativeConversation", agentCard: "agentCard", viewMode: "viewMode" }, outputs: { restartConversationEvent: "restartConversationEvent", showInfoEvent: "showInfoEvent", settingsClickEvent: "settingsClickEvent", viewModeChanged: "viewModeChanged" }, ngImport: i0, template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.name) {\n {{ agentCard.name }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.name }} </span>\n }\n\n <div class=\"header-controls\">\n @if (userService.isAdmin()){\n <div>\n <p-button variant=\"text\" [style]=\"{'color': 'rgb(255, 149, 0)'}\" [raised]=\"true\" icon=\"pi pi-key\" (click)=\"showInfo()\" pTooltip=\"Debug Info\" tooltipPosition=\"left\"></p-button>\n </div>\n }\n\n <div>\n <p-button\n variant=\"text\"\n [raised]=\"true\"\n [icon]=\"viewMode === 'chat' ? 'pi pi-tablet' : 'pi pi-comments'\"\n (click)=\"toggleViewMode()\"\n [pTooltip]=\"viewMode === 'chat' ? 'Modo Inmersivo' : 'Modo Chat'\"\n tooltipPosition=\"left\">\n </p-button>\n </div>\n\n <div>\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-cog\" (click)=\"settingsClick()\" pTooltip=\"Ajustes\" tooltipPosition=\"left\"></p-button>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
4029
4385
  }
4030
4386
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatHeaderComponent, decorators: [{
4031
4387
  type: Component,
4032
- args: [{ selector: 'dc-chat-header', standalone: true, imports: [ButtonModule, TooltipModule], template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.name) {\n {{ agentCard.name }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.name }} </span>\n }\n\n <div class=\"header-controls\">\n @if (userService.isAdmin()){\n <div class=\"admin-controls\">\n <i style=\"color: rgb(255, 149, 0)\" class=\"pi pi-key\"></i>\n\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-id-card\" (click)=\"showInfo()\"></p-button>\n </div>\n\n }\n\n <div>\n <p-button\n variant=\"text\"\n [raised]=\"true\"\n [icon]=\"viewMode === 'chat' ? 'pi pi-tablet' : 'pi pi-comments'\"\n (click)=\"toggleViewMode()\"\n [pTooltip]=\"viewMode === 'chat' ? 'Modo Inmersivo' : 'Modo Chat'\"\n tooltipPosition=\"bottom\">\n </p-button>\n </div>\n\n <div>\n <span class=\"pointer\" (click)=\"settingsClick()\"> \u2699\uFE0F </span>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}.admin-controls{background-color:bisque;padding:2px 5px;border-radius:4px}\n"] }]
4388
+ args: [{ selector: 'dc-chat-header', standalone: true, imports: [ButtonModule, TooltipModule], template: "<div class=\"chat-header\">\n <span class=\"pointer\" (click)=\"restartConversation()\">\n @if (agentCard?.name) {\n {{ agentCard.name }}\n } @else { Reiniciar conversaci\u00F3n }\n </span>\n\n @for (conversation of alternativeConversation; track conversation._id) {\n <span class=\"pointer\" (click)=\"restartConversation(conversation)\"> {{ conversation.name }} </span>\n }\n\n <div class=\"header-controls\">\n @if (userService.isAdmin()){\n <div>\n <p-button variant=\"text\" [style]=\"{'color': 'rgb(255, 149, 0)'}\" [raised]=\"true\" icon=\"pi pi-key\" (click)=\"showInfo()\" pTooltip=\"Debug Info\" tooltipPosition=\"left\"></p-button>\n </div>\n }\n\n <div>\n <p-button\n variant=\"text\"\n [raised]=\"true\"\n [icon]=\"viewMode === 'chat' ? 'pi pi-tablet' : 'pi pi-comments'\"\n (click)=\"toggleViewMode()\"\n [pTooltip]=\"viewMode === 'chat' ? 'Modo Inmersivo' : 'Modo Chat'\"\n tooltipPosition=\"left\">\n </p-button>\n </div>\n\n <div>\n <p-button variant=\"text\" [raised]=\"true\" icon=\"pi pi-cog\" (click)=\"settingsClick()\" pTooltip=\"Ajustes\" tooltipPosition=\"left\"></p-button>\n </div>\n </div>\n</div>\n", styles: [".chat-header{display:flex;justify-content:space-between;align-items:center;width:100%}.pointer{cursor:pointer}.header-controls{font-size:large;display:flex;justify-content:space-between;gap:10px}\n"] }]
4033
4389
  }], propDecorators: { alternativeConversation: [{
4034
4390
  type: Input
4035
4391
  }], agentCard: [{
@@ -4167,7 +4523,7 @@ class ChatFooterComponent {
4167
4523
  }
4168
4524
  }
4169
4525
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4170
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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: DCMicComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <dc-mic (onFinished)=\"handleAudioRecorded($event)\" (onCanceled)=\"handleAudioCanceled()\"></dc-mic>\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(challenges().length > 0) {\n <div class=\"challenges-container\">\n @for(challenge of challenges(); track challenge.name) {\n <span class=\"challenge-emoji\" [title]=\"challenge.description\" [style.opacity]=\"challenge.completed ? 1 : 0.3\">\n {{ challenge.emoji }}\n </span>\n }\n </div>\n } @if(agentCardStateService.conversationFlow$()?.goal?.enabled) {\n\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n }\n</div>\n", styles: [".progress-input{position:relative;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}.progress-input .challenges-container{position:absolute;top:-20px;left:100px;border-radius:20px;padding:2px 10px;z-index:10;display:flex;gap:8px;justify-content:flex-start}.progress-input .challenges-container .challenge-emoji{font-size:1.2rem;transition:opacity .3s ease,transform .3s ease;cursor:help}.progress-input .challenges-container .challenge-emoji:hover{transform:scale(1.2)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$2.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$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "maxRecordingTime", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished", "onCanceled"] }] }); }
4526
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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: DCMicComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <dc-mic (onFinished)=\"handleAudioRecorded($event)\" (onCanceled)=\"handleAudioCanceled()\"></dc-mic>\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(challenges().length > 0) {\n <div class=\"challenges-container\">\n @for(challenge of challenges(); track challenge.name) {\n <span class=\"challenge-emoji\" [title]=\"challenge.description\" [style.opacity]=\"challenge.completed ? 1 : 0.3\">\n {{ challenge.emoji }}\n </span>\n }\n </div>\n } @if(agentCardStateService.conversationFlow$()?.goal?.enabled) {\n\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n }\n</div>\n", styles: [".progress-input{position:relative;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}.progress-input .challenges-container{position:absolute;top:-20px;left:100px;border-radius:20px;padding:2px 10px;z-index:10;display:flex;gap:8px;justify-content:flex-start}.progress-input .challenges-container .challenge-emoji{font-size:1.2rem;transition:opacity .3s ease,transform .3s ease;cursor:help}.progress-input .challenges-container .challenge-emoji:hover{transform:scale(1.2)}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2$2.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: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCMicComponent, selector: "dc-mic", inputs: ["targetOrBase", "micSettings", "maxRecordingTime", "isDone"], outputs: ["onInterpretedText", "onFinishedRecognition", "onFinished", "onCanceled"] }] }); }
4171
4527
  }
4172
4528
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatFooterComponent, decorators: [{
4173
4529
  type: Component,
@@ -4867,11 +5223,11 @@ class ChatMessageComponent {
4867
5223
  console.log(res);
4868
5224
  }
4869
5225
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4870
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 || '/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]=\"messageContentArray()\" [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\" [pTooltip]=\"getMoodLabel(tag)\" tooltipPosition=\"top\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: var(--chat-user-message-bg);--assistant-message-bg: var(--chat-assistant-message-bg);--user-text-color: white;--assistant-text-color: #ffffff;--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:#d8d8d8;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$3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5226
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 || '/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]=\"messageContentArray()\" [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\" [pTooltip]=\"getMoodLabel(tag)\" tooltipPosition=\"top\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: var(--chat-user-message-bg);--assistant-message-bg: var(--chat-assistant-message-bg);--user-text-color: white;--assistant-text-color: #ffffff;--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(2px);backdrop-filter:blur(2px)}.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:#d8d8d8;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$3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], outputs: ["onShow", "onHide"] }, { 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4871
5227
  }
4872
5228
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ChatMessageComponent, decorators: [{
4873
5229
  type: Component,
4874
- args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, ChatMessageOrchestratorComponent, PopoverModule, TooltipModule], 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 || '/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]=\"messageContentArray()\" [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\" [pTooltip]=\"getMoodLabel(tag)\" tooltipPosition=\"top\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: var(--chat-user-message-bg);--assistant-message-bg: var(--chat-assistant-message-bg);--user-text-color: white;--assistant-text-color: #ffffff;--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:#d8d8d8;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"] }]
5230
+ args: [{ selector: 'dc-chat-message', standalone: true, imports: [CommonModule, ChatMessageOrchestratorComponent, PopoverModule, TooltipModule], 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 || '/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]=\"messageContentArray()\" [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\" [pTooltip]=\"getMoodLabel(tag)\" tooltipPosition=\"top\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [":host{--user-message-bg: var(--chat-user-message-bg);--assistant-message-bg: var(--chat-assistant-message-bg);--user-text-color: white;--assistant-text-color: #ffffff;--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(2px);backdrop-filter:blur(2px)}.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:#d8d8d8;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"] }]
4875
5231
  }], propDecorators: { chatMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatMessage", required: true }] }], chatUserSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatUserSettings", required: false }] }] } });
4876
5232
 
4877
5233
  class ChatMessagesListComponent {
@@ -5009,7 +5365,7 @@ class ModelSelectorComponent {
5009
5365
  }
5010
5366
  }
5011
5367
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ModelSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5012
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 \">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 \">Provider</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"providersOptions\"\n [formControl]=\"modelForm.controls.provider\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n }\n\n <!-- <div style=\"display: flex; gap: 10px\" [formGroup]=\"modelForm\">\n <div class=\"space\">\n <p-radioButton value=\"groq\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Groq</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openai\" formControlName=\"provider\"></p-radioButton>\n <label>Open AI</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"google\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Google</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openrouter\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Open Router</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"ollama\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Ollama</label>\n </div>\n </div> -->\n\n <!-- <b>Modelo: </b>\n <span pTooltip=\"Modelo Seleccionado\">{{ modelForm.controls.modelName.value }}</span>\n @if (modelForm.controls.provider.value) { @if(isLoadingModels) {\n <p-skeleton height=\"200px\" width=\"100%\"></p-skeleton>\n } @else {\n <p-table [value]=\"modelnames\" stripedRows [size]=\"'small'\" [paginator]=\"true\" [rows]=\"12\" [formGroup]=\"modelForm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th></th>\n <th>Name</th>\n <th>$$Prompt M</th>\n <th>$$Completion M</th>\n <th>$$Cost 90/10 M</th>\n <th>Created</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-model>\n <tr [pTooltip]=\"model.description | truncate : 200\" tooltipPosition=\"top\">\n <td><p-radioButton [value]=\"model.id\" formControlName=\"modelName\"></p-radioButton></td>\n <td>{{ model.name || model.id }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.completion * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 * 0.9 + +model.pricing?.completion * 1000000 * 0.1 | number : '1.2-2' }}</td>\n <td>{{ model.created * 1000 | date : 'dd/MM/yyyy' }}</td>\n </tr>\n </ng-template>\n </p-table>\n } }\n</div> -->\n</div>\n", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5368
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 \">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 \">Provider</label>\n <p-select\n id=\"modelQuality\"\n [options]=\"providersOptions\"\n [formControl]=\"modelForm.controls.provider\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-select>\n </div>\n }\n\n <!-- <div style=\"display: flex; gap: 10px\" [formGroup]=\"modelForm\">\n <div class=\"space\">\n <p-radioButton value=\"groq\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Groq</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openai\" formControlName=\"provider\"></p-radioButton>\n <label>Open AI</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"google\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Google</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"openrouter\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Open Router</label>\n </div>\n\n <div class=\"space\">\n <p-radioButton value=\"ollama\" formControlName=\"provider\"></p-radioButton>\n <label class=\"space\">Ollama</label>\n </div>\n </div> -->\n\n <!-- <b>Modelo: </b>\n <span pTooltip=\"Modelo Seleccionado\">{{ modelForm.controls.modelName.value }}</span>\n @if (modelForm.controls.provider.value) { @if(isLoadingModels) {\n <p-skeleton height=\"200px\" width=\"100%\"></p-skeleton>\n } @else {\n <p-table [value]=\"modelnames\" stripedRows [size]=\"'small'\" [paginator]=\"true\" [rows]=\"12\" [formGroup]=\"modelForm\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th></th>\n <th>Name</th>\n <th>$$Prompt M</th>\n <th>$$Completion M</th>\n <th>$$Cost 90/10 M</th>\n <th>Created</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-model>\n <tr [pTooltip]=\"model.description | truncate : 200\" tooltipPosition=\"top\">\n <td><p-radioButton [value]=\"model.id\" formControlName=\"modelName\"></p-radioButton></td>\n <td>{{ model.name || model.id }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.completion * 1000000 | number : '1.2-2' }}</td>\n <td>${{ +model.pricing?.prompt * 1000000 * 0.9 + +model.pricing?.completion * 1000000 * 0.1 | number : '1.2-2' }}</td>\n <td>{{ model.created * 1000 | date : 'dd/MM/yyyy' }}</td>\n </tr>\n </ng-template>\n </p-table>\n } }\n</div> -->\n</div>\n", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5013
5369
  }
5014
5370
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ModelSelectorComponent, decorators: [{
5015
5371
  type: Component,
@@ -5095,7 +5451,7 @@ class DCConversationUserChatSettingsComponent {
5095
5451
  }
5096
5452
  }
5097
5453
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCConversationUserChatSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5098
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"saveConversations\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.saveConversations.disabled\">Guardar conversaciones</span>\n <br />\n <small>Si marcas esta casilla, las conversaciones se guardar\u00E1n en tu historial.</small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"multilingualHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.multilingualHearing.disabled\">Escuchar en varios idiomas</span>\n <br />\n <small>El asistente podr\u00E1 entender y responder en varios idiomas, pero puede confundir idiomas si no lo pronuncias claramente.</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;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;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}button:last-child{background-color:#6c757d}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }] }); }
5454
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"saveConversations\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.saveConversations.disabled\">Guardar conversaciones</span>\n <br />\n <small>Si marcas esta casilla, las conversaciones se guardar\u00E1n en tu historial.</small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"multilingualHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.multilingualHearing.disabled\">Escuchar en varios idiomas</span>\n <br />\n <small>El asistente podr\u00E1 entender y responder en varios idiomas, pero puede confundir idiomas si no lo pronuncias claramente.</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;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;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}button:last-child{background-color:#6c757d}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }] }); }
5099
5455
  }
5100
5456
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCConversationUserChatSettingsComponent, decorators: [{
5101
5457
  type: Component,
@@ -5300,17 +5656,25 @@ class DcImmersiveChatComponent {
5300
5656
  }, ...(ngDevMode ? [{ debugName: "lastMessage" }] : /* istanbul ignore next */ []));
5301
5657
  this.isThinking = this.conversationService.isThinking();
5302
5658
  this.orchestratedMessageId = null;
5659
+ this.orchestratedSegmentsCount = 0;
5303
5660
  // Effect to start orchestration for new assistant messages
5304
5661
  effect(() => {
5305
5662
  const messages = this.messagesStateService.getMessagesSignal()();
5306
5663
  if (messages.length > 0) {
5307
5664
  const lastMsg = messages[messages.length - 1];
5308
- if (lastMsg.role === ChatRole.Assistant && lastMsg.messageId !== this.orchestratedMessageId) {
5309
- this.orchestratedMessageId = lastMsg.messageId || null;
5310
- if (lastMsg.multiMessages && lastMsg.multiMessages.length > 0) {
5311
- // If the last message is assistant and has multiMessages, start orchestration
5312
- // Note: MessageOrchestrationService handles sequential playback and prevents redundant starts
5313
- this.orchestration.startOrchestration(lastMsg.multiMessages, lastMsg.role);
5665
+ if (lastMsg.role === ChatRole.Assistant) {
5666
+ const isNewMessage = lastMsg.messageId !== this.orchestratedMessageId;
5667
+ const segmentCount = lastMsg.multiMessages?.length || 0;
5668
+ const hasNewSegments = segmentCount > this.orchestratedSegmentsCount;
5669
+ if (isNewMessage || hasNewSegments) {
5670
+ if (isNewMessage) {
5671
+ this.orchestratedMessageId = lastMsg.messageId || null;
5672
+ this.orchestratedSegmentsCount = 0;
5673
+ }
5674
+ if (lastMsg.multiMessages && lastMsg.multiMessages.length > 0) {
5675
+ this.orchestratedSegmentsCount = lastMsg.multiMessages.length;
5676
+ this.orchestration.startOrchestration(lastMsg.multiMessages, lastMsg.role);
5677
+ }
5314
5678
  }
5315
5679
  }
5316
5680
  }
@@ -5419,6 +5783,76 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
5419
5783
  `, styles: [":host{height:100%}.immersive-container{display:flex;flex-direction:column;height:100%;width:100%;background:radial-gradient(circle at center,#1e1e2d33,#0a0a0f1a);padding:2rem;box-sizing:border-box;overflow:hidden}.hud-section{flex:1;display:flex;flex-direction:column;align-items:center;width:100%;overflow-y:auto;min-height:0;padding:1rem 1.5rem;scrollbar-width:none}.hud-section::-webkit-scrollbar{display:none}.hud-section>div{margin:auto 0;width:100%;display:flex;flex-direction:column}.mic-section{flex-shrink:0;position:relative;height:180px;display:flex;align-items:center;justify-content:center;margin-top:1rem;padding-bottom:2rem}.mic-ripple-glow{position:absolute;width:140px;height:140px;border-radius:50%;background:radial-gradient(circle,rgba(64,156,255,.2) 0%,transparent 70%);animation:breathe 4s ease-in-out infinite;z-index:0}.mic-section.is-talking .mic-ripple-glow{background:radial-gradient(circle,rgba(64,255,156,.3) 0%,transparent 70%);animation:pulse-active 1.5s ease-in-out infinite}.mic-section dc-mic{z-index:1;transform:scale(1.5);transition:transform .3s cubic-bezier(.175,.885,.32,1.275)}.mic-section dc-mic:hover{transform:scale(1.6)}.active-sentence-hud{max-width:1000px;width:100%;transition:all .5s cubic-bezier(.4,0,.2,1);text-shadow:0 10px 30px rgba(0,0,0,.5);animation:fadeIn .8s ease-out}.active-sentence-hud ::ng-deep .audio-text-sync-container{background:transparent!important;padding:0!important;justify-content:center}.active-sentence-hud ::ng-deep .play-button{display:none!important}.active-sentence-hud ::ng-deep .text-content{font-size:clamp(1.8rem,6vw,3.5rem);font-weight:700;text-align:center;line-height:1.2;color:#ffffffe6;margin:0;letter-spacing:-.02em}.active-sentence-hud ::ng-deep .highlight{background:transparent!important;color:#fff;text-shadow:0 0 20px rgba(255,255,255,.8),0 0 40px rgba(64,156,255,.4);filter:brightness(1.2)}.user-talking-indicator,.idle-indicator,.last-message-hud,.thinking-indicator{font-size:1.8rem;color:#fff;opacity:.7;font-weight:300;text-align:center;max-width:800px;line-height:1.4}.thinking-indicator{animation:pulse-thinking 2s infinite ease-in-out}@keyframes pulse-thinking{0%,to{opacity:.5;transform:scale(.98)}50%{opacity:.9;transform:scale(1.02)}}.idle-indicator p{background:linear-gradient(90deg,transparent,rgba(255,255,255,.1),transparent);padding:1rem 2rem;border-radius:50px}@keyframes breathe{0%,to{transform:scale(1);opacity:.2}50%{transform:scale(1.2);opacity:.4}}@keyframes pulse-active{0%{transform:scale(1);opacity:.5;box-shadow:0 0 #40ff9c66}70%{transform:scale(1.5);opacity:0;box-shadow:0 0 0 40px transparent}to{transform:scale(1);opacity:0}}@keyframes fadeIn{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}\n"] }]
5420
5784
  }], ctorParameters: () => [], propDecorators: { micSettings: [{ type: i0.Input, args: [{ isSignal: true, alias: "micSettings", required: false }] }] } });
5421
5785
 
5786
+ class PolitoNotificationComponent {
5787
+ constructor() {
5788
+ this.flowStateService = inject(ConversationFlowStateService);
5789
+ this.agentCardStateService = inject(AgentCardStateService);
5790
+ this.notification = signal(null, ...(ngDevMode ? [{ debugName: "notification" }] : /* istanbul ignore next */ []));
5791
+ this.isHiding = signal(false, ...(ngDevMode ? [{ debugName: "isHiding" }] : /* istanbul ignore next */ []));
5792
+ this.subscription = new Subscription();
5793
+ }
5794
+ ngOnInit() {
5795
+ this.subscription.add(this.flowStateService.goalEvaluationUpdated$.subscribe((evalData) => {
5796
+ if (evalData.deltaPoints !== undefined && evalData.deltaPoints !== 0) {
5797
+ this.showNotification(evalData.deltaPoints, evalData.feedback || '');
5798
+ }
5799
+ }));
5800
+ }
5801
+ ngOnDestroy() {
5802
+ this.subscription.unsubscribe();
5803
+ this.clearTimeouts();
5804
+ }
5805
+ showNotification(points, feedback) {
5806
+ // Clear any pending timeouts to restart timing on new updates
5807
+ this.clearTimeouts();
5808
+ this.isHiding.set(false);
5809
+ this.notification.set({ points, feedback });
5810
+ // Transition out starts after 4.5 seconds
5811
+ this.hideTimeout = setTimeout(() => {
5812
+ this.isHiding.set(true);
5813
+ // Wait for CSS fade-out animation (400ms) to complete before removing element
5814
+ this.animTimeout = setTimeout(() => {
5815
+ this.notification.set(null);
5816
+ this.isHiding.set(false);
5817
+ }, 400);
5818
+ }, 4500);
5819
+ }
5820
+ clearTimeouts() {
5821
+ if (this.hideTimeout) {
5822
+ clearTimeout(this.hideTimeout);
5823
+ this.hideTimeout = null;
5824
+ }
5825
+ if (this.animTimeout) {
5826
+ clearTimeout(this.animTimeout);
5827
+ this.animTimeout = null;
5828
+ }
5829
+ }
5830
+ getPointsText(points) {
5831
+ const lang = this.agentCardStateService.agentCard$()?.lang || 'en';
5832
+ const isEs = lang.toLowerCase().startsWith('es');
5833
+ if (points >= 0) {
5834
+ return `+${points} ${isEs ? 'Puntos' : 'Points'}!`;
5835
+ }
5836
+ else {
5837
+ return `${points} ${isEs ? 'Puntos' : 'Points'}`;
5838
+ }
5839
+ }
5840
+ getFeatherPointsText(points) {
5841
+ if (points >= 0) {
5842
+ return `+${points}`;
5843
+ }
5844
+ else {
5845
+ return `${points}`;
5846
+ }
5847
+ }
5848
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PolitoNotificationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5849
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: PolitoNotificationComponent, isStandalone: true, selector: "dc-polito-notification", ngImport: i0, template: "@if (notification()) {\n <div class=\"polito-notification-wrapper\" [class.hiding]=\"isHiding()\">\n <div class=\"polito-card\">\n <!-- Polito Avatar (Salmon Flamingo) -->\n <div class=\"polito-avatar-container\">\n <svg viewBox=\"0 0 100 100\" class=\"polito-avatar-svg\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- Background circle soft glow -->\n <circle cx=\"50\" cy=\"50\" r=\"46\" fill=\"url(#bgGrad)\" />\n \n <!-- Flamingo Neck & Head -->\n <path d=\"M 42,82 C 42,57 52,47 62,42 C 72,37 77,27 72,17 C 67,7 52,10 47,22 C 44,28 45,34 42,37 C 39,40 32,37 27,40 C 22,42 20,47 24,50 C 28,52 34,47 40,47\" \n fill=\"none\" \n stroke=\"url(#flamingoGrad)\" \n stroke-width=\"12\" \n stroke-linecap=\"round\" \n stroke-linejoin=\"round\"/>\n \n <!-- Beak -->\n <path d=\"M 24,40 C 21,42 19,45 21,48 C 23,50 26,49 28,47 Z\" fill=\"#1C1917\"/>\n <path d=\"M 28,47 C 30,45 33,44 33,42 C 31,42 29,43 28,44\" fill=\"#FFFFFF\"/>\n \n <!-- Eye -->\n <circle cx=\"59\" cy=\"18\" r=\"2.5\" fill=\"#1C1917\"/>\n \n <!-- Cheek Blush -->\n <circle cx=\"63\" cy=\"24\" r=\"4.5\" fill=\"#FF5252\" opacity=\"0.45\"/>\n \n <defs>\n <linearGradient id=\"bgGrad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFE4E6\" />\n <stop offset=\"100%\" stop-color=\"#FECDD3\" />\n </linearGradient>\n <linearGradient id=\"flamingoGrad\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#F43F5E\" />\n <stop offset=\"50%\" stop-color=\"#FDA4AF\" />\n <stop offset=\"100%\" stop-color=\"#FFE4E6\" />\n </linearGradient>\n </defs>\n </svg>\n </div>\n\n <!-- Content Area -->\n <div class=\"polito-content\">\n <div class=\"polito-header\">\n <span class=\"polito-name\">Polito</span>\n \n <!-- Points Badge -->\n <div class=\"polito-badge\" [class.negative]=\"notification()!.points < 0\">\n <!-- Salmon Feather Icon -->\n <svg viewBox=\"0 0 24 24\" class=\"feather-svg\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19.5 4.5C18.5 3.5 16 3 13 4.5C10 6 7.5 9 6.5 11C5.5 13 4.5 16 4 19.5C5.5 19 8.5 18 10.5 17C12.5 16 15.5 13.5 17 10.5C18.5 7.5 18 5 19.5 4.5Z\" \n fill=\"url(#featherBadgeGrad)\" />\n <path d=\"M4 19.5C5.5 18.5 8.5 14.5 13 10.5\" \n stroke=\"url(#featherLineGrad)\" \n stroke-width=\"1.5\" \n stroke-linecap=\"round\" />\n <defs>\n <linearGradient id=\"featherBadgeGrad\" x1=\"4\" y1=\"19.5\" x2=\"19.5\" y2=\"4.5\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#FDA4AF\" />\n <stop offset=\"100%\" stop-color=\"#E11D48\" />\n </linearGradient>\n <linearGradient id=\"featherLineGrad\" x1=\"4\" y1=\"19.5\" x2=\"13\" y2=\"10.5\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#FFE4E6\" />\n <stop offset=\"100%\" stop-color=\"#F43F5E\" />\n </linearGradient>\n </defs>\n </svg>\n <span class=\"points-text\">{{ getPointsText(notification()!.points) }}</span>\n </div>\n </div>\n\n <!-- Speech bubble/feedback -->\n @if (notification()!.feedback) {\n <div class=\"polito-speech-bubble\">\n <p>{{ notification()!.feedback }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Falling Feather Animation Overlay -->\n <div class=\"polito-falling-feather-container\" [class.negative]=\"notification()!.points < 0\">\n <div class=\"feather-wrapper-sway\">\n <svg class=\"falling-feather-svg\" viewBox=\"0 0 100 100\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <!-- Positive gradient: beautiful pink-rose -->\n <linearGradient id=\"featherGradPos\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#F43F5E\" stop-opacity=\"0.85\" />\n <stop offset=\"50%\" stop-color=\"#FDA4AF\" stop-opacity=\"0.9\" />\n <stop offset=\"100%\" stop-color=\"#FFE4E6\" stop-opacity=\"0.95\" />\n </linearGradient>\n <!-- Negative gradient: cool grey/blue -->\n <linearGradient id=\"featherGradNeg\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#6B7280\" stop-opacity=\"0.85\" />\n <stop offset=\"50%\" stop-color=\"#9CA3AF\" stop-opacity=\"0.9\" />\n <stop offset=\"100%\" stop-color=\"#E5E7EB\" stop-opacity=\"0.95\" />\n </linearGradient>\n <!-- Rachis/spine line gradient -->\n <linearGradient id=\"rachisGrad\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0.8\" />\n <stop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0.2\" />\n </linearGradient>\n </defs>\n\n <!-- Main feather shape (Vane) -->\n <path d=\"M 50 90 C 40 85, 20 75, 20 50 C 20 30, 42 20, 50 10 C 50 10, 47 30, 45 45 C 43 60, 46 75, 50 90 Z\" \n fill=\"url(#featherGradPos)\" class=\"feather-vane-pos\" />\n <path d=\"M 50 90 C 60 85, 80 75, 80 50 C 80 30, 58 20, 50 10 C 50 10, 53 30, 55 45 C 57 60, 54 75, 50 90 Z\" \n fill=\"url(#featherGradPos)\" class=\"feather-vane-pos\" />\n\n <path d=\"M 50 90 C 40 85, 20 75, 20 50 C 20 30, 42 20, 50 10 C 50 10, 47 30, 45 45 C 43 60, 46 75, 50 90 Z\" \n fill=\"url(#featherGradNeg)\" class=\"feather-vane-neg\" />\n <path d=\"M 50 90 C 60 85, 80 75, 80 50 C 80 30, 58 20, 50 10 C 50 10, 53 30, 55 45 C 57 60, 54 75, 50 90 Z\" \n fill=\"url(#featherGradNeg)\" class=\"feather-vane-neg\" />\n\n <!-- Rachis/spine (the middle stem) -->\n <path d=\"M 50 92 L 50 10\" stroke=\"url(#rachisGrad)\" stroke-width=\"2.5\" stroke-linecap=\"round\" />\n\n <!-- Fine barb lines for feather texture -->\n <path d=\"M 50 75 Q 35 70, 25 65\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 60 Q 32 55, 22 45\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 45 Q 35 38, 28 28\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n \n <path d=\"M 50 75 Q 65 70, 75 65\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 60 Q 68 55, 78 45\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 45 Q 65 38, 72 28\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n </svg>\n <div class=\"falling-feather-points\">\n {{ getFeatherPointsText(notification()!.points) }}\n </div>\n </div>\n </div>\n}\n", styles: ["@keyframes bomp-in{0%{transform:scale(.4) translateY(40px);opacity:0}50%{transform:scale(1.08) translateY(-8px)}75%{transform:scale(.96) translateY(3px)}to{transform:scale(1) translateY(0);opacity:1}}@keyframes bomp-out{0%{transform:scale(1) translateY(0);opacity:1}to{transform:scale(.85) translateY(20px);opacity:0}}.polito-notification-wrapper{position:absolute;bottom:80px;right:16px;z-index:999;max-width:320px;width:calc(100% - 32px);pointer-events:none;display:flex;flex-direction:column;animation:bomp-in .45s cubic-bezier(.34,1.56,.64,1) forwards}.polito-notification-wrapper.hiding{animation:bomp-out .35s cubic-bezier(.25,1,.5,1) forwards}.polito-card{pointer-events:auto;display:flex;gap:12px;padding:14px 16px;border-radius:20px;background:#ffffffd9;backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);border:1px solid rgba(255,255,255,.45);box-shadow:0 10px 30px -5px #f43f5e1a,0 20px 40px -10px #00000014,0 1px 3px #0000000a;transition:transform .2s ease,box-shadow .2s ease}.polito-card:hover{transform:translateY(-2px);box-shadow:0 12px 35px -5px #f43f5e26,0 22px 45px -10px #0000001a,0 1px 4px #0000000a}.polito-avatar-container{flex-shrink:0;width:44px;height:44px;border-radius:50%;overflow:hidden;box-shadow:0 4px 12px #f43f5e33;border:2px solid #ffffff}.polito-avatar-svg{width:100%;height:100%;display:block}.polito-content{flex:1;display:flex;flex-direction:column}.polito-header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px}.polito-name{font-weight:700;font-size:.95rem;color:#1c1917;letter-spacing:-.2px}.polito-badge{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border-radius:12px;background:#fee4e6b3;border:1px solid rgba(251,113,133,.3);color:#e11d48;font-size:.78rem;font-weight:700}.polito-badge .feather-svg{width:14px;height:14px;flex-shrink:0}.polito-badge.negative{background:#f5f5f7b3;border-color:#0000001a;color:#4b5563}.polito-speech-bubble{position:relative;margin-top:6px;padding:8px 12px;border-radius:12px;background:#fff;border:1px solid rgba(229,231,235,.8);box-shadow:0 4px 12px #00000008}.polito-speech-bubble p{margin:0;font-size:.82rem;line-height:1.35;color:#4b5563;font-weight:450}.polito-speech-bubble:before{content:\"\";position:absolute;top:12px;left:-6px;width:10px;height:10px;background:#fff;border-left:1px solid rgba(229,231,235,.8);border-bottom:1px solid rgba(229,231,235,.8);transform:rotate(45deg)}@media(prefers-color-scheme:dark){.polito-card{background:#1e1e24d9;border-color:#ffffff1a;box-shadow:0 10px 30px -5px #f43f5e26,0 20px 40px -10px #0006,0 1px 3px #0000004d}.polito-card:hover{box-shadow:0 12px 35px -5px #f43f5e33,0 22px 45px -10px #00000080,0 1px 4px #0000004d}.polito-name{color:#f5f5f7}.polito-badge{background:#f43f5e26;border-color:#f43f5e4d;color:#fda4af}.polito-badge.negative{background:#ffffff0d;border-color:#ffffff1a;color:#9ca3af}.polito-speech-bubble{background:#27272a;border-color:#ffffff0f;box-shadow:0 4px 12px #0003}.polito-speech-bubble p{color:#d1d5db}.polito-speech-bubble:before{background:#27272a;border-left-color:#ffffff0f;border-bottom-color:#ffffff0f}.polito-avatar-container{border-color:#27272a}}@media(max-width:480px){.polito-notification-wrapper{right:8px;bottom:72px;width:calc(100% - 16px);max-width:none}}@keyframes feather-fall{0%{transform:translateY(-100px);opacity:0}12%{opacity:1}85%{opacity:1}to{transform:translateY(75vh);opacity:0}}@keyframes feather-sway{0%,to{transform:translate(-35px) rotate(-16deg)}50%{transform:translate(35px) rotate(16deg)}}.polito-falling-feather-container{position:absolute;top:0;right:120px;width:90px;height:90px;pointer-events:none;z-index:1000;animation:feather-fall 4.2s cubic-bezier(.33,1,.68,1) forwards}.polito-falling-feather-container .falling-feather-svg{width:100%;height:100%;filter:drop-shadow(0 6px 12px rgba(244,63,94,.25))}.polito-falling-feather-container .feather-vane-pos{display:block}.polito-falling-feather-container .feather-vane-neg{display:none}.polito-falling-feather-container .feather-wrapper-sway{position:relative;width:100%;height:100%;animation:feather-sway 2.2s ease-in-out infinite}.polito-falling-feather-container .falling-feather-points{position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);font-size:1.4rem;font-weight:900;color:#fff;letter-spacing:-.5px;text-shadow:0 2px 5px rgba(0,0,0,.3),-2px -2px 0 #e11d48,2px -2px 0 #e11d48,-2px 2px 0 #e11d48,2px 2px 0 #e11d48;white-space:nowrap;-webkit-user-select:none;user-select:none}.polito-falling-feather-container.negative .falling-feather-svg{filter:drop-shadow(0 6px 12px rgba(107,114,128,.25))}.polito-falling-feather-container.negative .feather-vane-pos{display:none}.polito-falling-feather-container.negative .feather-vane-neg{display:block}.polito-falling-feather-container.negative .falling-feather-points{text-shadow:0 2px 5px rgba(0,0,0,.3),-2px -2px 0 #4b5563,2px -2px 0 #4b5563,-2px 2px 0 #4b5563,2px 2px 0 #4b5563}@media(prefers-color-scheme:dark){.polito-falling-feather-container .falling-feather-svg{filter:drop-shadow(0 8px 16px rgba(244,63,94,.35))}.polito-falling-feather-container.negative .falling-feather-svg{filter:drop-shadow(0 8px 16px rgba(0,0,0,.4))}}@media(max-width:480px){.polito-falling-feather-container{right:auto;left:calc(50% - 45px)}@keyframes mobile-feather-sway{0%,to{transform:translate(-25px) rotate(-12deg)}50%{transform:translate(25px) rotate(12deg)}}.polito-falling-feather-container .feather-wrapper-sway{animation-name:mobile-feather-sway}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5850
+ }
5851
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PolitoNotificationComponent, decorators: [{
5852
+ type: Component,
5853
+ args: [{ selector: 'dc-polito-notification', standalone: true, imports: [CommonModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (notification()) {\n <div class=\"polito-notification-wrapper\" [class.hiding]=\"isHiding()\">\n <div class=\"polito-card\">\n <!-- Polito Avatar (Salmon Flamingo) -->\n <div class=\"polito-avatar-container\">\n <svg viewBox=\"0 0 100 100\" class=\"polito-avatar-svg\" xmlns=\"http://www.w3.org/2000/svg\">\n <!-- Background circle soft glow -->\n <circle cx=\"50\" cy=\"50\" r=\"46\" fill=\"url(#bgGrad)\" />\n \n <!-- Flamingo Neck & Head -->\n <path d=\"M 42,82 C 42,57 52,47 62,42 C 72,37 77,27 72,17 C 67,7 52,10 47,22 C 44,28 45,34 42,37 C 39,40 32,37 27,40 C 22,42 20,47 24,50 C 28,52 34,47 40,47\" \n fill=\"none\" \n stroke=\"url(#flamingoGrad)\" \n stroke-width=\"12\" \n stroke-linecap=\"round\" \n stroke-linejoin=\"round\"/>\n \n <!-- Beak -->\n <path d=\"M 24,40 C 21,42 19,45 21,48 C 23,50 26,49 28,47 Z\" fill=\"#1C1917\"/>\n <path d=\"M 28,47 C 30,45 33,44 33,42 C 31,42 29,43 28,44\" fill=\"#FFFFFF\"/>\n \n <!-- Eye -->\n <circle cx=\"59\" cy=\"18\" r=\"2.5\" fill=\"#1C1917\"/>\n \n <!-- Cheek Blush -->\n <circle cx=\"63\" cy=\"24\" r=\"4.5\" fill=\"#FF5252\" opacity=\"0.45\"/>\n \n <defs>\n <linearGradient id=\"bgGrad\" x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\">\n <stop offset=\"0%\" stop-color=\"#FFE4E6\" />\n <stop offset=\"100%\" stop-color=\"#FECDD3\" />\n </linearGradient>\n <linearGradient id=\"flamingoGrad\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#F43F5E\" />\n <stop offset=\"50%\" stop-color=\"#FDA4AF\" />\n <stop offset=\"100%\" stop-color=\"#FFE4E6\" />\n </linearGradient>\n </defs>\n </svg>\n </div>\n\n <!-- Content Area -->\n <div class=\"polito-content\">\n <div class=\"polito-header\">\n <span class=\"polito-name\">Polito</span>\n \n <!-- Points Badge -->\n <div class=\"polito-badge\" [class.negative]=\"notification()!.points < 0\">\n <!-- Salmon Feather Icon -->\n <svg viewBox=\"0 0 24 24\" class=\"feather-svg\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19.5 4.5C18.5 3.5 16 3 13 4.5C10 6 7.5 9 6.5 11C5.5 13 4.5 16 4 19.5C5.5 19 8.5 18 10.5 17C12.5 16 15.5 13.5 17 10.5C18.5 7.5 18 5 19.5 4.5Z\" \n fill=\"url(#featherBadgeGrad)\" />\n <path d=\"M4 19.5C5.5 18.5 8.5 14.5 13 10.5\" \n stroke=\"url(#featherLineGrad)\" \n stroke-width=\"1.5\" \n stroke-linecap=\"round\" />\n <defs>\n <linearGradient id=\"featherBadgeGrad\" x1=\"4\" y1=\"19.5\" x2=\"19.5\" y2=\"4.5\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#FDA4AF\" />\n <stop offset=\"100%\" stop-color=\"#E11D48\" />\n </linearGradient>\n <linearGradient id=\"featherLineGrad\" x1=\"4\" y1=\"19.5\" x2=\"13\" y2=\"10.5\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0%\" stop-color=\"#FFE4E6\" />\n <stop offset=\"100%\" stop-color=\"#F43F5E\" />\n </linearGradient>\n </defs>\n </svg>\n <span class=\"points-text\">{{ getPointsText(notification()!.points) }}</span>\n </div>\n </div>\n\n <!-- Speech bubble/feedback -->\n @if (notification()!.feedback) {\n <div class=\"polito-speech-bubble\">\n <p>{{ notification()!.feedback }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n\n <!-- Falling Feather Animation Overlay -->\n <div class=\"polito-falling-feather-container\" [class.negative]=\"notification()!.points < 0\">\n <div class=\"feather-wrapper-sway\">\n <svg class=\"falling-feather-svg\" viewBox=\"0 0 100 100\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <defs>\n <!-- Positive gradient: beautiful pink-rose -->\n <linearGradient id=\"featherGradPos\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#F43F5E\" stop-opacity=\"0.85\" />\n <stop offset=\"50%\" stop-color=\"#FDA4AF\" stop-opacity=\"0.9\" />\n <stop offset=\"100%\" stop-color=\"#FFE4E6\" stop-opacity=\"0.95\" />\n </linearGradient>\n <!-- Negative gradient: cool grey/blue -->\n <linearGradient id=\"featherGradNeg\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#6B7280\" stop-opacity=\"0.85\" />\n <stop offset=\"50%\" stop-color=\"#9CA3AF\" stop-opacity=\"0.9\" />\n <stop offset=\"100%\" stop-color=\"#E5E7EB\" stop-opacity=\"0.95\" />\n </linearGradient>\n <!-- Rachis/spine line gradient -->\n <linearGradient id=\"rachisGrad\" x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\">\n <stop offset=\"0%\" stop-color=\"#ffffff\" stop-opacity=\"0.8\" />\n <stop offset=\"100%\" stop-color=\"#ffffff\" stop-opacity=\"0.2\" />\n </linearGradient>\n </defs>\n\n <!-- Main feather shape (Vane) -->\n <path d=\"M 50 90 C 40 85, 20 75, 20 50 C 20 30, 42 20, 50 10 C 50 10, 47 30, 45 45 C 43 60, 46 75, 50 90 Z\" \n fill=\"url(#featherGradPos)\" class=\"feather-vane-pos\" />\n <path d=\"M 50 90 C 60 85, 80 75, 80 50 C 80 30, 58 20, 50 10 C 50 10, 53 30, 55 45 C 57 60, 54 75, 50 90 Z\" \n fill=\"url(#featherGradPos)\" class=\"feather-vane-pos\" />\n\n <path d=\"M 50 90 C 40 85, 20 75, 20 50 C 20 30, 42 20, 50 10 C 50 10, 47 30, 45 45 C 43 60, 46 75, 50 90 Z\" \n fill=\"url(#featherGradNeg)\" class=\"feather-vane-neg\" />\n <path d=\"M 50 90 C 60 85, 80 75, 80 50 C 80 30, 58 20, 50 10 C 50 10, 53 30, 55 45 C 57 60, 54 75, 50 90 Z\" \n fill=\"url(#featherGradNeg)\" class=\"feather-vane-neg\" />\n\n <!-- Rachis/spine (the middle stem) -->\n <path d=\"M 50 92 L 50 10\" stroke=\"url(#rachisGrad)\" stroke-width=\"2.5\" stroke-linecap=\"round\" />\n\n <!-- Fine barb lines for feather texture -->\n <path d=\"M 50 75 Q 35 70, 25 65\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 60 Q 32 55, 22 45\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 45 Q 35 38, 28 28\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n \n <path d=\"M 50 75 Q 65 70, 75 65\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 60 Q 68 55, 78 45\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n <path d=\"M 50 45 Q 65 38, 72 28\" stroke=\"#ffffff\" stroke-width=\"1.2\" opacity=\"0.35\" stroke-linecap=\"round\" />\n </svg>\n <div class=\"falling-feather-points\">\n {{ getFeatherPointsText(notification()!.points) }}\n </div>\n </div>\n </div>\n}\n", styles: ["@keyframes bomp-in{0%{transform:scale(.4) translateY(40px);opacity:0}50%{transform:scale(1.08) translateY(-8px)}75%{transform:scale(.96) translateY(3px)}to{transform:scale(1) translateY(0);opacity:1}}@keyframes bomp-out{0%{transform:scale(1) translateY(0);opacity:1}to{transform:scale(.85) translateY(20px);opacity:0}}.polito-notification-wrapper{position:absolute;bottom:80px;right:16px;z-index:999;max-width:320px;width:calc(100% - 32px);pointer-events:none;display:flex;flex-direction:column;animation:bomp-in .45s cubic-bezier(.34,1.56,.64,1) forwards}.polito-notification-wrapper.hiding{animation:bomp-out .35s cubic-bezier(.25,1,.5,1) forwards}.polito-card{pointer-events:auto;display:flex;gap:12px;padding:14px 16px;border-radius:20px;background:#ffffffd9;backdrop-filter:blur(16px) saturate(180%);-webkit-backdrop-filter:blur(16px) saturate(180%);border:1px solid rgba(255,255,255,.45);box-shadow:0 10px 30px -5px #f43f5e1a,0 20px 40px -10px #00000014,0 1px 3px #0000000a;transition:transform .2s ease,box-shadow .2s ease}.polito-card:hover{transform:translateY(-2px);box-shadow:0 12px 35px -5px #f43f5e26,0 22px 45px -10px #0000001a,0 1px 4px #0000000a}.polito-avatar-container{flex-shrink:0;width:44px;height:44px;border-radius:50%;overflow:hidden;box-shadow:0 4px 12px #f43f5e33;border:2px solid #ffffff}.polito-avatar-svg{width:100%;height:100%;display:block}.polito-content{flex:1;display:flex;flex-direction:column}.polito-header{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:4px}.polito-name{font-weight:700;font-size:.95rem;color:#1c1917;letter-spacing:-.2px}.polito-badge{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;border-radius:12px;background:#fee4e6b3;border:1px solid rgba(251,113,133,.3);color:#e11d48;font-size:.78rem;font-weight:700}.polito-badge .feather-svg{width:14px;height:14px;flex-shrink:0}.polito-badge.negative{background:#f5f5f7b3;border-color:#0000001a;color:#4b5563}.polito-speech-bubble{position:relative;margin-top:6px;padding:8px 12px;border-radius:12px;background:#fff;border:1px solid rgba(229,231,235,.8);box-shadow:0 4px 12px #00000008}.polito-speech-bubble p{margin:0;font-size:.82rem;line-height:1.35;color:#4b5563;font-weight:450}.polito-speech-bubble:before{content:\"\";position:absolute;top:12px;left:-6px;width:10px;height:10px;background:#fff;border-left:1px solid rgba(229,231,235,.8);border-bottom:1px solid rgba(229,231,235,.8);transform:rotate(45deg)}@media(prefers-color-scheme:dark){.polito-card{background:#1e1e24d9;border-color:#ffffff1a;box-shadow:0 10px 30px -5px #f43f5e26,0 20px 40px -10px #0006,0 1px 3px #0000004d}.polito-card:hover{box-shadow:0 12px 35px -5px #f43f5e33,0 22px 45px -10px #00000080,0 1px 4px #0000004d}.polito-name{color:#f5f5f7}.polito-badge{background:#f43f5e26;border-color:#f43f5e4d;color:#fda4af}.polito-badge.negative{background:#ffffff0d;border-color:#ffffff1a;color:#9ca3af}.polito-speech-bubble{background:#27272a;border-color:#ffffff0f;box-shadow:0 4px 12px #0003}.polito-speech-bubble p{color:#d1d5db}.polito-speech-bubble:before{background:#27272a;border-left-color:#ffffff0f;border-bottom-color:#ffffff0f}.polito-avatar-container{border-color:#27272a}}@media(max-width:480px){.polito-notification-wrapper{right:8px;bottom:72px;width:calc(100% - 16px);max-width:none}}@keyframes feather-fall{0%{transform:translateY(-100px);opacity:0}12%{opacity:1}85%{opacity:1}to{transform:translateY(75vh);opacity:0}}@keyframes feather-sway{0%,to{transform:translate(-35px) rotate(-16deg)}50%{transform:translate(35px) rotate(16deg)}}.polito-falling-feather-container{position:absolute;top:0;right:120px;width:90px;height:90px;pointer-events:none;z-index:1000;animation:feather-fall 4.2s cubic-bezier(.33,1,.68,1) forwards}.polito-falling-feather-container .falling-feather-svg{width:100%;height:100%;filter:drop-shadow(0 6px 12px rgba(244,63,94,.25))}.polito-falling-feather-container .feather-vane-pos{display:block}.polito-falling-feather-container .feather-vane-neg{display:none}.polito-falling-feather-container .feather-wrapper-sway{position:relative;width:100%;height:100%;animation:feather-sway 2.2s ease-in-out infinite}.polito-falling-feather-container .falling-feather-points{position:absolute;top:48%;left:50%;transform:translate(-50%,-50%);font-size:1.4rem;font-weight:900;color:#fff;letter-spacing:-.5px;text-shadow:0 2px 5px rgba(0,0,0,.3),-2px -2px 0 #e11d48,2px -2px 0 #e11d48,-2px 2px 0 #e11d48,2px 2px 0 #e11d48;white-space:nowrap;-webkit-user-select:none;user-select:none}.polito-falling-feather-container.negative .falling-feather-svg{filter:drop-shadow(0 6px 12px rgba(107,114,128,.25))}.polito-falling-feather-container.negative .feather-vane-pos{display:none}.polito-falling-feather-container.negative .feather-vane-neg{display:block}.polito-falling-feather-container.negative .falling-feather-points{text-shadow:0 2px 5px rgba(0,0,0,.3),-2px -2px 0 #4b5563,2px -2px 0 #4b5563,-2px 2px 0 #4b5563,2px 2px 0 #4b5563}@media(prefers-color-scheme:dark){.polito-falling-feather-container .falling-feather-svg{filter:drop-shadow(0 8px 16px rgba(244,63,94,.35))}.polito-falling-feather-container.negative .falling-feather-svg{filter:drop-shadow(0 8px 16px rgba(0,0,0,.4))}}@media(max-width:480px){.polito-falling-feather-container{right:auto;left:calc(50% - 45px)}@keyframes mobile-feather-sway{0%,to{transform:translate(-25px) rotate(-12deg)}50%{transform:translate(25px) rotate(12deg)}}.polito-falling-feather-container .feather-wrapper-sway{animation-name:mobile-feather-sway}}\n"] }]
5854
+ }] });
5855
+
5422
5856
  /**
5423
5857
  * SafeJsonPipe - A pipe that safely stringifies objects with circular references
5424
5858
  * This pipe handles circular references and DOM objects that can't be serialized
@@ -5516,7 +5950,7 @@ class PromptPreviewComponent {
5516
5950
  }
5517
5951
  ngOnInit() { }
5518
5952
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PromptPreviewComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5519
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<h3\n >Total Tokens: <b class=\"text-green-700\">{{ totalTokens }}</b></h3\n>\n@if (view() === 'regular') {\n<div>\n @for (section of sectionsOrder; track section) { @if (getMessagesBySection(section).length > 0) {\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" [value]=\"formatCamelCaseString(section)\" />\n </p-divider>\n @for (message of getMessagesBySection(section); 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 [data]=\"message.content\"></markdown>\n </div>\n } } } @if (messagesWithNoSection.length > 0) {\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" value=\"Others\" />\n </p-divider>\n @for (message of messagesWithNoSection; 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 [data]=\"message.content\"></markdown>\n </div>\n } } @if (jailBrake()) {\n <!-- JailBrake Instructions Will be DEPRECATED -->\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" value=\"JailBrake Instructions\" />\n </p-divider>\n <div>\n <h5>\n <b class=\"text-green-700\">({{ estimateTokens(jailBrake()!) }} tokens)</b>\n </h5>\n <p>{{ jailBrake() }}</p>\n </div>\n }\n</div>\n} @else {\n<div>\n <markdown [data]=\"markdownContent()\"></markdown>\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"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i1$3.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }] }); }
5953
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<h3\n >Total Tokens: <b class=\"text-green-700\">{{ totalTokens }}</b></h3\n>\n@if (view() === 'regular') {\n<div>\n @for (section of sectionsOrder; track section) { @if (getMessagesBySection(section).length > 0) {\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" [value]=\"formatCamelCaseString(section)\" />\n </p-divider>\n @for (message of getMessagesBySection(section); 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 [data]=\"message.content\"></markdown>\n </div>\n } } } @if (messagesWithNoSection.length > 0) {\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" value=\"Others\" />\n </p-divider>\n @for (message of messagesWithNoSection; 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 [data]=\"message.content\"></markdown>\n </div>\n } } @if (jailBrake()) {\n <!-- JailBrake Instructions Will be DEPRECATED -->\n <p-divider align=\"left\" type=\"dotted\">\n <p-tag severity=\"secondary\" value=\"JailBrake Instructions\" />\n </p-divider>\n <div>\n <h5>\n <b class=\"text-green-700\">({{ estimateTokens(jailBrake()!) }} tokens)</b>\n </h5>\n <p>{{ jailBrake() }}</p>\n </div>\n }\n</div>\n} @else {\n<div>\n <markdown [data]=\"markdownContent()\"></markdown>\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"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$3.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }] }); }
5520
5954
  }
5521
5955
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: PromptPreviewComponent, decorators: [{
5522
5956
  type: Component,
@@ -5539,7 +5973,7 @@ class CostDetailsComponent {
5539
5973
  }));
5540
5974
  }
5541
5975
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CostDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5542
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CostDetailsComponent, isStandalone: true, selector: "dc-cost-details", ngImport: i0, template: "<div class=\"cost-details-container\">\n <h3>Cost Details</h3>\n @if (conversationCostService.totalTokens() > 0) {\n <div class=\"token-counter\">\n <span>\n \uD83D\uDCE5 {{ conversationCostService.totalInputTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalInputCost() | number : '1.4-4' }}</span>\n </span>\n <span>\n \uD83D\uDCE4 {{ conversationCostService.totalOutputTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalOutputCost() | number : '1.4-4' }}</span>\n </span>\n <span>\n \uD83E\uDDEE {{ conversationCostService.totalTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalCost() | number : '1.4-4' }}</span>\n </span>\n <span> <i class=\"pi pi-cloud-upload\"></i> {{ conversationCostService.totalApiCalls() }} </span>\n </div>\n }\n <p-table [value]=\"usageArray\" [tableStyle]=\"{ 'min-width': '50rem' }\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Tag</th>\n <th>Input Tokens</th>\n <th>Output Tokens</th>\n <th>Total Tokens</th>\n <th>Input Cost</th>\n <th>Output Cost</th>\n <th>Total Cost</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-item>\n <tr>\n <td>{{ item.tag }}</td>\n <td>{{ item.tokenUsage.input }}</td>\n <td>{{ item.tokenUsage.output }}</td>\n <td>{{ item.tokenUsage.total }}</td>\n <td>{{ item.inputCost | number : '1.4-4' }}</td>\n <td>{{ item.outputCost | number : '1.4-4' }}</td>\n <td>{{ item.totalCost | number : '1.4-4' }}</td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }] }); }
5976
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CostDetailsComponent, isStandalone: true, selector: "dc-cost-details", ngImport: i0, template: "<div class=\"cost-details-container\">\n <h3>Cost Details</h3>\n @if (conversationCostService.totalTokens() > 0) {\n <div class=\"token-counter\">\n <span>\n \uD83D\uDCE5 {{ conversationCostService.totalInputTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalInputCost() | number : '1.4-4' }}</span>\n </span>\n <span>\n \uD83D\uDCE4 {{ conversationCostService.totalOutputTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalOutputCost() | number : '1.4-4' }}</span>\n </span>\n <span>\n \uD83E\uDDEE {{ conversationCostService.totalTokens() }}\n <span style=\"font-size: small; color: rgb(74, 74, 74)\">${{ conversationCostService.totalCost() | number : '1.4-4' }}</span>\n </span>\n <span> <i class=\"pi pi-cloud-upload\"></i> {{ conversationCostService.totalApiCalls() }} </span>\n </div>\n }\n <p-table [value]=\"usageArray\" [tableStyle]=\"{ 'min-width': '50rem' }\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>Tag</th>\n <th>Input Tokens</th>\n <th>Output Tokens</th>\n <th>Total Tokens</th>\n <th>Input Cost</th>\n <th>Output Cost</th>\n <th>Total Cost</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-item>\n <tr>\n <td>{{ item.tag }}</td>\n <td>{{ item.tokenUsage.input }}</td>\n <td>{{ item.tokenUsage.output }}</td>\n <td>{{ item.tokenUsage.total }}</td>\n <td>{{ item.inputCost | number : '1.4-4' }}</td>\n <td>{{ item.outputCost | number : '1.4-4' }}</td>\n <td>{{ item.totalCost | number : '1.4-4' }}</td>\n </tr>\n </ng-template>\n </p-table>\n</div>\n", styles: [":host{display:block}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i1$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "pipe", type: i2$1.DecimalPipe, name: "number" }] }); }
5543
5977
  }
5544
5978
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CostDetailsComponent, decorators: [{
5545
5979
  type: Component,
@@ -5552,11 +5986,11 @@ class MessagesStateInspectorComponent {
5552
5986
  this.messages = this.messagesStateService.getMessagesSignal();
5553
5987
  }
5554
5988
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessagesStateInspectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5555
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessagesStateInspectorComponent, isStandalone: true, selector: "dc-messages-state-inspector", ngImport: i0, template: "<div class=\"messages-state-inspector\">\n @for (msg of messages(); track msg.messageId; let i = $index) {\n <details class=\"message-group mb-2 border rounded p-2\">\n <summary class=\"cursor-pointer font-bold p-1 hover:bg-gray-100 flex justify-between items-center\">\n <span>\n <span class=\"text-xs text-gray-400 mr-2\">#{{ i + 1 }}</span>\n <span [class]=\"'role-badge ' + msg.role\">{{ msg.role }}</span>\n <span class=\"ml-2 text-sm truncate max-w-xs\">{{ msg.content | slice:0:50 }}{{ msg.content.length > 50 ? '...' : '' }}</span>\n </span>\n <span class=\"text-xs text-gray-400\">{{ msg.messageId }}</span>\n </summary>\n\n <div class=\"message-details mt-2 pl-4 border-l-2 border-primary\">\n <!-- Standard Properties -->\n <div class=\"grid grid-cols-2 gap-2 text-sm\">\n <div><strong>Role:</strong> {{ msg.role }}</div>\n <div><strong>Section:</strong> {{ msg.section || 'N/A' }}</div>\n <div><strong>Message ID:</strong> {{ msg.messageId }}</div>\n <div class=\"col-span-2\"><strong>Content:</strong> <pre class=\"whitespace-pre-wrap text-xs bg-gray-50 p-2 mt-1\">{{ msg.content }}</pre></div>\n @if (msg.translation) {\n <div class=\"col-span-2 text-blue-600\"><strong>Translation:</strong> {{ msg.translation }}</div>\n }\n </div>\n\n <!-- JSON Preview of other props -->\n <details class=\"mt-2\">\n <summary class=\"text-xs text-gray-500 cursor-pointer\">All Metadata</summary>\n <pre class=\"text-[10px] bg-slate-800 text-white p-2 rounded mt-1 overflow-auto max-h-64\">{{ msg | safeJson }}</pre>\n </details>\n\n <!-- MultiMessages recursive check -->\n @if (msg.multiMessages && msg.multiMessages.length > 0) {\n <div class=\"mt-3\">\n <strong class=\"text-xs uppercase text-gray-500\">Multi Messages ({{ msg.multiMessages.length }})</strong>\n <div class=\"pl-4 border-l-2 border-dashed border-gray-300\">\n @for (subMsg of msg.multiMessages; track $index) {\n <details class=\"mt-1 border rounded p-1 bg-gray-50\">\n <summary class=\"text-xs cursor-pointer truncate\">Sub: {{ subMsg.text | slice:0:30 }}...</summary>\n <pre class=\"text-[10px] mt-1 p-1 bg-white border overflow-auto\">{{ subMsg | safeJson }}</pre>\n </details>\n }\n </div>\n </div>\n }\n\n <!-- Evaluation -->\n @if (msg.evaluation) {\n <div class=\"mt-2 p-2 bg-yellow-50 rounded text-xs\">\n <strong>Evaluation:</strong>\n <pre>{{ msg.evaluation | safeJson }}</pre>\n </div>\n }\n\n <!-- Tags -->\n @if (msg.tags && msg.tags.length > 0) {\n <div class=\"mt-2 flex flex-wrap gap-1\">\n <strong>Tags:</strong>\n @for (tag of msg.tags; track tag) {\n <span class=\"bg-gray-200 px-1 rounded text-[10px]\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n </details>\n } @empty {\n <div class=\"p-4 text-center text-gray-400\">No messages in state.</div>\n }\n</div>\n\n<style>\n .role-badge {\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.7rem;\n text-transform: uppercase;\n font-weight: bold;\n }\n .role-badge.user { background: #e0f2fe; color: #0369a1; }\n .role-badge.assistant { background: #f0fdf4; color: #15803d; }\n .role-badge.assistantHelper { background: #faf5ff; color: #7e22ce; }\n .role-badge.system { background: #f1f5f9; color: #475569; }\n .border-primary { border-color: var(--p-primary-color, #3b82f6); }\n</style>\n", styles: [".role-badge{padding:2px 6px;border-radius:4px;font-size:.7rem;text-transform:uppercase;font-weight:700}.role-badge.user{background:#e0f2fe;color:#0369a1}.role-badge.assistant{background:#f0fdf4;color:#15803d}.role-badge.assistantHelper{background:#faf5ff;color:#7e22ce}.role-badge.system{background:#f1f5f9;color:#475569}.border-primary{border-color:var(--p-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$1.SlicePipe, name: "slice" }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
5989
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: MessagesStateInspectorComponent, isStandalone: true, selector: "dc-messages-state-inspector", ngImport: i0, template: "<div class=\"messages-state-inspector\">\n @for (msg of messages(); track msg.messageId; let i = $index) {\n <details class=\"message-group mb-2 border rounded p-2\">\n <summary class=\"cursor-pointer font-bold p-1 hover:bg-gray-100 flex justify-between items-center\">\n <span>\n <span class=\"text-xs text-gray-400 mr-2\">#{{ i + 1 }}</span>\n <span [class]=\"'role-badge ' + msg.role\">{{ msg.role }}</span>\n <span class=\"ml-2 text-sm truncate max-w-xs\">{{ msg.content | slice:0:50 }}{{ msg.content.length > 50 ? '...' : '' }}</span>\n </span>\n <span class=\"text-xs text-gray-400\">{{ msg.messageId }}</span>\n </summary>\n\n <div class=\"message-details mt-2 pl-4 border-l-2 border-primary\">\n <!-- Standard Properties -->\n <div class=\"grid grid-cols-2 gap-2 text-sm\">\n <div><strong>Role:</strong> {{ msg.role }}</div>\n <div><strong>Section:</strong> {{ msg.section || 'N/A' }}</div>\n <div><strong>Message ID:</strong> {{ msg.messageId }}</div>\n <div class=\"col-span-2\"><strong>Content:</strong> <pre class=\"whitespace-pre-wrap text-xs bg-gray-50 p-2 mt-1\">{{ msg.content }}</pre></div>\n @if (msg.translation) {\n <div class=\"col-span-2 text-blue-600\"><strong>Translation:</strong> {{ msg.translation }}</div>\n }\n </div>\n\n <!-- JSON Preview of other props -->\n <details class=\"mt-2\">\n <summary class=\"text-xs text-gray-500 cursor-pointer\">All Metadata</summary>\n <pre class=\"text-[10px] bg-slate-800 text-white p-2 rounded mt-1 overflow-auto max-h-64\">{{ msg | safeJson }}</pre>\n </details>\n\n <!-- MultiMessages recursive check -->\n @if (msg.multiMessages && msg.multiMessages.length > 0) {\n <div class=\"mt-3\">\n <strong class=\"text-xs uppercase text-gray-500\">Multi Messages ({{ msg.multiMessages.length }})</strong>\n <div class=\"pl-4 border-l-2 border-dashed border-gray-300\">\n @for (subMsg of msg.multiMessages; track $index) {\n <details class=\"mt-1 border rounded p-1 bg-gray-50\">\n <summary class=\"text-xs cursor-pointer truncate\">Sub: {{ subMsg.text | slice:0:30 }}...</summary>\n <pre class=\"text-[10px] mt-1 p-1 bg-white border overflow-auto\">{{ subMsg | safeJson }}</pre>\n </details>\n }\n </div>\n </div>\n }\n\n <!-- Evaluation -->\n @if (msg.evaluation) {\n <div class=\"mt-2 p-2 bg-yellow-50 rounded text-xs space-y-2\">\n <strong>Evaluation</strong>\n\n @if (msg.evaluation['flow']; as flow) {\n <div class=\"flow-eval space-y-2\">\n @if (flow.goal) {\n <div class=\"p-2 bg-white rounded border\">\n <div class=\"flex items-center justify-between\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Goal</strong>\n @if (flow.goal.deltaPoints != null) {\n <span\n class=\"px-1.5 rounded text-[11px] font-bold\"\n [class.bg-green-100]=\"flow.goal.deltaPoints > 0\"\n [class.text-green-700]=\"flow.goal.deltaPoints > 0\"\n [class.bg-red-100]=\"flow.goal.deltaPoints < 0\"\n [class.text-red-700]=\"flow.goal.deltaPoints < 0\"\n [class.bg-gray-100]=\"flow.goal.deltaPoints === 0\"\n [class.text-gray-600]=\"flow.goal.deltaPoints === 0\">\n {{ flow.goal.deltaPoints > 0 ? '+' : '' }}{{ flow.goal.deltaPoints }} pts\n </span>\n }\n </div>\n @if (flow.goal.previousValue != null && flow.goal.newValue != null) {\n <div class=\"mt-1 text-[11px] text-gray-600\">\n <span>{{ flow.goal.previousValue }}</span>\n <span class=\"mx-1\">\u2192</span>\n <span class=\"font-bold text-gray-900\">{{ flow.goal.newValue }}</span>\n <span class=\"text-gray-400\"> / 100</span>\n </div>\n <div class=\"w-full bg-gray-200 rounded h-1 mt-1 overflow-hidden\">\n <div class=\"bg-primary h-1\" [style.width.%]=\"flow.goal.newValue\" [style.background-color]=\"'#3b82f6'\"></div>\n </div>\n }\n @if (flow.goal.feedback) {\n <div class=\"mt-1 text-[11px] italic text-gray-700\">\"{{ flow.goal.feedback }}\"</div>\n }\n </div>\n }\n\n @if (flow.challenges?.length) {\n <div class=\"p-2 bg-white rounded border\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Challenges</strong>\n <ul class=\"mt-1 space-y-0.5\">\n @for (ch of flow.challenges; track ch.name) {\n <li class=\"flex items-center gap-1 text-[11px]\">\n <span [class.text-green-600]=\"ch.value\" [class.text-gray-400]=\"!ch.value\">\n {{ ch.value ? '\u2713' : '\u25CB' }}\n </span>\n <span [class.font-semibold]=\"ch.value\">{{ ch.name }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (flow.moodState?.value) {\n <div class=\"p-2 bg-white rounded border flex items-center justify-between\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Mood</strong>\n <span class=\"text-[11px] font-semibold\">{{ flow.moodState.value }}</span>\n </div>\n }\n\n @if (flow.evaluatedAt) {\n <div class=\"text-[10px] text-gray-400 text-right\">{{ flow.evaluatedAt }}</div>\n }\n </div>\n }\n\n <details class=\"mt-1\">\n <summary class=\"text-[10px] text-gray-500 cursor-pointer\">Raw evaluation</summary>\n <pre class=\"text-[10px]\">{{ msg.evaluation | safeJson }}</pre>\n </details>\n </div>\n }\n\n <!-- Tags -->\n @if (msg.tags && msg.tags.length > 0) {\n <div class=\"mt-2 flex flex-wrap gap-1\">\n <strong>Tags:</strong>\n @for (tag of msg.tags; track tag) {\n <span class=\"bg-gray-200 px-1 rounded text-[10px]\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n </details>\n } @empty {\n <div class=\"p-4 text-center text-gray-400\">No messages in state.</div>\n }\n</div>\n\n<style>\n .role-badge {\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.7rem;\n text-transform: uppercase;\n font-weight: bold;\n }\n .role-badge.user { background: #e0f2fe; color: #0369a1; }\n .role-badge.assistant { background: #f0fdf4; color: #15803d; }\n .role-badge.assistantHelper { background: #faf5ff; color: #7e22ce; }\n .role-badge.system { background: #f1f5f9; color: #475569; }\n .border-primary { border-color: var(--p-primary-color, #3b82f6); }\n</style>\n", styles: [".role-badge{padding:2px 6px;border-radius:4px;font-size:.7rem;text-transform:uppercase;font-weight:700}.role-badge.user{background:#e0f2fe;color:#0369a1}.role-badge.assistant{background:#f0fdf4;color:#15803d}.role-badge.assistantHelper{background:#faf5ff;color:#7e22ce}.role-badge.system{background:#f1f5f9;color:#475569}.border-primary{border-color:var(--p-primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "pipe", type: i2$1.SlicePipe, name: "slice" }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
5556
5990
  }
5557
5991
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: MessagesStateInspectorComponent, decorators: [{
5558
5992
  type: Component,
5559
- args: [{ selector: 'dc-messages-state-inspector', standalone: true, imports: [CommonModule, SafeJsonPipe], template: "<div class=\"messages-state-inspector\">\n @for (msg of messages(); track msg.messageId; let i = $index) {\n <details class=\"message-group mb-2 border rounded p-2\">\n <summary class=\"cursor-pointer font-bold p-1 hover:bg-gray-100 flex justify-between items-center\">\n <span>\n <span class=\"text-xs text-gray-400 mr-2\">#{{ i + 1 }}</span>\n <span [class]=\"'role-badge ' + msg.role\">{{ msg.role }}</span>\n <span class=\"ml-2 text-sm truncate max-w-xs\">{{ msg.content | slice:0:50 }}{{ msg.content.length > 50 ? '...' : '' }}</span>\n </span>\n <span class=\"text-xs text-gray-400\">{{ msg.messageId }}</span>\n </summary>\n\n <div class=\"message-details mt-2 pl-4 border-l-2 border-primary\">\n <!-- Standard Properties -->\n <div class=\"grid grid-cols-2 gap-2 text-sm\">\n <div><strong>Role:</strong> {{ msg.role }}</div>\n <div><strong>Section:</strong> {{ msg.section || 'N/A' }}</div>\n <div><strong>Message ID:</strong> {{ msg.messageId }}</div>\n <div class=\"col-span-2\"><strong>Content:</strong> <pre class=\"whitespace-pre-wrap text-xs bg-gray-50 p-2 mt-1\">{{ msg.content }}</pre></div>\n @if (msg.translation) {\n <div class=\"col-span-2 text-blue-600\"><strong>Translation:</strong> {{ msg.translation }}</div>\n }\n </div>\n\n <!-- JSON Preview of other props -->\n <details class=\"mt-2\">\n <summary class=\"text-xs text-gray-500 cursor-pointer\">All Metadata</summary>\n <pre class=\"text-[10px] bg-slate-800 text-white p-2 rounded mt-1 overflow-auto max-h-64\">{{ msg | safeJson }}</pre>\n </details>\n\n <!-- MultiMessages recursive check -->\n @if (msg.multiMessages && msg.multiMessages.length > 0) {\n <div class=\"mt-3\">\n <strong class=\"text-xs uppercase text-gray-500\">Multi Messages ({{ msg.multiMessages.length }})</strong>\n <div class=\"pl-4 border-l-2 border-dashed border-gray-300\">\n @for (subMsg of msg.multiMessages; track $index) {\n <details class=\"mt-1 border rounded p-1 bg-gray-50\">\n <summary class=\"text-xs cursor-pointer truncate\">Sub: {{ subMsg.text | slice:0:30 }}...</summary>\n <pre class=\"text-[10px] mt-1 p-1 bg-white border overflow-auto\">{{ subMsg | safeJson }}</pre>\n </details>\n }\n </div>\n </div>\n }\n\n <!-- Evaluation -->\n @if (msg.evaluation) {\n <div class=\"mt-2 p-2 bg-yellow-50 rounded text-xs\">\n <strong>Evaluation:</strong>\n <pre>{{ msg.evaluation | safeJson }}</pre>\n </div>\n }\n\n <!-- Tags -->\n @if (msg.tags && msg.tags.length > 0) {\n <div class=\"mt-2 flex flex-wrap gap-1\">\n <strong>Tags:</strong>\n @for (tag of msg.tags; track tag) {\n <span class=\"bg-gray-200 px-1 rounded text-[10px]\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n </details>\n } @empty {\n <div class=\"p-4 text-center text-gray-400\">No messages in state.</div>\n }\n</div>\n\n<style>\n .role-badge {\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.7rem;\n text-transform: uppercase;\n font-weight: bold;\n }\n .role-badge.user { background: #e0f2fe; color: #0369a1; }\n .role-badge.assistant { background: #f0fdf4; color: #15803d; }\n .role-badge.assistantHelper { background: #faf5ff; color: #7e22ce; }\n .role-badge.system { background: #f1f5f9; color: #475569; }\n .border-primary { border-color: var(--p-primary-color, #3b82f6); }\n</style>\n" }]
5993
+ args: [{ selector: 'dc-messages-state-inspector', standalone: true, imports: [CommonModule, SafeJsonPipe], template: "<div class=\"messages-state-inspector\">\n @for (msg of messages(); track msg.messageId; let i = $index) {\n <details class=\"message-group mb-2 border rounded p-2\">\n <summary class=\"cursor-pointer font-bold p-1 hover:bg-gray-100 flex justify-between items-center\">\n <span>\n <span class=\"text-xs text-gray-400 mr-2\">#{{ i + 1 }}</span>\n <span [class]=\"'role-badge ' + msg.role\">{{ msg.role }}</span>\n <span class=\"ml-2 text-sm truncate max-w-xs\">{{ msg.content | slice:0:50 }}{{ msg.content.length > 50 ? '...' : '' }}</span>\n </span>\n <span class=\"text-xs text-gray-400\">{{ msg.messageId }}</span>\n </summary>\n\n <div class=\"message-details mt-2 pl-4 border-l-2 border-primary\">\n <!-- Standard Properties -->\n <div class=\"grid grid-cols-2 gap-2 text-sm\">\n <div><strong>Role:</strong> {{ msg.role }}</div>\n <div><strong>Section:</strong> {{ msg.section || 'N/A' }}</div>\n <div><strong>Message ID:</strong> {{ msg.messageId }}</div>\n <div class=\"col-span-2\"><strong>Content:</strong> <pre class=\"whitespace-pre-wrap text-xs bg-gray-50 p-2 mt-1\">{{ msg.content }}</pre></div>\n @if (msg.translation) {\n <div class=\"col-span-2 text-blue-600\"><strong>Translation:</strong> {{ msg.translation }}</div>\n }\n </div>\n\n <!-- JSON Preview of other props -->\n <details class=\"mt-2\">\n <summary class=\"text-xs text-gray-500 cursor-pointer\">All Metadata</summary>\n <pre class=\"text-[10px] bg-slate-800 text-white p-2 rounded mt-1 overflow-auto max-h-64\">{{ msg | safeJson }}</pre>\n </details>\n\n <!-- MultiMessages recursive check -->\n @if (msg.multiMessages && msg.multiMessages.length > 0) {\n <div class=\"mt-3\">\n <strong class=\"text-xs uppercase text-gray-500\">Multi Messages ({{ msg.multiMessages.length }})</strong>\n <div class=\"pl-4 border-l-2 border-dashed border-gray-300\">\n @for (subMsg of msg.multiMessages; track $index) {\n <details class=\"mt-1 border rounded p-1 bg-gray-50\">\n <summary class=\"text-xs cursor-pointer truncate\">Sub: {{ subMsg.text | slice:0:30 }}...</summary>\n <pre class=\"text-[10px] mt-1 p-1 bg-white border overflow-auto\">{{ subMsg | safeJson }}</pre>\n </details>\n }\n </div>\n </div>\n }\n\n <!-- Evaluation -->\n @if (msg.evaluation) {\n <div class=\"mt-2 p-2 bg-yellow-50 rounded text-xs space-y-2\">\n <strong>Evaluation</strong>\n\n @if (msg.evaluation['flow']; as flow) {\n <div class=\"flow-eval space-y-2\">\n @if (flow.goal) {\n <div class=\"p-2 bg-white rounded border\">\n <div class=\"flex items-center justify-between\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Goal</strong>\n @if (flow.goal.deltaPoints != null) {\n <span\n class=\"px-1.5 rounded text-[11px] font-bold\"\n [class.bg-green-100]=\"flow.goal.deltaPoints > 0\"\n [class.text-green-700]=\"flow.goal.deltaPoints > 0\"\n [class.bg-red-100]=\"flow.goal.deltaPoints < 0\"\n [class.text-red-700]=\"flow.goal.deltaPoints < 0\"\n [class.bg-gray-100]=\"flow.goal.deltaPoints === 0\"\n [class.text-gray-600]=\"flow.goal.deltaPoints === 0\">\n {{ flow.goal.deltaPoints > 0 ? '+' : '' }}{{ flow.goal.deltaPoints }} pts\n </span>\n }\n </div>\n @if (flow.goal.previousValue != null && flow.goal.newValue != null) {\n <div class=\"mt-1 text-[11px] text-gray-600\">\n <span>{{ flow.goal.previousValue }}</span>\n <span class=\"mx-1\">\u2192</span>\n <span class=\"font-bold text-gray-900\">{{ flow.goal.newValue }}</span>\n <span class=\"text-gray-400\"> / 100</span>\n </div>\n <div class=\"w-full bg-gray-200 rounded h-1 mt-1 overflow-hidden\">\n <div class=\"bg-primary h-1\" [style.width.%]=\"flow.goal.newValue\" [style.background-color]=\"'#3b82f6'\"></div>\n </div>\n }\n @if (flow.goal.feedback) {\n <div class=\"mt-1 text-[11px] italic text-gray-700\">\"{{ flow.goal.feedback }}\"</div>\n }\n </div>\n }\n\n @if (flow.challenges?.length) {\n <div class=\"p-2 bg-white rounded border\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Challenges</strong>\n <ul class=\"mt-1 space-y-0.5\">\n @for (ch of flow.challenges; track ch.name) {\n <li class=\"flex items-center gap-1 text-[11px]\">\n <span [class.text-green-600]=\"ch.value\" [class.text-gray-400]=\"!ch.value\">\n {{ ch.value ? '\u2713' : '\u25CB' }}\n </span>\n <span [class.font-semibold]=\"ch.value\">{{ ch.name }}</span>\n </li>\n }\n </ul>\n </div>\n }\n\n @if (flow.moodState?.value) {\n <div class=\"p-2 bg-white rounded border flex items-center justify-between\">\n <strong class=\"text-[11px] uppercase text-gray-600\">Mood</strong>\n <span class=\"text-[11px] font-semibold\">{{ flow.moodState.value }}</span>\n </div>\n }\n\n @if (flow.evaluatedAt) {\n <div class=\"text-[10px] text-gray-400 text-right\">{{ flow.evaluatedAt }}</div>\n }\n </div>\n }\n\n <details class=\"mt-1\">\n <summary class=\"text-[10px] text-gray-500 cursor-pointer\">Raw evaluation</summary>\n <pre class=\"text-[10px]\">{{ msg.evaluation | safeJson }}</pre>\n </details>\n </div>\n }\n\n <!-- Tags -->\n @if (msg.tags && msg.tags.length > 0) {\n <div class=\"mt-2 flex flex-wrap gap-1\">\n <strong>Tags:</strong>\n @for (tag of msg.tags; track tag) {\n <span class=\"bg-gray-200 px-1 rounded text-[10px]\">{{ tag }}</span>\n }\n </div>\n }\n </div>\n </details>\n } @empty {\n <div class=\"p-4 text-center text-gray-400\">No messages in state.</div>\n }\n</div>\n\n<style>\n .role-badge {\n padding: 2px 6px;\n border-radius: 4px;\n font-size: 0.7rem;\n text-transform: uppercase;\n font-weight: bold;\n }\n .role-badge.user { background: #e0f2fe; color: #0369a1; }\n .role-badge.assistant { background: #f0fdf4; color: #15803d; }\n .role-badge.assistantHelper { background: #faf5ff; color: #7e22ce; }\n .role-badge.system { background: #f1f5f9; color: #475569; }\n .border-primary { border-color: var(--p-primary-color, #3b82f6); }\n</style>\n" }]
5560
5994
  }] });
5561
5995
 
5562
5996
  class DcAgentCardDetailComponent extends EntityBaseDetailComponent {
@@ -5597,13 +6031,61 @@ class DcAgentCardDetailComponent extends EntityBaseDetailComponent {
5597
6031
  this.selectedMotion.set(null);
5598
6032
  }
5599
6033
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcAgentCardDetailComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5600
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcAgentCardDetailComponent, isStandalone: true, selector: "dc-agent-card-detail", inputs: { entityData: { classPropertyName: "entityData", publicName: "entityData", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "@if (isLoading()) {\n<div class=\"loading-state\">\n <p-progressSpinner strokeWidth=\"4\" />\n</div>\n} @else if (entity()) {\n<div class=\"preview-container\">\n\n <!-- Banner -->\n @if (bannerUrl) {\n <div class=\"preview-banner\">\n <img class=\"banner-image\" [src]=\"bannerUrl\" alt=\"banner\" />\n </div>\n }\n\n <!-- Header: image + name + meta -->\n <div class=\"preview-header\" [class.has-banner]=\"bannerUrl\">\n @if (entity()?.assets?.image?.url) {\n <img class=\"preview-image\" [src]=\"entity()!.assets!.image!.url\" [alt]=\"characterData?.name || entity()?.name\" />\n }\n <div class=\"preview-header-info\">\n <h2 class=\"preview-name\">{{ characterData?.name || entity()?.name }}</h2>\n\n <div class=\"preview-meta-tags\">\n @if (entity()?.lang) {\n <p-tag [value]=\"entity()!.lang!\" severity=\"secondary\" icon=\"pi pi-flag\" />\n }\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-circle-fill\" />\n }\n @if (characterData?.gender) {\n <p-tag [value]=\"characterData!.gender\" severity=\"secondary\" icon=\"pi pi-user\" />\n }\n @if (entity()?.metaApp?.takenCount) {\n <p-tag [value]=\"'Taken: ' + entity()!.metaApp!.takenCount\" severity=\"success\" icon=\"pi pi-users\" />\n }\n @if (learnableInfo?.level) {\n <p-tag [value]=\"'Level ' + learnableInfo.level\" severity=\"warn\" icon=\"pi pi-star\" />\n }\n @if (learnableInfo?.takenCount) {\n <p-tag [value]=\"'Played: ' + learnableInfo.takenCount\" severity=\"secondary\" icon=\"pi pi-play\" />\n }\n </div>\n\n @if (characterData?.tags?.length) {\n <div class=\"preview-tags\">\n @for (tag of characterData!.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Entity-level description -->\n @if (entity()?.description) {\n <div class=\"preview-entity-description\">\n <p>{{ entity()!.description }}</p>\n </div>\n }\n\n <!-- Motion Videos -->\n @if (motions.length) {\n <div class=\"preview-section motions-top-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-video\"></i> Motion Videos ({{ motions.length }})</h4>\n <div class=\"motions-grid\">\n @for (motion of motions; track $index) {\n @if (motion.metadata?.moodState || motion.metadata?.event) {\n <button class=\"motion-chip\" (click)=\"openMotionVideo(motion)\">\n <i class=\"pi pi-play-circle\"></i>\n <span>{{ motion.metadata?.moodState || motion.metadata?.event }}</span>\n </button>\n }\n }\n </div>\n </div>\n }\n\n <p-divider />\n\n @if (characterData?.hook) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-bookmark\"></i> Hook</h4>\n <p>{{ characterData!.hook }}</p>\n </div>\n }\n\n @if (characterData?.instructions) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-info-circle\"></i> Instructions</h4>\n <p>{{ characterData!.instructions }}</p>\n </div>\n }\n\n @if (characterData?.scenario) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-map\"></i> Scenario</h4>\n <p>{{ characterData!.scenario }}</p>\n </div>\n }\n\n @if (characterData?.creator_notes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-file\"></i> Creator Notes</h4>\n <p>{{ characterData!.creator_notes }}</p>\n </div>\n }\n\n @if (characterData?.description) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-align-left\"></i> Description</h4>\n <p>{{ characterData!.description }}</p>\n </div>\n }\n\n @if (characterData?.greetings?.length) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comments\"></i> Greetings</h4>\n @for (greeting of characterData!.greetings; track $index) {\n <p class=\"greeting-item\"><i class=\"pi pi-chevron-right\"></i> {{ greeting }}</p>\n }\n </div>\n }\n\n @if (characterData?.first_mes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comment\"></i> First Message</h4>\n <p class=\"first-message\">{{ characterData!.first_mes }}</p>\n </div>\n }\n\n @if (persona) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-id-card\"></i> Persona</h4>\n <div class=\"persona-grid\">\n @if (persona.identity) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Identity</span>\n <span>{{ persona.identity }}</span>\n </div>\n }\n @if (persona.physical) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Physical</span>\n <span>{{ persona.physical }}</span>\n </div>\n }\n @if (persona.personality) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Personality</span>\n <span>{{ persona.personality }}</span>\n </div>\n }\n @if (persona.communication) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Communication</span>\n <span>{{ persona.communication }}</span>\n </div>\n }\n @if (persona.background) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Background</span>\n <span>{{ persona.background }}</span>\n </div>\n }\n @if (persona.psychology) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Psychology</span>\n <span>{{ persona.psychology }}</span>\n </div>\n }\n @if (persona.capabilities) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Capabilities</span>\n <span>{{ persona.capabilities }}</span>\n </div>\n }\n @if (persona.social) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Social</span>\n <span>{{ persona.social }}</span>\n </div>\n }\n @if (persona.preferences) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Preferences</span>\n <span>{{ persona.preferences }}</span>\n </div>\n }\n @if (persona.situation) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Situation</span>\n <span>{{ persona.situation }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Conversation Settings -->\n @if (entity()?.conversationSettings) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Conversation Settings</h4>\n <div class=\"settings-chips\">\n @if (entity()?.conversationSettings?.conversationType) {\n <p-tag [value]=\"entity()!.conversationSettings!.conversationType!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.conversationSettings?.textEngine) {\n <p-tag [value]=\"entity()!.conversationSettings!.textEngine!\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n @if (entity()?.conversationSettings?.autoStart) {\n <p-tag value=\"Auto Start\" severity=\"success\" icon=\"pi pi-play\" />\n }\n @if (entity()?.conversationSettings?.userMustStart) {\n <p-tag value=\"User Starts\" severity=\"warn\" icon=\"pi pi-user\" />\n }\n </div>\n </div>\n }\n\n <!-- Voices -->\n @if (entity()?.conversationSettings?.mainVoice?.voice) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-volume-up\"></i> Voices</h4>\n <div class=\"voice-info\">\n <p><span class=\"field-label\">Main:</span> {{ entity()!.conversationSettings!.mainVoice!.voice }}</p>\n @if (entity()?.conversationSettings?.secondaryVoice?.voice) {\n <p><span class=\"field-label\">Secondary:</span> {{ entity()!.conversationSettings!.secondaryVoice!.voice }}</p>\n }\n </div>\n </div>\n }\n\n</div>\n}\n\n@if (entity()?.manageable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Manageable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.manageable?.isPublic) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if (entity()?.learnable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Learnable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.learnable?.level) {\n <p-tag [value]=\"'Level ' + entity()!.learnable!.level!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.learnable?.tags) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if(entity()?.conversationFlow) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-tags\"></i> Conversation Flow</h4>\n\n @if (entity()?.conversationFlow?.moodState) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-face-smile\"></i> Mood State</h5>\n <div class=\"settings-chips\">\n @if (entity()!.conversationFlow!.moodState!.enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"danger\" icon=\"pi pi-times\" />\n }\n @if (entity()!.conversationFlow!.moodState!.useAssetStatesOnly) {\n <p-tag value=\"Asset States Only\" severity=\"warn\" icon=\"pi pi-images\" />\n }\n </div>\n @if (entity()!.conversationFlow!.moodState!.detectableStates?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.5rem;\">\n @for (state of entity()!.conversationFlow!.moodState!.detectableStates; track $index) {\n <p-tag [value]=\"state\" severity=\"info\" icon=\"pi pi-tag\" />\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.dynamicConditions?.length) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-sliders-v\"></i> Dynamic Conditions</h5>\n @for (condition of entity()!.conversationFlow!.dynamicConditions!; track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <div class=\"settings-chips\">\n <p-tag [value]=\"condition.what\" severity=\"info\" icon=\"pi pi-filter\" />\n <p-tag [value]=\"condition.when\" severity=\"secondary\" />\n <p-tag [value]=\"condition.value + ''\" severity=\"warn\" />\n </div>\n @if (condition.do?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @for (action of condition.do!; track $index) {\n <p-tag [value]=\"action.actionType\" severity=\"contrast\" icon=\"pi pi-bolt\" />\n @if (action.prompt) {\n <span class=\"field-label\" style=\"font-size: 0.75rem;\">{{ action.prompt | slice:0:60 }}\u2026</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.triggerTasks) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-bolt\"></i> Trigger Tasks</h5>\n @for (entry of objectEntries(entity()!.conversationFlow!.triggerTasks!); track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <span class=\"field-label\">{{ entry[0] }}</span>\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @if (entry[1].enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"secondary\" icon=\"pi pi-times\" />\n }\n @if (entry[1].disableFeature) {\n <p-tag value=\"Feature Disabled\" severity=\"danger\" icon=\"pi pi-ban\" />\n }\n </div>\n @if (entry[1].task) {\n <p style=\"font-size: 0.8rem; margin: 0.25rem 0 0;\">{{ entry[1].task | slice:0:120 }}\u2026</p>\n }\n </div>\n }\n </div>\n }\n</div>\n}\n\n<!-- Video Dialog -->\n<p-dialog\n [visible]=\"videoDialogVisible()\"\n (visibleChange)=\"$event ? null : closeMotionVideo()\"\n [header]=\"selectedMotion()?.metadata?.moodState || selectedMotion()?.metadata?.event || 'Video'\"\n [modal]=\"true\"\n [dismissableMask]=\"true\"\n [closable]=\"true\"\n styleClass=\"video-dialog\"\n [style]=\"{ width: '560px' }\">\n\n @if (selectedMotion()?.url) {\n <video\n class=\"motion-video\"\n [src]=\"selectedMotion().url\"\n controls\n autoplay>\n </video>\n }\n</p-dialog>\n", styles: [".preview-container{padding:.5rem}.preview-banner{width:100%;height:210px;overflow:hidden;border-radius:8px;margin-bottom:0}.banner-image{width:100%;height:100%;object-fit:cover;display:block}.preview-header{display:flex;gap:1.5rem;align-items:flex-start;padding:1rem 0 .5rem}.preview-header.has-banner{padding-top:.75rem}.preview-image{width:120px;height:170px;object-fit:cover;border-radius:8px;flex-shrink:0;box-shadow:0 2px 8px #00000026}.preview-header-info{display:flex;flex-direction:column;gap:.5rem}.preview-name{margin:0 0 .25rem;font-size:1.5rem;font-weight:700}.preview-meta-tags{display:flex;flex-wrap:wrap;gap:.35rem}.preview-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.25rem}.preview-entity-description{color:var(--p-text-muted-color);font-size:.9rem;margin:.5rem 0}.preview-entity-description p{margin:0}.preview-section{margin-bottom:1rem}.section-title{margin:0 0 .5rem;font-size:.95rem;font-weight:600;color:var(--p-text-muted-color);display:flex;align-items:center;gap:.4rem}.greeting-item{margin:.25rem 0;padding-left:.5rem;border-left:2px solid var(--p-primary-color)}.first-message{background:var(--p-surface-100);border-radius:6px;padding:.75rem;font-style:italic}.persona-grid{display:flex;flex-direction:column;gap:.5rem}.persona-field{display:flex;flex-direction:column;gap:.15rem}.field-label{font-size:.8rem;font-weight:600;color:var(--p-text-muted-color);text-transform:uppercase;letter-spacing:.05em}.motions-top-section{margin-top:.75rem;margin-bottom:0}.motions-grid{display:flex;flex-wrap:wrap;gap:.4rem}.motion-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .65rem;border-radius:20px;border:1px solid var(--p-surface-300);background:var(--p-surface-100);color:var(--p-text-color);font-size:.8rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,transform .1s;text-transform:capitalize}.motion-chip i{font-size:.85rem;color:var(--p-primary-color)}.motion-chip:hover{background:var(--p-primary-50, #f0f4ff);border-color:var(--p-primary-color);transform:translateY(-1px)}.motion-chip:active{transform:translateY(0)}.motion-video{width:100%;border-radius:6px;display:block}.settings-chips{display:flex;flex-wrap:wrap;gap:.4rem}.voice-info{display:flex;flex-direction:column;gap:.25rem}.loading-state{display:flex;justify-content:center;padding:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CardModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i1$3.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i3$3.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: ButtonModule }, { kind: "pipe", type: i2$1.SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6034
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcAgentCardDetailComponent, isStandalone: true, selector: "dc-agent-card-detail", inputs: { entityData: { classPropertyName: "entityData", publicName: "entityData", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "@if (isLoading()) {\n<div class=\"loading-state\">\n <p-progressSpinner strokeWidth=\"4\" />\n</div>\n} @else if (entity()) {\n<div class=\"preview-container\">\n\n <!-- Banner -->\n @if (bannerUrl) {\n <div class=\"preview-banner\">\n <img class=\"banner-image\" [src]=\"bannerUrl\" alt=\"banner\" />\n </div>\n }\n\n <!-- Header: image + name + meta -->\n <div class=\"preview-header\" [class.has-banner]=\"bannerUrl\">\n @if (entity()?.assets?.image?.url) {\n <img class=\"preview-image\" [src]=\"entity()!.assets!.image!.url\" [alt]=\"characterData?.name || entity()?.name\" />\n }\n <div class=\"preview-header-info\">\n <h2 class=\"preview-name\">{{ characterData?.name || entity()?.name }}</h2>\n\n <div class=\"preview-meta-tags\">\n @if (entity()?.lang) {\n <p-tag [value]=\"entity()!.lang!\" severity=\"secondary\" icon=\"pi pi-flag\" />\n }\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-circle-fill\" />\n }\n @if (characterData?.gender) {\n <p-tag [value]=\"characterData!.gender\" severity=\"secondary\" icon=\"pi pi-user\" />\n }\n @if (entity()?.metaApp?.takenCount) {\n <p-tag [value]=\"'Taken: ' + entity()!.metaApp!.takenCount\" severity=\"success\" icon=\"pi pi-users\" />\n }\n @if (learnableInfo?.level) {\n <p-tag [value]=\"'Level ' + learnableInfo.level\" severity=\"warn\" icon=\"pi pi-star\" />\n }\n @if (learnableInfo?.takenCount) {\n <p-tag [value]=\"'Played: ' + learnableInfo.takenCount\" severity=\"secondary\" icon=\"pi pi-play\" />\n }\n </div>\n\n @if (characterData?.tags?.length) {\n <div class=\"preview-tags\">\n @for (tag of characterData!.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Entity-level description -->\n @if (entity()?.description) {\n <div class=\"preview-entity-description\">\n <p>{{ entity()!.description }}</p>\n </div>\n }\n\n <!-- Motion Videos -->\n @if (motions.length) {\n <div class=\"preview-section motions-top-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-video\"></i> Motion Videos ({{ motions.length }})</h4>\n <div class=\"motions-grid\">\n @for (motion of motions; track $index) {\n @if (motion.metadata?.moodState || motion.metadata?.event) {\n <button class=\"motion-chip\" (click)=\"openMotionVideo(motion)\">\n <i class=\"pi pi-play-circle\"></i>\n <span>{{ motion.metadata?.moodState || motion.metadata?.event }}</span>\n </button>\n }\n }\n </div>\n </div>\n }\n\n <p-divider />\n\n @if (characterData?.hook) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-bookmark\"></i> Hook</h4>\n <p>{{ characterData!.hook }}</p>\n </div>\n }\n\n @if (characterData?.instructions) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-info-circle\"></i> Instructions</h4>\n <p>{{ characterData!.instructions }}</p>\n </div>\n }\n\n @if (characterData?.scenario) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-map\"></i> Scenario</h4>\n <p>{{ characterData!.scenario }}</p>\n </div>\n }\n\n @if (characterData?.creator_notes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-file\"></i> Creator Notes</h4>\n <p>{{ characterData!.creator_notes }}</p>\n </div>\n }\n\n @if (characterData?.description) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-align-left\"></i> Description</h4>\n <p>{{ characterData!.description }}</p>\n </div>\n }\n\n @if (characterData?.greetings?.length) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comments\"></i> Greetings</h4>\n @for (greeting of characterData!.greetings; track $index) {\n <p class=\"greeting-item\"><i class=\"pi pi-chevron-right\"></i> {{ greeting }}</p>\n }\n </div>\n }\n\n\n @if (persona) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-id-card\"></i> Persona</h4>\n <div class=\"persona-grid\">\n @if (persona.identity) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Identity</span>\n <span>{{ persona.identity }}</span>\n </div>\n }\n @if (persona.physical) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Physical</span>\n <span>{{ persona.physical }}</span>\n </div>\n }\n @if (persona.personality) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Personality</span>\n <span>{{ persona.personality }}</span>\n </div>\n }\n @if (persona.communication) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Communication</span>\n <span>{{ persona.communication }}</span>\n </div>\n }\n @if (persona.background) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Background</span>\n <span>{{ persona.background }}</span>\n </div>\n }\n @if (persona.psychology) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Psychology</span>\n <span>{{ persona.psychology }}</span>\n </div>\n }\n @if (persona.capabilities) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Capabilities</span>\n <span>{{ persona.capabilities }}</span>\n </div>\n }\n @if (persona.social) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Social</span>\n <span>{{ persona.social }}</span>\n </div>\n }\n @if (persona.preferences) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Preferences</span>\n <span>{{ persona.preferences }}</span>\n </div>\n }\n @if (persona.situation) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Situation</span>\n <span>{{ persona.situation }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Conversation Settings -->\n @if (entity()?.conversationSettings) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Conversation Settings</h4>\n <div class=\"settings-chips\">\n @if (entity()?.conversationSettings?.conversationType) {\n <p-tag [value]=\"entity()!.conversationSettings!.conversationType!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.conversationSettings?.textEngine) {\n <p-tag [value]=\"entity()!.conversationSettings!.textEngine!\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n @if (entity()?.conversationSettings?.autoStart) {\n <p-tag value=\"Auto Start\" severity=\"success\" icon=\"pi pi-play\" />\n }\n @if (entity()?.conversationSettings?.userMustStart) {\n <p-tag value=\"User Starts\" severity=\"warn\" icon=\"pi pi-user\" />\n }\n </div>\n </div>\n }\n\n <!-- Voices -->\n @if (entity()?.conversationSettings?.mainVoice?.voice) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-volume-up\"></i> Voices</h4>\n <div class=\"voice-info\">\n <p><span class=\"field-label\">Main:</span> {{ entity()!.conversationSettings!.mainVoice!.voice }}</p>\n @if (entity()?.conversationSettings?.secondaryVoice?.voice) {\n <p><span class=\"field-label\">Secondary:</span> {{ entity()!.conversationSettings!.secondaryVoice!.voice }}</p>\n }\n </div>\n </div>\n }\n\n</div>\n}\n\n@if (entity()?.manageable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Manageable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.manageable?.isPublic) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if (entity()?.learnable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Learnable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.learnable?.level) {\n <p-tag [value]=\"'Level ' + entity()!.learnable!.level!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.learnable?.tags) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if(entity()?.conversationFlow) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-tags\"></i> Conversation Flow</h4>\n\n @if (entity()?.conversationFlow?.moodState) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-face-smile\"></i> Mood State</h5>\n <div class=\"settings-chips\">\n @if (entity()!.conversationFlow!.moodState!.enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"danger\" icon=\"pi pi-times\" />\n }\n @if (entity()!.conversationFlow!.moodState!.useAssetStatesOnly) {\n <p-tag value=\"Asset States Only\" severity=\"warn\" icon=\"pi pi-images\" />\n }\n </div>\n @if (entity()!.conversationFlow!.moodState!.detectableStates?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.5rem;\">\n @for (state of entity()!.conversationFlow!.moodState!.detectableStates; track $index) {\n <p-tag [value]=\"state\" severity=\"info\" icon=\"pi pi-tag\" />\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.dynamicConditions?.length) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-sliders-v\"></i> Dynamic Conditions</h5>\n @for (condition of entity()!.conversationFlow!.dynamicConditions!; track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <div class=\"settings-chips\">\n <p-tag [value]=\"condition.what\" severity=\"info\" icon=\"pi pi-filter\" />\n <p-tag [value]=\"condition.when\" severity=\"secondary\" />\n <p-tag [value]=\"condition.value + ''\" severity=\"warn\" />\n </div>\n @if (condition.do?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @for (action of condition.do!; track $index) {\n <p-tag [value]=\"action.actionType\" severity=\"contrast\" icon=\"pi pi-bolt\" />\n @if (action.prompt) {\n <span class=\"field-label\" style=\"font-size: 0.75rem;\">{{ action.prompt | slice:0:60 }}\u2026</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.triggerTasks) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-bolt\"></i> Trigger Tasks</h5>\n @for (entry of objectEntries(entity()!.conversationFlow!.triggerTasks!); track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <span class=\"field-label\">{{ entry[0] }}</span>\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @if (entry[1].enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"secondary\" icon=\"pi pi-times\" />\n }\n @if (entry[1].disableFeature) {\n <p-tag value=\"Feature Disabled\" severity=\"danger\" icon=\"pi pi-ban\" />\n }\n </div>\n @if (entry[1].task) {\n <p style=\"font-size: 0.8rem; margin: 0.25rem 0 0;\">{{ entry[1].task | slice:0:120 }}\u2026</p>\n }\n </div>\n }\n </div>\n }\n</div>\n}\n\n<!-- Video Dialog -->\n<p-dialog\n [visible]=\"videoDialogVisible()\"\n (visibleChange)=\"$event ? null : closeMotionVideo()\"\n [header]=\"selectedMotion()?.metadata?.moodState || selectedMotion()?.metadata?.event || 'Video'\"\n [modal]=\"true\"\n [dismissableMask]=\"true\"\n [closable]=\"true\"\n styleClass=\"video-dialog\"\n [style]=\"{ width: '560px' }\">\n\n @if (selectedMotion()?.url) {\n <video\n class=\"motion-video\"\n [src]=\"selectedMotion().url\"\n controls\n autoplay>\n </video>\n }\n</p-dialog>\n", styles: [".preview-container{padding:.5rem}.preview-banner{width:100%;height:210px;overflow:hidden;border-radius:8px;margin-bottom:0}.banner-image{width:100%;height:100%;object-fit:cover;display:block}.preview-header{display:flex;gap:1.5rem;align-items:flex-start;padding:1rem 0 .5rem}.preview-header.has-banner{padding-top:.75rem}.preview-image{width:120px;height:170px;object-fit:cover;border-radius:8px;flex-shrink:0;box-shadow:0 2px 8px #00000026}.preview-header-info{display:flex;flex-direction:column;gap:.5rem}.preview-name{margin:0 0 .25rem;font-size:1.5rem;font-weight:700}.preview-meta-tags{display:flex;flex-wrap:wrap;gap:.35rem}.preview-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.25rem}.preview-entity-description{color:var(--p-text-muted-color);font-size:.9rem;margin:.5rem 0}.preview-entity-description p{margin:0}.preview-section{margin-bottom:1rem}.section-title{margin:0 0 .5rem;font-size:.95rem;font-weight:600;color:var(--p-text-muted-color);display:flex;align-items:center;gap:.4rem}.greeting-item{margin:.25rem 0;padding-left:.5rem;border-left:2px solid var(--p-primary-color)}.first-message{background:var(--p-surface-100);border-radius:6px;padding:.75rem;font-style:italic}.persona-grid{display:flex;flex-direction:column;gap:.5rem}.persona-field{display:flex;flex-direction:column;gap:.15rem}.field-label{font-size:.8rem;font-weight:600;color:var(--p-text-muted-color);text-transform:uppercase;letter-spacing:.05em}.motions-top-section{margin-top:.75rem;margin-bottom:0}.motions-grid{display:flex;flex-wrap:wrap;gap:.4rem}.motion-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .65rem;border-radius:20px;border:1px solid var(--p-surface-300);background:var(--p-surface-100);color:var(--p-text-color);font-size:.8rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,transform .1s;text-transform:capitalize}.motion-chip i{font-size:.85rem;color:var(--p-primary-color)}.motion-chip:hover{background:var(--p-primary-50, #f0f4ff);border-color:var(--p-primary-color);transform:translateY(-1px)}.motion-chip:active{transform:translateY(0)}.motion-video{width:100%;border-radius:6px;display:block}.settings-chips{display:flex;flex-wrap:wrap;gap:.4rem}.voice-info{display:flex;flex-direction:column;gap:.25rem}.loading-state{display:flex;justify-content:center;padding:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: CardModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$3.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i3$2.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: ButtonModule }, { kind: "pipe", type: i2$1.SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5601
6035
  }
5602
6036
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcAgentCardDetailComponent, decorators: [{
5603
6037
  type: Component,
5604
- args: [{ selector: 'dc-agent-card-detail', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, CardModule, TagModule, DividerModule, ProgressSpinnerModule, DialogModule, ButtonModule], template: "@if (isLoading()) {\n<div class=\"loading-state\">\n <p-progressSpinner strokeWidth=\"4\" />\n</div>\n} @else if (entity()) {\n<div class=\"preview-container\">\n\n <!-- Banner -->\n @if (bannerUrl) {\n <div class=\"preview-banner\">\n <img class=\"banner-image\" [src]=\"bannerUrl\" alt=\"banner\" />\n </div>\n }\n\n <!-- Header: image + name + meta -->\n <div class=\"preview-header\" [class.has-banner]=\"bannerUrl\">\n @if (entity()?.assets?.image?.url) {\n <img class=\"preview-image\" [src]=\"entity()!.assets!.image!.url\" [alt]=\"characterData?.name || entity()?.name\" />\n }\n <div class=\"preview-header-info\">\n <h2 class=\"preview-name\">{{ characterData?.name || entity()?.name }}</h2>\n\n <div class=\"preview-meta-tags\">\n @if (entity()?.lang) {\n <p-tag [value]=\"entity()!.lang!\" severity=\"secondary\" icon=\"pi pi-flag\" />\n }\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-circle-fill\" />\n }\n @if (characterData?.gender) {\n <p-tag [value]=\"characterData!.gender\" severity=\"secondary\" icon=\"pi pi-user\" />\n }\n @if (entity()?.metaApp?.takenCount) {\n <p-tag [value]=\"'Taken: ' + entity()!.metaApp!.takenCount\" severity=\"success\" icon=\"pi pi-users\" />\n }\n @if (learnableInfo?.level) {\n <p-tag [value]=\"'Level ' + learnableInfo.level\" severity=\"warn\" icon=\"pi pi-star\" />\n }\n @if (learnableInfo?.takenCount) {\n <p-tag [value]=\"'Played: ' + learnableInfo.takenCount\" severity=\"secondary\" icon=\"pi pi-play\" />\n }\n </div>\n\n @if (characterData?.tags?.length) {\n <div class=\"preview-tags\">\n @for (tag of characterData!.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Entity-level description -->\n @if (entity()?.description) {\n <div class=\"preview-entity-description\">\n <p>{{ entity()!.description }}</p>\n </div>\n }\n\n <!-- Motion Videos -->\n @if (motions.length) {\n <div class=\"preview-section motions-top-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-video\"></i> Motion Videos ({{ motions.length }})</h4>\n <div class=\"motions-grid\">\n @for (motion of motions; track $index) {\n @if (motion.metadata?.moodState || motion.metadata?.event) {\n <button class=\"motion-chip\" (click)=\"openMotionVideo(motion)\">\n <i class=\"pi pi-play-circle\"></i>\n <span>{{ motion.metadata?.moodState || motion.metadata?.event }}</span>\n </button>\n }\n }\n </div>\n </div>\n }\n\n <p-divider />\n\n @if (characterData?.hook) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-bookmark\"></i> Hook</h4>\n <p>{{ characterData!.hook }}</p>\n </div>\n }\n\n @if (characterData?.instructions) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-info-circle\"></i> Instructions</h4>\n <p>{{ characterData!.instructions }}</p>\n </div>\n }\n\n @if (characterData?.scenario) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-map\"></i> Scenario</h4>\n <p>{{ characterData!.scenario }}</p>\n </div>\n }\n\n @if (characterData?.creator_notes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-file\"></i> Creator Notes</h4>\n <p>{{ characterData!.creator_notes }}</p>\n </div>\n }\n\n @if (characterData?.description) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-align-left\"></i> Description</h4>\n <p>{{ characterData!.description }}</p>\n </div>\n }\n\n @if (characterData?.greetings?.length) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comments\"></i> Greetings</h4>\n @for (greeting of characterData!.greetings; track $index) {\n <p class=\"greeting-item\"><i class=\"pi pi-chevron-right\"></i> {{ greeting }}</p>\n }\n </div>\n }\n\n @if (characterData?.first_mes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comment\"></i> First Message</h4>\n <p class=\"first-message\">{{ characterData!.first_mes }}</p>\n </div>\n }\n\n @if (persona) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-id-card\"></i> Persona</h4>\n <div class=\"persona-grid\">\n @if (persona.identity) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Identity</span>\n <span>{{ persona.identity }}</span>\n </div>\n }\n @if (persona.physical) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Physical</span>\n <span>{{ persona.physical }}</span>\n </div>\n }\n @if (persona.personality) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Personality</span>\n <span>{{ persona.personality }}</span>\n </div>\n }\n @if (persona.communication) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Communication</span>\n <span>{{ persona.communication }}</span>\n </div>\n }\n @if (persona.background) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Background</span>\n <span>{{ persona.background }}</span>\n </div>\n }\n @if (persona.psychology) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Psychology</span>\n <span>{{ persona.psychology }}</span>\n </div>\n }\n @if (persona.capabilities) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Capabilities</span>\n <span>{{ persona.capabilities }}</span>\n </div>\n }\n @if (persona.social) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Social</span>\n <span>{{ persona.social }}</span>\n </div>\n }\n @if (persona.preferences) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Preferences</span>\n <span>{{ persona.preferences }}</span>\n </div>\n }\n @if (persona.situation) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Situation</span>\n <span>{{ persona.situation }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Conversation Settings -->\n @if (entity()?.conversationSettings) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Conversation Settings</h4>\n <div class=\"settings-chips\">\n @if (entity()?.conversationSettings?.conversationType) {\n <p-tag [value]=\"entity()!.conversationSettings!.conversationType!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.conversationSettings?.textEngine) {\n <p-tag [value]=\"entity()!.conversationSettings!.textEngine!\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n @if (entity()?.conversationSettings?.autoStart) {\n <p-tag value=\"Auto Start\" severity=\"success\" icon=\"pi pi-play\" />\n }\n @if (entity()?.conversationSettings?.userMustStart) {\n <p-tag value=\"User Starts\" severity=\"warn\" icon=\"pi pi-user\" />\n }\n </div>\n </div>\n }\n\n <!-- Voices -->\n @if (entity()?.conversationSettings?.mainVoice?.voice) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-volume-up\"></i> Voices</h4>\n <div class=\"voice-info\">\n <p><span class=\"field-label\">Main:</span> {{ entity()!.conversationSettings!.mainVoice!.voice }}</p>\n @if (entity()?.conversationSettings?.secondaryVoice?.voice) {\n <p><span class=\"field-label\">Secondary:</span> {{ entity()!.conversationSettings!.secondaryVoice!.voice }}</p>\n }\n </div>\n </div>\n }\n\n</div>\n}\n\n@if (entity()?.manageable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Manageable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.manageable?.isPublic) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if (entity()?.learnable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Learnable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.learnable?.level) {\n <p-tag [value]=\"'Level ' + entity()!.learnable!.level!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.learnable?.tags) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if(entity()?.conversationFlow) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-tags\"></i> Conversation Flow</h4>\n\n @if (entity()?.conversationFlow?.moodState) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-face-smile\"></i> Mood State</h5>\n <div class=\"settings-chips\">\n @if (entity()!.conversationFlow!.moodState!.enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"danger\" icon=\"pi pi-times\" />\n }\n @if (entity()!.conversationFlow!.moodState!.useAssetStatesOnly) {\n <p-tag value=\"Asset States Only\" severity=\"warn\" icon=\"pi pi-images\" />\n }\n </div>\n @if (entity()!.conversationFlow!.moodState!.detectableStates?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.5rem;\">\n @for (state of entity()!.conversationFlow!.moodState!.detectableStates; track $index) {\n <p-tag [value]=\"state\" severity=\"info\" icon=\"pi pi-tag\" />\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.dynamicConditions?.length) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-sliders-v\"></i> Dynamic Conditions</h5>\n @for (condition of entity()!.conversationFlow!.dynamicConditions!; track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <div class=\"settings-chips\">\n <p-tag [value]=\"condition.what\" severity=\"info\" icon=\"pi pi-filter\" />\n <p-tag [value]=\"condition.when\" severity=\"secondary\" />\n <p-tag [value]=\"condition.value + ''\" severity=\"warn\" />\n </div>\n @if (condition.do?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @for (action of condition.do!; track $index) {\n <p-tag [value]=\"action.actionType\" severity=\"contrast\" icon=\"pi pi-bolt\" />\n @if (action.prompt) {\n <span class=\"field-label\" style=\"font-size: 0.75rem;\">{{ action.prompt | slice:0:60 }}\u2026</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.triggerTasks) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-bolt\"></i> Trigger Tasks</h5>\n @for (entry of objectEntries(entity()!.conversationFlow!.triggerTasks!); track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <span class=\"field-label\">{{ entry[0] }}</span>\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @if (entry[1].enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"secondary\" icon=\"pi pi-times\" />\n }\n @if (entry[1].disableFeature) {\n <p-tag value=\"Feature Disabled\" severity=\"danger\" icon=\"pi pi-ban\" />\n }\n </div>\n @if (entry[1].task) {\n <p style=\"font-size: 0.8rem; margin: 0.25rem 0 0;\">{{ entry[1].task | slice:0:120 }}\u2026</p>\n }\n </div>\n }\n </div>\n }\n</div>\n}\n\n<!-- Video Dialog -->\n<p-dialog\n [visible]=\"videoDialogVisible()\"\n (visibleChange)=\"$event ? null : closeMotionVideo()\"\n [header]=\"selectedMotion()?.metadata?.moodState || selectedMotion()?.metadata?.event || 'Video'\"\n [modal]=\"true\"\n [dismissableMask]=\"true\"\n [closable]=\"true\"\n styleClass=\"video-dialog\"\n [style]=\"{ width: '560px' }\">\n\n @if (selectedMotion()?.url) {\n <video\n class=\"motion-video\"\n [src]=\"selectedMotion().url\"\n controls\n autoplay>\n </video>\n }\n</p-dialog>\n", styles: [".preview-container{padding:.5rem}.preview-banner{width:100%;height:210px;overflow:hidden;border-radius:8px;margin-bottom:0}.banner-image{width:100%;height:100%;object-fit:cover;display:block}.preview-header{display:flex;gap:1.5rem;align-items:flex-start;padding:1rem 0 .5rem}.preview-header.has-banner{padding-top:.75rem}.preview-image{width:120px;height:170px;object-fit:cover;border-radius:8px;flex-shrink:0;box-shadow:0 2px 8px #00000026}.preview-header-info{display:flex;flex-direction:column;gap:.5rem}.preview-name{margin:0 0 .25rem;font-size:1.5rem;font-weight:700}.preview-meta-tags{display:flex;flex-wrap:wrap;gap:.35rem}.preview-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.25rem}.preview-entity-description{color:var(--p-text-muted-color);font-size:.9rem;margin:.5rem 0}.preview-entity-description p{margin:0}.preview-section{margin-bottom:1rem}.section-title{margin:0 0 .5rem;font-size:.95rem;font-weight:600;color:var(--p-text-muted-color);display:flex;align-items:center;gap:.4rem}.greeting-item{margin:.25rem 0;padding-left:.5rem;border-left:2px solid var(--p-primary-color)}.first-message{background:var(--p-surface-100);border-radius:6px;padding:.75rem;font-style:italic}.persona-grid{display:flex;flex-direction:column;gap:.5rem}.persona-field{display:flex;flex-direction:column;gap:.15rem}.field-label{font-size:.8rem;font-weight:600;color:var(--p-text-muted-color);text-transform:uppercase;letter-spacing:.05em}.motions-top-section{margin-top:.75rem;margin-bottom:0}.motions-grid{display:flex;flex-wrap:wrap;gap:.4rem}.motion-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .65rem;border-radius:20px;border:1px solid var(--p-surface-300);background:var(--p-surface-100);color:var(--p-text-color);font-size:.8rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,transform .1s;text-transform:capitalize}.motion-chip i{font-size:.85rem;color:var(--p-primary-color)}.motion-chip:hover{background:var(--p-primary-50, #f0f4ff);border-color:var(--p-primary-color);transform:translateY(-1px)}.motion-chip:active{transform:translateY(0)}.motion-video{width:100%;border-radius:6px;display:block}.settings-chips{display:flex;flex-wrap:wrap;gap:.4rem}.voice-info{display:flex;flex-direction:column;gap:.25rem}.loading-state{display:flex;justify-content:center;padding:2rem}\n"] }]
6038
+ args: [{ selector: 'dc-agent-card-detail', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, CardModule, TagModule, DividerModule, ProgressSpinnerModule, DialogModule, ButtonModule], template: "@if (isLoading()) {\n<div class=\"loading-state\">\n <p-progressSpinner strokeWidth=\"4\" />\n</div>\n} @else if (entity()) {\n<div class=\"preview-container\">\n\n <!-- Banner -->\n @if (bannerUrl) {\n <div class=\"preview-banner\">\n <img class=\"banner-image\" [src]=\"bannerUrl\" alt=\"banner\" />\n </div>\n }\n\n <!-- Header: image + name + meta -->\n <div class=\"preview-header\" [class.has-banner]=\"bannerUrl\">\n @if (entity()?.assets?.image?.url) {\n <img class=\"preview-image\" [src]=\"entity()!.assets!.image!.url\" [alt]=\"characterData?.name || entity()?.name\" />\n }\n <div class=\"preview-header-info\">\n <h2 class=\"preview-name\">{{ characterData?.name || entity()?.name }}</h2>\n\n <div class=\"preview-meta-tags\">\n @if (entity()?.lang) {\n <p-tag [value]=\"entity()!.lang!\" severity=\"secondary\" icon=\"pi pi-flag\" />\n }\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-circle-fill\" />\n }\n @if (characterData?.gender) {\n <p-tag [value]=\"characterData!.gender\" severity=\"secondary\" icon=\"pi pi-user\" />\n }\n @if (entity()?.metaApp?.takenCount) {\n <p-tag [value]=\"'Taken: ' + entity()!.metaApp!.takenCount\" severity=\"success\" icon=\"pi pi-users\" />\n }\n @if (learnableInfo?.level) {\n <p-tag [value]=\"'Level ' + learnableInfo.level\" severity=\"warn\" icon=\"pi pi-star\" />\n }\n @if (learnableInfo?.takenCount) {\n <p-tag [value]=\"'Played: ' + learnableInfo.takenCount\" severity=\"secondary\" icon=\"pi pi-play\" />\n }\n </div>\n\n @if (characterData?.tags?.length) {\n <div class=\"preview-tags\">\n @for (tag of characterData!.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n </div>\n\n <!-- Entity-level description -->\n @if (entity()?.description) {\n <div class=\"preview-entity-description\">\n <p>{{ entity()!.description }}</p>\n </div>\n }\n\n <!-- Motion Videos -->\n @if (motions.length) {\n <div class=\"preview-section motions-top-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-video\"></i> Motion Videos ({{ motions.length }})</h4>\n <div class=\"motions-grid\">\n @for (motion of motions; track $index) {\n @if (motion.metadata?.moodState || motion.metadata?.event) {\n <button class=\"motion-chip\" (click)=\"openMotionVideo(motion)\">\n <i class=\"pi pi-play-circle\"></i>\n <span>{{ motion.metadata?.moodState || motion.metadata?.event }}</span>\n </button>\n }\n }\n </div>\n </div>\n }\n\n <p-divider />\n\n @if (characterData?.hook) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-bookmark\"></i> Hook</h4>\n <p>{{ characterData!.hook }}</p>\n </div>\n }\n\n @if (characterData?.instructions) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-info-circle\"></i> Instructions</h4>\n <p>{{ characterData!.instructions }}</p>\n </div>\n }\n\n @if (characterData?.scenario) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-map\"></i> Scenario</h4>\n <p>{{ characterData!.scenario }}</p>\n </div>\n }\n\n @if (characterData?.creator_notes) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-file\"></i> Creator Notes</h4>\n <p>{{ characterData!.creator_notes }}</p>\n </div>\n }\n\n @if (characterData?.description) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-align-left\"></i> Description</h4>\n <p>{{ characterData!.description }}</p>\n </div>\n }\n\n @if (characterData?.greetings?.length) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-comments\"></i> Greetings</h4>\n @for (greeting of characterData!.greetings; track $index) {\n <p class=\"greeting-item\"><i class=\"pi pi-chevron-right\"></i> {{ greeting }}</p>\n }\n </div>\n }\n\n\n @if (persona) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-id-card\"></i> Persona</h4>\n <div class=\"persona-grid\">\n @if (persona.identity) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Identity</span>\n <span>{{ persona.identity }}</span>\n </div>\n }\n @if (persona.physical) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Physical</span>\n <span>{{ persona.physical }}</span>\n </div>\n }\n @if (persona.personality) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Personality</span>\n <span>{{ persona.personality }}</span>\n </div>\n }\n @if (persona.communication) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Communication</span>\n <span>{{ persona.communication }}</span>\n </div>\n }\n @if (persona.background) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Background</span>\n <span>{{ persona.background }}</span>\n </div>\n }\n @if (persona.psychology) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Psychology</span>\n <span>{{ persona.psychology }}</span>\n </div>\n }\n @if (persona.capabilities) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Capabilities</span>\n <span>{{ persona.capabilities }}</span>\n </div>\n }\n @if (persona.social) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Social</span>\n <span>{{ persona.social }}</span>\n </div>\n }\n @if (persona.preferences) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Preferences</span>\n <span>{{ persona.preferences }}</span>\n </div>\n }\n @if (persona.situation) {\n <div class=\"persona-field\">\n <span class=\"field-label\">Situation</span>\n <span>{{ persona.situation }}</span>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Conversation Settings -->\n @if (entity()?.conversationSettings) {\n <p-divider />\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Conversation Settings</h4>\n <div class=\"settings-chips\">\n @if (entity()?.conversationSettings?.conversationType) {\n <p-tag [value]=\"entity()!.conversationSettings!.conversationType!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.conversationSettings?.textEngine) {\n <p-tag [value]=\"entity()!.conversationSettings!.textEngine!\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n @if (entity()?.conversationSettings?.autoStart) {\n <p-tag value=\"Auto Start\" severity=\"success\" icon=\"pi pi-play\" />\n }\n @if (entity()?.conversationSettings?.userMustStart) {\n <p-tag value=\"User Starts\" severity=\"warn\" icon=\"pi pi-user\" />\n }\n </div>\n </div>\n }\n\n <!-- Voices -->\n @if (entity()?.conversationSettings?.mainVoice?.voice) {\n <div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-volume-up\"></i> Voices</h4>\n <div class=\"voice-info\">\n <p><span class=\"field-label\">Main:</span> {{ entity()!.conversationSettings!.mainVoice!.voice }}</p>\n @if (entity()?.conversationSettings?.secondaryVoice?.voice) {\n <p><span class=\"field-label\">Secondary:</span> {{ entity()!.conversationSettings!.secondaryVoice!.voice }}</p>\n }\n </div>\n </div>\n }\n\n</div>\n}\n\n@if (entity()?.manageable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Manageable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.manageable?.status) {\n <p-tag [value]=\"entity()!.manageable!.status!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.manageable?.isPublic) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if (entity()?.learnable) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-sliders-h\"></i> Learnable</h4>\n <div class=\"settings-chips\">\n @if (entity()?.learnable?.level) {\n <p-tag [value]=\"'Level ' + entity()!.learnable!.level!\" severity=\"info\" icon=\"pi pi-comments\" />\n }\n @if (entity()?.learnable?.tags) {\n <p-tag [value]=\"'Public'\" severity=\"secondary\" icon=\"pi pi-code\" />\n }\n </div>\n</div>\n}\n\n@if(entity()?.conversationFlow) {\n<p-divider />\n<div class=\"preview-section\">\n <h4 class=\"section-title\"><i class=\"pi pi-tags\"></i> Conversation Flow</h4>\n\n @if (entity()?.conversationFlow?.moodState) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-face-smile\"></i> Mood State</h5>\n <div class=\"settings-chips\">\n @if (entity()!.conversationFlow!.moodState!.enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"danger\" icon=\"pi pi-times\" />\n }\n @if (entity()!.conversationFlow!.moodState!.useAssetStatesOnly) {\n <p-tag value=\"Asset States Only\" severity=\"warn\" icon=\"pi pi-images\" />\n }\n </div>\n @if (entity()!.conversationFlow!.moodState!.detectableStates?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.5rem;\">\n @for (state of entity()!.conversationFlow!.moodState!.detectableStates; track $index) {\n <p-tag [value]=\"state\" severity=\"info\" icon=\"pi pi-tag\" />\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.dynamicConditions?.length) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-sliders-v\"></i> Dynamic Conditions</h5>\n @for (condition of entity()!.conversationFlow!.dynamicConditions!; track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <div class=\"settings-chips\">\n <p-tag [value]=\"condition.what\" severity=\"info\" icon=\"pi pi-filter\" />\n <p-tag [value]=\"condition.when\" severity=\"secondary\" />\n <p-tag [value]=\"condition.value + ''\" severity=\"warn\" />\n </div>\n @if (condition.do?.length) {\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @for (action of condition.do!; track $index) {\n <p-tag [value]=\"action.actionType\" severity=\"contrast\" icon=\"pi pi-bolt\" />\n @if (action.prompt) {\n <span class=\"field-label\" style=\"font-size: 0.75rem;\">{{ action.prompt | slice:0:60 }}\u2026</span>\n }\n }\n </div>\n }\n </div>\n }\n </div>\n }\n\n @if (entity()?.conversationFlow?.triggerTasks) {\n <div class=\"preview-section\">\n <h5 class=\"section-title\"><i class=\"pi pi-bolt\"></i> Trigger Tasks</h5>\n @for (entry of objectEntries(entity()!.conversationFlow!.triggerTasks!); track $index) {\n <div class=\"persona-field\" style=\"margin-bottom: 0.5rem;\">\n <span class=\"field-label\">{{ entry[0] }}</span>\n <div class=\"settings-chips\" style=\"margin-top: 0.25rem;\">\n @if (entry[1].enabled) {\n <p-tag value=\"Enabled\" severity=\"success\" icon=\"pi pi-check\" />\n } @else {\n <p-tag value=\"Disabled\" severity=\"secondary\" icon=\"pi pi-times\" />\n }\n @if (entry[1].disableFeature) {\n <p-tag value=\"Feature Disabled\" severity=\"danger\" icon=\"pi pi-ban\" />\n }\n </div>\n @if (entry[1].task) {\n <p style=\"font-size: 0.8rem; margin: 0.25rem 0 0;\">{{ entry[1].task | slice:0:120 }}\u2026</p>\n }\n </div>\n }\n </div>\n }\n</div>\n}\n\n<!-- Video Dialog -->\n<p-dialog\n [visible]=\"videoDialogVisible()\"\n (visibleChange)=\"$event ? null : closeMotionVideo()\"\n [header]=\"selectedMotion()?.metadata?.moodState || selectedMotion()?.metadata?.event || 'Video'\"\n [modal]=\"true\"\n [dismissableMask]=\"true\"\n [closable]=\"true\"\n styleClass=\"video-dialog\"\n [style]=\"{ width: '560px' }\">\n\n @if (selectedMotion()?.url) {\n <video\n class=\"motion-video\"\n [src]=\"selectedMotion().url\"\n controls\n autoplay>\n </video>\n }\n</p-dialog>\n", styles: [".preview-container{padding:.5rem}.preview-banner{width:100%;height:210px;overflow:hidden;border-radius:8px;margin-bottom:0}.banner-image{width:100%;height:100%;object-fit:cover;display:block}.preview-header{display:flex;gap:1.5rem;align-items:flex-start;padding:1rem 0 .5rem}.preview-header.has-banner{padding-top:.75rem}.preview-image{width:120px;height:170px;object-fit:cover;border-radius:8px;flex-shrink:0;box-shadow:0 2px 8px #00000026}.preview-header-info{display:flex;flex-direction:column;gap:.5rem}.preview-name{margin:0 0 .25rem;font-size:1.5rem;font-weight:700}.preview-meta-tags{display:flex;flex-wrap:wrap;gap:.35rem}.preview-tags{display:flex;flex-wrap:wrap;gap:.25rem;margin-top:.25rem}.preview-entity-description{color:var(--p-text-muted-color);font-size:.9rem;margin:.5rem 0}.preview-entity-description p{margin:0}.preview-section{margin-bottom:1rem}.section-title{margin:0 0 .5rem;font-size:.95rem;font-weight:600;color:var(--p-text-muted-color);display:flex;align-items:center;gap:.4rem}.greeting-item{margin:.25rem 0;padding-left:.5rem;border-left:2px solid var(--p-primary-color)}.first-message{background:var(--p-surface-100);border-radius:6px;padding:.75rem;font-style:italic}.persona-grid{display:flex;flex-direction:column;gap:.5rem}.persona-field{display:flex;flex-direction:column;gap:.15rem}.field-label{font-size:.8rem;font-weight:600;color:var(--p-text-muted-color);text-transform:uppercase;letter-spacing:.05em}.motions-top-section{margin-top:.75rem;margin-bottom:0}.motions-grid{display:flex;flex-wrap:wrap;gap:.4rem}.motion-chip{display:inline-flex;align-items:center;gap:.35rem;padding:.3rem .65rem;border-radius:20px;border:1px solid var(--p-surface-300);background:var(--p-surface-100);color:var(--p-text-color);font-size:.8rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s,transform .1s;text-transform:capitalize}.motion-chip i{font-size:.85rem;color:var(--p-primary-color)}.motion-chip:hover{background:var(--p-primary-50, #f0f4ff);border-color:var(--p-primary-color);transform:translateY(-1px)}.motion-chip:active{transform:translateY(0)}.motion-video{width:100%;border-radius:6px;display:block}.settings-chips{display:flex;flex-wrap:wrap;gap:.4rem}.voice-info{display:flex;flex-direction:column;gap:.25rem}.loading-state{display:flex;justify-content:center;padding:2rem}\n"] }]
5605
6039
  }], ctorParameters: () => [], propDecorators: { entityData: [{ type: i0.Input, args: [{ isSignal: true, alias: "entityData", required: false }] }] } });
5606
6040
 
6041
+ class ConversationSummaryComponent {
6042
+ constructor() {
6043
+ this.agentCard = input.required(...(ngDevMode ? [{ debugName: "agentCard" }] : /* istanbul ignore next */ []));
6044
+ this.parentInjector = input.required(...(ngDevMode ? [{ debugName: "parentInjector" }] : /* istanbul ignore next */ []));
6045
+ this.completeEvent = output();
6046
+ this.value = 0;
6047
+ this.totalMessages = computed(() => this.messageStateService.getMessagesSignal()().length, ...(ngDevMode ? [{ debugName: "totalMessages" }] : /* istanbul ignore next */ []));
6048
+ this.userMessagesCount = computed(() => this.messageStateService.getMessagesSignal()().filter((m) => m.role === 'user').length, ...(ngDevMode ? [{ debugName: "userMessagesCount" }] : /* istanbul ignore next */ []));
6049
+ this.assistantMessagesCount = computed(() => this.messageStateService.getMessagesSignal()().filter((m) => m.role === 'assistant').length, ...(ngDevMode ? [{ debugName: "assistantMessagesCount" }] : /* istanbul ignore next */ []));
6050
+ this.activeChallengesCount = computed(() => {
6051
+ const challenges = this.dynamicFlowService.conversationFlowConfig()?.challenges || [];
6052
+ return challenges.filter(c => c.enabled).length;
6053
+ }, ...(ngDevMode ? [{ debugName: "activeChallengesCount" }] : /* istanbul ignore next */ []));
6054
+ this.totalTokensUsed = computed(() => {
6055
+ const usage = this.conversationCostService.usageByTag();
6056
+ let total = 0;
6057
+ for (const tag in usage) {
6058
+ total += usage[tag].tokenUsage.input + usage[tag].tokenUsage.output;
6059
+ }
6060
+ return total;
6061
+ }, ...(ngDevMode ? [{ debugName: "totalTokensUsed" }] : /* istanbul ignore next */ []));
6062
+ }
6063
+ get messageStateService() { return this.parentInjector().get(MessagesStateService); }
6064
+ get dynamicFlowService() { return this.parentInjector().get(DynamicFlowService); }
6065
+ get conversationFlowStateService() { return this.parentInjector().get(ConversationFlowStateService); }
6066
+ get conversationCostService() { return this.parentInjector().get(ConversationCostService); }
6067
+ get evaluationService() { return this.parentInjector().get(EvaluationService); }
6068
+ get globalToolsService() { return this.parentInjector().get(GlobalToolsService); }
6069
+ setScore() {
6070
+ this.evaluationService.setScore(this.value);
6071
+ }
6072
+ callAgent() {
6073
+ this.globalToolsService.useTool('closeChatDrawer');
6074
+ }
6075
+ openFeedback() {
6076
+ this.evaluationService.openFeedbackEvaluation();
6077
+ }
6078
+ complete() {
6079
+ this.completeEvent.emit();
6080
+ }
6081
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationSummaryComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6082
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationSummaryComponent, isStandalone: true, selector: "dc-conversation-summary", inputs: { agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: true, isRequired: true, transformFunction: null }, parentInjector: { classPropertyName: "parentInjector", publicName: "parentInjector", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { completeEvent: "completeEvent" }, ngImport: i0, template: "<div class=\"flex flex-wrap gap-2 mb-2\">\n <p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n <p-button label=\"Feedback\" icon=\"pi pi-pencil\" (click)=\"openFeedback()\" />\n <p-button label=\"Complete\" icon=\"pi pi-check\" (click)=\"complete()\" />\n</div>\n\n<p-divider>Session Stats</p-divider>\n<div class=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Messages</p>\n <p>Total: {{ totalMessages() }}</p>\n <p class=\"text-sm\">User: {{ userMessagesCount() }} | Assistant: {{ assistantMessagesCount() }}</p>\n </div>\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Agent Identity</p>\n <p>{{ agentCard().name }}</p>\n <p class=\"text-sm text-gray-600\">{{ agentCard().agentType || 'Agent' }} ({{ agentCard().lang || 'N/A' }})</p>\n </div>\n</div>\n\n<p-divider>Flow & Usage</p-divider>\n<div class=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Goal Status</p>\n <div class=\"flex items-center gap-2 mt-1\">\n @if (dynamicFlowService.conversationFlowConfig()?.goal?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n <span>In Progress</span>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n <span>Inactive / Completed</span>\n }\n </div>\n </div>\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Quick Stats</p>\n <p>Active Challenges: {{ activeChallengesCount() }}</p>\n <p>Total Tokens: {{ totalTokensUsed() }}</p>\n </div>\n</div>\n\n<!-- Summary -->\n<p-divider>Score</p-divider>\n\n<label for=\"slider\">Current Score : {{ conversationFlowStateService.flowState().goal.value }}</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", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i4$1.Slider, selector: "p-slider", inputs: ["animate", "min", "max", "orientation", "step", "range", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
6083
+ }
6084
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationSummaryComponent, decorators: [{
6085
+ type: Component,
6086
+ args: [{ selector: 'dc-conversation-summary', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, DividerModule, SliderModule, TooltipModule], template: "<div class=\"flex flex-wrap gap-2 mb-2\">\n <p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n <p-button label=\"Feedback\" icon=\"pi pi-pencil\" (click)=\"openFeedback()\" />\n <p-button label=\"Complete\" icon=\"pi pi-check\" (click)=\"complete()\" />\n</div>\n\n<p-divider>Session Stats</p-divider>\n<div class=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Messages</p>\n <p>Total: {{ totalMessages() }}</p>\n <p class=\"text-sm\">User: {{ userMessagesCount() }} | Assistant: {{ assistantMessagesCount() }}</p>\n </div>\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Agent Identity</p>\n <p>{{ agentCard().name }}</p>\n <p class=\"text-sm text-gray-600\">{{ agentCard().agentType || 'Agent' }} ({{ agentCard().lang || 'N/A' }})</p>\n </div>\n</div>\n\n<p-divider>Flow & Usage</p-divider>\n<div class=\"grid grid-cols-2 gap-4 mb-4\">\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Goal Status</p>\n <div class=\"flex items-center gap-2 mt-1\">\n @if (dynamicFlowService.conversationFlowConfig()?.goal?.enabled) {\n <div class=\"w-3 h-3 bg-green-500 rounded-full\" pTooltip=\"Active\"></div>\n <span>In Progress</span>\n } @else {\n <div class=\"w-3 h-3 bg-red-500 rounded-full\" pTooltip=\"Inactive\"></div>\n <span>Inactive / Completed</span>\n }\n </div>\n </div>\n <div>\n <p class=\"font-semibold text-sm text-gray-500\">Quick Stats</p>\n <p>Active Challenges: {{ activeChallengesCount() }}</p>\n <p>Total Tokens: {{ totalTokensUsed() }}</p>\n </div>\n</div>\n\n<!-- Summary -->\n<p-divider>Score</p-divider>\n\n<label for=\"slider\">Current Score : {{ conversationFlowStateService.flowState().goal.value }}</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" }]
6087
+ }], propDecorators: { agentCard: [{ type: i0.Input, args: [{ isSignal: true, alias: "agentCard", required: true }] }], parentInjector: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentInjector", required: true }] }], completeEvent: [{ type: i0.Output, args: ["completeEvent"] }] } });
6088
+
5607
6089
  class ConversationInspector {
5608
6090
  constructor() {
5609
6091
  this.config = inject(DynamicDialogConfig);
@@ -5620,6 +6102,7 @@ class ConversationInspector {
5620
6102
  this.conversationFlowStateService = parentInjector.get(ConversationFlowStateService);
5621
6103
  this.conversationService = parentInjector.get(ConversationService);
5622
6104
  this.agentCardStateService = parentInjector.get(AgentCardStateService);
6105
+ this.conversationCostService = parentInjector.get(ConversationCostService);
5623
6106
  console.log('ConversationInspector data assigned', this.agentCard, this.chatUserSettings);
5624
6107
  }
5625
6108
  setScore() {
@@ -5650,11 +6133,11 @@ class ConversationInspector {
5650
6133
  this.viewMode.set(this.viewMode() === 'markdown' ? 'regular' : 'markdown');
5651
6134
  }
5652
6135
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationInspector, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5653
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationInspector, isStandalone: true, selector: "dc-conversation-info", outputs: { completeEvent: "completeEvent" }, ngImport: i0, template: "<div class=\"info-content\">\n <p-tabs value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">Summary</p-tab>\n <p-tab value=\"1\">Dynamic Flow</p-tab>\n <p-tab value=\"5\">Conversation State</p-tab>\n <p-tab value=\"2\">Conversation Messages</p-tab>\n <p-tab value=\"6\">Messages State</p-tab>\n <p-tab value=\"3\">Pricing</p-tab>\n <p-tab value=\"4\">More</p-tab>\n <p-tab value=\"7\">Preview</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\n <ng-template #content>\n <div class=\"flex flex-wrap gap-2 mb-2\">\n <p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n <p-button label=\"Feedback\" icon=\"pi pi-pencil\" (click)=\"openFeedback()\" />\n <p-button label=\"Complete\" icon=\"pi pi-check\" (click)=\"complete()\" />\n </div>\n\n <!-- Summary -->\n <p-divider>Score</p-divider>\n\n <label for=\"slider\">Current Score : {{ conversationFlowStateService.flowState().goal.value }}</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 <!-- Summary ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"1\">\n <ng-template #content>\n <!-- Dynamic Flow -->\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowConfig()?.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.conversationFlowConfig()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 agentCardStateService.conversationFlow$()?.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.conversationFlowConfig()?.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.conversationFlowConfig()?.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>{{ agentCardStateService.conversationFlow$()?.challenges | safeJson }}</pre>\n\n <p-divider>Performance Evaluation</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\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\">Performance Prompt</p>\n <span class=\"text-xs text-gray-400 ml-2\" pTooltip=\"Minimum messages required to trigger evaluation\">(MIN_MESSAGES_EVALUATE: 4 hardcoded)</span>\n </div>\n @if(agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\n @if(agentCardStateService.conversationFlow$()?.performancePrompt; as prompt) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> \n <markdown>\n {{ prompt }} \n </markdown>\n </div>\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> No custom performance prompt defined (using default). </div>\n }\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> Performance analysis disabled. </div>\n }\n </div>\n\n <p-divider>System Evaluation Prompt</p-divider>\n <details>\n <summary>Show Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n\n <!-- Dynamic Flow ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"5\">\n <ng-template #content>\n <pre>{{ conversationFlowStateService.flowState() | safeJson }}</pre>\n <details>\n <summary>Current Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n <p-button [label]=\"'Vista ' + viewMode()\" (click)=\"toggleViewMode()\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\" [view]=\"viewMode()\"></dc-prompt-preview>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"6\">\n <ng-template #content>\n <dc-messages-state-inspector></dc-messages-state-inspector>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"3\">\n <ng-template #content>\n <dc-cost-details></dc-cost-details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <!-- MORE INFO -->\n\n <details>\n <summary>Estado Global Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Conversation Settings (Debug)</summary>\n <pre>{{ conversationService.conversationSettings$() | 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\n <!-- MORE INFO ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"7\">\n <ng-template #content>\n <dc-agent-card-detail [entityData]=\"agentCardStateService.agentCard$()\" />\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\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: "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"] }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i1$6.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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i1$3.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "component", type: PromptPreviewComponent, selector: "dc-prompt-preview", inputs: ["messages", "jailBrake", "view"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i2$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$5.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabList, selector: "p-tablist" }, { kind: "component", type: i2$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: CostDetailsComponent, selector: "dc-cost-details" }, { kind: "component", type: MessagesStateInspectorComponent, selector: "dc-messages-state-inspector" }, { kind: "component", type: DcAgentCardDetailComponent, selector: "dc-agent-card-detail", inputs: ["entityData"] }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
6136
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationInspector, isStandalone: true, selector: "dc-conversation-info", outputs: { completeEvent: "completeEvent" }, ngImport: i0, template: "<div class=\"info-content\">\n <p-tabs value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">\uD83D\uDCCA Summary</p-tab>\n <p-tab value=\"1\">\uD83D\uDD00 Dynamic Flow</p-tab>\n <p-tab value=\"6\">\uD83D\uDCE6 Messages State</p-tab>\n <p-tab value=\"7\">\uD83D\uDC64 Preview Card</p-tab>\n <p-tab value=\"5\">\uD83D\uDCBE Conversation State</p-tab>\n <p-tab value=\"2\">\uD83D\uDCAC Conversation Messages</p-tab>\n <p-tab value=\"3\">\uD83D\uDCB0 Pricing</p-tab>\n <p-tab value=\"4\">\uD83D\uDC1B More</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\n <ng-template #content>\n @if (conversationFlowStateService.flowState(); as flowState) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-2\">\n <!-- Goal State -->\n <div class=\"p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFAF</span> Goal Progress\n </h3>\n <div class=\"flex items-end gap-4 mb-3\">\n <div class=\"text-5xl font-black leading-none\">\n {{ flowState.goal?.value || 0 }}\n </div>\n @if (flowState.goal?.deltaPoints !== undefined) {\n <div class=\"text-xl font-bold mb-1\" \n [class.text-green-600]=\"flowState.goal.deltaPoints > 0\"\n [class.text-red-600]=\"flowState.goal.deltaPoints < 0\"\n [class.opacity-50]=\"flowState.goal.deltaPoints === 0\">\n {{ flowState.goal.deltaPoints > 0 ? '+' : '' }}{{ flowState.goal.deltaPoints }}\n </div>\n }\n </div>\n \n @if (flowState.goal?.feedback) {\n <div class=\"mt-4 p-3 rounded border-l-4 text-sm italic shadow-sm opacity-80\">\n \"{{ flowState.goal.feedback }}\"\n </div>\n }\n </div>\n\n <!-- Mood State -->\n <div class=\"p-4 border rounded-lg shadow-sm flex flex-col\">\n <h3 class=\"text-lg font-bold mb-2 flex items-center gap-2\">\n <span>\uD83C\uDFAD</span> Agent Mood\n </h3>\n <div class=\"flex-grow flex items-center justify-center\">\n @if (flowState.moodState?.value) {\n <div class=\"text-4xl font-black uppercase tracking-widest text-center drop-shadow-sm\">\n {{ flowState.moodState.value }}\n </div>\n } @else {\n <div class=\"text-xl font-medium italic opacity-50\">Neutral</div>\n }\n </div>\n </div>\n </div>\n }\n <dc-conversation-summary [agentCard]=\"agentCard\" [parentInjector]=\"config.data.injector\" (completeEvent)=\"complete()\"></dc-conversation-summary>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"1\">\n <ng-template #content>\n <!-- Dynamic Flow -->\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowConfig()?.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.conversationFlowConfig()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 agentCardStateService.conversationFlow$()?.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.conversationFlowConfig()?.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.conversationFlowConfig()?.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>{{ agentCardStateService.conversationFlow$()?.challenges | safeJson }}</pre>\n\n <p-divider>Performance Evaluation</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\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\">Performance Prompt</p>\n <span class=\"text-xs text-gray-400 ml-2\" pTooltip=\"Minimum messages required to trigger evaluation\">(MIN_MESSAGES_EVALUATE: 4 hardcoded)</span>\n </div>\n @if(agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\n @if(agentCardStateService.conversationFlow$()?.performancePrompt; as prompt) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> \n <markdown>\n {{ prompt }} \n </markdown>\n </div>\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> No custom performance prompt defined (using default). </div>\n }\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> Performance analysis disabled. </div>\n }\n </div>\n\n <p-divider>System Evaluation Prompt</p-divider>\n <details>\n <summary>Show Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n\n <!-- Dynamic Flow ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"5\">\n <ng-template #content>\n @if (conversationFlowStateService.flowState(); as flowState) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-2\">\n <!-- Goal State -->\n <div class=\"p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFAF</span> Goal Progress\n </h3>\n <div class=\"flex items-end gap-4 mb-3\">\n <div class=\"text-5xl font-black leading-none\">\n {{ flowState.goal?.value || 0 }}\n </div>\n @if (flowState.goal?.deltaPoints !== undefined) {\n <div class=\"text-xl font-bold mb-1\" \n [class.text-green-600]=\"flowState.goal.deltaPoints > 0\"\n [class.text-red-600]=\"flowState.goal.deltaPoints < 0\"\n [class.opacity-50]=\"flowState.goal.deltaPoints === 0\">\n {{ flowState.goal.deltaPoints > 0 ? '+' : '' }}{{ flowState.goal.deltaPoints }}\n </div>\n }\n </div>\n \n @if (flowState.goal?.feedback) {\n <div class=\"mt-4 p-3 rounded border-l-4 text-sm italic shadow-sm opacity-80\">\n \"{{ flowState.goal.feedback }}\"\n </div>\n }\n </div>\n\n <!-- Mood State -->\n <div class=\"p-4 border rounded-lg shadow-sm flex flex-col\">\n <h3 class=\"text-lg font-bold mb-2 flex items-center gap-2\">\n <span>\uD83C\uDFAD</span> Agent Mood\n </h3>\n <div class=\"flex-grow flex items-center justify-center\">\n @if (flowState.moodState?.value) {\n <div class=\"text-4xl font-black uppercase tracking-widest text-center drop-shadow-sm\">\n {{ flowState.moodState.value }}\n </div>\n } @else {\n <div class=\"text-xl font-medium italic opacity-50\">Neutral</div>\n }\n </div>\n </div>\n </div>\n\n @if (flowState.challenges?.length) {\n <div class=\"mb-4 p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFC6</span> Completed Challenges\n </h3>\n <ul class=\"list-disc pl-5 space-y-1\">\n @for (challenge of flowState.challenges; track challenge) {\n <li>{{ challenge }}</li>\n }\n </ul>\n </div>\n }\n\n <details class=\"mt-4\">\n <summary class=\"cursor-pointer text-sm font-medium\">Raw JSON State</summary>\n <pre class=\"mt-2 p-2 rounded text-xs overflow-auto\">{{ flowState | safeJson }}</pre>\n </details>\n } @else {\n <p class=\"italic mt-2 opacity-50\">No conversation state available.</p>\n }\n\n <details class=\"mt-2\">\n <summary class=\"cursor-pointer text-sm font-medium\">Current Prompt</summary>\n <pre class=\"mt-2 p-2 rounded text-xs overflow-auto\">{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n <p-button [label]=\"'Vista ' + viewMode()\" (click)=\"toggleViewMode()\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\" [view]=\"viewMode()\"></dc-prompt-preview>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"6\">\n <ng-template #content>\n <dc-messages-state-inspector></dc-messages-state-inspector>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"3\">\n <ng-template #content>\n <dc-cost-details></dc-cost-details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <!-- MORE INFO -->\n\n <details>\n <summary>Estado Global Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Conversation Settings (Debug)</summary>\n <pre>{{ conversationService.conversationSettings$() | 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\n <!-- MORE INFO ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"7\">\n <ng-template #content>\n <dc-agent-card-detail [entityData]=\"agentCardStateService.agentCard$()\" />\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\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: "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"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "component", type: PromptPreviewComponent, selector: "dc-prompt-preview", inputs: ["messages", "jailBrake", "view"] }, { 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: ["lazy", "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: CostDetailsComponent, selector: "dc-cost-details" }, { kind: "component", type: MessagesStateInspectorComponent, selector: "dc-messages-state-inspector" }, { kind: "component", type: DcAgentCardDetailComponent, selector: "dc-agent-card-detail", inputs: ["entityData"] }, { kind: "component", type: ConversationSummaryComponent, selector: "dc-conversation-summary", inputs: ["agentCard", "parentInjector"], outputs: ["completeEvent"] }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }] }); }
5654
6137
  }
5655
6138
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationInspector, decorators: [{
5656
6139
  type: Component,
5657
- args: [{ selector: 'dc-conversation-info', standalone: true, imports: [CommonModule, SafeJsonPipe, MarkdownComponent, SliderModule, ButtonModule, FormsModule, DividerModule, PromptPreviewComponent, TabsModule, CostDetailsComponent, MessagesStateInspectorComponent, DcAgentCardDetailComponent], template: "<div class=\"info-content\">\n <p-tabs value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">Summary</p-tab>\n <p-tab value=\"1\">Dynamic Flow</p-tab>\n <p-tab value=\"5\">Conversation State</p-tab>\n <p-tab value=\"2\">Conversation Messages</p-tab>\n <p-tab value=\"6\">Messages State</p-tab>\n <p-tab value=\"3\">Pricing</p-tab>\n <p-tab value=\"4\">More</p-tab>\n <p-tab value=\"7\">Preview</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\n <ng-template #content>\n <div class=\"flex flex-wrap gap-2 mb-2\">\n <p-button label=\"Call Agent\" (click)=\"callAgent()\" />\n <p-button label=\"Feedback\" icon=\"pi pi-pencil\" (click)=\"openFeedback()\" />\n <p-button label=\"Complete\" icon=\"pi pi-check\" (click)=\"complete()\" />\n </div>\n\n <!-- Summary -->\n <p-divider>Score</p-divider>\n\n <label for=\"slider\">Current Score : {{ conversationFlowStateService.flowState().goal.value }}</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 <!-- Summary ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"1\">\n <ng-template #content>\n <!-- Dynamic Flow -->\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowConfig()?.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.conversationFlowConfig()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 agentCardStateService.conversationFlow$()?.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.conversationFlowConfig()?.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.conversationFlowConfig()?.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>{{ agentCardStateService.conversationFlow$()?.challenges | safeJson }}</pre>\n\n <p-divider>Performance Evaluation</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\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\">Performance Prompt</p>\n <span class=\"text-xs text-gray-400 ml-2\" pTooltip=\"Minimum messages required to trigger evaluation\">(MIN_MESSAGES_EVALUATE: 4 hardcoded)</span>\n </div>\n @if(agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\n @if(agentCardStateService.conversationFlow$()?.performancePrompt; as prompt) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> \n <markdown>\n {{ prompt }} \n </markdown>\n </div>\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> No custom performance prompt defined (using default). </div>\n }\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> Performance analysis disabled. </div>\n }\n </div>\n\n <p-divider>System Evaluation Prompt</p-divider>\n <details>\n <summary>Show Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n\n <!-- Dynamic Flow ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"5\">\n <ng-template #content>\n <pre>{{ conversationFlowStateService.flowState() | safeJson }}</pre>\n <details>\n <summary>Current Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n <p-button [label]=\"'Vista ' + viewMode()\" (click)=\"toggleViewMode()\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\" [view]=\"viewMode()\"></dc-prompt-preview>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"6\">\n <ng-template #content>\n <dc-messages-state-inspector></dc-messages-state-inspector>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"3\">\n <ng-template #content>\n <dc-cost-details></dc-cost-details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <!-- MORE INFO -->\n\n <details>\n <summary>Estado Global Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Conversation Settings (Debug)</summary>\n <pre>{{ conversationService.conversationSettings$() | 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\n <!-- MORE INFO ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"7\">\n <ng-template #content>\n <dc-agent-card-detail [entityData]=\"agentCardStateService.agentCard$()\" />\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\n</div>\n", styles: [":host{overflow-y:scroll}.info-content{display:flex;flex-direction:column;gap:1rem;padding:1rem}\n"] }]
6140
+ args: [{ selector: 'dc-conversation-info', standalone: true, imports: [CommonModule, SafeJsonPipe, MarkdownComponent, SliderModule, ButtonModule, FormsModule, DividerModule, PromptPreviewComponent, TabsModule, CostDetailsComponent, MessagesStateInspectorComponent, DcAgentCardDetailComponent, ConversationSummaryComponent], template: "<div class=\"info-content\">\n <p-tabs value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">\uD83D\uDCCA Summary</p-tab>\n <p-tab value=\"1\">\uD83D\uDD00 Dynamic Flow</p-tab>\n <p-tab value=\"6\">\uD83D\uDCE6 Messages State</p-tab>\n <p-tab value=\"7\">\uD83D\uDC64 Preview Card</p-tab>\n <p-tab value=\"5\">\uD83D\uDCBE Conversation State</p-tab>\n <p-tab value=\"2\">\uD83D\uDCAC Conversation Messages</p-tab>\n <p-tab value=\"3\">\uD83D\uDCB0 Pricing</p-tab>\n <p-tab value=\"4\">\uD83D\uDC1B More</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\n <ng-template #content>\n @if (conversationFlowStateService.flowState(); as flowState) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-2\">\n <!-- Goal State -->\n <div class=\"p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFAF</span> Goal Progress\n </h3>\n <div class=\"flex items-end gap-4 mb-3\">\n <div class=\"text-5xl font-black leading-none\">\n {{ flowState.goal?.value || 0 }}\n </div>\n @if (flowState.goal?.deltaPoints !== undefined) {\n <div class=\"text-xl font-bold mb-1\" \n [class.text-green-600]=\"flowState.goal.deltaPoints > 0\"\n [class.text-red-600]=\"flowState.goal.deltaPoints < 0\"\n [class.opacity-50]=\"flowState.goal.deltaPoints === 0\">\n {{ flowState.goal.deltaPoints > 0 ? '+' : '' }}{{ flowState.goal.deltaPoints }}\n </div>\n }\n </div>\n \n @if (flowState.goal?.feedback) {\n <div class=\"mt-4 p-3 rounded border-l-4 text-sm italic shadow-sm opacity-80\">\n \"{{ flowState.goal.feedback }}\"\n </div>\n }\n </div>\n\n <!-- Mood State -->\n <div class=\"p-4 border rounded-lg shadow-sm flex flex-col\">\n <h3 class=\"text-lg font-bold mb-2 flex items-center gap-2\">\n <span>\uD83C\uDFAD</span> Agent Mood\n </h3>\n <div class=\"flex-grow flex items-center justify-center\">\n @if (flowState.moodState?.value) {\n <div class=\"text-4xl font-black uppercase tracking-widest text-center drop-shadow-sm\">\n {{ flowState.moodState.value }}\n </div>\n } @else {\n <div class=\"text-xl font-medium italic opacity-50\">Neutral</div>\n }\n </div>\n </div>\n </div>\n }\n <dc-conversation-summary [agentCard]=\"agentCard\" [parentInjector]=\"config.data.injector\" (completeEvent)=\"complete()\"></dc-conversation-summary>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"1\">\n <ng-template #content>\n <!-- Dynamic Flow -->\n\n <p-divider>Conversation Flow</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (dynamicFlowService.conversationFlowConfig()?.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.conversationFlowConfig()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 (agentCardStateService.conversationFlow$()?.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(agentCardStateService.conversationFlow$()?.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 agentCardStateService.conversationFlow$()?.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.conversationFlowConfig()?.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.conversationFlowConfig()?.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>{{ agentCardStateService.conversationFlow$()?.challenges | safeJson }}</pre>\n\n <p-divider>Performance Evaluation</p-divider>\n <div class=\"mb-2\">\n <div class=\"flex items-center gap-2\">\n @if (agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\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\">Performance Prompt</p>\n <span class=\"text-xs text-gray-400 ml-2\" pTooltip=\"Minimum messages required to trigger evaluation\">(MIN_MESSAGES_EVALUATE: 4 hardcoded)</span>\n </div>\n @if(agentCardStateService.conversationFlow$()?.enablePerformanceAnalysis !== false) {\n @if(agentCardStateService.conversationFlow$()?.performancePrompt; as prompt) {\n <div class=\"pl-5 mt-1 text-sm text-gray-600 italic\"> \n <markdown>\n {{ prompt }} \n </markdown>\n </div>\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> No custom performance prompt defined (using default). </div>\n }\n } @else {\n <div class=\"pl-5 mt-1 text-sm text-gray-400 italic\"> Performance analysis disabled. </div>\n }\n </div>\n\n <p-divider>System Evaluation Prompt</p-divider>\n <details>\n <summary>Show Prompt</summary>\n <pre>{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n\n <!-- Dynamic Flow ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"5\">\n <ng-template #content>\n @if (conversationFlowStateService.flowState(); as flowState) {\n <div class=\"grid grid-cols-1 md:grid-cols-2 gap-4 mb-4 mt-2\">\n <!-- Goal State -->\n <div class=\"p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFAF</span> Goal Progress\n </h3>\n <div class=\"flex items-end gap-4 mb-3\">\n <div class=\"text-5xl font-black leading-none\">\n {{ flowState.goal?.value || 0 }}\n </div>\n @if (flowState.goal?.deltaPoints !== undefined) {\n <div class=\"text-xl font-bold mb-1\" \n [class.text-green-600]=\"flowState.goal.deltaPoints > 0\"\n [class.text-red-600]=\"flowState.goal.deltaPoints < 0\"\n [class.opacity-50]=\"flowState.goal.deltaPoints === 0\">\n {{ flowState.goal.deltaPoints > 0 ? '+' : '' }}{{ flowState.goal.deltaPoints }}\n </div>\n }\n </div>\n \n @if (flowState.goal?.feedback) {\n <div class=\"mt-4 p-3 rounded border-l-4 text-sm italic shadow-sm opacity-80\">\n \"{{ flowState.goal.feedback }}\"\n </div>\n }\n </div>\n\n <!-- Mood State -->\n <div class=\"p-4 border rounded-lg shadow-sm flex flex-col\">\n <h3 class=\"text-lg font-bold mb-2 flex items-center gap-2\">\n <span>\uD83C\uDFAD</span> Agent Mood\n </h3>\n <div class=\"flex-grow flex items-center justify-center\">\n @if (flowState.moodState?.value) {\n <div class=\"text-4xl font-black uppercase tracking-widest text-center drop-shadow-sm\">\n {{ flowState.moodState.value }}\n </div>\n } @else {\n <div class=\"text-xl font-medium italic opacity-50\">Neutral</div>\n }\n </div>\n </div>\n </div>\n\n @if (flowState.challenges?.length) {\n <div class=\"mb-4 p-4 border rounded-lg shadow-sm\">\n <h3 class=\"text-lg font-bold mb-3 flex items-center gap-2\">\n <span>\uD83C\uDFC6</span> Completed Challenges\n </h3>\n <ul class=\"list-disc pl-5 space-y-1\">\n @for (challenge of flowState.challenges; track challenge) {\n <li>{{ challenge }}</li>\n }\n </ul>\n </div>\n }\n\n <details class=\"mt-4\">\n <summary class=\"cursor-pointer text-sm font-medium\">Raw JSON State</summary>\n <pre class=\"mt-2 p-2 rounded text-xs overflow-auto\">{{ flowState | safeJson }}</pre>\n </details>\n } @else {\n <p class=\"italic mt-2 opacity-50\">No conversation state available.</p>\n }\n\n <details class=\"mt-2\">\n <summary class=\"cursor-pointer text-sm font-medium\">Current Prompt</summary>\n <pre class=\"mt-2 p-2 rounded text-xs overflow-auto\">{{ dynamicFlowService.generateSystemPromptForFlow(messageStateService.getMessagesSignal()()) }}</pre>\n </details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <div>\n <p-button label=\"Exportar todo\" (click)=\"exportChat('all')\" />\n <p-button label=\"Exportar conversaci\u00F3n\" (click)=\"exportChat('conversation')\" />\n <p-button [label]=\"'Vista ' + viewMode()\" (click)=\"toggleViewMode()\" />\n </div>\n <dc-prompt-preview [messages]=\"messageStateService.getMessagesSignal()()\" [view]=\"viewMode()\"></dc-prompt-preview>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"6\">\n <ng-template #content>\n <dc-messages-state-inspector></dc-messages-state-inspector>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"3\">\n <ng-template #content>\n <dc-cost-details></dc-cost-details>\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <!-- MORE INFO -->\n\n <details>\n <summary>Estado Global Conversation Flow</summary>\n <p>Goal</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.goal | safeJson }}</pre>\n <p>Trigger User Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onUserMessage | safeJson }}</pre>\n <p>Trigger Assistant Message</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.triggerTasks?.onAssistantMessage | safeJson }}</pre>\n <p>Conditions</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.dynamicConditions | safeJson }}</pre>\n <p>Tools</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.tools | safeJson }}</pre>\n <p>Challenges</p>\n <pre>{{ dynamicFlowService.conversationFlowConfig()?.challenges | safeJson }}</pre>\n </details>\n\n <details>\n <summary>Conversation Settings (Debug)</summary>\n <pre>{{ conversationService.conversationSettings$() | 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\n <!-- MORE INFO ends Here -->\n </ng-template>\n </p-tabpanel>\n <p-tabpanel value=\"7\">\n <ng-template #content>\n <dc-agent-card-detail [entityData]=\"agentCardStateService.agentCard$()\" />\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\n</div>\n", styles: [":host{overflow-y:scroll}.info-content{display:flex;flex-direction:column;gap:1rem;padding:1rem}\n"] }]
5658
6141
  }], ctorParameters: () => [], propDecorators: { completeEvent: [{ type: i0.Output, args: ["completeEvent"] }] } });
5659
6142
 
5660
6143
  class ConversationInfoService {
@@ -5822,11 +6305,11 @@ class DCChatComponent {
5822
6305
  this.goalCompleted.emit();
5823
6306
  }
5824
6307
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
5825
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationFlow: { classPropertyName: "conversationFlow", publicName: "conversationFlow", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { chatEvent: "chatEvent", goalCompleted: "goalCompleted" }, providers: [ConversationService, AIGenerationService, EvaluationService, DynamicFlowTaskService, ConversationInfoService, MessageOrchestrationService, AudioTextSyncService], viewQueries: [{ propertyName: "chatFooterComponent", first: true, predicate: ChatFooterComponent, descendants: true }], ngImport: i0, template: "<div class=\"chat-container\">\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [viewMode]=\"viewMode()\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\"\n (viewModeChanged)=\"viewMode.set($event)\">\n </dc-chat-header>\n\n @if (viewMode() === 'chat') {\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\"> </dc-chat-messages-list>\n <dc-chat-footer [micSettings]=\"micSettings\"> </dc-chat-footer>\n } @else {\n <dc-immersive-chat [micSettings]=\"micSettings\"></dc-immersive-chat>\n }\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["alternativeConversation", "agentCard", "viewMode"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent", "viewModeChanged"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: DcImmersiveChatComponent, selector: "dc-immersive-chat", inputs: ["micSettings"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6308
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationFlow: { classPropertyName: "conversationFlow", publicName: "conversationFlow", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { chatEvent: "chatEvent", goalCompleted: "goalCompleted" }, providers: [ConversationService, AIGenerationService, EvaluationService, DynamicFlowTaskService, ConversationInfoService, MessageOrchestrationService, AudioTextSyncService], viewQueries: [{ propertyName: "chatFooterComponent", first: true, predicate: ChatFooterComponent, descendants: true }], ngImport: i0, template: "<div class=\"chat-container\">\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [viewMode]=\"viewMode()\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\"\n (viewModeChanged)=\"viewMode.set($event)\">\n </dc-chat-header>\n\n @if (viewMode() === 'chat') {\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\"> </dc-chat-messages-list>\n <dc-chat-footer [micSettings]=\"micSettings\"> </dc-chat-footer>\n } @else {\n <dc-immersive-chat [micSettings]=\"micSettings\"></dc-immersive-chat>\n }\n\n <dc-polito-notification></dc-polito-notification>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent;position:relative}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["alternativeConversation", "agentCard", "viewMode"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent", "viewModeChanged"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: DcImmersiveChatComponent, selector: "dc-immersive-chat", inputs: ["micSettings"] }, { kind: "component", type: PolitoNotificationComponent, selector: "dc-polito-notification" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5826
6309
  }
5827
6310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCChatComponent, decorators: [{
5828
6311
  type: Component,
5829
- args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, ProgressBarModule, DcImmersiveChatComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ConversationService, AIGenerationService, EvaluationService, DynamicFlowTaskService, ConversationInfoService, MessageOrchestrationService, AudioTextSyncService], template: "<div class=\"chat-container\">\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [viewMode]=\"viewMode()\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\"\n (viewModeChanged)=\"viewMode.set($event)\">\n </dc-chat-header>\n\n @if (viewMode() === 'chat') {\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\"> </dc-chat-messages-list>\n <dc-chat-footer [micSettings]=\"micSettings\"> </dc-chat-footer>\n } @else {\n <dc-immersive-chat [micSettings]=\"micSettings\"></dc-immersive-chat>\n }\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"] }]
6312
+ args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, ProgressBarModule, DcImmersiveChatComponent, PolitoNotificationComponent], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ConversationService, AIGenerationService, EvaluationService, DynamicFlowTaskService, ConversationInfoService, MessageOrchestrationService, AudioTextSyncService], template: "<div class=\"chat-container\">\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [viewMode]=\"viewMode()\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\"\n (completeEvent)=\"complete()\"\n (viewModeChanged)=\"viewMode.set($event)\">\n </dc-chat-header>\n\n @if (viewMode() === 'chat') {\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\"> </dc-chat-messages-list>\n <dc-chat-footer [micSettings]=\"micSettings\"> </dc-chat-footer>\n } @else {\n <dc-immersive-chat [micSettings]=\"micSettings\"></dc-immersive-chat>\n }\n\n <dc-polito-notification></dc-polito-notification>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}::ng-deep .p-dialog-content{display:contents}.chat-container{display:flex;flex-direction:column;height:100%;max-height:100vh;overflow:hidden;background-color:transparent;position:relative}dc-chat-messages-list{flex:1;overflow-y:auto;padding:.5rem}.score-container{padding:.5rem 1rem;background-color:var(--surface-card, #ffffff);border-top:1px solid var(--surface-border, #dee2e6)}.info-content{max-height:70vh;overflow-y:auto;padding:1rem}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"] }]
5830
6313
  }], ctorParameters: () => [], propDecorators: { chatFooterComponent: [{
5831
6314
  type: ViewChild,
5832
6315
  args: [ChatFooterComponent]
@@ -6106,7 +6589,7 @@ ${prompt_user}
6106
6589
  }
6107
6590
  }
6108
6591
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCDataGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6109
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 gap-2\">\n <p-button label=\"Show Prompt\" (click)=\"showPrompt()\" styleClass=\"p-button-secondary\"></p-button>\n <p-button label=\"Generate\" (click)=\"generateDirectly()\" [loading]=\"loading()\"></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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
6592
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 gap-2\">\n <p-button label=\"Show Prompt\" (click)=\"showPrompt()\" styleClass=\"p-button-secondary\"></p-button>\n <p-button label=\"Generate\" (click)=\"generateDirectly()\" [loading]=\"loading()\"></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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.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: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
6110
6593
  }
6111
6594
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCDataGenerationComponent, decorators: [{
6112
6595
  type: Component,
@@ -6277,7 +6760,7 @@ class ACCMotionGenerationComponent {
6277
6760
  this.videoPrompt = '';
6278
6761
  }
6279
6762
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCMotionGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6280
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$4.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] }); }
6763
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.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: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$3.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "pipe", type: SafeHtmlPipe, name: "safeHtml" }] }); }
6281
6764
  }
6282
6765
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCMotionGenerationComponent, decorators: [{
6283
6766
  type: Component,
@@ -6300,9 +6783,11 @@ class ACCTranslationGenerationComponent {
6300
6783
  this.top10Languages = ['en', 'zh', 'es', 'ar', 'fr', 'hi', 'pt', 'ru', 'de', 'ja'];
6301
6784
  }
6302
6785
  ngOnInit() {
6303
- const allGrettings = this.agentCard?.characterCard?.data?.greetings || [];
6304
- allGrettings.push(this.agentCard?.characterCard?.data.first_mes);
6305
- this.greetings.set(allGrettings);
6786
+ const originalGreetings = this.agentCard?.characterCard?.data?.greetings || [];
6787
+ const allGrettings = [...originalGreetings]; // Clone to avoid mutating original
6788
+ // Filter out any empty, null or undefined greetings
6789
+ const validGreetings = allGrettings.filter(g => g && typeof g === 'string' && g.trim() !== '');
6790
+ this.greetings.set(validGreetings);
6306
6791
  }
6307
6792
  getLanguageText(languages = null) {
6308
6793
  if (languages) {
@@ -6389,6 +6874,14 @@ ${prompt_user}
6389
6874
  else {
6390
6875
  improvements = response.content;
6391
6876
  }
6877
+ // Clean up empty greetings returned by the LLM
6878
+ if (improvements) {
6879
+ for (const lang of Object.keys(improvements)) {
6880
+ if (improvements[lang] && Array.isArray(improvements[lang].greetings)) {
6881
+ improvements[lang].greetings = improvements[lang].greetings.filter((g) => g && typeof g === 'string' && g.trim() !== '');
6882
+ }
6883
+ }
6884
+ }
6392
6885
  this.cardImprovements.set(improvements);
6393
6886
  this.cardImprovementsChange.emit(improvements);
6394
6887
  this.generationStep.set('result');
@@ -6409,7 +6902,7 @@ ${prompt_user}
6409
6902
  return Object.keys(obj);
6410
6903
  }
6411
6904
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCTranslationGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6412
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\"\n >Antes de traducir, aseg\u00FArate de que los campos de Saludos (Greetings), Gancho (Hook), Instrucciones (Instructions) y Comunicaci\u00F3n (Communication) est\u00E9n\n completados.</p-message\n >\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=\"Traducir a los 10 idiomas m\u00E1s importantes\" (click)=\"generateTop10Prompt()\"></p-button>\n <p-button label=\"Traducir a Ingl\u00E9s y Espa\u00F1ol\" (click)=\"generateEnEsPrompt()\"></p-button>\n <p-button label=\"Traducir a todos los idiomas\" (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=\"Generar\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Traducciones generadas para el personaje:</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 class=\"col-12\">\n <strong>Instrucciones:</strong>\n <p>{{ card[lang]?.instructions }}</p>\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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$4.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }] }); }
6905
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\"\n >Antes de traducir, aseg\u00FArate de que los campos de Saludos (Greetings), Gancho (Hook), Instrucciones (Instructions) y Comunicaci\u00F3n (Communication) est\u00E9n\n completados.</p-message\n >\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=\"Traducir a los 10 idiomas m\u00E1s importantes\" (click)=\"generateTop10Prompt()\"></p-button>\n <p-button label=\"Traducir a Ingl\u00E9s y Espa\u00F1ol\" (click)=\"generateEnEsPrompt()\"></p-button>\n <p-button label=\"Traducir a todos los idiomas\" (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=\"Generar\" (click)=\"generate()\" [loading]=\"loading()\"></p-button>\n </div>\n } @case ('result') {\n <div>\n <h3>Traducciones generadas para el personaje:</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 class=\"col-12\">\n <strong>Instrucciones:</strong>\n <p>{{ card[lang]?.instructions }}</p>\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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$3.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }] }); }
6413
6906
  }
6414
6907
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCTranslationGenerationComponent, decorators: [{
6415
6908
  type: Component,
@@ -6513,7 +7006,7 @@ class ACCSettingsGenerationComponent {
6513
7006
  }
6514
7007
  }
6515
7008
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCSettingsGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6516
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ACCSettingsGenerationComponent, isStandalone: true, selector: "dc-acc-settings-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n @switch (generationStep()) { @case ('idea') {\n <div class=\"flex flex-col gap-2\">\n <label for=\"idea\">Idea</label>\n <textarea id=\"idea\" name=\"idea\" pTextarea [(ngModel)]=\"idea\" rows=\"5\" cols=\"30\"></textarea>\n <p-button label=\"Generate\" (click)=\"generateDirectly()\"></p-button>\n <p-button label=\"Show Prompt\" (click)=\"showPrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div class=\"flex flex-col gap-2\">\n <label for=\"prompt\">Prompt</label>\n <textarea id=\"prompt\" name=\"prompt\" pTextarea [(ngModel)]=\"prompt\" rows=\"15\" cols=\"60\"></textarea>\n <p-button label=\"Generate\" (click)=\"generate()\"></p-button>\n </div>\n } @case ('result') {\n <div class=\"flex flex-col gap-2\">\n <label>Generated Settings</label>\n <pre>{{ cardImprovements() | json }}</pre>\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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
7009
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ACCSettingsGenerationComponent, isStandalone: true, selector: "dc-acc-settings-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n @switch (generationStep()) { @case ('idea') {\n <div class=\"flex flex-col gap-2\">\n <label for=\"idea\">Idea</label>\n <textarea id=\"idea\" name=\"idea\" pTextarea [(ngModel)]=\"idea\" rows=\"5\" cols=\"30\"></textarea>\n <p-button label=\"Generate\" (click)=\"generateDirectly()\"></p-button>\n <p-button label=\"Show Prompt\" (click)=\"showPrompt()\"></p-button>\n </div>\n } @case ('prompt') {\n <div class=\"flex flex-col gap-2\">\n <label for=\"prompt\">Prompt</label>\n <textarea id=\"prompt\" name=\"prompt\" pTextarea [(ngModel)]=\"prompt\" rows=\"15\" cols=\"60\"></textarea>\n <p-button label=\"Generate\" (click)=\"generate()\"></p-button>\n </div>\n } @case ('result') {\n <div class=\"flex flex-col gap-2\">\n <label>Generated Settings</label>\n <pre>{{ cardImprovements() | json }}</pre>\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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.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: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
6517
7010
  }
6518
7011
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCSettingsGenerationComponent, decorators: [{
6519
7012
  type: Component,
@@ -6632,7 +7125,7 @@ ${instructions}
6632
7125
  return Object.keys(obj);
6633
7126
  }
6634
7127
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCDynamicFlowGenerationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6635
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ACCDynamicFlowGenerationComponent, isStandalone: true, selector: "dc-acc-dynamic-flow-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n @switch (generationStep()) { @case ('idea') {\n <p-message severity=\"info\">\n <p>\n Genera un flujo de conversaci\u00F3n din\u00E1mico para tu personaje. Esto crear\u00E1 un objetivo principal y una serie de desaf\u00EDos que guiar\u00E1n la interacci\u00F3n del\n usuario, haciendo la conversaci\u00F3n m\u00E1s interactiva y dirigida.\n </p>\n </p-message>\n\n <div class=\"flex flex-col gap-2\">\n <p-button (click)=\"generatePrompt()\" label=\"\u2728 Generar Flujo Din\u00E1mico\" styleClass=\"p-button-primary w-full\"></p-button>\n </div>\n\n } @case('prompt') {\n <p-message severity=\"warn\">\n <p> Este es el prompt que se usar\u00E1 para generar el flujo din\u00E1mico. Puedes ajustarlo si es necesario. </p>\n </p-message>\n\n <textarea class=\"w-full h-64 p-2 border rounded\" [(ngModel)]=\"prompt\"></textarea>\n <p-button (click)=\"generate()\" label=\"\uD83D\uDE80 Enviar a la IA\" styleClass=\"p-button-success w-full\" [loading]=\"loading()\"></p-button>\n } @case('result') { @if(cardImprovements(); as improvements){\n <p-message severity=\"success\">\n <p>\u00A1El flujo din\u00E1mico ha sido generado! Revisa los resultados a continuaci\u00F3n.</p>\n </p-message>\n\n <div class=\"flex flex-col gap-4\">\n <div>\n <h3 class=\"font-bold text-lg\">\uD83C\uDFAF Objetivo Principal</h3>\n <p>{{ improvements.goal?.task }}</p>\n </div>\n\n <div>\n <h3 class=\"font-bold text-lg\">\uD83C\uDFC6 Desaf\u00EDos</h3>\n <ul class=\"list-disc pl-5\">\n @for(challenge of improvements.challenges; track challenge.name){\n <li>{{ challenge.emoji }} {{ challenge.description }}</li>\n }\n </ul>\n </div>\n </div>\n\n <p-button (click)=\"generationStep.set('idea')\" label=\"Volver a Generar\" styleClass=\"p-button-secondary w-full\"></p-button>\n } } }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$4.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }] }); }
7128
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ACCDynamicFlowGenerationComponent, isStandalone: true, selector: "dc-acc-dynamic-flow-generation", inputs: { agentCard: "agentCard" }, outputs: { cardImprovementsChange: "cardImprovementsChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n @switch (generationStep()) { @case ('idea') {\n <p-message severity=\"info\">\n <p>\n Genera un flujo de conversaci\u00F3n din\u00E1mico para tu personaje. Esto crear\u00E1 un objetivo principal y una serie de desaf\u00EDos que guiar\u00E1n la interacci\u00F3n del\n usuario, haciendo la conversaci\u00F3n m\u00E1s interactiva y dirigida.\n </p>\n </p-message>\n\n <div class=\"flex flex-col gap-2\">\n <p-button (click)=\"generatePrompt()\" label=\"\u2728 Generar Flujo Din\u00E1mico\" styleClass=\"p-button-primary w-full\"></p-button>\n </div>\n\n } @case('prompt') {\n <p-message severity=\"warn\">\n <p> Este es el prompt que se usar\u00E1 para generar el flujo din\u00E1mico. Puedes ajustarlo si es necesario. </p>\n </p-message>\n\n <textarea class=\"w-full h-64 p-2 border rounded\" [(ngModel)]=\"prompt\"></textarea>\n <p-button (click)=\"generate()\" label=\"\uD83D\uDE80 Enviar a la IA\" styleClass=\"p-button-success w-full\" [loading]=\"loading()\"></p-button>\n } @case('result') { @if(cardImprovements(); as improvements){\n <p-message severity=\"success\">\n <p>\u00A1El flujo din\u00E1mico ha sido generado! Revisa los resultados a continuaci\u00F3n.</p>\n </p-message>\n\n <div class=\"flex flex-col gap-4\">\n <div>\n <h3 class=\"font-bold text-lg\">\uD83C\uDFAF Objetivo Principal</h3>\n <p>{{ improvements.goal?.task }}</p>\n </div>\n\n <div>\n <h3 class=\"font-bold text-lg\">\uD83C\uDFC6 Desaf\u00EDos</h3>\n <ul class=\"list-disc pl-5\">\n @for(challenge of improvements.challenges; track challenge.name){\n <li>{{ challenge.emoji }} {{ challenge.description }}</li>\n }\n </ul>\n </div>\n </div>\n\n <p-button (click)=\"generationStep.set('idea')\" label=\"Volver a Generar\" styleClass=\"p-button-secondary w-full\"></p-button>\n } } }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$3.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }] }); }
6636
7129
  }
6637
7130
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ACCDynamicFlowGenerationComponent, decorators: [{
6638
7131
  type: Component,
@@ -6672,7 +7165,7 @@ class GenerateCharacterDialogComponent {
6672
7165
  this.ref.close(result);
6673
7166
  }
6674
7167
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GenerateCharacterDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6675
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: GenerateCharacterDialogComponent, isStandalone: true, selector: "dc-generate-character-dialog", ngImport: i0, template: "<div class=\"card\">\n <p-tabs lazy value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">Informaci\u00F3n del personaje</p-tab>\n <p-tab value=\"1\">Movimientos</p-tab>\n <p-tab value=\"2\">Traducciones</p-tab>\n <p-tab value=\"3\">Flujo Din\u00E1mico</p-tab>\n <p-tab value=\"4\">Settings</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\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-tabpanel>\n <p-tabpanel value=\"1\">\n <dc-acc-motion-generation [agentCard]=\"agentCard\"></dc-acc-motion-generation>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <dc-acc-translation-generation\n [agentCard]=\"agentCard\"\n (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 </ng-template>\n </p-tabpanel>\n\n <p-tabpanel value=\"3\">\n <dc-acc-dynamic-flow-generation\n [agentCard]=\"agentCard\"\n (cardImprovementsChange)=\"onDynamicFlowImprovementsChange($event)\"></dc-acc-dynamic-flow-generation>\n @if(cardImprovements.conversationFlow){\n <p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n }\n </p-tabpanel>\n\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <h3> Esta es la secci\u00F3n de configuraci\u00F3n</h3>\n <dc-acc-settings-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onSettingsImprovementsChange($event)\"></dc-acc-settings-generation>\n @if(cardImprovements.name){\n <p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n }\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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: "component", type: ACCSettingsGenerationComponent, selector: "dc-acc-settings-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { kind: "component", type: ACCDynamicFlowGenerationComponent, selector: "dc-acc-dynamic-flow-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i2$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$5.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabList, selector: "p-tablist" }, { kind: "component", type: i2$5.Tab, selector: "p-tab", inputs: ["value", "disabled"], outputs: ["valueChange"] }] }); }
7168
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: GenerateCharacterDialogComponent, isStandalone: true, selector: "dc-generate-character-dialog", ngImport: i0, template: "<div class=\"card\">\n <p-tabs lazy value=\"0\">\n <p-tablist>\n <p-tab value=\"0\">Informaci\u00F3n del personaje</p-tab>\n <p-tab value=\"1\">Movimientos</p-tab>\n <p-tab value=\"2\">Traducciones</p-tab>\n <p-tab value=\"3\">Flujo Din\u00E1mico</p-tab>\n <p-tab value=\"4\">Settings</p-tab>\n </p-tablist>\n <p-tabpanels>\n <p-tabpanel value=\"0\">\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-tabpanel>\n <p-tabpanel value=\"1\">\n <dc-acc-motion-generation [agentCard]=\"agentCard\"></dc-acc-motion-generation>\n </p-tabpanel>\n <p-tabpanel value=\"2\">\n <ng-template #content>\n <dc-acc-translation-generation\n [agentCard]=\"agentCard\"\n (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 </ng-template>\n </p-tabpanel>\n\n <p-tabpanel value=\"3\">\n <dc-acc-dynamic-flow-generation\n [agentCard]=\"agentCard\"\n (cardImprovementsChange)=\"onDynamicFlowImprovementsChange($event)\"></dc-acc-dynamic-flow-generation>\n @if(cardImprovements.conversationFlow){\n <p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n }\n </p-tabpanel>\n\n <p-tabpanel value=\"4\">\n <ng-template #content>\n <h3> Esta es la secci\u00F3n de configuraci\u00F3n</h3>\n <dc-acc-settings-generation [agentCard]=\"agentCard\" (cardImprovementsChange)=\"onSettingsImprovementsChange($event)\"></dc-acc-settings-generation>\n @if(cardImprovements.name){\n <p-button class=\"w-full\" label=\"Guardar Datos\" (click)=\"accept()\"></p-button>\n }\n </ng-template>\n </p-tabpanel>\n </p-tabpanels>\n </p-tabs>\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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: "component", type: ACCSettingsGenerationComponent, selector: "dc-acc-settings-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { kind: "component", type: ACCDynamicFlowGenerationComponent, selector: "dc-acc-dynamic-flow-generation", inputs: ["agentCard"], outputs: ["cardImprovementsChange"] }, { 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: ["lazy", "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"] }] }); }
6676
7169
  }
6677
7170
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: GenerateCharacterDialogComponent, decorators: [{
6678
7171
  type: Component,
@@ -6750,7 +7243,7 @@ class AccountPlatformForm {
6750
7243
  }
6751
7244
  }
6752
7245
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AccountPlatformForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
6753
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7246
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
6754
7247
  }
6755
7248
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AccountPlatformForm, decorators: [{
6756
7249
  type: Component,
@@ -6779,6 +7272,7 @@ class CharacterFormGroupService {
6779
7272
  manageable: this.formUtils.createManageableFormGroup(),
6780
7273
  learnable: this.formUtils.createLearnableFormGroup(),
6781
7274
  voiceCloning: this.createVoiceCloningFormGroup(),
7275
+ agenticConfig: this.createAgenticConfigFormGroup(),
6782
7276
  });
6783
7277
  }
6784
7278
  patchFormWithConversationData(form, agentCard) {
@@ -6875,6 +7369,15 @@ class CharacterFormGroupService {
6875
7369
  }));
6876
7370
  });
6877
7371
  }
7372
+ const allowedToolsFormArray = form.get('agenticConfig.allowedTools');
7373
+ if (allowedToolsFormArray) {
7374
+ allowedToolsFormArray.clear();
7375
+ if (agentCard.agenticConfig?.allowedTools?.length) {
7376
+ agentCard.agenticConfig.allowedTools.forEach((tool) => {
7377
+ allowedToolsFormArray.push(this.fb.control(tool));
7378
+ });
7379
+ }
7380
+ }
6878
7381
  }
6879
7382
  createCharacterCardFormGroup(characterCard) {
6880
7383
  return this.fb.group({
@@ -6932,6 +7435,7 @@ class CharacterFormGroupService {
6932
7435
  conversationType: [ConversationType.General],
6933
7436
  autoStart: [true],
6934
7437
  userMustStart: [false],
7438
+ streamResponses: [false],
6935
7439
  displayMode: ['chat'],
6936
7440
  mainVoice: this.createVoiceTTSFormGroup(),
6937
7441
  secondaryVoice: this.createVoiceTTSFormGroup(),
@@ -7033,6 +7537,19 @@ class CharacterFormGroupService {
7033
7537
  main: this.createVoiceTTSFormGroup(),
7034
7538
  });
7035
7539
  }
7540
+ createAgenticConfigFormGroup() {
7541
+ return this.fb.group({
7542
+ enabled: [false],
7543
+ engine: [AgenticEngine.SERVER_SDK],
7544
+ pattern: [AgenticPattern.DIRECT],
7545
+ maxIterations: [5],
7546
+ allowedTools: this.fb.array([]),
7547
+ reflectionPrompt: [''],
7548
+ connectionUrl: [''],
7549
+ reasoningModel: createAIModelFormGroup(),
7550
+ executionModel: createAIModelFormGroup()
7551
+ });
7552
+ }
7036
7553
  // Operations with Array
7037
7554
  // If you have the main fromGroup use this fisrt versión
7038
7555
  removeArrayItem(formGroup, controlPath, index) {
@@ -7109,11 +7626,11 @@ class AgentTaskFormComponent {
7109
7626
  this.shortForm = false; // is short means AITask else SimpleAgentTask AiTaks is shorter
7110
7627
  }
7111
7628
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentTaskFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7112
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 class=\"flex space-x-4\">\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" /> Activada </div>\n\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.disableFeature\" binary=\"true\" /> Disable Feature </div>\n </div>\n\n <label for=\"task\" class=\"block text-sm font-medium\">Descripci\u00F3n de la evaluaci\u00F3n y asignaci\u00F3n de puntaje por turno</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\">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 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$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: 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: ["hostName", "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 }); }
7629
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 class=\"flex flex-col space-y-2 mb-4\">\n <div class=\"flex items-start gap-2\">\n <p-checkbox inputId=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" />\n <label for=\"enabled\" class=\"text-sm cursor-pointer select-none\">\n <strong>Activada:</strong> Habilita la tarea en esta carta (si el texto est\u00E1 vac\u00EDo, puede ser sobrescrito por la configuraci\u00F3n por defecto de la aplicaci\u00F3n host).\n </label>\n </div>\n\n <div class=\"flex items-start gap-2\">\n <p-checkbox inputId=\"disableFeature\" [formControl]=\"formGroup.controls.disableFeature\" binary=\"true\" />\n <label for=\"disableFeature\" class=\"text-sm cursor-pointer select-none text-red-600 dark:text-red-400\">\n <strong>Desactivar funci\u00F3n (Disable Feature):</strong> Ignora la configuraci\u00F3n por defecto y desactiva esta funci\u00F3n/tarea por completo para esta carta.\n </label>\n </div>\n </div>\n\n <label for=\"task\" class=\"block text-sm font-medium\">Descripci\u00F3n de la evaluaci\u00F3n y asignaci\u00F3n de puntaje por turno</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\">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 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: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: 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: ["hostName", "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 }); }
7113
7630
  }
7114
7631
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentTaskFormComponent, decorators: [{
7115
7632
  type: Component,
7116
- args: [{ selector: 'agent-task-form', imports: [TextareaModule, InputTextModule, ReactiveFormsModule, SelectModule, ModelSelectorComponent, ModelSelectorComponent, CheckboxModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <div class=\"flex space-x-4\">\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" /> Activada </div>\n\n <div> <p-checkbox id=\"enabled\" [formControl]=\"formGroup.controls.disableFeature\" binary=\"true\" /> Disable Feature </div>\n </div>\n\n <label for=\"task\" class=\"block text-sm font-medium\">Descripci\u00F3n de la evaluaci\u00F3n y asignaci\u00F3n de puntaje por turno</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\">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 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"] }]
7633
+ args: [{ selector: 'agent-task-form', imports: [TextareaModule, InputTextModule, ReactiveFormsModule, SelectModule, ModelSelectorComponent, ModelSelectorComponent, CheckboxModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <div class=\"flex flex-col space-y-2 mb-4\">\n <div class=\"flex items-start gap-2\">\n <p-checkbox inputId=\"enabled\" [formControl]=\"formGroup.controls.enabled\" binary=\"true\" />\n <label for=\"enabled\" class=\"text-sm cursor-pointer select-none\">\n <strong>Activada:</strong> Habilita la tarea en esta carta (si el texto est\u00E1 vac\u00EDo, puede ser sobrescrito por la configuraci\u00F3n por defecto de la aplicaci\u00F3n host).\n </label>\n </div>\n\n <div class=\"flex items-start gap-2\">\n <p-checkbox inputId=\"disableFeature\" [formControl]=\"formGroup.controls.disableFeature\" binary=\"true\" />\n <label for=\"disableFeature\" class=\"text-sm cursor-pointer select-none text-red-600 dark:text-red-400\">\n <strong>Desactivar funci\u00F3n (Disable Feature):</strong> Ignora la configuraci\u00F3n por defecto y desactiva esta funci\u00F3n/tarea por completo para esta carta.\n </label>\n </div>\n </div>\n\n <label for=\"task\" class=\"block text-sm font-medium\">Descripci\u00F3n de la evaluaci\u00F3n y asignaci\u00F3n de puntaje por turno</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\">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 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"] }]
7117
7634
  }], propDecorators: { formGroup: [{
7118
7635
  type: Input
7119
7636
  }], shortForm: [{
@@ -7131,7 +7648,7 @@ class DcDoActionFormComponent {
7131
7648
  this.removeItem.emit({ conditionIndex: this.conditionIndex, doItemIndex: this.doItemIndex });
7132
7649
  }
7133
7650
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDoActionFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7134
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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=\"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 \">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 \">Enabled</label>\n </div>\n } }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "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: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
7651
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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=\"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 \">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 \">Enabled</label>\n </div>\n } }\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "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: ["hostName", "value", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "inputStyle", "styleClass", "inputClass", "indeterminate", "formControl", "checkboxIcon", "readonly", "autofocus", "trueValue", "falseValue", "variant", "size"], outputs: ["onChange", "onFocus", "onBlur"] }] }); }
7135
7652
  }
7136
7653
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDoActionFormComponent, decorators: [{
7137
7654
  type: Component,
@@ -7192,7 +7709,7 @@ class DcDynamicConditionsFormComponent {
7192
7709
  return control;
7193
7710
  }
7194
7711
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDynamicConditionsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7195
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcDynamicConditionsFormComponent, isStandalone: true, selector: "dc-dynamic-conditions-form", inputs: { dynamicConditionsArray: "dynamicConditionsArray", dynamicConditionsPath: "dynamicConditionsPath", entityWhatOptions: "entityWhatOptions", entityWhenOptions: "entityWhenOptions", systemPromptTypeOptions: "systemPromptTypeOptions" }, ngImport: i0, template: "<div class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of dynamicConditionsArray.controls; track conditionControl; let i = $index) {\n <div class=\"group nested-group dynamic-condition-item\">\n <div class=\"flex justify-between items-center mb-4\">\n <h5>Condition {{ i + 1 }}</h5>\n <button\n pTooltip=\"Remove Condition\"\n variant=\"outlined\"\n [raised]=\"true\"\n pButton\n severity=\"danger\"\n icon=\"pi pi-trash\"\n (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhat' + i\"\n [options]=\"entityWhatOptions\"\n [formControl]=\"conditionControl.controls.what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhen' + i\"\n [options]=\"entityWhenOptions\"\n [formControl]=\"conditionControl.controls.when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionValue' + i\">Value <span pTooltip=\"Value to compare against\">\u2139\uFE0F</span></label>\n <input pInputText [id]=\"'conditionValue' + i\" type=\"text\" [formControl]=\"conditionControl.controls.value\" />\n </div>\n\n <div class=\"group very-nested-group\">\n <h6>DO THIS <span pTooltip=\"Tasks to execute if this condition is met\">\u2139\uFE0F</span></h6>\n @for (doControl of conditionControl.controls.do.controls; track doControl; let j = $index) {\n <dc-do-action-form\n [formGroup]=\"doControl\"\n [conditionIndex]=\"i\"\n [doItemIndex]=\"j\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\"\n (removeItem)=\"removeDoItem(i, j)\">\n </dc-do-action-form>\n }\n <button\n pButton\n type=\"button\"\n label=\"Add 'Do' Task\"\n icon=\"pi pi-plus\"\n (click)=\"addDoControl(conditionControl.controls.do)\"\n class=\"p-button-outlined p-button-sm\"\n style=\"margin-top: 10px\"></button>\n </div>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
7712
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcDynamicConditionsFormComponent, isStandalone: true, selector: "dc-dynamic-conditions-form", inputs: { dynamicConditionsArray: "dynamicConditionsArray", dynamicConditionsPath: "dynamicConditionsPath", entityWhatOptions: "entityWhatOptions", entityWhenOptions: "entityWhenOptions", systemPromptTypeOptions: "systemPromptTypeOptions" }, ngImport: i0, template: "<div class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of dynamicConditionsArray.controls; track conditionControl; let i = $index) {\n <div class=\"group nested-group dynamic-condition-item\">\n <div class=\"flex justify-between items-center mb-4\">\n <h5>Condition {{ i + 1 }}</h5>\n <button\n pTooltip=\"Remove Condition\"\n variant=\"outlined\"\n [raised]=\"true\"\n pButton\n severity=\"danger\"\n icon=\"pi pi-trash\"\n (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhat' + i\"\n [options]=\"entityWhatOptions\"\n [formControl]=\"conditionControl.controls.what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n <p-select\n [id]=\"'conditionWhen' + i\"\n [options]=\"entityWhenOptions\"\n [formControl]=\"conditionControl.controls.when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionValue' + i\">Value <span pTooltip=\"Value to compare against\">\u2139\uFE0F</span></label>\n <input pInputText [id]=\"'conditionValue' + i\" type=\"text\" [formControl]=\"conditionControl.controls.value\" />\n </div>\n\n <div class=\"group very-nested-group\">\n <h6>DO THIS <span pTooltip=\"Tasks to execute if this condition is met\">\u2139\uFE0F</span></h6>\n @for (doControl of conditionControl.controls.do.controls; track doControl; let j = $index) {\n <dc-do-action-form\n [formGroup]=\"doControl\"\n [conditionIndex]=\"i\"\n [doItemIndex]=\"j\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\"\n (removeItem)=\"removeDoItem(i, j)\">\n </dc-do-action-form>\n }\n <button\n pButton\n type=\"button\"\n label=\"Add 'Do' Task\"\n icon=\"pi pi-plus\"\n (click)=\"addDoControl(conditionControl.controls.do)\"\n class=\"p-button-outlined p-button-sm\"\n style=\"margin-top: 10px\"></button>\n </div>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "component", type: DcDoActionFormComponent, selector: "dc-do-action-form", inputs: ["formGroup", "conditionIndex", "doItemIndex", "systemPromptTypeOptions"], outputs: ["removeItem"] }] }); }
7196
7713
  }
7197
7714
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDynamicConditionsFormComponent, decorators: [{
7198
7715
  type: Component,
@@ -7250,7 +7767,7 @@ class DcDynamicCriteriaFormComponent {
7250
7767
  return control;
7251
7768
  }
7252
7769
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDynamicCriteriaFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7253
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\n <div [formGroup]=\"getItemFormGroup($index)\" class=\"criteria-item\">\n <button pButton type=\"button\" icon=\"pi pi-trash\" (click)=\"removeItem($index)\" class=\"p-button-danger p-button-sm remove-button\"></button>\n\n <div class=\"criteria-form-grid\">\n <div class=\"field-enabled\">\n <label for=\"enabled-{{ $index }}\" class=\"block mb-2\">Enabled</label>\n <p-checkbox formControlName=\"enabled\" [binary]=\"true\" inputId=\"enabled-{{ $index }}\"></p-checkbox>\n </div>\n\n <div class=\"field-name\">\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\n <div class=\"field-emoji\">\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=\"field-description\">\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 </div>\n <hr />\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: [".criteria-item{position:relative;border:1px solid var(--surface-d);border-radius:var(--border-radius);padding:1.5rem;margin-bottom:1rem}.remove-button{position:absolute;top:.5rem;right:.5rem}.criteria-form-grid{display:grid;grid-template-columns:auto 1fr 1fr;gap:1rem;align-items:center}.criteria-form-grid .field-description{grid-column:1/-1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "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: ["hostName", "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", "maskMotionOptions", "motionOptions", "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"] }] }); }
7770
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\n <div [formGroup]=\"getItemFormGroup($index)\" class=\"criteria-item\">\n <button pButton type=\"button\" icon=\"pi pi-trash\" (click)=\"removeItem($index)\" class=\"p-button-danger p-button-sm remove-button\"></button>\n\n <div class=\"criteria-form-grid\">\n <div class=\"field-enabled\">\n <label for=\"enabled-{{ $index }}\" class=\"block mb-2\">Enabled</label>\n <p-checkbox formControlName=\"enabled\" [binary]=\"true\" inputId=\"enabled-{{ $index }}\"></p-checkbox>\n </div>\n\n <div class=\"field-name\">\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\n <div class=\"field-emoji\">\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=\"field-description\">\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 </div>\n <hr />\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: [".criteria-item{position:relative;border:1px solid var(--surface-d);border-radius:var(--border-radius);padding:1.5rem;margin-bottom:1rem}.remove-button{position:absolute;top:.5rem;right:.5rem}.criteria-form-grid{display:grid;grid-template-columns:auto 1fr 1fr;gap:1rem;align-items:center}.criteria-form-grid .field-description{grid-column:1/-1}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "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: ["hostName", "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", "maskMotionOptions", "motionOptions", "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"] }] }); }
7254
7771
  }
7255
7772
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcDynamicCriteriaFormComponent, decorators: [{
7256
7773
  type: Component,
@@ -7325,7 +7842,7 @@ class DCConversationFlowFormComponent {
7325
7842
  console.log(this.formGroup.value);
7326
7843
  }
7327
7844
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCConversationFlowFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7328
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 > Solo puede sentir emociones Etiquetadas <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 <p-divider></p-divider>\n\n\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\"\n >Goal\n <span pTooltip=\"Aqu\u00ED se especifican las reglas de como se progresa en la conversaci\u00F3n , si esta desmarcada utiliza el prompt default\">\u2139\uFE0F</span></label\n >\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 <br />\n <div class=\"form-field\">\n <label for=\"maxTurns\"\n >Max Turns (Assistant Role)\n <span pTooltip=\"Maximum number of turns (assistant responses) before the conversation ends. Recommended: 10-30. Default: 20\">\u2139\uFE0F</span></label\n >\n <br />\n <p-inputnumber formControlName=\"maxTurns\" [showButtons]=\"true\" [min]=\"0\" [max]=\"100\" placeholder=\"Set max turns...\"></p-inputnumber>\n </div>\n\n <hr />\n\n <h4>Performance Analysis</h4>\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"enablePerformanceAnalysis\"></p-toggleswitch>\n <label>\n Retroalimentaci\u00F3n y Rendimiento Final\n <span pTooltip=\"When enabled, an AI performance analysis is triggered when the conversation ends. Requires at least 5 messages.\">\u2139\uFE0F</span>\n </label>\n </div>\n\n\n\n\n\n @if (formGroup.controls.enablePerformanceAnalysis.value) {\n <div class=\"form-field\">\n <label for=\"performancePrompt\"\n >Prompt de Retroalimentaci\u00F3n\n <span pTooltip=\"Custom prompt for the final performance analysis. If empty, the system uses the default template.\">\u2139\uFE0F</span></label\n >\n <textarea pTextarea [autoResize]=\"true\" class=\"w-full\" formControlName=\"performancePrompt\" placeholder=\"Enter custom performance prompt...\"></textarea>\n </div>\n }\n\n <dc-dynamic-conditions-form\n [dynamicConditionsArray]=\"formGroup.controls.dynamicConditions\"\n [dynamicConditionsPath]=\"'formGroup.controls.dynamicConditions'\"\n [entityWhatOptions]=\"entityWhatOptions\"\n [entityWhenOptions]=\"entityWhenOptions\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\">\n </dc-dynamic-conditions-form>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormArrayDirective, selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { 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: i4$1.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: InputNumberModule }, { kind: "component", type: i5$2.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: DividerModule }, { kind: "component", type: i1$3.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "pipe", type: FormatKeyPipe, name: "formatKey" }] }); }
7845
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 > Solo puede sentir emociones Etiquetadas <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 <p-divider></p-divider>\n\n\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\"\n >Goal\n <span pTooltip=\"Aqu\u00ED se especifican las reglas de como se progresa en la conversaci\u00F3n , si esta desmarcada utiliza el prompt default\">\u2139\uFE0F</span></label\n >\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 <br />\n <div class=\"form-field\">\n <label for=\"maxTurns\"\n >Max Turns (Assistant Role)\n <span pTooltip=\"Maximum number of turns (assistant responses) before the conversation ends. Recommended: 10-30. Default: 20\">\u2139\uFE0F</span></label\n >\n <br />\n <p-inputnumber formControlName=\"maxTurns\" [showButtons]=\"true\" [min]=\"0\" [max]=\"100\" placeholder=\"Set max turns...\"></p-inputnumber>\n </div>\n\n <hr />\n\n <h4>Performance Analysis</h4>\n <div class=\"form-field\">\n <p-toggleswitch formControlName=\"enablePerformanceAnalysis\"></p-toggleswitch>\n <label>\n Retroalimentaci\u00F3n y Rendimiento Final\n <span pTooltip=\"When enabled, an AI performance analysis is triggered when the conversation ends. Requires at least 5 messages.\">\u2139\uFE0F</span>\n </label>\n </div>\n\n\n\n\n\n @if (formGroup.controls.enablePerformanceAnalysis.value) {\n <div class=\"form-field\">\n <label for=\"performancePrompt\"\n >Prompt de Retroalimentaci\u00F3n\n <span pTooltip=\"Custom prompt for the final performance analysis. If empty, the system uses the default template.\">\u2139\uFE0F</span></label\n >\n <textarea pTextarea [autoResize]=\"true\" class=\"w-full\" formControlName=\"performancePrompt\" placeholder=\"Enter custom performance prompt...\"></textarea>\n </div>\n }\n\n <dc-dynamic-conditions-form\n [dynamicConditionsArray]=\"formGroup.controls.dynamicConditions\"\n [dynamicConditionsPath]=\"'formGroup.controls.dynamicConditions'\"\n [entityWhatOptions]=\"entityWhatOptions\"\n [entityWhenOptions]=\"entityWhenOptions\"\n [systemPromptTypeOptions]=\"systemPromptTypeOptions\">\n </dc-dynamic-conditions-form>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormArrayDirective, selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { 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: i4$2.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: InputNumberModule }, { kind: "component", type: i5$2.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: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "pipe", type: FormatKeyPipe, name: "formatKey" }] }); }
7329
7846
  }
7330
7847
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCConversationFlowFormComponent, decorators: [{
7331
7848
  type: Component,
@@ -7366,7 +7883,7 @@ class DcCharacterCardTranslationFormComponent {
7366
7883
  console.log(this.formGroup);
7367
7884
  }
7368
7885
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardTranslationFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7369
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 \">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 \">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 for=\"instructions\" class=\"block text-sm font-medium \">Instructions</label>\n <textarea\n pInputTextarea\n id=\"instructions\"\n formControlName=\"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 <div class=\"form-field\">\n <label class=\"block text-sm font-medium \">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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7886
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 \">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 \">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 for=\"instructions\" class=\"block text-sm font-medium \">Instructions</label>\n <textarea\n pInputTextarea\n id=\"instructions\"\n formControlName=\"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 <div class=\"form-field\">\n <label class=\"block text-sm font-medium \">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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
7370
7887
  }
7371
7888
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardTranslationFormComponent, decorators: [{
7372
7889
  type: Component,
@@ -7402,18 +7919,18 @@ class DcCharacterCardTranslationsTabsFormComponent {
7402
7919
  this.formGroup.removeControl(langCode);
7403
7920
  }
7404
7921
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardTranslationsTabsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7405
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: TabsModule }, { kind: "component", type: i2$5.Tabs, selector: "p-tabs", inputs: ["value", "scrollable", "lazy", "selectOnFocus", "showNavigators", "tabindex"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabPanels, selector: "p-tabpanels" }, { kind: "component", type: i2$5.TabPanel, selector: "p-tabpanel", inputs: ["lazy", "value"], outputs: ["valueChange"] }, { kind: "component", type: i2$5.TabList, selector: "p-tablist" }, { kind: "component", type: i2$5.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: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }] }); }
7922
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 gap-2\">\n @if(control.key | flagImg) {\n <img [src]=\"control.key | flagImg\" alt=\"{{ control.key }}\" class=\"w-5 h-auto rounded-sm border border-gray-300 shadow-sm\" />\n } @else {\n <span class=\"text-lg\">{{ control.key | flagEmoji }}</span>\n }\n <span class=\"font-medium capitalize\">{{ control.key | langDesc:'es' }}</span>\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 <div class=\"flex justify-end mb-4\">\n <p-button\n severity=\"danger\"\n icon=\"pi pi-trash\"\n label=\"Remove {{ control.key | langDesc:'es' }}\"\n [outlined]=\"true\"\n size=\"small\"\n (click)=\"removeLanguage(control.key)\"></p-button>\n </div>\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$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: ["lazy", "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: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: LangDescTranslation, name: "langDesc" }, { kind: "pipe", type: FlagPipe, name: "flagEmoji" }, { kind: "pipe", type: FlagImgPipe, name: "flagImg" }] }); }
7406
7923
  }
7407
7924
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardTranslationsTabsFormComponent, decorators: [{
7408
7925
  type: Component,
7409
- 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" }]
7926
+ args: [{ selector: 'dc-character-card-translations-tabs-form', standalone: true, imports: [ReactiveFormsModule, FormsModule, TabsModule, DcCharacterCardTranslationFormComponent, ButtonModule, DialogModule, SelectModule, KeyValuePipe, LangDescTranslation, FlagPipe, FlagImgPipe], 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 gap-2\">\n @if(control.key | flagImg) {\n <img [src]=\"control.key | flagImg\" alt=\"{{ control.key }}\" class=\"w-5 h-auto rounded-sm border border-gray-300 shadow-sm\" />\n } @else {\n <span class=\"text-lg\">{{ control.key | flagEmoji }}</span>\n }\n <span class=\"font-medium capitalize\">{{ control.key | langDesc:'es' }}</span>\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 <div class=\"flex justify-end mb-4\">\n <p-button\n severity=\"danger\"\n icon=\"pi pi-trash\"\n label=\"Remove {{ control.key | langDesc:'es' }}\"\n [outlined]=\"true\"\n size=\"small\"\n (click)=\"removeLanguage(control.key)\"></p-button>\n </div>\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" }]
7410
7927
  }], propDecorators: { formGroup: [{
7411
7928
  type: Input
7412
7929
  }] } });
7413
7930
 
7414
7931
  class DcPersonaFormComponent {
7415
7932
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcPersonaFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7416
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", 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\">\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
7933
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", 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\">\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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\"\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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }] }); }
7417
7934
  }
7418
7935
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcPersonaFormComponent, decorators: [{
7419
7936
  type: Component,
@@ -7538,7 +8055,7 @@ Improve the following first message:`;
7538
8055
  return control;
7539
8056
  }
7540
8057
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7541
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 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 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 \"\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 \"\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 \"\n >Description\n <span pTooltip=\"Descripci\u00F3n de la tarjeta, si es una tarjeta compleja utiliza los campos de PERSONA\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></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=\"cardCreatorNotes\" class=\"block text-sm font-medium \"\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 <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardInstructions\" class=\"block text-sm font-medium \"\n >Instructions <span pTooltip=\"Instrucciones para el usuario, sepa que tiene que hacer.\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardInstructions\"\n formControlName=\"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=\"cardScenario\" class=\"block text-sm font-medium \"\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 \"\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 \"\n >(\u2757\uFE0FObsoleto) Post-History Instructions\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=\"1\"\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=\"cardSystemPrompt\" class=\"block text-sm font-medium \">\n (\u26A0\uFE0F Cuidado) System Prompt <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span>\n </label>\n <textarea\n rows=\"1\"\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 for=\"cardCreatorNotes\" class=\"block text-sm font-medium \"\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=\"1\"\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 pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium \">Tags \u2139\uFE0F</label>\n <dc-tags-form [form]=\"dataGroup\" />\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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i1$3.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: "component", type: DcTagsFormComponent, selector: "dc-tags-form", inputs: ["form"] }] }); }
8058
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 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 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 \"\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 \"\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 \"\n >Description\n <span pTooltip=\"Descripci\u00F3n de la tarjeta, si es una tarjeta compleja utiliza los campos de PERSONA\" class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></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=\"cardCreatorNotes\" class=\"block text-sm font-medium \"\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 <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardInstructions\" class=\"block text-sm font-medium \"\n >Instructions <span pTooltip=\"Instrucciones para el usuario, sepa que tiene que hacer.\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardInstructions\"\n formControlName=\"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=\"cardScenario\" class=\"block text-sm font-medium \"\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 \"\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 \"\n >(\u2757\uFE0FObsoleto) Post-History Instructions\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=\"1\"\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=\"cardSystemPrompt\" class=\"block text-sm font-medium \">\n (\u26A0\uFE0F Cuidado) System Prompt <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span>\n </label>\n <textarea\n rows=\"1\"\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 for=\"cardCreatorNotes\" class=\"block text-sm font-medium \"\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=\"1\"\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 pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium \">Tags \u2139\uFE0F</label>\n <dc-tags-form [form]=\"dataGroup\" />\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$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.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: "component", type: DcTagsFormComponent, selector: "dc-tags-form", inputs: ["form"] }] }); }
7542
8059
  }
7543
8060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcCharacterCardFormComponent, decorators: [{
7544
8061
  type: Component,
@@ -7597,7 +8114,7 @@ class DcVoiceTtsFormComponent {
7597
8114
  });
7598
8115
  }
7599
8116
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcVoiceTtsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7600
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }, fullForm: { classPropertyName: "fullForm", publicName: "fullForm", isSignal: true, isRequired: false, transformFunction: null } }, providers: [DialogService], ngImport: i0, template: "<h3> {{ title() }}</h3>\n<div [formGroup]=\"form()\" class=\"form-grid\">\n @if (fullForm()) {\n <div class=\"form-field\">\n <label for=\"provider\">Provider <span pTooltip=\"TTS provider\">\u2139\uFE0F</span></label>\n <p-select id=\"provider\" [options]=\"providerOptions\" formControlName=\"provider\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select Provider\" class=\"w-full\"></p-select>\n </div>\n }\n\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\n @if (fullForm()) {\n <div class=\"form-field\">\n <label for=\"model\">Model <span pTooltip=\"Model ID if the provider requires it\">\u2139\uFE0F</span></label>\n <input pInputText id=\"model\" type=\"text\" formControlName=\"model\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Language code override (optional, usually included in the voice ID)\">\u2139\uFE0F</span></label>\n <input pInputText id=\"lang\" type=\"text\" formControlName=\"lang\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"effect\">Effect <span pTooltip=\"Platform audio effect\">\u2139\uFE0F</span></label>\n <input pInputText id=\"effect\" type=\"text\" formControlName=\"effect\" />\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i3$6.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: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CardModule }] }); }
8117
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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 }, fullForm: { classPropertyName: "fullForm", publicName: "fullForm", isSignal: true, isRequired: false, transformFunction: null } }, providers: [DialogService], ngImport: i0, template: "<h3> {{ title() }}</h3>\n<div [formGroup]=\"form()\" class=\"form-grid\">\n @if (fullForm()) {\n <div class=\"form-field\">\n <label for=\"provider\">Provider <span pTooltip=\"TTS provider\">\u2139\uFE0F</span></label>\n <p-select id=\"provider\" [options]=\"providerOptions\" formControlName=\"provider\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select Provider\" class=\"w-full\"></p-select>\n </div>\n }\n\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\n @if (fullForm()) {\n <div class=\"form-field\">\n <label for=\"model\">Model <span pTooltip=\"Model ID if the provider requires it\">\u2139\uFE0F</span></label>\n <input pInputText id=\"model\" type=\"text\" formControlName=\"model\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Language code override (optional, usually included in the voice ID)\">\u2139\uFE0F</span></label>\n <input pInputText id=\"lang\" type=\"text\" formControlName=\"lang\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"effect\">Effect <span pTooltip=\"Platform audio effect\">\u2139\uFE0F</span></label>\n <input pInputText id=\"effect\" type=\"text\" formControlName=\"effect\" />\n </div>\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "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$3.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CardModule }] }); }
7601
8118
  }
7602
8119
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcVoiceTtsFormComponent, decorators: [{
7603
8120
  type: Component,
@@ -7701,7 +8218,7 @@ class DcConversationSettingsFormComponent {
7701
8218
  this.getRules();
7702
8219
  }
7703
8220
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcConversationSettingsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
7704
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\">\n <h3 class=\"text-xl font-bold 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>\n <label for=\"rules\" class=\"block text-sm font-medium\">\n Conversation Rules\n <span pTooltip=\"Add rules to the conversation\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select id=\"rules\" [options]=\"rules\" (onChange)=\"addRule($event.value)\" placeholder=\"Select a Rule\" optionLabel=\"name\" class=\"w-full\"></p-select>\n\n <div formArrayName=\"rules\" class=\"mt-4 space-y-2\">\n @for (rule of rulesFormArray.controls; track rule; let i = $index) {\n <div [formGroupName]=\"i\" class=\"flex items-center justify-between p-2 border rounded-md\">\n <span>{{ rule.value.name }}</span>\n <button pButton type=\"button\" icon=\"pi pi-trash\" class=\"p-button-danger p-button-text\" (click)=\"removeRule(i)\"></button>\n </div>\n }\n </div>\n </div>\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\">\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 class=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium\">\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 class=\"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\">\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\n <div class=\"md:col-span-2\">\n <label for=\"displayMode\" class=\"block text-sm font-medium\">\n Display Mode\n <span pTooltip=\"chat: standard card layout | immersive: full-screen experience | transparent: character floats over background (requires transparent WebM video)\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"displayMode\"\n [options]=\"displayModeOptions\"\n formControlName=\"displayMode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select Display Mode\"\n class=\"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\">\n User Must Start\n <span pTooltip=\"If true the user must start the conversation, ignoring first message if any.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"userMustStart\"></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 <hr />\n</div>\n\n<p-popover #textEngineDialog [style]=\"{ width: '350px' }\" header=\"Text Engine Information\">\n <ng-template pTemplate=\"content\">\n <div class=\"p-4\">\n <h3 class=\"text-md font-semibold mb-3 text-gray-800\">Text Engine Types</h3>\n <ul class=\"space-y-3 text-sm text-gray-600\">\n <li>\n <strong class=\"font-semibold text-gray-900\">Texto Simple:</strong>\n La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">Multi Mensajes:</strong>\n Utiliza markdown (recomendable entenderlo), para dar formato al texto. El sistema puede partir dialogos con distinto formato (normal, cursiva,\n negritas) para generar distintas voces y estilos para el narrador y personaje.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">MD SSML:</strong>\n Markdown con SSML. Similar a Multi Mensajes, pero se presenta en un solo mensaje y la voz se genera para toda la linea. \u00DAtil para conversaciones\n biling\u00FCes.\n </li>\n </ul>\n </div>\n </ng-template>\n</p-popover>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$1.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: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], 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", "fullForm"] }] }); }
8221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\">\n <h3 class=\"text-xl font-bold 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>\n <label for=\"rules\" class=\"block text-sm font-medium\">\n Conversation Rules\n <span pTooltip=\"Add rules to the conversation\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select id=\"rules\" [options]=\"rules\" (onChange)=\"addRule($event.value)\" placeholder=\"Select a Rule\" optionLabel=\"name\" class=\"w-full\"></p-select>\n\n <div formArrayName=\"rules\" class=\"mt-4 space-y-2\">\n @for (rule of rulesFormArray.controls; track rule; let i = $index) {\n <div [formGroupName]=\"i\" class=\"flex items-center justify-between p-2 border rounded-md\">\n <span>{{ rule.value.name }}</span>\n <button pButton type=\"button\" icon=\"pi pi-trash\" class=\"p-button-danger p-button-text\" (click)=\"removeRule(i)\"></button>\n </div>\n }\n </div>\n </div>\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\">\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 class=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium\">\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 class=\"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\">\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\n <div class=\"md:col-span-2\">\n <label for=\"displayMode\" class=\"block text-sm font-medium\">\n Display Mode\n <span pTooltip=\"chat: standard card layout | immersive: full-screen experience | transparent: character floats over background (requires transparent WebM video)\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"displayMode\"\n [options]=\"displayModeOptions\"\n formControlName=\"displayMode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select Display Mode\"\n class=\"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\">\n User Must Start\n <span pTooltip=\"If true the user must start the conversation, ignoring first message if any.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"userMustStart\"></p-toggleSwitch>\n </div>\n\n <div class=\"flex items-center justify-between md:col-span-2\">\n <label class=\"text-sm font-medium\">\n Stream Responses\n <span pTooltip=\"Enable real-time token streaming for LLM responses.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"streamResponses\"></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 <hr />\n</div>\n\n<p-popover #textEngineDialog [style]=\"{ width: '350px' }\" header=\"Text Engine Information\">\n <ng-template pTemplate=\"content\">\n <div class=\"p-4\">\n <h3 class=\"text-md font-semibold mb-3 text-gray-800\">Text Engine Types</h3>\n <ul class=\"space-y-3 text-sm text-gray-600\">\n <li>\n <strong class=\"font-semibold text-gray-900\">Texto Simple:</strong>\n La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">Multi Mensajes:</strong>\n Utiliza markdown (recomendable entenderlo), para dar formato al texto. El sistema puede partir dialogos con distinto formato (normal, cursiva,\n negritas) para generar distintas voces y estilos para el narrador y personaje.\n </li>\n <li>\n <strong class=\"font-semibold text-gray-900\">MD SSML:</strong>\n Markdown con SSML. Similar a Multi Mensajes, pero se presenta en un solo mensaje y la voz se genera para toda la linea. \u00DAtil para conversaciones\n biling\u00FCes.\n </li>\n </ul>\n </div>\n </ng-template>\n</p-popover>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1$1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$2.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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i2$3.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions", "motionOptions"], 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", "fullForm"] }] }); }
7705
8222
  }
7706
8223
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcConversationSettingsFormComponent, decorators: [{
7707
8224
  type: Component,
@@ -7716,7 +8233,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
7716
8233
  DynamicDialogModule,
7717
8234
  ModelSelectorComponent,
7718
8235
  DcVoiceTtsFormComponent,
7719
- ], providers: [DialogService], template: "<div [formGroup]=\"form\">\n <h3 class=\"text-xl font-bold 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>\n <label for=\"rules\" class=\"block text-sm font-medium\">\n Conversation Rules\n <span pTooltip=\"Add rules to the conversation\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select id=\"rules\" [options]=\"rules\" (onChange)=\"addRule($event.value)\" placeholder=\"Select a Rule\" optionLabel=\"name\" class=\"w-full\"></p-select>\n\n <div formArrayName=\"rules\" class=\"mt-4 space-y-2\">\n @for (rule of rulesFormArray.controls; track rule; let i = $index) {\n <div [formGroupName]=\"i\" class=\"flex items-center justify-between p-2 border rounded-md\">\n <span>{{ rule.value.name }}</span>\n <button pButton type=\"button\" icon=\"pi pi-trash\" class=\"p-button-danger p-button-text\" (click)=\"removeRule(i)\"></button>\n </div>\n }\n </div>\n </div>\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\">\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 class=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium\">\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 class=\"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\">\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\n <div class=\"md:col-span-2\">\n <label for=\"displayMode\" class=\"block text-sm font-medium\">\n Display Mode\n <span pTooltip=\"chat: standard card layout | immersive: full-screen experience | transparent: character floats over background (requires transparent WebM video)\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"displayMode\"\n [options]=\"displayModeOptions\"\n formControlName=\"displayMode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select Display Mode\"\n class=\"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\">\n User Must Start\n <span pTooltip=\"If true the user must start the conversation, ignoring first message if any.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"userMustStart\"></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 <hr />\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" }]
8236
+ ], providers: [DialogService], template: "<div [formGroup]=\"form\">\n <h3 class=\"text-xl font-bold 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>\n <label for=\"rules\" class=\"block text-sm font-medium\">\n Conversation Rules\n <span pTooltip=\"Add rules to the conversation\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select id=\"rules\" [options]=\"rules\" (onChange)=\"addRule($event.value)\" placeholder=\"Select a Rule\" optionLabel=\"name\" class=\"w-full\"></p-select>\n\n <div formArrayName=\"rules\" class=\"mt-4 space-y-2\">\n @for (rule of rulesFormArray.controls; track rule; let i = $index) {\n <div [formGroupName]=\"i\" class=\"flex items-center justify-between p-2 border rounded-md\">\n <span>{{ rule.value.name }}</span>\n <button pButton type=\"button\" icon=\"pi pi-trash\" class=\"p-button-danger p-button-text\" (click)=\"removeRule(i)\"></button>\n </div>\n }\n </div>\n </div>\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\">\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 class=\"w-full mt-1\"></p-select>\n </div>\n\n <div>\n <label for=\"textEngine\" class=\"block text-sm font-medium\">\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 class=\"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\">\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\n <div class=\"md:col-span-2\">\n <label for=\"displayMode\" class=\"block text-sm font-medium\">\n Display Mode\n <span pTooltip=\"chat: standard card layout | immersive: full-screen experience | transparent: character floats over background (requires transparent WebM video)\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-select\n id=\"displayMode\"\n [options]=\"displayModeOptions\"\n formControlName=\"displayMode\"\n optionLabel=\"label\"\n optionValue=\"value\"\n placeholder=\"Select Display Mode\"\n class=\"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\">\n User Must Start\n <span pTooltip=\"If true the user must start the conversation, ignoring first message if any.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"userMustStart\"></p-toggleSwitch>\n </div>\n\n <div class=\"flex items-center justify-between md:col-span-2\">\n <label class=\"text-sm font-medium\">\n Stream Responses\n <span pTooltip=\"Enable real-time token streaming for LLM responses.\" class=\"text-blue-500 cursor-help\">\u2139\uFE0F</span>\n </label>\n <p-toggleSwitch formControlName=\"streamResponses\"></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 <hr />\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" }]
7720
8237
  }], propDecorators: { form: [{
7721
8238
  type: Input
7722
8239
  }], textEngineOptions: [{
@@ -7742,6 +8259,15 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
7742
8259
  this.textEngineOptions = TextEngineOptions;
7743
8260
  this.languageOptions = getSupportedLanguageOptions('es');
7744
8261
  this.agentTypeOptions = Object.values(EAgentType).filter((value) => value !== null);
8262
+ this.agenticEngineOptions = Object.values(AgenticEngine);
8263
+ this.agenticPatternOptions = Object.values(AgenticPattern);
8264
+ this.allowedToolsOptions = [
8265
+ { label: 'Obtener Puntuación (getScore)', value: 'getScore' },
8266
+ { label: 'Perfil de Usuario (getUserProfile)', value: 'getUserProfile' },
8267
+ { label: 'Estadísticas de Usuario (getUserStats)', value: 'getUserStats' },
8268
+ { label: 'Ajustes de Usuario (getUserSettings)', value: 'getUserSettings' },
8269
+ { label: 'Palabras del Usuario (getUserWords)', value: 'getUserWords' }
8270
+ ];
7745
8271
  this.onSave = output();
7746
8272
  this.form = this.characterFormGroupService.createAgentCardForm();
7747
8273
  this.isGenerating = signal(false, ...(ngDevMode ? [{ debugName: "isGenerating" }] : /* istanbul ignore next */ []));
@@ -7750,7 +8276,6 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
7750
8276
  const sampleUrl = this.form.get('voiceCloning.sample')?.value?.url;
7751
8277
  const voiceId = this.form.get('voiceCloning.main.voice')?.value;
7752
8278
  const canCloneVoiceVar = !!sampleUrl && !voiceId;
7753
- debugger;
7754
8279
  return canCloneVoiceVar;
7755
8280
  }, ...(ngDevMode ? [{ debugName: "canCloneVoice" }] : /* istanbul ignore next */ []));
7756
8281
  this.fishModelId = computed(() => {
@@ -7759,6 +8284,26 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
7759
8284
  return voiceId && provider === 'fish-audio' ? voiceId : null;
7760
8285
  }, ...(ngDevMode ? [{ debugName: "fishModelId" }] : /* istanbul ignore next */ []));
7761
8286
  }
8287
+ isToolAllowed(toolValue) {
8288
+ const allowedTools = this.form.get('agenticConfig.allowedTools');
8289
+ return allowedTools?.value?.includes(toolValue);
8290
+ }
8291
+ toggleTool(toolValue, checked) {
8292
+ const allowedTools = this.form.get('agenticConfig.allowedTools');
8293
+ if (checked) {
8294
+ if (!allowedTools.value.includes(toolValue)) {
8295
+ allowedTools.push(this.fb.control(toolValue));
8296
+ allowedTools.markAsDirty();
8297
+ }
8298
+ }
8299
+ else {
8300
+ const index = allowedTools.value.indexOf(toolValue);
8301
+ if (index !== -1) {
8302
+ allowedTools.removeAt(index);
8303
+ allowedTools.markAsDirty();
8304
+ }
8305
+ }
8306
+ }
7762
8307
  patchForm(agentCard) {
7763
8308
  this.characterFormGroupService.patchFormWithConversationData(this.form, agentCard);
7764
8309
  this.characterFormGroupService.handleArrayForms(this.form, agentCard);
@@ -7982,7 +8527,7 @@ class DCAgentCardFormComponent extends EntityBaseFormComponent {
7982
8527
  this.router.navigate(['../../cards-creator'], { relativeTo: this.route });
7983
8528
  }
7984
8529
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCAgentCardFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
7985
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", outputs: { onSave: "onSave" }, 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 [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 <p-button severity=\"danger\" (click)=\"deleteCard()\" icon=\"pi pi-trash\"></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\" >\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n\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 <p-accordion [multiple]=\"true\" >\n <p-accordion-panel value=\"manageable\">\n <p-accordion-header>\n <span>Manageable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Controla visibilidad y acceso</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"learnable\">\n <p-accordion-header>\n <span>Learnable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Aprendizaje y conocimiento</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"conversationSettings\">\n <p-accordion-header>\n <span>Conversation Settings</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Modelo, voz y configuraci\u00F3n del chat</span>\n </p-accordion-header>\n <p-accordion-content>\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 </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.conversationFlow){\n <p-accordion-panel value=\"conversationFlow\">\n <p-accordion-header>\n <span>Conversation Flow</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Objetivos, triggers y condiciones din\u00E1micas</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </p-accordion-content>\n </p-accordion-panel>\n }\n <p-accordion-panel value=\"accounts\">\n <p-accordion-header>\n <span>Gesti\u00F3n de cuentas</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n @if(form.controls.accounts) {\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"voiceCloning\">\n <p-accordion-header>\n <span>Clonaci\u00F3n de voz</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"voiceCloning\">\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 <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 class=\"form-field voice-clone-status\">\n @if(!form.get('voiceCloning.sample').value?.url){\n <small class=\"muted\">Sube un audio para entrenar un modelo de voz.</small>\n }\n <!-- @if(canCloneVoice()){ -->\n <p-button\n icon=\"pi pi-bolt\"\n severity=\"help\"\n [loading]=\"isCloningVoice()\"\n label=\"Crear modelo en Fish Audio\"\n (click)=\"cloneVoice()\">\n </p-button>\n <!-- } -->\n @if(fishModelId()){\n <div class=\"model-tag\">\n <span>Modelo Fish Audio: <code>{{ fishModelId() }}</code></span>\n <p-button\n icon=\"pi pi-refresh\"\n severity=\"secondary\"\n [text]=\"true\"\n [loading]=\"isCloningVoice()\"\n label=\"Regenerar\"\n (click)=\"cloneVoice()\">\n </p-button>\n </div>\n }\n </div>\n <dc-voice-tts-form\n [form]=\"$any(form.get('voiceCloning.main'))\"\n [title]=\"'Voice Cloning \u2014 Main Voice'\"\n [voiceTTSOptions]=\"voiceTTSOptions\"\n [fullForm]=\"true\">\n </dc-voice-tts-form>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n </p-accordion>\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 .card-group{padding:1rem;margin-bottom:1.5rem}.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%}.voice-clone-status{display:flex;flex-direction:column;gap:.5rem;margin:.75rem 0}.voice-clone-status .muted{color:var(--p-text-muted-color)}.voice-clone-status .model-tag{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;background:var(--p-surface-100, #f3f4f6);border-radius:6px;font-size:.9rem}.voice-clone-status .model-tag code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormArrayDirective, selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: AssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], 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$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i7.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i7.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i7.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i7.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { 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: MessageModule }, { kind: "component", type: DcConversationSettingsFormComponent, selector: "dc-conversation-settings-form", inputs: ["form", "textEngineOptions", "conversationOptions", "voiceTTSOptions"] }, { kind: "component", type: DcVoiceTtsFormComponent, selector: "dc-voice-tts-form", inputs: ["form", "title", "voiceTTSOptions", "fullForm"] }, { 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", "provider"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }] }); }
8530
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", outputs: { onSave: "onSave" }, 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 [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 <p-button severity=\"danger\" (click)=\"deleteCard()\" icon=\"pi pi-trash\"></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\" >\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n\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 <p-accordion [multiple]=\"true\" >\n <p-accordion-panel value=\"manageable\">\n <p-accordion-header>\n <span>Manageable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Controla visibilidad y acceso</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"learnable\">\n <p-accordion-header>\n <span>Learnable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Aprendizaje y conocimiento</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"conversationSettings\">\n <p-accordion-header>\n <span>Conversation Settings</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Modelo, voz y configuraci\u00F3n del chat</span>\n </p-accordion-header>\n <p-accordion-content>\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 </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.conversationFlow){\n <p-accordion-panel value=\"conversationFlow\">\n <p-accordion-header>\n <span>Conversation Flow</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Objetivos, triggers y condiciones din\u00E1micas</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </p-accordion-content>\n </p-accordion-panel>\n }\n <p-accordion-panel value=\"accounts\">\n <p-accordion-header>\n <span>Gesti\u00F3n de cuentas</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n @if(form.controls.accounts) {\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"voiceCloning\">\n <p-accordion-header>\n <span>Clonaci\u00F3n de voz</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"voiceCloning\">\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 <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 class=\"form-field voice-clone-status\">\n @if(!form.get('voiceCloning.sample').value?.url){\n <small class=\"muted\">Sube un audio para entrenar un modelo de voz.</small>\n }\n <!-- @if(canCloneVoice()){ -->\n <p-button\n icon=\"pi pi-bolt\"\n severity=\"help\"\n [loading]=\"isCloningVoice()\"\n label=\"Crear modelo en Fish Audio\"\n (click)=\"cloneVoice()\">\n </p-button>\n <!-- } -->\n @if(fishModelId()){\n <div class=\"model-tag\">\n <span>Modelo Fish Audio: <code>{{ fishModelId() }}</code></span>\n <p-button\n icon=\"pi pi-refresh\"\n severity=\"secondary\"\n [text]=\"true\"\n [loading]=\"isCloningVoice()\"\n label=\"Regenerar\"\n (click)=\"cloneVoice()\">\n </p-button>\n </div>\n }\n </div>\n <dc-voice-tts-form\n [form]=\"$any(form.get('voiceCloning.main'))\"\n [title]=\"'Voice Cloning \u2014 Main Voice'\"\n [voiceTTSOptions]=\"voiceTTSOptions\"\n [fullForm]=\"true\">\n </dc-voice-tts-form>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.agenticConfig) {\n <p-accordion-panel value=\"agenticConfig\">\n <p-accordion-header>\n <span>Configuraci\u00F3n Ag\u00E9ntica</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Motor ag\u00E9ntico, patrones y herramientas</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"agenticConfig\">\n <div class=\"form-field flex items-center gap-2 mb-4\">\n <p-checkbox id=\"agenticEnabled\" formControlName=\"enabled\" [binary]=\"true\"></p-checkbox>\n <label for=\"agenticEnabled\" class=\"cursor-pointer\">Habilitar Agente Aut\u00F3nomo</label>\n </div>\n\n @if(form.get('agenticConfig.enabled').value) {\n <div class=\"form-field mb-4\">\n <label for=\"agenticEngine\" class=\"block text-sm font-medium mb-1\">Motor Ag\u00E9ntico</label>\n <p-select\n id=\"agenticEngine\"\n [options]=\"agenticEngineOptions\"\n formControlName=\"engine\"\n [placeholder]=\"'Seleccionar Motor'\"\n class=\"w-full\"></p-select>\n </div>\n\n <div class=\"form-field mb-4\">\n <label for=\"agenticPattern\" class=\"block text-sm font-medium mb-1\">Patr\u00F3n Ag\u00E9ntico</label>\n <p-select\n id=\"agenticPattern\"\n [options]=\"agenticPatternOptions\"\n formControlName=\"pattern\"\n [placeholder]=\"'Seleccionar Patr\u00F3n'\"\n class=\"w-full\"></p-select>\n </div>\n\n <div class=\"form-field mb-4\">\n <label for=\"maxIterations\" class=\"block text-sm font-medium mb-1\">M\u00E1ximo de Iteraciones</label>\n <input pInputText id=\"maxIterations\" type=\"number\" formControlName=\"maxIterations\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field mb-4\">\n <label class=\"block text-sm font-medium mb-2\">Herramientas Permitidas</label>\n <div class=\"flex flex-col gap-2 mt-2 pl-2\">\n @for (toolOpt of allowedToolsOptions; track toolOpt.value) {\n <div class=\"flex items-center gap-2\">\n <p-checkbox\n [inputId]=\"'tool_' + toolOpt.value\"\n [binary]=\"true\"\n [ngModel]=\"isToolAllowed(toolOpt.value)\"\n [ngModelOptions]=\"{standalone: true}\"\n (onChange)=\"toggleTool(toolOpt.value, $event.checked)\">\n </p-checkbox>\n <label [for]=\"'tool_' + toolOpt.value\" class=\"cursor-pointer text-sm\">{{ toolOpt.label }}</label>\n </div>\n }\n </div>\n </div>\n\n @if(form.get('agenticConfig.pattern').value === 'reflection') {\n <div class=\"form-field mb-4\">\n <label for=\"reflectionPrompt\" class=\"block text-sm font-medium mb-1\">Prompt de Reflexi\u00F3n</label>\n <textarea pTextarea id=\"reflectionPrompt\" formControlName=\"reflectionPrompt\" rows=\"3\" [autoResize]=\"true\" class=\"w-full\"></textarea>\n </div>\n }\n\n @if(form.get('agenticConfig.engine').value === 'os_hermes') {\n <div class=\"form-field mb-4\">\n <label for=\"connectionUrl\" class=\"block text-sm font-medium mb-1\">URL de Conexi\u00F3n</label>\n <input pInputText id=\"connectionUrl\" type=\"text\" formControlName=\"connectionUrl\" placeholder=\"ws://...\" class=\"w-full\" />\n </div>\n }\n\n <div class=\"form-field mt-6\">\n <h4 class=\"font-semibold text-base mb-2\">Modelo de Razonamiento</h4>\n <dc-model-selector [modelForm]=\"$any(form.get('agenticConfig.reasoningModel'))\" [shortForm]=\"true\"></dc-model-selector>\n </div>\n\n <div class=\"form-field mt-6\">\n <h4 class=\"font-semibold text-base mb-2\">Modelo de Ejecuci\u00F3n</h4>\n <dc-model-selector [modelForm]=\"$any(form.get('agenticConfig.executionModel'))\" [shortForm]=\"true\"></dc-model-selector>\n </div>\n }\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\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 .card-group{padding:1rem;margin-bottom:1.5rem}.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%}.voice-clone-status{display:flex;flex-direction:column;gap:.5rem;margin:.75rem 0}.voice-clone-status .muted{color:var(--p-text-muted-color)}.voice-clone-status .model-tag{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;background:var(--p-surface-100, #f3f4f6);border-radius:6px;font-size:.9rem}.voice-clone-status .model-tag code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormArrayDirective, selector: "[formArray]", inputs: ["formArray"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1$1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: AssetsLoaderComponent, selector: "assets-loader", inputs: ["assets", "storagePath"], outputs: ["assetsChange", "assetUpdate", "onFileSelected"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2.ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "pButtonPT", "pButtonUnstyled", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i4.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["hostName", "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: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], 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$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: AccordionModule }, { kind: "component", type: i8.Accordion, selector: "p-accordion", inputs: ["value", "multiple", "styleClass", "expandIcon", "collapseIcon", "selectOnFocus", "transitionOptions", "motionOptions"], outputs: ["valueChange", "onClose", "onOpen"] }, { kind: "component", type: i8.AccordionPanel, selector: "p-accordion-panel, p-accordionpanel", inputs: ["value", "disabled"], outputs: ["valueChange"] }, { kind: "component", type: i8.AccordionHeader, selector: "p-accordion-header, p-accordionheader" }, { kind: "component", type: i8.AccordionContent, selector: "p-accordion-content, p-accordioncontent" }, { 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: MessageModule }, { kind: "component", type: DcConversationSettingsFormComponent, selector: "dc-conversation-settings-form", inputs: ["form", "textEngineOptions", "conversationOptions", "voiceTTSOptions"] }, { kind: "component", type: DcVoiceTtsFormComponent, selector: "dc-voice-tts-form", inputs: ["form", "title", "voiceTTSOptions", "fullForm"] }, { 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", "provider"], outputs: ["fileUploaded", "uploadError"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "component", type: ModelSelectorComponent, selector: "dc-model-selector", inputs: ["modelForm", "shortForm"] }] }); }
7986
8531
  }
7987
8532
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DCAgentCardFormComponent, decorators: [{
7988
8533
  type: Component,
@@ -8009,7 +8554,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
8009
8554
  DcLearnableFormComponent,
8010
8555
  SimpleUploaderComponent,
8011
8556
  TextareaModule,
8012
- ], 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 [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 <p-button severity=\"danger\" (click)=\"deleteCard()\" icon=\"pi pi-trash\"></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\" >\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n\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 <p-accordion [multiple]=\"true\" >\n <p-accordion-panel value=\"manageable\">\n <p-accordion-header>\n <span>Manageable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Controla visibilidad y acceso</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"learnable\">\n <p-accordion-header>\n <span>Learnable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Aprendizaje y conocimiento</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"conversationSettings\">\n <p-accordion-header>\n <span>Conversation Settings</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Modelo, voz y configuraci\u00F3n del chat</span>\n </p-accordion-header>\n <p-accordion-content>\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 </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.conversationFlow){\n <p-accordion-panel value=\"conversationFlow\">\n <p-accordion-header>\n <span>Conversation Flow</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Objetivos, triggers y condiciones din\u00E1micas</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </p-accordion-content>\n </p-accordion-panel>\n }\n <p-accordion-panel value=\"accounts\">\n <p-accordion-header>\n <span>Gesti\u00F3n de cuentas</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n @if(form.controls.accounts) {\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"voiceCloning\">\n <p-accordion-header>\n <span>Clonaci\u00F3n de voz</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"voiceCloning\">\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 <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 class=\"form-field voice-clone-status\">\n @if(!form.get('voiceCloning.sample').value?.url){\n <small class=\"muted\">Sube un audio para entrenar un modelo de voz.</small>\n }\n <!-- @if(canCloneVoice()){ -->\n <p-button\n icon=\"pi pi-bolt\"\n severity=\"help\"\n [loading]=\"isCloningVoice()\"\n label=\"Crear modelo en Fish Audio\"\n (click)=\"cloneVoice()\">\n </p-button>\n <!-- } -->\n @if(fishModelId()){\n <div class=\"model-tag\">\n <span>Modelo Fish Audio: <code>{{ fishModelId() }}</code></span>\n <p-button\n icon=\"pi pi-refresh\"\n severity=\"secondary\"\n [text]=\"true\"\n [loading]=\"isCloningVoice()\"\n label=\"Regenerar\"\n (click)=\"cloneVoice()\">\n </p-button>\n </div>\n }\n </div>\n <dc-voice-tts-form\n [form]=\"$any(form.get('voiceCloning.main'))\"\n [title]=\"'Voice Cloning \u2014 Main Voice'\"\n [voiceTTSOptions]=\"voiceTTSOptions\"\n [fullForm]=\"true\">\n </dc-voice-tts-form>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n </p-accordion>\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 .card-group{padding:1rem;margin-bottom:1.5rem}.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%}.voice-clone-status{display:flex;flex-direction:column;gap:.5rem;margin:.75rem 0}.voice-clone-status .muted{color:var(--p-text-muted-color)}.voice-clone-status .model-tag{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;background:var(--p-surface-100, #f3f4f6);border-radius:6px;font-size:.9rem}.voice-clone-status .model-tag code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8rem}\n"] }]
8557
+ ModelSelectorComponent,
8558
+ ], 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 [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 <p-button severity=\"danger\" (click)=\"deleteCard()\" icon=\"pi pi-trash\"></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\" >\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.get('version').value }} <span pTooltip=\"Version number of the conversation\">\u2139\uFE0F</span></label>\n </div>\n\n <div class=\"form-field\">\n <label for=\"id\"\n >ID: <span pTooltip=\"Unique identifier for this conversation\"> {{ form.get('id').value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n\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 <p-accordion [multiple]=\"true\" >\n <p-accordion-panel value=\"manageable\">\n <p-accordion-header>\n <span>Manageable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Controla visibilidad y acceso</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-manageable-form [form]=\"form.controls.manageable\"></dc-manageable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"learnable\">\n <p-accordion-header>\n <span>Learnable</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Aprendizaje y conocimiento</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-learnable-form [form]=\"form.controls.learnable\"></dc-learnable-form>\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"conversationSettings\">\n <p-accordion-header>\n <span>Conversation Settings</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Modelo, voz y configuraci\u00F3n del chat</span>\n </p-accordion-header>\n <p-accordion-content>\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 </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.conversationFlow){\n <p-accordion-panel value=\"conversationFlow\">\n <p-accordion-header>\n <span>Conversation Flow</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Objetivos, triggers y condiciones din\u00E1micas</span>\n </p-accordion-header>\n <p-accordion-content>\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </p-accordion-content>\n </p-accordion-panel>\n }\n <p-accordion-panel value=\"accounts\">\n <p-accordion-header>\n <span>Gesti\u00F3n de cuentas</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n @if(form.controls.accounts) {\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </p-accordion-content>\n </p-accordion-panel>\n <p-accordion-panel value=\"voiceCloning\">\n <p-accordion-header>\n <span>Clonaci\u00F3n de voz</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Beta</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"voiceCloning\">\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 <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 class=\"form-field voice-clone-status\">\n @if(!form.get('voiceCloning.sample').value?.url){\n <small class=\"muted\">Sube un audio para entrenar un modelo de voz.</small>\n }\n <!-- @if(canCloneVoice()){ -->\n <p-button\n icon=\"pi pi-bolt\"\n severity=\"help\"\n [loading]=\"isCloningVoice()\"\n label=\"Crear modelo en Fish Audio\"\n (click)=\"cloneVoice()\">\n </p-button>\n <!-- } -->\n @if(fishModelId()){\n <div class=\"model-tag\">\n <span>Modelo Fish Audio: <code>{{ fishModelId() }}</code></span>\n <p-button\n icon=\"pi pi-refresh\"\n severity=\"secondary\"\n [text]=\"true\"\n [loading]=\"isCloningVoice()\"\n label=\"Regenerar\"\n (click)=\"cloneVoice()\">\n </p-button>\n </div>\n }\n </div>\n <dc-voice-tts-form\n [form]=\"$any(form.get('voiceCloning.main'))\"\n [title]=\"'Voice Cloning \u2014 Main Voice'\"\n [voiceTTSOptions]=\"voiceTTSOptions\"\n [fullForm]=\"true\">\n </dc-voice-tts-form>\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n @if(form.controls.agenticConfig) {\n <p-accordion-panel value=\"agenticConfig\">\n <p-accordion-header>\n <span>Configuraci\u00F3n Ag\u00E9ntica</span>\n <span style=\"margin-left: 8px; font-size: 0.75rem; color: var(--p-text-muted-color); font-weight: normal\">Motor ag\u00E9ntico, patrones y herramientas</span>\n </p-accordion-header>\n <p-accordion-content>\n <div formGroupName=\"agenticConfig\">\n <div class=\"form-field flex items-center gap-2 mb-4\">\n <p-checkbox id=\"agenticEnabled\" formControlName=\"enabled\" [binary]=\"true\"></p-checkbox>\n <label for=\"agenticEnabled\" class=\"cursor-pointer\">Habilitar Agente Aut\u00F3nomo</label>\n </div>\n\n @if(form.get('agenticConfig.enabled').value) {\n <div class=\"form-field mb-4\">\n <label for=\"agenticEngine\" class=\"block text-sm font-medium mb-1\">Motor Ag\u00E9ntico</label>\n <p-select\n id=\"agenticEngine\"\n [options]=\"agenticEngineOptions\"\n formControlName=\"engine\"\n [placeholder]=\"'Seleccionar Motor'\"\n class=\"w-full\"></p-select>\n </div>\n\n <div class=\"form-field mb-4\">\n <label for=\"agenticPattern\" class=\"block text-sm font-medium mb-1\">Patr\u00F3n Ag\u00E9ntico</label>\n <p-select\n id=\"agenticPattern\"\n [options]=\"agenticPatternOptions\"\n formControlName=\"pattern\"\n [placeholder]=\"'Seleccionar Patr\u00F3n'\"\n class=\"w-full\"></p-select>\n </div>\n\n <div class=\"form-field mb-4\">\n <label for=\"maxIterations\" class=\"block text-sm font-medium mb-1\">M\u00E1ximo de Iteraciones</label>\n <input pInputText id=\"maxIterations\" type=\"number\" formControlName=\"maxIterations\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field mb-4\">\n <label class=\"block text-sm font-medium mb-2\">Herramientas Permitidas</label>\n <div class=\"flex flex-col gap-2 mt-2 pl-2\">\n @for (toolOpt of allowedToolsOptions; track toolOpt.value) {\n <div class=\"flex items-center gap-2\">\n <p-checkbox\n [inputId]=\"'tool_' + toolOpt.value\"\n [binary]=\"true\"\n [ngModel]=\"isToolAllowed(toolOpt.value)\"\n [ngModelOptions]=\"{standalone: true}\"\n (onChange)=\"toggleTool(toolOpt.value, $event.checked)\">\n </p-checkbox>\n <label [for]=\"'tool_' + toolOpt.value\" class=\"cursor-pointer text-sm\">{{ toolOpt.label }}</label>\n </div>\n }\n </div>\n </div>\n\n @if(form.get('agenticConfig.pattern').value === 'reflection') {\n <div class=\"form-field mb-4\">\n <label for=\"reflectionPrompt\" class=\"block text-sm font-medium mb-1\">Prompt de Reflexi\u00F3n</label>\n <textarea pTextarea id=\"reflectionPrompt\" formControlName=\"reflectionPrompt\" rows=\"3\" [autoResize]=\"true\" class=\"w-full\"></textarea>\n </div>\n }\n\n @if(form.get('agenticConfig.engine').value === 'os_hermes') {\n <div class=\"form-field mb-4\">\n <label for=\"connectionUrl\" class=\"block text-sm font-medium mb-1\">URL de Conexi\u00F3n</label>\n <input pInputText id=\"connectionUrl\" type=\"text\" formControlName=\"connectionUrl\" placeholder=\"ws://...\" class=\"w-full\" />\n </div>\n }\n\n <div class=\"form-field mt-6\">\n <h4 class=\"font-semibold text-base mb-2\">Modelo de Razonamiento</h4>\n <dc-model-selector [modelForm]=\"$any(form.get('agenticConfig.reasoningModel'))\" [shortForm]=\"true\"></dc-model-selector>\n </div>\n\n <div class=\"form-field mt-6\">\n <h4 class=\"font-semibold text-base mb-2\">Modelo de Ejecuci\u00F3n</h4>\n <dc-model-selector [modelForm]=\"$any(form.get('agenticConfig.executionModel'))\" [shortForm]=\"true\"></dc-model-selector>\n </div>\n }\n </div>\n </p-accordion-content>\n </p-accordion-panel>\n }\n </p-accordion>\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 .card-group{padding:1rem;margin-bottom:1.5rem}.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%}.voice-clone-status{display:flex;flex-direction:column;gap:.5rem;margin:.75rem 0}.voice-clone-status .muted{color:var(--p-text-muted-color)}.voice-clone-status .model-tag{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;background:var(--p-surface-100, #f3f4f6);border-radius:6px;font-size:.9rem}.voice-clone-status .model-tag code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.8rem}\n"] }]
8013
8559
  }], propDecorators: { onSave: [{ type: i0.Output, args: ["onSave"] }] } });
8014
8560
 
8015
8561
  class TruncatePipe {
@@ -8069,11 +8615,11 @@ class AgentCardUI {
8069
8615
  if (this.card()?.characterCard?.data?.langTranslation?.[baseLang]) {
8070
8616
  const cardTranslation = this.card()?.characterCard?.data?.langTranslation[baseLang];
8071
8617
  console.log(cardTranslation);
8072
- description = cardTranslation?.hook || this.card()?.description || this.card()?.characterCard?.data?.creator_notes || '';
8618
+ description = cardTranslation?.hook || cardTranslation?.instructions || this.card()?.description || this.card()?.characterCard?.data?.creator_notes || '';
8073
8619
  this.name.set(this.card()?.characterCard?.data?.name);
8074
8620
  }
8075
8621
  else {
8076
- description = this.card()?.characterCard?.data?.hook || this.card()?.characterCard?.data?.creator_notes || this.card()?.description || '';
8622
+ description = this.card()?.characterCard?.data?.hook || this.card()?.characterCard?.data?.instructions || this.card()?.characterCard?.data?.creator_notes || this.card()?.description || '';
8077
8623
  this.name.set(this.card()?.name);
8078
8624
  }
8079
8625
  description = description?.replace(/{{char}}/g, this.card()?.name).replace(/{{user}}/g, this.userService.userName());
@@ -8091,7 +8637,7 @@ class AgentCardUI {
8091
8637
  }
8092
8638
  }
8093
8639
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentCardUI, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8094
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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(this.userService.isAdmin()) {\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 || '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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8640
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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(this.userService.isAdmin()) {\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 || '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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$3.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8095
8641
  }
8096
8642
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentCardUI, decorators: [{
8097
8643
  type: Component,
@@ -8123,6 +8669,7 @@ class AgentCardListComponent extends EntityBaseListV2Component {
8123
8669
  this.columns = DefaultColumns;
8124
8670
  this.customFilters = [];
8125
8671
  this.mongoState.options.sort = { _id: -1 };
8672
+ const baseLang = this.userService.getBaseLanguage?.() || 'en';
8126
8673
  this.mongoState.projection = {
8127
8674
  _id: 1,
8128
8675
  name: 1,
@@ -8131,6 +8678,7 @@ class AgentCardListComponent extends EntityBaseListV2Component {
8131
8678
  'characterCard.data.name': 1,
8132
8679
  'characterCard.data.creator_notes': 1,
8133
8680
  'characterCard.data.hook': 1,
8681
+ [`characterCard.data.langTranslation.${baseLang}.hook`]: 1,
8134
8682
  manageable: 1,
8135
8683
  };
8136
8684
  this.agentCardsMasterStateService.getUserState();
@@ -8220,7 +8768,7 @@ class AgentCardListComponent extends EntityBaseListV2Component {
8220
8768
  }
8221
8769
  }
8222
8770
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentCardListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8223
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: false, isRequired: false, transformFunction: null }, persistenceKey: { classPropertyName: "persistenceKey", publicName: "persistenceKey", isSignal: false, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, customGetButtons: { classPropertyName: "customGetButtons", publicName: "customGetButtons", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<dc-filter-bar\n [isAdmin]=\"userService.isAdmin()\"\n [options]=\"filterBarOptions\"\n [customFilters]=\"customFilters\"\n [persistenceKey]=\"persistenceKey\"\n (onFilterAction)=\"doAction($event)\"\n (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n} @else {\n\n<div class=\"conversation-card-lists\">\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @if(!isLoading()) { @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"card\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n } @if(items().length === 0 && !isLoading()) {\n <div>\n <dc-empty-state\n headingText=\"No hay conversaciones para este idioma\"\n subHeadingText=\"Estamos trabajando en ello...\"\n mainIconSrcString=\"/img/empty-states/empty-box.png\">\n </dc-empty-state>\n </div>\n } } @else { @for (i of [1,2,3,4,5,6]; track i) {\n <p-card class=\"card-image skeleton-card\">\n <div class=\"content\">\n <p-skeleton width=\"80%\" height=\"1.5rem\" styleClass=\"mb-4\" />\n <div style=\"margin-top: 40px\">\n <p-skeleton width=\"100%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"90%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"60%\" height=\"1rem\" />\n </div>\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-skeleton shape=\"circle\" size=\"2rem\" />\n </div>\n <p-skeleton\n shape=\"circle\"\n size=\"3rem\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\" />\n </div>\n </p-card>\n } }\n </div>\n</div>\n}\n\n\n<!-- Mobile Paginator -->\n<p-paginator\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecordsSignal()\"\n (onPageChange)=\"onPageChange($event)\"\n [showCurrentPageReport]=\"true\"\n [showPageLinks]=\"false\"\n [showFirstLastIcon]=\"false\"\n [rowsPerPageOptions]=\"[10, 20, 30]\"\n currentPageReportTemplate=\" {first}- {last} de {totalRecords} \" />\n", styles: [":host{display:flex;flex-direction:column;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:.7rem 0 0;width:100%;flex:1;min-height:0;display:flex;flex-direction:column}@media(min-width:900px){.conversation-card-lists{padding:1.5rem}}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}::ng-deep p-paginator .p-paginator{padding:0!important;background:transparent!important}.skeleton-card ::ng-deep .p-card-body{padding:0!important;height:100%}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block}.card-image .content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0006,#0003);height:100%;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "component", type: AgentCardUI, selector: "dc-agent-card-ui", inputs: ["card", "showOptions"], outputs: ["onAction"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i4$3.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EmptyStateComponent, selector: "dc-empty-state", inputs: ["headingText", "subHeadingText", "mainIconSrcString"] }] }); }
8771
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: AgentCardListComponent, isStandalone: true, selector: "dc-agent-card-lists", inputs: { extraFilters: { classPropertyName: "extraFilters", publicName: "extraFilters", isSignal: false, isRequired: false, transformFunction: null }, persistenceKey: { classPropertyName: "persistenceKey", publicName: "persistenceKey", isSignal: false, isRequired: false, transformFunction: null }, showOptions: { classPropertyName: "showOptions", publicName: "showOptions", isSignal: true, isRequired: false, transformFunction: null }, gridLayout: { classPropertyName: "gridLayout", publicName: "gridLayout", isSignal: true, isRequired: false, transformFunction: null }, customGetButtons: { classPropertyName: "customGetButtons", publicName: "customGetButtons", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<dc-filter-bar\n [isAdmin]=\"userService.isAdmin()\"\n [options]=\"filterBarOptions\"\n [customFilters]=\"customFilters\"\n [persistenceKey]=\"persistenceKey\"\n (onFilterAction)=\"doAction($event)\"\n (onNew)=\"onNew()\"></dc-filter-bar>\n\n@if(viewType() === 'table'){\n<app-quick-table [columns]=\"columns\" [tableData]=\"items()\" [actions]=\"actions()\" (onAction)=\"handleTableAction($event)\"></app-quick-table>\n\n} @else {\n\n<div class=\"conversation-card-lists\">\n <div [ngClass]=\"{ 'cards-container': gridLayout() }\">\n @if(!isLoading()) { @for (card of items(); track card._id) {\n <dc-agent-card-ui [card]=\"card\" [showOptions]=\"showOptions()\" (onAction)=\"handleAction($event)\"></dc-agent-card-ui>\n } @if(items().length === 0 && !isLoading()) {\n <div>\n <dc-empty-state\n headingText=\"No hay conversaciones para este idioma\"\n subHeadingText=\"Estamos trabajando en ello...\"\n mainIconSrcString=\"/img/empty-states/empty-box.png\">\n </dc-empty-state>\n </div>\n } } @else { @for (i of [1,2,3,4,5,6]; track i) {\n <p-card class=\"card-image skeleton-card\">\n <div class=\"content\">\n <p-skeleton width=\"80%\" height=\"1.5rem\" styleClass=\"mb-4\" />\n <div style=\"margin-top: 40px\">\n <p-skeleton width=\"100%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"90%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"60%\" height=\"1rem\" />\n </div>\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-skeleton shape=\"circle\" size=\"2rem\" />\n </div>\n <p-skeleton\n shape=\"circle\"\n size=\"3rem\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\" />\n </div>\n </p-card>\n } }\n </div>\n</div>\n}\n\n\n<!-- Mobile Paginator -->\n<p-paginator\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecordsSignal()\"\n (onPageChange)=\"onPageChange($event)\"\n [showCurrentPageReport]=\"true\"\n [showPageLinks]=\"false\"\n [showFirstLastIcon]=\"false\"\n [rowsPerPageOptions]=\"[10, 20, 30]\"\n currentPageReportTemplate=\" {first}- {last} de {totalRecords} \" />\n", styles: [":host{display:flex;flex-direction:column;height:100%}.options-icon{cursor:pointer;position:absolute;top:2px;right:3px;font-size:1.2rem;color:#dde9e9;background-color:#4f486281;border-radius:50%;padding:5px;z-index:1000}.conversation-card-lists{padding:.7rem 0 0;width:100%;flex:1;min-height:0;display:flex;flex-direction:column}@media(min-width:900px){.conversation-card-lists{padding:1.5rem}}.conversation-card-lists .cards-container{display:flex;flex-wrap:wrap;gap:2rem;width:100%;justify-content:center;flex:1;overflow-y:auto;min-height:0}.conversation-card-lists .cards-container>div{flex:0 0 240px}.conversation-card-lists .dc-card{position:relative;background:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a;padding:.5rem;transition:transform .2s ease,box-shadow .2s ease;display:flex;flex-direction:column;gap:2px}.conversation-card-lists .dc-card:hover{transform:translateY(-2px);box-shadow:0 4px 8px #00000026}.conversation-card-lists .dc-card .dc-card-header{position:absolute;top:10px;left:5px;border-radius:5px;padding:5px}.conversation-card-lists .dc-card .dc-card-header:before{content:\"\";position:absolute;inset:0;background-color:#4d30db81;filter:blur(2px);border-radius:5px;z-index:0}.conversation-card-lists .dc-card .dc-card-header h3{margin:0;font-size:1.25rem;font-weight:600;color:#ece7e7;position:relative;z-index:1}.conversation-card-lists .dc-card .dc-card-content{flex:1}.conversation-card-lists .dc-card .dc-card-content p{margin:0;color:#666;line-height:1.5}.conversation-card-lists .dc-card button{padding:.5rem 1rem;border:none;border-radius:4px;background-color:#007bff;color:#fff;cursor:pointer;font-weight:500;transition:background-color .2s ease}.conversation-card-lists .dc-card button:hover{background-color:#0056b3}.conversation-card-lists .dc-card button:active{transform:translateY(1px)}::ng-deep p-paginator .p-paginator{padding:0!important;background:transparent!important}.skeleton-card ::ng-deep .p-card-body{padding:0!important;height:100%}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block}.card-image .content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0006,#0003);height:100%;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "component", type: AgentCardUI, selector: "dc-agent-card-ui", inputs: ["card", "showOptions"], outputs: ["onAction"] }, { kind: "ngmodule", type: PopoverModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: PaginatorModule }, { kind: "component", type: i4$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "ngmodule", type: TagModule }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i2$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: EmptyStateComponent, selector: "dc-empty-state", inputs: ["headingText", "subHeadingText", "mainIconSrcString"] }] }); }
8224
8772
  }
8225
8773
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: AgentCardListComponent, decorators: [{
8226
8774
  type: Component,
@@ -8326,6 +8874,16 @@ class DcAgentCardConverseComponent {
8326
8874
  console.warn('⚠️ Conversation settings not found ⚠️ probably is an old version of the card.');
8327
8875
  card.conversationSettings = {};
8328
8876
  }
8877
+ const baseLang = this.userService.getBaseLanguage();
8878
+ if (card.characterCard?.data?.langTranslation?.[baseLang]) {
8879
+ const translation = card.characterCard.data.langTranslation[baseLang];
8880
+ if (translation.instructions) {
8881
+ card.characterCard.data.instructions = translation.instructions;
8882
+ }
8883
+ if (translation.hook) {
8884
+ card.characterCard.data.hook = translation.hook;
8885
+ }
8886
+ }
8329
8887
  this.agentCard.set(card);
8330
8888
  if (card.assets.banner?.url) {
8331
8889
  this.chatMonitorService.setBackground(card.assets.banner.url);
@@ -8388,7 +8946,7 @@ class DcAgentCardConverseComponent {
8388
8946
  this.showInfoLayer.update((value) => !value);
8389
8947
  }
8390
8948
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcAgentCardConverseComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8391
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcAgentCardConverseComponent, isStandalone: true, selector: "dc-agent-card-converse", inputs: { agentCardId: "agentCardId", useNativePlayer: "useNativePlayer" }, outputs: { onStartConversation: "onStartConversation" }, viewQueries: [{ propertyName: "videoPlayerA", first: true, predicate: ["videoPlayerA"], descendants: true, isSignal: true }, { propertyName: "videoPlayerB", first: true, predicate: ["videoPlayerB"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #cardContent>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard()?.assets?.image?.url\" [style.opacity]=\"videoPlayerService.isVideoPlaying() ? 0 : 1\" style=\"transition: opacity 0.5s ease-in-out;\" alt=\"\" />\n <!-- Se implementa l\u00F3gica de doble video (ping-pong) para evitar parpadeos -->\n <video #videoPlayerA class=\"card-image\" style=\"position: absolute; top: 0; left: 0; transition: opacity 0.3s ease-in-out; opacity: 1; z-index: 1;\" playsinline></video>\n <video #videoPlayerB class=\"card-image\" style=\"position: absolute; top: 0; left: 0; transition: opacity 0.3s ease-in-out; opacity: 0; z-index: 2;\" playsinline></video>\n\n\n\n @if (!chatMonitorService.isConversationActive()) {\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\n size=\"large\"\n [label]=\"'dataclouder.agentCards.dcAgentCardDetails.startConversation' | translate\"\n [rounded]=\"true\"\n (click)=\"startConversation()\" />\n </div>\n }\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer()\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard()?.name || agentCard()?.characterCard?.data?.name }}</strong></h1\n >\n\n @if (agentCard()?.characterCard?.data?.instructions) {\n <div class=\"scenario\">\n <h4>{{ 'dataclouder.agentCards.dcAgentCardDetails.instructions' | translate }}</h4>\n <p>{{ agentCard()?.characterCard?.data?.instructions | parseCard: agentCard() }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n</ng-template>\n\n<div style=\"display: flex; justify-content: center; align-items: center\" [class.transparent-mode]=\"isTransparent()\">\n @if (isTransparent()) {\n <ng-container *ngTemplateOutlet=\"cardContent\"></ng-container>\n } @else {\n <p-card>\n <ng-container *ngTemplateOutlet=\"cardContent\"></ng-container>\n </p-card>\n }\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.transparent-mode .card-container{width:420px;height:700px;position:relative}.transparent-mode .card-image{background:transparent}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}::ng-deep .plyr--full-ui{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:var(--chat-user-message-bg);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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }, { kind: "pipe", type: i3$8.TranslatePipe, name: "translate" }] }); }
8949
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: DcAgentCardConverseComponent, isStandalone: true, selector: "dc-agent-card-converse", inputs: { agentCardId: "agentCardId", useNativePlayer: "useNativePlayer" }, outputs: { onStartConversation: "onStartConversation" }, viewQueries: [{ propertyName: "videoPlayerA", first: true, predicate: ["videoPlayerA"], descendants: true, isSignal: true }, { propertyName: "videoPlayerB", first: true, predicate: ["videoPlayerB"], descendants: true, isSignal: true }], ngImport: i0, template: "<ng-template #cardContent>\n <div class=\"card-container\">\n <img class=\"card-image\" [src]=\"agentCard()?.assets?.image?.url\" [style.opacity]=\"videoPlayerService.isVideoPlaying() ? 0 : 1\" style=\"transition: opacity 0.5s ease-in-out;\" alt=\"\" />\n <!-- Se implementa l\u00F3gica de doble video (ping-pong) para evitar parpadeos -->\n <video #videoPlayerA class=\"card-image\" style=\"position: absolute; top: 0; left: 0; transition: opacity 0.3s ease-in-out; opacity: 1; z-index: 1;\" playsinline></video>\n <video #videoPlayerB class=\"card-image\" style=\"position: absolute; top: 0; left: 0; transition: opacity 0.3s ease-in-out; opacity: 0; z-index: 2;\" playsinline></video>\n\n\n\n @if (!chatMonitorService.isConversationActive()) {\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\n size=\"large\"\n [label]=\"'dataclouder.agentCards.dcAgentCardDetails.startConversation' | translate\"\n [rounded]=\"true\"\n (click)=\"startConversation()\" />\n </div>\n }\n\n <div class=\"info-layer\" [class.active]=\"showInfoLayer()\">\n <div class=\"info-content\">\n <h1\n ><strong>{{ agentCard()?.name || agentCard()?.characterCard?.data?.name }}</strong></h1\n >\n\n @if (agentCard()?.characterCard?.data?.instructions) {\n <div class=\"scenario\">\n <h4>{{ 'dataclouder.agentCards.dcAgentCardDetails.instructions' | translate }}</h4>\n <p>{{ agentCard()?.characterCard?.data?.instructions | parseCard: agentCard() }}</p>\n </div>\n }\n </div>\n </div>\n </div>\n</ng-template>\n\n<div style=\"display: flex; justify-content: center; align-items: center\" [class.transparent-mode]=\"isTransparent()\">\n @if (isTransparent()) {\n <ng-container *ngTemplateOutlet=\"cardContent\"></ng-container>\n } @else {\n <p-card>\n <ng-container *ngTemplateOutlet=\"cardContent\"></ng-container>\n </p-card>\n }\n</div>\n", styles: ["::ng-deep .p-card{width:420px;height:700px}::ng-deep .p-card .p-card-body{width:100%;height:100%}.transparent-mode .card-container{width:420px;height:700px;position:relative}.transparent-mode .card-image{background:transparent}.card-image{height:100%;width:100%;object-fit:cover;object-position:center;position:absolute;top:0;left:0;transition:filter .3s ease}::ng-deep .plyr--full-ui{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:var(--chat-user-message-bg);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: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TranslateModule }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: ParseCardPipe, name: "parseCard" }, { kind: "pipe", type: i3$7.TranslatePipe, name: "translate" }] }); }
8392
8950
  }
8393
8951
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: DcAgentCardConverseComponent, decorators: [{
8394
8952
  type: Component,
@@ -8544,14 +9102,14 @@ class CardsCreatorComponent {
8544
9102
  this.notPublishedResults.set(res);
8545
9103
  }
8546
9104
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardsCreatorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8547
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\n <p-divider align=\"center\" styleClass=\"my-5\"> Busquedas pendientes </p-divider>\n\n <p-button label=\"Buscar No publicadas\" icon=\"pi pi-database\" (onClick)=\"searchNotPublic()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <p-button label=\"Buscar no publicadas (new)\" icon=\"pi pi-database\" (onClick)=\"searchNotpublished()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <br />\n\n <br />\n\n @if (notPublishedResults()) {\n <div class=\"mt-4\">\n <p-table [value]=\"notPublishedResults().rows\" [tableStyle]=\"{ 'min-width': '50rem' }\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>ID</th>\n <th>Name</th>\n <th>Language</th>\n <th>Status</th>\n <th>Character Name</th>\n <th>Actions</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td>{{ row?._id }}</td>\n <td>{{ row?.name }}</td>\n <td>{{ row?.lang }}</td>\n <td>{{ row?.manageable?.status }}</td>\n <td>{{ row?.characterCard?.data?.name }}</td>\n <td>\n <a [href]=\"'/app/conversations/edit/' + row._id\" target=\"_blank\">\n <p-button icon=\"pi pi-pencil\" styleClass=\"p-button-rounded p-button-text\"></p-button>\n </a>\n </td>\n </tr>\n </ng-template>\n </p-table>\n\n <br />\n <br />\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i1$3.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$4.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$1.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: TableModule }, { kind: "component", type: i1$5.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
9105
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", 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\n <p-divider align=\"center\" styleClass=\"my-5\"> Busquedas pendientes </p-divider>\n\n <p-button label=\"Buscar No publicadas\" icon=\"pi pi-database\" (onClick)=\"searchNotPublic()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <p-button label=\"Buscar no publicadas (new)\" icon=\"pi pi-database\" (onClick)=\"searchNotpublished()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <br />\n\n <br />\n\n @if (notPublishedResults()) {\n <div class=\"mt-4\">\n <p-table [value]=\"notPublishedResults().rows\" [tableStyle]=\"{ 'min-width': '50rem' }\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>ID</th>\n <th>Name</th>\n <th>Language</th>\n <th>Status</th>\n <th>Character Name</th>\n <th>Actions</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td>{{ row?._id }}</td>\n <td>{{ row?.name }}</td>\n <td>{{ row?.lang }}</td>\n <td>{{ row?.manageable?.status }}</td>\n <td>{{ row?.characterCard?.data?.name }}</td>\n <td>\n <a [href]=\"'/app/conversations/edit/' + row._id\" target=\"_blank\">\n <p-button icon=\"pi pi-pencil\" styleClass=\"p-button-rounded p-button-text\"></p-button>\n </a>\n </td>\n </tr>\n </ng-template>\n </p-table>\n\n <br />\n <br />\n </div>\n }\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: DividerModule }, { kind: "component", type: i2$4.Divider, selector: "p-divider", inputs: ["styleClass", "layout", "type", "align"] }, { kind: "ngmodule", type: MessageModule }, { kind: "component", type: i3$3.Message, selector: "p-message", inputs: ["severity", "text", "escape", "style", "styleClass", "closable", "icon", "closeIcon", "life", "showTransitionOptions", "hideTransitionOptions", "size", "variant", "motionOptions"], outputs: ["onClose"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i6.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", "motionOptions"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$2.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: TableModule }, { kind: "component", type: i1$4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "styleClass", "tableStyle", "tableStyleClass", "paginator", "pageLinks", "rowsPerPageOptions", "alwaysShowPaginator", "paginatorPosition", "paginatorStyleClass", "paginatorDropdownAppendTo", "paginatorDropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showJumpToPageDropdown", "showJumpToPageInput", "showFirstLastIcon", "showPageLinks", "defaultSortOrder", "sortMode", "resetPageOnSort", "selectionMode", "selectionPageOnly", "contextMenuSelection", "contextMenuSelectionMode", "dataKey", "metaKeySelection", "rowSelectable", "rowTrackBy", "lazy", "lazyLoadOnInit", "compareSelectionBy", "csvSeparator", "exportFilename", "filters", "globalFilterFields", "filterDelay", "filterLocale", "expandedRowKeys", "editingRowKeys", "rowExpandMode", "scrollable", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "selectAll"], outputs: ["contextMenuSelectionChange", "selectAllChange", "selectionChange", "onRowSelect", "onRowUnselect", "onPage", "onSort", "onFilter", "onLazyLoad", "onRowExpand", "onRowCollapse", "onContextMenuSelect", "onColResize", "onColReorder", "onRowReorder", "onEditInit", "onEditComplete", "onEditCancel", "onHeaderCheckboxToggle", "sortFunction", "firstChange", "rowsChange", "onStateSave", "onStateRestore"] }, { kind: "pipe", type: i2$1.JsonPipe, name: "json" }] }); }
8548
9106
  }
8549
9107
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardsCreatorComponent, decorators: [{
8550
9108
  type: Component,
8551
9109
  args: [{ selector: 'app-cards-creator', standalone: true, imports: [ReactiveFormsModule, CommonModule, ButtonModule, InputTextModule, DividerModule, MessageModule, SelectModule, ToggleSwitchModule, TableModule], 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\n <p-divider align=\"center\" styleClass=\"my-5\"> Busquedas pendientes </p-divider>\n\n <p-button label=\"Buscar No publicadas\" icon=\"pi pi-database\" (onClick)=\"searchNotPublic()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <p-button label=\"Buscar no publicadas (new)\" icon=\"pi pi-database\" (onClick)=\"searchNotpublished()\" [loading]=\"loading()\" severity=\"secondary\"></p-button>\n <br />\n\n <br />\n\n @if (notPublishedResults()) {\n <div class=\"mt-4\">\n <p-table [value]=\"notPublishedResults().rows\" [tableStyle]=\"{ 'min-width': '50rem' }\">\n <ng-template pTemplate=\"header\">\n <tr>\n <th>ID</th>\n <th>Name</th>\n <th>Language</th>\n <th>Status</th>\n <th>Character Name</th>\n <th>Actions</th>\n </tr>\n </ng-template>\n <ng-template pTemplate=\"body\" let-row>\n <tr>\n <td>{{ row?._id }}</td>\n <td>{{ row?.name }}</td>\n <td>{{ row?.lang }}</td>\n <td>{{ row?.manageable?.status }}</td>\n <td>{{ row?.characterCard?.data?.name }}</td>\n <td>\n <a [href]=\"'/app/conversations/edit/' + row._id\" target=\"_blank\">\n <p-button icon=\"pi pi-pencil\" styleClass=\"p-button-rounded p-button-text\"></p-button>\n </a>\n </td>\n </tr>\n </ng-template>\n </p-table>\n\n <br />\n <br />\n </div>\n }\n</div>\n" }]
8552
9110
  }], ctorParameters: () => [] });
8553
9111
 
8554
- class ConversationRuleListComponent extends EntityBaseListComponent {
9112
+ class ConversationRuleListComponent extends EntityBaseListV2Component {
8555
9113
  constructor() {
8556
9114
  super(...arguments);
8557
9115
  this.entityCommunicationService = inject(ConversationRuleService);
@@ -8577,7 +9135,7 @@ class ConversationRuleListComponent extends EntityBaseListComponent {
8577
9135
  ];
8578
9136
  }
8579
9137
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRuleListComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8580
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationRuleListComponent, isStandalone: true, selector: "app-conversationRule-list", usesInheritance: true, ngImport: i0, template: "@if (!onlyView()) {\n<p-button [icon]=\"viewType() === 'card' ? 'pi pi-table' : 'pi pi-list'\" label=\"Change View\" [link]=\"true\" (click)=\"toggleView()\" />\n}\n<div class=\"conversationRule-list-container\">\n <dc-filter-bar [isAdmin]=\"userService.isAdmin()\" [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType() === 'card') {\n <div class=\"conversationRule-list-content\">\n @for (conversationRule of items(); track conversationRule.id) {\n <div class=\"card-source\">\n <div style=\"position: absolute; top: 4px; right: 4px; z-index: 1000\">\n <p-speeddial\n [model]=\"getCustomButtons(conversationRule)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card [header]=\"conversationRule.name\">\n <p class=\"m-0\">{{ conversationRule.description | slice : 0 : 250 }}...</p>\n <span>{{ conversationRule?.auditable?.updatedAt | date : 'dd/MM/yyyy HH:mm' }}</span>\n </p-card>\n </div>\n } @if (items().length === 0) {\n <p-card>\n <p>No conversationRules found</p>\n </p-card>\n }\n </div>\n } @else if ( viewType() === 'table'){\n\n <app-quick-table [tableData]=\"items()\"></app-quick-table>\n\n }\n\n <div class=\"paginator-container\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords() }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecords()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.conversationRule-list-container{display:flex;flex-direction:column;height:100%}.conversationRule-list-content{margin-top:10px;flex:1;overflow-y:auto;padding-bottom:10px}.card-source{margin-bottom:10px;position:relative}.paginator-container{margin-top:auto;padding-top:10px}\n"], dependencies: [{ kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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: PaginatorModule }, { kind: "component", type: i4$3.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9138
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationRuleListComponent, isStandalone: true, selector: "app-conversationRule-list", usesInheritance: true, ngImport: i0, template: "@if (!onlyView()) {\n<p-button [icon]=\"viewType() === 'card' ? 'pi pi-table' : 'pi pi-list'\" label=\"Change View\" [link]=\"true\" (click)=\"toggleView()\" />\n}\n<div class=\"conversationRule-list-container\">\n <dc-filter-bar [isAdmin]=\"userService.isAdmin()\" [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType() === 'card') {\n <div class=\"conversationRule-list-content\">\n @for (conversationRule of items(); track conversationRule.id) {\n <div class=\"card-source\">\n <div style=\"position: absolute; top: 4px; right: 4px; z-index: 1000\">\n <p-speeddial\n [model]=\"getCustomButtons(conversationRule)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card [header]=\"conversationRule.name\">\n <p class=\"m-0\">{{ conversationRule.description | slice : 0 : 250 }}...</p>\n <span>{{ conversationRule?.auditable?.updatedAt | date : 'dd/MM/yyyy HH:mm' }}</span>\n </p-card>\n </div>\n } @if (items().length === 0) {\n <p-card>\n <p>No conversationRules found</p>\n </p-card>\n }\n </div>\n } @else if ( viewType() === 'table'){\n\n <app-quick-table [tableData]=\"items()\"></app-quick-table>\n\n }\n\n <div class=\"paginator-container\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords() }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecords()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [":host{display:block;height:100%}.conversationRule-list-container{display:flex;flex-direction:column;height:100%}.conversationRule-list-content{margin-top:10px;flex:1;overflow-y:auto;padding-bottom:10px}.card-source{margin-bottom:10px;position:relative}.paginator-container{margin-top:auto;padding-top:10px}\n"], dependencies: [{ kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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: PaginatorModule }, { kind: "component", type: i4$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: SlicePipe, name: "slice" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8581
9139
  }
8582
9140
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRuleListComponent, decorators: [{
8583
9141
  type: Component,
@@ -8658,7 +9216,7 @@ class ConversationRuleFormComponent extends EntityBaseSignalFormComponent {
8658
9216
  this.relationPopupSelector.push(relation);
8659
9217
  }
8660
9218
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRuleFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8661
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationRuleFormComponent, isStandalone: true, selector: "app-conversation-rule-form", usesInheritance: true, ngImport: i0, template: "<h3>ConversationRules Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"entityId() ? 'Edit Conversation Rule' : 'New Conversation Rule'\">\n <div style=\"display: flex; gap: 10px\">\n <div style=\"width: 100%\">\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Name</label>\n <input pInputText id=\"name\" type=\"text\"\n [formField]=\"form.name\"\n placeholder=\"Enter rule name\" />\n @if (form.name().touched() && form.name().invalid()) {\n <small class=\"p-error\">{{ form.name().errors()[0].message }}</small>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\" class=\"block\">Description</label>\n <textarea id=\"description\" pTextarea rows=\"1\" class=\"w-full\"\n [ngModel]=\"entityForm().description\"\n (ngModelChange)=\"entityForm.update(m => ({ ...m, description: $event }))\"\n placeholder=\"Enter description\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"rule\" class=\"block\">Rule</label>\n <textarea id=\"rule\" pTextarea rows=\"3\" class=\"w-full\"\n [ngModel]=\"entityForm().rule\"\n (ngModelChange)=\"entityForm.update(m => ({ ...m, rule: $event }))\"\n placeholder=\"Enter rule content\"></textarea>\n </div>\n\n </div>\n </div>\n\n <div style=\"display: flex; justify-content: flex-end\">\n <p-button (click)=\"save()\" label=\"Save Rule\" [disabled]=\"!isValid()\" icon=\"pi pi-check\" iconPos=\"right\"></p-button>\n </div>\n\n <p-dialog header=\"Search for relation\" [(visible)]=\"isDialogVisible\" [modal]=\"true\" [style]=\"{ width: '50vw' }\" draggable=\"false\">\n <app-conversationRule-list [onlyView]=\"true\" (onSelect)=\"handleRelationSelection($event)\"></app-conversationRule-list>\n </p-dialog>\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: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: "component", type: ConversationRuleListComponent, selector: "app-conversationRule-list" }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9219
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: ConversationRuleFormComponent, isStandalone: true, selector: "app-conversation-rule-form", usesInheritance: true, ngImport: i0, template: "<h3>ConversationRules Form</h3>\n\n<div class=\"source-form-card\">\n <p-card [header]=\"entityId() ? 'Edit Conversation Rule' : 'New Conversation Rule'\">\n <div style=\"display: flex; gap: 10px\">\n <div style=\"width: 100%\">\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Name</label>\n <input pInputText id=\"name\" type=\"text\"\n [formField]=\"form.name\"\n placeholder=\"Enter rule name\" />\n @if (form.name().touched() && form.name().invalid()) {\n <small class=\"p-error\">{{ form.name().errors()[0].message }}</small>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"description\" class=\"block\">Description</label>\n <textarea id=\"description\" pTextarea rows=\"1\" class=\"w-full\"\n [ngModel]=\"entityForm().description\"\n (ngModelChange)=\"entityForm.update(m => ({ ...m, description: $event }))\"\n placeholder=\"Enter description\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"rule\" class=\"block\">Rule</label>\n <textarea id=\"rule\" pTextarea rows=\"3\" class=\"w-full\"\n [ngModel]=\"entityForm().rule\"\n (ngModelChange)=\"entityForm.update(m => ({ ...m, rule: $event }))\"\n placeholder=\"Enter rule content\"></textarea>\n </div>\n\n </div>\n </div>\n\n <div style=\"display: flex; justify-content: flex-end\">\n <p-button (click)=\"save()\" label=\"Save Rule\" [disabled]=\"!isValid()\" icon=\"pi pi-check\" iconPos=\"right\"></p-button>\n </div>\n\n <p-dialog header=\"Search for relation\" [(visible)]=\"isDialogVisible\" [modal]=\"true\" [style]=\"{ width: '50vw' }\" draggable=\"false\">\n <app-conversationRule-list [onlyView]=\"true\" (onSelect)=\"handleRelationSelection($event)\"></app-conversationRule-list>\n </p-dialog>\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: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: "component", type: ConversationRuleListComponent, selector: "app-conversationRule-list" }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8662
9220
  }
8663
9221
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRuleFormComponent, decorators: [{
8664
9222
  type: Component,
@@ -8705,7 +9263,7 @@ const GENERICS_ROUTES = [
8705
9263
  class ConversationRulesComponent {
8706
9264
  static { this.routes = GENERICS_ROUTES; }
8707
9265
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRulesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8708
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: ConversationRulesComponent, isStandalone: true, selector: "app-conversationRules", ngImport: i0, template: "<router-outlet />\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$7.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9266
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: ConversationRulesComponent, isStandalone: true, selector: "app-conversationRules", ngImport: i0, template: "<router-outlet />\n", styles: [":host{display:block;height:100%}\n"], dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$5.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8709
9267
  }
8710
9268
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: ConversationRulesComponent, decorators: [{
8711
9269
  type: Component,
@@ -8748,7 +9306,7 @@ class CardRouteListComponent extends EntityBaseListV2Component {
8748
9306
  ];
8749
9307
  }
8750
9308
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8751
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteListComponent, isStandalone: true, selector: "app-card-route-list", host: { classAttribute: "block h-full" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col h-full\">\n <dc-filter-bar [isAdmin]=\"userService.isAdmin()\" [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType() === 'card') {\n <div class=\"mt-2.5 flex-1 overflow-y-auto pb-2.5\">\n @if (!isLoading()) { @for (generic of items(); track generic.id) {\n <div class=\"mb-2.5 relative\">\n <div class=\"absolute top-1 right-1 z-[1000]\">\n <p-speeddial\n [model]=\"getCustomButtons(generic)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card (click)=\"doAction({item: generic, action: 'view'})\" class=\"cursor-pointer\">\n <div class=\"flex gap-4\">\n <div class=\"w-24 h-24 flex-shrink-0 overflow-hidden rounded-lg bg-slate-100 border border-slate-200\">\n @if (generic.assets?.image?.url) {\n <img [src]=\"generic.assets.image.url\" class=\"w-full h-full object-cover\" alt=\"Card Route Image\" />\n } @else {\n <div class=\"w-full h-full flex items-center justify-center text-slate-300\">\n <i class=\"pi pi-image text-3xl\"></i>\n </div>\n }\n </div>\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex justify-between items-start mb-1\">\n <h3 class=\"m-0 text-lg font-bold text-slate-800 truncate\">{{ generic.name }}</h3>\n </div>\n <p class=\"m-0 text-sm text-slate-500 line-clamp-2 leading-relaxed mb-2\">\n {{ generic.description || 'Sin descripci\u00F3n' }}\n </p>\n <div class=\"flex items-center gap-3\">\n <span class=\"text-[10px] uppercase tracking-wider font-semibold px-2 py-0.5 rounded-full\" \n [class]=\"generic.isActive ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-500'\">\n {{ generic.isActive ? 'Activo' : 'Inactivo' }}\n </span>\n <span class=\"text-xs text-slate-400\">\n <i class=\"pi pi-calendar text-[10px] mr-1\"></i>\n {{ generic?.auditable?.updatedAt | date : 'dd/MM/yyyy HH:mm' }}\n </span>\n </div>\n </div>\n </div>\n </p-card>\n </div>\n } @if (items().length === 0) {\n <p-card>\n <p>No generics found</p>\n </p-card>\n } } @else { @for (i of [1,2,3,4,5,6]; track i) {\n <p-card>\n <ng-template pTemplate=\"header\">\n <div class=\"p-4\">\n <p-skeleton width=\"80%\" height=\"1.5rem\" />\n </div>\n </ng-template>\n <div class=\"flex gap-2.5\">\n <p-skeleton width=\"120px\" height=\"120px\" />\n <div class=\"flex-1\">\n <p-skeleton width=\"100%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"90%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"60%\" height=\"1rem\" />\n </div>\n </div>\n <p-skeleton width=\"40%\" height=\"1rem\" styleClass=\"mt-2\" />\n </p-card>\n } }\n </div>\n } @else if ( viewType() === 'table'){\n\n <app-quick-table [tableData]=\"items()\"></app-quick-table>\n\n }\n\n <div class=\"mt-auto pt-2.5\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords() }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecords()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i2$4.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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: PaginatorModule }, { kind: "component", type: i4$3.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9309
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteListComponent, isStandalone: true, selector: "app-card-route-list", host: { classAttribute: "block h-full" }, usesInheritance: true, ngImport: i0, template: "<div class=\"flex flex-col h-full\">\n <dc-filter-bar [isAdmin]=\"userService.isAdmin()\" [options]=\"filterBarOptions\" (onNew)=\"onNew()\" (onFilterAction)=\"doAction($event)\"></dc-filter-bar>\n\n @if (viewType() === 'card') {\n <div class=\"mt-2.5 flex-1 overflow-y-auto pb-2.5\">\n @if (!isLoading()) { @for (generic of items(); track generic.id) {\n <div class=\"mb-2.5 relative\">\n <div class=\"absolute top-1 right-1 z-[1000]\">\n <p-speeddial\n [model]=\"getCustomButtons(generic)\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true }\" />\n </div>\n <p-card (click)=\"doAction({item: generic, action: 'view'})\" class=\"cursor-pointer\">\n <div class=\"flex gap-4\">\n <div class=\"w-24 h-24 flex-shrink-0 overflow-hidden rounded-lg bg-slate-100 border border-slate-200\">\n @if (generic.assets?.image?.url) {\n <img [src]=\"generic.assets.image.url\" class=\"w-full h-full object-cover\" alt=\"Card Route Image\" />\n } @else {\n <div class=\"w-full h-full flex items-center justify-center text-slate-300\">\n <i class=\"pi pi-image text-3xl\"></i>\n </div>\n }\n </div>\n <div class=\"flex-1 min-w-0\">\n <div class=\"flex justify-between items-start mb-1\">\n <h3 class=\"m-0 text-lg font-bold text-slate-800 truncate\">{{ generic.name }}</h3>\n </div>\n <p class=\"m-0 text-sm text-slate-500 line-clamp-2 leading-relaxed mb-2\">\n {{ generic.description || 'Sin descripci\u00F3n' }}\n </p>\n <div class=\"flex items-center gap-3\">\n <span class=\"text-[10px] uppercase tracking-wider font-semibold px-2 py-0.5 rounded-full\" \n [class]=\"generic.isActive ? 'bg-green-100 text-green-700' : 'bg-slate-100 text-slate-500'\">\n {{ generic.isActive ? 'Activo' : 'Inactivo' }}\n </span>\n <span class=\"text-xs text-slate-400\">\n <i class=\"pi pi-calendar text-[10px] mr-1\"></i>\n {{ generic?.auditable?.updatedAt | date : 'dd/MM/yyyy HH:mm' }}\n </span>\n </div>\n </div>\n </div>\n </p-card>\n </div>\n } @if (items().length === 0) {\n <p-card>\n <p>No generics found</p>\n </p-card>\n } } @else { @for (i of [1,2,3,4,5,6]; track i) {\n <p-card>\n <ng-template pTemplate=\"header\">\n <div class=\"p-4\">\n <p-skeleton width=\"80%\" height=\"1.5rem\" />\n </div>\n </ng-template>\n <div class=\"flex gap-2.5\">\n <p-skeleton width=\"120px\" height=\"120px\" />\n <div class=\"flex-1\">\n <p-skeleton width=\"100%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"90%\" height=\"1rem\" styleClass=\"mb-2\" />\n <p-skeleton width=\"60%\" height=\"1rem\" />\n </div>\n </div>\n <p-skeleton width=\"40%\" height=\"1rem\" styleClass=\"mt-2\" />\n </p-card>\n } }\n </div>\n } @else if ( viewType() === 'table'){\n\n <app-quick-table [tableData]=\"items()\"></app-quick-table>\n\n }\n\n <div class=\"mt-auto pt-2.5\">\n <p-paginator\n currentPageReportTemplate=\"{{ totalRecords() }} conversations\"\n [showCurrentPageReport]=\"true\"\n (onPageChange)=\"onPageChange($event)\"\n [first]=\"first()\"\n [rows]=\"rows()\"\n [totalRecords]=\"totalRecords()\"\n [rowsPerPageOptions]=\"[10, 20, 30]\">\n </p-paginator>\n </div>\n</div>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "directive", type: i2$5.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: DCFilterBarComponent, selector: "dc-filter-bar", inputs: ["items", "options", "customFilters", "customSortOptions", "isAdmin", "persistenceKey"], outputs: ["onFilterAction", "onNew"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i3$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: PaginatorModule }, { kind: "component", type: i4$4.Paginator, selector: "p-paginator", inputs: ["pageLinkSize", "styleClass", "alwaysShow", "dropdownAppendTo", "templateLeft", "templateRight", "dropdownScrollHeight", "currentPageReportTemplate", "showCurrentPageReport", "showFirstLastIcon", "totalRecords", "rows", "rowsPerPageOptions", "showJumpToPageDropdown", "showJumpToPageInput", "jumpToPageItemTemplate", "showPageLinks", "locale", "dropdownItemTemplate", "first", "appendTo"], outputs: ["onPageChange"] }, { kind: "ngmodule", type: RouterModule }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: QuickTableComponent, selector: "app-quick-table", inputs: ["columns", "tableData", "actions"], outputs: ["onAction"] }, { kind: "component", type: Skeleton, selector: "p-skeleton", inputs: ["styleClass", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8752
9310
  }
8753
9311
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteListComponent, decorators: [{
8754
9312
  type: Component,
@@ -8765,7 +9323,7 @@ class CardRouteDetailComponent extends EntityBaseDetailComponent {
8765
9323
  this.route = inject(ActivatedRoute);
8766
9324
  }
8767
9325
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteDetailComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8768
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteDetailComponent, isStandalone: true, selector: "app-card-route-detail", usesInheritance: true, ngImport: i0, template: "@if (isLoading()) {\n <div class=\"loading-wrapper\">\n <p-progressSpinner strokeWidth=\"3\" />\n </div>\n}\n\n@if (entity(); as cardRoute) {\n <div class=\"route-detail\">\n\n <!-- Header -->\n <div class=\"route-header\">\n <div class=\"header-content\">\n @if (cardRoute.assets?.image?.url) {\n <div class=\"route-image-wrapper\">\n <img [src]=\"cardRoute.assets.image.url\" [alt]=\"cardRoute.name\" class=\"route-image\" />\n </div>\n }\n <div class=\"header-text\">\n <div class=\"header-title-row\">\n <h1 class=\"route-title\">{{ cardRoute.name }}</h1>\n <p-tag\n [value]=\"cardRoute.isActive ? 'Active' : 'Inactive'\"\n [severity]=\"cardRoute.isActive ? 'success' : 'danger'\"\n />\n </div>\n @if (cardRoute.description) {\n <p class=\"route-description\">{{ cardRoute.description }}</p>\n }\n @if (cardRoute.tags?.length) {\n <div class=\"tags-row\">\n @for (tag of cardRoute.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n\n </div>\n </div>\n\n <!-- Steps Timeline -->\n <div class=\"steps-section\">\n <div class=\"steps-header\">\n <h2 class=\"steps-title\">\n <i class=\"pi pi-list-check\"></i>\n Learning Path\n </h2>\n <span class=\"steps-count\">{{ cardRoute.steps?.length ?? 0 }} steps</span>\n </div>\n\n @if (cardRoute.steps?.length) {\n <div class=\"steps-timeline\">\n @for (step of cardRoute.steps; track step.order; let i = $index; let last = $last) {\n <div class=\"step-row\" [class.step-row--right]=\"i % 2 === 1\">\n\n <!-- Left side -->\n <div class=\"step-side step-side--left\">\n @if (i % 2 === 0) {\n <div class=\"step-content\">\n <div class=\"step-avatar-wrapper\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" [alt]=\"step.agentCard.name\" class=\"step-avatar\" />\n } @else {\n <div class=\"step-avatar step-avatar-placeholder\"><i class=\"pi pi-robot\"></i></div>\n }\n <span class=\"step-avatar-name\">{{ step.name ?? step.agentCard.name }}</span>\n </div>\n <div class=\"step-label\">\n @if (step.passCondition) {\n <span class=\"pass-condition\"><i class=\"pi pi-check-circle\"></i> {{ step.passCondition.type }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Center line + badge -->\n <div class=\"step-center\">\n @if (!last) { <div class=\"center-line center-line--top\"></div> }\n <div class=\"step-order-badge\">{{ step.order }}</div>\n @if (!last) { <div class=\"center-line center-line--bottom\"></div> }\n </div>\n\n <!-- Right side -->\n <div class=\"step-side step-side--right\">\n @if (i % 2 === 1) {\n <div class=\"step-content\">\n <div class=\"step-avatar-wrapper\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" [alt]=\"step.agentCard.name\" class=\"step-avatar\" />\n } @else {\n <div class=\"step-avatar step-avatar-placeholder\"><i class=\"pi pi-robot\"></i></div>\n }\n <span class=\"step-avatar-name\">{{ step.name ?? step.agentCard.name }}</span>\n </div>\n <div class=\"step-label\">\n @if (step.passCondition) {\n <span class=\"pass-condition\"><i class=\"pi pi-check-circle\"></i> {{ step.passCondition.type }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-steps\">\n <i class=\"pi pi-inbox\"></i>\n <p>No steps defined yet.</p>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"route-footer\">\n <small>\n <i class=\"pi pi-clock\"></i>\n Updated: {{ cardRoute.auditable?.updatedAt | date: 'dd/MM/yyyy HH:mm' }}\n </small>\n </div>\n\n </div>\n}\n", styles: [".loading-wrapper{display:flex;justify-content:center;padding:3rem}.route-detail{max-width:860px;margin:0 auto;padding:1.5rem;display:flex;flex-direction:column;gap:1.5rem}.route-header{background:var(--surface-card);border:1px solid var(--surface-border);border-radius:12px;padding:1.5rem}.route-image-wrapper{width:120px;height:120px;border-radius:12px;overflow:hidden;border:1px solid var(--surface-border);flex-shrink:0}.route-image{width:100%;height:100%;object-fit:cover}.header-content{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap}.header-text{flex:1;min-width:280px}.header-title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin-bottom:.5rem}.route-title{font-size:1.6rem;font-weight:700;margin:0;color:var(--text-color)}.route-description{color:var(--text-color-secondary);margin:0 0 .75rem;line-height:1.5}.tags-row{display:flex;gap:.4rem;flex-wrap:wrap}.header-actions{display:flex;gap:.5rem;flex-shrink:0}.steps-section{display:flex;flex-direction:column;gap:1rem}.steps-header{display:flex;align-items:center;justify-content:space-between}.steps-title{font-size:1.1rem;font-weight:600;margin:0;display:flex;align-items:center;gap:.5rem;color:var(--text-color)}.steps-count{font-size:.85rem;color:var(--text-color-secondary);background:var(--surface-ground);border:1px solid var(--surface-border);border-radius:999px;padding:.2rem .75rem}.steps-timeline{display:flex;flex-direction:column}.step-row{display:grid;grid-template-columns:1fr 48px 1fr;align-items:stretch;min-height:200px}.step-side{display:flex;align-items:center}.step-side--left{justify-content:flex-end;padding-right:1.5rem}.step-side--right{justify-content:flex-start;padding-left:1.5rem}.step-content{display:flex;flex-direction:column;align-items:center;gap:.6rem;max-width:180px;text-align:center}.step-avatar-wrapper{position:relative;width:160px;height:160px;flex-shrink:0}.step-avatar-name{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,#000000b8);color:#fff;font-size:.78rem;font-weight:600;text-align:center;padding:1rem .4rem .45rem;border-radius:0 0 50% 50%;line-height:1.2;pointer-events:none}.step-avatar{width:160px;height:160px;border-radius:50%;object-fit:cover;object-position:top;border:3px solid var(--primary-color);box-shadow:0 4px 16px #0000001f;flex-shrink:0}.step-avatar-placeholder{width:160px;height:160px;border-radius:50%;background:var(--surface-ground);border:3px solid var(--surface-border);display:flex;align-items:center;justify-content:center;color:var(--text-color-secondary);font-size:3rem;flex-shrink:0}.step-label{display:flex;flex-direction:column;align-items:center;gap:.25rem}.step-name{font-size:.95rem;font-weight:600;color:var(--text-color);line-height:1.3}.step-center{display:flex;flex-direction:column;align-items:center;justify-content:center}.center-line--top,.center-line--bottom{width:2px;flex:1;background:var(--surface-border)}.step-order-badge{width:2rem;height:2rem;border-radius:50%;background:var(--primary-color);color:var(--primary-color-text);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem;flex-shrink:0;z-index:1}.pass-condition{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--green-500)}.empty-steps{display:flex;flex-direction:column;align-items:center;padding:2.5rem;color:var(--text-color-secondary);gap:.5rem;background:var(--surface-ground);border-radius:10px;border:1px dashed var(--surface-border)}.empty-steps i{font-size:2rem}.route-footer{color:var(--text-color-secondary);display:flex;align-items:center;gap:.4rem;font-size:.8rem}.route-footer small{display:flex;align-items:center;gap:.35rem}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$4.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i3$3.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9326
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteDetailComponent, isStandalone: true, selector: "app-card-route-detail", usesInheritance: true, ngImport: i0, template: "@if (isLoading()) {\n <div class=\"loading-wrapper\">\n <p-progressSpinner strokeWidth=\"3\" />\n </div>\n}\n\n@if (entity(); as cardRoute) {\n <div class=\"route-detail\">\n\n <!-- Header -->\n <div class=\"route-header\">\n <div class=\"header-content\">\n @if (cardRoute.assets?.image?.url) {\n <div class=\"route-image-wrapper\">\n <img [src]=\"cardRoute.assets.image.url\" [alt]=\"cardRoute.name\" class=\"route-image\" />\n </div>\n }\n <div class=\"header-text\">\n <div class=\"header-title-row\">\n <h1 class=\"route-title\">{{ cardRoute.name }}</h1>\n <p-tag\n [value]=\"cardRoute.isActive ? 'Active' : 'Inactive'\"\n [severity]=\"cardRoute.isActive ? 'success' : 'danger'\"\n />\n </div>\n @if (cardRoute.description) {\n <p class=\"route-description\">{{ cardRoute.description }}</p>\n }\n @if (cardRoute.tags?.length) {\n <div class=\"tags-row\">\n @for (tag of cardRoute.tags; track tag) {\n <p-tag [value]=\"tag\" severity=\"secondary\" />\n }\n </div>\n }\n </div>\n\n </div>\n </div>\n\n <!-- Steps Timeline -->\n <div class=\"steps-section\">\n <div class=\"steps-header\">\n <h2 class=\"steps-title\">\n <i class=\"pi pi-list-check\"></i>\n Learning Path\n </h2>\n <span class=\"steps-count\">{{ cardRoute.steps?.length ?? 0 }} steps</span>\n </div>\n\n @if (cardRoute.steps?.length) {\n <div class=\"steps-timeline\">\n @for (step of cardRoute.steps; track step.order; let i = $index; let last = $last) {\n <div class=\"step-row\" [class.step-row--right]=\"i % 2 === 1\">\n\n <!-- Left side -->\n <div class=\"step-side step-side--left\">\n @if (i % 2 === 0) {\n <div class=\"step-content\">\n <div class=\"step-avatar-wrapper\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" [alt]=\"step.agentCard.name\" class=\"step-avatar\" />\n } @else {\n <div class=\"step-avatar step-avatar-placeholder\"><i class=\"pi pi-robot\"></i></div>\n }\n <span class=\"step-avatar-name\">{{ step.name ?? step.agentCard.name }}</span>\n </div>\n <div class=\"step-label\">\n @if (step.passCondition) {\n <span class=\"pass-condition\"><i class=\"pi pi-check-circle\"></i> {{ step.passCondition.type }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Center line + badge -->\n <div class=\"step-center\">\n @if (!last) { <div class=\"center-line center-line--top\"></div> }\n <div class=\"step-order-badge\">{{ step.order }}</div>\n @if (!last) { <div class=\"center-line center-line--bottom\"></div> }\n </div>\n\n <!-- Right side -->\n <div class=\"step-side step-side--right\">\n @if (i % 2 === 1) {\n <div class=\"step-content\">\n <div class=\"step-avatar-wrapper\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" [alt]=\"step.agentCard.name\" class=\"step-avatar\" />\n } @else {\n <div class=\"step-avatar step-avatar-placeholder\"><i class=\"pi pi-robot\"></i></div>\n }\n <span class=\"step-avatar-name\">{{ step.name ?? step.agentCard.name }}</span>\n </div>\n <div class=\"step-label\">\n @if (step.passCondition) {\n <span class=\"pass-condition\"><i class=\"pi pi-check-circle\"></i> {{ step.passCondition.type }}</span>\n }\n </div>\n </div>\n }\n </div>\n\n </div>\n }\n </div>\n } @else {\n <div class=\"empty-steps\">\n <i class=\"pi pi-inbox\"></i>\n <p>No steps defined yet.</p>\n </div>\n }\n </div>\n\n <!-- Footer -->\n <div class=\"route-footer\">\n <small>\n <i class=\"pi pi-clock\"></i>\n Updated: {{ cardRoute.auditable?.updatedAt | date: 'dd/MM/yyyy HH:mm' }}\n </small>\n </div>\n\n </div>\n}\n", styles: [".loading-wrapper{display:flex;justify-content:center;padding:3rem}.route-detail{max-width:860px;margin:0 auto;padding:1.5rem;display:flex;flex-direction:column;gap:1.5rem}.route-header{background:var(--surface-card);border:1px solid var(--surface-border);border-radius:12px;padding:1.5rem}.route-image-wrapper{width:120px;height:120px;border-radius:12px;overflow:hidden;border:1px solid var(--surface-border);flex-shrink:0}.route-image{width:100%;height:100%;object-fit:cover}.header-content{display:flex;justify-content:space-between;align-items:flex-start;gap:1rem;flex-wrap:wrap}.header-text{flex:1;min-width:280px}.header-title-row{display:flex;align-items:center;gap:.75rem;flex-wrap:wrap;margin-bottom:.5rem}.route-title{font-size:1.6rem;font-weight:700;margin:0;color:var(--text-color)}.route-description{color:var(--text-color-secondary);margin:0 0 .75rem;line-height:1.5}.tags-row{display:flex;gap:.4rem;flex-wrap:wrap}.header-actions{display:flex;gap:.5rem;flex-shrink:0}.steps-section{display:flex;flex-direction:column;gap:1rem}.steps-header{display:flex;align-items:center;justify-content:space-between}.steps-title{font-size:1.1rem;font-weight:600;margin:0;display:flex;align-items:center;gap:.5rem;color:var(--text-color)}.steps-count{font-size:.85rem;color:var(--text-color-secondary);background:var(--surface-ground);border:1px solid var(--surface-border);border-radius:999px;padding:.2rem .75rem}.steps-timeline{display:flex;flex-direction:column}.step-row{display:grid;grid-template-columns:1fr 48px 1fr;align-items:stretch;min-height:200px}.step-side{display:flex;align-items:center}.step-side--left{justify-content:flex-end;padding-right:1.5rem}.step-side--right{justify-content:flex-start;padding-left:1.5rem}.step-content{display:flex;flex-direction:column;align-items:center;gap:.6rem;max-width:180px;text-align:center}.step-avatar-wrapper{position:relative;width:160px;height:160px;flex-shrink:0}.step-avatar-name{position:absolute;bottom:0;left:0;right:0;background:linear-gradient(transparent,#000000b8);color:#fff;font-size:.78rem;font-weight:600;text-align:center;padding:1rem .4rem .45rem;border-radius:0 0 50% 50%;line-height:1.2;pointer-events:none}.step-avatar{width:160px;height:160px;border-radius:50%;object-fit:cover;object-position:top;border:3px solid var(--primary-color);box-shadow:0 4px 16px #0000001f;flex-shrink:0}.step-avatar-placeholder{width:160px;height:160px;border-radius:50%;background:var(--surface-ground);border:3px solid var(--surface-border);display:flex;align-items:center;justify-content:center;color:var(--text-color-secondary);font-size:3rem;flex-shrink:0}.step-label{display:flex;flex-direction:column;align-items:center;gap:.25rem}.step-name{font-size:.95rem;font-weight:600;color:var(--text-color);line-height:1.3}.step-center{display:flex;flex-direction:column;align-items:center;justify-content:center}.center-line--top,.center-line--bottom{width:2px;flex:1;background:var(--surface-border)}.step-order-badge{width:2rem;height:2rem;border-radius:50%;background:var(--primary-color);color:var(--primary-color-text);display:flex;align-items:center;justify-content:center;font-weight:700;font-size:.85rem;flex-shrink:0;z-index:1}.pass-condition{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--green-500)}.empty-steps{display:flex;flex-direction:column;align-items:center;padding:2.5rem;color:var(--text-color-secondary);gap:.5rem;background:var(--surface-ground);border-radius:10px;border:1px dashed var(--surface-border)}.empty-steps i{font-size:2rem}.route-footer{color:var(--text-color-secondary);display:flex;align-items:center;gap:.4rem;font-size:.8rem}.route-footer small{display:flex;align-items:center;gap:.35rem}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i1$3.Tag, selector: "p-tag", inputs: ["styleClass", "severity", "value", "icon", "rounded"] }, { kind: "ngmodule", type: ProgressSpinnerModule }, { kind: "component", type: i3$2.ProgressSpinner, selector: "p-progressSpinner, p-progress-spinner, p-progressspinner", inputs: ["styleClass", "strokeWidth", "fill", "animationDuration", "ariaLabel"] }, { kind: "pipe", type: DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8769
9327
  }
8770
9328
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteDetailComponent, decorators: [{
8771
9329
  type: Component,
@@ -8849,7 +9407,7 @@ class CardRouteStepsFormComponent {
8849
9407
  this.showCardSelector.set(false);
8850
9408
  }
8851
9409
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteStepsFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8852
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteStepsFormComponent, isStandalone: true, selector: "app-card-route-steps-form", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n <div class=\"flex justify-between items-center\">\n <h3 class=\"text-xl font-semibold m-0\">Route Steps</h3>\n <p-button label=\"Add Step\" icon=\"pi pi-plus\" size=\"small\" (onClick)=\"addStep()\"></p-button>\n </div>\n\n @if (value().length === 0) {\n <div class=\"text-gray-500 italic p-4 text-center border rounded\">\n No steps added yet. Click \"Add Step\" to begin.\n </div>\n }\n\n @for (step of value(); track step.order; let i = $index) {\n <p-card class=\"mb-3 shadow-none border\">\n <div class=\"flex justify-between items-center mb-3\">\n <h4 class=\"m-0 font-medium\">Step {{ i + 1 }}</h4>\n <div class=\"flex gap-2\">\n <p-button icon=\"pi pi-arrow-up\" severity=\"secondary\" [text]=\"true\" [rounded]=\"true\" [disabled]=\"i === 0\" (onClick)=\"moveStep(i, 'up')\"></p-button>\n <p-button icon=\"pi pi-arrow-down\" severity=\"secondary\" [text]=\"true\" [rounded]=\"true\" [disabled]=\"i === value().length - 1\" (onClick)=\"moveStep(i, 'down')\"></p-button>\n <p-button icon=\"pi pi-trash\" severity=\"danger\" [text]=\"true\" [rounded]=\"true\" (onClick)=\"removeStep(i)\"></p-button>\n </div>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4\">\n\n <!-- Card selector row -->\n <div class=\"flex flex-col gap-2\">\n <label>Agent Card *</label>\n <div class=\"flex items-center gap-3\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" class=\"w-12 h-12 rounded-full object-cover\" />\n }\n <div class=\"flex flex-col flex-1 min-w-0\">\n <span class=\"font-medium truncate\">{{ step.agentCard.name || 'No card selected' }}</span>\n <span class=\"text-xs text-gray-400 truncate\">{{ step.agentCard.id }}</span>\n </div>\n <p-button label=\"Select Card\" icon=\"pi pi-search\" size=\"small\" [outlined]=\"true\" (onClick)=\"openCardSelector(i)\"></p-button>\n </div>\n </div>\n\n <div>\n <button type=\"button\" class=\"text-xs text-blue-500 hover:text-blue-700 flex items-center gap-1\" (click)=\"toggleStepDetails(i)\">\n <i [class]=\"isStepExpanded(i) ? 'pi pi-chevron-up' : 'pi pi-chevron-down'\" class=\"text-xs\"></i>\n {{ isStepExpanded(i) ? 'Hide optional fields' : 'Add name & description' }}\n </button>\n </div>\n\n @if (isStepExpanded(i)) {\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"'name_' + i\">Name</label>\n <input pInputText [id]=\"'name_' + i\"\n [ngModel]=\"step.name\"\n (ngModelChange)=\"patchStep(i, { name: $event })\"\n placeholder=\"Step name (optional)\" />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"'description_' + i\">Description</label>\n <textarea pTextarea [id]=\"'description_' + i\" rows=\"2\"\n [ngModel]=\"step.description\"\n (ngModelChange)=\"patchStep(i, { description: $event })\"\n placeholder=\"Step description (optional)\"></textarea>\n </div>\n }\n </div>\n </p-card>\n }\n</div>\n\n<!-- Card Selector Dialog -->\n<p-dialog\n header=\"Select Agent Card\"\n [visible]=\"showCardSelector()\"\n (visibleChange)=\"showCardSelector.set($event)\"\n [modal]=\"true\"\n [style]=\"{ width: '85vw', maxWidth: '1100px' }\"\n [draggable]=\"false\"\n [resizable]=\"false\">\n\n <dc-agent-card-lists\n [onlyView]=\"true\"\n (onAction)=\"onCardSelected($event)\">\n </dc-agent-card-lists>\n\n</p-dialog>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: CommonModule }, { kind: "component", type: AgentCardListComponent, selector: "dc-agent-card-lists", inputs: ["extraFilters", "persistenceKey", "showOptions", "gridLayout", "customGetButtons"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9410
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteStepsFormComponent, isStandalone: true, selector: "app-card-route-steps-form", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div class=\"flex flex-col gap-4\">\n <div class=\"flex justify-between items-center\">\n <h3 class=\"text-xl font-semibold m-0\">Route Steps</h3>\n <p-button label=\"Add Step\" icon=\"pi pi-plus\" size=\"small\" (onClick)=\"addStep()\"></p-button>\n </div>\n\n @if (value().length === 0) {\n <div class=\"text-gray-500 italic p-4 text-center border rounded\">\n No steps added yet. Click \"Add Step\" to begin.\n </div>\n }\n\n @for (step of value(); track step.order; let i = $index) {\n <p-card class=\"mb-3 shadow-none border\">\n <div class=\"flex justify-between items-center mb-3\">\n <h4 class=\"m-0 font-medium\">Step {{ i + 1 }}</h4>\n <div class=\"flex gap-2\">\n <p-button icon=\"pi pi-arrow-up\" severity=\"secondary\" [text]=\"true\" [rounded]=\"true\" [disabled]=\"i === 0\" (onClick)=\"moveStep(i, 'up')\"></p-button>\n <p-button icon=\"pi pi-arrow-down\" severity=\"secondary\" [text]=\"true\" [rounded]=\"true\" [disabled]=\"i === value().length - 1\" (onClick)=\"moveStep(i, 'down')\"></p-button>\n <p-button icon=\"pi pi-trash\" severity=\"danger\" [text]=\"true\" [rounded]=\"true\" (onClick)=\"removeStep(i)\"></p-button>\n </div>\n </div>\n\n <div class=\"grid grid-cols-1 gap-4\">\n\n <!-- Card selector row -->\n <div class=\"flex flex-col gap-2\">\n <label>Agent Card *</label>\n <div class=\"flex items-center gap-3\">\n @if (step.agentCard.imageUrl) {\n <img [src]=\"step.agentCard.imageUrl\" class=\"w-12 h-12 rounded-full object-cover\" />\n }\n <div class=\"flex flex-col flex-1 min-w-0\">\n <span class=\"font-medium truncate\">{{ step.agentCard.name || 'No card selected' }}</span>\n <span class=\"text-xs text-gray-400 truncate\">{{ step.agentCard.id }}</span>\n </div>\n <p-button label=\"Select Card\" icon=\"pi pi-search\" size=\"small\" [outlined]=\"true\" (onClick)=\"openCardSelector(i)\"></p-button>\n </div>\n </div>\n\n <div>\n <button type=\"button\" class=\"text-xs text-blue-500 hover:text-blue-700 flex items-center gap-1\" (click)=\"toggleStepDetails(i)\">\n <i [class]=\"isStepExpanded(i) ? 'pi pi-chevron-up' : 'pi pi-chevron-down'\" class=\"text-xs\"></i>\n {{ isStepExpanded(i) ? 'Hide optional fields' : 'Add name & description' }}\n </button>\n </div>\n\n @if (isStepExpanded(i)) {\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"'name_' + i\">Name</label>\n <input pInputText [id]=\"'name_' + i\"\n [ngModel]=\"step.name\"\n (ngModelChange)=\"patchStep(i, { name: $event })\"\n placeholder=\"Step name (optional)\" />\n </div>\n\n <div class=\"flex flex-col gap-2\">\n <label [for]=\"'description_' + i\">Description</label>\n <textarea pTextarea [id]=\"'description_' + i\" rows=\"2\"\n [ngModel]=\"step.description\"\n (ngModelChange)=\"patchStep(i, { description: $event })\"\n placeholder=\"Step description (optional)\"></textarea>\n </div>\n }\n </div>\n </p-card>\n }\n</div>\n\n<!-- Card Selector Dialog -->\n<p-dialog\n header=\"Select Agent Card\"\n [visible]=\"showCardSelector()\"\n (visibleChange)=\"showCardSelector.set($event)\"\n [modal]=\"true\"\n [style]=\"{ width: '85vw', maxWidth: '1100px' }\"\n [draggable]=\"false\"\n [resizable]=\"false\">\n\n <dc-agent-card-lists\n [onlyView]=\"true\"\n (onAction)=\"onCardSelected($event)\">\n </dc-agent-card-lists>\n\n</p-dialog>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i5$1.Dialog, selector: "p-dialog", inputs: ["hostName", "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", "maskMotionOptions", "motionOptions", "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: CommonModule }, { kind: "component", type: AgentCardListComponent, selector: "dc-agent-card-lists", inputs: ["extraFilters", "persistenceKey", "showOptions", "gridLayout", "customGetButtons"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8853
9411
  }
8854
9412
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteStepsFormComponent, decorators: [{
8855
9413
  type: Component,
@@ -8897,7 +9455,7 @@ class CardRouteFormComponent extends EntityBaseSignalFormComponent {
8897
9455
  this.save();
8898
9456
  }
8899
9457
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteFormComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
8900
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteFormComponent, isStandalone: true, selector: "app-card-route-form", usesInheritance: true, ngImport: i0, template: "<p-card [header]=\"entityId() ? 'Edit Card Route' : 'New Card Route'\">\n <div class=\"flex gap-2.5\">\n <div class=\"mb-4\">\n <label class=\"block font-medium mb-1\" pTooltip=\"Upload image after first save\">Image</label>\n <img width=\"218px\" [src]=\"entityForm().assets?.image?.url || 'defaults/images/face-3.jpg'\" alt=\"route image\" />\n <dc-cropper-modal [imgStorageSettings]=\"storageImgSettings\" (imageUploaded)=\"handleImageUpload($event)\"></dc-cropper-modal>\n </div>\n\n <div class=\"w-full\">\n <div class=\"form-field\">\n <label for=\"name\">Name *</label>\n <input pInputText id=\"name\" type=\"text\"\n [formField]=\"form.name\"\n placeholder=\"Route name\" class=\"w-full\" />\n @if (form.name().touched() && form.name().invalid()) {\n <small class=\"p-error\">{{ form.name().errors()[0].message }}</small>\n }\n </div>\n\n <div class=\"form-field mt-4\">\n <label for=\"description\">Description</label>\n <textarea pTextarea id=\"description\" rows=\"2\"\n [ngModel]=\"entityForm().description\"\n (ngModelChange)=\"entityForm.set({ ...entityForm(), description: $event })\"\n placeholder=\"Route description\" autoResize class=\"w-full\"></textarea>\n </div>\n </div>\n </div>\n\n <div class=\"form-field-inline\">\n <label for=\"isActive\">Active</label>\n <p-toggleswitch id=\"isActive\"\n [ngModel]=\"entityForm().isActive\"\n (ngModelChange)=\"entityForm.set({ ...entityForm(), isActive: $event })\" />\n </div>\n\n <div class=\"form-field mt-4\">\n <app-card-route-steps-form\n [value]=\"entityForm().steps\"\n (valueChange)=\"entityForm.set({ ...entityForm(), steps: $event })\">\n </app-card-route-steps-form>\n </div>\n\n <div class=\"form-actions mt-4\">\n <p-button label=\"Save\" (click)=\"save()\" [disabled]=\"!isValid()\" />\n </div>\n</p-card>\n", styles: [".form-field{display:flex;flex-direction:column;gap:.25rem;margin-bottom:1rem}.form-field input,.form-field textarea{width:100%}.form-field-inline{display:flex;align-items:center;gap:.5rem;margin-bottom:1rem}.form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$6.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$5.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3$1.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$1.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "component", type: CardRouteStepsFormComponent, selector: "app-card-route-steps-form", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i3.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9458
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.5", type: CardRouteFormComponent, isStandalone: true, selector: "app-card-route-form", usesInheritance: true, ngImport: i0, template: "<p-card [header]=\"entityId() ? 'Edit Card Route' : 'New Card Route'\">\n <div class=\"flex gap-2.5\">\n <div class=\"mb-4\">\n <label class=\"block font-medium mb-1\" pTooltip=\"Upload image after first save\">Image</label>\n <img width=\"218px\" [src]=\"entityForm().assets?.image?.url || 'defaults/images/face-3.jpg'\" alt=\"route image\" />\n <dc-cropper-modal [imgStorageSettings]=\"storageImgSettings\" (imageUploaded)=\"handleImageUpload($event)\"></dc-cropper-modal>\n </div>\n\n <div class=\"w-full\">\n <div class=\"form-field\">\n <label for=\"name\">Name *</label>\n <input pInputText id=\"name\" type=\"text\"\n [formField]=\"form.name\"\n placeholder=\"Route name\" class=\"w-full\" />\n @if (form.name().touched() && form.name().invalid()) {\n <small class=\"p-error\">{{ form.name().errors()[0].message }}</small>\n }\n </div>\n\n <div class=\"form-field mt-4\">\n <label for=\"description\">Description</label>\n <textarea pTextarea id=\"description\" rows=\"2\"\n [ngModel]=\"entityForm().description\"\n (ngModelChange)=\"entityForm.set({ ...entityForm(), description: $event })\"\n placeholder=\"Route description\" autoResize class=\"w-full\"></textarea>\n </div>\n </div>\n </div>\n\n <div class=\"form-field-inline\">\n <label for=\"isActive\">Active</label>\n <p-toggleswitch id=\"isActive\"\n [ngModel]=\"entityForm().isActive\"\n (ngModelChange)=\"entityForm.set({ ...entityForm(), isActive: $event })\" />\n </div>\n\n <div class=\"form-field mt-4\">\n <app-card-route-steps-form\n [value]=\"entityForm().steps\"\n (valueChange)=\"entityForm.set({ ...entityForm(), steps: $event })\">\n </app-card-route-steps-form>\n </div>\n\n <div class=\"form-actions mt-4\">\n <p-button label=\"Save\" (click)=\"save()\" [disabled]=\"!isValid()\" />\n </div>\n</p-card>\n", styles: [".form-field{display:flex;flex-direction:column;gap:.25rem;margin-bottom:1rem}.form-field input,.form-field textarea{width:100%}.form-field-inline{display:flex;align-items:center;gap:.5rem;margin-bottom:1rem}.form-actions{display:flex;justify-content:flex-end;gap:.5rem;margin-top:1rem}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: FormField, selector: "[formField]", inputs: ["formField"], exportAs: ["formField"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$7.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$4.InputText, selector: "[pInputText]", inputs: ["hostName", "ptInputText", "pInputTextPT", "pInputTextUnstyled", "pSize", "variant", "fluid", "invalid"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["pTextareaPT", "pTextareaUnstyled", "autoResize", "pSize", "variant", "fluid", "invalid"], outputs: ["onResize"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i4$2.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["styleClass", "tabindex", "inputId", "readonly", "trueValue", "falseValue", "ariaLabel", "size", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "component", type: CardRouteStepsFormComponent, selector: "app-card-route-steps-form", inputs: ["value"], outputs: ["valueChange"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { 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", "showOnEllipsis", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip", "pTooltipPT", "pTooltipUnstyled"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8901
9459
  }
8902
9460
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRouteFormComponent, decorators: [{
8903
9461
  type: Component,
@@ -8931,7 +9489,7 @@ const CARD_ROUTES = [
8931
9489
  class CardRoutesComponent {
8932
9490
  static { this.routes = CARD_ROUTES; }
8933
9491
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRoutesComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
8934
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: CardRoutesComponent, isStandalone: true, selector: "app-card-routes", ngImport: i0, template: `<router-outlet />`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$7.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
9492
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.2.5", type: CardRoutesComponent, isStandalone: true, selector: "app-card-routes", ngImport: i0, template: `<router-outlet />`, isInline: true, dependencies: [{ kind: "ngmodule", type: RouterModule }, { kind: "directive", type: i1$5.RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
8935
9493
  }
8936
9494
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImport: i0, type: CardRoutesComponent, decorators: [{
8937
9495
  type: Component,
@@ -8995,5 +9553,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.5", ngImpor
8995
9553
  * Generated bundle index. Do not edit.
8996
9554
  */
8997
9555
 
8998
- export { ACCDataGenerationComponent, AGENT_CARDS_STATE_SERVICE, AIGenerationService, AgentCardListComponent, AgentCardUI, AgentCardsGenerationService, AudioService, AudioSpeed, BACKGROUND_SERVICE_TOKEN, CONVERSATION_AI_TOKEN, CardRouteService, CardRoutesComponent, CardsCreatorComponent, ChatEngineTestComponent, ChatEventType, ChatMessage, ChatMessageOrchestratorComponent, ChatMonitorService, ChatRole, ConditionOperator, ConditionType, ContextEngineService, ContextType, ConversationDTO, ConversationEvents, ConversationFlowStateService, ConversationMessagesDTO, ConversationPromptBuilderService, ConversationRuleService, ConversationRulesComponent, ConversationStatus, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationUserChatSettingsComponent, DcAgentCardConverseComponent, DcAgentCardDetailComponent, DefaultAgentCardsService, DoActionTypeOptions, DynamicFlowService, DynamicFlowTaskTypeOptions, EAccountsPlatform, EAgentType, EDoActionType, EDynamicFlowTaskType, EntityThen, EntityWhatOptions, EntityWhenOptions, EvalResultStringDefinition, GlobalToolsService, MessageContent, MessageContentDisplayer, MessagesStateService, ModelSelectorComponent, PopupService, PromptPreviewComponent, SectionType, SystemPromptType, TextEngineOptions, TextEngines, VIDEO_PLAYER_SERVICE_TOKEN, VideoPlayerNativeService, VideoPlayerService, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, XKillsAgentCardsService, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, createAIModelFormGroup, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, getMoodStateLabelsAsString, getMoodStatePrompt, markdownToHtml, matchTranscription, provideAgentCardService, removeEmojis, removeEmojisAndSpecialCharacters, removeSpecialCharacters };
9556
+ export { ACCDataGenerationComponent, AGENT_CARDS_STATE_SERVICE, AIGenerationService, AgentCardListComponent, AgentCardUI, AgentCardsGenerationService, AgenticEngine, AgenticPattern, AudioService, AudioSpeed, BACKGROUND_SERVICE_TOKEN, CONVERSATION_AI_TOKEN, CardRouteService, CardRoutesComponent, CardsCreatorComponent, ChatEngineTestComponent, ChatEventType, ChatMessage, ChatMessageOrchestratorComponent, ChatMonitorService, ChatRole, ConditionOperator, ConditionType, ContextEngineService, ContextType, ConversationDTO, ConversationEvents, ConversationFlowStateService, ConversationMessagesDTO, ConversationPromptBuilderService, ConversationRuleService, ConversationRulesComponent, ConversationStatus, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationUserChatSettingsComponent, DcAgentCardConverseComponent, DcAgentCardDetailComponent, DefaultAgentCardsService, DoActionTypeOptions, DynamicFlowService, DynamicFlowTaskTypeOptions, EAccountsPlatform, EAgentType, EDoActionType, EDynamicFlowTaskType, EntityThen, EntityWhatOptions, EntityWhenOptions, EvalResultStringDefinition, GlobalToolsService, MessageContent, MessageContentDisplayer, MessagesStateService, ModelSelectorComponent, PolitoNotificationComponent, PopupService, PromptPreviewComponent, SectionType, SystemPromptType, TextEngineOptions, TextEngines, VIDEO_PLAYER_SERVICE_TOKEN, VideoPlayerNativeService, VideoPlayerService, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, XKillsAgentCardsService, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, createAIModelFormGroup, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, getMoodStateLabelsAsString, getMoodStatePrompt, markdownToHtml, matchTranscription, provideAgentCardService, removeEmojis, removeEmojisAndSpecialCharacters, removeSpecialCharacters };
8999
9557
  //# sourceMappingURL=dataclouder-ngx-agent-cards.mjs.map