sf-aiembedded 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,63 @@
1
+ # GeneralAgent
2
+
3
+ This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.2.0.
4
+
5
+ ## Code scaffolding
6
+
7
+ Angular CLI includes powerful code scaffolding tools. To generate a new component, run:
8
+
9
+ ```bash
10
+ ng generate component component-name
11
+ ```
12
+
13
+ For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:
14
+
15
+ ```bash
16
+ ng generate --help
17
+ ```
18
+
19
+ ## Building
20
+
21
+ To build the library, run:
22
+
23
+ ```bash
24
+ ng build general-agent
25
+ ```
26
+
27
+ This command will compile your project, and the build artifacts will be placed in the `dist/` directory.
28
+
29
+ ### Publishing the Library
30
+
31
+ Once the project is built, you can publish your library by following these steps:
32
+
33
+ 1. Navigate to the `dist` directory:
34
+ ```bash
35
+ cd dist/general-agent
36
+ ```
37
+
38
+ 2. Run the `npm publish` command to publish your library to the npm registry:
39
+ ```bash
40
+ npm publish
41
+ ```
42
+
43
+ ## Running unit tests
44
+
45
+ To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:
46
+
47
+ ```bash
48
+ ng test
49
+ ```
50
+
51
+ ## Running end-to-end tests
52
+
53
+ For end-to-end (e2e) testing, run:
54
+
55
+ ```bash
56
+ ng e2e
57
+ ```
58
+
59
+ Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.
60
+
61
+ ## Additional Resources
62
+
63
+ For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
@@ -0,0 +1,406 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Input, Component, ViewEncapsulation, InjectionToken, ViewChild, Inject } from '@angular/core';
3
+ import * as i1 from '@angular/common';
4
+ import { CommonModule } from '@angular/common';
5
+ import * as i2$1 from '@angular/forms';
6
+ import { FormsModule } from '@angular/forms';
7
+ import * as i2 from 'primeng/button';
8
+ import { ButtonModule } from 'primeng/button';
9
+ import { Avatar } from 'primeng/avatar';
10
+ import { TagModule } from 'primeng/tag';
11
+ import { Textarea } from 'primeng/textarea';
12
+ import { ChipModule } from 'primeng/chip';
13
+ import { marked } from 'marked';
14
+ import * as i1$1 from '@angular/platform-browser';
15
+
16
+ //import { Avatar } from 'primeng/avatar';
17
+ class TextComponent {
18
+ text = '';
19
+ role = '';
20
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
21
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: TextComponent, isStandalone: true, selector: "app-text", inputs: { text: "text", role: "role" }, ngImport: i0, template: "<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>", styles: [".user-chat{background:linear-gradient(to bottom right,#60a5fa,#2563eb);color:#fff}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }] });
22
+ }
23
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TextComponent, decorators: [{
24
+ type: Component,
25
+ args: [{ selector: 'app-text', standalone: true, imports: [CommonModule, FormsModule], template: "<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>", styles: [".user-chat{background:linear-gradient(to bottom right,#60a5fa,#2563eb);color:#fff}\n"] }]
26
+ }], propDecorators: { text: [{
27
+ type: Input
28
+ }], role: [{
29
+ type: Input
30
+ }] } });
31
+
32
+ class FileComponent {
33
+ files = [];
34
+ role = 'assistant';
35
+ remove = false;
36
+ getFileIcon(mime) {
37
+ if (mime.includes('pdf'))
38
+ return 'pi pi-file-pdf';
39
+ if (mime.includes('image'))
40
+ return 'pi pi-image';
41
+ if (mime.includes('audio'))
42
+ return 'pi pi-volume-up';
43
+ if (mime.includes('video'))
44
+ return 'pi pi-video';
45
+ if (mime.includes('zip'))
46
+ return 'pi pi-file-zip';
47
+ if (mime.includes('xlsx'))
48
+ return 'pi pi-file-excel';
49
+ return 'pi pi-file';
50
+ }
51
+ getFileClasses(mime) {
52
+ if (mime.includes('pdf'))
53
+ return 'bg-red-500 border-red-800 text-white';
54
+ if (mime.includes('image'))
55
+ return 'bg-gray-100 border-gray-200 text-white';
56
+ if (mime.includes('audio'))
57
+ return 'bg-blue-500 border-blue-800 text-white';
58
+ if (mime.includes('video'))
59
+ return 'bg-yellow-500 border-yellow-800 text-white';
60
+ if (mime.includes('zip'))
61
+ return 'bg-indigo-500 border-indigo-800 text-white';
62
+ if (mime.includes('xlsx'))
63
+ return 'bg-green-500 border-green-800 text-white';
64
+ return 'bg-gray-100 border-3 border-gray-200 text-gray-500';
65
+ }
66
+ removeSelectedFile(i) {
67
+ this.files.splice(i, 1);
68
+ }
69
+ getGridClass() {
70
+ const fileCount = this.files.length;
71
+ if (fileCount === 1) {
72
+ return 'col-12';
73
+ }
74
+ else if (fileCount === 2) {
75
+ return 'col-12 sm:col-6';
76
+ }
77
+ else {
78
+ return 'col-12 sm:col-6 md:col-4';
79
+ }
80
+ }
81
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
82
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: FileComponent, isStandalone: true, selector: "app-file", inputs: { files: "files", role: "role", remove: "remove" }, ngImport: i0, template: "<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>", styles: [".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}}\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: "ngmodule", type: FormsModule }, { 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"] }] });
83
+ }
84
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: FileComponent, decorators: [{
85
+ type: Component,
86
+ args: [{ selector: 'app-file', standalone: true, imports: [CommonModule, FormsModule, ButtonModule, Avatar], template: "<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>", styles: [".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}}\n"] }]
87
+ }], propDecorators: { files: [{
88
+ type: Input
89
+ }], role: [{
90
+ type: Input
91
+ }], remove: [{
92
+ type: Input
93
+ }] } });
94
+
95
+ class TableComponent {
96
+ table = "";
97
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
98
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: TableComponent, isStandalone: true, selector: "app-table", inputs: { table: "table" }, ngImport: i0, template: "<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>", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
99
+ }
100
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: TableComponent, decorators: [{
101
+ type: Component,
102
+ args: [{ selector: 'app-table', imports: [CommonModule], template: "<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>" }]
103
+ }], propDecorators: { table: [{
104
+ type: Input
105
+ }] } });
106
+
107
+ // marked.setOptions({
108
+ // highlight: (code, lang) => {
109
+ // if (lang && hljs.getLanguage(lang)) {
110
+ // return hljs.highlight(code, { language: lang }).value;
111
+ // }
112
+ // return hljs.highlightAuto(code).value;
113
+ // }
114
+ // });
115
+ class MarkdownComponent {
116
+ sanitizer;
117
+ content = '';
118
+ role = '';
119
+ safeHtml = '';
120
+ constructor(sanitizer) {
121
+ this.sanitizer = sanitizer;
122
+ }
123
+ async ngOnChanges(changes) {
124
+ if ('content' in changes) {
125
+ const rawHtml = await marked.parse(this.content || '');
126
+ this.safeHtml = this.sanitizer.bypassSecurityTrustHtml(rawHtml);
127
+ console.log(this.safeHtml);
128
+ }
129
+ }
130
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MarkdownComponent, deps: [{ token: i1$1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
131
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: MarkdownComponent, isStandalone: true, selector: "app-markdown", inputs: { content: "content", role: "role" }, usesOnChanges: true, ngImport: i0, template: "<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", styles: [".markdown-container{font-family:Arial,sans-serif;line-height:1.5;color:#333;min-width:0;flex:1;word-wrap:break-word;white-space:normal;overflow-wrap:break-word}.markdown-container table{display:block;width:100%;border-collapse:collapse;margin:1em 0;font-size:1.125rem;box-shadow:0 1px 2px #0000000d;border-right:none;border-left:none;overflow-x:auto}.markdown-container th{background-color:#f3f4f6;color:#333;font-weight:600;padding:10px;text-align:left;border-bottom:2px solid #d1d5db}.markdown-container td{padding:10px;border-top:1px solid #e5e7eb;vertical-align:top;text-align:left}@media (max-width: 1024px){.markdown-container table{font-size:1rem}}@media (max-width: 768px){.markdown-container table{font-size:.875rem}}.markdown-container tr:nth-child(2n){background-color:#f9fafb}.markdown-container tr:hover{background-color:#f1f5f9}.markdown-container a{color:#0366d6;text-decoration:underline}.markdown-container img{max-width:100%;margin:10px 0;border-radius:6px}.markdown-container pre{background:#f6f8fa;padding:12px;border-radius:6px;overflow-x:auto;margin:1em 0}.markdown-container code{font-family:monospace}.markdown-container p,li{font-size:1.125rem}@media (max-width: 1024px){.markdown-container p,li{font-size:1rem}}@media (max-width: 768px){.markdown-container p,li{font-size:.875rem}}.markdown-container ul,.markdown-container ol{padding-left:1.5rem;margin:.5rem 0}.markdown-container ul{list-style-type:disc}.markdown-container ol{list-style-type:decimal}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: Avatar, selector: "p-avatar", inputs: ["label", "icon", "image", "size", "shape", "style", "styleClass", "ariaLabel", "ariaLabelledBy"], outputs: ["onImageError"] }], encapsulation: i0.ViewEncapsulation.None });
132
+ }
133
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: MarkdownComponent, decorators: [{
134
+ type: Component,
135
+ args: [{ selector: 'app-markdown', standalone: true, imports: [CommonModule, Avatar], encapsulation: ViewEncapsulation.None, template: "<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", styles: [".markdown-container{font-family:Arial,sans-serif;line-height:1.5;color:#333;min-width:0;flex:1;word-wrap:break-word;white-space:normal;overflow-wrap:break-word}.markdown-container table{display:block;width:100%;border-collapse:collapse;margin:1em 0;font-size:1.125rem;box-shadow:0 1px 2px #0000000d;border-right:none;border-left:none;overflow-x:auto}.markdown-container th{background-color:#f3f4f6;color:#333;font-weight:600;padding:10px;text-align:left;border-bottom:2px solid #d1d5db}.markdown-container td{padding:10px;border-top:1px solid #e5e7eb;vertical-align:top;text-align:left}@media (max-width: 1024px){.markdown-container table{font-size:1rem}}@media (max-width: 768px){.markdown-container table{font-size:.875rem}}.markdown-container tr:nth-child(2n){background-color:#f9fafb}.markdown-container tr:hover{background-color:#f1f5f9}.markdown-container a{color:#0366d6;text-decoration:underline}.markdown-container img{max-width:100%;margin:10px 0;border-radius:6px}.markdown-container pre{background:#f6f8fa;padding:12px;border-radius:6px;overflow-x:auto;margin:1em 0}.markdown-container code{font-family:monospace}.markdown-container p,li{font-size:1.125rem}@media (max-width: 1024px){.markdown-container p,li{font-size:1rem}}@media (max-width: 768px){.markdown-container p,li{font-size:.875rem}}.markdown-container ul,.markdown-container ol{padding-left:1.5rem;margin:.5rem 0}.markdown-container ul{list-style-type:disc}.markdown-container ol{list-style-type:decimal}\n"] }]
136
+ }], ctorParameters: () => [{ type: i1$1.DomSanitizer }], propDecorators: { content: [{
137
+ type: Input
138
+ }], role: [{
139
+ type: Input
140
+ }] } });
141
+
142
+ // projects/general-agent/src/lib/agents-backend.port.ts
143
+ const AI_AGENTS = new InjectionToken('AI_AGENTS');
144
+
145
+ class GeneralAgentComponent {
146
+ aiAgentsGatewayService;
147
+ bottom;
148
+ // Propiedades internas (ya no inputs/outputs)
149
+ messages = [];
150
+ isBotWritting = false;
151
+ headerConfig;
152
+ agentInfo;
153
+ isLoading = false;
154
+ userInput = '';
155
+ configuration;
156
+ selectedFiles = [];
157
+ sessionId = '';
158
+ agentType = '';
159
+ agentId = '';
160
+ idKatios = '';
161
+ constructor(aiAgentsGatewayService) {
162
+ this.aiAgentsGatewayService = aiAgentsGatewayService;
163
+ }
164
+ async ngOnInit() {
165
+ await this.loadAgent();
166
+ }
167
+ async ngOnChanges(changes) {
168
+ if (changes['agentId'] || changes['agentType'] || changes['idKatios']) {
169
+ await this.loadAgent();
170
+ }
171
+ }
172
+ async loadAgent() {
173
+ this.isLoading = true;
174
+ this.isBotWritting = false;
175
+ this.messages = [];
176
+ this.sessionId = "";
177
+ try {
178
+ const agentInfo = await this.aiAgentsGatewayService.getAgent(this.idKatios, this.agentId);
179
+ if (agentInfo.statusCode === 200) {
180
+ this.agentInfo = JSON.parse(agentInfo.data.rawConfig);
181
+ let configurationAgent = null;
182
+ if (this.agentInfo.config?.i18n?.en) {
183
+ configurationAgent = this.agentInfo.config.i18n.en;
184
+ }
185
+ else {
186
+ configurationAgent = this.agentInfo.config.setUp;
187
+ }
188
+ this.headerConfig = {
189
+ title: configurationAgent.title,
190
+ subtitle: configurationAgent.subtitle,
191
+ initialMessages: configurationAgent.initialMessages,
192
+ type: this.agentType,
193
+ placeholder: configurationAgent.inputPlaceholder,
194
+ footer: configurationAgent.footer
195
+ };
196
+ console.log(this.headerConfig);
197
+ this.isLoading = false;
198
+ }
199
+ }
200
+ catch (error) {
201
+ console.error('An error occurred:', error);
202
+ this.isLoading = false;
203
+ }
204
+ }
205
+ get isInitial() {
206
+ return this.messages.length === 0 && !this.isBotWritting;
207
+ }
208
+ ngAfterViewChecked() {
209
+ this.scrollToBottom();
210
+ }
211
+ scrollToBottom() {
212
+ if (this.bottom) {
213
+ this.bottom.nativeElement.scrollIntoView({ behavior: 'smooth' });
214
+ }
215
+ }
216
+ /**
217
+ * Converts File objects to Attachment format expected by the backend
218
+ */
219
+ async convertFilesToAttachments(files) {
220
+ if (!files || files.length === 0) {
221
+ return [];
222
+ }
223
+ const attachments = [];
224
+ for (const file of files) {
225
+ try {
226
+ const base64Data = await this.fileToBase64(file);
227
+ const attachment = {
228
+ fileName: file.name,
229
+ contentType: file.type,
230
+ base64Data: base64Data
231
+ };
232
+ attachments.push(attachment);
233
+ }
234
+ catch (error) {
235
+ console.error(`Error converting file ${file.name} to base64:`, error);
236
+ }
237
+ }
238
+ return attachments;
239
+ }
240
+ /**
241
+ * Converts a File object to base64 string
242
+ */
243
+ fileToBase64(file) {
244
+ return new Promise((resolve, reject) => {
245
+ const reader = new FileReader();
246
+ reader.readAsDataURL(file);
247
+ reader.onload = () => {
248
+ // Remove the data URL prefix (e.g., "data:image/png;base64,")
249
+ const base64String = reader.result.split(',')[1];
250
+ resolve(base64String);
251
+ };
252
+ reader.onerror = error => reject(error);
253
+ });
254
+ }
255
+ async send() {
256
+ this.isBotWritting = true;
257
+ const text = this.userInput.trim();
258
+ if (!text) {
259
+ this.isBotWritting = false;
260
+ return;
261
+ }
262
+ console.log('Sending message:', text);
263
+ console.log('Requesting AI response...');
264
+ console.log('Files:', this.selectedFiles);
265
+ // Add user message to chat
266
+ if (this.selectedFiles && this.selectedFiles.length > 0) {
267
+ this.messages.push({ role: 'user', type: 'file', content: this.selectedFiles });
268
+ }
269
+ this.messages.push({ role: 'user', type: 'text', content: text });
270
+ try {
271
+ // Convert files to the format expected by the backend
272
+ const attachments = await this.convertFilesToAttachments(this.selectedFiles || []);
273
+ // Prepare the request object according to SendMessageRequest interface
274
+ const requestData = {
275
+ conversationId: this.sessionId,
276
+ text: text,
277
+ files: attachments,
278
+ metadata: {}
279
+ };
280
+ console.log('Request data:', requestData);
281
+ this.userInput = '';
282
+ // Call the standardized service
283
+ const response = await this.aiAgentsGatewayService.sendMessage(this.idKatios, this.agentId, requestData);
284
+ console.log('Response received:', response);
285
+ // Process the response according to ApiResponse<SendMessageResponse>
286
+ if (response.success && response.data) {
287
+ this.sessionId = response.data.conversationId;
288
+ const messages = response.data.messages;
289
+ messages.forEach((m) => {
290
+ if (m.type === 'table') {
291
+ this.messages.push({ role: m.role || 'assistant', type: 'table', content: m.content });
292
+ }
293
+ else {
294
+ this.messages.push({ role: m.role || 'assistant', type: m.type || 'markdown', content: m.content });
295
+ }
296
+ });
297
+ console.log('Messages received:', messages);
298
+ }
299
+ else {
300
+ console.error('Error in response:', response);
301
+ }
302
+ }
303
+ catch (error) {
304
+ console.error('Error sending message:', error);
305
+ }
306
+ finally {
307
+ this.isBotWritting = false;
308
+ this.selectedFiles = [];
309
+ }
310
+ }
311
+ uploadFile(e) {
312
+ const input = e.target;
313
+ if (input.files && input.files.length > 0) {
314
+ const newFiles = Array.from(input.files);
315
+ // Agrega los archivos nuevos sin duplicar por nombre
316
+ for (const file of newFiles) {
317
+ if (!this.selectedFiles.some(f => f.name === file.name && f.size === file.size)) {
318
+ this.selectedFiles.push(file);
319
+ }
320
+ }
321
+ }
322
+ }
323
+ getFileIcon(mime) {
324
+ if (mime.includes('pdf'))
325
+ return 'pi pi-file-pdf';
326
+ if (mime.includes('image'))
327
+ return 'pi pi-image';
328
+ if (mime.includes('audio'))
329
+ return 'pi pi-volume-up';
330
+ if (mime.includes('video'))
331
+ return 'pi pi-video';
332
+ if (mime.includes('zip'))
333
+ return 'pi pi-file-zip';
334
+ if (mime.includes('xlsx'))
335
+ return 'pi pi-file-excel';
336
+ return 'pi pi-file';
337
+ }
338
+ getFileClasses(mime) {
339
+ if (mime.includes('pdf'))
340
+ return 'bg-red-500 border-red-800 text-white';
341
+ if (mime.includes('image'))
342
+ return 'bg-gray-100 border-gray-200 text-white';
343
+ if (mime.includes('audio'))
344
+ return 'bg-blue-500 border-blue-800 text-white';
345
+ if (mime.includes('video'))
346
+ return 'bg-yellow-500 border-yellow-800 text-white';
347
+ if (mime.includes('zip'))
348
+ return 'bg-indigo-500 border-indigo-800 text-white';
349
+ if (mime.includes('xlsx'))
350
+ return 'bg-green-500 border-green-800 text-white';
351
+ return 'bg-gray-100 border-3 border-gray-200 text-gray-500';
352
+ }
353
+ removeSelectedFile(i) {
354
+ this.selectedFiles.splice(i, 1);
355
+ }
356
+ handleKeyDown(event) {
357
+ const trimmedInput = this.userInput?.trim();
358
+ if (event.key === 'Enter' && !event.shiftKey) {
359
+ if (!trimmedInput || this.isBotWritting) {
360
+ event.preventDefault();
361
+ return;
362
+ }
363
+ event.preventDefault();
364
+ this.send();
365
+ }
366
+ }
367
+ getAvatarStyles() {
368
+ const width = window.innerWidth;
369
+ if (width < 576) {
370
+ return { 'font-size': '1.25rem', 'width': '2rem', 'aspect-ratio': '1 / 1' };
371
+ }
372
+ if (width < 768) {
373
+ return { 'font-size': '1.5rem', 'width': '2.25rem', 'aspect-ratio': '1 / 1' };
374
+ }
375
+ return { 'font-size': '2rem', 'width': '2.5rem', 'height': '2.5rem', 'aspect-ratio': '1 / 1' };
376
+ }
377
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GeneralAgentComponent, deps: [{ token: AI_AGENTS }], target: i0.ɵɵFactoryTarget.Component });
378
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: GeneralAgentComponent, isStandalone: true, selector: "app-general-agent", inputs: { agentType: "agentType", agentId: "agentId", idKatios: "idKatios" }, viewQueries: [{ propertyName: "bottom", first: true, predicate: ["bottom"], 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 >\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 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 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\r\n image=\"./images/bot.png\"\r\n class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\"\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 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\" [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\" class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\" [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\" (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\" [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>", 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"] }] });
379
+ }
380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: GeneralAgentComponent, decorators: [{
381
+ type: Component,
382
+ 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 >\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 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 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\r\n image=\"./images/bot.png\"\r\n class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\"\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 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\" [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\" class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\" [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\" (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\" [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>", 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"] }]
383
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
384
+ type: Inject,
385
+ args: [AI_AGENTS]
386
+ }] }], propDecorators: { bottom: [{
387
+ type: ViewChild,
388
+ args: ['bottom']
389
+ }], agentType: [{
390
+ type: Input
391
+ }], agentId: [{
392
+ type: Input
393
+ }], idKatios: [{
394
+ type: Input
395
+ }] } });
396
+
397
+ /*
398
+ * Public API Surface of general-agent
399
+ */
400
+
401
+ /**
402
+ * Generated bundle index. Do not edit.
403
+ */
404
+
405
+ export { AI_AGENTS, GeneralAgentComponent };
406
+ //# sourceMappingURL=sf-aiembedded.mjs.map
@@ -0,0 +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 } 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\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 console.log(this.safeHtml)\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","\r\nimport { 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('bottom') private bottom!: ElementRef;\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\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: configurationAgent.initialMessages,\r\n type: this.agentType,\r\n placeholder: configurationAgent.inputPlaceholder,\r\n footer: configurationAgent.footer\r\n };\r\n\r\n console.log(this.headerConfig);\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 ngAfterViewChecked() {\r\n this.scrollToBottom();\r\n }\r\n\r\n scrollToBottom(): void {\r\n if (this.bottom) {\r\n this.bottom.nativeElement.scrollIntoView({ behavior: 'smooth' });\r\n }\r\n }\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 console.log('Sending message:', text);\r\n console.log('Requesting AI response...');\r\n console.log('Files:', this.selectedFiles);\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 console.log('Request data:', requestData);\r\n this.userInput = '';\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 console.log('Response received:', response);\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 console.log('Messages received:', messages);\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 this.selectedFiles = [];\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\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.selectedFiles.splice(i, 1);\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 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 >\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 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 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\r\n image=\"./images/bot.png\"\r\n class=\"bg-gray-100 border-3 border-gray-300 p-1 flex-shrink-0\"\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 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\" [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\" class=\"custom-input w-full text-sm md:text-base lg:text-lg\" style=\"max-height: 200px\" [placeholder]=\"headerConfig?.placeholder || 'Pregunta lo que necesites...'\" rows=\"1\" [autoResize]=\"true\" (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\" [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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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="sf-aiembedded" />
5
+ export * from './public-api';
@@ -0,0 +1,22 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ export interface AiAgentsGatewayService {
3
+ getAgent(idKatios: string, agentId: string): Promise<any>;
4
+ sendMessage(idKatios: string, agentId: string, req: {
5
+ conversationId?: string;
6
+ text: string;
7
+ files: Array<{
8
+ fileName: string;
9
+ contentType: string;
10
+ base64Data: string;
11
+ }>;
12
+ metadata?: any;
13
+ }): Promise<{
14
+ conversationId: string;
15
+ messages: Array<{
16
+ role?: string;
17
+ type?: string;
18
+ content: any;
19
+ }>;
20
+ }>;
21
+ }
22
+ export declare const AI_AGENTS: InjectionToken<AiAgentsGatewayService>;
@@ -0,0 +1,56 @@
1
+ import { OnInit, AfterViewChecked, SimpleChanges } from '@angular/core';
2
+ import { AiAgentsGatewayService } from '../agents-backend.port';
3
+ import * as i0 from "@angular/core";
4
+ export declare class GeneralAgentComponent implements OnInit, AfterViewChecked {
5
+ private aiAgentsGatewayService;
6
+ private bottom;
7
+ messages: {
8
+ content: any;
9
+ type: string;
10
+ role: string;
11
+ }[];
12
+ isBotWritting: boolean;
13
+ headerConfig?: {
14
+ title?: string;
15
+ subtitle?: string;
16
+ initialMessages?: string[];
17
+ type: string;
18
+ placeholder?: string;
19
+ footer?: string;
20
+ };
21
+ agentInfo: any;
22
+ isLoading: boolean;
23
+ userInput: string;
24
+ configuration: any;
25
+ selectedFiles: File[];
26
+ sessionId: string;
27
+ agentType: string;
28
+ agentId: string;
29
+ idKatios: string;
30
+ constructor(aiAgentsGatewayService: AiAgentsGatewayService);
31
+ ngOnInit(): Promise<void>;
32
+ ngOnChanges(changes: SimpleChanges): Promise<void>;
33
+ loadAgent(): Promise<void>;
34
+ get isInitial(): boolean;
35
+ ngAfterViewChecked(): void;
36
+ scrollToBottom(): void;
37
+ /**
38
+ * Converts File objects to Attachment format expected by the backend
39
+ */
40
+ private convertFilesToAttachments;
41
+ /**
42
+ * Converts a File object to base64 string
43
+ */
44
+ private fileToBase64;
45
+ send(): Promise<void>;
46
+ uploadFile(e: any): void;
47
+ getFileIcon(mime: string): string;
48
+ getFileClasses(mime: string): string;
49
+ removeSelectedFile(i: number): void;
50
+ handleKeyDown(event: KeyboardEvent): void;
51
+ getAvatarStyles(): {
52
+ [key: string]: string;
53
+ };
54
+ static ɵfac: i0.ɵɵFactoryDeclaration<GeneralAgentComponent, never>;
55
+ static ɵcmp: i0.ɵɵComponentDeclaration<GeneralAgentComponent, "app-general-agent", never, { "agentType": { "alias": "agentType"; "required": false; }; "agentId": { "alias": "agentId"; "required": false; }; "idKatios": { "alias": "idKatios"; "required": false; }; }, {}, never, never, true, never>;
56
+ }
@@ -0,0 +1,12 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class FileComponent {
3
+ files: File[];
4
+ role: string;
5
+ remove: boolean;
6
+ getFileIcon(mime: string): string;
7
+ getFileClasses(mime: string): string;
8
+ removeSelectedFile(i: number): void;
9
+ getGridClass(): "col-12" | "col-12 sm:col-6" | "col-12 sm:col-6 md:col-4";
10
+ static ɵfac: i0.ɵɵFactoryDeclaration<FileComponent, never>;
11
+ static ɵcmp: i0.ɵɵComponentDeclaration<FileComponent, "app-file", never, { "files": { "alias": "files"; "required": false; }; "role": { "alias": "role"; "required": false; }; "remove": { "alias": "remove"; "required": false; }; }, {}, never, never, true, never>;
12
+ }
@@ -0,0 +1,13 @@
1
+ import { OnChanges, SimpleChanges } from '@angular/core';
2
+ import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
3
+ import * as i0 from "@angular/core";
4
+ export declare class MarkdownComponent implements OnChanges {
5
+ private sanitizer;
6
+ content: string;
7
+ role: string;
8
+ safeHtml: SafeHtml;
9
+ constructor(sanitizer: DomSanitizer);
10
+ ngOnChanges(changes: SimpleChanges): Promise<void>;
11
+ static ɵfac: i0.ɵɵFactoryDeclaration<MarkdownComponent, never>;
12
+ static ɵcmp: i0.ɵɵComponentDeclaration<MarkdownComponent, "app-markdown", never, { "content": { "alias": "content"; "required": false; }; "role": { "alias": "role"; "required": false; }; }, {}, never, never, true, never>;
13
+ }
@@ -0,0 +1,6 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class TableComponent {
3
+ table: string;
4
+ static ɵfac: i0.ɵɵFactoryDeclaration<TableComponent, never>;
5
+ static ɵcmp: i0.ɵɵComponentDeclaration<TableComponent, "app-table", never, { "table": { "alias": "table"; "required": false; }; }, {}, never, never, true, never>;
6
+ }
@@ -0,0 +1,7 @@
1
+ import * as i0 from "@angular/core";
2
+ export declare class TextComponent {
3
+ text: string;
4
+ role: string;
5
+ static ɵfac: i0.ɵɵFactoryDeclaration<TextComponent, never>;
6
+ static ɵcmp: i0.ɵɵComponentDeclaration<TextComponent, "app-text", never, { "text": { "alias": "text"; "required": false; }; "role": { "alias": "role"; "required": false; }; }, {}, never, never, true, never>;
7
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "sf-aiembedded",
3
+ "version": "0.0.1",
4
+ "description": "GeneralAgent UI (standalone) para Angular",
5
+ "author": "mateo.forero@nhubex.com",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "angular",
9
+ "component",
10
+ "chat",
11
+ "primeng"
12
+ ],
13
+ "sideEffects": false,
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "peerDependencies": {
18
+ "@angular/common": "^19.0.0",
19
+ "@angular/core": "^19.0.0",
20
+ "@angular/forms": "^19.0.0",
21
+ "rxjs": "^7.8.0",
22
+ "primeng": "^19.0.0",
23
+ "primeicons": "^7.0.0"
24
+ },
25
+ "peerDependenciesMeta": {
26
+ "@n8n/chat": {
27
+ "optional": true
28
+ }
29
+ },
30
+ "dependencies": {
31
+ "tslib": "^2.3.0"
32
+ },
33
+ "module": "fesm2022/sf-aiembedded.mjs",
34
+ "typings": "index.d.ts",
35
+ "exports": {
36
+ "./package.json": {
37
+ "default": "./package.json"
38
+ },
39
+ ".": {
40
+ "types": "./index.d.ts",
41
+ "default": "./fesm2022/sf-aiembedded.mjs"
42
+ }
43
+ }
44
+ }
@@ -0,0 +1,2 @@
1
+ export * from './lib/general-agent/general-agent.component';
2
+ export * from './lib/agents-backend.port';