From 6a6f9ef1c45e504640c863dd4bfe5c37dd9ce7c6 Mon Sep 17 00:00:00 2001 From: Christian Gick Date: Mon, 23 Feb 2026 14:31:49 +0200 Subject: [PATCH] fix(voice): auto-use active Confluence page ID, allow roleplay on docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Confluence tools default to active page from room context — no more asking user for page_id - Prompt allows roleplay/mock interviews when document context present - Explicit instruction not to ask for page_id Co-Authored-By: Claude Opus 4.6 --- voice.py | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/voice.py b/voice.py index b2d400a..5685001 100644 --- a/voice.py +++ b/voice.py @@ -42,9 +42,9 @@ LLM-Modell: {model} STRIKTE Regeln: - Antworte in der Sprache des Nutzers (Deutsch oder Englisch) -- Halte JEDE Antwort auf MAXIMAL 1-2 kurze Saetze +- Halte Antworten normalerweise auf 1-2 kurze Saetze. AUSNAHME: Wenn ein Dokument geladen ist und der Nutzer Rollenspiele, Probegespraeche, Mock-Interviews oder ausfuehrliche Besprechungen wuenscht, antworte so ausfuehrlich wie noetig - Sei direkt und praezise, keine Fuellwoerter -- Erfinde NICHTS - keine Geschichten, keine Musik, keine Fantasie +- Erfinde NICHTS ausser der Nutzer bittet explizit um Rollenspiel, Probegespraech oder Simulation basierend auf dem Dokumentinhalt. In dem Fall spiele die Rolle ueberzeugend und nutze den Dokumentinhalt als Grundlage - Beantworte nur was gefragt wird - Wenn niemand etwas fragt oder du dir nicht sicher bist ob jemand mit dir spricht, SCHWEIGE. Antworte NUR auf klare, direkte Fragen oder Anweisungen. Kein Smalltalk, kein "Danke", kein "Wie kann ich helfen" von dir aus - Schreibe Zahlen und Jahreszahlen IMMER als Woerter aus (z.B. "zweitausendundzwanzig" statt "2026", "zweiundzwanzigsten Februar" statt "22. Februar") @@ -807,13 +807,24 @@ class VoiceSession: await _store_user_pref(caller_uid, "timezone", iana_timezone) return f"Timezone set to {iana_timezone}" + # Extract active Confluence page ID from document context (if any) + _active_conf_id = None + if self._document_context: + _conf_ids = re.findall(r'confluence_page_id:(\d+)', self._document_context) + if _conf_ids: + _active_conf_id = _conf_ids[0] + @function_tool - async def read_confluence_page(page_id: str) -> str: + async def read_confluence_page(page_id: str = "") -> str: """Read a Confluence page. Use when user asks to read, review, - or check a document. Returns page title and content as text.""" - logger.info("CONFLUENCE_READ: page_id=%s", page_id) + or check a document. Returns page title and content as text. + Leave page_id empty to use the active document from the room.""" + pid = page_id or _active_conf_id + if not pid: + return "No Confluence page ID available. Ask the user to share a Confluence link first." + logger.info("CONFLUENCE_READ: page_id=%s", pid) try: - title, text, _ver = await _confluence_read_page(page_id) + title, text, _ver = await _confluence_read_page(pid) result = f"Page: {title}\n\n{text}" logger.info("CONFLUENCE_READ_OK: %s (%d chars)", title, len(text)) return result @@ -822,17 +833,20 @@ class VoiceSession: return f"Failed to read page: {exc}" @function_tool - async def update_confluence_page(page_id: str, section_heading: str, new_content: str) -> str: + async def update_confluence_page(section_heading: str, new_content: str, page_id: str = "") -> str: """Update a section of a Confluence page. Use when user asks to change, update, or rewrite part of a document. - - page_id: Confluence page ID - section_heading: heading text of the section to update - new_content: new plain text for the section (will be wrapped in

tags) + - page_id: leave empty to use the active document from the room Human sees changes instantly in their browser via Live Docs.""" - logger.info("CONFLUENCE_UPDATE: page=%s section='%s'", page_id, section_heading) + pid = page_id or _active_conf_id + if not pid: + return "No Confluence page ID available. Ask the user to share a Confluence link first." + logger.info("CONFLUENCE_UPDATE: page=%s section='%s'", pid, section_heading) try: new_html = f"

{new_content}

" - result = await _confluence_update_section(page_id, section_heading, new_html) + result = await _confluence_update_section(pid, section_heading, new_html) logger.info("CONFLUENCE_UPDATE_OK: %s", result) return result except Exception as exc: @@ -842,10 +856,8 @@ class VoiceSession: instructions = _build_voice_prompt(model=self.model, timezone=user_timezone) + memory_section if self._document_context: instructions += f"\n\nDokument-Kontext (im Raum hochgeladen):\n{self._document_context}" - # Extract Confluence page IDs from document context for tool use - conf_ids = re.findall(r'confluence_page_id:(\d+)', self._document_context) - if conf_ids: - instructions += f"\n\nAktive Confluence-Seite(n): {', '.join(conf_ids)}. Nutze diese page_id fuer read_confluence_page und update_confluence_page." + if _active_conf_id: + instructions += f"\n\nAktive Confluence-Seite: {_active_conf_id}. Du brauchst den Nutzer NICHT nach der page_id zu fragen — nutze automatisch diese ID fuer read_confluence_page und update_confluence_page." agent = _NoiseFilterAgent( instructions=instructions, tools=[search_web, set_user_timezone, read_confluence_page, update_confluence_page],