Model-visible route-change notices
模型可见的路由切换提示
Session history identifies message roles but does not tell a newly selected model which route generated earlier assistant turns. In the motivating session, the user switched from `deepseek-v4-flash` to `deepseek-v4-flash-vision-exp`. The new model saw image placeholders saying that a text-only model had omitted the images and inferred that the limitation described its own image capability.
English
Problem
Session history identifies message roles but does not tell a newly selected model which route generated earlier assistant turns. In the motivating session, the user switched from deepseek-v4-flash to deepseek-v4-flash-vision-exp. The new model saw image placeholders saying that a text-only model had omitted the images and inferred that the limitation described its own image capability.
Decision
installModelSelection compares the provider/model selection captured during prompt assembly with the latest durable request header. When they differ, it appends [model changed: assistant turns above this point were generated by <previous>; the session continues with <next>] as an identified user-role message to a downstream agent/pre-step decision that would send a model request.
Routes from the same provider use model ids; cross-provider routes use provider/model. Initial selection, unchanged routes, reasoning-effort-only changes, rejected steps, and aborted steps add no notice. An empty first decision and a decision that removes offered messages remain no-request results. An empty continuation after a tool call receives the notice because the loop would still request the model from retained history. A selection changed during pre-step processing waits for the next prompt assembly.
The accepted message is logged through the existing user/message event before the request header and therefore appears in model input, Chat, and Trajectory. The request header remains the durable record that the new route was used. If a step fails before that header is logged, the next request step repeats the notice because the durable previous route remains unchanged.
Alternatives considered
Put the notice in the system prompt. A transient prompt change would not be reconstructable from the session log and would not mark the exact point where ownership of assistant turns changed.
Create a separate package or capability. The behavior only coordinates the prompt snapshot and request route already owned by installModelSelection; it has no independent service, provider, or consumer roles.
Show the change only in the client. Client-only presentation would leave the newly selected model without the fact needed to interpret earlier assistant turns.
Consequences
Each emitted route-change notice becomes retained user-role history and consumes context tokens on later requests. A failure before request-header persistence can retain more than one identical notice. Existing session events represent the behavior, so the session format does not change.
中文
问题
会话历史会标明消息角色,但不会告诉新选中的模型,先前的 assistant 消息由哪个路由生成。在引出本改动的会话中,用户从 deepseek-v4-flash 切换到 deepseek-v4-flash-vision-exp。新模型看到图片占位文本称纯文本模型省略了图片,于是误以为该限制描述的是自己的图片能力。
决策
installModelSelection 会比较提示词组装时捕获的提供方和模型选择与最新的持久请求 header。两者不同时,它会把 [model changed: assistant turns above this point were generated by <previous>; the session continues with <next>] 作为带标识的 user 角色消息,追加到下游原本会发出模型请求的 agent/pre-step 决策中。
同一提供方的路由只使用模型 ID;跨提供方的路由使用 provider/model。首次选择、未变化的路由、仅推理强度变化、被拒绝的步骤和被取消的步骤都不会增加提示。首次空决策与移除待处理消息后得到的空决策都不会产生请求。工具调用后的空续步仍会基于保留历史请求模型,因此会收到提示。pre-step 处理期间发生的选择变更会等待下一次提示词组装。
被接纳的消息会在请求 header 前通过现有 user/message 事件落盘,因此会出现在模型输入、Chat 和 Trajectory 中。请求 header 仍是新路由已被使用的持久记录。如果步骤在该 header 落盘前失败,持久记录中的先前路由保持不变,所以下一个请求步骤会再次发出提示。
考虑过的替代方案
把提示放进系统提示词。 临时提示词变更无法从会话日志重建,也不能标出 assistant 消息由哪个模型生成的分界点。
新建单独的包或能力。 该行为只协调 installModelSelection 已经负责的提示词快照与请求路由,没有独立的服务、提供方或消费方角色。
只在客户端展示切换。 仅由客户端展示时,新选中的模型仍然缺少解释先前 assistant 消息所需的信息。
影响
每条实际发出的路由切换提示都会成为保留的 user 角色历史,并在后续请求中占用上下文 token。请求 header 落盘前发生的失败可能保留多条相同提示。该行为使用现有会话事件,因此会话格式不变。