fix(server): /new 页面切换模型被工作区 terminal 残留 has_images 误拦

重启后工作区级 terminal 自动加载最近对话恢复焦点时,会从其 metadata
无条件恢复 has_images/has_videos(attach_history=False 不挂历史但标志仍残留)。
/new 页面切换模型不带 conversation_id,前端守卫已放行,但后端 set_model
守卫读到残留标志误抛「当前对话包含图片」。

/api/model 端点识别 /new 语义(无 conversation_id 且 terminal 未绑定对话)时,
切换前清除残留标志——与 create_new_conversation「新对话视为干净会话」语义一致;
显式打开对话时 load_conversation_by_id 会从 metadata 重新恢复,清除安全。
This commit is contained in:
JOJO 2026-08-26 10:23:01 +08:00
parent 2d9b4eb5a6
commit d5a7c94c8e

View File

@ -207,6 +207,21 @@ def update_model(terminal: WebTerminal, workspace: UserWorkspace, username: str)
"message": "被管理员强制禁用"
}), 403
# /new 页面语义:请求未携带 conversation_id 且为工作区级 terminal 时,
# 用户处于“待创建干净新对话”状态。此时 terminal 上的 has_images/has_videos
# 是启动时自动加载最近对话留下的残留焦点状态attach_history=False不持历史
# 不代表任何用户正在编辑的对话,不应拦截模型切换——与 create_new_conversation
# “新对话视为干净会话,清除图片限制”的语义一致。清除是安全的:
# 之后显式打开对话时 load_conversation_by_id 会从 metadata 重新恢复。
requested_cid = str(data.get("conversation_id") or "").strip()
if requested_cid and not requested_cid.startswith("conv_"):
requested_cid = f"conv_{requested_cid}"
if not requested_cid and not getattr(terminal, "_bound_conversation_id", None):
_new_ctx = getattr(terminal, "context_manager", None)
if _new_ctx is not None:
_new_ctx.has_images = False
_new_ctx.has_videos = False
terminal.set_model(model_key)
# fast-only 时 run_mode 可能被强制为 fast
session["model_key"] = terminal.model_key
@ -219,9 +234,6 @@ def update_model(terminal: WebTerminal, workspace: UserWorkspace, username: str)
# 盲目保存会把模型写到错误对话,或用陈旧 history 覆盖新消息。
# /new 页面(无 conversation_id不持久化新对话在首个任务时
# 由前端随任务传入的 model_key 落盘。
requested_cid = str(data.get("conversation_id") or "").strip()
if requested_cid and not requested_cid.startswith("conv_"):
requested_cid = f"conv_{requested_cid}"
ctx = terminal.context_manager
current_cid = getattr(ctx, "current_conversation_id", None)
if requested_cid and current_cid: