diff --git a/modules/features/commcoach/serviceCommcoach.py b/modules/features/commcoach/serviceCommcoach.py index 8151d343..38a1893e 100644 --- a/modules/features/commcoach/serviceCommcoach.py +++ b/modules/features/commcoach/serviceCommcoach.py @@ -178,6 +178,21 @@ async def _generateAndEmitTts(sessionId: str, speechText: str, currentUser, mand logger.warning(f"TTS failed for session {sessionId}: {e}") +def _resolveFileNameAndMime(title: str) -> tuple: + """Derive fileName and mimeType from a document title. Only appends .md if no known extension present.""" + import os + knownExtensions = { + ".md": "text/markdown", ".txt": "text/plain", ".html": "text/html", + ".htm": "text/html", ".pdf": "application/pdf", ".json": "application/json", + ".csv": "text/csv", ".xml": "application/xml", ".doc": "application/msword", + ".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + } + _, ext = os.path.splitext(title) + if ext.lower() in knownExtensions: + return title, knownExtensions[ext.lower()] + return f"{title}.md", "text/markdown" + + async def _saveOrUpdateDocument(doc: Dict[str, Any], contextId: str, userId: str, mandateId: str, instanceId: str, interface, sessionId: str, user=None): @@ -188,7 +203,7 @@ async def _saveOrUpdateDocument(doc: Dict[str, Any], contextId: str, userId: str title = doc.get("title", "Dokument") content = doc.get("content", "") contentBytes = content.encode("utf-8") - fileName = f"{title}.md" + fileName, mimeType = _resolveFileNameAndMime(title) fileRef = None try: @@ -196,7 +211,7 @@ async def _saveOrUpdateDocument(doc: Dict[str, Any], contextId: str, userId: str mgmtInterface = interfaceDbManagement.getInterface( currentUser=user, mandateId=mandateId, featureInstanceId=instanceId ) - fileItem = mgmtInterface.createFile(name=fileName, mimeType="text/markdown", content=contentBytes) + fileItem = mgmtInterface.createFile(name=fileName, mimeType=mimeType, content=contentBytes) mgmtInterface.createFileData(fileItem.id, contentBytes) fileRef = fileItem.id except Exception as e: @@ -205,6 +220,7 @@ async def _saveOrUpdateDocument(doc: Dict[str, Any], contextId: str, userId: str if docId: updates = { "fileName": fileName, + "mimeType": mimeType, "extractedText": content, "summary": title, "fileSize": len(contentBytes), @@ -224,7 +240,7 @@ async def _saveOrUpdateDocument(doc: Dict[str, Any], contextId: str, userId: str mandateId=mandateId, instanceId=instanceId, fileName=fileName, - mimeType="text/markdown", + mimeType=mimeType, fileSize=len(contentBytes), extractedText=content, summary=title, diff --git a/modules/features/commcoach/serviceCommcoachAi.py b/modules/features/commcoach/serviceCommcoachAi.py index 8db9e61c..7ba52f58 100644 --- a/modules/features/commcoach/serviceCommcoachAi.py +++ b/modules/features/commcoach/serviceCommcoachAi.py @@ -160,22 +160,35 @@ Kommunikationsstil: - Sei direkt aber wertschätzend - Verwende keine Emojis - Antworte in der Sprache des Benutzers -- Halte Antworten fokussiert (max 3-4 Absätze)""" +- Halte Chat-Antworten (text/speech) fokussiert. Dokumente duerfen ausfuehrlich sein.""" prompt += """ +Handlungsprinzip: +- Wenn der Benutzer dich bittet, etwas zu erstellen (Dokument, Präsentation, Checkliste, Plan), dann TU ES SOFORT. Frage NICHT nochmals nach Bestätigung. +- Verwende alle verfügbaren Informationen aus dem Chat-Verlauf, den Dokumenten und dem Kontext. +- Wenn der Benutzer sagt "erstelle", "mach", "schreib", dann liefere das fertige Ergebnis — keine Aufzählung von Punkten, die du "gleich umsetzen wirst". + Antwortformat: Du antwortest IMMER als reines JSON-Objekt mit exakt diesen Feldern: {"text": "...", "speech": "...", "documents": []} "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": 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 []. +"documents": Dokumente die der Benutzer aufbewahren kann. Erstelle ein Dokument wenn: der Benutzer explizit darum bittet, du strukturierte Inhalte lieferst, oder Material zum Aufbewahren sinnvoll ist. Wenn keine: leeres Array []. + +Dokument-Format: +{"title": "Dateiname_mit_Extension.html", "content": "...vollstaendiger Inhalt..."} +- Der Title IST der Dateiname inkl. Extension (.html, .md, .txt etc.) +- Fuer HTML-Dokumente: Erstelle VOLLSTAENDIGES, professionell gestyltes HTML mit inline CSS. Kein Markdown, sondern fertiges HTML mit Farben, Layout, Typografie. +- Fuer andere Dokumente: Verwende Markdown. +- WICHTIG: Der Content muss VOLLSTAENDIG und AUSFUEHRLICH sein. Keine Platzhalter, keine "hier kommt..."-Abschnitte. Schreibe echte, detaillierte Inhalte basierend auf allen verfuegbaren Informationen aus dem Chat und den Dokumenten. +- Laengenbeschraenkung fuer Dokumente: KEINE. Schreibe so viel wie noetig fuer ein vollstaendiges Ergebnis. Kanalverteilung: - Fakten, Listen, Übungen -> text - Empathie, Einordnung, Nachfragen -> speech -- Materialien zum Aufbewahren -> documents +- Erstellte Dateien, Materialien zum Aufbewahren -> documents WICHTIG: Antworte NUR mit dem JSON-Objekt. Kein Text vor oder nach dem JSON."""