@sftech/ng-orchestrator 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/README.md +89 -89
  2. package/fesm2022/sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs +188 -0
  3. package/fesm2022/sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs.map +1 -0
  4. package/fesm2022/sftech-ng-orchestrator-agents.routes-bBcxJpUD.mjs +284 -0
  5. package/fesm2022/sftech-ng-orchestrator-agents.routes-bBcxJpUD.mjs.map +1 -0
  6. package/fesm2022/sftech-ng-orchestrator-chats.routes-B3UPU3v9.mjs +743 -0
  7. package/fesm2022/sftech-ng-orchestrator-chats.routes-B3UPU3v9.mjs.map +1 -0
  8. package/fesm2022/{sftech-ng-orchestrator-prompt-display.component-CXGtE_Ui.mjs → sftech-ng-orchestrator-prompt-display.component-Cf16yAfr.mjs} +4 -4
  9. package/fesm2022/{sftech-ng-orchestrator-prompt-display.component-CXGtE_Ui.mjs.map → sftech-ng-orchestrator-prompt-display.component-Cf16yAfr.mjs.map} +1 -1
  10. package/fesm2022/sftech-ng-orchestrator-prompts.routes-lV1Np2KD.mjs +51 -0
  11. package/fesm2022/sftech-ng-orchestrator-prompts.routes-lV1Np2KD.mjs.map +1 -0
  12. package/fesm2022/{sftech-ng-orchestrator-sftech-ng-orchestrator-C51KniGY.mjs → sftech-ng-orchestrator-sftech-ng-orchestrator-CzwZe61l.mjs} +4 -4
  13. package/fesm2022/{sftech-ng-orchestrator-sftech-ng-orchestrator-C51KniGY.mjs.map → sftech-ng-orchestrator-sftech-ng-orchestrator-CzwZe61l.mjs.map} +1 -1
  14. package/fesm2022/sftech-ng-orchestrator.mjs +1 -1
  15. package/package.json +1 -1
  16. package/fesm2022/sftech-ng-orchestrator-agent-rag-upload.component-COPkzHNN.mjs +0 -188
  17. package/fesm2022/sftech-ng-orchestrator-agent-rag-upload.component-COPkzHNN.mjs.map +0 -1
  18. package/fesm2022/sftech-ng-orchestrator-agents.routes-DH_0cd5T.mjs +0 -284
  19. package/fesm2022/sftech-ng-orchestrator-agents.routes-DH_0cd5T.mjs.map +0 -1
  20. package/fesm2022/sftech-ng-orchestrator-chats.routes-CqFuG3l5.mjs +0 -743
  21. package/fesm2022/sftech-ng-orchestrator-chats.routes-CqFuG3l5.mjs.map +0 -1
  22. package/fesm2022/sftech-ng-orchestrator-prompts.routes-CvMtYkTK.mjs +0 -51
  23. package/fesm2022/sftech-ng-orchestrator-prompts.routes-CvMtYkTK.mjs.map +0 -1
package/README.md CHANGED
@@ -1,89 +1,89 @@
1
- # @sftech/ng-orchestrator
2
-
3
- Angular library for AI agent orchestration — admin interface for agents, prompts, and chat.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install @sftech/ng-orchestrator
9
- ```
10
-
11
- ## Peer Dependencies
12
-
13
- - `@angular/common` >= 19.0.0
14
- - `@angular/core` >= 19.0.0
15
- - `@sftech/ng-shared` >= 1.0.0
16
- - `@sftech/ng-auth` >= 1.0.0
17
- - PrimeNG >= 19.0.0
18
- - ngx-markdown >= 19.0.0
19
-
20
- ## Configuration
21
-
22
- Add `OrchestratorModule.forRoot()` to your `app.config.ts`:
23
-
24
- ```typescript
25
- import { OrchestratorModule } from '@sftech/ng-orchestrator';
26
- import { IAppConfig } from '@sftech/ng-shared';
27
-
28
- export function appConfig(config: IAppConfig): ApplicationConfig {
29
- return {
30
- providers: [
31
- importProvidersFrom(OrchestratorModule.forRoot(config)),
32
- ],
33
- };
34
- }
35
- ```
36
-
37
- The library reads the following keys from `IAppConfig`:
38
-
39
- | Key | Description | Default |
40
- |-----|-------------|---------|
41
- | `ORCHESTRATOR_API_URL` | Orchestrator API base URL | `http://localhost:3010` |
42
- | `ORCHESTRATOR_DB_API_URL` | Orchestrator DB API base URL | `http://localhost:3012` |
43
-
44
- ## Routing
45
-
46
- ```typescript
47
- import { Route } from '@angular/router';
48
-
49
- export const appRoutes: Route[] = [
50
- {
51
- path: 'orchestrator',
52
- loadChildren: () => import('@sftech/ng-orchestrator').then((m) => m.orchestratorRoutes),
53
- },
54
- ];
55
- ```
56
-
57
- ### Route Structure
58
-
59
- - `/orchestrator/chats` — Chat interface (protected by `authenticationGuard`)
60
- - `/orchestrator/admin/agents` — Agent management (protected by `adminGuard`)
61
- - `/orchestrator/admin/prompts` — Prompt management (protected by `adminGuard`)
62
-
63
- ## Features
64
-
65
- - **Agent Management**: CRUD for AI agents with LLM configuration (provider, model, temperature, timeout)
66
- - **Prompt Management**: System prompt templates with history tracking
67
- - **Chat Interface**: Real-time chat with AI agents, agent selection, message rendering with Markdown
68
- - **RAG Upload**: Document upload for Retrieval-Augmented Generation per agent
69
- - **MCP Tools**: Model Context Protocol tool management per agent
70
-
71
- ## Key Services
72
-
73
- - `AgentService` — Agent CRUD operations
74
- - `PromptService` — Prompt CRUD operations
75
- - `PromptHistoryService` — Prompt version history
76
- - `ChatService` — Chat session management
77
- - `AgentRunService` — Agent execution tracking
78
- - `OrchestratorService` — Core orchestrator API (tools, chat execution)
79
-
80
- ## Development
81
-
82
- ```bash
83
- npx nx build ng-orchestrator
84
- npx nx lint ng-orchestrator
85
- ```
86
-
87
- ## License
88
-
89
- MIT
1
+ # @sftech/ng-orchestrator
2
+
3
+ Angular library for AI agent orchestration — admin interface for agents, prompts, and chat.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sftech/ng-orchestrator
9
+ ```
10
+
11
+ ## Peer Dependencies
12
+
13
+ - `@angular/common` >= 19.0.0
14
+ - `@angular/core` >= 19.0.0
15
+ - `@sftech/ng-shared` >= 1.0.0
16
+ - `@sftech/ng-auth` >= 1.0.0
17
+ - PrimeNG >= 19.0.0
18
+ - ngx-markdown >= 19.0.0
19
+
20
+ ## Configuration
21
+
22
+ Add `OrchestratorModule.forRoot()` to your `app.config.ts`:
23
+
24
+ ```typescript
25
+ import { OrchestratorModule } from '@sftech/ng-orchestrator';
26
+ import { IAppConfig } from '@sftech/ng-shared';
27
+
28
+ export function appConfig(config: IAppConfig): ApplicationConfig {
29
+ return {
30
+ providers: [
31
+ importProvidersFrom(OrchestratorModule.forRoot(config)),
32
+ ],
33
+ };
34
+ }
35
+ ```
36
+
37
+ The library reads the following keys from `IAppConfig`:
38
+
39
+ | Key | Description | Default |
40
+ |-----|-------------|---------|
41
+ | `ORCHESTRATOR_API_URL` | Orchestrator API base URL | `http://localhost:3010` |
42
+ | `ORCHESTRATOR_DB_API_URL` | Orchestrator DB API base URL | `http://localhost:3012` |
43
+
44
+ ## Routing
45
+
46
+ ```typescript
47
+ import { Route } from '@angular/router';
48
+
49
+ export const appRoutes: Route[] = [
50
+ {
51
+ path: 'orchestrator',
52
+ loadChildren: () => import('@sftech/ng-orchestrator').then((m) => m.orchestratorRoutes),
53
+ },
54
+ ];
55
+ ```
56
+
57
+ ### Route Structure
58
+
59
+ - `/orchestrator/chats` — Chat interface (protected by `authenticationGuard`)
60
+ - `/orchestrator/admin/agents` — Agent management (protected by `adminGuard`)
61
+ - `/orchestrator/admin/prompts` — Prompt management (protected by `adminGuard`)
62
+
63
+ ## Features
64
+
65
+ - **Agent Management**: CRUD for AI agents with LLM configuration (provider, model, temperature, timeout)
66
+ - **Prompt Management**: System prompt templates with history tracking
67
+ - **Chat Interface**: Real-time chat with AI agents, agent selection, message rendering with Markdown
68
+ - **RAG Upload**: Document upload for Retrieval-Augmented Generation per agent
69
+ - **MCP Tools**: Model Context Protocol tool management per agent
70
+
71
+ ## Key Services
72
+
73
+ - `AgentService` — Agent CRUD operations
74
+ - `PromptService` — Prompt CRUD operations
75
+ - `PromptHistoryService` — Prompt version history
76
+ - `ChatService` — Chat session management
77
+ - `AgentRunService` — Agent execution tracking
78
+ - `OrchestratorService` — Core orchestrator API (tools, chat execution)
79
+
80
+ ## Development
81
+
82
+ ```bash
83
+ npx nx build ng-orchestrator
84
+ npx nx lint ng-orchestrator
85
+ ```
86
+
87
+ ## License
88
+
89
+ MIT
@@ -0,0 +1,188 @@
1
+ import * as i0 from '@angular/core';
2
+ import { Inject, Injectable, input, signal, inject, Component } from '@angular/core';
3
+ import { FaIconComponent } from '@fortawesome/angular-fontawesome';
4
+ import { BaseDbModel, EFilterTypes, BaseDbApiService, BaseDialogComponent, MappedApiError } from '@sftech/ng-shared';
5
+ import { Button } from 'primeng/button';
6
+ import * as i1$1 from 'primeng/fileupload';
7
+ import { FileUploadModule } from 'primeng/fileupload';
8
+ import * as i1 from '@angular/common/http';
9
+ import { O as ORCHESTRATOR_CONFIGURATION, a as OrchestratorService } from './sftech-ng-orchestrator-sftech-ng-orchestrator-CzwZe61l.mjs';
10
+ import { P as Prompt } from './sftech-ng-orchestrator-prompt.model-DhASegzq.mjs';
11
+
12
+ class Agent extends BaseDbModel {
13
+ identifier;
14
+ description;
15
+ name;
16
+ connectorUrl;
17
+ isGeneric;
18
+ answerSpecification;
19
+ tools;
20
+ llmProvider;
21
+ llmModel;
22
+ llmTemperature;
23
+ llmTimeout;
24
+ llmRetries;
25
+ llmUserPromptId;
26
+ llmUserPrompt;
27
+ llmSystemPromptId;
28
+ llmSystemPrompt;
29
+ llmUserPromptHistoryId;
30
+ llmUserPromptHistory;
31
+ llmSystemPromptHistoryId;
32
+ llmSystemPromptHistory;
33
+ ragModel;
34
+ ragProvider;
35
+ propertiesToShow = ['name', 'identifier', 'description'];
36
+ propertyUINames = new Map([
37
+ ['name', 'Name'],
38
+ ['description', 'Beschreibung'],
39
+ ['identifier', 'identifier'],
40
+ ['llmUserPromptTemplateIdentifier', 'User Prompt Identifier'],
41
+ ['connectorUrl', 'Connector-Url'],
42
+ ['answerSpecification', 'Answer Specification'],
43
+ ['isGeneric', 'Benutzerdefinierter Agent'],
44
+ ['tools', 'LLM-Tools'],
45
+ ['llmProvider', 'LLM-Provider'],
46
+ ['llmModel', 'LLM-Model'],
47
+ ['llmTemperature', 'LLM-Temperature'],
48
+ ['llmTimeout', 'LLM-Timeout'],
49
+ ['llmRetries', 'LLM-Retries'],
50
+ ['llmUserPromptId', 'User Prompt ID'],
51
+ ['llmUserPrompt', 'User Prompt Template'],
52
+ ['llmSystemPromptId', 'System Prompt ID'],
53
+ ['llmSystemPrompt', 'System Prompt Template'],
54
+ ['ragProvider', 'RAG - Provider'],
55
+ ['ragModel', 'RAG - Embedding Model'],
56
+ ]);
57
+ propertyFilterType = new Map([
58
+ ['name', EFilterTypes.STRING],
59
+ ['template', EFilterTypes.STRING],
60
+ ['identifier', EFilterTypes.STRING],
61
+ ]);
62
+ fromDto(dto) {
63
+ const model = new Agent();
64
+ model.id = dto.id;
65
+ model.createdAt = new Date(dto.createdAt);
66
+ model.name = dto.name;
67
+ model.identifier = dto.identifier;
68
+ model.description = dto.description;
69
+ model.connectorUrl = dto.connectorUrl;
70
+ model.isGeneric = dto.isGeneric;
71
+ model.answerSpecification = dto.answerSpecification;
72
+ model.tools = dto.tools ? dto.tools : [];
73
+ model.llmProvider = dto.llmProvider;
74
+ model.llmModel = dto.llmModel;
75
+ model.llmTemperature = dto.llmTemperature;
76
+ model.llmTimeout = dto.llmTimeout;
77
+ model.llmRetries = dto.llmRetries;
78
+ model.llmUserPrompt = dto.llmUserPrompt ? Prompt.fromDto(dto.llmUserPrompt) : undefined;
79
+ model.llmUserPromptId = dto.llmUserPromptId;
80
+ model.llmSystemPrompt = dto.llmSystemPrompt ? Prompt.fromDto(dto.llmSystemPrompt) : undefined;
81
+ model.llmSystemPromptId = dto.llmSystemPromptId;
82
+ model.llmUserPromptHistory = dto.llmUserPromptHistory ? Prompt.fromDto(dto.llmUserPromptHistory) : undefined;
83
+ model.llmUserPromptHistoryId = dto.llmUserPromptHistoryId;
84
+ model.llmSystemPromptHistory = dto.llmSystemPromptHistory ? Prompt.fromDto(dto.llmSystemPromptHistory) : undefined;
85
+ model.llmSystemPromptHistoryId = dto.llmSystemPromptHistoryId;
86
+ model.ragModel = dto.ragModel;
87
+ model.ragProvider = dto.ragProvider;
88
+ return model;
89
+ }
90
+ }
91
+
92
+ class AgentService extends BaseDbApiService {
93
+ http;
94
+ config;
95
+ constructor(http, config) {
96
+ super(http, config);
97
+ this.http = http;
98
+ this.config = config;
99
+ this.url = `${this.config.orchestratorDbUrl}/agents`;
100
+ }
101
+ getNewModel() {
102
+ return new Agent();
103
+ }
104
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentService, deps: [{ token: i1.HttpClient }, { token: ORCHESTRATOR_CONFIGURATION }], target: i0.ɵɵFactoryTarget.Injectable });
105
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentService, providedIn: 'root' });
106
+ }
107
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentService, decorators: [{
108
+ type: Injectable,
109
+ args: [{ providedIn: 'root' }]
110
+ }], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
111
+ type: Inject,
112
+ args: [ORCHESTRATOR_CONFIGURATION]
113
+ }] }] });
114
+
115
+ class AgentRagUploadComponent extends BaseDialogComponent {
116
+ agentId = input(...(ngDevMode ? [undefined, { debugName: "agentId" }] : []));
117
+ chatId = input(...(ngDevMode ? [undefined, { debugName: "chatId" }] : []));
118
+ uploadedFiles = signal([], ...(ngDevMode ? [{ debugName: "uploadedFiles" }] : []));
119
+ agent = signal(undefined, ...(ngDevMode ? [{ debugName: "agent" }] : []));
120
+ isUploading = signal(false, ...(ngDevMode ? [{ debugName: "isUploading" }] : []));
121
+ uploadError = signal(undefined, ...(ngDevMode ? [{ debugName: "uploadError" }] : []));
122
+ agentService = inject(AgentService);
123
+ orchestratorService = inject(OrchestratorService);
124
+ ngOnInit() {
125
+ if (this.agentId()) {
126
+ this.agentService.get(this.agentId()).subscribe((result) => {
127
+ if (result instanceof MappedApiError) {
128
+ this.uploadError.set('Fehler beim Laden des Agents');
129
+ return;
130
+ }
131
+ this.agent.set(result.data);
132
+ });
133
+ }
134
+ }
135
+ onFileSelect(event) {
136
+ const files = event.currentFiles || [];
137
+ this.uploadedFiles.set(files);
138
+ }
139
+ onFileRemove(event) {
140
+ const files = this.uploadedFiles();
141
+ const index = files.findIndex((f) => f.name === event.file.name);
142
+ if (index > -1) {
143
+ files.splice(index, 1);
144
+ this.uploadedFiles.set([...files]);
145
+ }
146
+ }
147
+ uploadFiles() {
148
+ const agent = this.agent();
149
+ if (!agent || !agent.identifier) {
150
+ this.uploadError.set('Agent-Identifier nicht gefunden');
151
+ return;
152
+ }
153
+ const files = this.uploadedFiles();
154
+ if (files.length === 0) {
155
+ return;
156
+ }
157
+ this.isUploading.set(true);
158
+ this.uploadError.set(undefined);
159
+ const ragInfo = {
160
+ agentIdentifier: agent.identifier,
161
+ chatId: this.chatId(),
162
+ };
163
+ this.orchestratorService.storeRagDocuments(files, ragInfo).subscribe({
164
+ next: (result) => {
165
+ this.isUploading.set(false);
166
+ if (result instanceof MappedApiError) {
167
+ this.uploadError.set('Fehler beim Hochladen der Dateien');
168
+ }
169
+ else {
170
+ this.close();
171
+ }
172
+ },
173
+ error: () => {
174
+ this.isUploading.set(false);
175
+ this.uploadError.set('Fehler beim Hochladen der Dateien');
176
+ },
177
+ });
178
+ }
179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentRagUploadComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", type: AgentRagUploadComponent, isStandalone: true, selector: "sftech-agent-rag-upload", inputs: { agentId: { classPropertyName: "agentId", publicName: "agentId", isSignal: true, isRequired: false, transformFunction: null }, chatId: { classPropertyName: "chatId", publicName: "chatId", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: "<sftech-base-dialog (closed)=\"close()\">\r\n <ng-template #body>\r\n <div class=\"h-full overflow-auto\">\r\n <p class=\"mb-4 text-gray-600\">\r\n Laden Sie Dokumente hoch, die f\u00FCr die RAG-Funktion (Retrieval-Augmented Generation) verwendet werden sollen.\r\n </p>\r\n\r\n @if (uploadError()) {\r\n <div class=\"p-4 mb-4 bg-red-50 border border-red-200 rounded text-red-800\">\r\n <strong>Fehler:</strong> {{ uploadError() }}\r\n </div>\r\n }\r\n\r\n @if (isUploading()) {\r\n <div class=\"flex items-center justify-center p-8\">\r\n <div class=\"text-center\">\r\n <i class=\"pi pi-spin pi-spinner text-4xl text-primary-500 mb-4\"></i>\r\n <p class=\"text-gray-600\">Dateien werden hochgeladen...</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"mt-4\">\r\n <p-fileupload\r\n mode=\"advanced\"\r\n [multiple]=\"true\"\r\n [showUploadButton]=\"false\"\r\n [showCancelButton]=\"false\"\r\n (onSelect)=\"onFileSelect($event)\"\r\n (onRemove)=\"onFileRemove($event)\"\r\n [auto]=\"false\"\r\n chooseLabel=\"Dateien ausw\u00E4hlen\"\r\n chooseIcon=\"pi pi-upload\"\r\n [maxFileSize]=\"10000000\"\r\n accept=\".pdf,.txt,.doc,.docx\">\r\n <ng-template #content let-files>\r\n @if (uploadedFiles().length > 0) {\r\n <div class=\"p-4 bg-gray-50 rounded\">\r\n <h5 class=\"font-semibold mb-2\">Ausgew\u00E4hlte Dateien ({{ uploadedFiles().length }})</h5>\r\n <ul class=\"list-disc pl-4\">\r\n @for (file of uploadedFiles(); track file.name) {\r\n <li class=\"mb-1\">\r\n <span class=\"font-medium\">{{ file.name }}</span>\r\n <span class=\"text-gray-500 text-sm ml-2\">({{ (file.size / 1024).toFixed(2) }} KB)</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </ng-template>\r\n </p-fileupload>\r\n <small class=\"block mt-2 text-gray-600\">\r\n Unterst\u00FCtzte Formate: PDF, TXT, DOC, DOCX (max. 10MB pro Datei)\r\n </small>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-template #footer>\r\n <div class=\"flex justify-end gap-2 mt-2\">\r\n <p-button\r\n label=\"Abbrechen\"\r\n (onClick)=\"close()\"\r\n [outlined]=\"true\"\r\n severity=\"secondary\">\r\n </p-button>\r\n <p-button\r\n label=\"Hochladen\"\r\n (onClick)=\"uploadFiles()\"\r\n [disabled]=\"uploadedFiles().length === 0 || isUploading()\"\r\n [loading]=\"isUploading()\">\r\n <fa-icon [icon]=\"iconProvider.upload\" class=\"mr-2\"></fa-icon>\r\n </p-button>\r\n </div>\r\n </ng-template>\r\n</sftech-base-dialog>\r\n", styles: [""], dependencies: [{ kind: "component", type: BaseDialogComponent, selector: "sftech-base-dialog", inputs: ["hasHeader", "hasFooter", "showButtons", "headerText"], outputs: ["closed"] }, { kind: "ngmodule", type: FileUploadModule }, { kind: "component", type: i1$1.FileUpload, selector: "p-fileupload, p-fileUpload", inputs: ["name", "url", "method", "multiple", "accept", "disabled", "auto", "withCredentials", "maxFileSize", "invalidFileSizeMessageSummary", "invalidFileSizeMessageDetail", "invalidFileTypeMessageSummary", "invalidFileTypeMessageDetail", "invalidFileLimitMessageDetail", "invalidFileLimitMessageSummary", "style", "styleClass", "previewWidth", "chooseLabel", "uploadLabel", "cancelLabel", "chooseIcon", "uploadIcon", "cancelIcon", "showUploadButton", "showCancelButton", "mode", "headers", "customUpload", "fileLimit", "uploadStyleClass", "cancelStyleClass", "removeStyleClass", "chooseStyleClass", "chooseButtonProps", "uploadButtonProps", "cancelButtonProps", "files"], outputs: ["onBeforeUpload", "onSend", "onUpload", "onError", "onClear", "onRemove", "onSelect", "onProgress", "uploadHandler", "onImageError", "onRemoveUploadedFile"] }, { kind: "component", type: Button, selector: "p-button", inputs: ["hostName", "type", "badge", "disabled", "raised", "rounded", "text", "plain", "outlined", "link", "tabindex", "size", "variant", "style", "styleClass", "badgeClass", "badgeSeverity", "ariaLabel", "autofocus", "iconPos", "icon", "label", "loading", "loadingIcon", "severity", "buttonProps", "fluid"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"], outputs: ["iconChange", "titleChange", "animationChange", "maskChange", "flipChange", "sizeChange", "pullChange", "borderChange", "inverseChange", "symbolChange", "rotateChange", "fixedWidthChange", "transformChange", "a11yRoleChange"] }] });
181
+ }
182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentRagUploadComponent, decorators: [{
183
+ type: Component,
184
+ args: [{ selector: 'sftech-agent-rag-upload', imports: [BaseDialogComponent, FileUploadModule, Button, FaIconComponent], template: "<sftech-base-dialog (closed)=\"close()\">\r\n <ng-template #body>\r\n <div class=\"h-full overflow-auto\">\r\n <p class=\"mb-4 text-gray-600\">\r\n Laden Sie Dokumente hoch, die f\u00FCr die RAG-Funktion (Retrieval-Augmented Generation) verwendet werden sollen.\r\n </p>\r\n\r\n @if (uploadError()) {\r\n <div class=\"p-4 mb-4 bg-red-50 border border-red-200 rounded text-red-800\">\r\n <strong>Fehler:</strong> {{ uploadError() }}\r\n </div>\r\n }\r\n\r\n @if (isUploading()) {\r\n <div class=\"flex items-center justify-center p-8\">\r\n <div class=\"text-center\">\r\n <i class=\"pi pi-spin pi-spinner text-4xl text-primary-500 mb-4\"></i>\r\n <p class=\"text-gray-600\">Dateien werden hochgeladen...</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"mt-4\">\r\n <p-fileupload\r\n mode=\"advanced\"\r\n [multiple]=\"true\"\r\n [showUploadButton]=\"false\"\r\n [showCancelButton]=\"false\"\r\n (onSelect)=\"onFileSelect($event)\"\r\n (onRemove)=\"onFileRemove($event)\"\r\n [auto]=\"false\"\r\n chooseLabel=\"Dateien ausw\u00E4hlen\"\r\n chooseIcon=\"pi pi-upload\"\r\n [maxFileSize]=\"10000000\"\r\n accept=\".pdf,.txt,.doc,.docx\">\r\n <ng-template #content let-files>\r\n @if (uploadedFiles().length > 0) {\r\n <div class=\"p-4 bg-gray-50 rounded\">\r\n <h5 class=\"font-semibold mb-2\">Ausgew\u00E4hlte Dateien ({{ uploadedFiles().length }})</h5>\r\n <ul class=\"list-disc pl-4\">\r\n @for (file of uploadedFiles(); track file.name) {\r\n <li class=\"mb-1\">\r\n <span class=\"font-medium\">{{ file.name }}</span>\r\n <span class=\"text-gray-500 text-sm ml-2\">({{ (file.size / 1024).toFixed(2) }} KB)</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </ng-template>\r\n </p-fileupload>\r\n <small class=\"block mt-2 text-gray-600\">\r\n Unterst\u00FCtzte Formate: PDF, TXT, DOC, DOCX (max. 10MB pro Datei)\r\n </small>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-template #footer>\r\n <div class=\"flex justify-end gap-2 mt-2\">\r\n <p-button\r\n label=\"Abbrechen\"\r\n (onClick)=\"close()\"\r\n [outlined]=\"true\"\r\n severity=\"secondary\">\r\n </p-button>\r\n <p-button\r\n label=\"Hochladen\"\r\n (onClick)=\"uploadFiles()\"\r\n [disabled]=\"uploadedFiles().length === 0 || isUploading()\"\r\n [loading]=\"isUploading()\">\r\n <fa-icon [icon]=\"iconProvider.upload\" class=\"mr-2\"></fa-icon>\r\n </p-button>\r\n </div>\r\n </ng-template>\r\n</sftech-base-dialog>\r\n" }]
185
+ }], propDecorators: { agentId: [{ type: i0.Input, args: [{ isSignal: true, alias: "agentId", required: false }] }], chatId: [{ type: i0.Input, args: [{ isSignal: true, alias: "chatId", required: false }] }] } });
186
+
187
+ export { AgentService as A, AgentRagUploadComponent as a, Agent as b };
188
+ //# sourceMappingURL=sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs","sources":["../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/core/models/agent.model.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/core/service/agent.service.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-rag-upload/agent-rag-upload.component.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-rag-upload/agent-rag-upload.component.html"],"sourcesContent":["import { BaseDbModel, EFilterTypes, IBaseDbResponseDto } from '@sftech/ng-shared';\r\nimport { IAgentResponseDto } from '../dtos/agent-response.dto';\r\nimport { IPromptHistoryResponseDto } from '../dtos/prompt-history-response.dto';\r\nimport { PromptHistory } from './prompt-history.model';\r\nimport { Prompt } from './prompt.model';\r\n\r\nexport class Agent extends BaseDbModel {\r\n public identifier!: string;\r\n\r\n public description!: string;\r\n\r\n public name!: string;\r\n\r\n public connectorUrl!: string;\r\n\r\n public isGeneric!: boolean;\r\n\r\n public answerSpecification!: string;\r\n\r\n public tools!: string[];\r\n\r\n public llmProvider!: string;\r\n\r\n public llmModel!: string;\r\n\r\n public llmTemperature!: number;\r\n\r\n public llmTimeout?: number;\r\n\r\n public llmRetries?: number;\r\n\r\n public llmUserPromptId!: number;\r\n\r\n public llmUserPrompt?: Prompt;\r\n\r\n public llmSystemPromptId!: number;\r\n\r\n public llmSystemPrompt?: Prompt;\r\n\r\n public llmUserPromptHistoryId?: number;\r\n\r\n public llmUserPromptHistory?: PromptHistory;\r\n\r\n public llmSystemPromptHistoryId?: number;\r\n\r\n public llmSystemPromptHistory?: PromptHistory;\r\n\r\n public ragModel?: string;\r\n\r\n public ragProvider?: string;\r\n\r\n public override propertiesToShow = ['name', 'identifier', 'description'];\r\n\r\n public override propertyUINames = new Map<string, string>([\r\n ['name', 'Name'],\r\n ['description', 'Beschreibung'],\r\n ['identifier', 'identifier'],\r\n ['llmUserPromptTemplateIdentifier', 'User Prompt Identifier'],\r\n ['connectorUrl', 'Connector-Url'],\r\n ['answerSpecification', 'Answer Specification'],\r\n ['isGeneric', 'Benutzerdefinierter Agent'],\r\n ['tools', 'LLM-Tools'],\r\n ['llmProvider', 'LLM-Provider'],\r\n ['llmModel', 'LLM-Model'],\r\n ['llmTemperature', 'LLM-Temperature'],\r\n ['llmTimeout', 'LLM-Timeout'],\r\n ['llmRetries', 'LLM-Retries'],\r\n ['llmUserPromptId', 'User Prompt ID'],\r\n ['llmUserPrompt', 'User Prompt Template'],\r\n ['llmSystemPromptId', 'System Prompt ID'],\r\n ['llmSystemPrompt', 'System Prompt Template'],\r\n ['ragProvider', 'RAG - Provider'],\r\n ['ragModel', 'RAG - Embedding Model'],\r\n ]);\r\n\r\n public override propertyFilterType = new Map<string, EFilterTypes>([\r\n ['name', EFilterTypes.STRING],\r\n ['template', EFilterTypes.STRING],\r\n ['identifier', EFilterTypes.STRING],\r\n ]);\r\n\r\n public override fromDto(dto: IAgentResponseDto): Agent {\r\n const model = new Agent();\r\n model.id = dto.id;\r\n model.createdAt = new Date(dto.createdAt);\r\n model.name = dto.name;\r\n model.identifier = dto.identifier;\r\n model.description = dto.description;\r\n model.connectorUrl = dto.connectorUrl;\r\n model.isGeneric = dto.isGeneric;\r\n model.answerSpecification = dto.answerSpecification;\r\n model.tools = dto.tools ? dto.tools : [];\r\n model.llmProvider = dto.llmProvider;\r\n model.llmModel = dto.llmModel;\r\n model.llmTemperature = dto.llmTemperature;\r\n model.llmTimeout = dto.llmTimeout;\r\n model.llmRetries = dto.llmRetries;\r\n model.llmUserPrompt = dto.llmUserPrompt ? (Prompt.fromDto(dto.llmUserPrompt) as Prompt) : undefined;\r\n model.llmUserPromptId = dto.llmUserPromptId;\r\n model.llmSystemPrompt = dto.llmSystemPrompt ? (Prompt.fromDto(dto.llmSystemPrompt) as Prompt) : undefined;\r\n model.llmSystemPromptId = dto.llmSystemPromptId;\r\n model.llmUserPromptHistory = dto.llmUserPromptHistory ? (Prompt.fromDto(dto.llmUserPromptHistory) as PromptHistory) : undefined;\r\n model.llmUserPromptHistoryId = dto.llmUserPromptHistoryId;\r\n model.llmSystemPromptHistory = dto.llmSystemPromptHistory ? (Prompt.fromDto(dto.llmSystemPromptHistory) as PromptHistory) : undefined;\r\n model.llmSystemPromptHistoryId = dto.llmSystemPromptHistoryId;\r\n model.ragModel = dto.ragModel;\r\n model.ragProvider = dto.ragProvider;\r\n return model;\r\n }\r\n}\r\n","import { HttpClient } from '@angular/common/http';\r\nimport { Inject, Injectable } from '@angular/core';\r\nimport { BaseDbApiService } from '@sftech/ng-shared';\r\nimport { IOrchestratorConfig } from '../configuration/orchestrator-config.interface';\r\nimport { ORCHESTRATOR_CONFIGURATION } from '../configuration/orchestrator-configuration.token';\r\nimport { IAgentCreateDto } from '../dtos/agent-create-request.dto';\r\nimport { IAgentResponseDto } from '../dtos/agent-response.dto';\r\nimport { IAgentUpdateDto } from '../dtos/agent-update-request.dto';\r\nimport { Agent } from '../models/agent.model';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class AgentService extends BaseDbApiService<Agent, IAgentCreateDto, IAgentUpdateDto, IAgentResponseDto> {\r\n constructor(\r\n protected override readonly http: HttpClient,\r\n @Inject(ORCHESTRATOR_CONFIGURATION) protected override readonly config: IOrchestratorConfig,\r\n ) {\r\n super(http, config);\r\n this.url = `${this.config.orchestratorDbUrl}/agents`;\r\n }\r\n\r\n protected getNewModel(): Agent {\r\n return new Agent();\r\n }\r\n}\r\n","import { Component, OnInit, inject, input, signal } from '@angular/core';\r\nimport { FaIconComponent } from '@fortawesome/angular-fontawesome';\r\nimport { BaseDialogComponent, IconProvider, MappedApiError } from '@sftech/ng-shared';\r\nimport { Button } from 'primeng/button';\r\nimport { DynamicDialogRef } from 'primeng/dynamicdialog';\r\nimport { FileRemoveEvent, FileSelectEvent, FileUploadModule } from 'primeng/fileupload';\r\nimport { IRagInfoDto } from '../../../../../core/dtos/rag-ingest-config.dto';\r\nimport { Agent } from '../../../../../core/models/agent.model';\r\nimport { AgentService } from '../../../../../core/service/agent.service';\r\nimport { OrchestratorService } from '../../../../../core/service/orchestrator.service';\r\n\r\n@Component({\r\n selector: 'sftech-agent-rag-upload',\r\n imports: [BaseDialogComponent, FileUploadModule, Button, FaIconComponent],\r\n templateUrl: './agent-rag-upload.component.html',\r\n styleUrl: './agent-rag-upload.component.css',\r\n})\r\nexport class AgentRagUploadComponent extends BaseDialogComponent implements OnInit {\r\n public agentId = input<number>();\r\n public chatId = input<number | undefined>();\r\n public uploadedFiles = signal<File[]>([]);\r\n public agent = signal<Agent | undefined>(undefined);\r\n public isUploading = signal<boolean>(false);\r\n public uploadError = signal<string | undefined>(undefined);\r\n\r\n private agentService = inject(AgentService);\r\n private orchestratorService = inject(OrchestratorService);\r\n\r\n public ngOnInit(): void {\r\n if (this.agentId()) {\r\n this.agentService.get(this.agentId()!).subscribe((result) => {\r\n if (result instanceof MappedApiError) {\r\n this.uploadError.set('Fehler beim Laden des Agents');\r\n return;\r\n }\r\n this.agent.set(result.data as Agent);\r\n });\r\n }\r\n }\r\n\r\n public onFileSelect(event: FileSelectEvent) {\r\n const files: File[] = event.currentFiles || [];\r\n this.uploadedFiles.set(files);\r\n }\r\n\r\n public onFileRemove(event: FileRemoveEvent) {\r\n const files = this.uploadedFiles();\r\n const index = files.findIndex((f) => f.name === event.file.name);\r\n if (index > -1) {\r\n files.splice(index, 1);\r\n this.uploadedFiles.set([...files]);\r\n }\r\n }\r\n\r\n public uploadFiles() {\r\n const agent = this.agent();\r\n if (!agent || !agent.identifier) {\r\n this.uploadError.set('Agent-Identifier nicht gefunden');\r\n return;\r\n }\r\n\r\n const files = this.uploadedFiles();\r\n if (files.length === 0) {\r\n return;\r\n }\r\n\r\n this.isUploading.set(true);\r\n this.uploadError.set(undefined);\r\n\r\n const ragInfo: IRagInfoDto = {\r\n agentIdentifier: agent.identifier,\r\n chatId: this.chatId(),\r\n };\r\n\r\n this.orchestratorService.storeRagDocuments(files, ragInfo).subscribe({\r\n next: (result) => {\r\n this.isUploading.set(false);\r\n if (result instanceof MappedApiError) {\r\n this.uploadError.set('Fehler beim Hochladen der Dateien');\r\n } else {\r\n this.close();\r\n }\r\n },\r\n error: () => {\r\n this.isUploading.set(false);\r\n this.uploadError.set('Fehler beim Hochladen der Dateien');\r\n },\r\n });\r\n }\r\n}\r\n","<sftech-base-dialog (closed)=\"close()\">\r\n <ng-template #body>\r\n <div class=\"h-full overflow-auto\">\r\n <p class=\"mb-4 text-gray-600\">\r\n Laden Sie Dokumente hoch, die für die RAG-Funktion (Retrieval-Augmented Generation) verwendet werden sollen.\r\n </p>\r\n\r\n @if (uploadError()) {\r\n <div class=\"p-4 mb-4 bg-red-50 border border-red-200 rounded text-red-800\">\r\n <strong>Fehler:</strong> {{ uploadError() }}\r\n </div>\r\n }\r\n\r\n @if (isUploading()) {\r\n <div class=\"flex items-center justify-center p-8\">\r\n <div class=\"text-center\">\r\n <i class=\"pi pi-spin pi-spinner text-4xl text-primary-500 mb-4\"></i>\r\n <p class=\"text-gray-600\">Dateien werden hochgeladen...</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"mt-4\">\r\n <p-fileupload\r\n mode=\"advanced\"\r\n [multiple]=\"true\"\r\n [showUploadButton]=\"false\"\r\n [showCancelButton]=\"false\"\r\n (onSelect)=\"onFileSelect($event)\"\r\n (onRemove)=\"onFileRemove($event)\"\r\n [auto]=\"false\"\r\n chooseLabel=\"Dateien auswählen\"\r\n chooseIcon=\"pi pi-upload\"\r\n [maxFileSize]=\"10000000\"\r\n accept=\".pdf,.txt,.doc,.docx\">\r\n <ng-template #content let-files>\r\n @if (uploadedFiles().length > 0) {\r\n <div class=\"p-4 bg-gray-50 rounded\">\r\n <h5 class=\"font-semibold mb-2\">Ausgewählte Dateien ({{ uploadedFiles().length }})</h5>\r\n <ul class=\"list-disc pl-4\">\r\n @for (file of uploadedFiles(); track file.name) {\r\n <li class=\"mb-1\">\r\n <span class=\"font-medium\">{{ file.name }}</span>\r\n <span class=\"text-gray-500 text-sm ml-2\">({{ (file.size / 1024).toFixed(2) }} KB)</span>\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </ng-template>\r\n </p-fileupload>\r\n <small class=\"block mt-2 text-gray-600\">\r\n Unterstützte Formate: PDF, TXT, DOC, DOCX (max. 10MB pro Datei)\r\n </small>\r\n </div>\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-template #footer>\r\n <div class=\"flex justify-end gap-2 mt-2\">\r\n <p-button\r\n label=\"Abbrechen\"\r\n (onClick)=\"close()\"\r\n [outlined]=\"true\"\r\n severity=\"secondary\">\r\n </p-button>\r\n <p-button\r\n label=\"Hochladen\"\r\n (onClick)=\"uploadFiles()\"\r\n [disabled]=\"uploadedFiles().length === 0 || isUploading()\"\r\n [loading]=\"isUploading()\">\r\n <fa-icon [icon]=\"iconProvider.upload\" class=\"mr-2\"></fa-icon>\r\n </p-button>\r\n </div>\r\n </ng-template>\r\n</sftech-base-dialog>\r\n"],"names":["i1"],"mappings":"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"}