fix(acp): preserve runtime option clears (#101044)

* fix(acp): preserve runtime option clears

* refactor(acp): simplify runtime option clears

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
This commit is contained in:
mushuiyu886
2026-07-06 23:12:50 +01:00
committed by GitHub
co-authored by Peter Steinberger
parent 0e0888a887
commit b75fe8102e
2 changed files with 54 additions and 7 deletions
+50 -1
View File
@@ -1,6 +1,55 @@
/** Tests runtime config-option serialization against advertised backend keys. */
import { describe, expect, it } from "vitest";
import { buildRuntimeConfigOptionPairs } from "./runtime-options.js";
import type { AcpSessionRuntimeOptions } from "../../config/sessions/types.js";
import { buildRuntimeConfigOptionPairs, mergeRuntimeOptions } from "./runtime-options.js";
describe("mergeRuntimeOptions", () => {
it("clears top-level options when a patch explicitly sets them to undefined", () => {
const patch = {
runtimeMode: undefined,
model: undefined,
thinking: undefined,
cwd: undefined,
permissionProfile: undefined,
timeoutSeconds: undefined,
} as Partial<AcpSessionRuntimeOptions>;
expect(
mergeRuntimeOptions({
current: {
runtimeMode: "plan",
model: "claude-sonnet-4.6",
thinking: "high",
cwd: "/tmp/project",
permissionProfile: "trusted",
timeoutSeconds: 120,
},
patch,
}),
).toEqual({});
});
it("clears backend extras when a patch explicitly clears them", () => {
expect(
mergeRuntimeOptions({
current: {
model: "claude-sonnet-4.6",
backendExtras: { provider: "anthropic", profile: "work" },
},
patch: { backendExtras: undefined } as Partial<AcpSessionRuntimeOptions>,
}),
).toEqual({ model: "claude-sonnet-4.6" });
});
it("keeps merging backend extras when a patch provides new entries", () => {
expect(
mergeRuntimeOptions({
current: { backendExtras: { provider: "anthropic" } },
patch: { backendExtras: { profile: "work" } },
}),
).toEqual({ backendExtras: { provider: "anthropic", profile: "work" } });
});
});
describe("buildRuntimeConfigOptionPairs timeout advertisement", () => {
it("omits the timeout pair when advertised keys exclude every timeout alias", () => {
+4 -6
View File
@@ -277,15 +277,13 @@ export function mergeRuntimeOptions(params: {
patch?: Partial<AcpSessionRuntimeOptions>;
}): AcpSessionRuntimeOptions {
const current = normalizeRuntimeOptions(params.current);
const patch = normalizeRuntimeOptions(validateRuntimeOptionPatch(params.patch));
const mergedExtras = {
...current.backendExtras,
...patch.backendExtras,
};
const patch = validateRuntimeOptionPatch(params.patch);
return normalizeRuntimeOptions({
...current,
...patch,
...(Object.keys(mergedExtras).length > 0 ? { backendExtras: mergedExtras } : {}),
...(patch.backendExtras
? { backendExtras: { ...current.backendExtras, ...patch.backendExtras } }
: {}),
});
}