3.2 KiB
3.2 KiB
| name | description |
|---|---|
| conversation_model_persistence | 当加载/恢复对话时发现模型未恢复,或新建对话后旧对话模型被覆盖时,应该索引本记忆 |
对话模型持久化约定
核心规则
- 每个对话的
model_key保存在对话文件的metadata.model_key中。 - 切换模型时(
/api/model)会立即调用utils/conversation_manager/ConversationManager.save_conversation(..., model_key=terminal.model_key)写入对话文件。 - 加载对话时必须恢复该对话保存的模型,不能沿用终端当前的默认模型或用户个性化默认模型。
- 创建新对话时,必须先保存旧对话、再应用默认模型到新对话,否则旧对话的
model_key会被默认模型覆盖。
关键实现点
1. 手动加载对话
路径:/api/conversations/<conversation_id>/load → core/web_terminal.py::WebTerminal.load_conversation()
- 该方法会从对话元数据中恢复
thinking_mode、permission_mode、execution_mode、network_permission等状态。 - 必须同时恢复
model_key:saved_model_key = meta.get("model_key") if saved_model_key: try: self.set_model(saved_model_key) except Exception as exc: logger.warning("加载对话模型 %s 失败: %s", saved_model_key, exc) - 恢复后,
terminal.model_key即对话保存的模型,get_status()和 API 返回的model_key都会正确。
2. 程序重启后自动恢复最近对话
路径:core/web_terminal.py::WebTerminal._ensure_conversation()
- Web 终端初始化时会自动加载最近的对话。
- 原来的实现只调用
utils/context_manager/ContextManager.load_conversation_by_id(),不会恢复model_key等运行时状态。 - 应改为调用
self.load_conversation(conv_id),以复用完整的状态恢复逻辑(含模型恢复)。
3. 创建新对话时保护旧对话的模型
路径:core/web_terminal.py::WebTerminal.create_new_conversation()
- 错误顺序:先
set_model(默认模型)→ 再start_new_conversation()→start_new_conversation()内部先save_current_conversation()→ 旧对话被按默认模型保存,覆盖了之前的模型。 - 正确顺序:
- 计算默认
run_mode、permission_mode并应用(不改model_key)。 - 调用
start_new_conversation(),此时terminal.model_key仍是旧对话的模型,旧对话被正确保存。 - 新对话创建完成后,再
set_model(默认模型),并save_conversation更新新对话的model_key。
- 计算默认
4. 前端
路径:static/src/app/methods/conversation/load.ts::loadConversation()
- 前端在调用
/api/conversations/<id>/load后,会根据返回的result.model_key更新当前模型:if (typeof result.model_key === 'string' && result.model_key) { this.modelSet(result.model_key); } - 后端修复后,返回的
model_key即为对话保存的模型,前端会自动应用。
注意事项
set_model()可能因图片/视频不兼容或模型被禁用而抛异常,加载场景下应捕获并记录警告,不要让加载失败。- 如果对话元数据中没有
model_key(旧数据或新建对话),保持当前模型即可。