From c6e38026ecc242e62b7eb29855bc307783527ff0 Mon Sep 17 00:00:00 2001 From: "Yuyao Huang (Sam)" Date: Sun, 29 Mar 2026 18:38:23 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=B6=88=E6=81=AF=E9=80=9A=E7=9F=A5):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=AF=B9markdown=E6=A0=BC=E5=BC=8F=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增send_markdown函数用于发送富文本格式消息,替换原有send_text调用以支持代码块、标题等格式内容显示。自动分割长消息为多个卡片发送,提升消息展示效果。 --- bot/feishu.py | 27 +++++++++++++++++++++++++++ bot/handler.py | 6 +++--- router/rpc.py | 4 ++-- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/bot/feishu.py b/bot/feishu.py index cf1f415..63505c9 100644 --- a/bot/feishu.py +++ b/bot/feishu.py @@ -108,6 +108,33 @@ async def send_text(receive_id: str, receive_id_type: str, text: str) -> None: await asyncio.sleep(0.3) +async def send_markdown(receive_id: str, receive_id_type: str, content: str) -> None: + """ + Send a markdown card message. Used for LLM/agent replies that contain + formatted text (code blocks, headings, bold, lists, etc.). + + Automatically splits long content into multiple cards. + """ + parts = _split_message(content) + + for i, part in enumerate(parts): + card = { + "schema": "2.0", + "body": { + "elements": [ + { + "tag": "markdown", + "content": part, + } + ] + } + } + await send_card(receive_id, receive_id_type, card) + + if len(parts) > 1 and i < len(parts) - 1: + await asyncio.sleep(0.3) + + async def send_card(receive_id: str, receive_id_type: str, card: dict) -> None: """ Send an interactive card message. diff --git a/bot/handler.py b/bot/handler.py index 54e7741..321f5f5 100644 --- a/bot/handler.py +++ b/bot/handler.py @@ -13,7 +13,7 @@ import lark_oapi as lark from lark_oapi.api.im.v1 import P2ImMessageReceiveV1 from bot.commands import handle_command -from bot.feishu import send_text +from bot.feishu import send_text, send_markdown from config import FEISHU_APP_ID, FEISHU_APP_SECRET, is_user_allowed from orchestrator.agent import agent from orchestrator.tools import set_current_chat @@ -177,14 +177,14 @@ async def _process_message(user_id: str, chat_id: str, text: str) -> None: try: reply = await forward(node_id, user_id, chat_id, text) if reply: - await send_text(chat_id, "chat_id", reply) + await send_markdown(chat_id, "chat_id", reply) except Exception as e: logger.exception("Failed to forward to node %s", node_id) await send_text(chat_id, "chat_id", f"Error communicating with node: {e}") else: reply = await agent.run(user_id, text) if reply: - await send_text(chat_id, "chat_id", reply) + await send_markdown(chat_id, "chat_id", reply) except Exception: logger.exception("Error processing message for user %s", user_id) diff --git a/router/rpc.py b/router/rpc.py index d319f95..6e920c7 100644 --- a/router/rpc.py +++ b/router/rpc.py @@ -96,10 +96,10 @@ async def handle_task_complete(msg: TaskComplete) -> None: """Handle a task completion notification from a host client.""" logger.info("Task %s completed for user %s", msg.task_id, msg.user_id) - from bot.feishu import send_text + from bot.feishu import send_markdown try: - await send_text(msg.chat_id, "chat_id", msg.result) + await send_markdown(msg.chat_id, "chat_id", msg.result) except Exception as e: logger.error("Failed to send task completion notification: %s", e)