@dataclouder/ngx-agent-cards 0.1.13 → 0.1.14

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.
Files changed (23) hide show
  1. package/fesm2022/dataclouder-ngx-agent-cards.mjs +440 -198
  2. package/fesm2022/dataclouder-ngx-agent-cards.mjs.map +1 -1
  3. package/lib/components/chat-container/chat-container.component.d.ts +4 -3
  4. package/lib/components/chat-container/chat-footer/chat-footer.component.d.ts +2 -2
  5. package/lib/components/chat-container/chat-messages-list/chat-message/chat-message.component.d.ts +2 -1
  6. package/lib/components/chat-container/chat-messages-list/chat-message/chat-message.utils.d.ts +2 -1
  7. package/lib/components/chat-container/chat-messages-list/chat-messages-list.component.d.ts +2 -1
  8. package/lib/components/dc-agent-card-lists/dc-agent-card-lists.component.d.ts +2 -2
  9. package/lib/components/dc-agent-form/account-platform/account-platform-form.component.d.ts +0 -2
  10. package/lib/components/dc-agent-form/agent-task-form/agent-task-form.component.d.ts +27 -0
  11. package/lib/components/dc-agent-form/dc-agent-card-form.component.d.ts +21 -50
  12. package/lib/components/dc-agent-form/dc-character-card-form/dc-character-card-form.component.d.ts +27 -0
  13. package/lib/components/dc-agent-form/dc-conversation-flow-form/dc-conversation-flow-form.component.d.ts +31 -0
  14. package/lib/components/dc-agent-form/form-group.service.d.ts +19 -0
  15. package/lib/components/dc-agent-form/form-group.utils.d.ts +45 -0
  16. package/lib/models/agent.models.d.ts +47 -26
  17. package/lib/models/conversation-ai.class.d.ts +2 -2
  18. package/lib/models/conversation-enums.d.ts +1 -1
  19. package/lib/models/user-data-exchange.d.ts +1 -1
  20. package/lib/services/default-agent-service.d.ts +2 -2
  21. package/lib/services/evaluation.service.d.ts +2 -2
  22. package/package.json +1 -1
  23. package/public-api.d.ts +1 -0
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injectable, inject, RendererFactory2, ApplicationRef, Injector, EnvironmentInjector, signal, createComponent, Pipe, input, output, Input, Component, effect, ViewChild, computed, DestroyRef, ChangeDetectionStrategy, ElementRef, ChangeDetectorRef, ViewChildren } from '@angular/core';
2
+ import { InjectionToken, Injectable, inject, RendererFactory2, ApplicationRef, Injector, EnvironmentInjector, signal, createComponent, Pipe, input, output, Input, Component, effect, ViewChild, computed, DestroyRef, ChangeDetectionStrategy, ElementRef, ChangeDetectorRef, EventEmitter, Output, ViewChildren } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { DOCUMENT, CommonModule, DatePipe, DecimalPipe, NgComponentOutlet } from '@angular/common';
5
5
  import { HttpCoreService, AudioSpeed as AudioSpeed$1, TOAST_ALERTS_TOKEN, AudioSpeedReverse, PaginationBase, DCFilterBarComponent, QuickTableComponent } from '@dataclouder/ngx-core';
@@ -9,7 +9,7 @@ import { DialogModule } from 'primeng/dialog';
9
9
  import * as i2 from 'primeng/progressbar';
10
10
  import { ProgressBarModule } from 'primeng/progressbar';
11
11
  import * as i1 from '@angular/forms';
12
- import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule } from '@angular/forms';
12
+ import { FormControl, ReactiveFormsModule, FormBuilder, FormsModule, FormArray } from '@angular/forms';
13
13
  import { MicVadComponent } from '@dataclouder/ngx-mic';
14
14
  import * as i3 from 'primeng/textarea';
15
15
  import { TextareaModule } from 'primeng/textarea';
@@ -31,40 +31,40 @@ import { RatingModule } from 'primeng/rating';
31
31
  import * as i4 from 'primeng/table';
32
32
  import { TableModule } from 'primeng/table';
33
33
  import { BadgeModule } from 'primeng/badge';
34
- import * as i6 from 'primeng/tooltip';
34
+ import * as i5 from 'primeng/tooltip';
35
35
  import { TooltipModule } from 'primeng/tooltip';
36
36
  import * as i3$1 from 'primeng/api';
37
- import * as i5 from 'primeng/select';
37
+ import * as i5$1 from 'primeng/select';
38
38
  import { SelectModule } from 'primeng/select';
39
39
  import { ActivatedRoute, Router } from '@angular/router';
40
40
  import { OverlayModule } from '@angular/cdk/overlay';
41
41
  import { PortalModule } from '@angular/cdk/portal';
42
- import * as i4$1 from 'primeng/inputtext';
42
+ import * as i3$3 from 'primeng/inputtext';
43
43
  import { InputTextModule } from 'primeng/inputtext';
44
- import * as i6$1 from 'primeng/togglebutton';
44
+ import * as i6 from 'primeng/togglebutton';
45
45
  import { ToggleButtonModule } from 'primeng/togglebutton';
46
- import { ResolutionType, AspectType, MultiImagesStorageService, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
46
+ import { MultiImagesStorageService, ResolutionType, AspectType, CropperComponentModal } from '@dataclouder/ngx-cloud-storage';
47
47
  import { DialogRef, DIALOG_DATA } from '@angular/cdk/dialog';
48
- import * as i8 from 'primeng/toggleswitch';
48
+ import * as i6$1 from 'primeng/toggleswitch';
49
49
  import { ToggleSwitchModule } from 'primeng/toggleswitch';
50
- import * as i10 from 'primeng/popover';
50
+ import * as i8 from 'primeng/popover';
51
51
  import { PopoverModule } from 'primeng/popover';
52
52
  import * as i2$4 from 'primeng/card';
53
53
  import { CardModule } from 'primeng/card';
54
54
  import * as i3$2 from 'primeng/dropdown';
55
55
  import { DropdownModule } from 'primeng/dropdown';
56
56
  import { ChipModule } from 'primeng/chip';
57
- import * as i3$3 from 'primeng/listbox';
57
+ import * as i3$4 from 'primeng/listbox';
58
58
  import { ListboxModule } from 'primeng/listbox';
59
- import * as i11 from 'primeng/inputgroupaddon';
59
+ import * as i9 from 'primeng/inputgroupaddon';
60
60
  import { InputGroupAddonModule } from 'primeng/inputgroupaddon';
61
- import * as i12 from 'primeng/inputgroup';
61
+ import * as i10 from 'primeng/inputgroup';
62
62
  import { InputGroupModule } from 'primeng/inputgroup';
63
63
  import * as i1$4 from 'primeng/paginator';
64
64
  import { PaginatorModule } from 'primeng/paginator';
65
65
  import * as i2$5 from 'primeng/speeddial';
66
66
  import { SpeedDialModule } from 'primeng/speeddial';
67
- import * as i4$2 from 'primeng/tag';
67
+ import * as i4$1 from 'primeng/tag';
68
68
  import { TagModule } from 'primeng/tag';
69
69
 
70
70
  const characterCardStringDataDefinition = `
@@ -78,11 +78,50 @@ interface CharacterCardData {
78
78
  tags: string[]; // Array of descriptive tags
79
79
  appearance: string; // Physical description including height, build, hair color/style, eye color, skin tone, distinctive marks, clothing style, current outfit
80
80
  }`;
81
+ var EntityWhat;
82
+ (function (EntityWhat) {
83
+ EntityWhat["Goal"] = "goal";
84
+ EntityWhat["Bonus"] = "bonus";
85
+ EntityWhat["NumMessages"] = "numMessages";
86
+ EntityWhat["Time"] = "time";
87
+ })(EntityWhat || (EntityWhat = {}));
88
+ const EntityWhatOptions = [
89
+ { label: 'Goal', value: EntityWhat.Goal },
90
+ { label: 'Bonus', value: EntityWhat.Bonus },
91
+ { label: 'NumMessages', value: EntityWhat.NumMessages },
92
+ { label: 'Time', value: EntityWhat.Time },
93
+ ];
94
+ var EntityWhen;
95
+ (function (EntityWhen) {
96
+ EntityWhen["LowerThan"] = "<";
97
+ EntityWhen["LowerThanOrEqual"] = "<=";
98
+ EntityWhen["Equal"] = "=";
99
+ EntityWhen["GreaterThanOrEqual"] = ">=";
100
+ EntityWhen["GreaterThan"] = ">";
101
+ })(EntityWhen || (EntityWhen = {}));
102
+ const EntityWhenOptions = [
103
+ { label: '<', value: EntityWhen.LowerThan },
104
+ { label: '<=', value: EntityWhen.LowerThanOrEqual },
105
+ { label: '=', value: EntityWhen.Equal },
106
+ { label: '>=', value: EntityWhen.GreaterThanOrEqual },
107
+ { label: '>', value: EntityWhen.GreaterThan },
108
+ ];
109
+ var EntityThen;
110
+ (function (EntityThen) {
111
+ EntityThen["ChangePrompt"] = "changePrompt";
112
+ })(EntityThen || (EntityThen = {}));
81
113
  const EvalResultStringDefinition = `
82
114
  interface SimpleEvalResult {
83
115
  score: number; // Score of the user's response 0 to 3
84
116
  feedback: string; // Feedback of the user's understanding of the conversation
85
117
  }`;
118
+ var EModelQuality$1;
119
+ (function (EModelQuality) {
120
+ EModelQuality["FAST"] = "fast";
121
+ EModelQuality["BALANCED"] = "balanced";
122
+ EModelQuality["SMART"] = "smart";
123
+ EModelQuality["SMART_THINKING"] = "smart-thinking";
124
+ })(EModelQuality$1 || (EModelQuality$1 = {}));
86
125
  var EAccountsPlatform;
87
126
  (function (EAccountsPlatform) {
88
127
  EAccountsPlatform["Tiktok"] = "tiktok";
@@ -105,8 +144,6 @@ var ChatRole;
105
144
  })(ChatRole || (ChatRole = {}));
106
145
  class ChatMessage extends MessageContent {
107
146
  }
108
- class ChatUserSettings {
109
- }
110
147
  class ConversationMessagesDTO {
111
148
  }
112
149
  class ConversationDTO {
@@ -1799,13 +1836,11 @@ class ChatFooterComponent {
1799
1836
  this.conversationService = inject(ConversationService);
1800
1837
  this.evaluationService = inject(EvaluationService);
1801
1838
  this.agentCardService = inject(CONVERSATION_AI_TOKEN);
1802
- // @deprecated in favor of appAgentTask
1803
- // readonly evaluatorAgentCard = input<IMiniAgentCard>();
1804
1839
  // Inputs
1805
1840
  this.isAIThinking = input(false);
1806
1841
  this.taskOnUserMessage = input();
1807
1842
  this.taskOnAssistantMessage = input();
1808
- this.backgroundTasks = input();
1843
+ this.triggerTasks = input();
1809
1844
  this.micSettings = input({ useWhisper: true, lang: 'en' });
1810
1845
  // Outputs
1811
1846
  this.sendMessage = output();
@@ -1909,13 +1944,13 @@ class ChatFooterComponent {
1909
1944
  const settings = this.userDataExchangeService.getUserChatSettings();
1910
1945
  // Process background tasks
1911
1946
  if (type === ConversationEvents.OnUserMessage) {
1912
- const task = this.backgroundTasks()[type];
1947
+ const task = this.triggerTasks()[type];
1913
1948
  if (task && settings?.userMessageTask) {
1914
1949
  await this.evaluationService.evaluateWithTask(task, messageToEvaluate);
1915
1950
  }
1916
1951
  }
1917
1952
  else if (type === ConversationEvents.OnAssistantMessage) {
1918
- const task = this.backgroundTasks()[type];
1953
+ const task = this.triggerTasks()[type];
1919
1954
  if (task && settings?.assistantMessageTask) {
1920
1955
  await this.evaluationService.evaluateWithTask(task, messageToEvaluate, ContextType.CurrentMessageContent);
1921
1956
  }
@@ -1984,7 +2019,7 @@ class ChatFooterComponent {
1984
2019
  }
1985
2020
  }
1986
2021
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1987
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", isSignal: true, isRequired: false, transformFunction: null }, taskOnUserMessage: { classPropertyName: "taskOnUserMessage", publicName: "taskOnUserMessage", isSignal: true, isRequired: false, transformFunction: null }, taskOnAssistantMessage: { classPropertyName: "taskOnAssistantMessage", publicName: "taskOnAssistantMessage", isSignal: true, isRequired: false, transformFunction: null }, backgroundTasks: { classPropertyName: "backgroundTasks", publicName: "backgroundTasks", isSignal: true, isRequired: false, transformFunction: null }, micSettings: { classPropertyName: "micSettings", publicName: "micSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", textInputChanged: "textInputChanged" }, viewQueries: [{ propertyName: "micComponent", first: true, predicate: MicVadComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" />\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"sendUserMessage()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"sendUserMessage()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(taskOnUserMessage()) {\n <div (click)=\"setScore(100)\">\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n </div>\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: MicVadComponent, selector: "app-mic-vad", inputs: ["continueListening"], outputs: ["statusChanged", "audioRecorded", "error"] }] }); }
2022
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ChatFooterComponent, isStandalone: true, selector: "dc-chat-footer", inputs: { isAIThinking: { classPropertyName: "isAIThinking", publicName: "isAIThinking", isSignal: true, isRequired: false, transformFunction: null }, taskOnUserMessage: { classPropertyName: "taskOnUserMessage", publicName: "taskOnUserMessage", isSignal: true, isRequired: false, transformFunction: null }, taskOnAssistantMessage: { classPropertyName: "taskOnAssistantMessage", publicName: "taskOnAssistantMessage", isSignal: true, isRequired: false, transformFunction: null }, triggerTasks: { classPropertyName: "triggerTasks", publicName: "triggerTasks", isSignal: true, isRequired: false, transformFunction: null }, micSettings: { classPropertyName: "micSettings", publicName: "micSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", textInputChanged: "textInputChanged" }, viewQueries: [{ propertyName: "micComponent", first: true, predicate: MicVadComponent, descendants: true }], ngImport: i0, template: "<div class=\"progress-input\">\n <div class=\"input-container\">\n <app-mic-vad\n (audioRecorded)=\"handleAudioRecorded($event)\"\n (statusChanged)=\"handleMicStatusChanged($event)\"\n [continueListening]=\"shouldContinueListening()\" />\n\n <textarea pTextarea [formControl]=\"chatInputControl\" (keyup.enter)=\"sendUserMessage()\" rows=\"1\"></textarea>\n\n <p-button (click)=\"sendUserMessage()\" [disabled]=\"isAIThinking() || !chatInputControl.value\" label=\"Enviar\" [rounded]=\"true\" />\n </div>\n\n @if(taskOnUserMessage()) {\n <div (click)=\"setScore(100)\">\n <p-progressbar showValue=\"false\" [value]=\"score()\" [style]=\"{ height: '6px' }\" />\n </div>\n }\n</div>\n", styles: [".progress-input{padding:10px;background-color:#f5f5f545;border-top:1px solid #b1a8a8}.progress-input .input-container{display:flex;align-items:center;margin-bottom:5px}.progress-input .input-container textarea{flex:1;resize:none;margin:0 10px}.progress-input .input-container .send-button{background-color:#007bff;color:#fff;border:none;border-radius:4px;padding:8px 15px;cursor:pointer}.progress-input .input-container .send-button:disabled{background-color:#ccc;cursor:not-allowed}.progress-input .input-container .send-button:hover:not(:disabled){background-color:#0069d9}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i2.ProgressBar, selector: "p-progressBar, p-progressbar, p-progress-bar", inputs: ["value", "showValue", "styleClass", "valueStyleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: MicVadComponent, selector: "app-mic-vad", inputs: ["continueListening"], outputs: ["statusChanged", "audioRecorded", "error"] }] }); }
1988
2023
  }
1989
2024
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ChatFooterComponent, decorators: [{
1990
2025
  type: Component,
@@ -2732,7 +2767,7 @@ class ProviderSelectorComponent {
2732
2767
  }
2733
2768
  }
2734
2769
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ProviderSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2735
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ProviderSelectorComponent, isStandalone: true, selector: "dc-provider-selector", inputs: { parentForm: "parentForm" }, ngImport: i0, template: "<div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Providers:</b>\n <div style=\"display: flex; gap: 10px\" [formGroup]=\"parentForm\">\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\">{{ parentForm.controls.modelName.value }}</span>\n @if (parentForm.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]=\"parentForm\">\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", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i2$2.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "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", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "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: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2770
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: ProviderSelectorComponent, isStandalone: true, selector: "dc-provider-selector", inputs: { parentForm: "parentForm" }, ngImport: i0, template: "<div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Providers:</b>\n <div style=\"display: flex; gap: 10px\" [formGroup]=\"parentForm\">\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\">{{ parentForm.controls.modelName.value }}</span>\n @if (parentForm.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]=\"parentForm\">\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", styles: [":host{display:block}.space{display:flex;gap:2px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i2$2.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "directive", type: i3$1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: TableModule }, { kind: "component", type: i4.Table, selector: "p-table", inputs: ["frozenColumns", "frozenValue", "style", "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", "scrollDirection", "rowGroupMode", "scrollHeight", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "virtualScrollDelay", "frozenWidth", "responsive", "contextMenu", "resizableColumns", "columnResizeMode", "reorderableColumns", "loading", "loadingIcon", "showLoader", "rowHover", "customSort", "showInitialSortBadge", "autoLayout", "exportFunction", "exportHeader", "stateKey", "stateStorage", "editMode", "groupRowsBy", "size", "showGridlines", "stripedRows", "groupRowsByOrder", "responsiveLayout", "breakpoint", "paginatorLocale", "value", "columns", "first", "rows", "totalRecords", "sortField", "sortOrder", "multiSortMeta", "selection", "virtualRowHeight", "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: "ngmodule", type: SkeletonModule }, { kind: "component", type: i1$2.Skeleton, selector: "p-skeleton", inputs: ["styleClass", "style", "shape", "animation", "borderRadius", "size", "width", "height"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: DecimalPipe, name: "number" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2736
2771
  }
2737
2772
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: ProviderSelectorComponent, decorators: [{
2738
2773
  type: Component,
@@ -2805,7 +2840,7 @@ class DCConversationUserChatSettingsComponent {
2805
2840
  }
2806
2841
  }
2807
2842
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationUserChatSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2808
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationUserChatSettingsComponent, isStandalone: true, selector: "dc-chat-settings-dialog", inputs: { showFeature: { classPropertyName: "showFeature", publicName: "showFeature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSettingsChange: "onSettingsChange" }, viewQueries: [{ propertyName: "tooltipRef", first: true, predicate: ["tooltipRef"], descendants: true }], ngImport: i0, template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i2$2.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }, { kind: "ngmodule", type: RatingModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: BadgeModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: ProviderSelectorComponent, selector: "dc-provider-selector", inputs: ["parentForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
2843
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationUserChatSettingsComponent, isStandalone: true, selector: "dc-chat-settings-dialog", inputs: { showFeature: { classPropertyName: "showFeature", publicName: "showFeature", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onSettingsChange: "onSettingsChange" }, viewQueries: [{ propertyName: "tooltipRef", first: true, predicate: ["tooltipRef"], descendants: true }], ngImport: i0, template: "<div class=\"dialog-container\">\n <form [formGroup]=\"form\">\n @if (showFeature().synthVoice) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"synthVoice\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.synthVoice.disabled\">Escuchar Voz</span>\n <br />\n <small>Desmarca si solo quieres leer texto</small>\n </p>\n </div>\n } @if (showFeature().highlightWords) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"highlightWords\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Narraci\u00F3n de texto</span>\n <br />\n <small>Remarca las palabras como se van pronuncionando</small>\n </p>\n </div>\n } @if (showFeature().speed) {\n <div class=\"settings-section\">\n <p>\n Velocidad ({{ form.controls.speed.value | speedDisplay }})\n <br />\n\n <!-- <p-rating formControlName=\"speed\" iconOnClass=\"pi pi-step-forward\" iconOffClass=\"pi pi-minus\" /> -->\n\n <p-select\n id=\"speed\"\n [options]=\"speedOptions\"\n formControlName=\"speed\"\n [placeholder]=\"'Select Language'\"\n optionLabel=\"label\"\n optionValue=\"value\"></p-select>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"realTime\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.realTime.disabled\">Tiempo real</span>\n <br />\n <small>No tienes que presionar el microphono, comenzar\u00E1 a grabar en cuanto la AI termine de hablar, cierra el chat para finalizar conversaci\u00F3n.</small>\n </p>\n </div>\n } @if (showFeature().realTime) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"repeatRecording\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Reproducir mi grabaci\u00F3n</span>\n <br />\n <small>Escucha tu dialogo, despu\u00E9s de grabar, te ayudar\u00E1 a notar tus errores.</small>\n </p>\n </div>\n } @if (showFeature().superHearing) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"superHearing\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span>Super O\u00EDdo \uD83E\uDDBE</span>\n <br />\n <small>Tu audio se procesa en el servidor para mejor efectividad, si no usa el navegador.</small>\n </p>\n </div>\n }\n\n <!-- @if (showFeature().fixGrammar) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"fixGrammar\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.fixGrammar.disabled\">Corregir gram\u00E1tica</span>\n <br />\n <small>La ai corrige tu forma de hablar/escribir y te retrolimenta de tus errores</small>\n </p>\n </div>\n } -->\n\n <!-- @if (showFeature().autoTranslate) {\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"autoTranslate\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.autoTranslate.disabled\">Mostrar Traducciones </span>\n <br />\n <small>Texto adicional con la traducci\u00F3n</small>\n </p>\n </div>\n } -->\n\n @if (showFeature().autoTranslate) {\n <div class=\"voice-selection\">\n <span>Voz Preferencial:</span>\n <br />\n <p-radioButton value=\"random\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Aleatorio</label>\n <p-radioButton value=\"randomMan\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Hombre</label>\n <p-radioButton value=\"randomWoman\" formControlName=\"voice\"></p-radioButton>\n <label class=\"space\">Mujer</label>\n </div>\n }\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"userMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.userMessageTask.disabled\">Procesar mensajes de usuario</span>\n <br />\n <small>Correcciones, mejoras, retroalimentaci\u00F3n y sugerencias en el texto del usuario </small>\n </p>\n </div>\n\n <div class=\"settings-section\">\n <p>\n <p-checkbox class=\"mr-2\" formControlName=\"assistantMessageTask\" [binary]=\"true\" inputId=\"binary\"></p-checkbox>\n <span [class.cross]=\"form.controls.assistantMessageTask.disabled\">Procesar mensajes de asistente</span>\n <br />\n <small>Correcciones, traducciones, pensamientos adicionales y m\u00E1s ayuda en el texto del asistente </small>\n </p>\n </div>\n\n @if(isAdmin) {\n <div>\n <hr />\n <b>Admin Section</b>\n <br />\n\n <b>Modelo:</b>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n }\n\n <div class=\"button-group\">\n <p-button (click)=\"saveSettings()\" label=\"Guardar cambios\"></p-button>\n <p-button (click)=\"close()\" label=\"Cancelar\" styleClass=\"p-button-secondary\"></p-button>\n </div>\n </form>\n</div>\n", styles: [".dialog-container{padding:20px;background:#fff;border-radius:8px;min-width:300px;max-width:500px}.dialog-content{margin:20px 0}.dialog-actions{display:flex;justify-content:flex-end}.settings-section{margin-bottom:20px}.settings-section label{display:block;margin-bottom:5px;font-weight:700}.settings-section small{display:block;color:#666;margin-top:2px}.voice-selection{margin:15px 0}.voice-selection label{margin-right:15px}.button-group{margin-top:20px;display:flex;gap:10px;justify-content:flex-end}button{padding:8px 16px;border-radius:4px;border:none;cursor:pointer}button:first-child{background-color:#007bff;color:#fff}button:last-child{background-color:#6c757d;color:#fff}.space{margin-left:3px}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SliderModule }, { kind: "ngmodule", type: RadioButtonModule }, { kind: "component", type: i2$2.RadioButton, selector: "p-radioButton, p-radiobutton, p-radio-button", inputs: ["value", "formControlName", "name", "disabled", "variant", "size", "tabindex", "inputId", "ariaLabelledBy", "ariaLabel", "style", "styleClass", "autofocus", "binary"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "pipe", type: SpeedDescPipe, name: "speedDisplay" }, { kind: "ngmodule", type: RatingModule }, { kind: "ngmodule", type: TableModule }, { kind: "ngmodule", type: BadgeModule }, { kind: "ngmodule", type: SkeletonModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "component", type: ProviderSelectorComponent, selector: "dc-provider-selector", inputs: ["parentForm"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
2809
2844
  }
2810
2845
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationUserChatSettingsComponent, decorators: [{
2811
2846
  type: Component,
@@ -2838,9 +2873,9 @@ class DCChatComponent {
2838
2873
  this.userDataExchange = inject(USER_DATA_EXCHANGE);
2839
2874
  // 📥 Inputs
2840
2875
  this.chatUserSettings = this.userDataExchange.getUserChatSettings(); // Default to user data exchange
2841
- this.backgroundTasks = null;
2876
+ this.conversationFlow = null;
2877
+ // @Input() backgroundTasks: Record<ConversationEvents, SimpleAgentTask> | null = null;
2842
2878
  // 📤 Input Signals
2843
- // readonly evaluatorAgentCard = input<IMiniAgentCard>(); // @Deprecated in favor of appAgentTask
2844
2879
  this.taskOnUserMessage = input();
2845
2880
  this.taskOnAssistantMessage = input();
2846
2881
  this.parseDict = input({});
@@ -2873,8 +2908,8 @@ class DCChatComponent {
2873
2908
  });
2874
2909
  }
2875
2910
  async ngOnInit() {
2911
+ this.conversationService.setDestroyed(false);
2876
2912
  if (this.conversationSettings) {
2877
- this.conversationService.setDestroyed(false);
2878
2913
  await this.conversationService.initConversationWithSettings(this.conversationSettings);
2879
2914
  }
2880
2915
  else {
@@ -2920,11 +2955,11 @@ class DCChatComponent {
2920
2955
  await this.ngOnInit();
2921
2956
  }
2922
2957
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2923
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, backgroundTasks: { classPropertyName: "backgroundTasks", publicName: "backgroundTasks", isSignal: false, isRequired: false, transformFunction: null }, taskOnUserMessage: { classPropertyName: "taskOnUserMessage", publicName: "taskOnUserMessage", isSignal: true, isRequired: false, transformFunction: null }, taskOnAssistantMessage: { classPropertyName: "taskOnAssistantMessage", publicName: "taskOnAssistantMessage", isSignal: true, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", goalCompleted: "goalCompleted" }, providers: [DialogService], viewQueries: [{ propertyName: "chatFooterComponent", first: true, predicate: ChatFooterComponent, descendants: true }], ngImport: i0, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [backgroundTasks]=\"backgroundTasks\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.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}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["isAdmin", "alternativeConversation", "agentCard"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "taskOnUserMessage", "taskOnAssistantMessage", "backgroundTasks", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings", "inputMessages"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2958
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.4", type: DCChatComponent, isStandalone: true, selector: "dc-chat", inputs: { chatUserSettings: { classPropertyName: "chatUserSettings", publicName: "chatUserSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationSettings: { classPropertyName: "conversationSettings", publicName: "conversationSettings", isSignal: false, isRequired: false, transformFunction: null }, conversationFlow: { classPropertyName: "conversationFlow", publicName: "conversationFlow", isSignal: false, isRequired: false, transformFunction: null }, agentCard: { classPropertyName: "agentCard", publicName: "agentCard", isSignal: false, isRequired: false, transformFunction: null }, taskOnUserMessage: { classPropertyName: "taskOnUserMessage", publicName: "taskOnUserMessage", isSignal: true, isRequired: false, transformFunction: null }, taskOnAssistantMessage: { classPropertyName: "taskOnAssistantMessage", publicName: "taskOnAssistantMessage", isSignal: true, isRequired: false, transformFunction: null }, parseDict: { classPropertyName: "parseDict", publicName: "parseDict", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { sendMessage: "sendMessage", goalCompleted: "goalCompleted" }, providers: [DialogService], viewQueries: [{ propertyName: "chatFooterComponent", first: true, predicate: ChatFooterComponent, descendants: true }], ngImport: i0, template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [triggerTasks]=\"conversationFlow?.triggerTasks\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.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}.info-content h3{margin-top:1rem;margin-bottom:.5rem;font-size:1.2rem}.info-content pre{background-color:var(--surface-hover, #f1f1f1);padding:1rem;border-radius:4px;overflow-x:auto;font-size:.9rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: ChatHeaderComponent, selector: "dc-chat-header", inputs: ["isAdmin", "alternativeConversation", "agentCard"], outputs: ["restartConversationEvent", "showInfoEvent", "settingsClickEvent"] }, { kind: "component", type: ChatFooterComponent, selector: "dc-chat-footer", inputs: ["isAIThinking", "taskOnUserMessage", "taskOnAssistantMessage", "triggerTasks", "micSettings"], outputs: ["sendMessage", "textInputChanged"] }, { kind: "component", type: ChatMessagesListComponent, selector: "dc-chat-messages-list", inputs: ["chatUserSettings", "inputMessages"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$3.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "closeButtonProps", "maximizeButtonProps", "visible", "style", "position", "role", "content", "contentTemplate", "footerTemplate", "closeIconTemplate", "maximizeIconTemplate", "minimizeIconTemplate", "headlessTemplate"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "pipe", type: SafeJsonPipe, name: "safeJson" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
2924
2959
  }
2925
2960
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCChatComponent, decorators: [{
2926
2961
  type: Component,
2927
- args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, DialogModule, ProgressBarModule, SafeJsonPipe], changeDetection: ChangeDetectionStrategy.OnPush, providers: [DialogService], template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [backgroundTasks]=\"backgroundTasks\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.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}.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"] }]
2962
+ args: [{ selector: 'dc-chat', standalone: true, imports: [CommonModule, ChatHeaderComponent, ChatFooterComponent, ChatMessagesListComponent, DialogModule, ProgressBarModule, SafeJsonPipe], changeDetection: ChangeDetectionStrategy.OnPush, providers: [DialogService], template: "<div class=\"chat-container\">\n <!-- Chat Header -->\n <dc-chat-header\n [agentCard]=\"agentCard\"\n [isAdmin]=\"isAdmin\"\n (showInfoEvent)=\"showInfo()\"\n (settingsClickEvent)=\"changeUserChatSettings()\"\n (restartConversationEvent)=\"restartConversation($event)\">\n </dc-chat-header>\n\n <!-- Messages List -->\n <dc-chat-messages-list [chatUserSettings]=\"chatUserSettings\" [inputMessages]=\"messages()\"> </dc-chat-messages-list>\n\n <!-- Chat Footer -->\n <dc-chat-footer [micSettings]=\"micSettings\" [triggerTasks]=\"conversationFlow?.triggerTasks\"> </dc-chat-footer>\n\n <!-- Info Dialog -->\n <p-dialog [(visible)]=\"isInfoVisible\" [modal]=\"true\" [draggable]=\"false\" [resizable]=\"false\" header=\"Conversation Info\">\n <div class=\"info-content\">\n <h3>Agent Card</h3>\n <pre>{{ agentCard | safeJson }}</pre>\n\n <h3>User Settings</h3>\n <pre>{{ chatUserSettings | safeJson }}</pre>\n </div>\n </p-dialog>\n</div>\n", styles: ["::ng-deep .p-drawer-content{padding:0!important}.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}.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"] }]
2928
2963
  }], ctorParameters: () => [], propDecorators: { chatFooterComponent: [{
2929
2964
  type: ViewChild,
2930
2965
  args: [ChatFooterComponent]
@@ -2932,9 +2967,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
2932
2967
  type: Input
2933
2968
  }], conversationSettings: [{
2934
2969
  type: Input
2935
- }], agentCard: [{
2970
+ }], conversationFlow: [{
2936
2971
  type: Input
2937
- }], backgroundTasks: [{
2972
+ }], agentCard: [{
2938
2973
  type: Input
2939
2974
  }] } });
2940
2975
 
@@ -3356,12 +3391,12 @@ class AccountPlatformForm {
3356
3391
  }
3357
3392
  }
3358
3393
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AccountPlatformForm, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3359
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AccountPlatformForm, isStandalone: true, selector: "account-platform-form", inputs: { formArray: "formArray" }, ngImport: i0, template: "<div class=\"source-form-card\">\n <p-card header=\"Cuenta\">\n @for (formAccount of formArray.controls; track formAccount) {\n <form [formGroup]=\"$any(formAccount)\">\n <div class=\"form-field\">\n <label class=\"block\">Platform</label>\n <p-dropdown [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-dropdown>\n </div>\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Username</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field\">\n <label class=\"block\">Email</label>\n <input pInputText type=\"text\" formControlName=\"email\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n </form>\n }\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$2.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3394
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AccountPlatformForm, isStandalone: true, selector: "account-platform-form", inputs: { formArray: "formArray" }, ngImport: i0, template: "<div class=\"source-form-card\">\n <p-card header=\"Cuenta\">\n @for (formAccount of formArray.controls; track formAccount) {\n <form [formGroup]=\"$any(formAccount)\">\n <div class=\"form-field\">\n <label class=\"block\">Platform</label>\n <p-dropdown [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-dropdown>\n </div>\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Username</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field\">\n <label class=\"block\">Email</label>\n <input pInputText type=\"text\" formControlName=\"email\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n </form>\n }\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$2.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "ngmodule", type: SelectModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "ngmodule", type: TooltipModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3360
3395
  }
3361
3396
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AccountPlatformForm, decorators: [{
3362
3397
  type: Component,
3363
3398
  args: [{ selector: 'account-platform-form', imports: [ReactiveFormsModule, CardModule, TextareaModule, DropdownModule, ButtonModule, SelectModule, InputTextModule, ChipModule, TooltipModule], changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"source-form-card\">\n <p-card header=\"Cuenta\">\n @for (formAccount of formArray.controls; track formAccount) {\n <form [formGroup]=\"$any(formAccount)\">\n <div class=\"form-field\">\n <label class=\"block\">Platform</label>\n <p-dropdown [options]=\"platformOptions\" formControlName=\"platform\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select a platform\"></p-dropdown>\n </div>\n\n <div class=\"form-field\">\n <label for=\"name\" class=\"block\">Username</label>\n <input pInputText id=\"name\" type=\"text\" formControlName=\"name\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n\n <div class=\"form-field\">\n <label class=\"block\">Email</label>\n <input pInputText type=\"text\" formControlName=\"email\" placeholder=\"Enter name\" class=\"w-full\" />\n </div>\n </form>\n }\n </p-card>\n</div>\n", styles: [":host{display:block;padding:1rem}.source-form-card{max-width:800px;margin:0 auto}.form-field{margin-bottom:1.5rem;display:flex;flex-direction:column}.form-field label{margin-bottom:.5rem;font-weight:500;color:#495057}.form-field input,.form-field textarea,.form-field ::ng-deep .p-element{margin-top:.25rem}:host ::ng-deep .p-card .p-card-content>div:last-child{margin-top:1.5rem;display:flex;justify-content:flex-end}:host ::ng-deep .p-card .p-card-header{background-color:#f8f9fa;padding:1rem;border-bottom:1px solid #dee2e6}h3{color:#495057;margin-bottom:1.5rem;text-align:center}\n"] }]
3364
- }], ctorParameters: () => [], propDecorators: { formArray: [{
3399
+ }], propDecorators: { formArray: [{
3365
3400
  type: Input
3366
3401
  }] } });
3367
3402
 
@@ -3494,23 +3529,334 @@ class VoiceSelectorComponent {
3494
3529
  this.dialogRef.close();
3495
3530
  }
3496
3531
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: VoiceSelectorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3497
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: VoiceSelectorComponent, isStandalone: true, selector: "dc-voice-selector", ngImport: i0, template: "<div class=\"p-fluid\">\n <div class=\"p-field mb-3\">\n <label for=\"language\">Select Language</label>\n <p-dropdown\n inputId=\"language\"\n [options]=\"availableLanguages\"\n [(ngModel)]=\"selectedLanguageCode\"\n optionLabel=\"name\"\n optionValue=\"code\"\n placeholder=\"Select a Language\"\n [filter]=\"true\"\n filterBy=\"name\"\n [style]=\"{ width: '100%' }\"\n [showClear]=\"true\">\n </p-dropdown>\n </div>\n\n <a href=\"https://cloud.google.com/text-to-speech/docs/chirp3-hd\" target=\"_blank\">Check Google Voice Examples</a>\n\n <div class=\"p-field\">\n <label for=\"voice\">Select Voice</label>\n <p-listbox\n inputId=\"voice\"\n [options]=\"voices\"\n [(ngModel)]=\"selectedVoiceId\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [style]=\"{ width: '100%' }\"\n listStyleClass=\"p-listbox-sm\"\n [filter]=\"true\"\n filterBy=\"name\"\n placeholder=\"Search voice\">\n </p-listbox>\n </div>\n</div>\n<div class=\"p-dialog-footer\">\n <p-button label=\"Cancel\" icon=\"pi pi-times\" (click)=\"cancel()\" styleClass=\"p-button-text\"></p-button>\n <p-button label=\"Select\" icon=\"pi pi-check\" (click)=\"selectVoice()\" [disabled]=\"!selectedVoiceId && !selectedLanguageCode\"></p-button>\n</div>\n", styles: [":host ::ng-deep .p-listbox-sm .p-listbox-item{padding:.5rem .75rem;font-size:.875rem}:host ::ng-deep .p-dialog-footer{padding-top:1rem;display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i3$3.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "style", "styleClass", "listStyle", "listStyleClass", "readonly", "disabled", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$2.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
3532
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.4", type: VoiceSelectorComponent, isStandalone: true, selector: "dc-voice-selector", ngImport: i0, template: "<div class=\"p-fluid\">\n <div class=\"p-field mb-3\">\n <label for=\"language\">Select Language</label>\n <p-dropdown\n inputId=\"language\"\n [options]=\"availableLanguages\"\n [(ngModel)]=\"selectedLanguageCode\"\n optionLabel=\"name\"\n optionValue=\"code\"\n placeholder=\"Select a Language\"\n [filter]=\"true\"\n filterBy=\"name\"\n [style]=\"{ width: '100%' }\"\n [showClear]=\"true\">\n </p-dropdown>\n </div>\n\n <a href=\"https://cloud.google.com/text-to-speech/docs/chirp3-hd\" target=\"_blank\">Check Google Voice Examples</a>\n\n <div class=\"p-field\">\n <label for=\"voice\">Select Voice</label>\n <p-listbox\n inputId=\"voice\"\n [options]=\"voices\"\n [(ngModel)]=\"selectedVoiceId\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [style]=\"{ width: '100%' }\"\n listStyleClass=\"p-listbox-sm\"\n [filter]=\"true\"\n filterBy=\"name\"\n placeholder=\"Search voice\">\n </p-listbox>\n </div>\n</div>\n<div class=\"p-dialog-footer\">\n <p-button label=\"Cancel\" icon=\"pi pi-times\" (click)=\"cancel()\" styleClass=\"p-button-text\"></p-button>\n <p-button label=\"Select\" icon=\"pi pi-check\" (click)=\"selectVoice()\" [disabled]=\"!selectedVoiceId && !selectedLanguageCode\"></p-button>\n</div>\n", styles: [":host ::ng-deep .p-listbox-sm .p-listbox-item{padding:.5rem .75rem;font-size:.875rem}:host ::ng-deep .p-dialog-footer{padding-top:1rem;display:flex;justify-content:flex-end;gap:.5rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ListboxModule }, { kind: "component", type: i3$4.Listbox, selector: "p-listbox, p-listBox, p-list-box", inputs: ["id", "searchMessage", "emptySelectionMessage", "selectionMessage", "autoOptionFocus", "ariaLabel", "selectOnFocus", "searchLocale", "focusOnHover", "filterMessage", "filterFields", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "scrollHeight", "tabindex", "multiple", "style", "styleClass", "listStyle", "listStyleClass", "readonly", "disabled", "checkbox", "filter", "filterBy", "filterMatchMode", "filterLocale", "metaKeySelection", "dataKey", "showToggleAll", "optionLabel", "optionValue", "optionGroupChildren", "optionGroupLabel", "optionDisabled", "ariaFilterLabel", "filterPlaceHolder", "emptyFilterMessage", "emptyMessage", "group", "options", "filterValue", "selectAll", "striped", "highlightOnSelect", "checkmark", "dragdrop"], outputs: ["onChange", "onClick", "onDblClick", "onFilter", "onFocus", "onBlur", "onSelectAllChange", "onLazyLoad", "onDrop"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$2.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
3498
3533
  }
3499
3534
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: VoiceSelectorComponent, decorators: [{
3500
3535
  type: Component,
3501
3536
  args: [{ selector: 'dc-voice-selector', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, ListboxModule, DropdownModule], template: "<div class=\"p-fluid\">\n <div class=\"p-field mb-3\">\n <label for=\"language\">Select Language</label>\n <p-dropdown\n inputId=\"language\"\n [options]=\"availableLanguages\"\n [(ngModel)]=\"selectedLanguageCode\"\n optionLabel=\"name\"\n optionValue=\"code\"\n placeholder=\"Select a Language\"\n [filter]=\"true\"\n filterBy=\"name\"\n [style]=\"{ width: '100%' }\"\n [showClear]=\"true\">\n </p-dropdown>\n </div>\n\n <a href=\"https://cloud.google.com/text-to-speech/docs/chirp3-hd\" target=\"_blank\">Check Google Voice Examples</a>\n\n <div class=\"p-field\">\n <label for=\"voice\">Select Voice</label>\n <p-listbox\n inputId=\"voice\"\n [options]=\"voices\"\n [(ngModel)]=\"selectedVoiceId\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [style]=\"{ width: '100%' }\"\n listStyleClass=\"p-listbox-sm\"\n [filter]=\"true\"\n filterBy=\"name\"\n placeholder=\"Search voice\">\n </p-listbox>\n </div>\n</div>\n<div class=\"p-dialog-footer\">\n <p-button label=\"Cancel\" icon=\"pi pi-times\" (click)=\"cancel()\" styleClass=\"p-button-text\"></p-button>\n <p-button label=\"Select\" icon=\"pi pi-check\" (click)=\"selectVoice()\" [disabled]=\"!selectedVoiceId && !selectedLanguageCode\"></p-button>\n</div>\n", styles: [":host ::ng-deep .p-listbox-sm .p-listbox-item{padding:.5rem .75rem;font-size:.875rem}:host ::ng-deep .p-dialog-footer{padding-top:1rem;display:flex;justify-content:flex-end;gap:.5rem}\n"] }]
3502
3537
  }] });
3503
3538
 
3504
- class DCAgentCardFormComponent {
3505
- getSettings() {
3506
- const imageSettings = {
3507
- path: 'conversation-cards/' + this.agentCardId,
3508
- fileName: '',
3509
- cropSettings: { aspectRatio: AspectType.Vertical_9_16, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 450 },
3510
- };
3511
- return imageSettings;
3539
+ class FormGroupService {
3540
+ constructor() {
3541
+ this.fb = inject(FormBuilder);
3542
+ }
3543
+ createCharacterCardFormGroup() {
3544
+ return this.fb.group({
3545
+ data: this.fb.group({
3546
+ name: [''],
3547
+ description: [''],
3548
+ scenario: [''],
3549
+ first_mes: [''],
3550
+ creator_notes: [''],
3551
+ mes_example: [''],
3552
+ alternate_greetings: this.fb.array([]),
3553
+ tags: this.fb.array([]),
3554
+ picture_description: [''],
3555
+ system_prompt: [''],
3556
+ post_history_instructions: [''],
3557
+ }),
3558
+ });
3559
+ }
3560
+ createConversationSettingFormGroup() {
3561
+ return this.fb.group({
3562
+ textEngine: [TextEngines.SimpleText],
3563
+ conversationType: [ConversationType.General],
3564
+ autoStart: [true],
3565
+ tts: this.fb.group({ voice: [''], secondaryVoice: [''], speed: ['1.0'], speedRate: [1.0] }),
3566
+ });
3567
+ }
3568
+ createAccountsFormGroup() {
3569
+ return this.fb.group({
3570
+ accounts: this.fb.array([]),
3571
+ });
3572
+ }
3573
+ createMetaFormGroup() {
3574
+ return this.fb.group({
3575
+ isPublished: [false],
3576
+ isPublic: [false],
3577
+ authorId: [''],
3578
+ authorEmail: [''],
3579
+ takenCount: [0],
3580
+ });
3581
+ }
3582
+ createModelFormGroup(model) {
3583
+ return this.fb.group({
3584
+ id: this.fb.control(model?.id || ''),
3585
+ modelName: this.fb.control(model?.modelName || ''),
3586
+ provider: this.fb.control(model?.provider || ''),
3587
+ });
3588
+ }
3589
+ createConversationFlowFormGroup() {
3590
+ return this.fb.group({
3591
+ goal: this.createSimpleAgentTaskFormGroup(),
3592
+ triggerTasks: this.createTriggerTasksFormGroup(),
3593
+ bonus: this.fb.control(''),
3594
+ dynamicConditions: this.fb.array([]),
3595
+ });
3596
+ }
3597
+ createDynamicConditionFormGroup(condition) {
3598
+ return this.fb.group({
3599
+ what: this.fb.control(condition?.what || ''),
3600
+ when: this.fb.control(condition?.when || ''),
3601
+ value: this.fb.control(condition?.value || ''),
3602
+ then: this.fb.control(condition?.then || ''),
3603
+ task: this.createSimpleAgentTaskFormGroup(condition?.task),
3604
+ });
3605
+ }
3606
+ createTriggerTasksFormGroup() {
3607
+ return this.fb.group({
3608
+ [ConversationEvents.OnUserMessage]: this.createSimpleAgentTaskFormGroup(),
3609
+ [ConversationEvents.OnAssistantMessage]: this.createSimpleAgentTaskFormGroup(),
3610
+ [ConversationEvents.OnGoalCompleted]: this.createSimpleAgentTaskFormGroup(),
3611
+ });
3612
+ }
3613
+ createSimpleAgentTaskFormGroup(task) {
3614
+ return this.fb.group({
3615
+ systemPrompt: this.fb.control(task?.systemPrompt || ''),
3616
+ task: this.fb.control(task?.task || ''),
3617
+ expectedResponseType: this.fb.control(task?.expectedResponseType || ''),
3618
+ modelQuality: this.fb.control(task?.modelQuality || EModelQuality$1.FAST),
3619
+ model: this.createModelFormGroup(task?.model),
3620
+ });
3621
+ }
3622
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FormGroupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3623
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FormGroupService, providedIn: 'root' }); }
3624
+ }
3625
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: FormGroupService, decorators: [{
3626
+ type: Injectable,
3627
+ args: [{
3628
+ providedIn: 'root',
3629
+ }]
3630
+ }] });
3631
+
3632
+ var EModelQuality;
3633
+ (function (EModelQuality) {
3634
+ EModelQuality["FAST"] = "fast";
3635
+ EModelQuality["BALANCED"] = "balanced";
3636
+ EModelQuality["SMART"] = "smart";
3637
+ EModelQuality["SMART_THINKING"] = "smart-thinking";
3638
+ })(EModelQuality || (EModelQuality = {}));
3639
+ function createAgentTaskFormGroup(task) {
3640
+ const fb = inject(FormBuilder);
3641
+ return fb.group({
3642
+ systemPrompt: [task?.systemPrompt || ''],
3643
+ task: [task?.task || ''],
3644
+ expectedResponseType: [task?.expectedResponseType || ''],
3645
+ modelQuality: [task?.modelQuality || EModelQuality.FAST],
3646
+ });
3647
+ }
3648
+ class AgentTaskFormComponent {
3649
+ constructor() {
3650
+ this.fb = inject(FormBuilder);
3651
+ this.formGroupService = inject(FormGroupService);
3652
+ this.formGroup = this.formGroupService.createSimpleAgentTaskFormGroup();
3653
+ this.modelQualityOptions = Object.values(EModelQuality).map((value) => ({
3654
+ label: value.charAt(0).toUpperCase() + value.slice(1).replace(/_/g, ' '), // Format for display
3655
+ value: value,
3656
+ }));
3657
+ }
3658
+ ngOnInit() {
3659
+ console.log(this.formGroup);
3660
+ }
3661
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentTaskFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3662
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: AgentTaskFormComponent, isStandalone: true, selector: "agent-task-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n <input pInputText id=\"task\" [formControl]=\"formGroup.controls?.task\" class=\"w-full\" />\n </div>\n } @if(formGroup.controls?.expectedResponseType) {\n <div class=\"form-field\">\n <label for=\"expectedResponseType\" class=\"block text-sm font-medium text-gray-700\">Expected Response Type</label>\n <input pInputText id=\"expectedResponseType\" type=\"text\" [formControl]=\"formGroup.controls?.expectedResponseType\" class=\"w-full\" />\n </div>\n } @if (formGroup.controls?.modelQuality) {\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Model Quality</label>\n <p-dropdown\n id=\"modelQuality\"\n [options]=\"modelQualityOptions\"\n [formControl]=\"formGroup.controls?.modelQuality\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-dropdown>\n </div>\n } @if (formGroup.controls?.systemPrompt) {\n <div class=\"form-field\">\n <label for=\"systemPrompt\" class=\"block text-sm font-medium text-gray-700 mb-1\">System Prompt</label>\n <input pInputText id=\"systemPrompt\" [formControl]=\"formGroup.controls?.systemPrompt\" class=\"w-full\" />\n </div>\n }\n</div>\n", styles: [":host{display:block}.form-field{margin:0}\n"], dependencies: [{ kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i3$2.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
3663
+ }
3664
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: AgentTaskFormComponent, decorators: [{
3665
+ type: Component,
3666
+ args: [{ selector: 'agent-task-form', imports: [TextareaModule, InputTextModule, ReactiveFormsModule, DropdownModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [formGroup]=\"formGroup\" class=\"space-y-6 p-4\">\n @if(formGroup.controls?.task) {\n <div class=\"form-field\">\n <label for=\"task\" class=\"block text-sm font-medium text-gray-700\">Task</label>\n <input pInputText id=\"task\" [formControl]=\"formGroup.controls?.task\" class=\"w-full\" />\n </div>\n } @if(formGroup.controls?.expectedResponseType) {\n <div class=\"form-field\">\n <label for=\"expectedResponseType\" class=\"block text-sm font-medium text-gray-700\">Expected Response Type</label>\n <input pInputText id=\"expectedResponseType\" type=\"text\" [formControl]=\"formGroup.controls?.expectedResponseType\" class=\"w-full\" />\n </div>\n } @if (formGroup.controls?.modelQuality) {\n <div class=\"form-field\">\n <label for=\"modelQuality\" class=\"block text-sm font-medium text-gray-700\">Model Quality</label>\n <p-dropdown\n id=\"modelQuality\"\n [options]=\"modelQualityOptions\"\n [formControl]=\"formGroup.controls?.modelQuality\"\n placeholder=\"Select a Quality\"\n optionLabel=\"label\"\n optionValue=\"value\"\n class=\"w-full\"></p-dropdown>\n </div>\n } @if (formGroup.controls?.systemPrompt) {\n <div class=\"form-field\">\n <label for=\"systemPrompt\" class=\"block text-sm font-medium text-gray-700 mb-1\">System Prompt</label>\n <input pInputText id=\"systemPrompt\" [formControl]=\"formGroup.controls?.systemPrompt\" class=\"w-full\" />\n </div>\n }\n</div>\n", styles: [":host{display:block}.form-field{margin:0}\n"] }]
3667
+ }], propDecorators: { formGroup: [{
3668
+ type: Input
3669
+ }] } });
3670
+
3671
+ class DCConversationFlowFormComponent {
3672
+ constructor() {
3673
+ this.formGroupService = inject(FormGroupService);
3674
+ this.entityWhatOptions = EntityWhatOptions;
3675
+ this.entityWhenOptions = EntityWhenOptions;
3676
+ this.formGroup = this.formGroupService.createConversationFlowFormGroup();
3677
+ this.conversationEvents = ConversationEvents;
3678
+ this.objectKeys = Object.keys;
3679
+ }
3680
+ ngOnInit() {
3681
+ if (!this.formGroup) {
3682
+ throw new Error('DCConversationFlowFormComponent requires a formGroup input.');
3683
+ }
3684
+ }
3685
+ get dynamicConditionsArray() {
3686
+ return this.formGroup.controls.dynamicConditions;
3687
+ }
3688
+ addDynamicCondition() {
3689
+ this.dynamicConditionsArray.push(this.formGroupService.createDynamicConditionFormGroup());
3690
+ }
3691
+ removeDynamicCondition(index) {
3692
+ this.dynamicConditionsArray.removeAt(index);
3693
+ }
3694
+ // Helper to get controls for the template to iterate
3695
+ getDynamicConditionsControls() {
3696
+ return this.dynamicConditionsArray.controls;
3697
+ }
3698
+ // Helper to safely cast to FormControl for the template
3699
+ getFormControl(control) {
3700
+ if (!(control instanceof FormControl)) {
3701
+ // This case should ideally not happen if types are correct,
3702
+ // but it's a safeguard.
3703
+ console.error('Expected a FormControl, but received:', control);
3704
+ // Return a dummy FormControl or handle error appropriately
3705
+ return new FormControl(null);
3706
+ }
3707
+ return control;
3512
3708
  }
3709
+ showData() {
3710
+ console.log(this.formGroup.value);
3711
+ }
3712
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationFlowFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3713
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationFlowFormComponent, isStandalone: true, selector: "dc-conversation-flow-form", inputs: { formGroup: "formGroup" }, ngImport: i0, template: "<div [formGroup]=\"formGroup\" class=\"group\">\n <h3>Conversation Flow <span pTooltip=\"Define the flow and logic of the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\">Goal <span pTooltip=\"The main objective of this conversation flow\">\u2139\uFE0F</span></label>\n\n <agent-task-form [formGroup]=\"formGroup.controls.goal\"></agent-task-form>\n </div>\n\n <details>\n <summary>Trigger Tasks</summary>\n\n <div formGroupName=\"triggerTasks\" class=\"group\">\n <h4>Trigger Tasks <span (click)=\"showData()\" pTooltip=\"Tasks to be executed on specific conversation events\">\u2139\uFE0F</span></h4>\n @for (eventKey of objectKeys(formGroup.controls.triggerTasks.controls); track eventKey) {\n <!-- {{ eventKey }} -->\n <div class=\"form-field\">\n <label [for]=\"eventKey\">{{ eventKey }}</label>\n <agent-task-form [formGroup]=\"formGroup.controls.triggerTasks.controls[eventKey]\"></agent-task-form>\n </div>\n }\n\n <!-- <div [formGroupName]=\"eventKey\" class=\"group nested-group\">\n <h5>{{ conversationEvents[eventKey] }} <span pTooltip=\"Task for {{ conversationEvents[eventKey] }} event\">\u2139\uFE0F</span></h5>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'SystemPrompt'\">System Prompt</label>\n <textarea pTextarea [autoResize]=\"true\" [id]=\"eventKey + 'SystemPrompt'\" formControlName=\"systemPrompt\"></textarea>\n </div>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'Task'\">Task</label>\n <textarea pTextarea [autoResize]=\"true\" [id]=\"eventKey + 'Task'\" formControlName=\"task\"></textarea>\n </div>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'ExpectedResponseType'\">Expected Response Type</label>\n <input pInputText [id]=\"eventKey + 'ExpectedResponseType'\" type=\"text\" formControlName=\"expectedResponseType\" />\n </div>\n </div> -->\n </div>\n </details>\n\n <div class=\"form-field\">\n <label for=\"flowBonus\">Bonus <span pTooltip=\"Bonus information or context (e.g., JSON string)\">\u2139\uFE0F</span></label>\n <input id=\"flowBonus\" formControlName=\"bonus\" />\n </div>\n\n <div formArrayName=\"dynamicConditions\" class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of getDynamicConditionsControls(); track conditionControl; let i = $index) {\n <div [formGroupName]=\"i\" class=\"group nested-group dynamic-condition-item\">\n <h5>Condition {{ i + 1 }}</h5>\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n\n <p-select\n id=\"lang\"\n [options]=\"entityWhatOptions\"\n formControlName=\"what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n\n <!-- <p-dropdown [options]=\"entityWhatOptions\" formControlName=\"what\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select What\"></p-dropdown> -->\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n\n <p-select\n id=\"lang\"\n [options]=\"entityWhenOptions\"\n formControlName=\"when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n\n <!-- <p-dropdown [options]=\"entityWhenOptions\" formControlName=\"when\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select When\"></p-dropdown> -->\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\" formControlName=\"value\" />\n </div>\n <!-- The 'then' FormControl is not directly rendered here as it's an any[] type.\n If it's meant to hold specific structured data to be rendered,\n its type and rendering logic would need to be adjusted.\n The task to execute is handled by the 'task' FormGroup below. -->\n\n <div formGroupName=\"task\" class=\"group very-nested-group\">\n <h6>Task <span pTooltip=\"Task to execute if this condition is met\">\u2139\uFE0F</span></h6>\n <agent-task-form [formGroup]=\"conditionControl.controls.task\"></agent-task-form>\n </div>\n <button pButton type=\"button\" severity=\"danger\" label=\"Remove Condition\" (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n </div>\n</div>\n", styles: [".nested-group{border:1px solid #eee;padding:10px;margin-top:10px;border-radius:4px}.very-nested-group{border:1px dashed #ccc;padding:8px;margin-top:8px;border-radius:4px}.dynamic-condition-item{margin-bottom:15px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "directive", type: i1.FormArrayName, selector: "[formArrayName]", inputs: ["formArrayName"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: AgentTaskFormComponent, selector: "agent-task-form", inputs: ["formGroup"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }] }); }
3714
+ }
3715
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationFlowFormComponent, decorators: [{
3716
+ type: Component,
3717
+ args: [{ selector: 'dc-conversation-flow-form', standalone: true, imports: [CommonModule, ReactiveFormsModule, ButtonModule, InputTextModule, TextareaModule, TooltipModule, AgentTaskFormComponent, SelectModule], template: "<div [formGroup]=\"formGroup\" class=\"group\">\n <h3>Conversation Flow <span pTooltip=\"Define the flow and logic of the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"flowGoal\">Goal <span pTooltip=\"The main objective of this conversation flow\">\u2139\uFE0F</span></label>\n\n <agent-task-form [formGroup]=\"formGroup.controls.goal\"></agent-task-form>\n </div>\n\n <details>\n <summary>Trigger Tasks</summary>\n\n <div formGroupName=\"triggerTasks\" class=\"group\">\n <h4>Trigger Tasks <span (click)=\"showData()\" pTooltip=\"Tasks to be executed on specific conversation events\">\u2139\uFE0F</span></h4>\n @for (eventKey of objectKeys(formGroup.controls.triggerTasks.controls); track eventKey) {\n <!-- {{ eventKey }} -->\n <div class=\"form-field\">\n <label [for]=\"eventKey\">{{ eventKey }}</label>\n <agent-task-form [formGroup]=\"formGroup.controls.triggerTasks.controls[eventKey]\"></agent-task-form>\n </div>\n }\n\n <!-- <div [formGroupName]=\"eventKey\" class=\"group nested-group\">\n <h5>{{ conversationEvents[eventKey] }} <span pTooltip=\"Task for {{ conversationEvents[eventKey] }} event\">\u2139\uFE0F</span></h5>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'SystemPrompt'\">System Prompt</label>\n <textarea pTextarea [autoResize]=\"true\" [id]=\"eventKey + 'SystemPrompt'\" formControlName=\"systemPrompt\"></textarea>\n </div>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'Task'\">Task</label>\n <textarea pTextarea [autoResize]=\"true\" [id]=\"eventKey + 'Task'\" formControlName=\"task\"></textarea>\n </div>\n <div class=\"form-field\">\n <label [for]=\"eventKey + 'ExpectedResponseType'\">Expected Response Type</label>\n <input pInputText [id]=\"eventKey + 'ExpectedResponseType'\" type=\"text\" formControlName=\"expectedResponseType\" />\n </div>\n </div> -->\n </div>\n </details>\n\n <div class=\"form-field\">\n <label for=\"flowBonus\">Bonus <span pTooltip=\"Bonus information or context (e.g., JSON string)\">\u2139\uFE0F</span></label>\n <input id=\"flowBonus\" formControlName=\"bonus\" />\n </div>\n\n <div formArrayName=\"dynamicConditions\" class=\"group\">\n <h4>Dynamic Conditions <span pTooltip=\"Conditions that trigger tasks based on conversation state\">\u2139\uFE0F</span></h4>\n @for (conditionControl of getDynamicConditionsControls(); track conditionControl; let i = $index) {\n <div [formGroupName]=\"i\" class=\"group nested-group dynamic-condition-item\">\n <h5>Condition {{ i + 1 }}</h5>\n <div class=\"form-field\">\n <label [for]=\"'conditionWhat' + i\">What <span pTooltip=\"Identifier for this condition (optional)\">\u2139\uFE0F</span></label>\n\n <p-select\n id=\"lang\"\n [options]=\"entityWhatOptions\"\n formControlName=\"what\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select What'\"></p-select>\n\n <!-- <p-dropdown [options]=\"entityWhatOptions\" formControlName=\"what\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select What\"></p-dropdown> -->\n </div>\n <div class=\"form-field\">\n <label [for]=\"'conditionWhen' + i\">When <span pTooltip=\"Field or variable to check\">\u2139\uFE0F</span></label>\n\n <p-select\n id=\"lang\"\n [options]=\"entityWhenOptions\"\n formControlName=\"when\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select When'\"></p-select>\n\n <!-- <p-dropdown [options]=\"entityWhenOptions\" formControlName=\"when\" optionLabel=\"label\" optionValue=\"value\" placeholder=\"Select When\"></p-dropdown> -->\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\" formControlName=\"value\" />\n </div>\n <!-- The 'then' FormControl is not directly rendered here as it's an any[] type.\n If it's meant to hold specific structured data to be rendered,\n its type and rendering logic would need to be adjusted.\n The task to execute is handled by the 'task' FormGroup below. -->\n\n <div formGroupName=\"task\" class=\"group very-nested-group\">\n <h6>Task <span pTooltip=\"Task to execute if this condition is met\">\u2139\uFE0F</span></h6>\n <agent-task-form [formGroup]=\"conditionControl.controls.task\"></agent-task-form>\n </div>\n <button pButton type=\"button\" severity=\"danger\" label=\"Remove Condition\" (click)=\"removeDynamicCondition(i)\"></button>\n </div>\n }\n <button pButton type=\"button\" severity=\"info\" label=\"Add Dynamic Condition\" (click)=\"addDynamicCondition()\"></button>\n </div>\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"] }]
3718
+ }], propDecorators: { formGroup: [{
3719
+ type: Input
3720
+ }] } });
3721
+
3722
+ class DcCharacterCardFormComponent {
3513
3723
  constructor() {
3724
+ this.generateMissingDataRequest = new EventEmitter();
3725
+ this.fb = inject(FormBuilder);
3726
+ this.cdr = inject(ChangeDetectorRef);
3727
+ this.agentCardService = inject(CONVERSATION_AI_TOKEN);
3728
+ this.toastService = inject(TOAST_ALERTS_TOKEN, { optional: true });
3729
+ this.markdownForm = this.fb.group({ seeMarkdown: [false] });
3730
+ this.isGenerating = false; // For improveFirstMessage loading state
3731
+ }
3732
+ get dataGroup() {
3733
+ return this.characterCardForm.get('data');
3734
+ }
3735
+ get alternateGreetingsArray() {
3736
+ return this.dataGroup.get('alternate_greetings');
3737
+ }
3738
+ get tagsArray() {
3739
+ return this.dataGroup.get('tags');
3740
+ }
3741
+ ngOnInit() {
3742
+ if (!this.characterCardForm) {
3743
+ console.error('CharacterCardFormComponent expects an FormGroup instance.');
3744
+ // Potentially initialize a default form group here if appropriate
3745
+ // or throw an error to ensure parent component provides it.
3746
+ }
3747
+ // Initialize markdownForm listener if needed, similar to parent
3748
+ this.markdownForm.get('seeMarkdown')?.valueChanges.subscribe(() => {
3749
+ this.cdr.detectChanges();
3750
+ });
3751
+ }
3752
+ checkCdr() {
3753
+ this.cdr.detectChanges();
3754
+ }
3755
+ addArrayItem(controlPath) {
3756
+ const control = this.characterCardForm.get(`data.${controlPath}`);
3757
+ if (control) {
3758
+ control.push(this.fb.control(''));
3759
+ this.cdr.detectChanges();
3760
+ }
3761
+ }
3762
+ removeArrayItem(controlPath, index) {
3763
+ const control = this.characterCardForm.get(`data.${controlPath}`);
3764
+ if (control) {
3765
+ control.removeAt(index);
3766
+ this.cdr.detectChanges();
3767
+ }
3768
+ }
3769
+ updateArrayField(controlPath, index, event) {
3770
+ const control = this.characterCardForm.get(`data.${controlPath}`);
3771
+ if (control instanceof FormArray && event.target instanceof HTMLInputElement) {
3772
+ const formControlAtIndex = control.at(index);
3773
+ if (formControlAtIndex) {
3774
+ formControlAtIndex.setValue(event.target.value);
3775
+ }
3776
+ }
3777
+ else if (control instanceof FormArray && event.target instanceof HTMLTextAreaElement) {
3778
+ // Handle textarea
3779
+ const formControlAtIndex = control.at(index);
3780
+ if (formControlAtIndex) {
3781
+ formControlAtIndex.setValue(event.target.value);
3782
+ }
3783
+ }
3784
+ }
3785
+ async improveFirstMessage() {
3786
+ const confirmImprove = window.confirm('Are you sure you want to improve the first message? It might be shortened.');
3787
+ if (!confirmImprove) {
3788
+ return;
3789
+ }
3790
+ this.isGenerating = true;
3791
+ if (this.toastService) {
3792
+ this.toastService.info({ title: 'Improving Message', subtitle: 'Please wait...' });
3793
+ }
3794
+ const characterData = this.characterCardForm.get('data')?.value;
3795
+ if (!characterData) {
3796
+ if (this.toastService) {
3797
+ this.toastService.error({ title: 'Error', subtitle: 'Character data not found.' });
3798
+ }
3799
+ this.isGenerating = false;
3800
+ return;
3801
+ }
3802
+ const systemPrompt = `You are an expert in roleplay. Your task is to improve and shorten the provided first message for a conversation, ensuring it is at most 2 paragraphs. Use the following character information as context:
3803
+ Character Name: ${characterData.name}
3804
+ Description: ${characterData.description}
3805
+ Scenario: ${characterData.scenario}
3806
+
3807
+ Improve the following first message:`;
3808
+ const messages = [
3809
+ { role: ChatRole.System, content: systemPrompt },
3810
+ { role: ChatRole.User, content: characterData.first_mes },
3811
+ ];
3812
+ try {
3813
+ const response = await this.agentCardService.callChatCompletion({ messages, model: { provider: 'google' } }); // Assuming default textEngine and conversationType are fine or not needed here
3814
+ const improvedMessage = extractJsonFromResponse(response.content) || response.content; // Try to extract JSON, fallback to raw content
3815
+ if (improvedMessage) {
3816
+ this.characterCardForm.get('data.first_mes')?.setValue(typeof improvedMessage === 'string' ? improvedMessage : JSON.stringify(improvedMessage));
3817
+ if (this.toastService) {
3818
+ this.toastService.success({ title: 'First message improved', subtitle: 'Remember to save changes if you are sure' });
3819
+ }
3820
+ }
3821
+ else {
3822
+ if (this.toastService) {
3823
+ this.toastService.error({
3824
+ title: 'Something went wrong :/',
3825
+ subtitle: "The information could not be extracted correctly, but don't worry, you can try again",
3826
+ });
3827
+ }
3828
+ }
3829
+ }
3830
+ catch (error) {
3831
+ console.error('Error improving first message:', error);
3832
+ if (this.toastService) {
3833
+ this.toastService.error({ title: 'API Error', subtitle: 'Failed to improve first message.' });
3834
+ }
3835
+ }
3836
+ finally {
3837
+ this.isGenerating = false;
3838
+ this.cdr.detectChanges();
3839
+ }
3840
+ }
3841
+ asFormControl(control) {
3842
+ return control;
3843
+ }
3844
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcCharacterCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3845
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DcCharacterCardFormComponent, isStandalone: true, selector: "dc-character-card-form", inputs: { characterCardForm: "characterCardForm" }, outputs: { generateMissingDataRequest: "generateMissingDataRequest" }, ngImport: i0, template: "<div [formGroup]=\"characterCardForm\" class=\"p-6 bg-gray-50 min-h-screen\">\n <div formGroupName=\"data\" class=\"card-group space-y-6 bg-white p-8 rounded-lg shadow-md\">\n <div class=\"flex justify-end\">\n <p-button\n (click)=\"generateMissingDataRequest.emit()\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\"\n label=\"Arreglar Campos\"\n styleClass=\"p-button-sm\" />\n </div>\n\n <h3 class=\"text-2xl font-semibold text-gray-700 mb-6\"\n >Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></h3\n >\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Name <span pTooltip=\"El nombre del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <input\n pInputText\n id=\"cardName\"\n type=\"text\"\n formControlName=\"name\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" />\n @if (dataGroup.controls['name']?.errors?.['required'] && dataGroup.controls['name']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardDescription\" class=\"block text-sm font-medium text-gray-700\"\n >Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n class=\"textmin mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"\n rows=\"3\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardDescription\"\n formControlName=\"description\"></textarea>\n @if (dataGroup.controls['description']?.errors?.['required'] && dataGroup.controls['description']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardScenario\" class=\"block text-sm font-medium text-gray-700\"\n >Scenario <span pTooltip=\"Describe the context or setting for the conversation\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardScenario\"\n formControlName=\"scenario\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >First Message\n <span\n pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></span\n >\n <div class=\"flex items-center space-x-2\">\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown'\"\n size=\"small\"\n styleClass=\"min-w-16 p-button-sm\"\n (onChange)=\"checkCdr()\" />\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\" styleClass=\"p-button-sm p-button-outlined\"></p-button>\n </div>\n </div>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"dataGroup.controls['first_mes'].value | mdToHtmlArray\" class=\"prose mt-1 p-3 border border-gray-200 rounded-md bg-gray-50\"></div>\n }@else{\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardFirstMessage\"\n formControlName=\"first_mes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\">\n </textarea>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"mes_example\" class=\"block text-sm font-medium text-gray-700\"\n >Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"mes_example\"\n formControlName=\"mes_example\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardCreatorNotes\" class=\"block text-sm font-medium text-gray-700\"\n >Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardCreatorNotes\"\n formControlName=\"creator_notes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardSystemPrompt\" class=\"block text-sm font-medium text-gray-700\"\n >System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardSystemPrompt\"\n formControlName=\"system_prompt\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n @if (dataGroup.controls['system_prompt']?.errors?.['required'] && dataGroup.controls['system_prompt']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> System prompt is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label class=\"block text-sm font-medium text-gray-700\">Image Description</label>\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"picture_description\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardPostHistoryInstructions\" class=\"block text-sm font-medium text-gray-700\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"post_history_instructions\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field space-y-2\">\n @for (greeting of alternateGreetingsArray.controls; track greeting; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"asFormControl(greeting)\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\">\n </textarea>\n <button\n pButton\n severity=\"danger\"\n icon=\"pi pi-times\"\n class=\"remove-button p-button-sm p-button-rounded p-button-danger\"\n (click)=\"removeArrayItem('alternate_greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('alternate_greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium text-gray-700\">Tags \u2139\uFE0F</label>\n <div class=\"array-field space-y-2\">\n @for (tag of tagsArray.controls; track tag; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\">\n <input\n pInputText\n [id]=\"'cardTag' + i\"\n type=\"text\"\n [formControl]=\"asFormControl(tag)\"\n (input)=\"updateArrayField('tags', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\" />\n <button pButton severity=\"danger\" label=\"Remove\" icon=\"pi pi-times\" (click)=\"removeArrayItem('tags', i)\" class=\"p-button-sm\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Tag\" icon=\"pi pi-plus\" (click)=\"addArrayItem('tags')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".textmin{min-height:40px}.array-field{display:flex;flex-direction:column;gap:8px}.array-item{display:flex;align-items:center;gap:8px;position:relative}.array-item textarea,.array-item input[type=text]{flex-grow:1}.remove-button{position:absolute;right:5px;top:5px;min-width:auto!important;width:2rem;height:2rem}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "disabled", "style", "styleClass", "inputId", "tabindex", "size", "iconPos", "autofocus", "allowEmpty"], outputs: ["onChange"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }] }); }
3846
+ }
3847
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DcCharacterCardFormComponent, decorators: [{
3848
+ type: Component,
3849
+ args: [{ selector: 'dc-character-card-form', standalone: true, imports: [ReactiveFormsModule, FormsModule, ButtonModule, InputTextModule, TextareaModule, TooltipModule, ToggleButtonModule, MdToHtmlArrayPipe], template: "<div [formGroup]=\"characterCardForm\" class=\"p-6 bg-gray-50 min-h-screen\">\n <div formGroupName=\"data\" class=\"card-group space-y-6 bg-white p-8 rounded-lg shadow-md\">\n <div class=\"flex justify-end\">\n <p-button\n (click)=\"generateMissingDataRequest.emit()\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\"\n label=\"Arreglar Campos\"\n styleClass=\"p-button-sm\" />\n </div>\n\n <h3 class=\"text-2xl font-semibold text-gray-700 mb-6\"\n >Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></h3\n >\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardName\" class=\"block text-sm font-medium text-gray-700\"\n >Name <span pTooltip=\"El nombre del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <input\n pInputText\n id=\"cardName\"\n type=\"text\"\n formControlName=\"name\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\" />\n @if (dataGroup.controls['name']?.errors?.['required'] && dataGroup.controls['name']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardDescription\" class=\"block text-sm font-medium text-gray-700\"\n >Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n class=\"textmin mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"\n rows=\"3\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardDescription\"\n formControlName=\"description\"></textarea>\n @if (dataGroup.controls['description']?.errors?.['required'] && dataGroup.controls['description']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardScenario\" class=\"block text-sm font-medium text-gray-700\"\n >Scenario <span pTooltip=\"Describe the context or setting for the conversation\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardScenario\"\n formControlName=\"scenario\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardFirstMessage\" class=\"flex flex-col text-sm font-medium text-gray-700\">\n <div class=\"flex justify-between items-center\">\n <span\n >First Message\n <span\n pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></span\n >\n <div class=\"flex items-center space-x-2\">\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown'\"\n size=\"small\"\n styleClass=\"min-w-16 p-button-sm\"\n (onChange)=\"checkCdr()\" />\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\" styleClass=\"p-button-sm p-button-outlined\"></p-button>\n </div>\n </div>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"dataGroup.controls['first_mes'].value | mdToHtmlArray\" class=\"prose mt-1 p-3 border border-gray-200 rounded-md bg-gray-50\"></div>\n }@else{\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardFirstMessage\"\n formControlName=\"first_mes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\">\n </textarea>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"mes_example\" class=\"block text-sm font-medium text-gray-700\"\n >Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"mes_example\"\n formControlName=\"mes_example\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardCreatorNotes\" class=\"block text-sm font-medium text-gray-700\"\n >Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardCreatorNotes\"\n formControlName=\"creator_notes\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardSystemPrompt\" class=\"block text-sm font-medium text-gray-700\"\n >System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n id=\"cardSystemPrompt\"\n formControlName=\"system_prompt\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n @if (dataGroup.controls['system_prompt']?.errors?.['required'] && dataGroup.controls['system_prompt']?.touched) {\n <div class=\"error text-red-500 text-xs mt-1\"> System prompt is required </div>\n }\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label class=\"block text-sm font-medium text-gray-700\">Image Description</label>\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"picture_description\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardPostHistoryInstructions\" class=\"block text-sm font-medium text-gray-700\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n class=\"text-blue-500 cursor-pointer\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea\n rows=\"2\"\n pTextarea\n [autoResize]=\"true\"\n formControlName=\"post_history_instructions\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm\"></textarea>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label for=\"cardAlternateGreetings\" class=\"block text-sm font-medium text-gray-700\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\" class=\"text-blue-500 cursor-pointer\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field space-y-2\">\n @for (greeting of alternateGreetingsArray.controls; track greeting; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"asFormControl(greeting)\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\">\n </textarea>\n <button\n pButton\n severity=\"danger\"\n icon=\"pi pi-times\"\n class=\"remove-button p-button-sm p-button-rounded p-button-danger\"\n (click)=\"removeArrayItem('alternate_greetings', i)\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Greeting\" icon=\"pi pi-plus\" (click)=\"addArrayItem('alternate_greetings')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n\n <div class=\"form-field grid grid-cols-1 gap-2\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\" class=\"block text-sm font-medium text-gray-700\">Tags \u2139\uFE0F</label>\n <div class=\"array-field space-y-2\">\n @for (tag of tagsArray.controls; track tag; let i = $index) {\n <div class=\"array-item flex items-center space-x-2\">\n <input\n pInputText\n [id]=\"'cardTag' + i\"\n type=\"text\"\n [formControl]=\"asFormControl(tag)\"\n (input)=\"updateArrayField('tags', i, $event)\"\n class=\"mt-1 block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm flex-grow\" />\n <button pButton severity=\"danger\" label=\"Remove\" icon=\"pi pi-times\" (click)=\"removeArrayItem('tags', i)\" class=\"p-button-sm\"></button>\n </div>\n }\n <button pButton severity=\"info\" label=\"Add Tag\" icon=\"pi pi-plus\" (click)=\"addArrayItem('tags')\" class=\"p-button-sm\"></button>\n </div>\n </div>\n </div>\n</div>\n", styles: [".textmin{min-height:40px}.array-field{display:flex;flex-direction:column;gap:8px}.array-item{display:flex;align-items:center;gap:8px;position:relative}.array-item textarea,.array-item input[type=text]{flex-grow:1}.remove-button{position:absolute;right:5px;top:5px;min-width:auto!important;width:2rem;height:2rem}\n"] }]
3850
+ }], propDecorators: { characterCardForm: [{
3851
+ type: Input,
3852
+ args: [{ required: true }]
3853
+ }], generateMissingDataRequest: [{
3854
+ type: Output
3855
+ }] } });
3856
+
3857
+ class DCAgentCardFormComponent {
3858
+ constructor() {
3859
+ // Services
3514
3860
  this.fb = inject(FormBuilder);
3515
3861
  this.storageService = inject(MultiImagesStorageService);
3516
3862
  this.agentCardService = inject(CONVERSATION_AI_TOKEN);
@@ -3521,6 +3867,7 @@ class DCAgentCardFormComponent {
3521
3867
  this.promptBuilder = inject(DCConversationPromptBuilderService);
3522
3868
  this.toastService = inject(TOAST_ALERTS_TOKEN, { optional: true });
3523
3869
  this.defaultAgentCardService = inject(DefaultAgentCardsService);
3870
+ this.formGroupService = inject(FormGroupService);
3524
3871
  // select options
3525
3872
  this.textEngines = Object.values(TextEngines);
3526
3873
  this.conversationOptions = ConversationTypeOptions;
@@ -3528,6 +3875,8 @@ class DCAgentCardFormComponent {
3528
3875
  this.textEngineOptions = TextEngineOptions;
3529
3876
  this.accountsOptions = Object.values(EAccountsPlatform);
3530
3877
  this.languageOptions = Object.entries(LangCodeDescriptionEs).map(([value, label]) => ({ value, label }));
3878
+ this.conversationEvents = ConversationEvents;
3879
+ this.objectKeys = Object.keys;
3531
3880
  this.agentCardId = this.activatedRoute.snapshot.paramMap.get('id');
3532
3881
  this.audioSpeedOptions = Object.values(AudioSpeed$1).map((speed) => ({ label: speed, value: speed }));
3533
3882
  this.storageSettings = input(this.getSettings());
@@ -3550,49 +3899,32 @@ class DCAgentCardFormComponent {
3550
3899
  this.onSave = output();
3551
3900
  this.onGoDetails = output();
3552
3901
  this.onTranslate = output();
3553
- this.markdownForm = this.fb.group({ seeMarkdown: [false] });
3554
3902
  // Type is IAgentCard
3555
3903
  this.form = this.fb.group({
3556
3904
  version: ['1.0'],
3557
3905
  id: [''],
3558
3906
  title: [''],
3559
- characterCard: this.fb.group({
3560
- data: this.fb.group({
3561
- name: [''],
3562
- description: [''],
3563
- scenario: [''],
3564
- first_mes: [''],
3565
- creator_notes: [''],
3566
- mes_example: [''],
3567
- alternate_greetings: this.fb.array([]),
3568
- tags: this.fb.array([]),
3569
- picture_description: [''],
3570
- system_prompt: [''],
3571
- post_history_instructions: [''],
3572
- }),
3573
- }),
3574
- conversationSettings: this.fb.group({
3575
- textEngine: [TextEngines.SimpleText],
3576
- conversationType: [ConversationType.General],
3577
- autoStart: [true],
3578
- tts: this.fb.group({ voice: [''], secondaryVoice: [''], speed: ['1.0'], speedRate: [1.0] }),
3579
- }),
3580
3907
  lang: [''],
3581
- metaApp: this.fb.group({ isPublished: [false], isPublic: [false], authorId: [''], authorEmail: [''], takenCount: [0] }),
3582
- model: this.fb.group({ id: [''], modelName: [''], provider: [''] }),
3908
+ characterCard: this.formGroupService.createCharacterCardFormGroup(),
3909
+ conversationSettings: this.formGroupService.createConversationSettingFormGroup(),
3910
+ metaApp: this.formGroupService.createMetaFormGroup(),
3911
+ model: this.formGroupService.createModelFormGroup(),
3583
3912
  accounts: this.fb.array([]),
3913
+ conversationFlow: this.formGroupService.createConversationFlowFormGroup(),
3584
3914
  });
3585
3915
  this.isGenerating = false;
3586
3916
  }
3917
+ getSettings() {
3918
+ const imageSettings = {
3919
+ path: 'conversation-cards/' + this.agentCardId,
3920
+ fileName: '',
3921
+ cropSettings: { aspectRatio: AspectType.Vertical_9_16, resolutions: [ResolutionType.MediumLarge], resizeToWidth: 450 },
3922
+ };
3923
+ return imageSettings;
3924
+ }
3587
3925
  ngOnInit() {
3588
- this.form.controls.conversationSettings.controls.autoStart;
3589
- console.log('form', this.form.value, this.conversationOptions);
3590
3926
  this.imageSettings = this.storageSettings().cropSettings;
3591
3927
  this.loadConversationCard();
3592
- this.markdownForm.get('checked')?.valueChanges.subscribe((value) => {
3593
- this.markdownForm.patchValue({ seeMarkdown: value }, { emitEvent: false });
3594
- this.cdr.detectChanges();
3595
- });
3596
3928
  }
3597
3929
  async loadConversationCard() {
3598
3930
  if (this.agentCardId) {
@@ -3600,7 +3932,7 @@ class DCAgentCardFormComponent {
3600
3932
  this.conversation = await this.agentCardService.findConversationCardByID(this.agentCardId);
3601
3933
  if (this.conversation) {
3602
3934
  this.patchFormWithConversationData();
3603
- this.handleAlternateGreetings();
3935
+ this.handleArrayForms();
3604
3936
  }
3605
3937
  this.storageSettings().path = 'conversation-cards/' + this.agentCardId;
3606
3938
  this.cdr.detectChanges();
@@ -3615,63 +3947,20 @@ class DCAgentCardFormComponent {
3615
3947
  }
3616
3948
  }
3617
3949
  patchFormWithConversationData() {
3618
- const defaultData = {
3619
- version: '1.0',
3620
- id: '',
3621
- title: '',
3622
- characterCard: {
3623
- data: {
3624
- name: '',
3625
- description: '',
3626
- scenario: '',
3627
- first_mes: '',
3628
- creator_notes: '',
3629
- mes_example: '',
3630
- alternate_greetings: [],
3631
- tags: [],
3632
- system_prompt: '',
3633
- post_history_instructions: '',
3634
- },
3635
- },
3636
- textEngine: TextEngines.SimpleText,
3637
- conversationType: ConversationType.Challenge,
3638
- lang: '',
3639
- tts: {
3640
- voice: '',
3641
- secondaryVoice: '',
3642
- speed: '1.0',
3643
- speedRate: 1.0,
3644
- },
3645
- metaApp: {
3646
- isPublished: false,
3647
- isPublic: false,
3648
- authorId: '',
3649
- authorEmail: '',
3650
- takenCount: 0,
3651
- },
3652
- };
3653
- const conversationData = this.conversation || {};
3654
- const mergedData = {
3655
- ...defaultData,
3656
- ...conversationData,
3657
- characterCard: {
3658
- data: {
3659
- ...defaultData.characterCard.data,
3660
- ...conversationData.characterCard?.data,
3661
- },
3662
- },
3663
- tts: {
3664
- ...defaultData.tts,
3665
- ...conversationData.tts,
3666
- },
3667
- metaApp: {
3668
- ...defaultData.metaApp,
3669
- ...conversationData.metaApp,
3670
- },
3671
- };
3672
- this.form.patchValue(mergedData);
3673
- }
3674
- handleAlternateGreetings() {
3950
+ // Ensure conversationFlow and its sub-properties are initialized if not present
3951
+ // const conversationFlowData: Partial<IConversationFlow> = this.conversation?.conversationFlow || {};
3952
+ this.form.patchValue(this.conversation);
3953
+ // Patch dynamicConditions FormArray after the main form is patched
3954
+ const dynamicConditionsFormArray = this.form.get('conversationFlow.dynamicConditions');
3955
+ dynamicConditionsFormArray.clear(); // Clear any existing default items
3956
+ // if (this.conversation.conversationFlow?.dynamicConditions?.length) {
3957
+ // this.conversation.conversationFlow.dynamicConditions.forEach((condition: DynamicCondition) => {
3958
+ // dynamicConditionsFormArray.push(this.createDynamicConditionFormGroup(condition));
3959
+ // });
3960
+ // }
3961
+ }
3962
+ handleArrayForms() {
3963
+ // If not posible to patch arrays if control does not exist, that why they are created dinamycally depending on the data.
3675
3964
  const alternateGreetingsFormArray = this.form.get('characterCard.data.alternate_greetings');
3676
3965
  alternateGreetingsFormArray.clear();
3677
3966
  if (this.conversation.characterCard.data.alternate_greetings?.length) {
@@ -3679,8 +3968,16 @@ class DCAgentCardFormComponent {
3679
3968
  alternateGreetingsFormArray.push(this.fb.control(greeting));
3680
3969
  });
3681
3970
  }
3971
+ debugger;
3972
+ if (this.conversation.conversationFlow?.dynamicConditions?.length) {
3973
+ const dynamicConditionsFormArray = this.form.get('conversationFlow.dynamicConditions');
3974
+ this.conversation.conversationFlow.dynamicConditions.forEach((condition) => {
3975
+ dynamicConditionsFormArray.push(this.formGroupService.createDynamicConditionFormGroup(condition));
3976
+ });
3977
+ }
3682
3978
  }
3683
3979
  async saveConversation() {
3980
+ debugger;
3684
3981
  if (this.form.valid) {
3685
3982
  console.log(this.form.value);
3686
3983
  const data = { ...this.form.value, _id: this.agentCardId };
@@ -3738,8 +4035,8 @@ class DCAgentCardFormComponent {
3738
4035
  jsonData.data.alternate_greetings.forEach((_) => {
3739
4036
  this.form.get('characterCard.data.alternate_greetings').push(this.fb.control(''));
3740
4037
  });
3741
- this.form.controls.conversationSettings.controls.conversationType.setValue(ConversationType.RolePlay);
3742
- this.form.controls.conversationSettings.controls.textEngine.setValue(TextEngines.MarkdownMultiMessages);
4038
+ this.form.controls.conversationSettings.controls['conversationType'].setValue(ConversationType.RolePlay);
4039
+ this.form.controls.conversationSettings.controls['textEngine'].setValue(TextEngines.MarkdownMultiMessages);
3743
4040
  }
3744
4041
  this.form.patchValue({ characterCard: jsonData });
3745
4042
  console.log(this.form.value);
@@ -3747,28 +4044,6 @@ class DCAgentCardFormComponent {
3747
4044
  }
3748
4045
  }
3749
4046
  }
3750
- addArrayItem(controlPath) {
3751
- const fullPath = `characterCard.data.${controlPath}`;
3752
- const control = this.form.get(fullPath);
3753
- if (control) {
3754
- control.push(this.fb.control(''));
3755
- }
3756
- }
3757
- removeArrayItem(controlPath, index) {
3758
- const fullPath = `characterCard.data.${controlPath}`;
3759
- const control = this.form.get(fullPath);
3760
- if (control) {
3761
- control.removeAt(index);
3762
- }
3763
- }
3764
- updateArrayField(controlPath, index, event) {
3765
- const fullPath = `characterCard.data.${controlPath}`;
3766
- const control = this.form.get(fullPath);
3767
- if (control && event.target instanceof HTMLInputElement) {
3768
- const currentValue = control.value;
3769
- control.setValue([...currentValue.slice(0, index), event.target.value, ...currentValue.slice(index + 1)]);
3770
- }
3771
- }
3772
4047
  checkPrompt() {
3773
4048
  const messages = this.promptBuilder.buildConversationMessages(this.form.value);
3774
4049
  const jailBrake = this.promptBuilder.getJailBrakePrompt(this.form.value);
@@ -3806,9 +4081,6 @@ class DCAgentCardFormComponent {
3806
4081
  }
3807
4082
  });
3808
4083
  }
3809
- checkCdr() {
3810
- this.cdr.detectChanges();
3811
- }
3812
4084
  openDialogNodeRef(htmlRef) {
3813
4085
  const dialogRef = this.dialogService.open(htmlRef, {
3814
4086
  width: '80vw',
@@ -3901,40 +4173,6 @@ class DCAgentCardFormComponent {
3901
4173
  }
3902
4174
  this.isGenerating = false;
3903
4175
  }
3904
- async improveFirstMessage() {
3905
- const confirm = window.confirm('Are you sure you want to improve the first message, will be shorter?');
3906
- if (!confirm) {
3907
- return;
3908
- }
3909
- const characterData = this.form.controls.characterCard.value.data;
3910
- const systemPrompt = `You are an expert in roleplay. Your task is to improve and shorten the provided first message for a conversation, ensuring it is at most 2 paragraphs. Use the following character information as context:
3911
- Character Name: ${characterData.name}
3912
- Description: ${characterData.description}
3913
- Scenario: ${characterData.scenario}
3914
-
3915
- Improve the following first message:`;
3916
- const messages = [
3917
- {
3918
- role: ChatRole.System,
3919
- content: systemPrompt,
3920
- },
3921
- { role: ChatRole.User, content: characterData.first_mes },
3922
- ];
3923
- const response = await this.agentCardService.callChatCompletion({ messages, model: { provider: 'google' } });
3924
- const jsonData = extractJsonFromResponse(response.content);
3925
- if (jsonData) {
3926
- this.toastService.success({ title: 'First message improved', subtitle: 'Remember to save changes if you are sure' });
3927
- // Assuming the LLM returns just the improved first message text, not a full JSON object
3928
- this.form.controls.characterCard.patchValue({ data: { first_mes: jsonData } });
3929
- }
3930
- else {
3931
- this.toastService.error({
3932
- title: 'Something went wrong :/',
3933
- subtitle: "The information could not be extracted correctly, but don't worry, you can try again",
3934
- });
3935
- }
3936
- this.isGenerating = false;
3937
- }
3938
4176
  async removeSticker(sticker) {
3939
4177
  console.log('remove sticker', sticker);
3940
4178
  this.storageService.deleteImage(sticker.path);
@@ -3973,7 +4211,7 @@ Improve the following first message:`;
3973
4211
  });
3974
4212
  }
3975
4213
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCAgentCardFormComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3976
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", inputs: { storageSettings: { classPropertyName: "storageSettings", publicName: "storageSettings", isSignal: true, isRequired: false, transformFunction: null }, bannerImgSettings: { classPropertyName: "bannerImgSettings", publicName: "bannerImgSettings", isSignal: true, isRequired: false, transformFunction: null }, imageStorageSettings: { classPropertyName: "imageStorageSettings", publicName: "imageStorageSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onImageLoaded: "onImageLoaded", onSave: "onSave", onGoDetails: "onGoDetails", onTranslate: "onTranslate" }, providers: [DialogService], 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)=\"saveConversation()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.controls.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.controls.id.value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.controls.title.errors?.['required'] && form.controls.title.touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div formGroupName=\"conversationSettings\" class=\"group\">\n <h3>Conversation Settings <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"textEngine\">\n Text Engine\n <span\n class=\"cursor-pointer\"\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\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"conversationType\">Conversation Type <span pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span></label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label> Auto Start <span pTooltip=\"Start conversation automatically\">\u2139\uFE0F</span> </label>\n <p-toggleSwitch formControlName=\"autoStart\"> </p-toggleSwitch>\n </div>\n\n <div formGroupName=\"tts\" class=\"group\">\n <h3>TTS Settings <span pTooltip=\"Text-to-Speech configuration options\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the primary voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector(true)\" />\n </p-inputgroup-addon>\n\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'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"secondaryVoice\">Secondary Voice <span pTooltip=\"Select an alternative voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-info-circle\" (click)=\"openVoiceSelector(false)\" />\n </p-inputgroup-addon>\n\n <p-select\n id=\"secondaryVoice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions\"\n formControlName=\"secondaryVoice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Secondary Voice'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speed\">Speed <span pTooltip=\"Set the speech rate for text-to-speech conversion\">\u2139\uFE0F</span></label>\n <p-select\n id=\"speed\"\n [options]=\"audioSpeedOptions\"\n formControlName=\"speed\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Speed'\"></p-select>\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 <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n </div>\n </div>\n\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n\n <div class=\"group\">\n <h4>Model Settings <span pTooltip=\"AI model configuration\">\u2139\uFE0F</span></h4>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n\n }\n </div>\n </div>\n\n <div class=\"right-column\">\n <div style=\"position: relative; min-height: 60px\">\n <img [src]=\"conversation?.assets?.bannerImg?.url || 'assets/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n @if(!conversation?.assets?.bannerImg?.url && agentCardId) {\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; right: 10px\"\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"conversation?.assets?.bannerImg?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"conversation?.assets?.bannerImg\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'bannerImg')\"></dc-cropper-modal>\n }\n </div>\n <div style=\"position: relative\">\n <img [src]=\"conversation?.assets?.image?.url || 'assets/images/default_2_3.webp'\" class=\"main-image-card\" />\n @if (!agentCardId) {\n <button pButton (click)=\"saveConversation()\"> Guarda el scenario para subir la imagen</button>\n } @else {\n\n <p-button\n (click)=\"generateMainImage()\"\n class=\"image-gen-btn\"\n pTooltip=\"Generar/Re generar la imagen\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\" />\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; left: 50%\"\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"conversation?.assets?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"></dc-cropper-modal>\n }\n </div>\n\n <div>\n <h4>Agregar stickers</h4>\n\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n\n <div style=\"display: flex; flex-wrap: wrap; gap: 10px\">\n @for (sticker of conversation?.assets?.stickers; track sticker.url) {\n <div style=\"position: relative\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <!-- <input pInputText type=\"file\" accept=\"image/*\" (change)=\"onImageSelected($event)\" /> -->\n\n <div formGroupName=\"characterCard\">\n <div formGroupName=\"data\" class=\"card-group\">\n <p-button (click)=\"generateMissingData()\" icon=\"pi pi-sparkles\" [rounded]=\"true\" severity=\"info\" label=\"Arreglar Campos\" />\n\n <h3>Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"cardName\">Name <span pTooltip=\"El nombre del personaje\">\u2139\uFE0F</span></label>\n <input pInputText id=\"cardName\" type=\"text\" formControlName=\"name\" />\n @if (form.get('characterCard.data.name')?.errors?.['required'] && form.get('characterCard.data.name')?.touched) {\n <div class=\"error\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardDescription\">Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\">\u2139\uFE0F</span></label>\n <textarea class=\"textmin\" rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardDescription\" formControlName=\"description\"></textarea>\n @if (form.get('characterCard.data.description')?.errors?.['required'] && form.get('characterCard.data.description')?.touched) {\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardScenario\">Scenario <span pTooltip=\"Describe the context or setting for the conversation\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardScenario\" formControlName=\"scenario\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardFirstMessage\">\n First Message\n <span pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n >\u2139\uFE0F</span\n >\n\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown Texto'\"\n size=\"small\"\n styleClass=\"min-w-16\"\n (onChange)=\"checkCdr()\" />\n\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\"></p-button>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"form.controls.characterCard.controls.data.controls.first_mes.value | mdToHtmlArray\"></div>\n }@else{\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardFirstMessage\" formControlName=\"first_mes\"> </textarea>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"mes_example\">Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"mes_example\" formControlName=\"mes_example\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardCreatorNotes\">Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardCreatorNotes\" formControlName=\"creator_notes\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardSystemPrompt\">System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardSystemPrompt\" formControlName=\"system_prompt\"></textarea>\n @if (form.get('characterCard.data.system_prompt')?.errors?.['required'] && form.get('characterCard.data.system_prompt')?.touched) {\n <div class=\"error\"> System prompt is required </div>\n }\n </div>\n\n <div>\n <div class=\"form-field\">\n <label>Image Description</label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" formControlName=\"picture_description\"></textarea>\n </div>\n </div>\n\n <div style=\"display: flex; flex-direction: column\">\n <label for=\"cardPostHistoryInstructions\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" formControlName=\"post_history_instructions\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardAlternateGreetings\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field\">\n @for (greeting of form.controls.characterCard.controls.data.controls.alternate_greetings.controls; track greeting; let i = $index) {\n <div class=\"array-item\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"greeting\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\">\n </textarea>\n <button pButton severity=\"danger\" class=\"remove-button\" (click)=\"removeArrayItem('alternate_greetings', i)\">&#x2716;</button>\n </div>\n }\n <button pButton severity=\"info\" (click)=\"addArrayItem('alternate_greetings')\">Add Greeting</button>\n </div>\n </div>\n\n <div class=\"form-field\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\">Tags \u2139\uFE0F</label>\n <div class=\"array-field\">\n @for (tag of form.controls.characterCard.controls.data.controls.tags.controls; track tag; let i = $index) {\n <div class=\"array-item\">\n <input [id]=\"'cardTag' + i\" type=\"text\" [formControl]=\"tag\" (input)=\"updateArrayField('tags', i, $event)\" />\n <button pButton severity=\"danger\" (click)=\"removeArrayItem('tags', i)\">Remove</button>\n </div>\n }\n <button pButton severity=\"info\" (click)=\"addArrayItem('tags')\">Add Tag</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </form>\n\n <p-popover #textEngineDialog header=\"Text Engine Information\">\n <div class=\"p-4\">\n <h3>Text Engine Types</h3>\n <ul>\n <li> <strong>Texto Simple</strong> La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica</li>\n\n <li\n ><strong>Multi Mensajes</strong> Utiliza markdown (recomendable entenderlo), sirve para darle formato al texto y sea m\u00E1s agradable de leer, el sistema\n puede partir dialogos que tienen distinto formato, como normal, cursiva y negritas, asi puede generar distintas voces y estilo para el narrador y\n personaje principal</li\n >\n <li\n ><strong>MD SSML :</strong> Markdown con Lenguaje de marcaci\u00F3n de s\u00EDntesis de voz (SSML), es tambien markdown pero a diferencia de multimessage, solo\n se presenta un mensaje. y la voz se genera para toda la linea,normalmente lo uso para conversaciones bilingues.</li\n >\n </ul>\n </div>\n </p-popover>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"saveConversation()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".textmin{min-width:36vw}.image-gen-btn{position:absolute;bottom:15px;left:35%}.main-image-card{max-width:280px;display:block;margin:0 auto;border-radius:8px}.main-banner-image-card{border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{background-color:#f8f9fa;padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .array-field{display:flex;flex-direction:column;gap:.5rem}.conversation-form .array-field .array-item{display:flex;gap:.5rem}.conversation-form .array-field .array-item input,.conversation-form .array-field .array-item textarea{flex:1}.conversation-form .array-field .array-item button{padding:.5rem}.conversation-form .array-field button[type=button]{background-color:#28a745;color:#fff;border:none;padding:8px 12px;border-radius:4px;cursor:pointer;transition:background-color .2s}.conversation-form .array-field button[type=button]:hover{background-color:#218838}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{background-color:#f8f9fa;padding:1rem;border-radius:4px;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "ngmodule", type: PortalModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "directive", type: i3.Textarea, selector: "[pTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i4$1.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "component", type: i6$1.ToggleButton, selector: "p-toggleButton, p-togglebutton, p-toggle-button", inputs: ["onLabel", "offLabel", "onIcon", "offIcon", "ariaLabel", "ariaLabelledBy", "disabled", "style", "styleClass", "inputId", "tabindex", "size", "iconPos", "autofocus", "allowEmpty"], outputs: ["onChange"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i8.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["style", "styleClass", "tabindex", "inputId", "name", "disabled", "readonly", "trueValue", "falseValue", "ariaLabel", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "pipe", type: MdToHtmlArrayPipe, name: "mdToHtmlArray" }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i10.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: ProviderSelectorComponent, selector: "dc-provider-selector", inputs: ["parentForm"] }, { kind: "component", type: AccountPlatformForm, selector: "account-platform-form", inputs: ["formArray"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i11.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i12.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }] }); }
4214
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCAgentCardFormComponent, isStandalone: true, selector: "dc-agent-form", inputs: { storageSettings: { classPropertyName: "storageSettings", publicName: "storageSettings", isSignal: true, isRequired: false, transformFunction: null }, bannerImgSettings: { classPropertyName: "bannerImgSettings", publicName: "bannerImgSettings", isSignal: true, isRequired: false, transformFunction: null }, imageStorageSettings: { classPropertyName: "imageStorageSettings", publicName: "imageStorageSettings", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onImageLoaded: "onImageLoaded", onSave: "onSave", onGoDetails: "onGoDetails", onTranslate: "onTranslate" }, providers: [DialogService], 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)=\"saveConversation()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.controls.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.controls.id.value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.controls.title.errors?.['required'] && form.controls.title.touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div formGroupName=\"conversationSettings\" class=\"group\">\n <h3>Conversation Settings <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"textEngine\">\n Text Engine\n <span\n class=\"cursor-pointer\"\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\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"conversationType\">Conversation Type <span pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span></label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label> Auto Start <span pTooltip=\"Start conversation automatically\">\u2139\uFE0F</span> </label>\n <p-toggleSwitch formControlName=\"autoStart\"> </p-toggleSwitch>\n </div>\n\n <div formGroupName=\"tts\" class=\"group\">\n <h3>TTS Settings <span pTooltip=\"Text-to-Speech configuration options\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the primary voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector(true)\" />\n </p-inputgroup-addon>\n\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'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"secondaryVoice\">Secondary Voice <span pTooltip=\"Select an alternative voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-info-circle\" (click)=\"openVoiceSelector(false)\" />\n </p-inputgroup-addon>\n\n <p-select\n id=\"secondaryVoice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions\"\n formControlName=\"secondaryVoice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Secondary Voice'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speed\">Speed <span pTooltip=\"Set the speech rate for text-to-speech conversion\">\u2139\uFE0F</span></label>\n <p-select\n id=\"speed\"\n [options]=\"audioSpeedOptions\"\n formControlName=\"speed\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Speed'\"></p-select>\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 <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n </div>\n </div>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <div class=\"group\">\n <h4>Model Settings <span pTooltip=\"AI model configuration\">\u2139\uFE0F</span></h4>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(form.controls.conversationFlow){\n <div class=\"group\">\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n <div style=\"position: relative; min-height: 60px\">\n <img [src]=\"conversation?.assets?.bannerImg?.url || 'assets/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n @if(!conversation?.assets?.bannerImg?.url && agentCardId) {\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; right: 10px\"\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"conversation?.assets?.bannerImg?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"conversation?.assets?.bannerImg\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'bannerImg')\"></dc-cropper-modal>\n }\n </div>\n <div style=\"position: relative\">\n <img [src]=\"conversation?.assets?.image?.url || 'assets/images/default_2_3.webp'\" class=\"main-image-card\" />\n @if (!agentCardId) {\n <button pButton (click)=\"saveConversation()\"> Guarda el scenario para subir la imagen</button>\n } @else {\n\n <p-button\n (click)=\"generateMainImage()\"\n class=\"image-gen-btn\"\n pTooltip=\"Generar/Re generar la imagen\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\" />\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; left: 50%\"\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"conversation?.assets?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"></dc-cropper-modal>\n }\n </div>\n\n <div>\n <h4>Agregar stickers</h4>\n\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n\n <div style=\"display: flex; flex-wrap: wrap; gap: 10px\">\n @for (sticker of conversation?.assets?.stickers; track sticker.url) {\n <div style=\"position: relative\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <!-- <input pInputText type=\"file\" accept=\"image/*\" (change)=\"onImageSelected($event)\" /> -->\n\n @if(form.controls.characterCard){\n <dc-character-card-form [characterCardForm]=\"form.controls.characterCard\" (generateMissingDataRequest)=\"generateMissingData()\">\n </dc-character-card-form>\n }\n </div>\n </div>\n </form>\n\n <p-popover #textEngineDialog header=\"Text Engine Information\">\n <div class=\"p-4\">\n <h3>Text Engine Types</h3>\n <ul>\n <li> <strong>Texto Simple</strong> La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica</li>\n\n <li\n ><strong>Multi Mensajes</strong> Utiliza markdown (recomendable entenderlo), sirve para darle formato al texto y sea m\u00E1s agradable de leer, el sistema\n puede partir dialogos que tienen distinto formato, como normal, cursiva y negritas, asi puede generar distintas voces y estilo para el narrador y\n personaje principal</li\n >\n <li\n ><strong>MD SSML :</strong> Markdown con Lenguaje de marcaci\u00F3n de s\u00EDntesis de voz (SSML), es tambien markdown pero a diferencia de multimessage, solo\n se presenta un mensaje. y la voz se genera para toda la linea,normalmente lo uso para conversaciones bilingues.</li\n >\n </ul>\n </div>\n </p-popover>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"saveConversation()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".textmin{min-width:36vw}.image-gen-btn{position:absolute;bottom:15px;left:35%}.main-image-card{max-width:280px;display:block;margin:0 auto;border-radius:8px}.main-banner-image-card{border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{background-color:#f8f9fa;padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .array-field{display:flex;flex-direction:column;gap:.5rem}.conversation-form .array-field .array-item{display:flex;gap:.5rem}.conversation-form .array-field .array-item input,.conversation-form .array-field .array-item textarea{flex:1}.conversation-form .array-field .array-item button{padding:.5rem}.conversation-form .array-field button[type=button]{background-color:#28a745;color:#fff;border:none;padding:8px 12px;border-radius:4px;cursor:pointer;transition:background-color .2s}.conversation-form .array-field button[type=button]:hover{background-color:#218838}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{background-color:#f8f9fa;padding:1rem;border-radius:4px;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i1.FormGroupName, selector: "[formGroupName]", inputs: ["formGroupName"] }, { kind: "component", type: CropperComponentModal, selector: "dc-cropper-modal", inputs: ["imgStorageSettings", "buttonLabel", "currentStorage"], outputs: ["imageUploaded", "onImageCropped", "onFileSelected"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "ngmodule", type: PortalModule }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: TextareaModule }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3$3.InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i2$3.Checkbox, selector: "p-checkbox, p-checkBox, p-check-box", inputs: ["value", "name", "disabled", "binary", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "inputStyle", "styleClass", "inputClass", "indeterminate", "size", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ToggleButtonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: ToggleSwitchModule }, { kind: "component", type: i6$1.ToggleSwitch, selector: "p-toggleswitch, p-toggleSwitch, p-toggle-switch", inputs: ["style", "styleClass", "tabindex", "inputId", "name", "disabled", "readonly", "trueValue", "falseValue", "ariaLabel", "ariaLabelledBy", "autofocus"], outputs: ["onChange"] }, { kind: "ngmodule", type: SelectModule }, { kind: "component", type: i5$1.Select, selector: "p-select", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "size", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "fluid", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: DialogModule }, { kind: "ngmodule", type: DynamicDialogModule }, { kind: "ngmodule", type: PopoverModule }, { kind: "component", type: i8.Popover, selector: "p-popover", inputs: ["ariaLabel", "ariaLabelledBy", "dismissable", "style", "styleClass", "appendTo", "autoZIndex", "ariaCloseLabel", "baseZIndex", "focusOnShow", "showTransitionOptions", "hideTransitionOptions"], outputs: ["onShow", "onHide"] }, { kind: "component", type: ProviderSelectorComponent, selector: "dc-provider-selector", inputs: ["parentForm"] }, { kind: "component", type: AccountPlatformForm, selector: "account-platform-form", inputs: ["formArray"] }, { kind: "ngmodule", type: InputGroupAddonModule }, { kind: "component", type: i9.InputGroupAddon, selector: "p-inputgroup-addon, p-inputGroupAddon", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: InputGroupModule }, { kind: "component", type: i10.InputGroup, selector: "p-inputgroup, p-inputGroup, p-input-group", inputs: ["style", "styleClass"] }, { kind: "ngmodule", type: CardModule }, { kind: "component", type: i2$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "component", type: DCConversationFlowFormComponent, selector: "dc-conversation-flow-form", inputs: ["formGroup"] }, { kind: "component", type: DcCharacterCardFormComponent, selector: "dc-character-card-form", inputs: ["characterCardForm"], outputs: ["generateMissingDataRequest"] }] }); }
3977
4215
  }
3978
4216
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCAgentCardFormComponent, decorators: [{
3979
4217
  type: Component,
@@ -4001,8 +4239,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
4001
4239
  InputGroupAddonModule,
4002
4240
  InputGroupModule,
4003
4241
  CardModule,
4004
- ], 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)=\"saveConversation()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.controls.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.controls.id.value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.controls.title.errors?.['required'] && form.controls.title.touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div formGroupName=\"conversationSettings\" class=\"group\">\n <h3>Conversation Settings <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"textEngine\">\n Text Engine\n <span\n class=\"cursor-pointer\"\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\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"conversationType\">Conversation Type <span pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span></label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label> Auto Start <span pTooltip=\"Start conversation automatically\">\u2139\uFE0F</span> </label>\n <p-toggleSwitch formControlName=\"autoStart\"> </p-toggleSwitch>\n </div>\n\n <div formGroupName=\"tts\" class=\"group\">\n <h3>TTS Settings <span pTooltip=\"Text-to-Speech configuration options\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the primary voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector(true)\" />\n </p-inputgroup-addon>\n\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'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"secondaryVoice\">Secondary Voice <span pTooltip=\"Select an alternative voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-info-circle\" (click)=\"openVoiceSelector(false)\" />\n </p-inputgroup-addon>\n\n <p-select\n id=\"secondaryVoice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions\"\n formControlName=\"secondaryVoice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Secondary Voice'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speed\">Speed <span pTooltip=\"Set the speech rate for text-to-speech conversion\">\u2139\uFE0F</span></label>\n <p-select\n id=\"speed\"\n [options]=\"audioSpeedOptions\"\n formControlName=\"speed\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Speed'\"></p-select>\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 <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n </div>\n </div>\n\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n\n <div class=\"group\">\n <h4>Model Settings <span pTooltip=\"AI model configuration\">\u2139\uFE0F</span></h4>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n\n }\n </div>\n </div>\n\n <div class=\"right-column\">\n <div style=\"position: relative; min-height: 60px\">\n <img [src]=\"conversation?.assets?.bannerImg?.url || 'assets/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n @if(!conversation?.assets?.bannerImg?.url && agentCardId) {\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; right: 10px\"\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"conversation?.assets?.bannerImg?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"conversation?.assets?.bannerImg\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'bannerImg')\"></dc-cropper-modal>\n }\n </div>\n <div style=\"position: relative\">\n <img [src]=\"conversation?.assets?.image?.url || 'assets/images/default_2_3.webp'\" class=\"main-image-card\" />\n @if (!agentCardId) {\n <button pButton (click)=\"saveConversation()\"> Guarda el scenario para subir la imagen</button>\n } @else {\n\n <p-button\n (click)=\"generateMainImage()\"\n class=\"image-gen-btn\"\n pTooltip=\"Generar/Re generar la imagen\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\" />\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; left: 50%\"\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"conversation?.assets?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"></dc-cropper-modal>\n }\n </div>\n\n <div>\n <h4>Agregar stickers</h4>\n\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n\n <div style=\"display: flex; flex-wrap: wrap; gap: 10px\">\n @for (sticker of conversation?.assets?.stickers; track sticker.url) {\n <div style=\"position: relative\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <!-- <input pInputText type=\"file\" accept=\"image/*\" (change)=\"onImageSelected($event)\" /> -->\n\n <div formGroupName=\"characterCard\">\n <div formGroupName=\"data\" class=\"card-group\">\n <p-button (click)=\"generateMissingData()\" icon=\"pi pi-sparkles\" [rounded]=\"true\" severity=\"info\" label=\"Arreglar Campos\" />\n\n <h3>Character Card <span pTooltip=\"Informaci\u00F3n de la ficha del personaje\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"cardName\">Name <span pTooltip=\"El nombre del personaje\">\u2139\uFE0F</span></label>\n <input pInputText id=\"cardName\" type=\"text\" formControlName=\"name\" />\n @if (form.get('characterCard.data.name')?.errors?.['required'] && form.get('characterCard.data.name')?.touched) {\n <div class=\"error\"> Name is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardDescription\">Description <span pTooltip=\"Descripci\u00F3n detallada del personaje\">\u2139\uFE0F</span></label>\n <textarea class=\"textmin\" rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardDescription\" formControlName=\"description\"></textarea>\n @if (form.get('characterCard.data.description')?.errors?.['required'] && form.get('characterCard.data.description')?.touched) {\n <div class=\"error\"> Description is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardScenario\">Scenario <span pTooltip=\"Describe the context or setting for the conversation\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardScenario\" formControlName=\"scenario\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardFirstMessage\">\n First Message\n <span pTooltip=\"Es muy importante que la historia inicie bien, ya que es el patr\u00F3n inicial para la AI, respetar las convenciones de texto\"\n >\u2139\uFE0F</span\n >\n\n <p-togglebutton\n [formControl]=\"markdownForm.controls.seeMarkdown\"\n [onLabel]=\"'Editar'\"\n [offLabel]=\"'Ver Markdown Texto'\"\n size=\"small\"\n styleClass=\"min-w-16\"\n (onChange)=\"checkCdr()\" />\n\n <p-button icon=\"pi pi-refresh\" (click)=\"improveFirstMessage()\" label=\"Mejorar\"></p-button>\n </label>\n\n @if(markdownForm.controls.seeMarkdown.value){\n <div [innerHTML]=\"form.controls.characterCard.controls.data.controls.first_mes.value | mdToHtmlArray\"></div>\n }@else{\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardFirstMessage\" formControlName=\"first_mes\"> </textarea>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"mes_example\">Mensajes de Ejemplo <span pTooltip=\"Importante para el estilo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"mes_example\" formControlName=\"mes_example\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardCreatorNotes\">Creator Notes <span pTooltip=\"son solo notas del creador, no afecta nada a la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardCreatorNotes\" formControlName=\"creator_notes\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardSystemPrompt\">System Prompt (Opcional) <span pTooltip=\"Instrucciones del sistema para la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" id=\"cardSystemPrompt\" formControlName=\"system_prompt\"></textarea>\n @if (form.get('characterCard.data.system_prompt')?.errors?.['required'] && form.get('characterCard.data.system_prompt')?.touched) {\n <div class=\"error\"> System prompt is required </div>\n }\n </div>\n\n <div>\n <div class=\"form-field\">\n <label>Image Description</label>\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" formControlName=\"picture_description\"></textarea>\n </div>\n </div>\n\n <div style=\"display: flex; flex-direction: column\">\n <label for=\"cardPostHistoryInstructions\"\n >Post-History Instructions (Opcional)\n <span\n pTooltip=\"Dejar en blanco, al menos que se sepa como funciona, esto se llama jailbreak, es para darle instrucciones finales y m\u00E1s importantes al modelo\"\n >\u2139\uFE0F</span\n ></label\n >\n <textarea rows=\"1\" pTextarea [autoResize]=\"true\" formControlName=\"post_history_instructions\"></textarea>\n </div>\n\n <div class=\"form-field\">\n <label for=\"cardAlternateGreetings\"\n >Alternate Greetings <span pTooltip=\"Saludos alternativos para comenzar una historia diferente\">\u2139\uFE0F</span></label\n >\n <div class=\"array-field\">\n @for (greeting of form.controls.characterCard.controls.data.controls.alternate_greetings.controls; track greeting; let i = $index) {\n <div class=\"array-item\" style=\"position: relative\">\n <textarea\n pTextarea\n rows=\"1\"\n [autoResize]=\"true\"\n [id]=\"'cardAlternateGreeting' + i\"\n [formControl]=\"greeting\"\n (input)=\"updateArrayField('alternate_greetings', i, $event)\">\n </textarea>\n <button pButton severity=\"danger\" class=\"remove-button\" (click)=\"removeArrayItem('alternate_greetings', i)\">&#x2716;</button>\n </div>\n }\n <button pButton severity=\"info\" (click)=\"addArrayItem('alternate_greetings')\">Add Greeting</button>\n </div>\n </div>\n\n <div class=\"form-field\">\n <label pTooltip=\"Agrega las categorias\" for=\"cardTags\">Tags \u2139\uFE0F</label>\n <div class=\"array-field\">\n @for (tag of form.controls.characterCard.controls.data.controls.tags.controls; track tag; let i = $index) {\n <div class=\"array-item\">\n <input [id]=\"'cardTag' + i\" type=\"text\" [formControl]=\"tag\" (input)=\"updateArrayField('tags', i, $event)\" />\n <button pButton severity=\"danger\" (click)=\"removeArrayItem('tags', i)\">Remove</button>\n </div>\n }\n <button pButton severity=\"info\" (click)=\"addArrayItem('tags')\">Add Tag</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n </form>\n\n <p-popover #textEngineDialog header=\"Text Engine Information\">\n <div class=\"p-4\">\n <h3>Text Engine Types</h3>\n <ul>\n <li> <strong>Texto Simple</strong> La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica</li>\n\n <li\n ><strong>Multi Mensajes</strong> Utiliza markdown (recomendable entenderlo), sirve para darle formato al texto y sea m\u00E1s agradable de leer, el sistema\n puede partir dialogos que tienen distinto formato, como normal, cursiva y negritas, asi puede generar distintas voces y estilo para el narrador y\n personaje principal</li\n >\n <li\n ><strong>MD SSML :</strong> Markdown con Lenguaje de marcaci\u00F3n de s\u00EDntesis de voz (SSML), es tambien markdown pero a diferencia de multimessage, solo\n se presenta un mensaje. y la voz se genera para toda la linea,normalmente lo uso para conversaciones bilingues.</li\n >\n </ul>\n </div>\n </p-popover>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"saveConversation()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".textmin{min-width:36vw}.image-gen-btn{position:absolute;bottom:15px;left:35%}.main-image-card{max-width:280px;display:block;margin:0 auto;border-radius:8px}.main-banner-image-card{border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{background-color:#f8f9fa;padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .array-field{display:flex;flex-direction:column;gap:.5rem}.conversation-form .array-field .array-item{display:flex;gap:.5rem}.conversation-form .array-field .array-item input,.conversation-form .array-field .array-item textarea{flex:1}.conversation-form .array-field .array-item button{padding:.5rem}.conversation-form .array-field button[type=button]{background-color:#28a745;color:#fff;border:none;padding:8px 12px;border-radius:4px;cursor:pointer;transition:background-color .2s}.conversation-form .array-field button[type=button]:hover{background-color:#218838}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{background-color:#f8f9fa;padding:1rem;border-radius:4px;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"] }]
4005
- }], ctorParameters: () => [] });
4242
+ DCConversationFlowFormComponent,
4243
+ DcCharacterCardFormComponent,
4244
+ ], 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)=\"saveConversation()\" label=\"\uD83D\uDCBE Guardar cambios\"></button>\n </div>\n\n <div class=\"top-buttons\">\n <p-button severity=\"help\" (click)=\"translate()\" label=\"\uD83D\uDD04 Traducir\"></p-button>\n <p-button [loading]=\"isGenerating\" severity=\"help\" (click)=\"generateCharacter()\" label=\"Generar \uD83E\uDDBE\"></p-button>\n\n <p-button severity=\"info\" (click)=\"downloadConversation()\" label=\"\uD83D\uDCC1 Exportar \u2B07\uFE0F\"></p-button>\n <p-button severity=\"info\" (click)=\"importConversation()\" label=\"\uD83C\uDCCF Importar \u2B06\uFE0F\"></p-button>\n </div>\n\n <br />\n <br />\n <form [formGroup]=\"form\" class=\"conversation-form\">\n <div class=\"form-grid\">\n <div class=\"left-column\">\n <div style=\"display: flex; gap: 15px\">\n <div class=\"form-field\">\n <label for=\"version\">Version: {{ form.controls.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.controls.id.value }} \u2139\uFE0F</span></label\n >\n </div>\n </div>\n\n <div class=\"form-field\">\n <label for=\"title\">Title <span pTooltip=\"T\u00EDtulo de la conversaci\u00F3n\">\u2139\uFE0F</span></label>\n <input pInputText id=\"title\" type=\"text\" formControlName=\"title\" />\n @if(form.controls.title.errors?.['required'] && form.controls.title.touched){\n <div class=\"error\"> Title is required </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"lang\">Language <span pTooltip=\"Select the primary language for the conversation\">\u2139\uFE0F</span></label>\n <p-select\n id=\"lang\"\n [options]=\"languageOptions\"\n formControlName=\"lang\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Language'\"></p-select>\n </div>\n\n <div formGroupName=\"conversationSettings\" class=\"group\">\n <h3>Conversation Settings <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"textEngine\">\n Text Engine\n <span\n class=\"cursor-pointer\"\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\n <p-select\n id=\"textEngine\"\n [options]=\"textEngineOptions\"\n formControlName=\"textEngine\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Text Engine'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label for=\"conversationType\">Conversation Type <span pTooltip=\"Choose the type of conversation interaction\">\u2139\uFE0F</span></label>\n <p-select\n id=\"conversationType\"\n [options]=\"conversationOptions\"\n formControlName=\"conversationType\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Conversation Type'\"></p-select>\n </div>\n\n <div class=\"form-field\">\n <label> Auto Start <span pTooltip=\"Start conversation automatically\">\u2139\uFE0F</span> </label>\n <p-toggleSwitch formControlName=\"autoStart\"> </p-toggleSwitch>\n </div>\n\n <div formGroupName=\"tts\" class=\"group\">\n <h3>TTS Settings <span pTooltip=\"Text-to-Speech configuration options\">\u2139\uFE0F</span></h3>\n\n <div class=\"form-field\">\n <label for=\"voice\">Voice <span pTooltip=\"Select the primary voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-exclamation-circle\" (click)=\"openVoiceSelector(true)\" />\n </p-inputgroup-addon>\n\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'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"secondaryVoice\">Secondary Voice <span pTooltip=\"Select an alternative voice for text-to-speech\">\u2139\uFE0F</span></label>\n\n <p-inputgroup>\n <p-inputgroup-addon>\n <p-button [rounded]=\"true\" [text]=\"true\" icon=\"pi pi-info-circle\" (click)=\"openVoiceSelector(false)\" />\n </p-inputgroup-addon>\n\n <p-select\n id=\"secondaryVoice\"\n [editable]=\"true\"\n [options]=\"voiceTTSOptions\"\n formControlName=\"secondaryVoice\"\n optionLabel=\"name\"\n optionValue=\"id\"\n [placeholder]=\"'Select Secondary Voice'\"></p-select>\n </p-inputgroup>\n </div>\n\n <div class=\"form-field\">\n <label for=\"speed\">Speed <span pTooltip=\"Set the speech rate for text-to-speech conversion\">\u2139\uFE0F</span></label>\n <p-select\n id=\"speed\"\n [options]=\"audioSpeedOptions\"\n formControlName=\"speed\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [placeholder]=\"'Select Speed'\"></p-select>\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 <input pInputText id=\"speedRate\" type=\"number\" formControlName=\"speedRate\" step=\"0.1\" />\n </div>\n </div>\n </div>\n\n <details>\n <summary>Meta Information</summary>\n <div formGroupName=\"metaApp\" class=\"group\">\n <h3>Meta Information <span pTooltip=\"Additional information about the conversation\">\u2139\uFE0F</span></h3>\n <div class=\"form-field\">\n <label for=\"authorId\">Author ID <span pTooltip=\"Unique identifier for the conversation author\">\u2139\uFE0F</span></label>\n <input pInputText id=\"authorId\" type=\"text\" formControlName=\"authorId\" />\n </div>\n\n <div class=\"form-field\">\n <label for=\"authorEmail\">Author Email \u2139\uFE0F</label>\n <input pInputText id=\"authorEmail\" type=\"email\" formControlName=\"authorEmail\" />\n @if (form.get('metaApp.authorEmail')?.errors?.['email'] && form.get('metaApp.authorEmail')?.touched) {\n <div class=\"error\"> Please enter a valid email address </div>\n }\n </div>\n\n <div class=\"form-field\">\n <label for=\"takenCount\"\n >Taken Count <span pTooltip=\"Es el contador de cuantas veces se ha tomado esta conversaci\u00F3n, no sirve por ahora\"> \u2139\uFE0F</span></label\n >\n <input pInputText id=\"takenCount\" type=\"number\" formControlName=\"takenCount\" />\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublic\" />\n Public\n </label>\n </div>\n\n <div class=\"form-field checkbox\">\n <label>\n <p-checkbox [binary]=\"true\" formControlName=\"isPublished\" />\n Published\n </label>\n </div>\n </div>\n </details>\n\n <div class=\"group\">\n <h4>Model Settings <span pTooltip=\"AI model configuration\">\u2139\uFE0F</span></h4>\n\n <dc-provider-selector [parentForm]=\"form.controls.model\"></dc-provider-selector>\n </div>\n\n <details>\n <summary>Gestion de cuentas</summary>\n <div class=\"group\">\n <h4>Gestion de cuentas</h4>\n @if(form.controls.accounts){\n <account-platform-form [formArray]=\"form.controls.accounts\"></account-platform-form>\n }\n </div>\n </details>\n\n @if(form.controls.conversationFlow){\n <div class=\"group\">\n <dc-conversation-flow-form [formGroup]=\"form.controls.conversationFlow\"></dc-conversation-flow-form>\n </div>\n }\n </div>\n\n <div class=\"right-column\">\n <div style=\"position: relative; min-height: 60px\">\n <img [src]=\"conversation?.assets?.bannerImg?.url || 'assets/images/default_banner.webp'\" class=\"main-banner-image-card\" />\n @if(!conversation?.assets?.bannerImg?.url && agentCardId) {\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; right: 10px\"\n #cropperBanner\n id=\"cropperBanner\"\n [buttonLabel]=\"conversation?.assets?.bannerImg?.url ? 'Cambiar el banner' : 'Cargar un banner'\"\n [imgStorageSettings]=\"bannerImgSettings()\"\n [currentStorage]=\"conversation?.assets?.bannerImg\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'bannerImg')\"></dc-cropper-modal>\n }\n </div>\n <div style=\"position: relative\">\n <img [src]=\"conversation?.assets?.image?.url || 'assets/images/default_2_3.webp'\" class=\"main-image-card\" />\n @if (!agentCardId) {\n <button pButton (click)=\"saveConversation()\"> Guarda el scenario para subir la imagen</button>\n } @else {\n\n <p-button\n (click)=\"generateMainImage()\"\n class=\"image-gen-btn\"\n pTooltip=\"Generar/Re generar la imagen\"\n icon=\"pi pi-sparkles\"\n [rounded]=\"true\"\n severity=\"info\" />\n\n <dc-cropper-modal\n style=\"position: absolute; bottom: 10px; left: 50%\"\n id=\"cropperCardImage\"\n #cropperCardImage\n [buttonLabel]=\"conversation?.assets?.image?.url ? 'Cambiar imagen' : 'Cargar una imagen'\"\n [imgStorageSettings]=\"imageStorageSettings()\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'image')\"></dc-cropper-modal>\n }\n </div>\n\n <div>\n <h4>Agregar stickers</h4>\n\n <dc-cropper-modal\n id=\"cropperCardImage\"\n #cropperStickers\n [buttonLabel]=\"'agregar sticker'\"\n [imgStorageSettings]=\"stickerStorageSettings\"\n (onFileSelected)=\"onImageSelected($event)\"\n (imageUploaded)=\"onImageUploaded($event, 'sticker')\"></dc-cropper-modal>\n </div>\n\n <div style=\"display: flex; flex-wrap: wrap; gap: 10px\">\n @for (sticker of conversation?.assets?.stickers; track sticker.url) {\n <div style=\"position: relative\">\n <img width=\"100\" [src]=\"sticker.url\" alt=\"\" />\n <p-button (click)=\"removeSticker(sticker)\" class=\"remove-sticker\" icon=\"pi pi-times\" [rounded]=\"true\" [text]=\"true\" severity=\"danger\" />\n </div>\n }\n </div>\n\n <!-- <input pInputText type=\"file\" accept=\"image/*\" (change)=\"onImageSelected($event)\" /> -->\n\n @if(form.controls.characterCard){\n <dc-character-card-form [characterCardForm]=\"form.controls.characterCard\" (generateMissingDataRequest)=\"generateMissingData()\">\n </dc-character-card-form>\n }\n </div>\n </div>\n </form>\n\n <p-popover #textEngineDialog header=\"Text Engine Information\">\n <div class=\"p-4\">\n <h3>Text Engine Types</h3>\n <ul>\n <li> <strong>Texto Simple</strong> La conversaci\u00F3n es como chatgpt, preguntas y responde, es la m\u00E1s b\u00E1sica</li>\n\n <li\n ><strong>Multi Mensajes</strong> Utiliza markdown (recomendable entenderlo), sirve para darle formato al texto y sea m\u00E1s agradable de leer, el sistema\n puede partir dialogos que tienen distinto formato, como normal, cursiva y negritas, asi puede generar distintas voces y estilo para el narrador y\n personaje principal</li\n >\n <li\n ><strong>MD SSML :</strong> Markdown con Lenguaje de marcaci\u00F3n de s\u00EDntesis de voz (SSML), es tambien markdown pero a diferencia de multimessage, solo\n se presenta un mensaje. y la voz se genera para toda la linea,normalmente lo uso para conversaciones bilingues.</li\n >\n </ul>\n </div>\n </p-popover>\n\n <div class=\"float-button\">\n <p-button icon=\"pi pi-save\" (click)=\"saveConversation()\" severity=\"primary\" [rounded]=\"true\" [raised]=\"true\" pTooltip=\"Guardar (Ctrl + S)\"> </p-button>\n </div>\n</p-card>\n", styles: [".textmin{min-width:36vw}.image-gen-btn{position:absolute;bottom:15px;left:35%}.main-image-card{max-width:280px;display:block;margin:0 auto;border-radius:8px}.main-banner-image-card{border-radius:8px}.remove-sticker{position:absolute;top:5px;right:5px}.conversation-form{max-width:100%;padding:20px;background-color:#fff;border-radius:8px;box-shadow:0 2px 4px #0000001a}.conversation-form .card-group{background-color:#f8f9fa;padding:20px;border-radius:6px;margin-bottom:24px}.conversation-form .card-group h3{margin:0 0 20px;color:#2c3e50;font-size:1.25rem}.conversation-form .form-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:2rem;width:100%;max-width:100%}@media (max-width: 768px){.conversation-form .form-grid{grid-template-columns:1fr}}.conversation-form .form-field{margin-bottom:1.5rem;display:flex;flex-direction:column;gap:.5rem}.conversation-form .form-field label{font-weight:500}.conversation-form .form-field textarea{resize:vertical}.conversation-form .form-field.checkbox{flex-direction:row;align-items:center;gap:.5rem}.conversation-form .form-field.checkbox input[type=checkbox]{width:auto}.conversation-form .form-field .error{color:#dc3545;font-size:.875rem;margin-top:.25rem}.conversation-form .form-field .remove-button{position:absolute;border:none;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;cursor:pointer;top:-10px;right:-10px}.conversation-form .left-column,.conversation-form .right-column{display:flex;flex-direction:column;gap:1rem}.conversation-form .array-field{display:flex;flex-direction:column;gap:.5rem}.conversation-form .array-field .array-item{display:flex;gap:.5rem}.conversation-form .array-field .array-item input,.conversation-form .array-field .array-item textarea{flex:1}.conversation-form .array-field .array-item button{padding:.5rem}.conversation-form .array-field button[type=button]{background-color:#28a745;color:#fff;border:none;padding:8px 12px;border-radius:4px;cursor:pointer;transition:background-color .2s}.conversation-form .array-field button[type=button]:hover{background-color:#218838}.conversation-form .group,.conversation-form .meta-group,.conversation-form .card-group{background-color:#f8f9fa;padding:1rem;border-radius:4px;margin-bottom:1.5rem}.conversation-form .group h3,.conversation-form .meta-group h3,.conversation-form .card-group h3{margin-top:0;margin-bottom:1rem}.top-buttons{display:flex;justify-content:space-between;margin-bottom:2rem;gap:1rem}.top-buttons button{flex:1}::ng-deep em{font-weight:900;color:#014a93}.float-button{position:fixed;bottom:4rem;right:2rem;z-index:1000;display:flex;gap:1px}.float-button :host ::ng-deep .p-button{width:4rem;height:4rem;border-radius:50%}\n"] }]
4245
+ }] });
4006
4246
 
4007
4247
  class DCConversationCardUIComponent {
4008
4248
  constructor() {
@@ -4030,7 +4270,7 @@ class DCConversationCardUIComponent {
4030
4270
  this.onCardAction.emit({ event: 'delete', card: this.card() });
4031
4271
  }
4032
4272
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationCardUIComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
4033
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationCardUIComponent, isStandalone: true, selector: "dc-agent-card-default-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: { onCardAction: "onCardAction" }, ngImport: i0, template: "<p-card class=\"card-image\">\n @if(showOptions()) {\n <div style=\"position: absolute; top: 5px; right: 5px; z-index: 1000\">\n <p-speeddial\n [model]=\"speedDialModel\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n </div>\n }\n\n <img [src]=\"card()?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div (click)=\"onDetails()\" class=\"content\">\n <p class=\"text-xl font-bold text-shadow-lg/30\">{{ card().title }}</p>\n\n <!-- <h5 class=\"title\">\n <span [innerHTML]=\"card().characterCard?.data.description | truncate : 100\"></span>\n </h5> -->\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"card().characterCard?.data.creator_notes | truncate : 200\"></span>\n </p>\n\n @if(card().taken){\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-tag icon=\"pi pi-check-circle\" severity=\"secondary\" value=\"Tomada\" [rounded]=\"true\" />\n </div>\n }\n <p-button\n (click)=\"onDetails()\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\"\n icon=\"pi pi-comment\"\n [rounded]=\"true\"\n severity=\"info\"\n [outlined]=\"true\"\n [raised]=\"true\" />\n </div>\n</p-card>\n", styles: [":host{display:block}:host ::ng-deep .p-card{height:100%}:host ::ng-deep .p-card-body{height:100%;padding:0!important}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block;padding:-10px}.card-image img{position:absolute;z-index:3;width:100%;height:100%;opacity:.75;object-fit:cover;transition:opacity .5s}.content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0003,#0000001a);height:100%;display:flex;flex-direction:column;justify-content:space-between}.content:hover{background:linear-gradient(to bottom,color-mix(in srgb,var(--p-primary-color) 20%,transparent),color-mix(in srgb,black 10%,transparent));cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: PopoverModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$5.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$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$2.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4273
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.4", type: DCConversationCardUIComponent, isStandalone: true, selector: "dc-agent-card-default-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: { onCardAction: "onCardAction" }, ngImport: i0, template: "<p-card class=\"card-image\">\n @if(showOptions()) {\n <div style=\"position: absolute; top: 5px; right: 5px; z-index: 1000\">\n <p-speeddial\n [model]=\"speedDialModel\"\n [radius]=\"70\"\n type=\"quarter-circle\"\n direction=\"down-left\"\n [buttonProps]=\"{ severity: 'primary', rounded: true, outlined: true, raised: true }\" />\n </div>\n }\n\n <img [src]=\"card()?.assets?.image?.url || 'assets/images/default_conversation_card.webp'\" alt=\"\" />\n\n <div (click)=\"onDetails()\" class=\"content\">\n <p class=\"text-xl font-bold text-shadow-lg/30\">{{ card().title }}</p>\n\n <!-- <h5 class=\"title\">\n <span [innerHTML]=\"card().characterCard?.data.description | truncate : 100\"></span>\n </h5> -->\n\n <p style=\"margin-top: 40px\">\n <span class=\"title text-shadow-lg/30\" [innerHTML]=\"card().characterCard?.data.creator_notes | truncate : 200\"></span>\n </p>\n\n @if(card().taken){\n\n <div style=\"position: absolute; bottom: 10px; left: 10px\">\n <p-tag icon=\"pi pi-check-circle\" severity=\"secondary\" value=\"Tomada\" [rounded]=\"true\" />\n </div>\n }\n <p-button\n (click)=\"onDetails()\"\n [style]=\"{ position: 'absolute', bottom: '10px', right: '10px' }\"\n icon=\"pi pi-comment\"\n [rounded]=\"true\"\n severity=\"info\"\n [outlined]=\"true\"\n [raised]=\"true\" />\n </div>\n</p-card>\n", styles: [":host{display:block}:host ::ng-deep .p-card{height:100%}:host ::ng-deep .p-card-body{height:100%;padding:0!important}.card-image{width:280px;height:380px;position:relative;align-items:center;display:block;padding:-10px}.card-image img{position:absolute;z-index:3;width:100%;height:100%;opacity:.75;object-fit:cover;transition:opacity .5s}.content{position:absolute;inset:0;z-index:4;padding:1rem;color:#fff;background:linear-gradient(to bottom,#0003,#0000001a);height:100%;display:flex;flex-direction:column;justify-content:space-between}.content:hover{background:linear-gradient(to bottom,color-mix(in srgb,var(--p-primary-color) 20%,transparent),color-mix(in srgb,black 10%,transparent));cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: PopoverModule }, { kind: "pipe", type: TruncatePipe, name: "truncate" }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2$1.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: SpeedDialModule }, { kind: "component", type: i2$5.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$4.Card, selector: "p-card", inputs: ["header", "subheader", "style", "styleClass"] }, { kind: "ngmodule", type: TagModule }, { kind: "component", type: i4$1.Tag, selector: "p-tag", inputs: ["style", "styleClass", "severity", "value", "icon", "rounded"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
4034
4274
  }
4035
4275
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImport: i0, type: DCConversationCardUIComponent, decorators: [{
4036
4276
  type: Component,
@@ -4080,7 +4320,7 @@ class AgentCardListComponent extends PaginationBase {
4080
4320
  }
4081
4321
  subscribeDinamicInstantToEvents() {
4082
4322
  // Clear previous cardEventSubs
4083
- this.clearcardEventSubs();
4323
+ this.clearCardEventSubs();
4084
4324
  this.subscribeToCardEvents();
4085
4325
  }
4086
4326
  subscribeToCardEvents() {
@@ -4094,12 +4334,12 @@ class AgentCardListComponent extends PaginationBase {
4094
4334
  }
4095
4335
  });
4096
4336
  }
4097
- clearcardEventSubs() {
4337
+ clearCardEventSubs() {
4098
4338
  this.cardEventSubs.forEach((sub) => sub.unsubscribe());
4099
4339
  this.cardEventSubs = [];
4100
4340
  }
4101
4341
  ngOnDestroy() {
4102
- this.clearcardEventSubs();
4342
+ this.clearCardEventSubs();
4103
4343
  }
4104
4344
  async loadConversationCards() {
4105
4345
  try {
@@ -4178,6 +4418,8 @@ class AgentCardListComponent extends PaginationBase {
4178
4418
  this.subscribeDinamicInstantToEvents();
4179
4419
  }
4180
4420
  onCardAction(actionEvent) {
4421
+ // This event is only for list component, the one exposed is onAction in the father component
4422
+ console.log(' ->>> onCardAction', actionEvent);
4181
4423
  if (actionEvent.action == 'delete') {
4182
4424
  this.deleteCard(actionEvent.item._id);
4183
4425
  }
@@ -4287,5 +4529,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.4", ngImpor
4287
4529
  * Generated bundle index. Do not edit.
4288
4530
  */
4289
4531
 
4290
- export { AgentCardListComponent, AgentCardProgressStatus, AgentCardsAbstractService, AgentUserProgressService, AudioService, AudioSpeed, CONVERSATION_AI_TOKEN, ChatEventType, ChatMessage, ChatRole, ChatUserSettings, ContextType, ConversationDTO, ConversationEvents, ConversationMessagesDTO, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationCardUIComponent, DCConversationPromptBuilderService, DcAgentCardDetailsComponent, EAccountsPlatform, EvalResultStringDefinition, LangCodeDescriptionEs, MessageContent, MessageOrchestratorComponent, PopupService, ProviderSelectorComponent, TextEngineOptions, TextEngines, TextHighlighterComponent, USER_DATA_EXCHANGE, UserDataExchangeAbstractService, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, markdownBasicToHTML, markdownToHTML$1 as markdownToHTML, markdownToHTML2, markdownToHtml, matchTranscription, provideChatAIService, provideUserDataExchange, removeAllEmojis, removeEmojis };
4532
+ export { AgentCardListComponent, AgentCardProgressStatus, AgentCardsAbstractService, AgentUserProgressService, AudioService, AudioSpeed, CONVERSATION_AI_TOKEN, ChatEventType, ChatMessage, ChatRole, ContextType, ConversationDTO, ConversationEvents, ConversationMessagesDTO, ConversationType, ConversationTypeOptions, DCAgentCardFormComponent, DCChatComponent, DCConversationCardUIComponent, DCConversationPromptBuilderService, DcAgentCardDetailsComponent, EAccountsPlatform, EModelQuality$1 as EModelQuality, EntityThen, EntityWhat, EntityWhatOptions, EntityWhen, EntityWhenOptions, EvalResultStringDefinition, LangCodeDescriptionEs, MessageContent, MessageOrchestratorComponent, PopupService, ProviderSelectorComponent, TextEngineOptions, TextEngines, TextHighlighterComponent, USER_DATA_EXCHANGE, UserDataExchangeAbstractService, VoiceTTSOption, VoiceTTSOptions, WordTimestamps, buildObjectTTSRequest, characterCardStringDataDefinition, convertToHTML, defaultconvUserSettings, extractAudioAndTranscription, extractJsonFromResponse, markdownBasicToHTML, markdownToHTML$1 as markdownToHTML, markdownToHTML2, markdownToHtml, matchTranscription, provideChatAIService, provideUserDataExchange, removeAllEmojis, removeEmojis };
4291
4533
  //# sourceMappingURL=dataclouder-ngx-agent-cards.mjs.map