放置核心层(stocklens/)和适配层(bot/、api/)共享的数据类,避免核心反向依赖适配器(层级倒挂)。
| 文件 | 职责 |
|---|---|
__init__.py |
导出所有契约类型 |
bot_message.py |
BotMessage 数据类、ChatType 枚举 |
protocols.py |
跨层 Protocol 定义(LLMAnalyzerProto / AsyncLLMAnalyzerProto / CacheProto / NotifierProto / SearchServiceProto / DataFetcherManagerProto) |
stock_code.py |
2026-05 G9 新增 — 用户输入侧的股票代码 shape 校验(is_valid_user_stock_code / validate_user_stock_code) |
核心层 NEVER 依赖适配层。 反过来:适配层(bot 平台、API endpoint)引用 contracts,把平台原生数据归一化成契约类型后再交给 pipeline。
跨平台统一消息模型。Pipeline 用 source_message: Optional[BotMessage] 携带"是谁触发了这次分析"上下文。
字段:platform / message_id / user_id / user_name / chat_id / chat_type / content / raw_content / mentioned / mentions / timestamp / raw_data
GROUP / PRIVATE / UNKNOWN 三种聊天类型。
6 个 runtime_checkable Protocol 用于跨层依赖注入,所有签名都基于 duck typing:
| 名称 | 用途 |
|---|---|
LLMAnalyzerProto |
同步 LLM 分析器(analyze / is_available) |
AsyncLLMAnalyzerProto |
异步 LLM 分析器(aanalyze / is_available) |
CacheProto |
最小缓存接口(get / set) |
NotifierProto |
通知派发接口 |
SearchServiceProto |
股票领域搜索接口 |
DataFetcherManagerProto |
多源数据 fetcher 管理 |
| 函数 | 用途 |
|---|---|
is_valid_user_stock_code(code: str) → bool |
判断字符串是否符合用户输入侧股票代码格式(A 股 6 位 / HK + 5 位 / 美股 1-5 字母可带 .X) |
validate_user_stock_code(code: str) → Optional[str] |
通过返回 None,否则返回中文人类可读的错误提示(直接给 bot 用户看) |
bot/commands/analyze.py 已切到这两个函数,原 inline 正则全部下线。后续 API 端的 stock_code 校验可以复用同一对函数(保持跨入口一致性)。
2026-05-18之前BotMessage定义在bot/models.py,stocklens/{pipeline,notification,services}反向 import 它,造成层级倒挂。2026-05-18把BotMessage/ChatType上提到stocklens.contracts;bot/models.py改为 re-export 保持向后兼容。
| 调用点 | 用途 |
|---|---|
stocklens/pipeline/orchestrator.py |
source_message: Optional[BotMessage] |
stocklens/notification/dispatcher.py |
推送时回填会话上下文 |
stocklens/notification/report_builder.py |
报告头部记录请求方 |
stocklens/notification/context_sender.py |
会话内回复 |
stocklens/services/task_service.py |
任务队列携带原始消息 |
bot/models.py |
re-export(向后兼容旧 import) |
- 在
stocklens/contracts/新建文件(如analysis_event.py)。 __init__.py加 import +__all__。- 适配层引用它而非反过来。
- 如果是替换原本在适配层的类型,旧位置改为 re-export 保持兼容。