Skip to content

Latest commit

 

History

History
115 lines (84 loc) · 5.04 KB

File metadata and controls

115 lines (84 loc) · 5.04 KB

bot/ — 钉钉/飞书 Bot

职责

钉钉与飞书 Stream 长连接客户端,接收用户消息,分发到命令处理器。所有跨层数据类(BotMessage / ChatType)来自 stocklens.contracts,本目录仅作 re-export。

文件清单

根目录

文件 职责
__init__.py 导出
dispatcher.py 命令分发入口(被 platforms 调用);RateLimiter 现已包装 limits.MovingWindowRateLimiter(slowapi 间接依赖),自动回收离线用户 key
models.py BotResponse / WebhookResponse + re-export BotMessage / ChatType

BotMessageChatType 的真实定义在 stocklens/contracts/bot_message.py,本文件保留 re-export 是为了向后兼容旧代码 from bot.models import BotMessage。详见 contracts.md

platforms/

文件 职责
base.py Bot 平台抽象
dingtalk.py 钉钉客户端(HTTP webhook)
dingtalk_stream.py 钉钉 Stream 长连接
feishu_stream.py 飞书 Stream 长连接

commands/

文件 职责
base.py Command 基类
help.py /help 帮助
status.py /status 系统状态
analyze.py /analyze <代码> 单股分析
batch.py /batch 批量分析
ask.py /ask <代码> [策略] Agent 分析
chat.py /chat <消息> AI 对话

核心类

BotMessage(来自 stocklens.contracts

跨平台统一消息模型。字段:platform / message_id / user_id / user_name / chat_id / chat_type / content / raw_content / mentioned / mentions / timestamp / raw_data

提供 get_command_and_args(prefix='/') 解析命令;中文别名(分析 / 大盘 / 批量 / 帮助 / 状态)也支持。

BotResponse / WebhookResponse

只在 bot 包内部使用,不入核心层:

BotResponse(text, markdown, at_user, reply_to_message, extra)
BotResponse.text_response(text)
BotResponse.markdown_response(text)
BotResponse.error_response(message)

WebhookResponse(status_code, body, headers)
WebhookResponse.success(body)
WebhookResponse.challenge(challenge)
WebhookResponse.error(message)

Stream Bot(dingtalk_stream / feishu_stream)

  • start() — 启动长连接
  • on_message(...) — 消息回调;归一化为 BotMessagedispatcher.dispatch()
  • send_reply(...) — 平台原生回复

命令分发

# bot/dispatcher.py 接收 BotMessage
# 解析命令前缀 → 路由到 commands/<name>.py 处理器

支持的命令:

命令 处理器 说明
/help help.py 显示帮助
/status status.py 系统状态(数据源/LLM/任务队列)
/analyze <代码> analyze.py 单股分析(调用 Pipeline.analyze_stock)
/batch batch.py 批量分析(STOCK_LIST 中所有股票)
/ask <代码> [策略] ask.py Agent 分析
/chat <消息> chat.py AI 自由对话

依赖关系

  • 依赖:dingtalk-stream(可选)、lark-oapi(可选)、stocklens.contractsstocklens.configstocklens.pipelinestocklens.agentstocklens.servicesstocklens.notification(formatting 工具)
  • 被依赖:main.py(start_bot_stream_clients)

配置项

变量 默认 说明
DINGTALK_APP_KEY None 钉钉应用 Key
DINGTALK_APP_SECRET None 钉钉应用 Secret
DINGTALK_STREAM_ENABLED false 启用钉钉 Stream
FEISHU_APP_ID None 飞书应用 ID
FEISHU_APP_SECRET None 飞书应用 Secret
FEISHU_STREAM_ENABLED false 启用飞书 Stream
AGENT_NL_ROUTING false 自然语言路由(用 LLM 判断意图)

注意事项

  • dingtalk-streamlark-oapi 是可选依赖,未装时 Bot 不可用

  • Stream 模式是长连接,不需要公网 IP / Webhook

  • 自然语言路由会用 LLM 判断意图,消耗 token

  • 长消息会按平台限制截断

  • /chat 会话独立维护,进程重启后会话丢失

  • 不要stocklens/ 核心层直接 from bot.models import BotMessage;改用 from stocklens.contracts import BotMessage

  • 2026-05 修复bot/models.py 之前 BotResponse / WebhookResponse 各被定义了两次(第二份覆盖第一份),统一为单一定义;同时把 error_responsef"❌ 错误:{message}"(中文+emoji)改为 f"[ERROR] {message}",符合 CLAUDE.md 第 2 铁律(源代码全英文)

  • 2026-05 G9 — 股票代码校验抽到 contracts/stock_code.pyAnalyzeCommand.validate_args 之前内联了 3 条正则(A 股 6 位数字 / 港股 HK + 5 位 / 美股 1-5 字母可带 .X 后缀)+ 中文错误模板字符串。现在用 stocklens.contracts.validate_user_stock_code(code) → Optional[error_msg] —— bot 层不再持有验证规则,跨层 contract 单一来源。is_valid_user_stock_code(code) 同样导出,可被 API/CLI 复用。回归测试 tests/unit/test_contracts_stock_code.py(26 用例:A 股 / HK / US / 大小写混入 / 非法字符 / 边界长度)。