2.8 KiB
2.8 KiB
| name | description |
|---|---|
| conversation_model_persistence | 当加载/恢复对话时发现模型未恢复、新建对话后旧对话模型被覆盖、或修改 /api/model、_apply_workspace_personalization_preferences 时,应该索引本记忆 |
name: conversation_model_persistence description: 当加载/恢复对话时发现模型未恢复、新建对话后旧对话模型被覆盖、或修改 /api/model、_apply_workspace_personalization_preferences 时,应该索引本记忆
对话模型持久化约定(对话级隔离架构版)
核心规则
- 每个对话的
model_key保存在对话文件的metadata.model_key。 - 对话级 terminal(
_bound_conversation_id非空)的模型由绑定加载权威恢复(WebTerminal._ensure_conversation用restore_model=True),其它任何逻辑不得覆盖它。 - 工作区级 terminal(未绑定)刻意
restore_model=False自动加载最近对话:避免 /new 页面显示旧对话模型。
四条关键防线(2026-07-20 修复,commit 1289c31d)
core/web_terminal.py::_ensure_conversation:绑定路径load_conversation(bound_id, restore_model=True)。工作区自动加载路径保持restore_model=False。server/chat/settings.py::/api/model:仅当请求显式携带conversation_id且与 terminalcurrent_conversation_id一致时才save_conversation;无 cid(/new 页面)不持久化——工作区级 terminal 的 current 可能是陈旧对话,盲存会把模型写错对话或用陈旧 history 覆盖新消息。- 前端
static/src/app/methods/ui/model.ts::handleModelSelect:POST /api/model 必须带conversation_id: this.currentConversationId。 server/context.py::_apply_workspace_personalization_preferences:对_bound_conversation_id非空的 terminal 跳过 session 模型恢复与 default_model 应用——否则 session 里的全局模型会把对话级 terminal 恢复好的模型再盖掉(重启后回变默认的直接元凶)。
会话级语义
session["model_key"]是全局"用户最后选择的模型":用于工作区级 terminal 恢复与 /new 继承,不代表任何具体对话的模型。- 任务创建时前端随任务传
model_key(send.ts),server/tasks/models.py在任务起点terminal.set_model(rec.model_key)——前端是任务模型的权威来源。 set_model()可能因图片/视频不兼容或模型被禁用抛异常,加载场景应捕获降级。- 管理员强制禁用模型的切换(context.py 406/549 行附近)对对话级 terminal 仍然生效,属正当覆盖。
验证脚本
_experiments/verify_model_fix.py:p1 全周期(带cid切换→落盘、不带cid不污染)、p2 重启后保持;另需验证GET /api/status?conversation_id=X返回对话保存模型。