@sftech/ng-orchestrator 0.0.18 → 0.0.21
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/fesm2022/{sftech-ng-orchestrator-agent-rag-upload.component-iqEbrzkb.mjs → sftech-ng-orchestrator-agent-rag-upload.component-d281IZS6.mjs} +2 -2
- package/fesm2022/{sftech-ng-orchestrator-agent-rag-upload.component-iqEbrzkb.mjs.map → sftech-ng-orchestrator-agent-rag-upload.component-d281IZS6.mjs.map} +1 -1
- package/fesm2022/{sftech-ng-orchestrator-agents.routes-CVcxzNAE.mjs → sftech-ng-orchestrator-agents.routes-BMA3nsjg.mjs} +21 -7
- package/fesm2022/sftech-ng-orchestrator-agents.routes-BMA3nsjg.mjs.map +1 -0
- package/fesm2022/sftech-ng-orchestrator-chats.routes-iRU4Q1Hz.mjs +740 -0
- package/fesm2022/sftech-ng-orchestrator-chats.routes-iRU4Q1Hz.mjs.map +1 -0
- package/fesm2022/{sftech-ng-orchestrator-prompt-display.component-BkSLQgGU.mjs → sftech-ng-orchestrator-prompt-display.component-BGO4cTtM.mjs} +2 -2
- package/fesm2022/{sftech-ng-orchestrator-prompt-display.component-BkSLQgGU.mjs.map → sftech-ng-orchestrator-prompt-display.component-BGO4cTtM.mjs.map} +1 -1
- package/fesm2022/sftech-ng-orchestrator-prompts.routes-BLBkcAxi.mjs +51 -0
- package/fesm2022/sftech-ng-orchestrator-prompts.routes-BLBkcAxi.mjs.map +1 -0
- package/fesm2022/{sftech-ng-orchestrator-sftech-ng-orchestrator-D9fLhC24.mjs → sftech-ng-orchestrator-sftech-ng-orchestrator-CJwdYvWr.mjs} +6 -6
- package/fesm2022/{sftech-ng-orchestrator-sftech-ng-orchestrator-D9fLhC24.mjs.map → sftech-ng-orchestrator-sftech-ng-orchestrator-CJwdYvWr.mjs.map} +1 -1
- package/fesm2022/sftech-ng-orchestrator.mjs +1 -1
- package/lib/ng-orchestrator/chats/agent-chat/agent-chat-message-human-input/agent-chat-message-human-input.component.d.ts +3 -0
- package/lib/ng-orchestrator/chats/agent-chat/agent-chat-message-human-input-initial/agent-chat-message-human-input-initial.component.d.ts +8 -1
- package/lib/ng-orchestrator/chats/agent-chat/agent-chat.component.d.ts +2 -0
- package/lib/ng-orchestrator/chats/agent-selection/agent-selection.component.d.ts +6 -0
- package/lib/ng-orchestrator/chats/chats.routes.d.ts +1 -2
- package/package.json +2 -2
- package/fesm2022/sftech-ng-orchestrator-agents.routes-CVcxzNAE.mjs.map +0 -1
- package/fesm2022/sftech-ng-orchestrator-chats.routes-BDe9JC4m.mjs +0 -625
- package/fesm2022/sftech-ng-orchestrator-chats.routes-BDe9JC4m.mjs.map +0 -1
- package/fesm2022/sftech-ng-orchestrator-prompts.routes-DeR6lppF.mjs +0 -51
- package/fesm2022/sftech-ng-orchestrator-prompts.routes-DeR6lppF.mjs.map +0 -1
|
@@ -1,625 +0,0 @@
|
|
|
1
|
-
import { AuthenticationGuard } from '@sftech/ng-auth';
|
|
2
|
-
import { NgClass, DatePipe } from '@angular/common';
|
|
3
|
-
import * as i0 from '@angular/core';
|
|
4
|
-
import { Inject, Injectable, input, EventEmitter, inject, effect, Output, Component, signal, computed, ViewChild } from '@angular/core';
|
|
5
|
-
import { ActivatedRoute, Router, RouterLink, RouterOutlet } from '@angular/router';
|
|
6
|
-
import { FaIconComponent } from '@fortawesome/angular-fontawesome';
|
|
7
|
-
import { BaseDbApiService, IconProvider, MappedApiError, FormErrorDisplayComponent, OData, OdataFilter, EFilterOperator, EFilterTypes, ESortDirection, BaseListComponent } from '@sftech/ng-shared';
|
|
8
|
-
import { MessageService } from 'primeng/api';
|
|
9
|
-
import { Button, ButtonDirective } from 'primeng/button';
|
|
10
|
-
import { DialogService } from 'primeng/dynamicdialog';
|
|
11
|
-
import { Tooltip } from 'primeng/tooltip';
|
|
12
|
-
import { map, catchError } from 'rxjs';
|
|
13
|
-
import { A as AgentService, a as AgentRagUploadComponent } from './sftech-ng-orchestrator-agent-rag-upload.component-iqEbrzkb.mjs';
|
|
14
|
-
import { A as AgentRun, O as ORCHESTRATOR_CONFIGURATION, C as Chat, E as EAgentRunStatus, a as OrchestratorService, b as ChatMessage } from './sftech-ng-orchestrator-sftech-ng-orchestrator-D9fLhC24.mjs';
|
|
15
|
-
import * as i1 from '@angular/common/http';
|
|
16
|
-
import { faNoteSticky, faCog, faCheck, faXmark, faSpinner, faClipboardCheck, faCircleQuestion, faBrain, faUser, faNetworkWired } from '@fortawesome/free-solid-svg-icons';
|
|
17
|
-
import * as i1$1 from '@angular/forms';
|
|
18
|
-
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
19
|
-
import { AgentRunIconTextDataprovider as AgentRunIconTextDataprovider$1 } from 'libs/ng-orchestrator/src/lib/ng-orchestrator/chats/core/dataprovider/agent-run-icon-text.dataprovider';
|
|
20
|
-
import { FloatLabel } from 'primeng/floatlabel';
|
|
21
|
-
import { InputText } from 'primeng/inputtext';
|
|
22
|
-
import { MarkdownComponent } from 'ngx-markdown';
|
|
23
|
-
import { Panel } from 'primeng/panel';
|
|
24
|
-
|
|
25
|
-
class AgentRunService extends BaseDbApiService {
|
|
26
|
-
http;
|
|
27
|
-
config;
|
|
28
|
-
constructor(http, config) {
|
|
29
|
-
super(http, config);
|
|
30
|
-
this.http = http;
|
|
31
|
-
this.config = config;
|
|
32
|
-
this.url = `${this.config.orchestratorDbUrl}/agent-runs`;
|
|
33
|
-
}
|
|
34
|
-
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
|
35
|
-
insert(dto) {
|
|
36
|
-
throw new Error('Method not implemented');
|
|
37
|
-
}
|
|
38
|
-
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
|
39
|
-
update(id, dto) {
|
|
40
|
-
throw new Error('Method not implemented');
|
|
41
|
-
}
|
|
42
|
-
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
|
43
|
-
delete(id) {
|
|
44
|
-
throw new Error('Method not implemented');
|
|
45
|
-
}
|
|
46
|
-
getNewModel() {
|
|
47
|
-
return new AgentRun();
|
|
48
|
-
}
|
|
49
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentRunService, deps: [{ token: i1.HttpClient }, { token: ORCHESTRATOR_CONFIGURATION }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
50
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentRunService, providedIn: 'root' });
|
|
51
|
-
}
|
|
52
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentRunService, decorators: [{
|
|
53
|
-
type: Injectable,
|
|
54
|
-
args: [{ providedIn: 'root' }]
|
|
55
|
-
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
56
|
-
type: Inject,
|
|
57
|
-
args: [ORCHESTRATOR_CONFIGURATION]
|
|
58
|
-
}] }] });
|
|
59
|
-
|
|
60
|
-
class ChatService extends BaseDbApiService {
|
|
61
|
-
http;
|
|
62
|
-
config;
|
|
63
|
-
constructor(http, config) {
|
|
64
|
-
super(http, config);
|
|
65
|
-
this.http = http;
|
|
66
|
-
this.config = config;
|
|
67
|
-
this.url = `${this.config.orchestratorDbUrl}/chats`;
|
|
68
|
-
}
|
|
69
|
-
odata(odataQuery) {
|
|
70
|
-
return this.http.get(`${this.url}/${odataQuery.toGetParameter()}`).pipe(map((response) => this.responseOdataMapping(response)), catchError((error) => {
|
|
71
|
-
return this.httpErrorToApiResponse(error);
|
|
72
|
-
}));
|
|
73
|
-
}
|
|
74
|
-
insert(dto) {
|
|
75
|
-
return this.http.post(this.url, dto).pipe(map((response) => this.responseMapping(response)), catchError((error) => {
|
|
76
|
-
return this.httpErrorToApiResponse(error);
|
|
77
|
-
}));
|
|
78
|
-
}
|
|
79
|
-
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
|
80
|
-
update(id, dto) {
|
|
81
|
-
throw new Error('update of a chat is not allowed');
|
|
82
|
-
}
|
|
83
|
-
getNewModel() {
|
|
84
|
-
return new Chat();
|
|
85
|
-
}
|
|
86
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ChatService, deps: [{ token: i1.HttpClient }, { token: ORCHESTRATOR_CONFIGURATION }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
87
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ChatService, providedIn: 'root' });
|
|
88
|
-
}
|
|
89
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ChatService, decorators: [{
|
|
90
|
-
type: Injectable,
|
|
91
|
-
args: [{ providedIn: 'root' }]
|
|
92
|
-
}], ctorParameters: () => [{ type: i1.HttpClient }, { type: undefined, decorators: [{
|
|
93
|
-
type: Inject,
|
|
94
|
-
args: [ORCHESTRATOR_CONFIGURATION]
|
|
95
|
-
}] }] });
|
|
96
|
-
|
|
97
|
-
class OrchestratorIconProvider extends IconProvider {
|
|
98
|
-
static agentRunStatusInit = faNoteSticky;
|
|
99
|
-
static agentRunStatusRunning = faCog;
|
|
100
|
-
static agentRunStatusCompleted = faCheck;
|
|
101
|
-
static agentRunStatusFailed = faXmark;
|
|
102
|
-
static agentRunStatusPrerun = faSpinner;
|
|
103
|
-
static agentRunStatusPostrun = faClipboardCheck;
|
|
104
|
-
static agentRunStatusClarify = faCircleQuestion;
|
|
105
|
-
static messageTypeAI = faBrain;
|
|
106
|
-
static messageTypeHuman = faUser;
|
|
107
|
-
static messageTypeSystem = faNetworkWired;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// biome-ignore lint/complexity/noStaticOnlyClass: <explanation>
|
|
111
|
-
class AgentRunIconTextDataprovider {
|
|
112
|
-
static UNKNOWN_TEXT = 'Unbekannt';
|
|
113
|
-
static getTextForStatus(status) {
|
|
114
|
-
if (!status) {
|
|
115
|
-
return AgentRunIconTextDataprovider.UNKNOWN_TEXT;
|
|
116
|
-
}
|
|
117
|
-
switch (status) {
|
|
118
|
-
case EAgentRunStatus.INIT:
|
|
119
|
-
return 'Anlage';
|
|
120
|
-
case EAgentRunStatus.RUNNING:
|
|
121
|
-
return 'In Bearbeitung';
|
|
122
|
-
case EAgentRunStatus.COMPLETED:
|
|
123
|
-
return 'Abgeschlossen';
|
|
124
|
-
case EAgentRunStatus.FAILED:
|
|
125
|
-
return 'Fehlgeschlagen';
|
|
126
|
-
case EAgentRunStatus.CLARIFICATION_NEEDED:
|
|
127
|
-
return 'Rückfrage';
|
|
128
|
-
case EAgentRunStatus.PRERUNNING:
|
|
129
|
-
return 'Vorbereitung';
|
|
130
|
-
case EAgentRunStatus.POSTRUNNING:
|
|
131
|
-
return 'Nachbereitung';
|
|
132
|
-
default:
|
|
133
|
-
return AgentRunIconTextDataprovider.UNKNOWN_TEXT;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
static getIconForStatus(status) {
|
|
137
|
-
if (!status) {
|
|
138
|
-
return IconProvider.unknown;
|
|
139
|
-
}
|
|
140
|
-
switch (status) {
|
|
141
|
-
case EAgentRunStatus.INIT:
|
|
142
|
-
return OrchestratorIconProvider.agentRunStatusInit;
|
|
143
|
-
case EAgentRunStatus.RUNNING:
|
|
144
|
-
return OrchestratorIconProvider.agentRunStatusRunning;
|
|
145
|
-
case EAgentRunStatus.COMPLETED:
|
|
146
|
-
return OrchestratorIconProvider.agentRunStatusCompleted;
|
|
147
|
-
case EAgentRunStatus.FAILED:
|
|
148
|
-
return OrchestratorIconProvider.agentRunStatusFailed;
|
|
149
|
-
case EAgentRunStatus.CLARIFICATION_NEEDED:
|
|
150
|
-
return OrchestratorIconProvider.agentRunStatusClarify;
|
|
151
|
-
case EAgentRunStatus.PRERUNNING:
|
|
152
|
-
return OrchestratorIconProvider.agentRunStatusPrerun;
|
|
153
|
-
case EAgentRunStatus.POSTRUNNING:
|
|
154
|
-
return OrchestratorIconProvider.agentRunStatusPostrun;
|
|
155
|
-
default:
|
|
156
|
-
return IconProvider.unknown;
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
static getIconClassesForStatus(status) {
|
|
160
|
-
if (!status) {
|
|
161
|
-
return AgentRunIconTextDataprovider.UNKNOWN_TEXT;
|
|
162
|
-
}
|
|
163
|
-
switch (status) {
|
|
164
|
-
case EAgentRunStatus.INIT:
|
|
165
|
-
return '';
|
|
166
|
-
case EAgentRunStatus.RUNNING:
|
|
167
|
-
return 'text-primary-600';
|
|
168
|
-
case EAgentRunStatus.COMPLETED:
|
|
169
|
-
return 'text-green-600';
|
|
170
|
-
case EAgentRunStatus.FAILED:
|
|
171
|
-
return 'text-red-600';
|
|
172
|
-
case EAgentRunStatus.CLARIFICATION_NEEDED:
|
|
173
|
-
return '';
|
|
174
|
-
case EAgentRunStatus.PRERUNNING:
|
|
175
|
-
return '';
|
|
176
|
-
case EAgentRunStatus.POSTRUNNING:
|
|
177
|
-
return '';
|
|
178
|
-
default:
|
|
179
|
-
return '';
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
static getIconForMessageType(messageType) {
|
|
183
|
-
switch (messageType) {
|
|
184
|
-
case 'system':
|
|
185
|
-
return OrchestratorIconProvider.messageTypeSystem;
|
|
186
|
-
case 'human':
|
|
187
|
-
return OrchestratorIconProvider.messageTypeHuman;
|
|
188
|
-
case 'ai':
|
|
189
|
-
return OrchestratorIconProvider.messageTypeAI;
|
|
190
|
-
default:
|
|
191
|
-
return IconProvider.unknown;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
class AgentChatMessageHumanInputInitialComponent {
|
|
197
|
-
agent = input();
|
|
198
|
-
agentRunIdReceived = new EventEmitter();
|
|
199
|
-
messageService = inject(MessageService);
|
|
200
|
-
orchestratorService = inject(OrchestratorService);
|
|
201
|
-
form = new FormGroup({});
|
|
202
|
-
_agentChanged$ = effect(() => {
|
|
203
|
-
this.agent()
|
|
204
|
-
.llmUserPrompt?.template.match(/{{(.*?)}}/g)
|
|
205
|
-
?.forEach((m) => {
|
|
206
|
-
const key = m.slice(2, -2);
|
|
207
|
-
this.form.addControl(key, new FormControl('', [Validators.required]));
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
iconTextMapper = AgentRunIconTextDataprovider$1;
|
|
211
|
-
run() {
|
|
212
|
-
if (this.form.valid && this.form.valid) {
|
|
213
|
-
this.orchestratorService
|
|
214
|
-
.runAgent({
|
|
215
|
-
agentIdentifier: this.agent().identifier,
|
|
216
|
-
userInput: this.form.value,
|
|
217
|
-
})
|
|
218
|
-
.subscribe((res) => {
|
|
219
|
-
if (res instanceof MappedApiError) {
|
|
220
|
-
this.messageService.add({ severity: 'error', summary: 'Error', detail: res.messages.join('|') });
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
this.agentRunIdReceived.emit(res);
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
else {
|
|
227
|
-
console.error('Form is invalid');
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
getInputFormControlNames() {
|
|
231
|
-
return Object.keys(this.form.controls);
|
|
232
|
-
}
|
|
233
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageHumanInputInitialComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
234
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AgentChatMessageHumanInputInitialComponent, isStandalone: true, selector: "sftech-agent-chat-message-human-input-initial", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { agentRunIdReceived: "agentRunIdReceived" }, ngImport: i0, template: "<div class=\"my-2 p-4 rounded bg-white flex border-1 flex-row items-center text-right border-gray-600 flex-row-reverse\">\r\n <div class=\"me-4 ms-4 text-gray-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('human')\" size=\"2x\"></fa-icon>\r\n </div>\r\n <div class=\"m-0 flex-grow\">\r\n <div class=\"template border-b-1 border-gray-600 p-3\">{{this.agent()!.llmUserPrompt?.template}}</div>\r\n <hr />\r\n <div class=\"inputs mt-2\">\r\n <form [formGroup]=\"form!\">\r\n <div class=\"flex justify-end\">\r\n @for (controlName of getInputFormControlNames(); track controlName) {\r\n <div>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"{{ controlName}}\" formControlName=\"{{ controlName }}\" pInputText\r\n class=\"w-full\"/>\r\n <label for=\"{{ controlName }}\">{{ controlName }}</label>\r\n </p-floatlabel>\r\n <sftech-form-error-display [control]=\"form!.get(controlName)!\"\r\n [label]=\"controlName\"></sftech-form-error-display>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"mt-2\">\r\n <p-button type=\"submit\" label=\"Senden\" (onClick)=\"run()\" tabindex=\"1\"/>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</div>", styles: [""], dependencies: [{ kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: 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: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: FormErrorDisplayComponent, selector: "sftech-form-error-display", inputs: ["control", "label"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
235
|
-
}
|
|
236
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageHumanInputInitialComponent, decorators: [{
|
|
237
|
-
type: Component,
|
|
238
|
-
args: [{ selector: 'sftech-agent-chat-message-human-input-initial', imports: [FaIconComponent, Button, FloatLabel, FormErrorDisplayComponent, InputText, ReactiveFormsModule], template: "<div class=\"my-2 p-4 rounded bg-white flex border-1 flex-row items-center text-right border-gray-600 flex-row-reverse\">\r\n <div class=\"me-4 ms-4 text-gray-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('human')\" size=\"2x\"></fa-icon>\r\n </div>\r\n <div class=\"m-0 flex-grow\">\r\n <div class=\"template border-b-1 border-gray-600 p-3\">{{this.agent()!.llmUserPrompt?.template}}</div>\r\n <hr />\r\n <div class=\"inputs mt-2\">\r\n <form [formGroup]=\"form!\">\r\n <div class=\"flex justify-end\">\r\n @for (controlName of getInputFormControlNames(); track controlName) {\r\n <div>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"{{ controlName}}\" formControlName=\"{{ controlName }}\" pInputText\r\n class=\"w-full\"/>\r\n <label for=\"{{ controlName }}\">{{ controlName }}</label>\r\n </p-floatlabel>\r\n <sftech-form-error-display [control]=\"form!.get(controlName)!\"\r\n [label]=\"controlName\"></sftech-form-error-display>\r\n </div>\r\n }\r\n </div>\r\n <div class=\"mt-2\">\r\n <p-button type=\"submit\" label=\"Senden\" (onClick)=\"run()\" tabindex=\"1\"/>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</div>" }]
|
|
239
|
-
}], propDecorators: { agentRunIdReceived: [{
|
|
240
|
-
type: Output
|
|
241
|
-
}] } });
|
|
242
|
-
|
|
243
|
-
class AgentChatMessageHumanInputComponent {
|
|
244
|
-
agent = input();
|
|
245
|
-
agentRunId = input();
|
|
246
|
-
agentRunIdReceived = new EventEmitter();
|
|
247
|
-
messageService = inject(MessageService);
|
|
248
|
-
orchestratorService = inject(OrchestratorService);
|
|
249
|
-
form = new FormGroup({
|
|
250
|
-
message: new FormControl('', [Validators.required]),
|
|
251
|
-
});
|
|
252
|
-
iconTextMapper = AgentRunIconTextDataprovider$1;
|
|
253
|
-
run() {
|
|
254
|
-
if (this.form.valid) {
|
|
255
|
-
const message = this.form.value.message;
|
|
256
|
-
this.orchestratorService.chatAgent(this.agentRunId(), message).subscribe((res) => {
|
|
257
|
-
if (res instanceof MappedApiError) {
|
|
258
|
-
this.messageService.add({ severity: 'error', summary: 'Error', detail: res.messages.join('|') });
|
|
259
|
-
return;
|
|
260
|
-
}
|
|
261
|
-
this.form.reset();
|
|
262
|
-
this.agentRunIdReceived.emit(res);
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageHumanInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
267
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.14", type: AgentChatMessageHumanInputComponent, isStandalone: true, selector: "sftech-agent-chat-message-human-input", inputs: { agent: { classPropertyName: "agent", publicName: "agent", isSignal: true, isRequired: false, transformFunction: null }, agentRunId: { classPropertyName: "agentRunId", publicName: "agentRunId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { agentRunIdReceived: "agentRunIdReceived" }, ngImport: i0, template: "<div class=\"my-2 p-4 rounded bg-white flex border-1 flex-row items-center text-right border-gray-600 flex-row-reverse\">\r\n <div class=\"me-4 ms-4 text-gray-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('human')\" size=\"2x\"></fa-icon>\r\n </div>\r\n <div class=\"m-0 flex-grow\">\r\n <div class=\"inputs mt-2\">\r\n <form [formGroup]=\"form\">\r\n <div class=\"flex justify-end\">\r\n <div class=\"w-full\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\"\r\n id=\"message\"\r\n formControlName=\"message\"\r\n pInputText\r\n class=\"w-full\"/>\r\n <label for=\"message\">Nachricht</label>\r\n </p-floatlabel>\r\n <sftech-form-error-display [control]=\"form.get('message')!\"\r\n label=\"Nachricht\"></sftech-form-error-display>\r\n </div>\r\n </div>\r\n <div class=\"mt-2\">\r\n <p-button type=\"submit\" label=\"Senden\" (onClick)=\"run()\" tabindex=\"1\"></p-button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: 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: FloatLabel, selector: "p-floatlabel, p-floatLabel, p-float-label", inputs: ["variant"] }, { kind: "component", type: FormErrorDisplayComponent, selector: "sftech-form-error-display", inputs: ["control", "label"] }, { kind: "directive", type: InputText, selector: "[pInputText]", inputs: ["variant", "fluid", "pSize"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
|
|
268
|
-
}
|
|
269
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageHumanInputComponent, decorators: [{
|
|
270
|
-
type: Component,
|
|
271
|
-
args: [{ selector: 'sftech-agent-chat-message-human-input', imports: [FaIconComponent, Button, FloatLabel, FormErrorDisplayComponent, InputText, ReactiveFormsModule], template: "<div class=\"my-2 p-4 rounded bg-white flex border-1 flex-row items-center text-right border-gray-600 flex-row-reverse\">\r\n <div class=\"me-4 ms-4 text-gray-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('human')\" size=\"2x\"></fa-icon>\r\n </div>\r\n <div class=\"m-0 flex-grow\">\r\n <div class=\"inputs mt-2\">\r\n <form [formGroup]=\"form\">\r\n <div class=\"flex justify-end\">\r\n <div class=\"w-full\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\"\r\n id=\"message\"\r\n formControlName=\"message\"\r\n pInputText\r\n class=\"w-full\"/>\r\n <label for=\"message\">Nachricht</label>\r\n </p-floatlabel>\r\n <sftech-form-error-display [control]=\"form.get('message')!\"\r\n label=\"Nachricht\"></sftech-form-error-display>\r\n </div>\r\n </div>\r\n <div class=\"mt-2\">\r\n <p-button type=\"submit\" label=\"Senden\" (onClick)=\"run()\" tabindex=\"1\"></p-button>\r\n </div>\r\n </form>\r\n </div>\r\n </div>\r\n</div>\r\n" }]
|
|
272
|
-
}], propDecorators: { agentRunIdReceived: [{
|
|
273
|
-
type: Output
|
|
274
|
-
}] } });
|
|
275
|
-
|
|
276
|
-
class AgentChatMessageComponent {
|
|
277
|
-
message = input('message');
|
|
278
|
-
type = input('type');
|
|
279
|
-
iconTextMapper = AgentRunIconTextDataprovider;
|
|
280
|
-
extractJson(message) {
|
|
281
|
-
const jsonMatch = message.match(/```json\s*([\s\S]*?)\s*```/);
|
|
282
|
-
if (jsonMatch && jsonMatch[1]) {
|
|
283
|
-
try {
|
|
284
|
-
const data = JSON.parse(jsonMatch[1]);
|
|
285
|
-
const md = this._toMarkdownFromJson(data);
|
|
286
|
-
return md;
|
|
287
|
-
}
|
|
288
|
-
catch (e) {
|
|
289
|
-
console.error('Failed to parse JSON:', e);
|
|
290
|
-
return 'Invalid JSON';
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
return 'No JSON found';
|
|
294
|
-
}
|
|
295
|
-
_toMarkdownFromJson(obj) {
|
|
296
|
-
let md = '';
|
|
297
|
-
for (const key of Object.keys(obj)) {
|
|
298
|
-
const value = obj[key];
|
|
299
|
-
// Überschrift für jede Kategorie
|
|
300
|
-
md += `\n### ${key}\n\n`;
|
|
301
|
-
if (Array.isArray(value) && value.length && typeof value[0] === 'object') {
|
|
302
|
-
// Tabellen-Header
|
|
303
|
-
const headers = Object.keys(value[0]);
|
|
304
|
-
md += `| ${headers.join(' | ')} |\n`;
|
|
305
|
-
md += `| ${headers.map(() => '---').join(' | ')} |\n`;
|
|
306
|
-
// Tabellen-Zeilen
|
|
307
|
-
for (const row of value) {
|
|
308
|
-
md += `| ${headers.map((h) => row[h]).join(' | ')} |\n`;
|
|
309
|
-
}
|
|
310
|
-
md += '\n';
|
|
311
|
-
}
|
|
312
|
-
else if (typeof value === 'object') {
|
|
313
|
-
// Rekursiver Aufruf bei verschachtelten Objekten
|
|
314
|
-
md += this._toMarkdownFromJson(value);
|
|
315
|
-
}
|
|
316
|
-
else {
|
|
317
|
-
// Einfaches Feld
|
|
318
|
-
md += `- **${key}:** ${value}\n`;
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
return md;
|
|
322
|
-
}
|
|
323
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
324
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AgentChatMessageComponent, isStandalone: true, selector: "sftech-agent-chat-message", inputs: { message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (type() === 'ai_loading') {\r\n <div class=\"flex items-center p-4 rounded-xl bg-green-50 shadow-sm border border-green-200\">\r\n <div class=\"me-4 ms-2 text-green-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('ai')\" size=\"lg\"></fa-icon>\r\n </div>\r\n <div class=\"flex items-center space-x-3 text-gray-600\">\r\n <span class=\"text-sm\">Die Antwort wird ermittelt...</span>\r\n <div class=\"flex space-x-1\">\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay\"></div>\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay [animation-delay:-0.32s]\"></div>\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay [animation-delay:-0.16s]\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n\r\n@else if (type() === 'ai_failed') {\r\n <div class=\"flex items-center p-4 rounded-xl bg-red-50 shadow-sm border border-red-200\">\r\n <div class=\"me-4 ms-2 text-red-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('ai')\" size=\"lg\"></fa-icon>\r\n </div>\r\n <div class=\"text-sm text-red-700\">\r\n {{ message() }}\r\n </div>\r\n </div>\r\n}\r\n\r\n@else {\r\n <div\r\n class=\"w-full p-4 rounded-xl shadow-sm flex gap-3\"\r\n [ngClass]=\"{\r\n 'bg-green-50 border border-green-200': type() === 'ai',\r\n 'bg-gray-100 border border-gray-200 flex-row-reverse text-right': type() === 'human',\r\n 'bg-yellow-50 border border-yellow-200': type() === 'system',\r\n }\"\r\n >\r\n <div\r\n class=\"flex-shrink-0 mt-1\"\r\n [ngClass]=\"{\r\n 'text-green-600': type() === 'ai',\r\n 'text-gray-500': type() === 'human',\r\n 'text-yellow-600': type() === 'system',\r\n }\"\r\n >\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType(type())\" size=\"lg\"></fa-icon>\r\n </div>\r\n\r\n <div class=\"w-full text-sm leading-relaxed\">\r\n @if (message().includes('```json')) {\r\n <div class=\"p-3 rounded-md text-gray-100 overflow-x-auto text-xs font-mono\">\r\n <markdown class=\"markdown-body\">{{ extractJson(message()) }}</markdown>\r\n </div>\r\n } @else {\r\n <markdown class=\"markdown-body\">{{ message() }}</markdown>\r\n }\r\n </div>\r\n </div>\r\n}", styles: ["@layer utilities{@keyframes bounceDelay{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.animate-bounceDelay{animation:bounceDelay 1.4s infinite ease-in-out both}}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }] });
|
|
325
|
-
}
|
|
326
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatMessageComponent, decorators: [{
|
|
327
|
-
type: Component,
|
|
328
|
-
args: [{ selector: 'sftech-agent-chat-message', imports: [NgClass, FaIconComponent, MarkdownComponent], template: "@if (type() === 'ai_loading') {\r\n <div class=\"flex items-center p-4 rounded-xl bg-green-50 shadow-sm border border-green-200\">\r\n <div class=\"me-4 ms-2 text-green-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('ai')\" size=\"lg\"></fa-icon>\r\n </div>\r\n <div class=\"flex items-center space-x-3 text-gray-600\">\r\n <span class=\"text-sm\">Die Antwort wird ermittelt...</span>\r\n <div class=\"flex space-x-1\">\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay\"></div>\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay [animation-delay:-0.32s]\"></div>\r\n <div class=\"w-2.5 h-2.5 bg-green-600 rounded-full animate-bounceDelay [animation-delay:-0.16s]\"></div>\r\n </div>\r\n </div>\r\n </div>\r\n}\r\n\r\n@else if (type() === 'ai_failed') {\r\n <div class=\"flex items-center p-4 rounded-xl bg-red-50 shadow-sm border border-red-200\">\r\n <div class=\"me-4 ms-2 text-red-600\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType('ai')\" size=\"lg\"></fa-icon>\r\n </div>\r\n <div class=\"text-sm text-red-700\">\r\n {{ message() }}\r\n </div>\r\n </div>\r\n}\r\n\r\n@else {\r\n <div\r\n class=\"w-full p-4 rounded-xl shadow-sm flex gap-3\"\r\n [ngClass]=\"{\r\n 'bg-green-50 border border-green-200': type() === 'ai',\r\n 'bg-gray-100 border border-gray-200 flex-row-reverse text-right': type() === 'human',\r\n 'bg-yellow-50 border border-yellow-200': type() === 'system',\r\n }\"\r\n >\r\n <div\r\n class=\"flex-shrink-0 mt-1\"\r\n [ngClass]=\"{\r\n 'text-green-600': type() === 'ai',\r\n 'text-gray-500': type() === 'human',\r\n 'text-yellow-600': type() === 'system',\r\n }\"\r\n >\r\n <fa-icon [icon]=\"iconTextMapper.getIconForMessageType(type())\" size=\"lg\"></fa-icon>\r\n </div>\r\n\r\n <div class=\"w-full text-sm leading-relaxed\">\r\n @if (message().includes('```json')) {\r\n <div class=\"p-3 rounded-md text-gray-100 overflow-x-auto text-xs font-mono\">\r\n <markdown class=\"markdown-body\">{{ extractJson(message()) }}</markdown>\r\n </div>\r\n } @else {\r\n <markdown class=\"markdown-body\">{{ message() }}</markdown>\r\n }\r\n </div>\r\n </div>\r\n}", styles: ["@layer utilities{@keyframes bounceDelay{0%,80%,to{transform:scale(0)}40%{transform:scale(1)}}.animate-bounceDelay{animation:bounceDelay 1.4s infinite ease-in-out both}}\n"] }]
|
|
329
|
-
}] });
|
|
330
|
-
|
|
331
|
-
class AgentChatComponent {
|
|
332
|
-
activeRoute = inject(ActivatedRoute);
|
|
333
|
-
router = inject(Router);
|
|
334
|
-
agentService = inject(AgentService);
|
|
335
|
-
agentRunService = inject(AgentRunService);
|
|
336
|
-
chatService = inject(ChatService);
|
|
337
|
-
orchestratorService = inject(OrchestratorService);
|
|
338
|
-
messageService = inject(MessageService);
|
|
339
|
-
dialogService = inject(DialogService);
|
|
340
|
-
agent;
|
|
341
|
-
agentRuns = signal(undefined);
|
|
342
|
-
selectedAgentRun = signal(undefined);
|
|
343
|
-
selectedAgent = signal(undefined);
|
|
344
|
-
chatContainer;
|
|
345
|
-
iconProvider = IconProvider;
|
|
346
|
-
iconTextMapper = AgentRunIconTextDataprovider;
|
|
347
|
-
agentRunStatus = EAgentRunStatus;
|
|
348
|
-
subscriptions = [];
|
|
349
|
-
selectedAgentRunChanged$ = effect(() => {
|
|
350
|
-
if (!this.selectedAgentRun()) {
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
353
|
-
this._loadChat();
|
|
354
|
-
});
|
|
355
|
-
chatMessagesChanged$ = effect(() => {
|
|
356
|
-
const messages = this.selectedAgentRun()?.chat?.messages;
|
|
357
|
-
if (messages && messages.length > 0) {
|
|
358
|
-
this.startScrollingStrategy();
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
loading = computed(() => {
|
|
362
|
-
if (!this.selectedAgentRun()?.status) {
|
|
363
|
-
return false;
|
|
364
|
-
}
|
|
365
|
-
return ![EAgentRunStatus.COMPLETED, EAgentRunStatus.CLARIFICATION_NEEDED, EAgentRunStatus.FAILED, EAgentRunStatus.INIT].includes(this.selectedAgentRun().status);
|
|
366
|
-
});
|
|
367
|
-
ngOnInit() {
|
|
368
|
-
const agentId = Number(this.activeRoute.snapshot.paramMap.get('agentId'));
|
|
369
|
-
const agentRunId = Number(this.activeRoute.snapshot.paramMap.get('agentRunId'));
|
|
370
|
-
if (agentId) {
|
|
371
|
-
const odata = new OData();
|
|
372
|
-
odata.filter.addAnd(new OdataFilter('agentId', agentId, EFilterOperator.EQUALS, EFilterTypes.NUMERIC));
|
|
373
|
-
odata.order.column = 'updatedAt';
|
|
374
|
-
odata.order.direction = ESortDirection.DESC;
|
|
375
|
-
this.agentRunService
|
|
376
|
-
.odata(odata)
|
|
377
|
-
.pipe(map((res) => {
|
|
378
|
-
if (res instanceof MappedApiError) {
|
|
379
|
-
this.messageService.add({
|
|
380
|
-
severity: 'error',
|
|
381
|
-
summary: 'Error',
|
|
382
|
-
detail: 'Fehler beim Laden der Chat-Daten',
|
|
383
|
-
});
|
|
384
|
-
throw new Error(res.messages.join('|'));
|
|
385
|
-
}
|
|
386
|
-
this.selectedAgentRun.set(res.data.items.find((ar) => agentRunId == ar.id));
|
|
387
|
-
this.agentRuns.set(res.data.items);
|
|
388
|
-
}))
|
|
389
|
-
.subscribe();
|
|
390
|
-
this.agentService.get(agentId, true).subscribe((res) => {
|
|
391
|
-
if (res instanceof MappedApiError) {
|
|
392
|
-
this.messageService.add({
|
|
393
|
-
severity: 'error',
|
|
394
|
-
summary: 'Error',
|
|
395
|
-
detail: 'Fehler beim Laden des Agenten-Daten',
|
|
396
|
-
});
|
|
397
|
-
throw new Error(res.messages.join('|'));
|
|
398
|
-
}
|
|
399
|
-
this.selectedAgent.set(res.data);
|
|
400
|
-
});
|
|
401
|
-
}
|
|
402
|
-
else {
|
|
403
|
-
this.messageService.add({ severity: 'error', summary: 'Error', detail: 'Fehler beim Laden des Agenten' });
|
|
404
|
-
// this.router.navigate(['../chats']);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
ngOnDestroy() {
|
|
408
|
-
this.subscriptions.forEach((subscription) => subscription.unsubscribe());
|
|
409
|
-
}
|
|
410
|
-
startNewRun() {
|
|
411
|
-
if (!this.selectedAgent()) {
|
|
412
|
-
return;
|
|
413
|
-
}
|
|
414
|
-
const agentRun = new AgentRun();
|
|
415
|
-
agentRun.agentId = this.selectedAgent().id;
|
|
416
|
-
agentRun.agent = this.selectedAgent();
|
|
417
|
-
agentRun.status = EAgentRunStatus.INIT;
|
|
418
|
-
agentRun.createdAt = new Date();
|
|
419
|
-
agentRun.chat = new Chat();
|
|
420
|
-
const systemContextMessage = new ChatMessage();
|
|
421
|
-
systemContextMessage.messageType = 'system';
|
|
422
|
-
systemContextMessage.message = `${this.selectedAgent().llmSystemPrompt?.template}Antworte nach folgender Spezifikation:<br>${this.selectedAgent()?.answerSpecification}`;
|
|
423
|
-
agentRun.chat.messages = [systemContextMessage];
|
|
424
|
-
this.selectedAgentRun.set(agentRun);
|
|
425
|
-
}
|
|
426
|
-
selectAgentRun(agentRun) {
|
|
427
|
-
this.selectedAgentRun.set(agentRun);
|
|
428
|
-
if (this.selectedAgentRun().id) {
|
|
429
|
-
this._setRelativeUrl();
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
startObservingAgentRun(agentRunId) {
|
|
433
|
-
this.subscriptions.push(this.orchestratorService.observeAgentRun(agentRunId).subscribe({
|
|
434
|
-
next: (update) => {
|
|
435
|
-
if (update instanceof MappedApiError) {
|
|
436
|
-
this.messageService.add({ severity: 'error', summary: 'Error', detail: 'Fehler beim Beobachten des Agentenlaufs' });
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
this.selectedAgentRun.update((agentRun) => {
|
|
440
|
-
return this._mapUpdateOnAgentRun(agentRun, update);
|
|
441
|
-
});
|
|
442
|
-
if (update.id && this.agentRuns()?.filter((ars) => ars.id === update.id).length === 0) {
|
|
443
|
-
this.agentRuns.update((ars) => {
|
|
444
|
-
ars?.unshift(update);
|
|
445
|
-
return ars;
|
|
446
|
-
});
|
|
447
|
-
}
|
|
448
|
-
},
|
|
449
|
-
error: (err) => {
|
|
450
|
-
this.messageService.add({ severity: 'error', summary: 'Error', detail: 'Fehler beim Beobachten des Agentenlaufs' });
|
|
451
|
-
console.error('Error observing agent run:', err);
|
|
452
|
-
},
|
|
453
|
-
complete: () => {
|
|
454
|
-
console.log('Completed observing agent run');
|
|
455
|
-
},
|
|
456
|
-
}));
|
|
457
|
-
}
|
|
458
|
-
goBack() {
|
|
459
|
-
const index = this.router.url.indexOf('/agent/');
|
|
460
|
-
const result = this.router.url.substring(0, index);
|
|
461
|
-
this.router.navigateByUrl(result);
|
|
462
|
-
}
|
|
463
|
-
_loadChat() {
|
|
464
|
-
if (!this.selectedAgentRun() || !this.selectedAgentRun().chatId) {
|
|
465
|
-
return;
|
|
466
|
-
}
|
|
467
|
-
this.chatService.get(this.selectedAgentRun().chatId, true).subscribe((res) => {
|
|
468
|
-
if (res instanceof MappedApiError) {
|
|
469
|
-
this.messageService.add({
|
|
470
|
-
severity: 'error',
|
|
471
|
-
summary: 'Error',
|
|
472
|
-
detail: 'Fehler beim Laden der Chat-Daten',
|
|
473
|
-
});
|
|
474
|
-
return;
|
|
475
|
-
}
|
|
476
|
-
this.selectedAgentRun.update((ar) => {
|
|
477
|
-
ar.chat = res.data;
|
|
478
|
-
return ar;
|
|
479
|
-
});
|
|
480
|
-
this.startScrollingStrategy();
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
_setRelativeUrl() {
|
|
484
|
-
let relativeUrl;
|
|
485
|
-
if (this.router.url.includes('/r/')) {
|
|
486
|
-
const index = this.router.url.indexOf('/r/') + 3; // 3 = Länge von "/r/"
|
|
487
|
-
const result = this.router.url.substring(0, index);
|
|
488
|
-
relativeUrl = `${result}${this.selectedAgentRun().id}`;
|
|
489
|
-
}
|
|
490
|
-
else {
|
|
491
|
-
relativeUrl = `r/${this.selectedAgentRun().id}`;
|
|
492
|
-
}
|
|
493
|
-
this.router.navigate([relativeUrl], {
|
|
494
|
-
relativeTo: this.activeRoute,
|
|
495
|
-
replaceUrl: true, // überschreibt den Verlauf
|
|
496
|
-
skipLocationChange: false, // false = URL sichtbar, true = nur intern
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
_mapUpdateOnAgentRun(agentRun, update) {
|
|
500
|
-
if (!agentRun.chat?.messages && !update.chat?.messages) {
|
|
501
|
-
return update;
|
|
502
|
-
}
|
|
503
|
-
if (!update.chat && agentRun.chat) {
|
|
504
|
-
update.chat = agentRun.chat;
|
|
505
|
-
}
|
|
506
|
-
if (agentRun.chat?.messages && update.chat.messages.length <= agentRun.chat.messages.length) {
|
|
507
|
-
update.chat.messages = agentRun.chat.messages;
|
|
508
|
-
}
|
|
509
|
-
console.log('Mapped AgentRun:', update.chat.messages.length, agentRun.chat.messages.length);
|
|
510
|
-
return update;
|
|
511
|
-
}
|
|
512
|
-
openRagUploadModal() {
|
|
513
|
-
const agent = this.selectedAgent();
|
|
514
|
-
const chatId = this.selectedAgentRun()?.chatId;
|
|
515
|
-
if (!agent) {
|
|
516
|
-
this.messageService.add({
|
|
517
|
-
severity: 'error',
|
|
518
|
-
summary: 'Fehler',
|
|
519
|
-
detail: 'Agent nicht gefunden',
|
|
520
|
-
});
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
|
-
const header = chatId ? 'RAG-Dokumente für Chat hochladen' : 'RAG-Dokumente für Agent hochladen';
|
|
524
|
-
this.dialogService.open(AgentRagUploadComponent, {
|
|
525
|
-
inputValues: { agentId: agent.id, chatId },
|
|
526
|
-
focusOnShow: false,
|
|
527
|
-
modal: true,
|
|
528
|
-
dismissableMask: true,
|
|
529
|
-
header: header,
|
|
530
|
-
width: '50%',
|
|
531
|
-
contentStyle: { overflow: 'auto' },
|
|
532
|
-
});
|
|
533
|
-
}
|
|
534
|
-
startScrollingStrategy() {
|
|
535
|
-
this.scrollToBottom();
|
|
536
|
-
// Fallback-Scrolls für langsames Markdown-Rendering
|
|
537
|
-
[100, 500, 1000, 2000].forEach((delay) => {
|
|
538
|
-
setTimeout(() => this.scrollToBottom(), delay);
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
scrollToBottom() {
|
|
542
|
-
if (!this.chatContainer?.nativeElement) {
|
|
543
|
-
return;
|
|
544
|
-
}
|
|
545
|
-
const container = this.chatContainer.nativeElement;
|
|
546
|
-
container.scrollTop = container.scrollHeight - container.clientHeight;
|
|
547
|
-
}
|
|
548
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
549
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AgentChatComponent, isStandalone: true, selector: "sftech-agent-chat", providers: [DialogService], viewQueries: [{ propertyName: "chatContainer", first: true, predicate: ["chatContainer"], descendants: true }], ngImport: i0, template: "<div class=\"flex flex-col h-full shadow-lg\">\r\n <!-- Header \u00FCber gesamte Breite -->\r\n @if (selectedAgent()) {\r\n <div class=\"border-b border-gray-300 px-4 py-3 flex items-center bg-white\">\r\n <div class=\"flex items-center gap-3 flex-1\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"goBack()\"\r\n [pTooltip]=\"'Zur\u00FCck'\"\r\n tooltipPosition=\"bottom\"\r\n tabindex=\"2\">\r\n <fa-icon [icon]=\"iconProvider.back\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (selectedAgentRun()) {\r\n <h2 class=\"text-xl font-semibold\">\r\n Agent: {{ selectedAgent()?.name }}\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - hh:mm') }}\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-xl font-semibold\">\r\n Agent: {{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-sm\"\r\n (click)=\"startNewRun()\"\r\n tabindex=\"3\">\r\n <fa-icon [icon]=\"iconProvider.add\" class=\"mr-2\"></fa-icon>\r\n Neuer Chat\r\n </button>\r\n <div class=\"flex items-center gap-3 flex-1 justify-end\">\r\n @if (selectedAgentRun()) {\r\n @if (selectedAgent()?.ragProvider && selectedAgent()?.ragModel) {\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"openRagUploadModal()\"\r\n [pTooltip]=\"'RAG-Dokumente hochladen'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.documentAdd\" size=\"lg\"></fa-icon>\r\n </button>\r\n }\r\n <div [pTooltip]=\"'Status: ' + iconTextMapper.getTextForStatus(selectedAgentRun()?.status)\"\r\n tooltipPosition=\"bottom\"\r\n class=\"cursor-help\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(selectedAgentRun()?.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(selectedAgentRun()?.status)\"\r\n [animation]=\"selectedAgentRun()?.status === 'running' ? 'spin' : undefined\"\r\n size=\"lg\"></fa-icon>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Sidebar + Chat nebeneinander -->\r\n <div class=\"flex flex-1 min-h-0 overflow-hidden\">\r\n <div class=\"chats-panel border-r-1 border-gray-300 p-4 w-[250px] h-full flex-shrink-0 overflow-y-auto\">\r\n @if (agentRuns() === undefined) {\r\n <p class=\"m-0\">\r\n Die Chats werden geladen...\r\n </p>\r\n } @else if (!agentRuns()?.length) {\r\n <p class=\"m-0\">\r\n Bisher noch keine Chats vorhanden\r\n </p>\r\n } @else {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"border border-gray-300 rounded-lg p-4 hover:shadow-lg transition cursor-pointer\"\r\n (click)=\"selectAgentRun(agentRun)\"\r\n [class.bg-blue-100]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"text-sm text-gray-500\">{{ agentRun.createdAt | date:'dd.MM.YY - hh:mm' }}</div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n <div class=\"chat bg-gray-50 flex-1 relative\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <p class=\"m-0 text-gray-500\">\r\n Bitte einen Chat aus der linken Liste ausw\u00E4hlen\r\n </p>\r\n </div>\r\n } @else if (selectedAgent() === undefined) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <p class=\"m-0 text-gray-500\">\r\n Die Chat-Daten werden geladen...\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"absolute inset-0 overflow-y-auto p-3\" #chatContainer>\r\n @if (selectedAgentRun()!.chat) {\r\n @for (message of selectedAgentRun()!.chat!.messages; track message.id) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message [message]=\"message.message\"\r\n [type]=\"message.messageType\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n }\r\n @if (selectedAgentRun()!.status === agentRunStatus.INIT) {\r\n <sftech-agent-chat-message-human-input-initial [agent]=\"selectedAgent()\"\r\n (agentRunIdReceived)=\"startObservingAgentRun($event)\"></sftech-agent-chat-message-human-input-initial>\r\n }\r\n @if (loading()) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message [message]=\"'Am \u00DCberlegen'\"\r\n [type]=\"'ai_loading'\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n @if (selectedAgentRun()?.status === agentRunStatus.FAILED) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message\r\n [message]=\"'Es ist ein Fehler aufgetreten! Bitte versuche es zu einem sp\u00E4teren Zeitpunkt erneut.'\"\r\n [type]=\"'ai_failed'\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n @if (selectedAgentRun()!.status === agentRunStatus.COMPLETED) {\r\n <sftech-agent-chat-message-human-input [agent]=\"selectedAgent()\"\r\n [agentRunId]=\"selectedAgentRun()!.id\"\r\n (agentRunIdReceived)=\"startObservingAgentRun(selectedAgentRun()!.id!)\"></sftech-agent-chat-message-human-input>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [""], dependencies: [{ kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "loading", "severity", "raised", "rounded", "text", "outlined", "size", "plain", "fluid", "label", "icon", "buttonProps"] }, { kind: "component", type: AgentChatMessageComponent, selector: "sftech-agent-chat-message", inputs: ["message", "type"] }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "component", type: FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: AgentChatMessageHumanInputInitialComponent, selector: "sftech-agent-chat-message-human-input-initial", inputs: ["agent"], outputs: ["agentRunIdReceived"] }, { kind: "component", type: AgentChatMessageHumanInputComponent, selector: "sftech-agent-chat-message-human-input", inputs: ["agent", "agentRunId"], outputs: ["agentRunIdReceived"] }, { kind: "directive", type: Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] });
|
|
550
|
-
}
|
|
551
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentChatComponent, decorators: [{
|
|
552
|
-
type: Component,
|
|
553
|
-
args: [{ selector: 'sftech-agent-chat', imports: [ButtonDirective, AgentChatMessageComponent, DatePipe, FaIconComponent, AgentChatMessageHumanInputInitialComponent, AgentChatMessageHumanInputComponent, Tooltip], providers: [DialogService], template: "<div class=\"flex flex-col h-full shadow-lg\">\r\n <!-- Header \u00FCber gesamte Breite -->\r\n @if (selectedAgent()) {\r\n <div class=\"border-b border-gray-300 px-4 py-3 flex items-center bg-white\">\r\n <div class=\"flex items-center gap-3 flex-1\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"goBack()\"\r\n [pTooltip]=\"'Zur\u00FCck'\"\r\n tooltipPosition=\"bottom\"\r\n tabindex=\"2\">\r\n <fa-icon [icon]=\"iconProvider.back\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (selectedAgentRun()) {\r\n <h2 class=\"text-xl font-semibold\">\r\n Agent: {{ selectedAgent()?.name }}\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - hh:mm') }}\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-xl font-semibold\">\r\n Agent: {{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-sm\"\r\n (click)=\"startNewRun()\"\r\n tabindex=\"3\">\r\n <fa-icon [icon]=\"iconProvider.add\" class=\"mr-2\"></fa-icon>\r\n Neuer Chat\r\n </button>\r\n <div class=\"flex items-center gap-3 flex-1 justify-end\">\r\n @if (selectedAgentRun()) {\r\n @if (selectedAgent()?.ragProvider && selectedAgent()?.ragModel) {\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"openRagUploadModal()\"\r\n [pTooltip]=\"'RAG-Dokumente hochladen'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.documentAdd\" size=\"lg\"></fa-icon>\r\n </button>\r\n }\r\n <div [pTooltip]=\"'Status: ' + iconTextMapper.getTextForStatus(selectedAgentRun()?.status)\"\r\n tooltipPosition=\"bottom\"\r\n class=\"cursor-help\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(selectedAgentRun()?.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(selectedAgentRun()?.status)\"\r\n [animation]=\"selectedAgentRun()?.status === 'running' ? 'spin' : undefined\"\r\n size=\"lg\"></fa-icon>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Sidebar + Chat nebeneinander -->\r\n <div class=\"flex flex-1 min-h-0 overflow-hidden\">\r\n <div class=\"chats-panel border-r-1 border-gray-300 p-4 w-[250px] h-full flex-shrink-0 overflow-y-auto\">\r\n @if (agentRuns() === undefined) {\r\n <p class=\"m-0\">\r\n Die Chats werden geladen...\r\n </p>\r\n } @else if (!agentRuns()?.length) {\r\n <p class=\"m-0\">\r\n Bisher noch keine Chats vorhanden\r\n </p>\r\n } @else {\r\n <div class=\"flex flex-col gap-1\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"border border-gray-300 rounded-lg p-4 hover:shadow-lg transition cursor-pointer\"\r\n (click)=\"selectAgentRun(agentRun)\"\r\n [class.bg-blue-100]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"text-sm text-gray-500\">{{ agentRun.createdAt | date:'dd.MM.YY - hh:mm' }}</div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n <div class=\"chat bg-gray-50 flex-1 relative\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <p class=\"m-0 text-gray-500\">\r\n Bitte einen Chat aus der linken Liste ausw\u00E4hlen\r\n </p>\r\n </div>\r\n } @else if (selectedAgent() === undefined) {\r\n <div class=\"flex items-center justify-center h-full\">\r\n <p class=\"m-0 text-gray-500\">\r\n Die Chat-Daten werden geladen...\r\n </p>\r\n </div>\r\n } @else {\r\n <div class=\"absolute inset-0 overflow-y-auto p-3\" #chatContainer>\r\n @if (selectedAgentRun()!.chat) {\r\n @for (message of selectedAgentRun()!.chat!.messages; track message.id) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message [message]=\"message.message\"\r\n [type]=\"message.messageType\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n }\r\n @if (selectedAgentRun()!.status === agentRunStatus.INIT) {\r\n <sftech-agent-chat-message-human-input-initial [agent]=\"selectedAgent()\"\r\n (agentRunIdReceived)=\"startObservingAgentRun($event)\"></sftech-agent-chat-message-human-input-initial>\r\n }\r\n @if (loading()) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message [message]=\"'Am \u00DCberlegen'\"\r\n [type]=\"'ai_loading'\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n @if (selectedAgentRun()?.status === agentRunStatus.FAILED) {\r\n <div class=\"mb-2\">\r\n <sftech-agent-chat-message\r\n [message]=\"'Es ist ein Fehler aufgetreten! Bitte versuche es zu einem sp\u00E4teren Zeitpunkt erneut.'\"\r\n [type]=\"'ai_failed'\"></sftech-agent-chat-message>\r\n </div>\r\n }\r\n @if (selectedAgentRun()!.status === agentRunStatus.COMPLETED) {\r\n <sftech-agent-chat-message-human-input [agent]=\"selectedAgent()\"\r\n [agentRunId]=\"selectedAgentRun()!.id\"\r\n (agentRunIdReceived)=\"startObservingAgentRun(selectedAgentRun()!.id!)\"></sftech-agent-chat-message-human-input>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</div>\r\n" }]
|
|
554
|
-
}], propDecorators: { chatContainer: [{
|
|
555
|
-
type: ViewChild,
|
|
556
|
-
args: ['chatContainer']
|
|
557
|
-
}] } });
|
|
558
|
-
|
|
559
|
-
class AgentSelectionComponent extends BaseListComponent {
|
|
560
|
-
_repo = inject(AgentService);
|
|
561
|
-
_route = 'chats/agents';
|
|
562
|
-
orchestratorService = inject(OrchestratorService);
|
|
563
|
-
messageService = inject(MessageService);
|
|
564
|
-
iconProvider = IconProvider;
|
|
565
|
-
tools = signal(undefined);
|
|
566
|
-
ngOnInit() {
|
|
567
|
-
super.ngOnInit();
|
|
568
|
-
this.orchestratorService.getTools().subscribe((res) => {
|
|
569
|
-
if (res instanceof MappedApiError) {
|
|
570
|
-
this.messageService.add({ severity: 'error', summary: 'Fehler', detail: res.messages.join('|') });
|
|
571
|
-
return;
|
|
572
|
-
}
|
|
573
|
-
this.tools.set(res.data);
|
|
574
|
-
});
|
|
575
|
-
}
|
|
576
|
-
getToolNames(agent) {
|
|
577
|
-
if (!agent.tools || agent.tools.length === 0) {
|
|
578
|
-
return 'Keine Tools';
|
|
579
|
-
}
|
|
580
|
-
return agent.tools
|
|
581
|
-
.map((tool) => this.tools()?.find((t) => t.identifier === tool)?.name)
|
|
582
|
-
.filter((name) => !!name)
|
|
583
|
-
.join(' | ');
|
|
584
|
-
}
|
|
585
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentSelectionComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
586
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.14", type: AgentSelectionComponent, isStandalone: true, selector: "sftech-agent-selection", providers: [DialogService], usesInheritance: true, ngImport: i0, template: "<div class=\"p-2\">\r\n\r\n <h2 class=\"pt-4 text-2xl font-bold mb-4\">Agenten Auswahl</h2>\r\n\r\n @if (data() === undefined) {\r\n <p-panel [toggleable]=\"false\">\r\n <p class=\"m-0\">\r\n Daten werden geladen...\r\n </p>\r\n </p-panel>\r\n } @else if (!data()?.length) {\r\n <p-panel [toggleable]=\"false\">\r\n <p class=\"m-0\">\r\n Keine Daten vorhanden\r\n </p>\r\n </p-panel>\r\n } @else {\r\n <div class=\"grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\r\n @for (agent of data(); track agent) {\r\n <div\r\n class=\"aspect-square flex flex-col justify-between p-5 rounded-xl bg-white shadow-md border border-gray-200 hover:shadow-lg hover:scale-[1.02] transition cursor-pointer\"\r\n [routerLink]=\"['agent/' + agent.id]\"\r\n >\r\n <div>\r\n <div class=\"flex items-center gap-2 mb-4\">\r\n <div class=\"w-10 h-10 rounded-full bg-primary-100 text-primary-700 flex items-center justify-center font-bold\">\r\n {{ agent.name[0] }}\r\n </div>\r\n <h2 class=\"text-lg font-semibold\">{{ agent.name }}</h2>\r\n </div>\r\n <p class=\"text-gray-600 text-sm leading-snug line-clamp-3\">{{ agent.description }}</p>\r\n </div>\r\n <div class=\"flex flex-wrap gap-2 mt-4 border-t-1 border-gray-200 pt-2\">\r\n <span class=\"text-gray-500 text-xs font-medium px-2 py-0.5 rounded\">{{ getToolNames(agent) }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>", styles: [""], dependencies: [{ kind: "component", type: Panel, selector: "p-panel", inputs: ["toggleable", "header", "collapsed", "style", "styleClass", "iconPos", "expandIcon", "collapseIcon", "showHeader", "toggler", "transitionOptions", "toggleButtonProps"], outputs: ["collapsedChange", "onBeforeToggle", "onAfterToggle"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }] });
|
|
587
|
-
}
|
|
588
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: AgentSelectionComponent, decorators: [{
|
|
589
|
-
type: Component,
|
|
590
|
-
args: [{ selector: 'sftech-agent-selection', imports: [Panel, RouterLink], providers: [DialogService], template: "<div class=\"p-2\">\r\n\r\n <h2 class=\"pt-4 text-2xl font-bold mb-4\">Agenten Auswahl</h2>\r\n\r\n @if (data() === undefined) {\r\n <p-panel [toggleable]=\"false\">\r\n <p class=\"m-0\">\r\n Daten werden geladen...\r\n </p>\r\n </p-panel>\r\n } @else if (!data()?.length) {\r\n <p-panel [toggleable]=\"false\">\r\n <p class=\"m-0\">\r\n Keine Daten vorhanden\r\n </p>\r\n </p-panel>\r\n } @else {\r\n <div class=\"grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4\">\r\n @for (agent of data(); track agent) {\r\n <div\r\n class=\"aspect-square flex flex-col justify-between p-5 rounded-xl bg-white shadow-md border border-gray-200 hover:shadow-lg hover:scale-[1.02] transition cursor-pointer\"\r\n [routerLink]=\"['agent/' + agent.id]\"\r\n >\r\n <div>\r\n <div class=\"flex items-center gap-2 mb-4\">\r\n <div class=\"w-10 h-10 rounded-full bg-primary-100 text-primary-700 flex items-center justify-center font-bold\">\r\n {{ agent.name[0] }}\r\n </div>\r\n <h2 class=\"text-lg font-semibold\">{{ agent.name }}</h2>\r\n </div>\r\n <p class=\"text-gray-600 text-sm leading-snug line-clamp-3\">{{ agent.description }}</p>\r\n </div>\r\n <div class=\"flex flex-wrap gap-2 mt-4 border-t-1 border-gray-200 pt-2\">\r\n <span class=\"text-gray-500 text-xs font-medium px-2 py-0.5 rounded\">{{ getToolNames(agent) }}</span>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n }\r\n</div>" }]
|
|
591
|
-
}] });
|
|
592
|
-
|
|
593
|
-
class ChatsComponent {
|
|
594
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ChatsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
595
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.14", type: ChatsComponent, isStandalone: true, selector: "sftech-chats", ngImport: i0, template: '<router-outlet></router-outlet>', isInline: true, styles: [":host{display:block;height:100%;overflow:hidden}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }] });
|
|
596
|
-
}
|
|
597
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.14", ngImport: i0, type: ChatsComponent, decorators: [{
|
|
598
|
-
type: Component,
|
|
599
|
-
args: [{ selector: 'sftech-chats', imports: [RouterOutlet], template: '<router-outlet></router-outlet>', styles: [":host{display:block;height:100%;overflow:hidden}\n"] }]
|
|
600
|
-
}] });
|
|
601
|
-
|
|
602
|
-
const chatsRoutes = [
|
|
603
|
-
{
|
|
604
|
-
path: '',
|
|
605
|
-
component: ChatsComponent,
|
|
606
|
-
children: [
|
|
607
|
-
{
|
|
608
|
-
path: '',
|
|
609
|
-
component: AgentSelectionComponent,
|
|
610
|
-
},
|
|
611
|
-
{
|
|
612
|
-
path: 'agent/:agentId/r/:agentRunId',
|
|
613
|
-
component: AgentChatComponent,
|
|
614
|
-
},
|
|
615
|
-
{
|
|
616
|
-
path: 'agent/:agentId',
|
|
617
|
-
component: AgentChatComponent,
|
|
618
|
-
},
|
|
619
|
-
],
|
|
620
|
-
canActivate: [AuthenticationGuard],
|
|
621
|
-
},
|
|
622
|
-
];
|
|
623
|
-
|
|
624
|
-
export { chatsRoutes };
|
|
625
|
-
//# sourceMappingURL=sftech-ng-orchestrator-chats.routes-BDe9JC4m.mjs.map
|