diff --git a/src/plugin-handlers/agent-config-handler.ts b/src/plugin-handlers/agent-config-handler.ts index f270fd0a..ca2e8d2c 100644 --- a/src/plugin-handlers/agent-config-handler.ts +++ b/src/plugin-handlers/agent-config-handler.ts @@ -112,15 +112,13 @@ export async function applyAgentConfig(params: { const shouldDemotePlan = plannerEnabled && replacePlan; const configuredDefaultAgent = getConfiguredDefaultAgent(params.config); - if (configuredDefaultAgent) { - (params.config as { default_agent?: string }).default_agent = - getAgentDisplayName(configuredDefaultAgent); - } - const configAgent = params.config.agent as AgentConfigRecord | undefined; if (isSisyphusEnabled && builtinAgents.sisyphus) { - if (!configuredDefaultAgent) { + if (configuredDefaultAgent) { + (params.config as { default_agent?: string }).default_agent = + getAgentDisplayName(configuredDefaultAgent); + } else { (params.config as { default_agent?: string }).default_agent = getAgentDisplayName("sisyphus"); } diff --git a/src/plugin-handlers/config-handler.test.ts b/src/plugin-handlers/config-handler.test.ts index a86f6783..ebba28ea 100644 --- a/src/plugin-handlers/config-handler.test.ts +++ b/src/plugin-handlers/config-handler.test.ts @@ -350,6 +350,54 @@ describe("Agent permission defaults", () => { }) describe("default_agent behavior with Sisyphus orchestration", () => { + test("canonicalizes configured default_agent with surrounding whitespace", async () => { + // given + const pluginConfig: OhMyOpenCodeConfig = {} + const config: Record = { + model: "anthropic/claude-opus-4-6", + default_agent: " hephaestus ", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // when + await handler(config) + + // then + expect(config.default_agent).toBe(getAgentDisplayName("hephaestus")) + }) + + test("canonicalizes configured default_agent when key uses mixed case", async () => { + // given + const pluginConfig: OhMyOpenCodeConfig = {} + const config: Record = { + model: "anthropic/claude-opus-4-6", + default_agent: "HePhAeStUs", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // when + await handler(config) + + // then + expect(config.default_agent).toBe(getAgentDisplayName("hephaestus")) + }) + test("canonicalizes configured default_agent key to display name", async () => { // #given const pluginConfig: OhMyOpenCodeConfig = {} @@ -421,6 +469,82 @@ describe("default_agent behavior with Sisyphus orchestration", () => { // #then expect(config.default_agent).toBe(getAgentDisplayName("sisyphus")) }) + + test("sets default_agent to sisyphus when configured default_agent is empty after trim", async () => { + // given + const pluginConfig: OhMyOpenCodeConfig = {} + const config: Record = { + model: "anthropic/claude-opus-4-6", + default_agent: " ", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // when + await handler(config) + + // then + expect(config.default_agent).toBe(getAgentDisplayName("sisyphus")) + }) + + test("preserves custom default_agent names while trimming whitespace", async () => { + // given + const pluginConfig: OhMyOpenCodeConfig = {} + const config: Record = { + model: "anthropic/claude-opus-4-6", + default_agent: " Custom Agent ", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // when + await handler(config) + + // then + expect(config.default_agent).toBe("Custom Agent") + }) + + test("does not normalize configured default_agent when Sisyphus is disabled", async () => { + // given + const pluginConfig: OhMyOpenCodeConfig = { + sisyphus_agent: { + disabled: true, + }, + } + const config: Record = { + model: "anthropic/claude-opus-4-6", + default_agent: " HePhAeStUs ", + agent: {}, + } + const handler = createConfigHandler({ + ctx: { directory: "/tmp" }, + pluginConfig, + modelCacheState: { + anthropicContext1MEnabled: false, + modelContextLimitsCache: new Map(), + }, + }) + + // when + await handler(config) + + // then + expect(config.default_agent).toBe(" HePhAeStUs ") + }) }) describe("Prometheus category config resolution", () => {