ForcePilot/backend/package/yuxi/channels/adapters/mattermost/send.py
Kris 002d601d1b feat(mattermost): 实现完整的 Mattermost 适配器模块
新增 Mattermost 渠道完整实现,包含适配器核心、消息处理、交互回调、命令支持、安全校验、多账号管理等功能,支持机器人消息发送、交互按钮、命令注册、投票功能以及配置动态修改等特性。
2026-05-12 00:46:12 +08:00

92 lines
2.5 KiB
Python

from __future__ import annotations
from typing import Any
from yuxi.channels.models import ChannelResponse
_PARAGRAPH_SEP = "\n\n"
_DEFAULT_CHUNK_LIMIT = 16383
def build_post_options(response: ChannelResponse) -> dict[str, Any]:
return {
"channel_id": response.identity.channel_chat_id,
"message": response.content,
"root_id": response.reply_to_message_id or "",
"props": response.metadata.get("props", {}),
"file_ids": response.metadata.get("file_ids", []),
}
def build_patch_options(chunk_text: str) -> dict[str, Any]:
return {"message": chunk_text}
def chunk_text_for_outbound(text: str, limit: int = _DEFAULT_CHUNK_LIMIT) -> list[str]:
"""按段落边界将文本拆分为不超过 limit 的分块。
优先在双换行符(段落)边界拆分;如果单段仍超限,
则在单换行符(行)边界拆分;如果单行仍超限,则硬截断。
"""
if len(text) <= limit:
return [text]
chunks: list[str] = []
paragraphs = text.split(_PARAGRAPH_SEP)
current = ""
for para in paragraphs:
if len(para) > limit:
if current:
chunks.append(current.rstrip())
current = ""
chunks.extend(_split_by_lines(para, limit))
continue
candidate = f"{current}{_PARAGRAPH_SEP}{para}" if current else para
if len(candidate) > limit:
chunks.append(current.rstrip())
current = para
else:
current = candidate
if current:
chunks.append(current.rstrip())
if not chunks:
chunks.append(text[:limit])
return chunks
def _split_by_lines(text: str, limit: int) -> list[str]:
"""在换行符边界拆分超限段落。"""
chunks: list[str] = []
lines = text.split("\n")
current = ""
for line in lines:
if len(line) > limit:
if current:
chunks.append(current.rstrip())
current = ""
chunks.extend(_split_hard(line, limit))
continue
candidate = f"{current}\n{line}" if current else line
if len(candidate) > limit:
chunks.append(current.rstrip())
current = line
else:
current = candidate
if current:
chunks.append(current.rstrip())
return chunks
def _split_hard(text: str, limit: int) -> list[str]:
"""硬截断超长行。"""
return [text[i : i + limit] for i in range(0, len(text), limit)]