@sftech/ng-orchestrator 1.0.0 → 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.
- package/README.md +88 -2
- package/fesm2022/{sftech-ng-orchestrator-agent-rag-upload.component-DGMkaMBy.mjs → sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs} +2 -2
- package/fesm2022/{sftech-ng-orchestrator-agent-rag-upload.component-DGMkaMBy.mjs.map → sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.mjs.map} +1 -1
- package/fesm2022/sftech-ng-orchestrator-agents.routes-bBcxJpUD.mjs +284 -0
- package/fesm2022/sftech-ng-orchestrator-agents.routes-bBcxJpUD.mjs.map +1 -0
- package/fesm2022/{sftech-ng-orchestrator-chats.routes-BRjYTnIk.mjs → sftech-ng-orchestrator-chats.routes-B3UPU3v9.mjs} +10 -10
- package/fesm2022/sftech-ng-orchestrator-chats.routes-B3UPU3v9.mjs.map +1 -0
- package/fesm2022/{sftech-ng-orchestrator-prompt-display.component--3QaYOkH.mjs → sftech-ng-orchestrator-prompt-display.component-Cf16yAfr.mjs} +2 -2
- package/fesm2022/{sftech-ng-orchestrator-prompt-display.component--3QaYOkH.mjs.map → sftech-ng-orchestrator-prompt-display.component-Cf16yAfr.mjs.map} +1 -1
- package/fesm2022/{sftech-ng-orchestrator-prompts.routes-kVoXLKCC.mjs → sftech-ng-orchestrator-prompts.routes-lV1Np2KD.mjs} +2 -2
- package/fesm2022/{sftech-ng-orchestrator-prompts.routes-kVoXLKCC.mjs.map → sftech-ng-orchestrator-prompts.routes-lV1Np2KD.mjs.map} +1 -1
- package/fesm2022/{sftech-ng-orchestrator-sftech-ng-orchestrator-BdFSlSN_.mjs → sftech-ng-orchestrator-sftech-ng-orchestrator-CzwZe61l.mjs} +7 -7
- package/fesm2022/sftech-ng-orchestrator-sftech-ng-orchestrator-CzwZe61l.mjs.map +1 -0
- package/fesm2022/sftech-ng-orchestrator.mjs +1 -1
- package/package.json +7 -4
- package/fesm2022/sftech-ng-orchestrator-agents.routes-DWOr4y4m.mjs +0 -284
- package/fesm2022/sftech-ng-orchestrator-agents.routes-DWOr4y4m.mjs.map +0 -1
- package/fesm2022/sftech-ng-orchestrator-chats.routes-BRjYTnIk.mjs.map +0 -1
- package/fesm2022/sftech-ng-orchestrator-sftech-ng-orchestrator-BdFSlSN_.mjs.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sftech-ng-orchestrator-agents.routes-bBcxJpUD.mjs","sources":["../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/agents.component.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/agents.component.html","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/core/validators/rag.validator.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-display/prompt-helper-modal/prompt-helper-modal.component.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-display/prompt-helper-modal/prompt-helper-modal.component.html","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-display/agent-display.component.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agent-display/agent-display.component.html","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agents-list/agents-list.component.ts","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/components/agent/agents-list/agents-list.component.html","../../../../libs/ng-orchestrator/src/lib/ng-orchestrator/admin/agents/agents.routes.ts"],"sourcesContent":["import { Component } from '@angular/core';\r\nimport { RouterOutlet } from '@angular/router';\r\n\r\n@Component({\r\n selector: 'sftech-agents',\r\n imports: [RouterOutlet],\r\n templateUrl: './agents.component.html',\r\n styleUrl: './agents.component.css',\r\n})\r\nexport class AgentsComponent {}\r\n","<router-outlet></router-outlet>\r\n","// rag.validator.ts\r\nimport { AbstractControl, FormGroup, ValidationErrors, ValidatorFn } from '@angular/forms';\r\n\r\nexport const ragPairValidator = (): ValidatorFn => {\r\n return (control: AbstractControl): ValidationErrors | null => {\r\n const group = control as FormGroup;\r\n\r\n const ragProvider = group.get('ragProvider')?.value;\r\n const ragModel = group.get('ragModel')?.value;\r\n\r\n // beide leer → ok\r\n if (!ragProvider && !ragModel) {\r\n return null;\r\n }\r\n\r\n // beide gesetzt → ok\r\n if (ragProvider && ragModel) {\r\n return null;\r\n }\r\n\r\n // nur eins gesetzt → Fehler auf dem FormGroup\r\n return { ragPairInvalid: true };\r\n };\r\n};\r\n","import { NgTemplateOutlet } from '@angular/common';\r\nimport { Component, OnDestroy, OnInit } from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { FaIconComponent } from '@fortawesome/angular-fontawesome';\r\nimport { BaseDialogComponent } from '@sftech/ng-shared';\r\nimport { AutoFocus } from 'primeng/autofocus';\r\nimport { Button } from 'primeng/button';\r\nimport { Fieldset } from 'primeng/fieldset';\r\nimport { FloatLabel } from 'primeng/floatlabel';\r\nimport { Popover } from 'primeng/popover';\r\nimport { Textarea } from 'primeng/textarea';\r\nimport { Subscription, map } from 'rxjs';\r\n\r\n@Component({\r\n selector: 'sftech-prompt-helper-modal',\r\n imports: [BaseDialogComponent, ReactiveFormsModule, Fieldset, FloatLabel, Textarea, AutoFocus, Button, FaIconComponent, Popover, NgTemplateOutlet],\r\n templateUrl: './prompt-helper-modal.component.html',\r\n styleUrl: './prompt-helper-modal.component.css',\r\n})\r\nexport class PromptHelperModalComponent extends BaseDialogComponent implements OnInit, OnDestroy {\r\n private _subscriptions: Subscription[] = [];\r\n\r\n protected systemPromptForm: FormGroup = new FormGroup({\r\n systemPromptText: new FormControl({ value: '', disabled: true }),\r\n roleSpecification: new FormControl(''),\r\n targetGroupSpecification: new FormControl(''),\r\n inputSpecification: new FormControl(''),\r\n exampleSpecification: new FormControl(''),\r\n additionalRulesSpecification: new FormControl(''),\r\n });\r\n\r\n ngOnInit(): void {\r\n this._subscriptions.push(\r\n this.systemPromptForm.valueChanges\r\n .pipe(\r\n map((value) => {\r\n let systemPromptText = '';\r\n if (value.roleSpecification) {\r\n systemPromptText += `Role:\\n${value.roleSpecification}\\n\\n`;\r\n }\r\n if (value.targetGroupSpecification) {\r\n systemPromptText += `Target Group:\\n${value.targetGroupSpecification}\\n\\n`;\r\n }\r\n if (value.inputSpecification) {\r\n systemPromptText += `Input:\\n${value.inputSpecification}\\n\\n`;\r\n }\r\n if (value.exampleSpecification) {\r\n systemPromptText += `Example:\\n${value.exampleSpecification}\\n\\n`;\r\n }\r\n if (value.additionalRulesSpecification) {\r\n systemPromptText += `Additional Rules:\\n${value.additionalRulesSpecification}\\n\\n`;\r\n }\r\n this.systemPromptForm.get('systemPromptText')?.setValue(systemPromptText);\r\n }),\r\n )\r\n .subscribe(),\r\n );\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this._subscriptions.forEach((subscription) => subscription.unsubscribe());\r\n }\r\n}\r\n","<sftech-base-dialog [hasHeader]=\"true\" (closed)=\"close()\">\r\n <ng-template #header>\r\n <div class=\"flex justify-between\">\r\n <h2 class=\"text-xl font-semibold\">\r\n Hilfe zur Prompt-Erstellung\r\n </h2>\r\n </div>\r\n </ng-template>\r\n <ng-template #body>\r\n <form [formGroup]=\"systemPromptForm\" [pAutoFocus]=\"true\">\r\n <p-fieldset legend=\"Prompt-Elemente\">\r\n <div class=\"grid grid-cols-2 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full mt-2\">\r\n <textarea id=\"systemPromptText\" formControlName=\"systemPromptText\" pTextarea\r\n class=\"w-full h-full\"\r\n [class.ng-invalid]=\"systemPromptForm.get('systemPromptText')?.dirty && systemPromptForm.get('systemPromptText')?.invalid\"></textarea>\r\n <label for=\"systemPromptText\">Mein Prompt</label>\r\n </p-floatlabel>\r\n <div>\r\n <ng-container [ngTemplateOutlet]=\"textField\"\r\n [ngTemplateOutletContext]=\"{ controlName: 'roleSpecification', popover: roleSpecificationPO, label: 'KI-Rolle' }\"></ng-container>\r\n <ng-container [ngTemplateOutlet]=\"textField\"\r\n [ngTemplateOutletContext]=\"{ controlName: 'targetGroupSpecification', popover: targetGroupSpecificationPO, label: 'Zielgruppe' }\"></ng-container>\r\n <ng-container [ngTemplateOutlet]=\"textField\"\r\n [ngTemplateOutletContext]=\"{ controlName: 'inputSpecification', popover: inputSpecificationPO, label: 'Eingabe' }\"></ng-container>\r\n <ng-container [ngTemplateOutlet]=\"textField\"\r\n [ngTemplateOutletContext]=\"{ controlName: 'exampleSpecification', popover: exampleSpecificationPO, label: 'Eingabe-Beispiel' }\"></ng-container>\r\n <ng-container [ngTemplateOutlet]=\"textField\"\r\n [ngTemplateOutletContext]=\"{ controlName: 'additionalRulesSpecification', popover: additionalRulesSpecificationPO, label: 'Zusätzliche Informationen' }\"></ng-container>\r\n </div>\r\n </div>\r\n\r\n </p-fieldset>\r\n <div class=\"flex justify-end mt-2 w-full\">\r\n <p-button label=\"übernehmen\" type=\"submit\" [disabled]=\"!systemPromptForm.valid\"\r\n (click)=\"ref.close(systemPromptForm.get('systemPromptText')?.value ?? '')\"></p-button>\r\n </div>\r\n\r\n\r\n <ng-template #textField let-controlName=\"controlName\" let-popover=\"popover\" let-label=\"label\">\r\n <label [for]=\"controlName\" class=\"font-bold me-2\">{{ label }}</label>\r\n <fa-icon [icon]=\"iconProvider.help\" class=\"rounded-[50%] bg-primary text-white\" [fixedWidth]=\"true\"\r\n (click)=\"popover.toggle($event)\"></fa-icon>\r\n <textarea rows=\"4\" [id]=\"controlName\" [formControlName]=\"controlName\"\r\n pTextarea class=\"w-full mt-1\"\r\n [class.ng-invalid]=\"systemPromptForm.get(controlName)?.dirty && systemPromptForm.get(controlName)?.invalid\"></textarea>\r\n </ng-template>\r\n\r\n <p-popover #roleSpecificationPO styleClass=\"bg-gray-500\">\r\n <ng-container\r\n *ngTemplateOutlet=\"popoverStyle; context: { po: roleSpecificationPO, controlName: 'roleSpecification', description: 'Die Rolle der KI beschreibt, wie sie sich verhalten soll. Die Rolle hilft der KI, den Kontext zu verstehen und angemessen zu antworten.', example: 'Du bist ein kompetenter, hilfreicher Assistent mit Fachwissen in Technik, Text, Organisation und Problemlösung. Du analysierst präzise, erklärst klar und gibst fundierte, praktische Antworten.' }\"></ng-container>\r\n </p-popover>\r\n\r\n <p-popover #targetGroupSpecificationPO styleClass=\"bg-gray-500\">\r\n <ng-container\r\n *ngTemplateOutlet=\"popoverStyle; context: { po: targetGroupSpecificationPO, controlName: 'targetGroupSpecification', description: 'Die Zielgruppe beschreibt, für wen die KI antworten soll. Sie hilft der KI, den Ton und die Komplexität der Antworten anzupassen.', example: 'Sprich mit einer Person, die in ihrem Fachgebiet erfahren oder zumindest mit den Grundbegriffen vertraut ist. Du darfst Fachsprache verwenden, aber kein unnötiges Theoriewissen voraussetzen.' }\"></ng-container>\r\n </p-popover>\r\n <p-popover #inputSpecificationPO styleClass=\"bg-gray-500\">\r\n <ng-container\r\n *ngTemplateOutlet=\"popoverStyle; context: { po: inputSpecificationPO, controlName: 'inputSpecification', description: 'Die Eingabe beschreibt, wie das vom Anwender eingegebene aussieht. Sie hilft der KI, das vom Anwender übergebene zu verstehen.', example: 'z.B. Du erhältst eine Frage oder ein Problem, das du lösen sollst. Analysiere es gründlich und gib eine klare, präzise Antwort. Mein Input ist ein JSON: {"frage": "Fragen, die du beantworten sollst"}' }\"></ng-container>\r\n </p-popover>\r\n\r\n <p-popover #exampleSpecificationPO styleClass=\"bg-gray-500\">\r\n <ng-container\r\n *ngTemplateOutlet=\"popoverStyle; context: { po: exampleSpecificationPO, controlName: 'exampleSpecification', description: 'Das Eingabe-Beispiel zeigt der KI ein konkretes Beispiel, wie die Anfragen aussehen können. Dies hilft der KI, das erwartete Format besser zu verstehen.', example: 'Beispiel {"frage": "Wie kann ich meine Produktivität steigern?"}' }\"></ng-container>\r\n </p-popover>\r\n\r\n <p-popover #additionalRulesSpecificationPO styleClass=\"bg-gray-500\">\r\n <ng-container\r\n *ngTemplateOutlet=\"popoverStyle; context: { po: additionalRulesSpecificationPO, controlName: 'additionalRulesSpecification', description: 'Zusätzliche Informationen oder Regeln, die die KI bei der Beantwortung beachten soll. Diese können Einschränkungen, spezielle Anforderungen oder wichtige Hinweise enthalten.', example: 'Du darfst keine persönlichen Daten sammeln oder speichern. Deine Antworten müssen respektvoll und professionell sein. Vermeide es, persönliche Meinungen zu äußern.' }\"></ng-container>\r\n </p-popover>\r\n\r\n <ng-template #popoverStyle let-po='po' let-formControlName='controlName' let-description=\"description\"\r\n let-example=\"example\">\r\n <div class=\"p-3 w-200\">\r\n <p><span class=\"font-bold\">Beschreibung:</span></p>\r\n <p>{{ description }}</p>\r\n <p class=\"mt-4\"><span class=\"font-bold\">Beispiel:</span></p>\r\n <p>{{ example }}</p>\r\n <p class=\"mt-2\">\r\n <p-button (onClick)=\"systemPromptForm.get(formControlName)?.setValue(example); po.toggle($event)\">\r\n übernehmen\r\n </p-button>\r\n </p>\r\n </div>\r\n </ng-template>\r\n\r\n </form>\r\n </ng-template>\r\n <ng-template #footer>\r\n\r\n </ng-template>\r\n</sftech-base-dialog>\r\n","import { Component, OnInit, inject, signal } from '@angular/core';\r\nimport { FormControl, FormGroup, ReactiveFormsModule } from '@angular/forms';\r\nimport { FaIconComponent } from '@fortawesome/angular-fontawesome';\r\nimport { BaseDialogComponent, BaseDisplayComponent, MappedApiError } from '@sftech/ng-shared';\r\nimport { AutoFocus } from 'primeng/autofocus';\r\nimport { Button } from 'primeng/button';\r\nimport { Checkbox } from 'primeng/checkbox';\r\nimport { DatePicker } from 'primeng/datepicker';\r\nimport { DialogService } from 'primeng/dynamicdialog';\r\nimport { Fieldset } from 'primeng/fieldset';\r\nimport { FloatLabel } from 'primeng/floatlabel';\r\nimport { InputText } from 'primeng/inputtext';\r\nimport { MultiSelect } from 'primeng/multiselect';\r\nimport { Textarea } from 'primeng/textarea';\r\nimport { ToggleButtonModule } from 'primeng/togglebutton';\r\nimport { IOrchestratorConfig } from '../../../../../core/configuration/orchestrator-config.interface';\r\nimport { ORCHESTRATOR_CONFIGURATION } from '../../../../../core/configuration/orchestrator-configuration.token';\r\nimport { IAgentCreateDto } from '../../../../../core/dtos/agent-create-request.dto';\r\nimport { IAgentResponseDto } from '../../../../../core/dtos/agent-response.dto';\r\nimport { IAgentUpdateDto } from '../../../../../core/dtos/agent-update-request.dto';\r\nimport { Agent } from '../../../../../core/models/agent.model';\r\nimport { McpTool } from '../../../../../core/models/mcp-tool.model';\r\nimport { AgentService } from '../../../../../core/service/agent.service';\r\nimport { OrchestratorService } from '../../../../../core/service/orchestrator.service';\r\nimport { ragPairValidator } from '../../../../../core/validators/rag.validator';\r\nimport { PromptDisplayComponent } from '../../../../prompts/components/prompt/prompt-display/prompt-display.component';\r\nimport { PromptHelperModalComponent } from './prompt-helper-modal/prompt-helper-modal.component';\r\n\r\n@Component({\r\n selector: 'sftech-agent-display',\r\n imports: [ReactiveFormsModule, InputText, AutoFocus, FloatLabel, DatePicker, Textarea, Button, BaseDialogComponent, Fieldset, MultiSelect, ToggleButtonModule, FaIconComponent, Checkbox],\r\n providers: [DialogService],\r\n templateUrl: './agent-display.component.html',\r\n styleUrl: './agent-display.component.css',\r\n})\r\nexport class AgentDisplayComponent extends BaseDisplayComponent<Agent, IAgentUpdateDto, IAgentUpdateDto, IAgentResponseDto> implements OnInit {\r\n protected override _repo = inject(AgentService);\r\n protected override _route = 'agents';\r\n protected _orchestratorService: OrchestratorService = inject(OrchestratorService);\r\n\r\n public tools = signal<McpTool[] | undefined>(undefined);\r\n\r\n protected dialog = inject(DialogService);\r\n\r\n private _options: IOrchestratorConfig = inject(ORCHESTRATOR_CONFIGURATION);\r\n\r\n public override ngOnInit(): void {\r\n super.ngOnInit();\r\n this._orchestratorService.getTools().subscribe((res) => {\r\n if (res instanceof MappedApiError) {\r\n this.tools.set([]);\r\n return;\r\n }\r\n this.tools.set(res.data);\r\n });\r\n }\r\n\r\n protected override initializeForm(): FormGroup {\r\n const form = new FormGroup(\r\n {\r\n id: new FormControl({ value: this.model()!.id, disabled: true }),\r\n createdAt: new FormControl({ value: this.model()!.createdAt, disabled: true }),\r\n identifier: new FormControl({ value: this.model()!.identifier, disabled: true }),\r\n llmUserPrompt: new FormControl({ value: this.model()!.llmUserPrompt, disabled: true }),\r\n llmSystemPrompt: new FormControl({ value: this.model()!.llmSystemPrompt, disabled: true }),\r\n description: new FormControl({ value: this.model()!.description, disabled: !this.canEdit }),\r\n connectorUrl: new FormControl({ value: this.model()!.connectorUrl, disabled: !this.canEdit }),\r\n systemPromptText: new FormControl(''),\r\n answerSpecification: new FormControl({\r\n value: this.model()!.answerSpecification,\r\n disabled: !this.canEdit || !this.model()!.isGeneric,\r\n }),\r\n tools: new FormControl({ value: this.model()!.tools, disabled: !this.canEdit }),\r\n llmProvider: new FormControl({ value: this.model()!.llmProvider, disabled: !this.canEdit }),\r\n llmModel: new FormControl({ value: this.model()!.llmModel, disabled: !this.canEdit }),\r\n llmTemperature: new FormControl({ value: this.model()!.llmTemperature, disabled: !this.canEdit }),\r\n llmTimeout: new FormControl({ value: this.model()!.llmTimeout, disabled: !this.canEdit }),\r\n llmRetries: new FormControl({ value: this.model()!.llmRetries, disabled: !this.canEdit }),\r\n useRag: new FormControl({ value: this.model()!.ragProvider !== null && this.model()!.ragModel !== null, disabled: !this.canEdit }),\r\n ragProvider: new FormControl({ value: this.model()!.ragProvider, disabled: !this.canEdit }),\r\n ragModel: new FormControl({ value: this.model()!.ragModel, disabled: !this.canEdit }),\r\n name: new FormControl(this.model()?.name),\r\n },\r\n {\r\n validators: [ragPairValidator()],\r\n },\r\n );\r\n form.get('useRag')?.valueChanges.subscribe((useRag: boolean | null) => {\r\n if (useRag) {\r\n const ragProviderControl = this.form.get('ragProvider');\r\n const ragModelControl = this.form.get('ragModel');\r\n\r\n // Only set default values if fields are currently empty\r\n if (!ragProviderControl?.value) {\r\n ragProviderControl?.setValue(this._options.defaultRagProvider);\r\n }\r\n if (!ragModelControl?.value) {\r\n ragModelControl?.setValue(this._options.defaultRagModel);\r\n }\r\n }\r\n });\r\n return form;\r\n }\r\n\r\n protected override getNewModel(): Agent {\r\n const agent = new Agent();\r\n agent.connectorUrl = this._options.defaultConnectorUrl;\r\n agent.isGeneric = true;\r\n agent.answerSpecification = this._options.defaultAnswerSpecification;\r\n agent.llmProvider = this._options.defaultLlmProvider;\r\n agent.llmModel = this._options.defaultLlmModel;\r\n agent.llmTemperature = this._options.defaultLlmTemperature;\r\n agent.llmTimeout = this._options.defaultLlmTimeout;\r\n agent.llmRetries = this._options.defaultLlmRetries;\r\n return agent;\r\n }\r\n\r\n protected override mapFormToUpdateDto(): IAgentUpdateDto {\r\n return {\r\n description: this.form.get('description')?.value,\r\n connectorUrl: this.form.get('connectorUrl')?.value,\r\n tools: this.form.get('tools')?.value,\r\n answerSpecification: this.form.get('answerSpecification')?.value,\r\n llmProvider: this.form.get('llmProvider')?.value,\r\n llmModel: this.form.get('llmModel')?.value,\r\n llmTemperature: +this.form.get('llmTemperature')?.value,\r\n llmTimeout: this.form.get('llmTimeout')?.value,\r\n llmRetries: this.form.get('llmRetries')?.value,\r\n ragModel: this.form.get('ragModel')?.value,\r\n ragProvider: this.form.get('ragProvider')?.value,\r\n name: this.form.get('name')?.value,\r\n };\r\n }\r\n\r\n protected override mapFormToCreateDto(): IAgentCreateDto {\r\n return {\r\n description: this.form.get('description')?.value,\r\n connectorUrl: this.form.get('connectorUrl')?.value,\r\n systemPromptText: this.form.get('systemPromptText')?.value,\r\n answerSpecification: this.form.get('answerSpecification')?.value,\r\n tools: this.form.get('tools')?.value,\r\n llmProvider: this.form.get('llmProvider')?.value,\r\n llmModel: this.form.get('llmModel')?.value,\r\n llmTemperature: +this.form.get('llmTemperature')?.value,\r\n llmTimeout: this.form.get('llmTimeout')?.value,\r\n llmRetries: this.form.get('llmRetries')?.value,\r\n ragModel: this.form.get('ragModel')?.value,\r\n ragProvider: this.form.get('ragProvider')?.value,\r\n name: this.form.get('name')?.value,\r\n };\r\n }\r\n\r\n public openPromptModal(promptId: number | undefined): void {\r\n if (!promptId) {\r\n return;\r\n }\r\n this.dialog.open(PromptDisplayComponent, {\r\n inputValues: { id: promptId, canEdit: true, openedAsModal: true },\r\n focusOnShow: false,\r\n modal: true,\r\n dismissableMask: true,\r\n width: '40%',\r\n contentStyle: { overflow: 'auto' },\r\n });\r\n }\r\n\r\n public openPromptHelper() {\r\n const modalRef = this.dialog.open(PromptHelperModalComponent, {\r\n modal: true,\r\n dismissableMask: true,\r\n width: '60%',\r\n contentStyle: { overflow: 'auto' },\r\n });\r\n modalRef?.onClose.subscribe((result: string | undefined) => {\r\n if (!result) {\r\n return;\r\n }\r\n this.form.get('systemPromptText')?.setValue(result);\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 @if (model()) {\r\n <form [formGroup]=\"form\" [pAutoFocus]=\"true\">\r\n <p-fieldset legend=\"Stammdaten\" class=\"bg-primary-50!\">\r\n @if (!isNew()) {\r\n\r\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"id\" formControlName=\"id\" pInputText class=\"w-full\"/>\r\n <label for=\"id\">{{ this.model()!.getUiNameForProperty('id') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"identifier\" formControlName=\"identifier\" pInputText\r\n class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('identifier')?.dirty && form.get('identifier')?.invalid\"/>\r\n <label for=\"identifier\">{{ this.model()!.getUiNameForProperty('identifier') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <p-datePicker id=\"createdAt\" formControlName=\"createdAt\" dateFormat=\"dd.mm.yy\"\r\n [showTime]=\"true\"\r\n [hourFormat]=\"'24'\" [style]=\"{'width': '100%'}\"\r\n [class.ng-invalid]=\"form.get('createdAt')?.dirty && form.get('createdAt')?.invalid\"></p-datePicker>\r\n <label for=\"createdAt\">{{ this.model()!.getUiNameForProperty('createdAt') }}</label>\r\n </p-floatlabel>\r\n </div>\r\n }\r\n\r\n <p-floatlabel variant=\"in\" class=\"w-full mt-2\">\r\n <input type=\"text\" id=\"name\" formControlName=\"name\" pTextarea class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('name')?.dirty && form.get('name')?.invalid\"/>\r\n <label for=\"name\">{{ this.model()!.getUiNameForProperty('name') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full mt-2\">\r\n <textarea rows=\"2\" id=\"description\" formControlName=\"description\" pTextarea class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('description')?.dirty && form.get('description')?.invalid\"></textarea>\r\n <label for=\"description\">{{ this.model()!.getUiNameForProperty('description') }}</label>\r\n </p-floatlabel>\r\n </p-fieldset>\r\n <hr class=\"my-10 text-primary-50\"/>\r\n <p-fieldset legend=\"Prompts\">\r\n @if (!isNew()) {\r\n <div class=\"grid grid-cols-1 sm:grid-cols-2 mb-2 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"llmUserPrompt\"\r\n (click)=\"openPromptModal(model()!.llmUserPromptId)\"\r\n [value]=\"model()!.llmUserPrompt?.identifier\" pInputText\r\n class=\"w-full cursor-pointer\"/>\r\n <label for=\"llmUserPrompt\">{{ this.model()!.getUiNameForProperty('llmUserPrompt') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"llmSystemPrompt\"\r\n (click)=\"openPromptModal(model()!.llmSystemPromptId)\"\r\n [value]=\"model()!.llmSystemPrompt?.identifier\" pInputText\r\n class=\"w-full cursor-pointer\"/>\r\n <label for=\"llmSystemPrompt\">{{ this.model()!.getUiNameForProperty('llmSystemPrompt') }}</label>\r\n </p-floatlabel>\r\n </div>\r\n } @else {\r\n <span class=\"me-2\">Ich möchte Unterstützung bei der Prompt-Erstellung</span>\r\n <p-button [rounded]=\"true\" (onClick)=\"openPromptHelper()\">\r\n <fa-icon [icon]=\"iconProvider.help\" [fixedWidth]=\"true\"></fa-icon>\r\n </p-button>\r\n <p-floatlabel variant=\"in\" class=\"w-full mb-2\">\r\n <textarea rows=\"10\" id=\"systemPromptText\" formControlName=\"systemPromptText\" pTextarea\r\n class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('systemPromptText')?.dirty && form.get('systemPromptText')?.invalid\"></textarea>\r\n <label for=\"systemPromptText\">{{ this.model()!.getUiNameForProperty('systemPromptText') }}</label>\r\n </p-floatlabel>\r\n }\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <textarea rows=\"5\" id=\"answerSpecification\" formControlName=\"answerSpecification\" pTextarea\r\n class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('answerSpecification')?.dirty && form.get('answerSpecification')?.invalid\"></textarea>\r\n <label for=\"answerSpecification\">{{ this.model()!.getUiNameForProperty('answerSpecification') }}</label>\r\n </p-floatlabel>\r\n </p-fieldset>\r\n <hr class=\"my-10 text-primary-50\"/>\r\n <p-fieldset legend=\"LLM-Tools\">\r\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mb-2 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <p-multiselect id=\"tools\" [options]=\"tools()\" [loading]=\"!tools()\"\r\n appendTo=\"body\"\r\n formControlName=\"tools\"\r\n optionLabel=\"name\"\r\n optionValue=\"identifier\" styleClass=\"w-full md:w-80\" display=\"chip\">\r\n <ng-template let-tool #item>\r\n <div class=\"flex items-center gap-2\">\r\n <div>{{ tool.name }}</div>\r\n </div>\r\n </ng-template>\r\n <ng-template #dropdownicon>\r\n <i class=\"pi pi-map\"></i>\r\n </ng-template>\r\n <ng-template #header>\r\n <div class=\"font-medium px-3 py-2\">Verfügbare Tools</div>\r\n </ng-template>\r\n </p-multiselect>\r\n <label for=\"tools\">Tools</label>\r\n </p-floatlabel>\r\n </div>\r\n </p-fieldset>\r\n <hr class=\"my-10 text-primary-50\"/>\r\n\r\n <p-fieldset legend=\"LLM-RAG\" [toggleable]=\"true\">\r\n <div class=\"mb-4\">\r\n <p-checkbox id=\"useRag\" formControlName=\"useRag\" [binary]=\"true\" class=\"me-2\" />\r\n <label for=\"useRag\">Soll das LLM mit eigenen Dokumenten angereichert werden (RAG)?</label>\r\n </div>\r\n @if (this.form.get('useRag')!.value) {\r\n <div class=\"grid grid-cols-1 sm:grid-cols-2 mb-2 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"ragProvider\"\r\n formControlName=\"ragProvider\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('ragProvider')?.dirty && form.get('ragProvider')?.invalid\"/>\r\n <label for=\"ragProvider\">{{ this.model()!.getUiNameForProperty('ragProvider') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"ragModel\"\r\n formControlName=\"ragModel\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('ragModel')?.dirty && form.get('ragModel')?.invalid\"/>\r\n <label for=\"ragModel\">{{ this.model()!.getUiNameForProperty('ragModel') }}</label>\r\n </p-floatlabel>\r\n </div>\r\n }\r\n </p-fieldset>\r\n <hr class=\"my-10 text-primary-50\"/>\r\n\r\n <p-fieldset legend=\"LLM-Konfiguration\" [toggleable]=\"true\" [collapsed]=\"true\">\r\n <div class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 mb-2 gap-2\">\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"connectorUrl\"\r\n formControlName=\"connectorUrl\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('connectorUrl')?.dirty && form.get('connectorUrl')?.invalid\"/>\r\n <label for=\"connectorUrl\">{{ this.model()!.getUiNameForProperty('connectorUrl') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"llmProvider\"\r\n formControlName=\"llmProvider\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('llmProvider')?.dirty && form.get('llmProvider')?.invalid\"/>\r\n <label for=\"llmProvider\">{{ this.model()!.getUiNameForProperty('llmProvider') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"text\" id=\"llmModel\"\r\n formControlName=\"llmModel\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('llmModel')?.dirty && form.get('llmModel')?.invalid\"/>\r\n <label for=\"llmModel\">{{ this.model()!.getUiNameForProperty('llmModel') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"number\" id=\"llmTemperature\"\r\n formControlName=\"llmTemperature\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('llmTemperature')?.dirty && form.get('llmTemperature')?.invalid\"/>\r\n <label for=\"llmTemperature\">{{ this.model()!.getUiNameForProperty('llmTemperature') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"number\" id=\"llmTimeout\"\r\n formControlName=\"llmTimeout\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('llmTimeout')?.dirty && form.get('llmTimeout')?.invalid\"/>\r\n <label for=\"llmTimeout\">{{ this.model()!.getUiNameForProperty('llmTimeout') }}</label>\r\n </p-floatlabel>\r\n <p-floatlabel variant=\"in\" class=\"w-full\">\r\n <input type=\"number\" id=\"llmRetries\"\r\n formControlName=\"llmRetries\" pInputText class=\"w-full\"\r\n [class.ng-invalid]=\"form.get('llmRetries')?.dirty && form.get('llmRetries')?.invalid\"/>\r\n <label for=\"llmRetries\">{{ this.model()!.getUiNameForProperty('llmRetries') }}</label>\r\n </p-floatlabel>\r\n </div>\r\n </p-fieldset>\r\n\r\n\r\n </form>\r\n }\r\n </div>\r\n </ng-template>\r\n <ng-template #footer>\r\n <div class=\"flex justify-end mt-2\">\r\n <p-button label=\"Speichern\" (onClick)=\"submitForm()\" (keyup.enter)=\"submitForm()\"\r\n [disabled]=\"!form || !form.dirty\"></p-button>\r\n </div>\r\n </ng-template>\r\n\r\n\r\n</sftech-base-dialog>\r\n","import { Component, inject } from '@angular/core';\r\nimport { FaIconComponent } from '@fortawesome/angular-fontawesome';\r\nimport { BaseListComponent, IconProvider, PaginatorComponent } from '@sftech/ng-shared';\r\nimport { Button } from 'primeng/button';\r\nimport { DialogService } from 'primeng/dynamicdialog';\r\nimport { Panel } from 'primeng/panel';\r\nimport { TableModule } from 'primeng/table';\r\nimport { Tooltip } from 'primeng/tooltip';\r\nimport { IAgentResponseDto } from '../../../../../core/dtos/agent-response.dto';\r\nimport { IAgentUpdateDto } from '../../../../../core/dtos/agent-update-request.dto';\r\nimport { Agent } from '../../../../../core/models/agent.model';\r\nimport { AgentService } from '../../../../../core/service/agent.service';\r\nimport { AgentDisplayComponent } from '../agent-display/agent-display.component';\r\nimport { AgentRagUploadComponent } from '../agent-rag-upload/agent-rag-upload.component';\r\n\r\n@Component({\r\n selector: 'sftech-agents-list',\r\n imports: [PaginatorComponent, Panel, TableModule, Button, FaIconComponent, Tooltip],\r\n providers: [DialogService],\r\n templateUrl: './agents-list.component.html',\r\n styleUrl: './agents-list.component.css',\r\n})\r\nexport class AgentsListComponent extends BaseListComponent<Agent, IAgentUpdateDto, IAgentUpdateDto, IAgentResponseDto> {\r\n protected _repo = inject(AgentService);\r\n protected _route = 'agents';\r\n protected override _modalComponent = AgentDisplayComponent;\r\n protected override detailModalHeaderText = 'Agent-Details';\r\n\r\n private dialogService = inject(DialogService);\r\n\r\n public iconProvider = IconProvider;\r\n\r\n constructor() {\r\n super();\r\n }\r\n\r\n public openRagUploadModal(agentId: number, event: Event) {\r\n event.stopPropagation();\r\n this.dialogService.open(AgentRagUploadComponent, {\r\n inputValues: { agentId },\r\n focusOnShow: false,\r\n modal: true,\r\n dismissableMask: true,\r\n header: 'RAG-Dokumente hochladen',\r\n width: '50%',\r\n contentStyle: { overflow: 'auto' },\r\n });\r\n }\r\n}\r\n","<div class=\"h-full overflow-y-auto px-2 sm:px-4\">\r\n <h1 class=\"text-primary-900 font-bold text-lg sm:text-xl p-2 my-4\">Agent-Übersicht</h1>\r\n\r\n @if (!data()) {\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 === 0) {\r\n <p-panel [toggleable]=\"false\">\r\n <p class=\"m-0\">\r\n Es sind keine Agenten vorhanden.\r\n </p>\r\n </p-panel>\r\n } @else if (data()!.length > 0) {\r\n <div class=\"overflow-x-auto -mx-2 sm:mx-0\">\r\n <p-table [value]=\"data()!\"\r\n stripedRows\r\n [tableStyle]=\"{ 'min-width': '50rem' }\"\r\n selectionMode=\"single\"\r\n [resizableColumns]=\"true\"\r\n dataKey=\"id\"\r\n >\r\n <ng-template #header>\r\n <tr>\r\n @for(column of data()![0].propertiesToShow; track column) {\r\n <th>{{ data()![0].getUiNameForProperty(column) }}</th>\r\n }\r\n <th style=\"width: 80px\">Aktionen</th>\r\n </tr>\r\n </ng-template>\r\n <ng-template #body let-agent>\r\n <tr (click)=\"openDisplay(agent.id)\" [pSelectableRow]=\"agent\" class=\"cursor-pointer\">\r\n @for(column of data()![0].propertiesToShow; track column) {\r\n <td style=\"white-space: pre-wrap\">\r\n {{ agent.getPropertyValue(column) }}\r\n </td>\r\n }\r\n <td>\r\n @if (agent.ragProvider && agent.ragModel) {\r\n <p-button\r\n (onClick)=\"openRagUploadModal(agent.id, $event)\"\r\n [pTooltip]=\"'RAG-Dokumente hochladen'\"\r\n tooltipPosition=\"left\">\r\n <fa-icon [icon]=\"iconProvider.documentAdd\"></fa-icon>\r\n </p-button>\r\n }\r\n </td>\r\n </tr>\r\n </ng-template>\r\n </p-table>\r\n </div>\r\n <sftech-paginator [pagination]=\"odata().pagination\" (odataChanged)=\"updatePagination($event)\"></sftech-paginator>\r\n <div class=\"flex justify-end p-2\">\r\n <p-button (onClick)=\"openDisplay(undefined)\">\r\n <fa-icon [icon]=\"iconProvider.add\" class=\"sm:mr-2\"></fa-icon>\r\n <span class=\"hidden sm:inline\">Neuer Agent</span>\r\n </p-button>\r\n </div>\r\n }\r\n</div>\r\n\r\n","import { AgentsComponent } from './agents.component';\r\nimport { AgentsListComponent } from './components/agent/agents-list/agents-list.component';\r\n\r\nexport const agentsRoutes = [\r\n {\r\n path: '',\r\n component: AgentsComponent,\r\n children: [\r\n {\r\n path: '',\r\n component: AgentsListComponent,\r\n },\r\n ],\r\n },\r\n];\r\n"],"names":["i1"],"mappings":"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"}
|
|
@@ -10,8 +10,8 @@ import { ButtonDirective } from 'primeng/button';
|
|
|
10
10
|
import { DialogService } from 'primeng/dynamicdialog';
|
|
11
11
|
import { Tooltip } from 'primeng/tooltip';
|
|
12
12
|
import { map, catchError } from 'rxjs';
|
|
13
|
-
import { A as AgentService, a as AgentRagUploadComponent } from './sftech-ng-orchestrator-agent-rag-upload.component-
|
|
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-
|
|
13
|
+
import { A as AgentService, a as AgentRagUploadComponent } from './sftech-ng-orchestrator-agent-rag-upload.component-DRmF3l76.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-CzwZe61l.mjs';
|
|
15
15
|
import * as i1 from '@angular/common/http';
|
|
16
16
|
import { faNoteSticky, faCog, faCheck, faXmark, faSpinner, faClipboardCheck, faCircleQuestion, faBrain, faUser, faNetworkWired } from '@fortawesome/free-solid-svg-icons';
|
|
17
17
|
import * as i1$1 from '@angular/forms';
|
|
@@ -214,7 +214,7 @@ class AgentChatMessageHumanInputInitialComponent {
|
|
|
214
214
|
run() {
|
|
215
215
|
if (this.form.invalid || this.isSubmitting) {
|
|
216
216
|
// Mark all fields as touched to show validation errors
|
|
217
|
-
Object.keys(this.form.controls).forEach(key => {
|
|
217
|
+
Object.keys(this.form.controls).forEach((key) => {
|
|
218
218
|
this.form.get(key)?.markAsTouched();
|
|
219
219
|
});
|
|
220
220
|
return;
|
|
@@ -231,7 +231,7 @@ class AgentChatMessageHumanInputInitialComponent {
|
|
|
231
231
|
this.messageService.add({
|
|
232
232
|
severity: 'error',
|
|
233
233
|
summary: 'Fehler',
|
|
234
|
-
detail: res.messages.join(' | ')
|
|
234
|
+
detail: res.messages.join(' | '),
|
|
235
235
|
});
|
|
236
236
|
this.isSubmitting = false;
|
|
237
237
|
return;
|
|
@@ -241,7 +241,7 @@ class AgentChatMessageHumanInputInitialComponent {
|
|
|
241
241
|
},
|
|
242
242
|
error: () => {
|
|
243
243
|
this.isSubmitting = false;
|
|
244
|
-
}
|
|
244
|
+
},
|
|
245
245
|
});
|
|
246
246
|
}
|
|
247
247
|
getInputFormControlNames() {
|
|
@@ -254,7 +254,7 @@ class AgentChatMessageHumanInputInitialComponent {
|
|
|
254
254
|
.replace(/_/g, ' ')
|
|
255
255
|
.trim()
|
|
256
256
|
.split(' ')
|
|
257
|
-
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
257
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
258
258
|
.join(' ');
|
|
259
259
|
}
|
|
260
260
|
getFormattedTemplate() {
|
|
@@ -311,7 +311,7 @@ class AgentChatMessageHumanInputComponent {
|
|
|
311
311
|
error: () => {
|
|
312
312
|
this.form.get('message')?.enable();
|
|
313
313
|
this.isSubmitting = false;
|
|
314
|
-
}
|
|
314
|
+
},
|
|
315
315
|
});
|
|
316
316
|
}
|
|
317
317
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentChatMessageHumanInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
@@ -620,11 +620,11 @@ class AgentChatComponent {
|
|
|
620
620
|
return agentRun.chat.messages.filter((msg) => msg.messageType === 'human' || msg.messageType === 'user' || msg.messageType === 'ai').length;
|
|
621
621
|
}
|
|
622
622
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentChatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
623
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", 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-3 sm:px-4 py-3 flex items-center bg-white gap-2\">\r\n <!-- Mobile Sidebar Toggle -->\r\n <div class=\"relative lg:hidden flex-shrink-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"toggleSidebar()\"\r\n [pTooltip]=\"'Chat-Verlauf (' + (agentRuns()?.length ?? 0) + ')'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (agentRuns()?.length) {\r\n <span class=\"absolute -top-1 -right-1 bg-primary-500 text-white text-xs font-bold rounded-full min-w-5 h-5 flex items-center justify-center px-1 pointer-events-none\">\r\n {{ agentRuns()!.length }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-1 min-w-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded flex-shrink-0\"\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-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n <span class=\"hidden md:inline text-gray-500 font-normal\">\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - HH:mm') }}\r\n </span>\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-shrink-0\">\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=\"sm:mr-2\"></fa-icon>\r\n <span class=\"hidden sm:inline\">Neuer Chat</span>\r\n </button>\r\n\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 relative\">\r\n <!-- Mobile Overlay -->\r\n @if (sidebarVisible()) {\r\n <div class=\"fixed inset-0 bg-black/50 z-40 lg:hidden\"\r\n (click)=\"closeSidebar()\"></div>\r\n }\r\n\r\n <!-- Sidebar -->\r\n <div class=\"chats-panel border-r border-gray-200 bg-gradient-to-b from-gray-50 to-white p-3 h-full flex-shrink-0 overflow-y-auto\r\n fixed lg:relative inset-y-0 left-0 z-50 lg:z-auto\r\n w-[280px] sm:w-[300px] lg:w-[220px]\r\n transform transition-transform duration-300 ease-in-out\r\n lg:transform-none\"\r\n [class.-translate-x-full]=\"!sidebarVisible()\"\r\n [class.translate-x-0]=\"sidebarVisible()\"\r\n [class.lg:translate-x-0]=\"true\">\r\n\r\n <!-- Mobile Close Button -->\r\n <div class=\"flex items-center justify-between mb-3 lg:hidden\">\r\n <h3 class=\"text-sm font-semibold text-gray-700\">Chat-Verlauf</h3>\r\n <button class=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\r\n (click)=\"closeSidebar()\">\r\n <fa-icon [icon]=\"iconProvider.close\" class=\"text-gray-500\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3 hidden lg:block\">\r\n <h3 class=\"text-xs font-semibold text-gray-500 uppercase tracking-wider px-2\">Chat Verlauf</h3>\r\n </div>\r\n @if (agentRuns() === undefined) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.loading\" [animation]=\"'spin'\" size=\"2x\" class=\"text-gray-400 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Chats werden geladen...</p>\r\n </div>\r\n </div>\r\n } @else if (!agentRuns()?.length) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"2x\" class=\"text-gray-300 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Noch keine Chats</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-2\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"chat-item group relative rounded-xl p-3 cursor-pointer transition-all duration-200 border active:scale-[0.98]\"\r\n (click)=\"selectAgentRun(agentRun); closeSidebar()\"\r\n [class.active]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.bg-white]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.shadow-sm]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.hover:shadow-md]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.border-gray-200]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.bg-primary-50]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-primary-300]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.shadow-md]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"flex items-start justify-between mb-2\">\r\n <div class=\"flex items-center gap-2 flex-1 min-w-0\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(agentRun.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(agentRun.status)\"\r\n [animation]=\"agentRun.status === 'running' ? 'spin' : undefined\"\r\n class=\"flex-shrink-0\"\r\n size=\"sm\"></fa-icon>\r\n <span class=\"text-xs font-medium truncate\"\r\n [class.text-primary-700]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-700]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'dd.MM.YY' }}\r\n </span>\r\n </div>\r\n <span class=\"text-xs font-medium flex-shrink-0 ml-2\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'HH:mm' }}\r\n </span>\r\n </div>\r\n @if (agentRun.chat && agentRun.chat.messages && agentRun.chat.messages.length > 0) {\r\n <div class=\"text-xs truncate leading-relaxed\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-600]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getFirstUserMessage(agentRun) }}\r\n </div>\r\n } @else {\r\n <div class=\"text-xs italic truncate\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n Neuer Chat\r\n </div>\r\n }\r\n @if (agentRun.chat && agentRun.chat.messages) {\r\n <div class=\"flex items-center gap-2 mt-2 pt-2 border-t\"\r\n [class.border-primary-200]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-gray-100]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n <fa-icon [icon]=\"iconProvider.message\" size=\"xs\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\"></fa-icon>\r\n <span class=\"text-xs\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getMessageCount(agentRun) }} Nachrichten\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Chat Area -->\r\n <div class=\"chat bg-gray-50 flex-1 relative min-w-0\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full p-4\">\r\n <p class=\"m-0 text-gray-500 text-center\">\r\n <span class=\"hidden lg:inline\">Bitte einen Chat aus der linken Liste ausw\u00E4hlen</span>\r\n <span class=\"lg:hidden\">Tippe auf das Men\u00FC-Icon um einen Chat auszuw\u00E4hlen</span>\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-2 sm: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: [":host{display:block;height:100%;overflow:hidden}.chat-item{transform:translate(0);transition:all .2s ease-in-out}.chat-item:hover{transform:translate(2px)}.chat-item.active{border-left-width:3px}\n"], dependencies: [{ kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: AgentChatMessageComponent, selector: "sftech-agent-chat-message", inputs: ["message", "type"] }, { 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"] }, { 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", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
|
|
623
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.9", 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-3 sm:px-4 py-3 flex items-center bg-white gap-2\">\r\n <!-- Mobile Sidebar Toggle -->\r\n <div class=\"relative lg:hidden flex-shrink-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"toggleSidebar()\"\r\n [pTooltip]=\"'Chat-Verlauf (' + (agentRuns()?.length ?? 0) + ')'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (agentRuns()?.length) {\r\n <span class=\"absolute -top-1 -right-1 bg-primary-500 text-white text-xs font-bold rounded-full min-w-5 h-5 flex items-center justify-center px-1 pointer-events-none\">\r\n {{ agentRuns()!.length }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-1 min-w-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded flex-shrink-0\"\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-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n <span class=\"hidden md:inline text-gray-500 font-normal\">\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - HH:mm') }}\r\n </span>\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-shrink-0\">\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=\"sm:mr-2\"></fa-icon>\r\n <span class=\"hidden sm:inline\">Neuer Chat</span>\r\n </button>\r\n\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 relative\">\r\n <!-- Mobile Overlay -->\r\n @if (sidebarVisible()) {\r\n <div class=\"fixed inset-0 bg-black/50 z-40 lg:hidden\"\r\n (click)=\"closeSidebar()\"></div>\r\n }\r\n\r\n <!-- Sidebar -->\r\n <div class=\"chats-panel border-r border-gray-200 bg-gradient-to-b from-gray-50 to-white p-3 h-full flex-shrink-0 overflow-y-auto\r\n fixed lg:relative inset-y-0 left-0 z-50 lg:z-auto\r\n w-[280px] sm:w-[300px] lg:w-[220px]\r\n transform transition-transform duration-300 ease-in-out\r\n lg:transform-none\"\r\n [class.-translate-x-full]=\"!sidebarVisible()\"\r\n [class.translate-x-0]=\"sidebarVisible()\"\r\n [class.lg:translate-x-0]=\"true\">\r\n\r\n <!-- Mobile Close Button -->\r\n <div class=\"flex items-center justify-between mb-3 lg:hidden\">\r\n <h3 class=\"text-sm font-semibold text-gray-700\">Chat-Verlauf</h3>\r\n <button class=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\r\n (click)=\"closeSidebar()\">\r\n <fa-icon [icon]=\"iconProvider.close\" class=\"text-gray-500\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3 hidden lg:block\">\r\n <h3 class=\"text-xs font-semibold text-gray-500 uppercase tracking-wider px-2\">Chat Verlauf</h3>\r\n </div>\r\n @if (agentRuns() === undefined) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.loading\" [animation]=\"'spin'\" size=\"2x\" class=\"text-gray-400 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Chats werden geladen...</p>\r\n </div>\r\n </div>\r\n } @else if (!agentRuns()?.length) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"2x\" class=\"text-gray-300 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Noch keine Chats</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-2\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"chat-item group relative rounded-xl p-3 cursor-pointer transition-all duration-200 border active:scale-[0.98]\"\r\n (click)=\"selectAgentRun(agentRun); closeSidebar()\"\r\n [class.active]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.bg-white]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.shadow-sm]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.hover:shadow-md]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.border-gray-200]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.bg-primary-50]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-primary-300]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.shadow-md]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"flex items-start justify-between mb-2\">\r\n <div class=\"flex items-center gap-2 flex-1 min-w-0\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(agentRun.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(agentRun.status)\"\r\n [animation]=\"agentRun.status === 'running' ? 'spin' : undefined\"\r\n class=\"flex-shrink-0\"\r\n size=\"sm\"></fa-icon>\r\n <span class=\"text-xs font-medium truncate\"\r\n [class.text-primary-700]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-700]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'dd.MM.yy' }}\r\n </span>\r\n </div>\r\n <span class=\"text-xs font-medium flex-shrink-0 ml-2\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'HH:mm' }}\r\n </span>\r\n </div>\r\n @if (agentRun.chat && agentRun.chat.messages && agentRun.chat.messages.length > 0) {\r\n <div class=\"text-xs truncate leading-relaxed\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-600]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getFirstUserMessage(agentRun) }}\r\n </div>\r\n } @else {\r\n <div class=\"text-xs italic truncate\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n Neuer Chat\r\n </div>\r\n }\r\n @if (agentRun.chat && agentRun.chat.messages) {\r\n <div class=\"flex items-center gap-2 mt-2 pt-2 border-t\"\r\n [class.border-primary-200]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-gray-100]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n <fa-icon [icon]=\"iconProvider.message\" size=\"xs\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\"></fa-icon>\r\n <span class=\"text-xs\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getMessageCount(agentRun) }} Nachrichten\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Chat Area -->\r\n <div class=\"chat bg-gray-50 flex-1 relative min-w-0\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full p-4\">\r\n <p class=\"m-0 text-gray-500 text-center\">\r\n <span class=\"hidden lg:inline\">Bitte einen Chat aus der linken Liste ausw\u00E4hlen</span>\r\n <span class=\"lg:hidden\">Tippe auf das Men\u00FC-Icon um einen Chat auszuw\u00E4hlen</span>\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-2 sm: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: [":host{display:block;height:100%;overflow:hidden}.chat-item{transform:translate(0);transition:all .2s ease-in-out}.chat-item:hover{transform:translate(2px)}.chat-item.active{border-left-width:3px}\n"], dependencies: [{ kind: "directive", type: ButtonDirective, selector: "[pButton]", inputs: ["ptButtonDirective", "hostName", "text", "plain", "raised", "size", "outlined", "rounded", "iconPos", "loadingIcon", "fluid", "label", "icon", "loading", "buttonProps", "severity"] }, { kind: "component", type: AgentChatMessageComponent, selector: "sftech-agent-chat-message", inputs: ["message", "type"] }, { 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"] }, { 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", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions", "appendTo", "ptTooltip"] }, { kind: "pipe", type: DatePipe, name: "date" }] });
|
|
624
624
|
}
|
|
625
625
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.9", ngImport: i0, type: AgentChatComponent, decorators: [{
|
|
626
626
|
type: Component,
|
|
627
|
-
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-3 sm:px-4 py-3 flex items-center bg-white gap-2\">\r\n <!-- Mobile Sidebar Toggle -->\r\n <div class=\"relative lg:hidden flex-shrink-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"toggleSidebar()\"\r\n [pTooltip]=\"'Chat-Verlauf (' + (agentRuns()?.length ?? 0) + ')'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (agentRuns()?.length) {\r\n <span class=\"absolute -top-1 -right-1 bg-primary-500 text-white text-xs font-bold rounded-full min-w-5 h-5 flex items-center justify-center px-1 pointer-events-none\">\r\n {{ agentRuns()!.length }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-1 min-w-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded flex-shrink-0\"\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-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n <span class=\"hidden md:inline text-gray-500 font-normal\">\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - HH:mm') }}\r\n </span>\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-shrink-0\">\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=\"sm:mr-2\"></fa-icon>\r\n <span class=\"hidden sm:inline\">Neuer Chat</span>\r\n </button>\r\n\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 relative\">\r\n <!-- Mobile Overlay -->\r\n @if (sidebarVisible()) {\r\n <div class=\"fixed inset-0 bg-black/50 z-40 lg:hidden\"\r\n (click)=\"closeSidebar()\"></div>\r\n }\r\n\r\n <!-- Sidebar -->\r\n <div class=\"chats-panel border-r border-gray-200 bg-gradient-to-b from-gray-50 to-white p-3 h-full flex-shrink-0 overflow-y-auto\r\n fixed lg:relative inset-y-0 left-0 z-50 lg:z-auto\r\n w-[280px] sm:w-[300px] lg:w-[220px]\r\n transform transition-transform duration-300 ease-in-out\r\n lg:transform-none\"\r\n [class.-translate-x-full]=\"!sidebarVisible()\"\r\n [class.translate-x-0]=\"sidebarVisible()\"\r\n [class.lg:translate-x-0]=\"true\">\r\n\r\n <!-- Mobile Close Button -->\r\n <div class=\"flex items-center justify-between mb-3 lg:hidden\">\r\n <h3 class=\"text-sm font-semibold text-gray-700\">Chat-Verlauf</h3>\r\n <button class=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\r\n (click)=\"closeSidebar()\">\r\n <fa-icon [icon]=\"iconProvider.close\" class=\"text-gray-500\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3 hidden lg:block\">\r\n <h3 class=\"text-xs font-semibold text-gray-500 uppercase tracking-wider px-2\">Chat Verlauf</h3>\r\n </div>\r\n @if (agentRuns() === undefined) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.loading\" [animation]=\"'spin'\" size=\"2x\" class=\"text-gray-400 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Chats werden geladen...</p>\r\n </div>\r\n </div>\r\n } @else if (!agentRuns()?.length) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"2x\" class=\"text-gray-300 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Noch keine Chats</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-2\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"chat-item group relative rounded-xl p-3 cursor-pointer transition-all duration-200 border active:scale-[0.98]\"\r\n (click)=\"selectAgentRun(agentRun); closeSidebar()\"\r\n [class.active]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.bg-white]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.shadow-sm]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.hover:shadow-md]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.border-gray-200]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.bg-primary-50]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-primary-300]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.shadow-md]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"flex items-start justify-between mb-2\">\r\n <div class=\"flex items-center gap-2 flex-1 min-w-0\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(agentRun.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(agentRun.status)\"\r\n [animation]=\"agentRun.status === 'running' ? 'spin' : undefined\"\r\n class=\"flex-shrink-0\"\r\n size=\"sm\"></fa-icon>\r\n <span class=\"text-xs font-medium truncate\"\r\n [class.text-primary-700]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-700]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'dd.MM.YY' }}\r\n </span>\r\n </div>\r\n <span class=\"text-xs font-medium flex-shrink-0 ml-2\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'HH:mm' }}\r\n </span>\r\n </div>\r\n @if (agentRun.chat && agentRun.chat.messages && agentRun.chat.messages.length > 0) {\r\n <div class=\"text-xs truncate leading-relaxed\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-600]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getFirstUserMessage(agentRun) }}\r\n </div>\r\n } @else {\r\n <div class=\"text-xs italic truncate\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n Neuer Chat\r\n </div>\r\n }\r\n @if (agentRun.chat && agentRun.chat.messages) {\r\n <div class=\"flex items-center gap-2 mt-2 pt-2 border-t\"\r\n [class.border-primary-200]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-gray-100]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n <fa-icon [icon]=\"iconProvider.message\" size=\"xs\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\"></fa-icon>\r\n <span class=\"text-xs\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getMessageCount(agentRun) }} Nachrichten\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Chat Area -->\r\n <div class=\"chat bg-gray-50 flex-1 relative min-w-0\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full p-4\">\r\n <p class=\"m-0 text-gray-500 text-center\">\r\n <span class=\"hidden lg:inline\">Bitte einen Chat aus der linken Liste ausw\u00E4hlen</span>\r\n <span class=\"lg:hidden\">Tippe auf das Men\u00FC-Icon um einen Chat auszuw\u00E4hlen</span>\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-2 sm: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: [":host{display:block;height:100%;overflow:hidden}.chat-item{transform:translate(0);transition:all .2s ease-in-out}.chat-item:hover{transform:translate(2px)}.chat-item.active{border-left-width:3px}\n"] }]
|
|
627
|
+
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-3 sm:px-4 py-3 flex items-center bg-white gap-2\">\r\n <!-- Mobile Sidebar Toggle -->\r\n <div class=\"relative lg:hidden flex-shrink-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded\"\r\n (click)=\"toggleSidebar()\"\r\n [pTooltip]=\"'Chat-Verlauf (' + (agentRuns()?.length ?? 0) + ')'\"\r\n tooltipPosition=\"bottom\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"lg\"></fa-icon>\r\n </button>\r\n @if (agentRuns()?.length) {\r\n <span class=\"absolute -top-1 -right-1 bg-primary-500 text-white text-xs font-bold rounded-full min-w-5 h-5 flex items-center justify-center px-1 pointer-events-none\">\r\n {{ agentRuns()!.length }}\r\n </span>\r\n }\r\n </div>\r\n\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-1 min-w-0\">\r\n <button pButton\r\n type=\"button\"\r\n class=\"p-button-text p-button-rounded flex-shrink-0\"\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-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n <span class=\"hidden md:inline text-gray-500 font-normal\">\r\n vom {{ (selectedAgentRun()?.createdAt ?? selectedAgentRun()?.startedAt | date:'dd.MM.yyyy - HH:mm') }}\r\n </span>\r\n </h2>\r\n } @else {\r\n <h2 class=\"text-base sm:text-xl font-semibold truncate\">\r\n <span class=\"hidden sm:inline\">Agent: </span>{{ selectedAgent()?.name }}\r\n </h2>\r\n }\r\n </div>\r\n <div class=\"flex items-center gap-2 sm:gap-3 flex-shrink-0\">\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=\"sm:mr-2\"></fa-icon>\r\n <span class=\"hidden sm:inline\">Neuer Chat</span>\r\n </button>\r\n\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 relative\">\r\n <!-- Mobile Overlay -->\r\n @if (sidebarVisible()) {\r\n <div class=\"fixed inset-0 bg-black/50 z-40 lg:hidden\"\r\n (click)=\"closeSidebar()\"></div>\r\n }\r\n\r\n <!-- Sidebar -->\r\n <div class=\"chats-panel border-r border-gray-200 bg-gradient-to-b from-gray-50 to-white p-3 h-full flex-shrink-0 overflow-y-auto\r\n fixed lg:relative inset-y-0 left-0 z-50 lg:z-auto\r\n w-[280px] sm:w-[300px] lg:w-[220px]\r\n transform transition-transform duration-300 ease-in-out\r\n lg:transform-none\"\r\n [class.-translate-x-full]=\"!sidebarVisible()\"\r\n [class.translate-x-0]=\"sidebarVisible()\"\r\n [class.lg:translate-x-0]=\"true\">\r\n\r\n <!-- Mobile Close Button -->\r\n <div class=\"flex items-center justify-between mb-3 lg:hidden\">\r\n <h3 class=\"text-sm font-semibold text-gray-700\">Chat-Verlauf</h3>\r\n <button class=\"p-2 hover:bg-gray-100 rounded-lg transition-colors\"\r\n (click)=\"closeSidebar()\">\r\n <fa-icon [icon]=\"iconProvider.close\" class=\"text-gray-500\"></fa-icon>\r\n </button>\r\n </div>\r\n\r\n <div class=\"mb-3 hidden lg:block\">\r\n <h3 class=\"text-xs font-semibold text-gray-500 uppercase tracking-wider px-2\">Chat Verlauf</h3>\r\n </div>\r\n @if (agentRuns() === undefined) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.loading\" [animation]=\"'spin'\" size=\"2x\" class=\"text-gray-400 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Chats werden geladen...</p>\r\n </div>\r\n </div>\r\n } @else if (!agentRuns()?.length) {\r\n <div class=\"flex items-center justify-center py-8\">\r\n <div class=\"text-center\">\r\n <fa-icon [icon]=\"iconProvider.chat\" size=\"2x\" class=\"text-gray-300 mb-2\"></fa-icon>\r\n <p class=\"text-sm text-gray-500 m-0\">Noch keine Chats</p>\r\n </div>\r\n </div>\r\n } @else {\r\n <div class=\"flex flex-col gap-2\">\r\n @for (agentRun of agentRuns(); track agentRun) {\r\n <div class=\"chat-item group relative rounded-xl p-3 cursor-pointer transition-all duration-200 border active:scale-[0.98]\"\r\n (click)=\"selectAgentRun(agentRun); closeSidebar()\"\r\n [class.active]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.bg-white]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.shadow-sm]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.hover:shadow-md]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.border-gray-200]=\"selectedAgentRun()?.id !== agentRun.id\"\r\n [class.bg-primary-50]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-primary-300]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.shadow-md]=\"selectedAgentRun()?.id === agentRun.id\">\r\n <div class=\"flex items-start justify-between mb-2\">\r\n <div class=\"flex items-center gap-2 flex-1 min-w-0\">\r\n <fa-icon [icon]=\"iconTextMapper.getIconForStatus(agentRun.status)\"\r\n [classList]=\"iconTextMapper.getIconClassesForStatus(agentRun.status)\"\r\n [animation]=\"agentRun.status === 'running' ? 'spin' : undefined\"\r\n class=\"flex-shrink-0\"\r\n size=\"sm\"></fa-icon>\r\n <span class=\"text-xs font-medium truncate\"\r\n [class.text-primary-700]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-700]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'dd.MM.yy' }}\r\n </span>\r\n </div>\r\n <span class=\"text-xs font-medium flex-shrink-0 ml-2\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ agentRun.createdAt | date:'HH:mm' }}\r\n </span>\r\n </div>\r\n @if (agentRun.chat && agentRun.chat.messages && agentRun.chat.messages.length > 0) {\r\n <div class=\"text-xs truncate leading-relaxed\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-600]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getFirstUserMessage(agentRun) }}\r\n </div>\r\n } @else {\r\n <div class=\"text-xs italic truncate\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n Neuer Chat\r\n </div>\r\n }\r\n @if (agentRun.chat && agentRun.chat.messages) {\r\n <div class=\"flex items-center gap-2 mt-2 pt-2 border-t\"\r\n [class.border-primary-200]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.border-gray-100]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n <fa-icon [icon]=\"iconProvider.message\" size=\"xs\"\r\n [class.text-primary-500]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-400]=\"selectedAgentRun()?.id !== agentRun.id\"></fa-icon>\r\n <span class=\"text-xs\"\r\n [class.text-primary-600]=\"selectedAgentRun()?.id === agentRun.id\"\r\n [class.text-gray-500]=\"selectedAgentRun()?.id !== agentRun.id\">\r\n {{ getMessageCount(agentRun) }} Nachrichten\r\n </span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Chat Area -->\r\n <div class=\"chat bg-gray-50 flex-1 relative min-w-0\">\r\n @if (selectedAgentRun() === undefined) {\r\n <div class=\"flex items-center justify-center h-full p-4\">\r\n <p class=\"m-0 text-gray-500 text-center\">\r\n <span class=\"hidden lg:inline\">Bitte einen Chat aus der linken Liste ausw\u00E4hlen</span>\r\n <span class=\"lg:hidden\">Tippe auf das Men\u00FC-Icon um einen Chat auszuw\u00E4hlen</span>\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-2 sm: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: [":host{display:block;height:100%;overflow:hidden}.chat-item{transform:translate(0);transition:all .2s ease-in-out}.chat-item:hover{transform:translate(2px)}.chat-item.active{border-left-width:3px}\n"] }]
|
|
628
628
|
}], propDecorators: { chatContainer: [{
|
|
629
629
|
type: ViewChild,
|
|
630
630
|
args: ['chatContainer']
|
|
@@ -740,4 +740,4 @@ const chatsRoutes = [
|
|
|
740
740
|
];
|
|
741
741
|
|
|
742
742
|
export { chatsRoutes };
|
|
743
|
-
//# sourceMappingURL=sftech-ng-orchestrator-chats.routes-
|
|
743
|
+
//# sourceMappingURL=sftech-ng-orchestrator-chats.routes-B3UPU3v9.mjs.map
|