fix(server): Claude reports Fast as off, not removed, when a model switch drops it

A removed key lets a config.json default of fast_mode: true fill back in
while Fast is off at runtime.
This commit is contained in:
Mohamed Boudra
2026-11-01 15:15:20 +01:00
parent 13ad4a13ff
commit 9d8747cd3a
2 changed files with 17 additions and 6 deletions
@@ -33,6 +33,8 @@ import type {
} from "../../agent-sdk-types.js";
import type { AgentAttachment } from "@getpaseo/protocol/messages";
import { buildAgentPrompt, renderPromptAttachmentAsText } from "../../prompt-attachments.js";
import { applyProviderOptionsPatch } from "../../option-controls.js";
import { mergeProviderOptions } from "../../provider-options.js";
interface TestClaudeSession {
translateMessageToEvents(message: SDKMessage): Promise<AgentStreamEvent[]>;
@@ -1547,9 +1549,14 @@ describe("ClaudeAgentSession features", () => {
await session.setModel?.("claude-fable-5");
expect(queryMock.applyFlagSettings).toHaveBeenLastCalledWith({ fastMode: false });
expect(events.filter((event) => event.type === "options_changed")).toEqual([
{ type: "options_changed", provider: "claude", patch: { fast_mode: null } },
const reported = events.filter((event) => event.type === "options_changed");
expect(reported).toEqual([
{ type: "options_changed", provider: "claude", patch: { fast_mode: false } },
]);
// With a `config.json` default of `fast_mode: true`, the agent's effective options must
// still read Fast as off: a removed key would let the default fill `true` back in.
const stored = applyProviderOptionsPatch({ fast_mode: true }, reported[0].patch);
expect(mergeProviderOptions({ fast_mode: true }, stored)).toEqual({ fast_mode: false });
await expect(session.applyOptions?.({ allowedTools: ["Read"] })).resolves.toBeUndefined();
await session.close();
});
@@ -2747,10 +2747,14 @@ class ClaudeAgentSession implements AgentSession {
const supported = claudeModelSupportsFastMode(this.config.model);
await activeQuery.applyFlagSettings({ fastMode: supported });
if (!supported) {
// Fast cannot run on this model, so the session drops the option and says so.
const { fast_mode: _fastMode, ...rest } = this.config.providerOptions;
this.config.providerOptions = rest;
this.pushEvent({ type: "options_changed", provider: "claude", patch: { fast_mode: null } });
// Fast cannot run on this model. Reporting it off rather than removed keeps a
// `config.json` default of `fast_mode: true` from filling it back in.
this.config.providerOptions = { ...this.config.providerOptions, fast_mode: false };
this.pushEvent({
type: "options_changed",
provider: "claude",
patch: { fast_mode: false },
});
}
this.cachedRuntimeInfo = null;
}