fixes commcoach

This commit is contained in:
ValueOn AG 2026-03-28 22:29:15 +01:00
parent 1883f8cd6a
commit 1f42c015d6
2 changed files with 61 additions and 7 deletions

View file

@ -33,6 +33,7 @@ from .serviceCommcoachContextRetrieval import (
buildSessionSummariesForPrompt, buildSessionSummariesForPrompt,
findSessionByDate, findSessionByDate,
searchSessionsByTopic, searchSessionsByTopic,
searchSessionsByTopicRag,
_parseDateFromMessage, _parseDateFromMessage,
PREVIOUS_SESSION_SUMMARIES_COUNT, PREVIOUS_SESSION_SUMMARIES_COUNT,
ROLLING_OVERVIEW_SESSION_THRESHOLD, ROLLING_OVERVIEW_SESSION_THRESHOLD,
@ -1035,10 +1036,29 @@ class CommcoachService:
result["rollingOverview"] = rollingOverview result["rollingOverview"] = rollingOverview
elif intent == RetrievalIntent.RECALL_TOPIC: elif intent == RetrievalIntent.RECALL_TOPIC:
retrieved = searchSessionsByTopic(completedSessions, userContent) retrieved = list(searchSessionsByTopic(completedSessions, userContent))
queryVector = await self._embedUserQuery(userContent)
if queryVector:
ragHits = searchSessionsByTopicRag(
userContent,
self.userId,
self.instanceId,
mandateId=self.mandateId,
queryVector=queryVector,
)
for hit in ragHits:
content = (hit.get("content") or "").strip()
if not content:
continue
retrieved.append({
"summary": content[:450],
"date": "",
"source": "rag",
"ragSourceLabel": hit.get("fileName") or "Mandantenwissen",
})
result["retrievedByTopic"] = retrieved result["retrievedByTopic"] = retrieved
if retrieved: if retrieved:
logger.info(f"Topic recall: found {len(retrieved)} sessions for query") logger.info(f"Topic recall: {len(retrieved)} item(s) (sessions + optional RAG)")
result["previousSessionSummaries"] = buildSessionSummariesForPrompt( result["previousSessionSummaries"] = buildSessionSummariesForPrompt(
allSessions, excludeSessionId=sessionId, limit=PREVIOUS_SESSION_SUMMARIES_COUNT allSessions, excludeSessionId=sessionId, limit=PREVIOUS_SESSION_SUMMARIES_COUNT
) )
@ -1101,3 +1121,31 @@ class CommcoachService:
) )
) )
return await aiService.callAi(aiRequest) return await aiService.callAi(aiRequest)
async def _embedUserQuery(self, text: str) -> Optional[List[float]]:
"""Embedding for mandate-wide RAG (same ServiceCenter AI service as coaching calls)."""
snippet = (text or "").strip()[:2000]
if not snippet:
return None
from modules.serviceCenter import getService
from modules.serviceCenter.context import ServiceCenterContext
serviceContext = ServiceCenterContext(
user=self.currentUser,
mandate_id=self.mandateId,
feature_instance_id=self.instanceId,
)
aiService = getService("ai", serviceContext)
await aiService.ensureAiObjectsInitialized()
try:
response = await aiService.callEmbedding([snippet])
except Exception as e:
logger.warning(f"CommCoach RAG embedding failed: {e}")
return None
if not response or response.errorCount > 0:
return None
embs = (response.metadata or {}).get("embeddings") or []
vec = embs[0] if embs else None
if isinstance(vec, list) and len(vec) > 0:
return vec
return None

View file

@ -229,12 +229,18 @@ WICHTIG: Antworte NUR mit dem JSON-Objekt. Kein Text vor oder nach dem JSON."""
prompt += f"\n{retrievedSession.get('summary', '')[:500]}" prompt += f"\n{retrievedSession.get('summary', '')[:500]}"
if retrievedByTopic: if retrievedByTopic:
prompt += "\n\nRelevante Sessions zum angefragten Thema:" prompt += "\n\nRelevante Sessions und Mandantenwissen zum angefragten Thema:"
for s in retrievedByTopic[:3]: for s in retrievedByTopic[:5]:
summary = s.get("summary", "") summary = s.get("summary", s.get("content", ""))
if not summary:
continue
dateStr = s.get("date", "") dateStr = s.get("date", "")
if summary: if s.get("source") == "rag":
prompt += f"\n- [{dateStr}] {summary[:300]}" label = s.get("ragSourceLabel") or "Mandantenwissen"
prompt += f"\n- [Wissen: {label}] {summary[:320]}"
else:
prefix = f"[{dateStr}] " if dateStr else ""
prompt += f"\n- {prefix}{summary[:300]}"
if openTasks: if openTasks:
prompt += "\n\nOffene Aufgaben:" prompt += "\n\nOffene Aufgaben:"