sf-aiembedded 0.0.5 → 0.0.6
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.
|
@@ -157,6 +157,10 @@ class GeneralAgentComponent {
|
|
|
157
157
|
messages = [];
|
|
158
158
|
isBotWritting = false;
|
|
159
159
|
headerConfig;
|
|
160
|
+
isRecording = false;
|
|
161
|
+
mediaRecorder;
|
|
162
|
+
audioChunks = [];
|
|
163
|
+
recordingStream;
|
|
160
164
|
agentInfo;
|
|
161
165
|
isLoading = false;
|
|
162
166
|
userInput = '';
|
|
@@ -263,30 +267,33 @@ class GeneralAgentComponent {
|
|
|
263
267
|
async send() {
|
|
264
268
|
this.isBotWritting = true;
|
|
265
269
|
const text = this.userInput.trim();
|
|
266
|
-
|
|
270
|
+
const audioFile = this.selectedFiles.find(f => f.type.includes('audio'));
|
|
271
|
+
if (!text && !audioFile) {
|
|
267
272
|
this.isBotWritting = false;
|
|
268
273
|
return;
|
|
269
274
|
}
|
|
270
|
-
//
|
|
271
|
-
if (this.selectedFiles
|
|
275
|
+
// pinta mensajes en UI
|
|
276
|
+
if (this.selectedFiles?.length > 0) {
|
|
272
277
|
this.messages.push({ role: 'user', type: 'file', content: this.selectedFiles });
|
|
273
278
|
}
|
|
274
|
-
|
|
279
|
+
if (text) {
|
|
280
|
+
this.messages.push({ role: 'user', type: 'text', content: text });
|
|
281
|
+
}
|
|
275
282
|
try {
|
|
276
283
|
// Convert files to the format expected by the backend
|
|
277
284
|
const attachments = await this.convertFilesToAttachments(this.selectedFiles || []);
|
|
278
285
|
// Prepare the request object according to SendMessageRequest interface
|
|
279
286
|
const requestData = {
|
|
280
287
|
conversationId: this.sessionId,
|
|
281
|
-
text:
|
|
288
|
+
text: this.userInput.trim() || "",
|
|
282
289
|
files: attachments,
|
|
283
290
|
metadata: {}
|
|
284
291
|
};
|
|
292
|
+
const audio = this.selectedFiles.find(f => f.type.includes('audio'));
|
|
293
|
+
const response = await this.aiAgentsGatewayService.sendMessage(this.idKatios, this.agentId, requestData, audio);
|
|
294
|
+
// limpiar input
|
|
285
295
|
this.userInput = '';
|
|
286
296
|
this.selectedFiles = [];
|
|
287
|
-
// Call the standardized service
|
|
288
|
-
const response = await this.aiAgentsGatewayService.sendMessage(this.idKatios, this.agentId, requestData);
|
|
289
|
-
// Process the response according to ApiResponse<SendMessageResponse>
|
|
290
297
|
if (response.success && response.data) {
|
|
291
298
|
this.sessionId = response.data.conversationId;
|
|
292
299
|
const messages = response.data.messages;
|
|
@@ -310,6 +317,53 @@ class GeneralAgentComponent {
|
|
|
310
317
|
this.isBotWritting = false;
|
|
311
318
|
}
|
|
312
319
|
}
|
|
320
|
+
async startRecording() {
|
|
321
|
+
try {
|
|
322
|
+
// pide permiso al micrófono
|
|
323
|
+
this.recordingStream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
324
|
+
// mimeType: mejor opción común en Chrome/Edge
|
|
325
|
+
const mimeType = MediaRecorder.isTypeSupported('audio/webm;codecs=opus')
|
|
326
|
+
? 'audio/webm;codecs=opus'
|
|
327
|
+
: 'audio/webm';
|
|
328
|
+
this.audioChunks = [];
|
|
329
|
+
this.mediaRecorder = new MediaRecorder(this.recordingStream, { mimeType });
|
|
330
|
+
this.mediaRecorder.ondataavailable = (e) => {
|
|
331
|
+
if (e.data && e.data.size > 0)
|
|
332
|
+
this.audioChunks.push(e.data);
|
|
333
|
+
};
|
|
334
|
+
this.mediaRecorder.onstop = () => {
|
|
335
|
+
const blob = new Blob(this.audioChunks, { type: mimeType });
|
|
336
|
+
// conviértelo a File para reutilizar tu selectedFiles
|
|
337
|
+
const fileName = `audio_${new Date().toISOString().replace(/[:.]/g, '-')}.webm`;
|
|
338
|
+
const audioFile = new File([blob], fileName, { type: mimeType });
|
|
339
|
+
// adjunta como si fuera un archivo subido
|
|
340
|
+
this.selectedFiles.push(audioFile);
|
|
341
|
+
// limpia
|
|
342
|
+
this.audioChunks = [];
|
|
343
|
+
};
|
|
344
|
+
this.mediaRecorder.start();
|
|
345
|
+
this.isRecording = true;
|
|
346
|
+
}
|
|
347
|
+
catch (err) {
|
|
348
|
+
console.error('No se pudo iniciar la grabación:', err);
|
|
349
|
+
this.isRecording = false;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
stopRecording() {
|
|
353
|
+
try {
|
|
354
|
+
if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {
|
|
355
|
+
this.mediaRecorder.stop();
|
|
356
|
+
}
|
|
357
|
+
// detener pistas del micrófono (importantísimo para liberar el icono de mic)
|
|
358
|
+
if (this.recordingStream) {
|
|
359
|
+
this.recordingStream.getTracks().forEach(t => t.stop());
|
|
360
|
+
this.recordingStream = undefined;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
finally {
|
|
364
|
+
this.isRecording = false;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
313
367
|
uploadFile(e) {
|
|
314
368
|
const input = e.target;
|
|
315
369
|
if (input.files && input.files.length > 0) {
|
|
@@ -377,11 +431,11 @@ class GeneralAgentComponent {
|
|
|
377
431
|
return { 'font-size': '2rem', 'width': '2.5rem', 'height': '2.5rem', 'aspect-ratio': '1 / 1' };
|
|
378
432
|
}
|
|
379
433
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: GeneralAgentComponent, deps: [{ token: AI_AGENTS }], target: i0.ɵɵFactoryTarget.Component });
|
|
380
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: GeneralAgentComponent, isStandalone: true, selector: "app-general-agent", inputs: { agentType: "agentType", agentId: "agentId", idKatios: "idKatios" }, viewQueries: [{ propertyName: "chatContainer", first: true, predicate: ["chatContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n
|
|
434
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: GeneralAgentComponent, isStandalone: true, selector: "app-general-agent", inputs: { agentType: "agentType", agentId: "agentId", idKatios: "idKatios" }, viewQueries: [{ propertyName: "chatContainer", first: true, predicate: ["chatContainer"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <!-- NUEVO: grabaci\u00F3n -->\r\n <p-button *ngIf=\"!isRecording\" icon=\"pi pi-microphone\" [text]=\"true\"\r\n (click)=\"startRecording()\" severity=\"contrast\" />\r\n\r\n <p-button *ngIf=\"isRecording\" icon=\"pi pi-stop\" [text]=\"true\"\r\n (click)=\"stopRecording()\" severity=\"danger\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n \r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n [disabled]=\"isBotWritting || (!userInput.trim() && selectedFiles.length === 0)\"\r\n />\r\n </div>\r\n </form>\r\n </div>\r\n <p class=\"mx-auto text-sm text-gray-600 mt-1\">{{headerConfig?.footer}}</p>\r\n </div>\r\n</div>", styles: [".custom-chat{height:calc(100vh - 4rem)}.chat-container{max-width:85%}.file-custom{height:100%}.file-upload-container{display:flex;align-items:center}.custom-size{width:auto;max-width:60rem;padding:0 1rem}.user-chat{background:linear-gradient(to bottom right,#60a5fa,#2563eb);color:#fff}.custom-input{border:none!important;box-shadow:none!important}.custom-input:focus{outline:none!important;box-shadow:none!important}.avatar-responsive{aspect-ratio:1/1;width:2.5rem;height:2.5rem;font-size:2rem;flex-shrink:0}@media (max-width: 768px){.avatar-responsive{width:2rem;height:2rem;font-size:1.5rem}}@media (max-width: 576px){.avatar-responsive{width:1.75rem;height:1.75rem;font-size:1.25rem}}.down{position:absolute;bottom:0;left:50%;transform:translate(-50%)}.custom-message{margin-bottom:150px}.custom-tag{background-color:#ea4b714d;border:1px solid #ea4b71;color:#ea4b71}.scroll{scrollbar-width:thin;scrollbar-color:rgba(188,195,205,.8) transparent}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i2$1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "fluid", "buttonProps"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }, { kind: "ngmodule", type: TagModule }, { kind: "directive", type: Textarea, selector: "[pTextarea], [pInputTextarea]", inputs: ["autoResize", "variant", "fluid", "pSize"], outputs: ["onResize"] }, { kind: "ngmodule", type: ChipModule }, { kind: "component", type: TextComponent, selector: "app-text", inputs: ["text", "role"] }, { kind: "component", type: FileComponent, selector: "app-file", inputs: ["files", "role", "remove"] }, { kind: "component", type: TableComponent, selector: "app-table", inputs: ["table"] }, { kind: "component", type: MarkdownComponent, selector: "app-markdown", inputs: ["content", "role"] }] });
|
|
381
435
|
}
|
|
382
436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: GeneralAgentComponent, decorators: [{
|
|
383
437
|
type: Component,
|
|
384
|
-
args: [{ selector: 'app-general-agent', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, Avatar, TagModule, Textarea, ChipModule, TextComponent, FileComponent, TableComponent, MarkdownComponent], template: "<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n
|
|
438
|
+
args: [{ selector: 'app-general-agent', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, Avatar, TagModule, Textarea, ChipModule, TextComponent, FileComponent, TableComponent, MarkdownComponent], template: "<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <!-- NUEVO: grabaci\u00F3n -->\r\n <p-button *ngIf=\"!isRecording\" icon=\"pi pi-microphone\" [text]=\"true\"\r\n (click)=\"startRecording()\" severity=\"contrast\" />\r\n\r\n <p-button *ngIf=\"isRecording\" icon=\"pi pi-stop\" [text]=\"true\"\r\n (click)=\"stopRecording()\" severity=\"danger\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n \r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n [disabled]=\"isBotWritting || (!userInput.trim() && selectedFiles.length === 0)\"\r\n />\r\n </div>\r\n </form>\r\n </div>\r\n <p class=\"mx-auto text-sm text-gray-600 mt-1\">{{headerConfig?.footer}}</p>\r\n </div>\r\n</div>", styles: [".custom-chat{height:calc(100vh - 4rem)}.chat-container{max-width:85%}.file-custom{height:100%}.file-upload-container{display:flex;align-items:center}.custom-size{width:auto;max-width:60rem;padding:0 1rem}.user-chat{background:linear-gradient(to bottom right,#60a5fa,#2563eb);color:#fff}.custom-input{border:none!important;box-shadow:none!important}.custom-input:focus{outline:none!important;box-shadow:none!important}.avatar-responsive{aspect-ratio:1/1;width:2.5rem;height:2.5rem;font-size:2rem;flex-shrink:0}@media (max-width: 768px){.avatar-responsive{width:2rem;height:2rem;font-size:1.5rem}}@media (max-width: 576px){.avatar-responsive{width:1.75rem;height:1.75rem;font-size:1.25rem}}.down{position:absolute;bottom:0;left:50%;transform:translate(-50%)}.custom-message{margin-bottom:150px}.custom-tag{background-color:#ea4b714d;border:1px solid #ea4b71;color:#ea4b71}.scroll{scrollbar-width:thin;scrollbar-color:rgba(188,195,205,.8) transparent}\n"] }]
|
|
385
439
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
386
440
|
type: Inject,
|
|
387
441
|
args: [AI_AGENTS]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sf-aiembedded.mjs","sources":["../../../projects/general-agent/src/lib/general-agent/types/text/text.component.ts","../../../projects/general-agent/src/lib/general-agent/types/text/text.component.html","../../../projects/general-agent/src/lib/general-agent/types/file/file.component.ts","../../../projects/general-agent/src/lib/general-agent/types/file/file.component.html","../../../projects/general-agent/src/lib/general-agent/types/table/table.component.ts","../../../projects/general-agent/src/lib/general-agent/types/table/table.component.html","../../../projects/general-agent/src/lib/general-agent/types/markdown/markdown.component.ts","../../../projects/general-agent/src/lib/general-agent/types/markdown/markdown.component.html","../../../projects/general-agent/src/lib/agents-backend.port.ts","../../../projects/general-agent/src/lib/general-agent/general-agent.component.ts","../../../projects/general-agent/src/lib/general-agent/general-agent.component.html","../../../projects/general-agent/src/public-api.ts","../../../projects/general-agent/src/sf-aiembedded.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\n//import { Avatar } from 'primeng/avatar';\r\n\r\n@Component({\r\n selector: 'app-text',\r\n standalone: true,\r\n imports: [CommonModule,FormsModule],\r\n templateUrl: './text.component.html',\r\n styleUrl: './text.component.scss'\r\n})\r\nexport class TextComponent {\r\n @Input() text: string = '';\r\n @Input() role: string = '';\r\n\r\n}\r\n","<div\r\nclass=\"shadow-1 border-1 border-gray-200 px-3 py-2 border-round-bottom-xl w-fit\"\r\n[ngClass]=\"role !== 'user' ? 'bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl' : 'border-round-left-xl border-round-right-sm user-chat'\"\r\n>\r\n<span class=\"text-sm m-0 whitespace-normal md:text-base lg:text-lg\" style=\"word-break: break-word;\">{{text}}</span>\r\n</div>","import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { ButtonModule } from 'primeng/button';\r\n\r\n@Component({\r\n selector: 'app-file',\r\n standalone: true,\r\n imports: [CommonModule,FormsModule,ButtonModule,Avatar],\r\n templateUrl: './file.component.html',\r\n styleUrl: './file.component.scss'\r\n})\r\nexport class FileComponent {\r\n @Input() files: File[] = [];\r\n @Input() role: string = 'assistant';\r\n @Input() remove: boolean = false;\r\n\r\n getFileIcon(mime: string): string {\r\n if (mime.includes('pdf')) return 'pi pi-file-pdf';\r\n if (mime.includes('image')) return 'pi pi-image';\r\n if (mime.includes('audio')) return 'pi pi-volume-up';\r\n if (mime.includes('video')) return 'pi pi-video';\r\n if (mime.includes('zip')) return 'pi pi-file-zip';\r\n if (mime.includes('xlsx')) return 'pi pi-file-excel';\r\n return 'pi pi-file';\r\n }\r\n getFileClasses(mime: string): string {\r\n if (mime.includes('pdf')) return 'bg-red-500 border-red-800 text-white';\r\n if (mime.includes('image')) return 'bg-gray-100 border-gray-200 text-white';\r\n if (mime.includes('audio')) return 'bg-blue-500 border-blue-800 text-white';\r\n if (mime.includes('video')) return 'bg-yellow-500 border-yellow-800 text-white';\r\n if (mime.includes('zip')) return 'bg-indigo-500 border-indigo-800 text-white';\r\n if (mime.includes('xlsx')) return 'bg-green-500 border-green-800 text-white';\r\n return 'bg-gray-100 border-3 border-gray-200 text-gray-500';\r\n }\r\n removeSelectedFile(i: number) {\r\n this.files.splice(i,1);\r\n }\r\n getGridClass(){\r\n const fileCount = this.files.length;\r\n if (fileCount === 1) {\r\n return 'col-12';\r\n } else if (fileCount === 2) {\r\n return 'col-12 sm:col-6';\r\n } else {\r\n return 'col-12 sm:col-6 md:col-4';\r\n }\r\n }\r\n\r\n}\r\n","<div *ngIf=\"!remove\" class=\"grid w-full m-o\" [ngClass]=\"role !== 'user' ? 'items-start justify-content-start' : 'items-end justify-content-end'\">\r\n <div *ngFor=\"let file of files\" [ngClass]=\"getGridClass()\">\r\n <div class=\"flex align-items-center gap-3 border-1 border-gray-300 border-round-2xl p-2 bg-gray-100 h-full\">\r\n <p-avatar class=\"p-1 border-1 avatar-responsive\" [ngClass]=\"getFileClasses(file.name)\" [icon]=\"getFileIcon(file.name)\"></p-avatar>\r\n <div class=\"flex flex-column overflow-hidden\" style=\"min-width: 0;\">\r\n <span class=\"text-sm font-semibold text-gray-500 md:text-base lg:text-lg\" style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n {{ file.name }}\r\n </span>\r\n <p class=\"text-xs text-gray-400 md:text-sm lg:text-base\" style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n ({{ file.type || 'Archivo' }})\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"remove\" class=\"grid w-full\">\r\n <div *ngFor=\"let file of files; let i = index\" class=\"col-12 sm:col-6 md:col-4\">\r\n <div class=\"relative border-1 border-gray-300 border-round-xl p-2 h-full\">\r\n <p-button icon=\"pi pi-times\" [rounded]=\"true\" variant=\"text\" severity=\"secondary\" class=\"no-hover absolute top-0 right-0 z-1\" (click)=\"removeSelectedFile(i)\" size=\"small\"/>\r\n <div class=\"flex align-items-center gap-3\">\r\n <p-avatar \r\n class=\"p-1 border-1 avatar-responsive\"\r\n [ngClass]=\"getFileClasses(file.name)\" \r\n [icon]=\"getFileIcon(file.name)\" \r\n >\r\n </p-avatar>\r\n \r\n <div class=\"flex flex-column overflow-hidden\" style=\"min-width: 0;\">\r\n <span class=\"text-sm font-semibold text-gray-500 md:text-base lg:text-lg\" \r\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n {{ file.name }}\r\n </span>\r\n <p class=\"text-xs text-gray-400 md:text-sm lg:text-base\" \r\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n ({{ file.type || 'archivo' }})\r\n </p>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</div>","import { Component, Input } from '@angular/core';\r\n\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-table',\r\n imports: [CommonModule],\r\n templateUrl: './table.component.html',\r\n styleUrl: './table.component.scss'\r\n})\r\nexport class TableComponent {\r\n @Input() table: string = \"\";\r\n}\r\n","<div\r\n *ngIf=\"table\"\r\n class=\"mt-2 overflow-auto\"\r\n [innerHTML]=\"table\"\r\n style=\"max-width: 100%; overflow-x: auto;\"\r\n></div>","import { Component, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { marked, RendererObject } from 'marked';\r\nimport hljs from 'highlight.js';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Avatar } from 'primeng/avatar';\r\n\r\n// marked.setOptions({\r\n// highlight: (code, lang) => {\r\n// if (lang && hljs.getLanguage(lang)) {\r\n// return hljs.highlight(code, { language: lang }).value;\r\n// }\r\n// return hljs.highlightAuto(code).value;\r\n// }\r\n// });\r\n\r\nconst renderer: RendererObject = {\r\n link(token) {\r\n const href = token.href ?? '';\r\n const title = token.title ? ` title=\"${token.title}\"` : '';\r\n const text = token.text ?? token.raw ?? href;\r\n\r\n return `<a href=\"${href}\"${title} target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>`;\r\n },\r\n};\r\n\r\nmarked.use({ renderer });\r\n\r\n@Component({\r\n selector: 'app-markdown',\r\n standalone: true,\r\n imports: [CommonModule,Avatar],\r\n templateUrl: './markdown.component.html',\r\n styleUrl: './markdown.component.scss',\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\nexport class MarkdownComponent implements OnChanges {\r\n @Input() content = '';\r\n @Input() role = '';\r\n safeHtml: SafeHtml = '';\r\n constructor(private sanitizer: DomSanitizer) {}\r\n\r\n\r\n async ngOnChanges(changes: SimpleChanges) {\r\n if ('content' in changes) {\r\n const rawHtml = await marked.parse(this.content || '');\r\n this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(rawHtml);\r\n }\r\n }\r\n}\r\n","<div [ngClass]=\"role !== 'user' ? 'flex items-start gap-2' : ''\">\r\n <p-avatar\r\n *ngIf=\"role !== 'user'\" \r\n image=\"./images/bot.png\"\r\n class=\"bg-gray-100 border-3 border-gray-300 p-1\"\r\n shape=\"circle\" \r\n size=\"large\"\r\n [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div>\r\n <div class=\"markdown-container\" [innerHTML]=\"safeHtml\"></div>\r\n </div>\r\n</div>\r\n\r\n","// projects/general-agent/src/lib/agents-backend.port.ts\r\nimport { InjectionToken } from '@angular/core';\r\n\r\nexport interface AiAgentsGatewayService {\r\n getAgent(idKatios: string, agentId: string): Promise<any>;\r\n sendMessage(idKatios: string, agentId: string, req: {\r\n conversationId?: string;\r\n text: string;\r\n files: Array<{fileName:string; contentType:string; base64Data:string;}>;\r\n metadata?: any;\r\n }): Promise<{\r\n conversationId: string;\r\n messages: Array<{ role?: string; type?: string; content: any }>;\r\n }>;\r\n}\r\n\r\nexport const AI_AGENTS = new InjectionToken<AiAgentsGatewayService>('AI_AGENTS');\r\n","import { Component, OnInit, ViewChild, ElementRef, AfterViewChecked, Input, Inject, SimpleChanges } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { TagModule } from 'primeng/tag';\r\nimport { Textarea } from 'primeng/textarea';\r\nimport { ChipModule } from 'primeng/chip';\r\nimport { TextComponent } from './types/text/text.component';\r\nimport { FileComponent } from './types/file/file.component';\r\nimport { TableComponent } from './types/table/table.component';\r\nimport { MarkdownComponent } from './types/markdown/markdown.component';\r\n\r\nimport { AI_AGENTS, AiAgentsGatewayService } from '../agents-backend.port';\r\n\r\n@Component({\r\n selector: 'app-general-agent',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, ButtonModule, Avatar, TagModule, Textarea, ChipModule, TextComponent, FileComponent, TableComponent, MarkdownComponent],\r\n templateUrl: './general-agent.component.html',\r\n styleUrl: './general-agent.component.scss'\r\n})\r\nexport class GeneralAgentComponent implements OnInit, AfterViewChecked {\r\n @ViewChild('chatContainer') private chatContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // Propiedades internas (ya no inputs/outputs)\r\n messages: { content: any; type: string; role: string; }[] = [];\r\n isBotWritting: boolean = false;\r\n headerConfig?: {\r\n title?: string;\r\n subtitle?: string;\r\n initialMessages?: string[];\r\n type: string;\r\n placeholder?: string;\r\n footer?: string;\r\n };\r\n\r\n agentInfo: any;\r\n public isLoading: boolean = false;\r\n userInput = '';\r\n configuration: any;\r\n selectedFiles: File[] = [];\r\n sessionId: string = '';\r\n @Input() agentType = '';\r\n @Input() agentId = '';\r\n @Input() idKatios = '';\r\n\r\n constructor(\r\n @Inject(AI_AGENTS) private aiAgentsGatewayService: AiAgentsGatewayService\r\n ) { }\r\n\r\n async ngOnInit() {\r\n await this.loadAgent();\r\n }\r\n async ngOnChanges(changes: SimpleChanges) {\r\n if (changes['agentId'] || changes['agentType'] || changes['idKatios']) {\r\n await this.loadAgent();\r\n }\r\n }\r\n\r\n ngAfterViewChecked() {\r\n this.scrollToBottom();\r\n }\r\n\r\n private scrollToBottom(behavior: ScrollBehavior = 'smooth'): void {\r\n if (!this.chatContainer) return;\r\n const el = this.chatContainer.nativeElement;\r\n el.scrollTo({ top: el.scrollHeight, behavior });\r\n }\r\n\r\n async loadAgent() {\r\n this.isLoading = true;\r\n this.isBotWritting = false;\r\n this.messages = [];\r\n this.sessionId = \"\";\r\n try {\r\n\r\n const agentInfo = await this.aiAgentsGatewayService.getAgent(this.idKatios, this.agentId) as any;\r\n\r\n if (agentInfo.statusCode === 200) {\r\n this.agentInfo = JSON.parse(agentInfo.data.rawConfig);\r\n let configurationAgent = null;\r\n if (this.agentInfo.config?.i18n?.en) {\r\n configurationAgent = this.agentInfo.config.i18n.en;\r\n }\r\n else {\r\n configurationAgent = this.agentInfo.config.setUp;\r\n }\r\n\r\n this.headerConfig = {\r\n title: configurationAgent.title,\r\n subtitle: configurationAgent.subtitle,\r\n initialMessages: this.agentInfo.config.initialMessages,\r\n type: this.agentType,\r\n placeholder: configurationAgent.inputPlaceholder,\r\n footer: configurationAgent.footer\r\n };\r\n\r\n this.isLoading = false;\r\n }\r\n } catch (error) {\r\n console.error('An error occurred:', error);\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n get isInitial(): boolean {\r\n return this.messages.length === 0 && !this.isBotWritting;\r\n }\r\n\r\n /**\r\n * Converts File objects to Attachment format expected by the backend\r\n */\r\n private async convertFilesToAttachments(files: File[]): Promise<any[]> {\r\n if (!files || files.length === 0) {\r\n return [];\r\n }\r\n\r\n const attachments = [];\r\n for (const file of files) {\r\n try {\r\n const base64Data = await this.fileToBase64(file);\r\n const attachment = {\r\n fileName: file.name,\r\n contentType: file.type,\r\n base64Data: base64Data\r\n };\r\n attachments.push(attachment);\r\n } catch (error) {\r\n console.error(`Error converting file ${file.name} to base64:`, error);\r\n }\r\n }\r\n\r\n return attachments;\r\n }\r\n\r\n /**\r\n * Converts a File object to base64 string\r\n */\r\n private fileToBase64(file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.readAsDataURL(file);\r\n reader.onload = () => {\r\n // Remove the data URL prefix (e.g., \"data:image/png;base64,\")\r\n const base64String = (reader.result as string).split(',')[1];\r\n resolve(base64String);\r\n };\r\n reader.onerror = error => reject(error);\r\n });\r\n }\r\n\r\n async send() {\r\n this.isBotWritting = true;\r\n\r\n const text = this.userInput.trim();\r\n if (!text) {\r\n this.isBotWritting = false;\r\n return;\r\n }\r\n\r\n // Add user message to chat\r\n if (this.selectedFiles && this.selectedFiles.length > 0) {\r\n this.messages.push({ role: 'user', type: 'file', content: this.selectedFiles });\r\n }\r\n this.messages.push({ role: 'user', type: 'text', content: text });\r\n\r\n try {\r\n // Convert files to the format expected by the backend\r\n const attachments = await this.convertFilesToAttachments(this.selectedFiles || []);\r\n\r\n // Prepare the request object according to SendMessageRequest interface\r\n const requestData = {\r\n conversationId: this.sessionId,\r\n text: text,\r\n files: attachments,\r\n metadata: {}\r\n };\r\n\r\n this.userInput = '';\r\n this.selectedFiles = [];\r\n // Call the standardized service\r\n const response = await this.aiAgentsGatewayService.sendMessage(\r\n this.idKatios,\r\n this.agentId,\r\n requestData\r\n ) as any;\r\n\r\n // Process the response according to ApiResponse<SendMessageResponse>\r\n if (response.success && response.data) {\r\n this.sessionId = response.data.conversationId;\r\n const messages = response.data.messages;\r\n messages.forEach((m: any) => {\r\n if (m.type === 'table') {\r\n this.messages.push({ role: m.role || 'assistant', type: 'table', content: m.content });\r\n } else {\r\n this.messages.push({ role: m.role || 'assistant', type: m.type || 'markdown', content: m.content });\r\n }\r\n });\r\n \r\n } else {\r\n console.error('Error in response:', response);\r\n }\r\n } catch (error) {\r\n console.error('Error sending message:', error);\r\n } finally {\r\n this.isBotWritting = false;\r\n }\r\n }\r\n\r\n uploadFile(e: any) {\r\n const input = e.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n const newFiles = Array.from(input.files);\r\n\r\n // Agrega los archivos nuevos sin duplicar por nombre\r\n for (const file of newFiles) {\r\n if (!this.selectedFiles.some(f => f.name === file.name && f.size === file.size)) {\r\n this.selectedFiles.push(file);\r\n }\r\n }\r\n }\r\n }\r\n\r\n getFileIcon(mime: string): string {\r\n if (mime.includes('pdf')) return 'pi pi-file-pdf';\r\n if (mime.includes('image')) return 'pi pi-image';\r\n if (mime.includes('audio')) return 'pi pi-volume-up';\r\n if (mime.includes('video')) return 'pi pi-video';\r\n if (mime.includes('zip')) return 'pi pi-file-zip';\r\n if (mime.includes('xlsx')) return 'pi pi-file-excel';\r\n return 'pi pi-file';\r\n }\r\n\r\n getFileClasses(mime: string): string {\r\n if (mime.includes('pdf')) return 'bg-red-500 border-red-800 text-white';\r\n if (mime.includes('image')) return 'bg-gray-100 border-gray-200 text-white';\r\n if (mime.includes('audio')) return 'bg-blue-500 border-blue-800 text-white';\r\n if (mime.includes('video')) return 'bg-yellow-500 border-yellow-800 text-white';\r\n if (mime.includes('zip')) return 'bg-indigo-500 border-indigo-800 text-white';\r\n if (mime.includes('xlsx')) return 'bg-green-500 border-green-800 text-white';\r\n return 'bg-gray-100 border-3 border-gray-200 text-gray-500';\r\n }\r\n\r\n removeSelectedFile(i: number) {\r\n this.selectedFiles.splice(i, 1);\r\n }\r\n\r\n handleKeyDown(event: KeyboardEvent) {\r\n const trimmedInput = this.userInput?.trim();\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n if (!trimmedInput || this.isBotWritting) {\r\n event.preventDefault();\r\n return;\r\n\r\n }\r\n event.preventDefault();\r\n this.send();\r\n }\r\n }\r\n\r\n getAvatarStyles(): { [key: string]: string } {\r\n const width = window.innerWidth;\r\n if (width < 576) {\r\n return { 'font-size': '1.25rem', 'width': '2rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n if (width < 768) {\r\n return { 'font-size': '1.5rem', 'width': '2.25rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n return { 'font-size': '2rem', 'width': '2.5rem', 'height': '2.5rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n\r\n\r\n}\r\n","<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n [disabled]=\"isBotWritting || !userInput.trim()\" />\r\n </div>\r\n </form>\r\n </div>\r\n <p class=\"mx-auto text-sm text-gray-600 mt-1\">{{headerConfig?.footer}}</p>\r\n </div>\r\n</div>","/*\r\n * Public API Surface of general-agent\r\n */\r\n\r\nexport * from './lib/general-agent/general-agent.component';\r\nexport * from './lib/agents-backend.port';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2","i3"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"sf-aiembedded.mjs","sources":["../../../projects/general-agent/src/lib/general-agent/types/text/text.component.ts","../../../projects/general-agent/src/lib/general-agent/types/text/text.component.html","../../../projects/general-agent/src/lib/general-agent/types/file/file.component.ts","../../../projects/general-agent/src/lib/general-agent/types/file/file.component.html","../../../projects/general-agent/src/lib/general-agent/types/table/table.component.ts","../../../projects/general-agent/src/lib/general-agent/types/table/table.component.html","../../../projects/general-agent/src/lib/general-agent/types/markdown/markdown.component.ts","../../../projects/general-agent/src/lib/general-agent/types/markdown/markdown.component.html","../../../projects/general-agent/src/lib/agents-backend.port.ts","../../../projects/general-agent/src/lib/general-agent/general-agent.component.ts","../../../projects/general-agent/src/lib/general-agent/general-agent.component.html","../../../projects/general-agent/src/public-api.ts","../../../projects/general-agent/src/sf-aiembedded.ts"],"sourcesContent":["import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\n//import { Avatar } from 'primeng/avatar';\r\n\r\n@Component({\r\n selector: 'app-text',\r\n standalone: true,\r\n imports: [CommonModule,FormsModule],\r\n templateUrl: './text.component.html',\r\n styleUrl: './text.component.scss'\r\n})\r\nexport class TextComponent {\r\n @Input() text: string = '';\r\n @Input() role: string = '';\r\n\r\n}\r\n","<div\r\nclass=\"shadow-1 border-1 border-gray-200 px-3 py-2 border-round-bottom-xl w-fit\"\r\n[ngClass]=\"role !== 'user' ? 'bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl' : 'border-round-left-xl border-round-right-sm user-chat'\"\r\n>\r\n<span class=\"text-sm m-0 whitespace-normal md:text-base lg:text-lg\" style=\"word-break: break-word;\">{{text}}</span>\r\n</div>","import { CommonModule } from '@angular/common';\r\nimport { Component, Input } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { ButtonModule } from 'primeng/button';\r\n\r\n@Component({\r\n selector: 'app-file',\r\n standalone: true,\r\n imports: [CommonModule,FormsModule,ButtonModule,Avatar],\r\n templateUrl: './file.component.html',\r\n styleUrl: './file.component.scss'\r\n})\r\nexport class FileComponent {\r\n @Input() files: File[] = [];\r\n @Input() role: string = 'assistant';\r\n @Input() remove: boolean = false;\r\n\r\n getFileIcon(mime: string): string {\r\n if (mime.includes('pdf')) return 'pi pi-file-pdf';\r\n if (mime.includes('image')) return 'pi pi-image';\r\n if (mime.includes('audio')) return 'pi pi-volume-up';\r\n if (mime.includes('video')) return 'pi pi-video';\r\n if (mime.includes('zip')) return 'pi pi-file-zip';\r\n if (mime.includes('xlsx')) return 'pi pi-file-excel';\r\n return 'pi pi-file';\r\n }\r\n getFileClasses(mime: string): string {\r\n if (mime.includes('pdf')) return 'bg-red-500 border-red-800 text-white';\r\n if (mime.includes('image')) return 'bg-gray-100 border-gray-200 text-white';\r\n if (mime.includes('audio')) return 'bg-blue-500 border-blue-800 text-white';\r\n if (mime.includes('video')) return 'bg-yellow-500 border-yellow-800 text-white';\r\n if (mime.includes('zip')) return 'bg-indigo-500 border-indigo-800 text-white';\r\n if (mime.includes('xlsx')) return 'bg-green-500 border-green-800 text-white';\r\n return 'bg-gray-100 border-3 border-gray-200 text-gray-500';\r\n }\r\n removeSelectedFile(i: number) {\r\n this.files.splice(i,1);\r\n }\r\n getGridClass(){\r\n const fileCount = this.files.length;\r\n if (fileCount === 1) {\r\n return 'col-12';\r\n } else if (fileCount === 2) {\r\n return 'col-12 sm:col-6';\r\n } else {\r\n return 'col-12 sm:col-6 md:col-4';\r\n }\r\n }\r\n\r\n}\r\n","<div *ngIf=\"!remove\" class=\"grid w-full m-o\" [ngClass]=\"role !== 'user' ? 'items-start justify-content-start' : 'items-end justify-content-end'\">\r\n <div *ngFor=\"let file of files\" [ngClass]=\"getGridClass()\">\r\n <div class=\"flex align-items-center gap-3 border-1 border-gray-300 border-round-2xl p-2 bg-gray-100 h-full\">\r\n <p-avatar class=\"p-1 border-1 avatar-responsive\" [ngClass]=\"getFileClasses(file.name)\" [icon]=\"getFileIcon(file.name)\"></p-avatar>\r\n <div class=\"flex flex-column overflow-hidden\" style=\"min-width: 0;\">\r\n <span class=\"text-sm font-semibold text-gray-500 md:text-base lg:text-lg\" style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n {{ file.name }}\r\n </span>\r\n <p class=\"text-xs text-gray-400 md:text-sm lg:text-base\" style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n ({{ file.type || 'Archivo' }})\r\n </p>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<div *ngIf=\"remove\" class=\"grid w-full\">\r\n <div *ngFor=\"let file of files; let i = index\" class=\"col-12 sm:col-6 md:col-4\">\r\n <div class=\"relative border-1 border-gray-300 border-round-xl p-2 h-full\">\r\n <p-button icon=\"pi pi-times\" [rounded]=\"true\" variant=\"text\" severity=\"secondary\" class=\"no-hover absolute top-0 right-0 z-1\" (click)=\"removeSelectedFile(i)\" size=\"small\"/>\r\n <div class=\"flex align-items-center gap-3\">\r\n <p-avatar \r\n class=\"p-1 border-1 avatar-responsive\"\r\n [ngClass]=\"getFileClasses(file.name)\" \r\n [icon]=\"getFileIcon(file.name)\" \r\n >\r\n </p-avatar>\r\n \r\n <div class=\"flex flex-column overflow-hidden\" style=\"min-width: 0;\">\r\n <span class=\"text-sm font-semibold text-gray-500 md:text-base lg:text-lg\" \r\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n {{ file.name }}\r\n </span>\r\n <p class=\"text-xs text-gray-400 md:text-sm lg:text-base\" \r\n style=\"white-space: nowrap; overflow: hidden; text-overflow: ellipsis;\">\r\n ({{ file.type || 'archivo' }})\r\n </p>\r\n </div>\r\n </div>\r\n\r\n </div>\r\n </div>\r\n</div>","import { Component, Input } from '@angular/core';\r\n\r\nimport { CommonModule } from '@angular/common';\r\n\r\n@Component({\r\n selector: 'app-table',\r\n imports: [CommonModule],\r\n templateUrl: './table.component.html',\r\n styleUrl: './table.component.scss'\r\n})\r\nexport class TableComponent {\r\n @Input() table: string = \"\";\r\n}\r\n","<div\r\n *ngIf=\"table\"\r\n class=\"mt-2 overflow-auto\"\r\n [innerHTML]=\"table\"\r\n style=\"max-width: 100%; overflow-x: auto;\"\r\n></div>","import { Component, Input, OnChanges, SimpleChanges, ViewEncapsulation } from '@angular/core';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\nimport { marked, RendererObject } from 'marked';\r\nimport hljs from 'highlight.js';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Avatar } from 'primeng/avatar';\r\n\r\n// marked.setOptions({\r\n// highlight: (code, lang) => {\r\n// if (lang && hljs.getLanguage(lang)) {\r\n// return hljs.highlight(code, { language: lang }).value;\r\n// }\r\n// return hljs.highlightAuto(code).value;\r\n// }\r\n// });\r\n\r\nconst renderer: RendererObject = {\r\n link(token) {\r\n const href = token.href ?? '';\r\n const title = token.title ? ` title=\"${token.title}\"` : '';\r\n const text = token.text ?? token.raw ?? href;\r\n\r\n return `<a href=\"${href}\"${title} target=\"_blank\" rel=\"noopener noreferrer\">${text}</a>`;\r\n },\r\n};\r\n\r\nmarked.use({ renderer });\r\n\r\n@Component({\r\n selector: 'app-markdown',\r\n standalone: true,\r\n imports: [CommonModule,Avatar],\r\n templateUrl: './markdown.component.html',\r\n styleUrl: './markdown.component.scss',\r\n encapsulation: ViewEncapsulation.None,\r\n})\r\nexport class MarkdownComponent implements OnChanges {\r\n @Input() content = '';\r\n @Input() role = '';\r\n safeHtml: SafeHtml = '';\r\n constructor(private sanitizer: DomSanitizer) {}\r\n\r\n\r\n async ngOnChanges(changes: SimpleChanges) {\r\n if ('content' in changes) {\r\n const rawHtml = await marked.parse(this.content || '');\r\n this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(rawHtml);\r\n }\r\n }\r\n}\r\n","<div [ngClass]=\"role !== 'user' ? 'flex items-start gap-2' : ''\">\r\n <p-avatar\r\n *ngIf=\"role !== 'user'\" \r\n image=\"./images/bot.png\"\r\n class=\"bg-gray-100 border-3 border-gray-300 p-1\"\r\n shape=\"circle\" \r\n size=\"large\"\r\n [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div>\r\n <div class=\"markdown-container\" [innerHTML]=\"safeHtml\"></div>\r\n </div>\r\n</div>\r\n\r\n","// projects/general-agent/src/lib/agents-backend.port.ts\r\nimport { InjectionToken } from '@angular/core';\r\n\r\nexport interface AiAgentsGatewayService {\r\n getAgent(idKatios: string, agentId: string): Promise<any>;\r\n sendMessage(idKatios: string, agentId: string, req: {\r\n conversationId?: string;\r\n text: string;\r\n files: Array<{fileName:string; contentType:string; base64Data:string;}>;\r\n metadata?: any;\r\n }, audio? : File): Promise<{\r\n conversationId: string;\r\n messages: Array<{ role?: string; type?: string; content: any }>;\r\n }>;\r\n}\r\n\r\nexport const AI_AGENTS = new InjectionToken<AiAgentsGatewayService>('AI_AGENTS');\r\n","import { Component, OnInit, ViewChild, ElementRef, AfterViewChecked, Input, Inject, SimpleChanges } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ButtonModule } from 'primeng/button';\r\nimport { Avatar } from 'primeng/avatar';\r\nimport { TagModule } from 'primeng/tag';\r\nimport { Textarea } from 'primeng/textarea';\r\nimport { ChipModule } from 'primeng/chip';\r\nimport { TextComponent } from './types/text/text.component';\r\nimport { FileComponent } from './types/file/file.component';\r\nimport { TableComponent } from './types/table/table.component';\r\nimport { MarkdownComponent } from './types/markdown/markdown.component';\r\n\r\nimport { AI_AGENTS, AiAgentsGatewayService } from '../agents-backend.port';\r\n\r\n@Component({\r\n selector: 'app-general-agent',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, ButtonModule, Avatar, TagModule, Textarea, ChipModule, TextComponent, FileComponent, TableComponent, MarkdownComponent],\r\n templateUrl: './general-agent.component.html',\r\n styleUrl: './general-agent.component.scss'\r\n})\r\nexport class GeneralAgentComponent implements OnInit, AfterViewChecked {\r\n @ViewChild('chatContainer') private chatContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // Propiedades internas (ya no inputs/outputs)\r\n messages: { content: any; type: string; role: string; }[] = [];\r\n isBotWritting: boolean = false;\r\n headerConfig?: {\r\n title?: string;\r\n subtitle?: string;\r\n initialMessages?: string[];\r\n type: string;\r\n placeholder?: string;\r\n footer?: string;\r\n };\r\n isRecording = false;\r\n private mediaRecorder?: MediaRecorder;\r\n private audioChunks: BlobPart[] = [];\r\n private recordingStream?: MediaStream;\r\n agentInfo: any;\r\n public isLoading: boolean = false;\r\n userInput = '';\r\n configuration: any;\r\n selectedFiles: File[] = [];\r\n sessionId: string = '';\r\n @Input() agentType = '';\r\n @Input() agentId = '';\r\n @Input() idKatios = '';\r\n\r\n constructor(\r\n @Inject(AI_AGENTS) private aiAgentsGatewayService: AiAgentsGatewayService\r\n ) { }\r\n\r\n async ngOnInit() {\r\n await this.loadAgent();\r\n }\r\n async ngOnChanges(changes: SimpleChanges) {\r\n if (changes['agentId'] || changes['agentType'] || changes['idKatios']) {\r\n await this.loadAgent();\r\n }\r\n }\r\n\r\n ngAfterViewChecked() {\r\n this.scrollToBottom();\r\n }\r\n\r\n private scrollToBottom(behavior: ScrollBehavior = 'smooth'): void {\r\n if (!this.chatContainer) return;\r\n const el = this.chatContainer.nativeElement;\r\n el.scrollTo({ top: el.scrollHeight, behavior });\r\n }\r\n\r\n async loadAgent() {\r\n this.isLoading = true;\r\n this.isBotWritting = false;\r\n this.messages = [];\r\n this.sessionId = \"\";\r\n try {\r\n\r\n const agentInfo = await this.aiAgentsGatewayService.getAgent(this.idKatios, this.agentId) as any;\r\n\r\n if (agentInfo.statusCode === 200) {\r\n this.agentInfo = JSON.parse(agentInfo.data.rawConfig);\r\n let configurationAgent = null;\r\n if (this.agentInfo.config?.i18n?.en) {\r\n configurationAgent = this.agentInfo.config.i18n.en;\r\n }\r\n else {\r\n configurationAgent = this.agentInfo.config.setUp;\r\n }\r\n\r\n this.headerConfig = {\r\n title: configurationAgent.title,\r\n subtitle: configurationAgent.subtitle,\r\n initialMessages: this.agentInfo.config.initialMessages,\r\n type: this.agentType,\r\n placeholder: configurationAgent.inputPlaceholder,\r\n footer: configurationAgent.footer\r\n };\r\n\r\n this.isLoading = false;\r\n }\r\n } catch (error) {\r\n console.error('An error occurred:', error);\r\n this.isLoading = false;\r\n }\r\n }\r\n\r\n get isInitial(): boolean {\r\n return this.messages.length === 0 && !this.isBotWritting;\r\n }\r\n\r\n /**\r\n * Converts File objects to Attachment format expected by the backend\r\n */\r\n private async convertFilesToAttachments(files: File[]): Promise<any[]> {\r\n if (!files || files.length === 0) {\r\n return [];\r\n }\r\n\r\n const attachments = [];\r\n for (const file of files) {\r\n try {\r\n const base64Data = await this.fileToBase64(file);\r\n const attachment = {\r\n fileName: file.name,\r\n contentType: file.type,\r\n base64Data: base64Data\r\n };\r\n attachments.push(attachment);\r\n } catch (error) {\r\n console.error(`Error converting file ${file.name} to base64:`, error);\r\n }\r\n }\r\n\r\n return attachments;\r\n }\r\n\r\n /**\r\n * Converts a File object to base64 string\r\n */\r\n private fileToBase64(file: File): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.readAsDataURL(file);\r\n reader.onload = () => {\r\n // Remove the data URL prefix (e.g., \"data:image/png;base64,\")\r\n const base64String = (reader.result as string).split(',')[1];\r\n resolve(base64String);\r\n };\r\n reader.onerror = error => reject(error);\r\n });\r\n }\r\n\r\n async send() {\r\n this.isBotWritting = true;\r\n \r\n const text = this.userInput.trim();\r\n const audioFile = this.selectedFiles.find(f => f.type.includes('audio'));\r\n \r\n if (!text && !audioFile) {\r\n this.isBotWritting = false;\r\n return;\r\n }\r\n \r\n // pinta mensajes en UI\r\n if (this.selectedFiles?.length > 0) {\r\n this.messages.push({ role: 'user', type: 'file', content: this.selectedFiles });\r\n }\r\n if (text) {\r\n this.messages.push({ role: 'user', type: 'text', content: text });\r\n }\r\n \r\n try {\r\n // Convert files to the format expected by the backend\r\n const attachments = await this.convertFilesToAttachments(this.selectedFiles || []);\r\n\r\n // Prepare the request object according to SendMessageRequest interface\r\n const requestData = {\r\n conversationId: this.sessionId,\r\n text: this.userInput.trim() || \"\",\r\n files: attachments,\r\n metadata: {}\r\n };\r\n \r\n const audio = this.selectedFiles.find(f => f.type.includes('audio'));\r\n const response = await this.aiAgentsGatewayService.sendMessage(this.idKatios, this.agentId, requestData, audio) as any;\r\n \r\n // limpiar input\r\n this.userInput = '';\r\n this.selectedFiles = [];\r\n \r\n if (response.success && response.data) {\r\n this.sessionId = response.data.conversationId;\r\n const messages = response.data.messages;\r\n messages.forEach((m: any) => {\r\n if (m.type === 'table') {\r\n this.messages.push({ role: m.role || 'assistant', type: 'table', content: m.content });\r\n } else {\r\n this.messages.push({ role: m.role || 'assistant', type: m.type || 'markdown', content: m.content });\r\n }\r\n });\r\n } else {\r\n console.error('Error in response:', response);\r\n }\r\n \r\n } catch (error) {\r\n console.error('Error sending message:', error);\r\n } finally {\r\n this.isBotWritting = false;\r\n }\r\n }\r\n async startRecording() {\r\n try {\r\n // pide permiso al micrófono\r\n this.recordingStream = await navigator.mediaDevices.getUserMedia({ audio: true });\r\n \r\n // mimeType: mejor opción común en Chrome/Edge\r\n const mimeType = MediaRecorder.isTypeSupported('audio/webm;codecs=opus')\r\n ? 'audio/webm;codecs=opus'\r\n : 'audio/webm';\r\n \r\n this.audioChunks = [];\r\n this.mediaRecorder = new MediaRecorder(this.recordingStream, { mimeType });\r\n \r\n this.mediaRecorder.ondataavailable = (e: BlobEvent) => {\r\n if (e.data && e.data.size > 0) this.audioChunks.push(e.data);\r\n };\r\n \r\n this.mediaRecorder.onstop = () => {\r\n const blob = new Blob(this.audioChunks, { type: mimeType });\r\n \r\n // conviértelo a File para reutilizar tu selectedFiles\r\n const fileName = `audio_${new Date().toISOString().replace(/[:.]/g, '-')}.webm`;\r\n const audioFile = new File([blob], fileName, { type: mimeType });\r\n \r\n // adjunta como si fuera un archivo subido\r\n this.selectedFiles.push(audioFile);\r\n \r\n // limpia\r\n this.audioChunks = [];\r\n };\r\n \r\n this.mediaRecorder.start();\r\n this.isRecording = true;\r\n } catch (err) {\r\n console.error('No se pudo iniciar la grabación:', err);\r\n this.isRecording = false;\r\n }\r\n }\r\n stopRecording() {\r\n try {\r\n if (this.mediaRecorder && this.mediaRecorder.state !== 'inactive') {\r\n this.mediaRecorder.stop();\r\n }\r\n \r\n // detener pistas del micrófono (importantísimo para liberar el icono de mic)\r\n if (this.recordingStream) {\r\n this.recordingStream.getTracks().forEach(t => t.stop());\r\n this.recordingStream = undefined;\r\n }\r\n \r\n } finally {\r\n this.isRecording = false;\r\n }\r\n }\r\n \r\n uploadFile(e: any) {\r\n const input = e.target as HTMLInputElement;\r\n if (input.files && input.files.length > 0) {\r\n const newFiles = Array.from(input.files);\r\n\r\n // Agrega los archivos nuevos sin duplicar por nombre\r\n for (const file of newFiles) {\r\n if (!this.selectedFiles.some(f => f.name === file.name && f.size === file.size)) {\r\n this.selectedFiles.push(file);\r\n }\r\n }\r\n }\r\n }\r\n\r\n getFileIcon(mime: string): string {\r\n if (mime.includes('pdf')) return 'pi pi-file-pdf';\r\n if (mime.includes('image')) return 'pi pi-image';\r\n if (mime.includes('audio')) return 'pi pi-volume-up';\r\n if (mime.includes('video')) return 'pi pi-video';\r\n if (mime.includes('zip')) return 'pi pi-file-zip';\r\n if (mime.includes('xlsx')) return 'pi pi-file-excel';\r\n return 'pi pi-file';\r\n }\r\n\r\n getFileClasses(mime: string): string {\r\n if (mime.includes('pdf')) return 'bg-red-500 border-red-800 text-white';\r\n if (mime.includes('image')) return 'bg-gray-100 border-gray-200 text-white';\r\n if (mime.includes('audio')) return 'bg-blue-500 border-blue-800 text-white';\r\n if (mime.includes('video')) return 'bg-yellow-500 border-yellow-800 text-white';\r\n if (mime.includes('zip')) return 'bg-indigo-500 border-indigo-800 text-white';\r\n if (mime.includes('xlsx')) return 'bg-green-500 border-green-800 text-white';\r\n return 'bg-gray-100 border-3 border-gray-200 text-gray-500';\r\n }\r\n\r\n removeSelectedFile(i: number) {\r\n this.selectedFiles.splice(i, 1);\r\n }\r\n\r\n handleKeyDown(event: KeyboardEvent) {\r\n const trimmedInput = this.userInput?.trim();\r\n if (event.key === 'Enter' && !event.shiftKey) {\r\n if (!trimmedInput || this.isBotWritting) {\r\n event.preventDefault();\r\n return;\r\n\r\n }\r\n event.preventDefault();\r\n this.send();\r\n }\r\n }\r\n\r\n getAvatarStyles(): { [key: string]: string } {\r\n const width = window.innerWidth;\r\n if (width < 576) {\r\n return { 'font-size': '1.25rem', 'width': '2rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n if (width < 768) {\r\n return { 'font-size': '1.5rem', 'width': '2.25rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n return { 'font-size': '2rem', 'width': '2.5rem', 'height': '2.5rem', 'aspect-ratio': '1 / 1' };\r\n }\r\n\r\n\r\n}\r\n","<div class=\"relative custom-chat flex flex-column items-center w-full\"\r\n [ngClass]=\"{ 'justify-content-center': isInitial }\">\r\n <div class=\"flex flex-column items-center justify-content-center gap-4 p-3 mb-3 text-center md:p-1\" *ngIf=\"isInitial\">\r\n <h2 class=\"text-2xl font-semibold text-gray-900 md:text-3xl lg:text-4xl\">{{headerConfig?.title || 'Agente'}}</h2>\r\n <div\r\n class=\"flex flex-wrap items-start justify-content-center gap-2 border-1 border-300 border-round-3xl p-2 shadow-2 surface-100\">\r\n <p-avatar image=\"./images/bot.png\" class=\"border-3 border-300 p-1\" shape=\"circle\" size=\"large\"></p-avatar>\r\n <div *ngIf=\"headerConfig?.initialMessages\" class=\"flex flex-column items-start\">\r\n <div *ngFor=\"let msg of headerConfig?.initialMessages\">\r\n <span class=\"text-sm m-0 text-gray-700 md:text-base lg:text-lg\">{{msg}}</span>\r\n </div>\r\n </div>\r\n </div>\r\n <p class=\"text-sm text-gray-500\">{{headerConfig?.subtitle}}</p>\r\n </div>\r\n <!-- <div class=\"p-2 w-full flex justify-content-center\" *ngIf=\"!isInitial\" >\r\n <p-tag [rounded]=\"true\" class=\"custom-tag\">\r\n <div class=\"flex items-center gap-2 px-1\">\r\n <img alt=\"AI logo\" src=\"./images/n8n.png\" style=\"width: 20px\" />\r\n <span class=\"text-base\">\r\n Online\r\n </span>\r\n </div>\r\n </p-tag> \r\n </div> -->\r\n <div class=\"overflow-auto w-full scroll\" #chatContainer *ngIf=\"!isInitial\">\r\n <div class=\"flex flex-column gap-3 mx-auto w-full custom-size min-height-0 pt-5 custom-message pb-2\">\r\n <div *ngFor=\"let msg of messages\">\r\n <div class=\"flex\"\r\n [ngClass]=\"msg.role !== 'user' ? 'align-start justify-content-start w-full' : 'align-end justify-content-end'\">\r\n <div [ngClass]=\"msg.role !== 'user' ? 'w-full' : 'chat-container'\">\r\n <app-table *ngIf=\"msg.type === 'table'\" [table]=\"msg.content\"></app-table>\r\n <app-file *ngIf=\"msg.type === 'file'\" [files]=\"msg.content\" [role]=\"msg.role\"></app-file>\r\n <app-text *ngIf=\"msg.type === 'text'\" [text]=\"msg.content\" [role]=\"msg.role\"></app-text>\r\n <app-markdown *ngIf=\"msg.type === 'markdown'\" [content]=\"msg.content\" [role]=\"msg.role\"></app-markdown>\r\n </div>\r\n </div>\r\n </div>\r\n <div *ngIf=\"isBotWritting\" class=\"flex gap-2 chat-container\">\r\n <p-avatar image=\"./images/bot.png\" class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\" shape=\"circle\"\r\n size=\"large\" [ngStyle]=\"{ 'aspect-ratio': '1 / 1', 'min-width': '40px' }\">\r\n </p-avatar>\r\n <div\r\n class=\"shadow-3 bg-white border-1 border-gray-300 text-gray-900 border-round-right-xl px-3 py-2 border-round-bottom-xl shadow-3 w-fit\">\r\n <div class=\"flex items-center gap-2\">\r\n <i class=\"pi pi-spin pi-spinner text-gray-600\"></i>\r\n <span class=\"text-sm text-gray-600 md:text-base lg:text-lg\">Escribiendo...</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n <div #bottom></div>\r\n </div>\r\n\r\n <!-- Input -->\r\n <div class=\"flex flex-column items-center justify-content-center custom-size w-full pt-1 pb-1\"\r\n [ngClass]=\"isInitial ? '' : 'down'\">\r\n <div class=\"flex flex-column gap-2 p-2 w-full border-1 border-400 border-round-3xl bg-white\">\r\n <app-file [files]=\"selectedFiles\" role=\"assitant\" [remove]=\"true\" />\r\n <form (ngSubmit)=\"send()\" class=\"w-full flex flex-column align-items-end gap-2\">\r\n <textarea pTextarea id=\"input\" name=\"userInput\" [(ngModel)]=\"userInput\"\r\n class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\"\r\n [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\"\r\n (keydown)=\"handleKeyDown($event)\"></textarea>\r\n <div class=\"flex align-items-center justify-content-between w-full p-1\">\r\n <div class=\"file-upload-container\">\r\n <p-button icon=\"pi pi-paperclip\" [text]=\"true\" (click)=\"fileInput.click()\" severity=\"contrast\" />\r\n <!-- NUEVO: grabación -->\r\n <p-button *ngIf=\"!isRecording\" icon=\"pi pi-microphone\" [text]=\"true\"\r\n (click)=\"startRecording()\" severity=\"contrast\" />\r\n\r\n <p-button *ngIf=\"isRecording\" icon=\"pi pi-stop\" [text]=\"true\"\r\n (click)=\"stopRecording()\" severity=\"danger\" />\r\n <input type=\"file\" #fileInput multiple (change)=\"uploadFile($event)\" style=\"display: none;\">\r\n \r\n </div>\r\n <p-button icon=\"pi pi-send\" [rounded]=\"true\" severity=\"contrast\" type=\"submit\"\r\n [disabled]=\"isBotWritting || (!userInput.trim() && selectedFiles.length === 0)\"\r\n />\r\n </div>\r\n </form>\r\n </div>\r\n <p class=\"mx-auto text-sm text-gray-600 mt-1\">{{headerConfig?.footer}}</p>\r\n </div>\r\n</div>","/*\r\n * Public API Surface of general-agent\r\n */\r\n\r\nexport * from './lib/general-agent/general-agent.component';\r\nexport * from './lib/agents-backend.port';\r\n\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i2","i3"],"mappings":"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"}
|
|
@@ -18,6 +18,10 @@ export declare class GeneralAgentComponent implements OnInit, AfterViewChecked {
|
|
|
18
18
|
placeholder?: string;
|
|
19
19
|
footer?: string;
|
|
20
20
|
};
|
|
21
|
+
isRecording: boolean;
|
|
22
|
+
private mediaRecorder?;
|
|
23
|
+
private audioChunks;
|
|
24
|
+
private recordingStream?;
|
|
21
25
|
agentInfo: any;
|
|
22
26
|
isLoading: boolean;
|
|
23
27
|
userInput: string;
|
|
@@ -43,6 +47,8 @@ export declare class GeneralAgentComponent implements OnInit, AfterViewChecked {
|
|
|
43
47
|
*/
|
|
44
48
|
private fileToBase64;
|
|
45
49
|
send(): Promise<void>;
|
|
50
|
+
startRecording(): Promise<void>;
|
|
51
|
+
stopRecording(): void;
|
|
46
52
|
uploadFile(e: any): void;
|
|
47
53
|
getFileIcon(mime: string): string;
|
|
48
54
|
getFileClasses(mime: string): string;
|