Phase 2.3 chat 上下文捕获链路从未真正激活到完整工作: - 14 处 ai-float-button 补 sourcePage,chat.ts 三分支同步设 pageFilters.contextId - 后端 page_context 4 层 BUG 修(列名错位 + RLS site_id 未重设) - xcx_chat filters.pop 破坏 body.page_context 引用 — dict() 浅拷贝隔离 - chat 流式 markdown 实时解析(表格/标题/列表/加粗 + KPI 富卡) - reference_card KPI 富卡接入 SSE 路径,db 真写入 - 维客线索 source 显示规则:AI 来源用机器人 icon 替代长文字 数据库: - public.member_retention_clue 加 emoji + runtime_mode + sandbox_instance_id - biz.ai_run_logs 加 assistant_id + 复合索引 - chk_ai_cache_type CHECK 约束 8 类应用名 - cache_type / app_type 命名统一(app6_note / app7_customer / app8_consolidation) - 历史 emoji 抽取脚本 44/44 成功 后端 silent failure 修: - cleanup_service WHERE app_type → cache_type(90 天清理 + 20K 上限重新生效) - _build_ai_insight 字段错位修复(app4 → app7 + 字段对齐 prompt schema) - task_manager talkingPoints 改 app5_tactics + tactics 字段 - task_manager aiSuggestion 改取 one_line_summary - cache_service.CACHE_EXPIRY_DAYS 加 app2a_finance_area - WS /ws/ai-cache 加 token + JWT + site_id 校验(P0 信息泄露漏洞) - internal_ai token 改 hmac.compare_digest 工具/文档: - main.py 加 RotatingFileHandler logs/backend.log + uvicorn /health 过滤 - 新建 utils/clue_category.py(VI 6 类配色 + emoji fallback + source 显示规则) - 新建 utils/markdown.ts(轻量 md 转 rich-text 解析 + streaming 容错) - audit + 数据库变更说明 + backlog §七 #14 收口 + #15-#38 残余子任务 - backlog 追加 §十一 App1 参数/MCP/沙箱审计 + §十二 百炼/SQL MCP 主任务线 实地 MCP 走查:14 入口数据层 + 5 代表入口 sourcePage 注入 + customer-detail 全模块 + chat md 渲染 + reference_card 富卡 都已验证。9 项预先 BUG/UX 登记 §七 #29-#38 后续修复。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
166 lines
3.4 KiB
Python
166 lines
3.4 KiB
Python
"""AI 集成层 Pydantic 模型定义。
|
||
|
||
覆盖请求/响应体、缓存类型枚举、线索模型、各应用结果模型。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import enum
|
||
|
||
from pydantic import BaseModel, Field
|
||
|
||
|
||
# ── 请求/响应 ──
|
||
|
||
|
||
class ChatStreamRequest(BaseModel):
|
||
"""SSE 流式对话请求体"""
|
||
|
||
message: str
|
||
source_page: str | None = None
|
||
page_context: dict | None = None
|
||
screen_content: str | None = None
|
||
|
||
|
||
class SSEEvent(BaseModel):
|
||
"""SSE 事件"""
|
||
|
||
type: str # chunk / done / error
|
||
content: str | None = None
|
||
conversation_id: int | None = None
|
||
tokens_used: int | None = None
|
||
message: str | None = None
|
||
|
||
|
||
# ── 缓存类型枚举 ──
|
||
|
||
|
||
class CacheTypeEnum(str, enum.Enum):
|
||
"""ai_cache.cache_type 允许的取值(8 类,与 prompt 文件名 + 数据库 chk_ai_cache_type
|
||
约束完全对齐;app1_chat 走 ai_messages 不进缓存)。
|
||
|
||
W1-AI-CLOSURE 组 1 命名统一:旧名字 app6_note_analysis / app7_customer_analysis /
|
||
app8_clue_consolidated / app8_consolidate 已在数据库迁移中清理,代码不再使用。
|
||
"""
|
||
|
||
APP2_FINANCE = "app2_finance"
|
||
APP2A_FINANCE_AREA = "app2a_finance_area"
|
||
APP3_CLUE = "app3_clue"
|
||
APP4_ANALYSIS = "app4_analysis"
|
||
APP5_TACTICS = "app5_tactics"
|
||
APP6_NOTE = "app6_note"
|
||
APP7_CUSTOMER = "app7_customer"
|
||
APP8_CONSOLIDATION = "app8_consolidation"
|
||
|
||
|
||
# ── 线索相关 ──
|
||
|
||
|
||
class App3CategoryEnum(str, enum.Enum):
|
||
"""App3 线索分类(3 个枚举值)"""
|
||
|
||
CUSTOMER_BASIC = "客户基础"
|
||
CONSUMPTION_HABIT = "消费习惯"
|
||
PLAY_PREFERENCE = "玩法偏好"
|
||
|
||
|
||
class App6CategoryEnum(str, enum.Enum):
|
||
"""App6/8 线索分类(6 个枚举值)"""
|
||
|
||
CUSTOMER_BASIC = "客户基础"
|
||
CONSUMPTION_HABIT = "消费习惯"
|
||
PLAY_PREFERENCE = "玩法偏好"
|
||
PROMO_PREFERENCE = "促销偏好"
|
||
SOCIAL_RELATION = "社交关系"
|
||
IMPORTANT_FEEDBACK = "重要反馈"
|
||
|
||
|
||
class ClueItem(BaseModel):
|
||
"""单条线索(App3/App6 共用)"""
|
||
|
||
category: str
|
||
summary: str
|
||
detail: str
|
||
emoji: str
|
||
|
||
|
||
class ConsolidatedClueItem(BaseModel):
|
||
"""整合后线索(App8,含 providers)"""
|
||
|
||
category: str
|
||
summary: str
|
||
detail: str
|
||
emoji: str
|
||
providers: str
|
||
|
||
|
||
# ── 各应用结果模型 ──
|
||
|
||
|
||
class App2InsightItem(BaseModel):
|
||
"""App2 财务洞察单条"""
|
||
|
||
seq: int
|
||
title: str
|
||
body: str
|
||
|
||
|
||
class App2Result(BaseModel):
|
||
"""App2 财务洞察结果"""
|
||
|
||
insights: list[App2InsightItem]
|
||
|
||
|
||
class App3Result(BaseModel):
|
||
"""App3 客户数据维客线索结果"""
|
||
|
||
clues: list[ClueItem]
|
||
|
||
|
||
class App4Result(BaseModel):
|
||
"""App4 关系分析结果"""
|
||
|
||
task_description: str
|
||
action_suggestions: list[str]
|
||
one_line_summary: str
|
||
|
||
|
||
class App5TacticsItem(BaseModel):
|
||
"""App5 话术单条"""
|
||
|
||
scenario: str
|
||
script: str
|
||
|
||
|
||
class App5Result(BaseModel):
|
||
"""App5 话术参考结果"""
|
||
|
||
tactics: list[App5TacticsItem]
|
||
|
||
|
||
class App6Result(BaseModel):
|
||
"""App6 备注分析结果"""
|
||
|
||
score: int = Field(ge=1, le=10)
|
||
clues: list[ClueItem]
|
||
|
||
|
||
class App7StrategyItem(BaseModel):
|
||
"""App7 客户分析策略单条"""
|
||
|
||
title: str
|
||
content: str
|
||
|
||
|
||
class App7Result(BaseModel):
|
||
"""App7 客户分析结果"""
|
||
|
||
strategies: list[App7StrategyItem]
|
||
summary: str
|
||
|
||
|
||
class App8Result(BaseModel):
|
||
"""App8 维客线索整理结果"""
|
||
|
||
clues: list[ConsolidatedClueItem]
|