feat(CF-1812): Use confluence-collab for section-based page editing

Replace inline regex section parser in voice.py with confluence_collab
library (BS4 parsing, 409 conflict retry). Bot now loads section outline
into LLM context when Confluence links are detected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-24 11:37:37 +02:00
parent 3e60e822be
commit 9e146da3b0
6 changed files with 52 additions and 64 deletions

36
bot.py
View File

@@ -857,20 +857,42 @@ class Bot:
except Exception as exc:
logger.warning("Confluence short link resolution failed: %s", exc)
if confluence_page_id:
# Fetch actual page content so the text bot can work with it
# Fetch page with section structure for targeted editing
conf_text = f"confluence_page_id:{confluence_page_id}"
conf_title = f"Confluence page {confluence_page_id}"
if CONFLUENCE_URL and CONFLUENCE_USER and CONFLUENCE_TOKEN:
try:
from voice import _confluence_read_page
title, plain, _ver = await _confluence_read_page(confluence_page_id)
conf_title = title
conf_text = f"confluence_page_id:{confluence_page_id}\n\nTitle: {title}\n\n{plain}"
logger.info("Fetched Confluence page %s: %s (%d chars)",
confluence_page_id, title, len(plain))
from confluence_collab.client import Auth, get_page
from confluence_collab.parser import parse_sections
auth = Auth(base_url=CONFLUENCE_URL, username=CONFLUENCE_USER, api_token=CONFLUENCE_TOKEN)
page = await get_page(confluence_page_id, auth)
conf_title = page.title
sections = parse_sections(page.body_html)
section_outline = "\n".join(
f"{' ' * (s.level - 1)}h{s.level}: {s.heading}" for s in sections
)
# Strip HTML for plain text context
plain = re.sub(r"<[^>]+>", " ", page.body_html)
plain = re.sub(r"\s+", " ", plain).strip()
conf_text = (
f"confluence_page_id:{confluence_page_id}\n\n"
f"Title: {page.title}\n\n"
f"Sections:\n{section_outline}\n\n"
f"{plain}"
)
logger.info("Fetched Confluence page %s: %s (%d chars, %d sections)",
confluence_page_id, page.title, len(plain), len(sections))
except Exception as exc:
logger.warning("Confluence page fetch failed for %s: %s",
confluence_page_id, exc)
# Fallback to voice.py reader
try:
from voice import _confluence_read_page
title, plain, _ver = await _confluence_read_page(confluence_page_id)
conf_title = title
conf_text = f"confluence_page_id:{confluence_page_id}\n\nTitle: {title}\n\n{plain}"
except Exception:
pass
docs = self._room_document_context.setdefault(room.room_id, [])
docs.append({
"type": "confluence",