fix(config-handler): preserve plan prompt when demoted (#1416)

This commit is contained in:
YeonGyu-Kim 2026-02-03 13:37:57 +09:00 committed by GitHub
parent 1b9303ba37
commit 9d217b05b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 115 additions and 3 deletions

View File

@ -184,6 +184,117 @@ describe("Plan agent demote behavior", () => {
expect(agents.plan.prompt).not.toBe(agents.prometheus?.prompt)
})
test("plan agent should not be demoted when replacePlan is false", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: false,
},
}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-5",
agent: {
plan: {
name: "plan",
mode: "primary",
prompt: "original plan prompt",
},
},
}
const handler = createConfigHandler({
ctx: { directory: "/tmp" },
pluginConfig,
modelCacheState: {
anthropicContext1MEnabled: false,
modelContextLimitsCache: new Map(),
},
})
// when
await handler(config)
// then
const agents = config.agent as Record<string, { mode?: string; name?: string; prompt?: string }>
expect(agents.plan).toBeDefined()
expect(agents.plan.mode).toBe("primary")
expect(agents.plan.name).toBe("plan")
expect(agents.plan.prompt).toBe("original plan prompt")
})
test("plan agent should not be demoted when planner is disabled", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
sisyphus_agent: {
planner_enabled: false,
replace_plan: true,
},
}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-5",
agent: {
plan: {
name: "plan",
mode: "primary",
prompt: "original plan prompt",
},
},
}
const handler = createConfigHandler({
ctx: { directory: "/tmp" },
pluginConfig,
modelCacheState: {
anthropicContext1MEnabled: false,
modelContextLimitsCache: new Map(),
},
})
// when
await handler(config)
// then
const agents = config.agent as Record<string, { mode?: string; name?: string; prompt?: string }>
expect(agents.prometheus).toBeUndefined()
expect(agents.plan).toBeDefined()
expect(agents.plan.mode).toBe("primary")
})
test("preserves empty plan prompt when demoting", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {
sisyphus_agent: {
planner_enabled: true,
replace_plan: true,
},
}
const config: Record<string, unknown> = {
model: "anthropic/claude-opus-4-5",
agent: {
plan: {
name: "plan",
mode: "primary",
prompt: "",
},
},
}
const handler = createConfigHandler({
ctx: { directory: "/tmp" },
pluginConfig,
modelCacheState: {
anthropicContext1MEnabled: false,
modelContextLimitsCache: new Map(),
},
})
// when
await handler(config)
// then
const agents = config.agent as Record<string, { prompt?: string }>
expect(agents.plan).toBeDefined()
expect(agents.plan.prompt).toBe("")
})
test("prometheus should have mode 'all' to be callable via delegate_task", async () => {
// given
const pluginConfig: OhMyOpenCodeConfig = {

View File

@ -195,6 +195,7 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
const plannerEnabled =
pluginConfig.sisyphus_agent?.planner_enabled ?? true;
const replacePlan = pluginConfig.sisyphus_agent?.replace_plan ?? true;
const shouldReplacePlan = plannerEnabled && replacePlan;
type AgentConfig = Record<
string,
@ -344,7 +345,7 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
Object.entries(configAgent)
.filter(([key]) => {
if (key === "build") return false;
if (key === "plan" && replacePlan) return false;
if (key === "plan" && shouldReplacePlan) return false;
// Filter out agents that oh-my-opencode provides to prevent
// OpenCode defaults from overwriting user config in oh-my-opencode.json
// See: https://github.com/code-yeongyu/oh-my-opencode/issues/472
@ -362,12 +363,12 @@ export function createConfigHandler(deps: ConfigHandlerDeps) {
? migrateAgentConfig(configAgent.build as Record<string, unknown>)
: {};
const planDemoteConfig = replacePlan && agentConfig["prometheus"]
const planDemoteConfig = shouldReplacePlan && agentConfig["prometheus"]
? {
...agentConfig["prometheus"],
name: "plan",
mode: "subagent" as const,
...(planPrompt ? { prompt: planPrompt } : {}),
...(typeof planPrompt === "string" ? { prompt: planPrompt } : {}),
}
: undefined;