From cb601ddd775f01101145511ab61645a84807526e Mon Sep 17 00:00:00 2001 From: YeonGyu-Kim Date: Mon, 16 Feb 2026 21:32:33 +0900 Subject: [PATCH] fix: resolve category delegation and command routing with display name agent keys Category-based delegation (task(category='quick')) was broken because SISYPHUS_JUNIOR_AGENT sent 'sisyphus-junior' to session.prompt but config.agent keys are now display names ('Sisyphus-Junior'). - Use getAgentDisplayName() for SISYPHUS_JUNIOR_AGENT constant - Replace hardcoded 'sisyphus-junior' strings in tools.ts with constant - Update background-output local constants to use display names - Add remapCommandAgentFields() to translate command agent fields - Add raw-key fallback in tool-config-handler agentByKey() --- src/plugin-handlers/command-config-handler.ts | 11 +++++++++++ src/plugin-handlers/tool-config-handler.ts | 4 +++- src/tools/background-task/create-background-output.ts | 4 +++- .../background-task/modules/background-output.ts | 4 +++- src/tools/background-task/tools.test.ts | 2 +- src/tools/delegate-task/sisyphus-junior-agent.ts | 4 +++- src/tools/delegate-task/tools.test.ts | 6 +++--- src/tools/delegate-task/tools.ts | 5 +++-- 8 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/plugin-handlers/command-config-handler.ts b/src/plugin-handlers/command-config-handler.ts index 1ef73df3..a5cb0e94 100644 --- a/src/plugin-handlers/command-config-handler.ts +++ b/src/plugin-handlers/command-config-handler.ts @@ -1,4 +1,5 @@ import type { OhMyOpenCodeConfig } from "../config"; +import { getAgentDisplayName } from "../shared/agent-display-names"; import { loadUserCommands, loadProjectCommands, @@ -68,4 +69,14 @@ export async function applyCommandConfig(params: { ...params.pluginComponents.commands, ...params.pluginComponents.skills, }; + + remapCommandAgentFields(params.config.command as Record>); +} + +function remapCommandAgentFields(commands: Record>): void { + for (const cmd of Object.values(commands)) { + if (cmd?.agent && typeof cmd.agent === "string") { + cmd.agent = getAgentDisplayName(cmd.agent); + } + } } diff --git a/src/plugin-handlers/tool-config-handler.ts b/src/plugin-handlers/tool-config-handler.ts index 1e0cdac9..e488d2da 100644 --- a/src/plugin-handlers/tool-config-handler.ts +++ b/src/plugin-handlers/tool-config-handler.ts @@ -4,7 +4,9 @@ import { getAgentDisplayName } from "../shared/agent-display-names"; type AgentWithPermission = { permission?: Record }; function agentByKey(agentResult: Record, key: string): AgentWithPermission | undefined { - return agentResult[getAgentDisplayName(key)] as AgentWithPermission | undefined; + return (agentResult[key] ?? agentResult[getAgentDisplayName(key)]) as + | AgentWithPermission + | undefined; } export function applyToolConfig(params: { diff --git a/src/tools/background-task/create-background-output.ts b/src/tools/background-task/create-background-output.ts index aaca3cb1..37c0f348 100644 --- a/src/tools/background-task/create-background-output.ts +++ b/src/tools/background-task/create-background-output.ts @@ -9,7 +9,9 @@ import { formatFullSession } from "./full-session-format" import { formatTaskResult } from "./task-result-format" import { formatTaskStatus } from "./task-status-format" -const SISYPHUS_JUNIOR_AGENT = "sisyphus-junior" +import { getAgentDisplayName } from "../../shared/agent-display-names" + +const SISYPHUS_JUNIOR_AGENT = getAgentDisplayName("sisyphus-junior") type ToolContextWithMetadata = { sessionID: string diff --git a/src/tools/background-task/modules/background-output.ts b/src/tools/background-task/modules/background-output.ts index 70f52284..38d4d3b9 100644 --- a/src/tools/background-task/modules/background-output.ts +++ b/src/tools/background-task/modules/background-output.ts @@ -8,7 +8,9 @@ import { storeToolMetadata } from "../../../features/tool-metadata-store" import type { BackgroundTask } from "../../../features/background-agent" import type { ToolContextWithMetadata } from "./utils" -const SISYPHUS_JUNIOR_AGENT = "sisyphus-junior" +import { getAgentDisplayName } from "../../../shared/agent-display-names" + +const SISYPHUS_JUNIOR_AGENT = getAgentDisplayName("sisyphus-junior") type ToolContextWithCallId = ToolContextWithMetadata & { callID?: string diff --git a/src/tools/background-task/tools.test.ts b/src/tools/background-task/tools.test.ts index dbb8be90..2f1d6502 100644 --- a/src/tools/background-task/tools.test.ts +++ b/src/tools/background-task/tools.test.ts @@ -85,7 +85,7 @@ describe("background_output full_session", () => { const task = createTask({ id: "task-1", - agent: "sisyphus-junior", + agent: "Sisyphus-Junior", category: "quick", description: "Fix flaky test", status: "running", diff --git a/src/tools/delegate-task/sisyphus-junior-agent.ts b/src/tools/delegate-task/sisyphus-junior-agent.ts index 1839932e..6e7f795a 100644 --- a/src/tools/delegate-task/sisyphus-junior-agent.ts +++ b/src/tools/delegate-task/sisyphus-junior-agent.ts @@ -1 +1,3 @@ -export const SISYPHUS_JUNIOR_AGENT = "sisyphus-junior" +import { getAgentDisplayName } from "../../shared/agent-display-names" + +export const SISYPHUS_JUNIOR_AGENT = getAgentDisplayName("sisyphus-junior") diff --git a/src/tools/delegate-task/tools.test.ts b/src/tools/delegate-task/tools.test.ts index c2cfff1a..36950e8f 100644 --- a/src/tools/delegate-task/tools.test.ts +++ b/src/tools/delegate-task/tools.test.ts @@ -452,7 +452,7 @@ describe("sisyphus-task", () => { await tool.execute(args, toolContext) // then - expect(args.subagent_type).toBe("sisyphus-junior") + expect(args.subagent_type).toBe("Sisyphus-Junior") }, { timeout: 10000 }) test("category overrides subagent_type and still maps to sisyphus-junior", async () => { @@ -517,7 +517,7 @@ describe("sisyphus-task", () => { const result = await tool.execute(args, toolContext) //#then - expect(args.subagent_type).toBe("sisyphus-junior") + expect(args.subagent_type).toBe("Sisyphus-Junior") expect(result).toContain("Background task launched") }, { timeout: 10000 }) @@ -3718,7 +3718,7 @@ describe("sisyphus-task", () => { ) // then - title should follow OpenCode format - expect(createBody.title).toBe("Implement feature X (@sisyphus-junior subagent)") + expect(createBody.title).toBe("Implement feature X (@Sisyphus-Junior subagent)") }, { timeout: 10000 }) test("sync task output includes block with session_id", async () => { diff --git a/src/tools/delegate-task/tools.ts b/src/tools/delegate-task/tools.ts index 763b09f0..f3fb04ca 100644 --- a/src/tools/delegate-task/tools.ts +++ b/src/tools/delegate-task/tools.ts @@ -1,6 +1,7 @@ import { tool, type ToolDefinition } from "@opencode-ai/plugin" import type { DelegateTaskArgs, ToolContextWithMetadata, DelegateTaskToolOptions } from "./types" import { CATEGORY_DESCRIPTIONS } from "./constants" +import { SISYPHUS_JUNIOR_AGENT } from "./sisyphus-junior-agent" import { mergeCategories } from "../../shared/merge-categories" import { log } from "../../shared/logger" import { buildSystemContent } from "./prompt-builder" @@ -88,13 +89,13 @@ Prompts MUST be in English.` const ctx = toolContext as ToolContextWithMetadata if (args.category) { - if (args.subagent_type && args.subagent_type !== "sisyphus-junior") { + if (args.subagent_type && args.subagent_type !== SISYPHUS_JUNIOR_AGENT) { log("[task] category provided - overriding subagent_type to sisyphus-junior", { category: args.category, subagent_type: args.subagent_type, }) } - args.subagent_type = "sisyphus-junior" + args.subagent_type = SISYPHUS_JUNIOR_AGENT } await ctx.metadata?.({ title: args.description,