12 KiB
12 KiB
| name | overview | todos | isProject | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Cursor-Style Chat Feature MVP | Integration eines Cursor-artigen File-Editing-Chat-Features als neues Feature "codeeditor" im Gateway und der Nyla UI. Nutzt aicore-Modelle direkt, Chat-Datenmodelle vom Chatplayground, SSE-Streaming vom Chatbot-Feature. Nur Text-Dokumente (Markdown, JSON, YAML, Code). Dateien werden hochgeladen (kein SharePoint), spaeter mit virtuellen Folder-Tags strukturiert. Apply erzeugt neue lokale Dokument-Versionen. |
|
false |
MVP: Cursor-Style File-Editing Chat Feature ("CodeEditor")
Professionelle Einschaetzung
Kernfrage: aicore-Modelle direkt oder ueber Chat-Komponente?
Empfehlung: Die bestehenden aicore-Modelle direkt nutzen (nicht ueber eine externe Cursor-Chat-Komponente).
Begruendung:
- Die aicore-Infrastruktur (
aicoreModelRegistry,aicoreModelSelector, Plugin-System) ist bereits produktionsreif mit Failover, Billing, RBAC und Multi-Provider-Support - Eine externe Cursor-Komponente wuerde eine Abhaengigkeit schaffen, die schwer zu kontrollieren ist
- Der Mehrwert liegt nicht im LLM-Aufruf (den beherrscht aicore), sondern in der Prompt-Orchestrierung (System Prompt + Context + Tool Definitions) und dem Response Parsing (Antwort in Dokument-Segmente zerlegen)
- Der neue "Cursor-Style" Layer wird auf aicore aufgebaut, nicht neben oder statt aicore
Was vom Chatplayground uebernommen werden kann
Sehr viel -- die Grundarchitektur ist ideal:
- ChatWorkflow Datenmodell: 1:1 wiederverwendbar (neuer
workflowMode: "CodeEditor") - ChatMessage + ChatDocument: Vollstaendig wiederverwendbar fuer Chat-Verlauf und Datei-Referenzen
- Polling-Mechanismus (
getUnifiedChatDatamitafterTimestamp): Sofort nutzbar - SSE-Infrastruktur (aus Chatbot-Feature): Kann fuer Echtzeit-Streaming aktiviert werden
- PlaygroundPage UI-Pattern: Resizable Two-Column Layout, Messages-Komponente, File-Upload, Input-Footer
- Route-Pattern (
routeFeatureChatplayground.py): Als Vorlage fuer neue Feature-Route - Feature-Registrierung:
VIEW_COMPONENTSRegistry inFeatureView.tsx, BackendmainChatplayground.py
Was NEU gebaut werden muss
- File-Context-Manager (Backend): Hochgeladene Text-Dateien als "Workspace" laden und als Kontext bereitstellen (kein SharePoint, spaeter virtuelle Folder-Tags)
- Prompt Assembly Service (Backend): System Prompt mit File-Kontext und Cursor-artigen Instruktionen zusammenbauen
- Response Document Parser (Backend): AI-Antwort in typisierte Dokument-Segmente zerlegen (text, code_block, file_edit, etc.)
- Diff-Preview UI (Frontend): Text-Aenderungen als Diff anzeigen mit Accept/Reject
- File-List Panel (Frontend): Hochgeladene Dateien auflisten und als Kontext auswaehlen (spaeter: virtuelle Folder-Tags)
- SSE-Integration (Backend+Frontend): Echtzeit-Streaming ueber bestehende EventManager-Infrastruktur
Architektur
flowchart TB
subgraph ui [Nyla UI - Frontend]
CodeEditorPage["CodeEditorPage\n(neue View)"]
FileList["FileListPanel\n(hochgeladene Dateien)"]
ChatPanel["ChatPanel\n(Messages + SSE)"]
DiffPreview["DiffPreviewPanel\n(Text-Diffs)"]
CodeEditorPage --> FileList
CodeEditorPage --> ChatPanel
CodeEditorPage --> DiffPreview
end
subgraph gw [Gateway - Backend]
Route["routeFeatureCodeeditor.py\n(FastAPI Endpoints)"]
SSE["SSE Stream Endpoint\n(EventManager)"]
FileCtx["fileContextManager.py\n(Text-Dateien laden)"]
PromptAsm["promptAssembly.py\n(System Prompt Builder)"]
RespParse["responseParser.py\n(Document Segmentation)"]
Route --> FileCtx
Route --> PromptAsm
PromptAsm --> AiService["serviceAi\n(bestehend)"]
AiService --> AiCore["aicore\n(ModelRegistry + Plugins)"]
RespParse --> Route
RespParse --> SSE
end
subgraph data [Datenspeicher]
DB["Gateway DB\n(interfaceDbComponent)\nHochgeladene Dateien"]
end
ChatPanel -->|"POST /api/codeeditor/.../start"| Route
ChatPanel -->|"GET .../stream (SSE)"| SSE
FileList -->|"GET .../files"| Route
DiffPreview -->|"POST .../apply"| Route
FileCtx --> DB
MVP Scope: Konkrete Implementierung
Backend: Gateway
1. Neues Feature codeeditor
- Datei:
gateway/modules/features/codeeditor/mainCodeeditor.py - Registrierung analog zu
mainChatplayground.py(RBAC, Feature-Config)
2. Routes
- Datei:
gateway/modules/features/codeeditor/routeFeatureCodeeditor.py - Kopie von
routeFeatureChatplayground.pyals Basis, erweitert um:
| Endpoint | Methode | Beschreibung |
|---|---|---|
/{instanceId}/start |
POST | Workflow starten (nutzt chatStart mit mode CodeEditor) |
/{instanceId}/{workflowId}/stop |
POST | Workflow stoppen |
/{instanceId}/{workflowId}/stream |
GET | SSE-Stream fuer Echtzeit-Updates (Messages, Logs, Edits) |
/{instanceId}/{workflowId}/chatData |
GET | Fallback-Polling fuer Chat-Daten |
/{instanceId}/workflows |
GET | Workflows auflisten |
/{instanceId}/files |
GET | Hochgeladene Text-Dateien auflisten |
/{instanceId}/files/{fileId}/content |
GET | Text-Datei-Inhalt laden |
/{instanceId}/{workflowId}/apply |
POST | Aenderung als neue Dokument-Version speichern |
3. WorkflowMode Erweiterung
- Datei:
gateway/modules/datamodels/datamodelChat.py - Neuer Enum-Wert:
WORKFLOW_CODEEDITOR = "CodeEditor"inWorkflowModeEnum
4. File Context Manager
- Datei:
gateway/modules/features/codeeditor/fileContextManager.py - Laedt hochgeladene Text-Dateien aus Gateway DB (
interfaceDbComponent) - Unterstuetzte Formate:
.md,.txt,.json,.yaml,.yml,.xml,.csv,.py,.js,.ts,.html,.css,.sql - Baut einen "Workspace-Snapshot": Dateiliste + Inhalte der vom User ausgewaehlten Dateien
- Validiert MIME-Types (nur text-basierte Dateien akzeptieren)
- Spaeter erweiterbar: virtuelle Folder-Tags pro Datei fuer Strukturierung
5. Prompt Assembly
- Datei:
gateway/modules/features/codeeditor/promptAssembly.py - Baut System Prompt nach Cursor-Muster (dokumentiert in
wiki/cursor-doc/doc_cursor_ai_agent_architecture.md) - Injiziert: Datei-Kontexte, Benutzer-Instruktionen, Antwort-Format-Vorgaben
- Nutzt
aiService.callAiContent()oderinterfaceAiObjects.callWithTextContext()als LLM-Aufruf
6. Response Document Parser
- Datei:
gateway/modules/features/codeeditor/responseParser.py - Parst AI-Antwort in typisierte Segmente:
text,code_block,code_reference,file_edit - Speichert Segmente als erweiterte
ChatMessageEintraege (mitactionMethod: "codeeditor") - Spezifikation:
wiki/cursor-doc/doc_cursor_response_json_structure.md
Frontend: Nyla UI
7. Feature-Registrierung
- Datei:
frontend_nyla/src/pages/FeatureView.tsx - Neuer Eintrag in
VIEW_COMPONENTS:
codeeditor: {
editor: CodeEditorPage,
workflows: WorkflowsPage, // wiederverwendet
}
8. CodeEditorPage
- Datei:
frontend_nyla/src/pages/views/codeeditor/CodeEditorPage.tsx - Drei-Panel-Layout (File-Browser links, Chat mitte, Diff-Preview rechts)
- Nutzt bestehende
MessagesKomponente,useResizablePanels,usePlayground-Pattern
9. File List Panel
- Datei:
frontend_nyla/src/components/CodeEditor/FileListPanel.tsx - Flache Liste der hochgeladenen Text-Dateien mit Checkbox-Auswahl
- Upload-Button fuer neue Dateien (Drag & Drop wiederverwendet aus Playground)
- Ausgewaehlte Dateien werden als Kontext an den Chat gesendet (analog
listFileId) - Spaeter erweiterbar: virtuelle Folder-Tags als Gruppierung
10. Diff Preview Panel
- Datei:
frontend_nyla/src/components/CodeEditor/DiffPreviewPanel.tsx - Zeigt
file_editSegmente aus der AI-Antwort als Text-Diff an - Accept/Reject Buttons pro Aenderung
- Accept erzeugt neue Dokument-Version (POST
/{instanceId}/{workflowId}/apply) - MVP: einfacher Side-by-Side Text-Diff (kein vollstaendiger Code-Editor noetig)
11. Hooks
- Datei:
frontend_nyla/src/hooks/useCodeEditor.ts - Erweitert
useDashboardInputFormPattern um:selectedFiles: string[](ausgewaehlte Kontext-Dateien)pendingEdits: FileEdit[](vorgeschlagene Aenderungen)applyEdit(editId)/rejectEdit(editId)Aktionen
Datenmodell-Erweiterungen
12. Neue Pydantic Models (in bestehendem datamodelChat.py oder eigenem File)
class FileContext(BaseModel):
fileId: str
fileName: str
content: Optional[str] = None
mimeType: str
tags: List[str] = Field(default_factory=list) # virtuelle Folder-Tags (spaeter)
class FileEditProposal(BaseModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
fileId: str # Referenz auf bestehende Datei
fileName: str
operation: str # "edit" | "create"
oldContent: Optional[str] = None
newContent: str
diffSummary: Optional[str] = None # Kurzbeschreibung der Aenderung
status: str = "pending" # "pending" | "accepted" | "rejected"
class FileVersion(BaseModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
sourceFileId: str # Original-Datei
editProposalId: str # Referenz auf akzeptiertes FileEditProposal
newFileId: str # Neue Datei-Version in DB
createdAt: float = Field(default_factory=getUtcTimestamp)
Entschiedene Design-Entscheide
- Datenquelle: Hochgeladene Dateien im System (kein SharePoint). Spaeter: virtuelle Folder-Tags pro Datei fuer Strukturierung
- Dateitypen: Nur Text-basierte Dokumente (Markdown, JSON, YAML, Code, etc.)
- Apply-Mechanismus: Erzeugt neue lokale Dokument-Version in der DB (keine externe Synchronisation)
- Streaming: SSE ueber bestehende
EventManager-Infrastruktur aus dem Chatbot-Feature
SSE-Integration (Details)
Nutzt die bestehende Infrastruktur aus gateway/modules/features/chatbot/streaming/events.py:
- EventManager Singleton:
get_event_manager()- verwaltet async Queues pro Workflow - Event-Emission: In
interfaceDbChat.createMessage()undcreateLog()bereits eingebaut - Neuer SSE-Endpoint:
GET /api/codeeditor/{instanceId}/{workflowId}/stream - Event-Typen fuer CodeEditor:
chatdata(bestehend): Messages, Logs, Statsfile_edit(neu): FileEditProposal Events fuer Echtzeit-Diff-Updatesfile_version(neu): Neue Datei-Version erstellt (nach Apply)
- Frontend:
useCodeEditorHook oeffnetEventSourcestatt Polling - Fallback:
chatDataPolling-Endpoint bleibt als Fallback verfuegbar