# Konzept: Agent Toolbox & Dateisystem-Erweiterung > Poweron Platform -- Erweiterung der Agent-Fähigkeiten und des Dateisystems > Status: Konzept / Version 1.2 / März 2026 --- ## 1. Ausgangslage (IST-Zustand) ### 1.1 Datenmodelle Die Grundstruktur für ein hierarchisches Dateisystem existiert bereits, wird aber kaum genutzt. **FileItem** (`gateway/modules/datamodels/datamodelFiles.py`): | Feld | Typ | Beschreibung | |------|-----|-------------| | `id` | str | Primary Key (UUID) | | `fileName` | str | Dateiname | | `mimeType` | str | MIME-Typ | | `fileSize` | int | Grösse in Bytes | | `folderId` | Optional[str] | Verweis auf übergeordneten Folder | | `featureInstanceId` | Optional[str] | Feature-Instanz-Zuordnung | | `tags` | Optional[List[str]] | Tags | | `status` | Optional[str] | Verarbeitungsstatus | | `description` | Optional[str] | Beschreibung | **FileFolder** (`gateway/modules/datamodels/datamodelFileFolder.py`): | Feld | Typ | Beschreibung | |------|-----|-------------| | `id` | str | Primary Key (UUID) | | `name` | str | Ordnername | | `parentId` | Optional[str] | Übergeordneter Folder (None = Root) | | `mandateId` | Optional[str] | Mandant | | `featureInstanceId` | Optional[str] | Feature-Instanz-Zuordnung | ### 1.2 Backend-Operationen ``` Vorhanden Fehlend ───────────────────── ────────────────────── Files: Files: createFile ✓ copyFile ✗ deleteFile ✓ updateFile ✓ (Metadaten) createFileData ✓ (Update-Pfad: Logik aus Codeeditor applyEdit kopieren) getAllFiles ✓ Folders: Folders: createFolder ✓ deleteFolder ✗ listFolders ✓ renameFolder ✗ moveFolder ✗ getFolder ✗ ``` ### 1.3 Agent-Tools (27 registriert) Dateibezogene Tools im aktuellen Agent: | Tool | Funktion | Status | |------|----------|--------| | `readFile` | Datei lesen | Vorhanden | | `listFiles` | Dateien auflisten | Vorhanden | | `searchFiles` | Dateien suchen | Vorhanden | | `writeFile` | Neue Datei erstellen | Vorhanden | | `moveFile` | Datei verschieben (via `updateFile({folderId})`) | Vorhanden | | `tagFile` | Tags setzen | Vorhanden | | `createFolder` | Ordner erstellen | Vorhanden | | `listFolders` | Ordner auflisten | Vorhanden | | `deleteFile` | Datei löschen | **Fehlt** (Backend existiert) | | `renameFile` | Datei umbenennen | **Fehlt** (Backend existiert) | | `editFile` | Dateiinhalt ändern | **Fehlt** (Logik aus Codeeditor `applyEdit` extrahieren) | | `copyFile` | Datei duplizieren | **Fehlt** (Backend muss gebaut werden) | ### 1.4 Codeeditor-Feature (wird entfernt -- Logik extrahieren) Das bestehende **Codeeditor-Feature** (`gateway/modules/features/codeeditor/`) wird perspektivisch entfernt. Es enthält jedoch bewährte File-Edit-Logik, die vor dem Entfernen in den Workspace-Agent **kopiert** werden muss: **Zu extrahierende Backend-Logik:** | Datei | Was kopieren | |-------|-------------| | `routeFeatureCodeeditor.py` | `applyEdit()`-Logik: File-Write via `createFileData(fileId, contentBytes)`, MIME-Type-Erkennung | | `datamodelCodeeditor.py` | `FileEditProposal`, `EditStatusEnum` (PENDING → ACCEPTED / REJECTED) | | `responseParser.py` | `file_edit`-Block-Parsing (`fileName`, `oldContent`, `newContent`) | **Zu extrahierende Frontend-Logik:** | Datei | Was kopieren | |-------|-------------| | `DiffPreviewPanel.tsx` | Diff-View mit Accept/Reject-Buttons → als Shared-Komponente extrahieren | | `useCodeEditor.ts` | `acceptEdit` / `rejectEdit` Handlers → in Workspace-Hook übernehmen | ### 1.5 Frontend - **FileBrowser** (`frontend_nyla/src/pages/views/workspace/FileBrowser.tsx`): Gruppiert Dateien nach `featureInstanceId`, ignoriert `folderId` und Folder komplett. Kein Folder-Tree. - **FilesPage** (`frontend_nyla/src/pages/basedata/FilesPage.tsx`): Flache Tabelle mit FormGeneratorTable. Keine Ordner-Navigation. - **DataSourcePanel**: Externer Datenquellen-Tree existiert als Referenzimplementierung für Lazy-Loading-Tree-UI. --- ## 2. Dateisystem-Erweiterung (Backend) ### 2.1 Übersicht ```mermaid graph TB subgraph fileSystem [Hierarchisches Dateisystem] Root["(Global) Root"] FolderA["Folder: Projekte"] FolderB["Folder: Analysen"] FolderC["Folder: Q1"] FileA["File: Report.pdf"] FileB["File: Daten.xlsx"] FileC["File: Summary.md"] Root --> FolderA Root --> FolderB FolderA --> FolderC FolderA --> FileA FolderC --> FileB FolderB --> FileC end subgraph agent [Agent Tools] CRUD_Files["Files: create, read, edit, copy, delete, rename, move"] CRUD_Folders["Folders: create, delete, rename, move, list"] end agent -->|"operiert auf"| fileSystem ``` ### 2.2 Neue/Erweiterte DB-Methoden Alle Methoden in `interfaceDbManagement.py` ergänzen: **Übergreifende Regeln für alle Folder-Operationen:** - **Unique-Name-Constraint:** Innerhalb eines Folders darf ein Foldername nur einmal vorkommen (unique pro `parentId`) - **Geschützter Name:** Der Name `"(Global)"` ist reserviert für den virtuellen Root und darf nicht für echte Folder verwendet werden - Validation bei `createFolder`, `renameFolder`, `moveFolder` **deleteFolder(folderId, recursive=False)** - Wenn `recursive=True`: Alle Dateien und Unterordner kaskadierend löschen - Wenn `recursive=False` und Folder nicht leer: Fehler werfen - RBAC-Check auf Folder-Ebene **renameFolder(folderId, newName)** - Via `recordModify(FileFolder, folderId, {"name": newName})` - **Unique-Name-Constraint:** Prüfen, dass im gleichen `parentId` kein anderer Folder mit `newName` existiert - **Geschützter Name:** `"(Global)"` darf nicht als Foldername verwendet werden (reserviert für virtuellen Root) **moveFolder(folderId, targetParentId)** - Validierung: Zirkelverweis verhindern (Folder darf nicht in eigenen Unterbaum verschoben werden) - **Unique-Name-Constraint:** Prüfen, dass im Ziel-Folder kein Folder mit gleichem Namen existiert - Via `recordModify(FileFolder, folderId, {"parentId": targetParentId})` **copyFile(sourceFileId, targetFolderId=None, newFileName=None)** - FileItem duplizieren mit neuer ID - **FileData vollständig duplizieren** (eigenständige Kopie, damit die Kopie unabhängig bearbeitet werden kann) - Optional: neuer Name, anderer Ziel-Folder **updateFileData(fileId, data)** -- Logik aus Codeeditor `applyEdit` kopieren - `createFileData(fileId, contentBytes)` zum Überschreiben bestehender Dateien - Falls `createFileData` bei existierenden Daten überspringt: vorher `deleteFileData(fileId)`, dann `createFileData(fileId, newData)` - FileItem-Metadaten aktualisieren (fileSize, fileHash via `updateFile`) - Hinweis: Codeeditor wird später entfernt -- relevante Logik vorher in `interfaceDbManagement` oder Agent-Tool extrahieren ### 2.3 Root-Folder "(Global)" Der Root-Folder ist **virtuell** und wird nicht als DB-Eintrag gespeichert: - Dateien mit `folderId=None` gehören zum Root - Ordner mit `parentId=None` sind Top-Level-Ordner unter Root - Anzeige im UI als "(Global)" Label ### 2.4 Migration: featureInstanceId entfernen Die Gruppierung nach `featureInstanceId` wird durch die Ordnerstruktur ersetzt: 1. **Spalte beibehalten** aber nicht mehr für Gruppierung nutzen 2. `featureInstanceId` als informatives Metadatum ("Erstellt in: Workspace A") in einer zusätzlichen Tabellenspalte anzeigen 3. Bestehende Dateien: `folderId` bleibt `None` (Root), keine Migration nötig 4. Frontend-Gruppierung nach `featureInstanceId` entfernen, stattdessen Folder-Baum nutzen --- ## 3. Neue Agent-Tools ### 3.1 Phase 1 -- Quick Wins (Backend existiert) #### deleteFile | Eigenschaft | Wert | |-------------|------| | Backend | `interfaceDbManagement.deleteFile(fileId)` | | Parameter | `fileId` (required) | | readOnly | false | | Hinweis | Knowledge-Store-Einträge ebenfalls bereinigen | #### renameFile | Eigenschaft | Wert | |-------------|------| | Backend | `interfaceDbManagement.updateFile(fileId, {"fileName": newName})` | | Parameter | `fileId` (required), `newName` (required) | | readOnly | false | #### readUrl | Eigenschaft | Wert | |-------------|------| | Backend | `serviceWeb._performWebCrawl(urls=[url])` | | Parameter | `url` (required) | | readOnly | true | | Hinweis | Ergänzt `webSearch`: Während `webSearch` nach Informationen sucht, liest `readUrl` gezielt eine bekannte URL | #### translateText | Eigenschaft | Wert | |-------------|------| | Backend | `interfaceVoiceObjects.translateText(text, targetLanguage)` + Google Cloud Translation | | Parameter | `text` (required), `targetLanguage` (required), `sourceLanguage` (optional, auto-detect) | | readOnly | true | | Hinweis | Effizienter als AI-basierte Übersetzung für grosse Textmengen | ### 3.2 Phase 2 -- Dateisystem-Tools #### deleteFolder | Eigenschaft | Wert | |-------------|------| | Backend | Neu: `interfaceDbManagement.deleteFolder()` | | Parameter | `folderId` (required), `recursive` (optional, default false) | | readOnly | false | | Sicherheit | Agent muss vor kaskadierendem Löschen bestätigen (Anzahl betroffener Dateien nennen) | #### renameFolder | Eigenschaft | Wert | |-------------|------| | Backend | Neu: `interfaceDbManagement.renameFolder()` | | Parameter | `folderId` (required), `newName` (required) | | readOnly | false | #### moveFolder | Eigenschaft | Wert | |-------------|------| | Backend | Neu: `interfaceDbManagement.moveFolder()` | | Parameter | `folderId` (required), `targetParentId` (required, null für Root) | | readOnly | false | | Validierung | Zirkelverweis-Check: Ziel darf kein Unterordner der Quelle sein | #### copyFile | Eigenschaft | Wert | |-------------|------| | Backend | Neu: `interfaceDbManagement.copyFile()` | | Parameter | `fileId` (required), `targetFolderId` (optional), `newFileName` (optional) | | readOnly | false | | Implementierung | Vollständige Duplikation: FileItem + FileData werden als eigenständige Kopie erstellt (editierbar) | #### editFile | Eigenschaft | Wert | |-------------|------| | Backend | `dbManagement.createFileData(fileId, contentBytes)` (Logik aus Codeeditor kopiert, siehe 5.2) | | Parameter | `fileId` (required), `content` (required, Text-Inhalt) | | readOnly | false | | Einschränkung | Nur für Text-basierte Dateien (text/\*, application/json, etc.) | | UX-Option | Optional: Approve/Reject-Mode (Agent schlägt Edit als Diff vor, User bestätigt) | ### 3.3 Phase 3 -- Erweiterte Fähigkeiten #### speechToText | Eigenschaft | Wert | |-------------|------| | Backend | `connectorVoiceGoogle.speechToText()` | | Parameter | `fileId` (required, Audio-Datei), `language` (optional, auto-detect) | | readOnly | true | | Hinweis | Gegenstück zu `textToSpeech`. Akzeptiert Audio-Dateien aus dem Workspace | #### detectLanguage | Eigenschaft | Wert | |-------------|------| | Backend | `interfaceVoiceObjects.detectLanguage()` | | Parameter | `text` (required) | | readOnly | true | #### searchImages | Eigenschaft | Wert | |-------------|------| | Backend | Neu: Google Custom Search API (Konzept in `local/pending/doc_enhancement_web_image_actions_pending.md`) | | Parameter | `query` (required), `maxResults` (optional), `imageType` (optional), `size` (optional) | | readOnly | true | | Abhängigkeit | Google Custom Search API Key + Engine ID | | Hinweis | Bilder werden als URLs zurückgegeben, können via `downloadFromDataSource` oder einem neuen Download-Mechanismus heruntergeladen werden | #### neutralizeData | Eigenschaft | Wert | |-------------|------| | Backend | `serviceNeutralization.processText()` / `processFile()` | | Parameter | `text` (optional) oder `fileId` (optional, eines von beiden required) | | readOnly | true (gibt anonymisierten Text zurück, ändert Original nicht) | #### executeCode | Eigenschaft | Wert | |-------------|------| | Backend | Neu: Sandboxed Code Execution | | Parameter | `code` (required), `language` (required: "python" oder "javascript") | | readOnly | true | | Sicherheitskonzept | Siehe Abschnitt 5.1 | --- ## 4. UI-Umbau ### 4.1 Dateien-Seite (Split-View) ``` ┌──────────────────────────────────────────────────────────┐ │ Dateien │ ├───────────────────┬──────────────────────────────────────┤ │ │ [+ Upload / Drag&Drop] [Filter]│ │ (Global) │ ─────────────────────────────────── │ │ ├── Projekte │ Name Typ Grösse Quelle │ │ │ ├── Q1 │ ─────────────────────────────────── │ │ │ └── Q2 │ Report.pdf PDF 1.2 MB Workspace│ │ ├── Analysen │ Daten.xlsx XLSX 450 KB Chat AI │ │ └── Archiv │ Notes.md MD 12 KB Chat AI │ │ │ │ │ [+ Neuer Ordner] │ │ │ │ │ ├───────────────────┴──────────────────────────────────────┤ │ ◄═══════════════ Divider (verschiebbar) ═══════════════►│ └──────────────────────────────────────────────────────────┘ Wichtig: Die Action-Buttons (Upload, Filter) sind OBERHALB der Tabelle fixiert, damit sie bei wechselnder Tabellengrösse nicht springen. ``` ### 4.2 Komponenten **FolderTree (neue Shared-Komponente)** - Rekursiv verschachtelbarer Baum - Lazy-Loading der Unterordner (Referenz: `DataSourcePanel.tsx` für Tree-Pattern) - **Inline-Icons pro Folder-Zeile:** Delete (🗑), Add Subfolder (+), Rename (✏) -- direkt sichtbar, kein Kontextmenü nötig - **Drag-and-Drop:** Folders und Files können per Drag auf andere Folders verschoben werden - Visuelles Feedback: Drop-Target-Highlighting beim Hover über gültiges Ziel - Wiederverwendbar in der Dateien-Seite UND im Workspace-Chat (gleiche Komponente) **FileTable (bestehend, erweitert)** - Zeigt Dateien des aktuell markierten Folders - Neue Spalte "Quelle" (zeigt `featureInstanceLabel` als Information, nicht als Gruppierung) - **Drag-and-Drop:** Dateien aus der Tabelle in den Folder-Tree ziehen zum Verschieben - Kontextmenü pro Datei: Umbenennen, Löschen, Kopieren, Verschieben, Download **SplitView / Divider** - Verschiebbar per Maus-Drag - Default-Position: 25% links / 75% rechts - Minimum-Breite pro Seite: 200px - Position persistent im LocalStorage ### 4.3 Workspace-Integration Im Workspace-Chat (`WorkspacePage.tsx`) wird der bestehende `FileBrowser` umgebaut: - Statt Gruppierung nach `featureInstanceId`: der gleiche `FolderTree` wie auf der Dateien-Seite - Kompaktere Darstellung (kein Split-View nötig, Tree + Dateien untereinander) - Gleiche Drag-and-Drop-Fähigkeiten --- ## 5. Kritische Bewertung ### 5.1 executeCode -- Sicherheitskonzept **Anforderung:** "Hier einfach nur für Analysen und Berechnungen zulassen, nicht für Codeelemente ausserhalb der Umgebung oder Installationen." **Bewertung:** Sinnvoll und notwendig für Datenanalyse. Die Einschränkung auf Analysen/Berechnungen ist korrekt. **Empfohlene Absicherung:** - **Isolierte Ausführung:** RestrictedPython (Python) oder vm2/isolated-vm (JS) -- keine eigene Docker-Sandbox nötig für reine Berechnungen - **Kein Dateisystem-Zugriff:** `open()`, `os`, `subprocess`, `sys` blockieren - **Kein Netzwerk-Zugriff:** `socket`, `urllib`, `requests` blockieren - **Keine Installationen:** `pip`, `import` nur für Whitelist (math, statistics, json, csv, re, datetime, collections, itertools, functools, decimal, fractions) - **Timeout:** Max. 30 Sekunden Ausführungszeit - **Memory-Limit:** Max. 256 MB - **Output-Limit:** Max. 50.000 Zeichen Rückgabe **Risiko-Bewertung:** Mittel. RestrictedPython ist gut getestet, aber kein perfekter Sandbox. Für den Use Case (Berechnungen, Datenanalyse) ist das Risiko vertretbar, solange die Whitelist strikt eingehalten wird. ### 5.2 editFile -- Logik aus Codeeditor übernehmen **Anforderung:** "Bestehende Datei-Inhalte aktualisieren." **Bewertung:** Das Codeeditor-Feature hat eine bewährte File-Edit-Pipeline (`applyEdit`-Route, `createFileData(fileId, contentBytes)`). Da der Codeeditor später entfernt wird, muss die benötigte Logik in den Workspace-Agent **kopiert** werden -- keine Referenzen auf Codeeditor-Module. **Zu übernehmende Logik (aus Codeeditor extrahieren):** - File-Write: `createFileData(fileId, contentBytes)` zum Überschreiben bestehender Dateien - Falls `createFileData` bei existierenden Daten überspringt: `deleteFileData` → `createFileData` als Fallback - MIME-Type-Erkennung: `_guessMimeType(fileName)` Logik kopieren - FileItem-Metadaten (fileSize, fileHash) via `updateFile` aktualisieren - MIME-Type-Check: Nur Text-basierte Dateien erlauben (text/\*, application/json, etc.) - Knowledge-Store re-indexieren nach Edit (bestehende Pipeline nutzen) **Zu übernehmende UX-Logik (aus Codeeditor extrahieren):** - `FileEditProposal`-Datenmodell (`EditStatusEnum`: PENDING → ACCEPTED / REJECTED) in Agent-Datenmodelle kopieren - `file_edit_proposal` SSE-Event-Pattern in den Workspace-Agent übernehmen - Diff-View-Komponente (`DiffPreviewPanel.tsx`) als eigenständige Shared-Komponente extrahieren **Optionaler Approve/Reject-Mode:** - Agent emittiert `file_edit_proposal` SSE-Event mit Old/New-Content - Frontend zeigt Diff-View (extrahierte Shared-Komponente) - User akzeptiert oder lehnt ab - Konfigurierbar: Auto-Apply für kleine Edits, Approve für Dateien > 1 KB **Race-Condition-Risiko:** Gering. Benutzerbezogen, sequenzieller Agent-Zugriff. ### 5.3 copyFile -- Vollständige Kopie **Anforderung:** "Datei im Workspace duplizieren." **Bewertung:** Korrekt. Nur File-Level-Kopie sinnvoll. FileData **muss** vollständig dupliziert werden, damit die Kopie unabhängig bearbeitet werden kann (z.B. via `editFile`). **Empfehlung:** - Nur einzelne Dateien kopieren, keine ganzen Ordner - **Vollständige Duplikation:** FileItem UND FileData werden als eigenständige Einträge mit neuer ID erstellt. Keine Shared-Referenz auf dieselben Daten, da die Kopie editierbar sein muss. - Ordner-Kopie als eigenes Feature für später (komplexer wegen Rekursion und Namenskonflikten) ### 5.4 createCalendarEvent -- Nicht implementierbar **Anforderung:** "Kalender-Eintrag erstellen." **Bewertung: Noch nicht umsetzbar.** Calendar-API (Microsoft Graph `/calendar/events`) ist nicht gebaut. **Empfehlung:** Aus dem aktuellen Scope entfernen. Als separates Feature planen: 1. Microsoft Graph Calendar-Endpoints in `connectorMsft.py` implementieren 2. Workflow-Actions für Calendar erstellen (`outlook.createEvent`, `outlook.listEvents`) 3. Dann als Agent-Tool exponieren **Bestandsaufnahme Mail-Operationen (für Kontext):** | Operation | Microsoft Outlook | Google Gmail | |-----------|-------------------|--------------| | Mail-Ordner auflisten | `OutlookAdapter.browse(me/mailFolders)` | `GmailAdapter.browse(labels)` | | Mails in Ordner lesen | `OutlookAdapter.browse(me/mailFolders/{id}/messages)` | `GmailAdapter.browse(messages?labelIds=)` | | Mail herunterladen | `OutlookAdapter.download(me/messages/{id})` | **Stub** (gibt `b""` zurück) | | Mails suchen | `OutlookAdapter.search(me/messages?$search=)` | `GmailAdapter.search(users/me/messages?q=)` | | Mail senden | `OutlookAdapter.sendMail(me/sendMail)` | **Nicht implementiert** | | Draft erstellen | `composeAndDraftEmailWithContext` (Workflow) | **Nicht implementiert** | | Draft senden | `sendDraftEmail` (Workflow) | **Nicht implementiert** | | Agent-Tool `sendMail` | Implementiert (nur Outlook trotz Doku "Outlook, Gmail") | **Nicht unterstützt** | **Fazit Mail:** Microsoft Outlook ist vollständig integriert (lesen, suchen, senden, drafts). Google Gmail hat nur Lesen/Suchen (readonly Scopes). Gmail-Senden, Drafts und Download sind nicht implementiert -- bei Bedarf separates Feature. ### 5.5 featureInstanceId-Entfernung **Anforderung:** "Die Strukturierung der Daten nach deren Creation Feature Instanz entfernen wir. Dazu eine zusätzliche Spalte ergänzen." **Bewertung:** Guter Ansatz. Die Ordnerstruktur ersetzt die Feature-Instanz-Gruppierung. **Empfehlung:** - `featureInstanceId` auf `FileItem` beibehalten (nicht aus dem Modell entfernen) - Nicht mehr für Gruppierung nutzen, nur als informatives Metadatum - Neue Tabellenspalte "Quelle" zeigt den Feature-Instanz-Namen - Kein Datenmigrations-Aufwand nötig -- bestehende Dateien bleiben im Root und können manuell in Ordner verschoben werden - Die Zuordnung `featureInstanceId` bei neuen Dateien weiterhin setzen (Audit-Trail) ### 5.6 Root "(Global)" -- Multi-Mandanten-Implikation **Anforderung:** "Der Root ist der Folder '(Global)'." **Bewertung:** Konsistent mit dem bestehenden System. Dateien sind bereits benutzerbezogen (`_createdBy` Filter). Der Root-Scope ist pro User, nicht systemweit. **Empfehlung:** - Root ist virtuell (kein DB-Eintrag), repräsentiert `folderId=None` - Dateien sind weiterhin pro User isoliert (bestehende RBAC-Filter) - Label "(Global)" im UI zeigt dem User, dass dies sein persönlicher Root ist - Für Multi-Mandanten: Dateien haben `mandateId`, Filter bleibt bestehen ### 5.7 searchImages -- Abhängigkeit und Integration **Anforderung:** Aus `doc_enhancement_web_image_actions_pending.md` ein Tool ableiten. **Bewertung:** Das bestehende Konzept ist solide (Google Custom Search API, `WEB_SEARCH_MEDIA` Operation Type). Für den Agent-Tool-Kontext reicht eine vereinfachte Version. **Empfehlung:** - Das Agent-Tool `searchImages` als Wrapper um die neue `WEB_SEARCH_MEDIA`-Operation implementieren - Ergebnisse als Liste von URLs zurückgeben (der Agent kann dann `downloadFromDataSource` oder einen neuen Mechanismus nutzen, um Bilder herunterzuladen) - Google API Key als Voraussetzung klar dokumentieren - Fallback: Wenn kein Google API Key konfiguriert, Tool nicht registrieren ### 5.8 Dokument-Rendering mit Bildern **Anforderung:** Können professionelle Berichte (DOCX, XLSX, PPTX, PDF, HTML) mit eingebetteten Bildern generiert werden? **Bewertung: Ja, alle 5 Renderer unterstützen Bilder bereits vollständig.** | Renderer | Pfad | Bild-Methode | Bibliothek | |----------|------|-------------|------------| | DOCX | `renderers/rendererDocx.py` | `_renderJsonImage()` → `doc.add_picture()` | python-docx | | XLSX | `renderers/rendererXlsx.py` | `_addImageToExcel()` → `sheet.add_image()` | openpyxl | | PPTX | `renderers/rendererPptx.py` | `_addImagesToSlide()` → `slide.shapes.add_picture()` | python-pptx | | PDF | `renderers/rendererPdf.py` | `_renderJsonImage()` → `ReportLabImage` | reportlab | | HTML | `renderers/rendererHtml.py` | `_renderJsonImage()` → `` | native | **Gemeinsames Bild-Format (alle Renderer):** ```json { "type": "image", "content": { "base64Data": "", "altText": "Bildbeschreibung", "caption": "Optionale Bildunterschrift" } } ``` **Basis-Klasse** (`documentRendererBaseTemplate.py`): Bietet `_validateImageData()`, `_getImageDimensions()`, `_resizeImageIfNeeded()` als Shared-Funktionen. **Fazit:** Kein Handlungsbedarf für Bild-Rendering. Der Agent kann Bilder (z.B. via `generateImage` oder `searchImages` + Download) als Base64-Daten in das Dokument-Schema einbetten, und alle Renderer verarbeiten diese korrekt. ### 5.9 neutralizeData -- Scope **Anforderung:** "Text/Datei anonymisieren." **Bewertung:** `serviceNeutralization` existiert, ist aber Feature-spezifisch (Neutralization Feature). Als Agent-Tool muss es Feature-unabhängig aufrufbar sein. **Empfehlung:** - Read-Only: Gibt anonymisierten Text zurück, ändert das Original nicht - Für Dateien: Temporär extrahieren, neutralisieren, Ergebnis als neuen Text zurückgeben - Feature-Abhängigkeit prüfen: Wenn Neutralization-Feature nicht lizenziert, Tool nicht registrieren --- ## 6. Zusammenfassung und Priorisierung ### Tool-Übersicht nach Aufwand und Nutzen | Tool | Aufwand | Nutzen | Priorität | Phase | |------|---------|--------|-----------|-------| | `deleteFile` | Niedrig | Hoch | **Must** | 1 | | `renameFile` | Niedrig | Hoch | **Must** | 1 | | `readUrl` | Niedrig | Hoch | **Must** | 1 | | `translateText` | Niedrig | Mittel | **Should** | 1 | | `deleteFolder` | Mittel | Hoch | **Must** | 2 | | `renameFolder` | Niedrig | Mittel | **Should** | 2 | | `moveFolder` | Mittel | Mittel | **Should** | 2 | | `copyFile` | Niedrig | Mittel | **Should** | 2 | | `editFile` | Niedrig (Codeeditor-Logik vorhanden) | Hoch | **Must** | 2 | | `speechToText` | Niedrig | Mittel | **Should** | 3 | | `detectLanguage` | Niedrig | Niedrig | **Could** | 3 | | `searchImages` | Hoch | Mittel | **Should** | 3 | | `neutralizeData` | Mittel | Niedrig | **Could** | 3 | | `executeCode` | Hoch | Hoch | **Should** | 3 | | `createCalendarEvent` | Hoch | Mittel | **Won't** (vorerst) | - | ### Geschätzter Gesamtaufwand | Bereich | Aufwand | |---------|---------| | Phase 1: Quick-Win Tools | 2-3 Tage | | Phase 2: Dateisystem-Backend + Tools | 4-5 Tage | | Phase 3: Erweiterte Tools | 5-7 Tage | | UI: Dateien-Seite Split-View | 3-4 Tage | | UI: Folder-Tree Komponente | 2-3 Tage | | UI: Workspace-Integration | 1-2 Tage | | **Gesamt** | **17-24 Tage** | --- ## 7. Referenzen | Dokument | Pfad | |----------|------| | AI Agent Architecture | `wiki/concepts/AI-Agent-Architecture-Konzept.md` | | Web Image Search Konzept | `local/pending/doc_enhancement_web_image_actions_pending.md` | | Codeeditor (Logik extrahieren, Feature wird entfernt) | `gateway/modules/features/codeeditor/routeFeatureCodeeditor.py` | | Codeeditor Datenmodell (extrahieren) | `gateway/modules/features/codeeditor/datamodelCodeeditor.py` | | Codeeditor Response Parser (extrahieren) | `gateway/modules/features/codeeditor/responseParser.py` | | Codeeditor DiffPreview (als Shared-Komponente extrahieren) | `frontend_nyla/src/pages/views/codeeditor/DiffPreviewPanel.tsx` | | Dokument-Renderer (Bild-Support) | `gateway/modules/serviceCenter/services/serviceGeneration/renderers/` | | FileItem Datenmodell | `gateway/modules/datamodels/datamodelFiles.py` | | FileFolder Datenmodell | `gateway/modules/datamodels/datamodelFileFolder.py` | | DB-Operationen | `gateway/modules/interfaces/interfaceDbManagement.py` | | Agent Tools | `gateway/modules/serviceCenter/services/serviceAgent/mainServiceAgent.py` | | Tool Registry | `gateway/modules/serviceCenter/services/serviceAgent/toolRegistry.py` | | Frontend FileBrowser | `frontend_nyla/src/pages/views/workspace/FileBrowser.tsx` | | Frontend FilesPage | `frontend_nyla/src/pages/basedata/FilesPage.tsx` | | DataSourcePanel (Tree-Referenz) | `frontend_nyla/src/pages/views/workspace/DataSourcePanel.tsx` |