From d7ba24f61ac218f5cd9b3e6c510f769a94ccde70 Mon Sep 17 00:00:00 2001 From: patrick-motsch Date: Thu, 5 Mar 2026 23:41:37 +0100 Subject: [PATCH] fixed stt procedure --- modules/features/commcoach/mainCommcoach.py | 7 +---- .../commcoach/routeFeatureCommcoach.py | 25 ++++++++++++++-- .../features/commcoach/serviceCommcoach.py | 29 +++++++++++++++---- .../features/commcoach/serviceCommcoachAi.py | 11 +++++-- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/modules/features/commcoach/mainCommcoach.py b/modules/features/commcoach/mainCommcoach.py index 2147a867..6da38087 100644 --- a/modules/features/commcoach/mainCommcoach.py +++ b/modules/features/commcoach/mainCommcoach.py @@ -22,14 +22,9 @@ UI_OBJECTS = [ }, { "objectKey": "ui.feature.commcoach.coaching", - "label": {"en": "Coaching", "de": "Coaching", "fr": "Coaching"}, + "label": {"en": "Coaching & Dossier", "de": "Coaching & Dossier", "fr": "Coaching & Dossier"}, "meta": {"area": "coaching"} }, - { - "objectKey": "ui.feature.commcoach.dossier", - "label": {"en": "Dossier", "de": "Dossier", "fr": "Dossier"}, - "meta": {"area": "dossier"} - }, { "objectKey": "ui.feature.commcoach.settings", "label": {"en": "Settings", "de": "Einstellungen", "fr": "Parametres"}, diff --git a/modules/features/commcoach/routeFeatureCommcoach.py b/modules/features/commcoach/routeFeatureCommcoach.py index 685a0f4e..1efa6556 100644 --- a/modules/features/commcoach/routeFeatureCommcoach.py +++ b/modules/features/commcoach/routeFeatureCommcoach.py @@ -1093,8 +1093,7 @@ async def uploadDocument( contextId: str, context: RequestContext = Depends(getRequestContext), ): - """Upload a document and bind it to a context.""" - from fastapi import UploadFile + """Upload a document and bind it to a context. Stores file in Management DB.""" mandateId = _validateInstanceAccess(instanceId, context) interface = _getInterface(context, instanceId) userId = str(context.user.id) @@ -1114,6 +1113,14 @@ async def uploadDocument( mimeType = getattr(file, "content_type", "application/octet-stream") fileSize = len(content) + if not content: + raise HTTPException(status_code=400, detail="Leere Datei hochgeladen") + + import modules.interfaces.interfaceDbManagement as interfaceDbManagement + mgmtInterface = interfaceDbManagement.getInterface(currentUser=context.user) + fileItem, _dupType = mgmtInterface.saveUploadedFile(content, fileName) + fileRef = fileItem.id + extractedText = _extractText(content, mimeType, fileName) summary = None if extractedText and len(extractedText.strip()) > 50: @@ -1139,6 +1146,7 @@ async def uploadDocument( fileSize=fileSize, extractedText=extractedText[:10000] if extractedText else None, summary=summary, + fileRef=fileRef, ).model_dump() created = interface.createDocument(docData) return {"document": created} @@ -1152,7 +1160,7 @@ async def deleteDocumentRoute( documentId: str, context: RequestContext = Depends(getRequestContext), ): - _validateInstanceAccess(instanceId, context) + mandateId = _validateInstanceAccess(instanceId, context) interface = _getInterface(context, instanceId) doc = interface.getDocument(documentId) @@ -1160,6 +1168,17 @@ async def deleteDocumentRoute( raise HTTPException(status_code=404, detail="Document not found") _validateOwnership(doc, context) + fileRef = doc.get("fileRef") + if fileRef: + try: + import modules.interfaces.interfaceDbManagement as interfaceDbManagement + mgmtInterface = interfaceDbManagement.getInterface( + currentUser=context.user, mandateId=mandateId, featureInstanceId=instanceId + ) + mgmtInterface.deleteFile(fileRef) + except Exception as e: + logger.warning(f"Failed to delete file {fileRef}: {e}") + interface.deleteDocument(documentId) return {"deleted": True} diff --git a/modules/features/commcoach/serviceCommcoach.py b/modules/features/commcoach/serviceCommcoach.py index df490aa2..5d9b6f29 100644 --- a/modules/features/commcoach/serviceCommcoach.py +++ b/modules/features/commcoach/serviceCommcoach.py @@ -132,22 +132,39 @@ async def _generateAndEmitTts(sessionId: str, speechText: str, currentUser, mand async def _saveGeneratedDocument(doc: Dict[str, Any], contextId: str, userId: str, - mandateId: str, instanceId: str, interface, sessionId: str): - """Save a document generated by AI and emit SSE event.""" + mandateId: str, instanceId: str, interface, sessionId: str, + user=None): + """Save a document generated by AI. Stores file in Management DB.""" from .datamodelCommcoach import CoachingDocument try: title = doc.get("title", "Dokument") content = doc.get("content", "") + contentBytes = content.encode("utf-8") + fileName = f"{title}.md" + + fileRef = None + try: + import modules.interfaces.interfaceDbManagement as interfaceDbManagement + mgmtInterface = interfaceDbManagement.getInterface( + currentUser=user, mandateId=mandateId, featureInstanceId=instanceId + ) + fileItem = mgmtInterface.createFile(name=fileName, mimeType="text/markdown", content=contentBytes) + mgmtInterface.createFileData(fileItem.id, contentBytes) + fileRef = fileItem.id + except Exception as e: + logger.warning(f"Failed to store generated document in file DB: {e}") + docData = CoachingDocument( contextId=contextId, userId=userId, mandateId=mandateId, instanceId=instanceId, - fileName=f"{title}.md", + fileName=fileName, mimeType="text/markdown", - fileSize=len(content.encode()), + fileSize=len(contentBytes), extractedText=content, summary=title, + fileRef=fileRef, ).model_dump() created = interface.createDocument(docData) await emitSessionEvent(sessionId, "documentCreated", created) @@ -328,7 +345,7 @@ class CommcoachService: documents = parsed.get("documents", []) for doc in documents: - await _saveGeneratedDocument(doc, contextId, self.userId, self.mandateId, self.instanceId, interface, sessionId) + await _saveGeneratedDocument(doc, contextId, self.userId, self.mandateId, self.instanceId, interface, sessionId, user=self.currentUser) assistantMsg = CoachingMessage( sessionId=sessionId, @@ -419,7 +436,7 @@ class CommcoachService: documents = parsed.get("documents", []) for doc in documents: - await _saveGeneratedDocument(doc, contextId, self.userId, self.mandateId, self.instanceId, interface, sessionId) + await _saveGeneratedDocument(doc, contextId, self.userId, self.mandateId, self.instanceId, interface, sessionId, user=self.currentUser) assistantMsg = CoachingMessage( sessionId=sessionId, diff --git a/modules/features/commcoach/serviceCommcoachAi.py b/modules/features/commcoach/serviceCommcoachAi.py index 357a65b3..7b67406f 100644 --- a/modules/features/commcoach/serviceCommcoachAi.py +++ b/modules/features/commcoach/serviceCommcoachAi.py @@ -124,7 +124,8 @@ def buildCoachingSystemPrompt( Rollenbeschreibung: {personaDescription} WICHTIG für dein Verhalten: -- Bleibe KONSEQUENT in deiner Rolle. Du bist NICHT der Coach, du bist {personaLabel}. +- Du BIST {personaLabel}. Du bist NICHT der Coach. Sprich IMMER direkt als diese Person. +- Beschreibe KEINE Szenarien. Beginne SOFORT mit dem Dialog in deiner Rolle. - Reagiere authentisch und emotional gemäss deiner Rollenbeschreibung. - Verwende eine Sprache und Tonalität, die zu deiner Rolle passt. - Der Benutzer übt ein Gespräch mit dir. Gib ihm realistische Reaktionen. @@ -147,6 +148,12 @@ Deine Rolle: - Schlage am Ende der Session konkrete nächste Schritte vor (als Tasks) - Kommuniziere empathisch, klar und auf Augenhöhe +Roleplay: +- Wenn der Benutzer dich bittet, eine bestimmte Person zu spielen (z.B. einen kritischen Kunden, einen Vorgesetzten, einen Mitarbeiter), dann wechsle SOFORT in diese Rolle. +- Beschreibe KEIN Szenario. Sprich direkt ALS diese Person. Beginne sofort mit dem Dialog in der Rolle. +- Bleibe in der Rolle, bis der Benutzer explizit sagt, dass das Roleplay beendet ist oder Feedback möchte. +- Reagiere authentisch, emotional und realistisch wie die beschriebene Person. + Kommunikationsstil: - Duze den Benutzer - Sei direkt aber wertschätzend @@ -162,7 +169,7 @@ Du antwortest IMMER als reines JSON-Objekt mit exakt diesen Feldern: "text": Dein schriftlicher Chat-Text. Details, Struktur, Übungen, Beispiele. Markdown-Formatierung erlaubt. "speech": Dein gesprochener Kommentar. Natürlich, wie ein Gespräch. Fasse zusammen, kommentiere, motiviere, stelle Fragen. Lies NICHT den Text vor, ergänze ihn mündlich. 2-4 Sätze, reiner Redetext ohne Formatierung. -"documents": Optionale Dokumente (Zusammenfassungen, Checklisten, Übungen). Nur wenn sinnvoll. Jedes Dokument: {"title": "...", "content": "..."}. Sonst leeres Array []. +"documents": Dokumente (Zusammenfassungen, Checklisten, Übungen, Protokolle). Erstelle ein Dokument wenn: der Benutzer explizit darum bittet, du strukturierte Inhalte (Listen, Pläne, Checklisten) lieferst, oder Material zum Aufbewahren sinnvoll ist. Jedes Dokument: {"title": "...", "content": "Markdown-Inhalt"}. Wenn keine: leeres Array []. Kanalverteilung: - Fakten, Listen, Übungen -> text