fixed stt procedure

This commit is contained in:
patrick-motsch 2026-03-05 23:41:37 +01:00
parent 12b0d3d36e
commit d7ba24f61a
4 changed files with 55 additions and 17 deletions

View file

@ -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"},

View file

@ -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}

View file

@ -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,

View file

@ -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