ForcePilot/backend/package/yuxi/channel/extensions/confluence/knowledge.py
Kris f943c31ce4 feat(confluence): 新增Confluence渠道插件完整实现
新增了完整的Confluence集成插件,包含以下核心功能:
1.  基础认证与配置管理,支持API Token和OAuth2两种认证方式
2.  评论去重、权限控制与提及解析
3.  知识库检索与页面内容处理
4.  评论收发、编辑删除与流式回复支持
5.  附件与页面标签管理
6.  内容属性存储与AI元数据管理
7.  Webhook事件接收与处理
8.  完整的插件配置与状态检查
2026-05-21 10:43:42 +08:00

68 lines
2.1 KiB
Python

import logging
from yuxi.channel.extensions.confluence.format import extract_text_from_adf
from yuxi.channel.extensions.confluence.gateway import ConfluenceGateway
from yuxi.channel.extensions.confluence.search import CQLBuilder
logger = logging.getLogger(__name__)
class ConfluenceKnowledge:
def __init__(self, gateway: ConfluenceGateway):
self._gateway = gateway
async def retrieve_context(
self,
query: str,
account_id: str = "default",
space_keys: list[str] | None = None,
max_pages: int = 5,
) -> list[dict]:
client = self._gateway.get_client(account_id)
if client is None:
return []
cql = CQLBuilder.search_pages(query, space_keys)
try:
results = await client.cql_search(cql, limit=max_pages)
except Exception as e:
logger.error("CQL search failed for context retrieval '%s': %s", query, e)
return []
contexts = []
for item in results.get("results", []):
content = item.get("content", {})
page_id = content.get("id")
title = content.get("title", "")
body = content.get("body", {})
adf_value = body.get("view", {}).get("value", "")
text = extract_text_from_adf(adf_value) if adf_value else ""
contexts.append({
"page_id": page_id,
"title": title,
"text": text[:2000],
"url": content.get("_links", {}).get("base", ""),
})
return contexts
async def build_context_note(
self,
page_context,
account_id: str = "default",
) -> str:
if page_context is None:
return ""
client = self._gateway.get_client(account_id)
if client is None:
return ""
try:
page = await client.get_page(page_context.page_id)
title = page.get("title", "")
return f"当前页面: [{page_context.space_key}] {title}"
except Exception:
return f"当前页面: {page_context.context_label}"