ForcePilot/backend/package/yuxi/channels/adapters/yuanbao/doc_gen.py
Kris eb25707668 feat(yuanbao): 新增元宝渠道适配器完整实现
新增元宝(Yuanbao)渠道的完整适配器实现,包含以下核心模块:
- 基础适配器与导出入口
- 协议编解码与WebSocket帧处理
- 会话管理与路由逻辑
- 事件队列与出站消息队列
- 消息格式转换与发送重试
- 安全审计与权限校验
- 配置映射与账户管理
- 视觉分析与工具函数
- 文档生成与设置向导
2026-05-12 00:52:20 +08:00

146 lines
6.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from __future__ import annotations
from dataclasses import dataclass, field
from yuxi.channels.capabilities import ChannelCapabilities
from yuxi.channels.meta import ChannelMeta
@dataclass
class ChannelDocSection:
title: str
content: str
subsections: list[ChannelDocSection] = field(default_factory=list)
YUANBAO_CONFIG_KEYS: dict[str, str] = {
"app_key": "应用 Key支持 ${ENV_VAR} 环境变量引用)",
"app_secret": "应用 Secret支持 ${ENV_VAR} 环境变量引用)",
"bot_app_id": "Bot 应用 ID",
"token": "预签名 Token跳过自动签名流程",
"apiBase": "API 基础域名(顶级)",
"ws_url": "WebSocket 连接地址",
"ws_max_reconnect": "WebSocket 最大重连次数",
"ws_ping_interval": "WebSocket 心跳间隔(秒)",
"ws_ping_timeout": "WebSocket 心跳超时(秒)",
"ws_close_timeout": "WebSocket 关闭超时(秒)",
"ws_auth_timeout": "WebSocket 认证超时(秒)",
"dm_policy": "DM 策略open/pairing/allowlist/disabled",
"allow_from": "DM 白名单(支持 * 通配)",
"requireMention": "群聊是否需要 @机器人",
"overflowPolicy": "溢出策略split/stop",
"replyToMode": "引用回复模式off/first/all",
"outboundQueueStrategy": "出站队列策略merge-text/immediate",
"minChars": "merge-text 最小合并字符数",
"maxChars": "merge-text 最大合并字符数",
"idleMs": "merge-text 空闲等待毫秒数",
"mediaMaxMb": "媒体最大大小MB",
"historyLimit": "群聊历史上下文限制",
"disableBlockStreaming": "禁用块级流式输出",
"fallbackReply": "回退回复内容",
"markdownHintEnabled": "启用 Markdown 提示注入",
"debugBotIds": "调试 Bot ID 列表",
"defaultAccount": "默认账户 ID",
"maxConcurrency": "最大并发发送数",
"routeEnv": "路由环境标识(顶级)",
"accounts.<id>.appKey": "账户级 App Key",
"accounts.<id>.appSecret": "账户级 App Secret",
"accounts.<id>.enabled": "账户启用状态",
"accounts.<id>.name": "账户名称",
"accounts.<id>.token": "账户级预签名 Token",
"accounts.<id>.apiDomain": "账户级 API 域名",
"accounts.<id>.wsUrl": "账户级 WebSocket 地址",
"accounts.<id>.logUploadApiUrl": "账户级日志上传 API URL",
"accounts.<id>.routeEnv": "账户级路由环境标识",
"groups.<id>.requireMention": "群组级是否需要 @机器人",
"groups.<id>.enabled": "群组级启用状态",
}
def generate_channel_docs(
channel_id: str,
capabilities: ChannelCapabilities,
meta: ChannelMeta,
config_keys: dict[str, str] | None = None,
) -> str:
config_keys = config_keys or YUANBAO_CONFIG_KEYS
lines = [
f"# {meta.label} ({channel_id})",
"",
f"> {meta.blurb}",
"",
"## 基本信息",
"",
f"- **渠道 ID**: `{channel_id}`",
f"- **别名**: {', '.join(f'`{a}`' for a in meta.aliases) if meta.aliases else ''}",
f"- **支持的聊天类型**: {', '.join(capabilities.chat_types)}",
f"- **投递模式**: {capabilities.delivery_mode}",
f"- **排序权重**: {meta.order}",
"",
"## 能力矩阵",
"",
_capability_table(capabilities),
"",
"## 消息类型支持",
"",
_message_type_section(capabilities),
"",
"## 流式输出",
"",
f"- **支持流式输出**: {'' if capabilities.supports_streaming else ''}",
f"- **流式模式**: {', '.join(capabilities.streaming_modes)}",
f"- **Block Streaming**: {'支持' if capabilities.block_streaming else '不支持'}",
f"- **Lane Streaming**: {'支持' if capabilities.lane_streaming else '不支持'}",
f"- **Reasoning Streaming**: {'支持' if capabilities.reasoning_streaming else '不支持'}",
f"- **Markdown 支持**: {'' if capabilities.supports_markdown else ''}",
f"- **文本分块限制**: {capabilities.text_chunk_limit} 字符",
f"- **媒体大小限制**: {capabilities.max_media_size_mb} MB",
]
if config_keys:
lines.extend(["", "## 配置项参考", "", _config_table(config_keys)])
return "\n".join(lines)
def _capability_table(caps: ChannelCapabilities) -> str:
rows = [
"| 能力 | 状态 |",
"|------|:--:|",
f"| 媒体消息 | {'' if caps.media else ''} |",
f"| 消息回复 | {'' if caps.reply else ''} |",
f"| 消息编辑 | {'' if caps.edit else ''} |",
f"| 消息撤回 | {'' if caps.unsend else ''} |",
f"| 反应 | {'' if caps.reactions else ''} |",
f"| 投票 | {'' if caps.polls else ''} |",
f"| 线程 | {'' if caps.threads else ''} |",
f"| 群组管理 | {'' if caps.group_management else ''} |",
f"| 置顶 | {'' if caps.pin else ''} |",
f"| 取消置顶 | {'' if caps.unpin else ''} |",
f"| 消息特效 | {'' if caps.effects else ''} |",
f"| TTS 语音 | {'' if caps.tts.voice.enabled else ''} |",
f"| 原生命令 | {'' if caps.native_commands else ''} |",
f"| 阅后即焚 | {'' if caps.send_ephemeral else ''} |",
]
return "\n".join(rows)
def _message_type_section(caps: ChannelCapabilities) -> str:
return (
f"- **文本**: 支持\n"
f"- **媒体(图片/文件/音频/视频/贴纸)**: {'支持' if caps.media else '不支持'}\n"
f"- **Markdown**: {'支持' if caps.supports_markdown else '不支持'}\n"
f"- **投票**: {'支持' if caps.polls else '不支持'}\n"
f"- **TTS**: {'支持' if caps.tts.voice.enabled else '不支持'}"
)
def _config_table(config_keys: dict[str, str]) -> str:
rows = [
"| 配置键 | 说明 |",
"|--------|------|",
]
for key, desc in config_keys.items():
rows.append(f"| `{key}` | {desc} |")
return "\n".join(rows)