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