diff --git a/src/shared/agent-display-names.test.ts b/src/shared/agent-display-names.test.ts index 57cdd3c27..2c3d732cd 100644 --- a/src/shared/agent-display-names.test.ts +++ b/src/shared/agent-display-names.test.ts @@ -217,6 +217,10 @@ describe("normalizeAgentForPrompt", () => { it("removes zero-width characters before returning canonical names", () => { expect(normalizeAgentForPrompt("Sisyphus\u200B - Ultraworker")).toBe("Sisyphus - Ultraworker") }) + + it("converts legacy parenthesized names to canonical display names", () => { + expect(normalizeAgentForPrompt("Atlas (Plan Executor)")).toBe("Atlas - Plan Executor") + }) }) describe("normalizeAgentForPromptKey", () => { @@ -224,6 +228,10 @@ describe("normalizeAgentForPromptKey", () => { expect(normalizeAgentForPromptKey("Sisyphus (Ultraworker)")).toBe("sisyphus") }) + it("strips UI ordering prefixes before returning config keys", () => { + expect(normalizeAgentForPromptKey(getAgentListDisplayName("atlas"))).toBe("atlas") + }) + it("preserves custom agents", () => { expect(normalizeAgentForPromptKey("MyCustomAgent")).toBe("MyCustomAgent") }) @@ -259,7 +267,7 @@ describe("AGENT_DISPLAY_NAMES", () => { const httpHeaderUnsafe = /[()]/ // when checking each display name - for (const [key, displayName] of Object.entries(AGENT_DISPLAY_NAMES)) { + for (const [, displayName] of Object.entries(AGENT_DISPLAY_NAMES)) { // then none should contain parentheses expect(httpHeaderUnsafe.test(displayName)).toBe(false) } diff --git a/src/shared/agent-display-names.ts b/src/shared/agent-display-names.ts index 6747d445f..324fac785 100644 --- a/src/shared/agent-display-names.ts +++ b/src/shared/agent-display-names.ts @@ -94,18 +94,23 @@ const LEGACY_DISPLAY_NAMES: Record = { "athena-junior (council)": "athena-junior", } -/** - * Resolve an agent name (display name or config key) to its lowercase config key. - * "Atlas - Plan Executor" -> "atlas", "Atlas (Plan Executor)" -> "atlas", "atlas" -> "atlas" - */ -export function getAgentConfigKey(agentName: string): string { +function resolveKnownAgentConfigKey(agentName: string): string | undefined { const lower = stripAgentListSortPrefix(agentName).trim().toLowerCase() const reversed = REVERSE_DISPLAY_NAMES[lower] if (reversed !== undefined) return reversed const legacy = LEGACY_DISPLAY_NAMES[lower] if (legacy !== undefined) return legacy if (AGENT_DISPLAY_NAMES[lower] !== undefined) return lower - return lower + return undefined +} + +/** + * Resolve an agent name (display name or config key) to its lowercase config key. + * "Atlas - Plan Executor" -> "atlas", "Atlas (Plan Executor)" -> "atlas", "atlas" -> "atlas" + */ +export function getAgentConfigKey(agentName: string): string { + const lower = stripAgentListSortPrefix(agentName).trim().toLowerCase() + return resolveKnownAgentConfigKey(agentName) ?? lower } /** @@ -124,17 +129,9 @@ export function normalizeAgentForPrompt(agentName: string | undefined): string | return undefined } - const lower = trimmed.toLowerCase() - const reversed = REVERSE_DISPLAY_NAMES[lower] - if (reversed !== undefined) { - return AGENT_DISPLAY_NAMES[reversed] ?? trimmed - } - const legacy = LEGACY_DISPLAY_NAMES[lower] - if (legacy !== undefined) { - return AGENT_DISPLAY_NAMES[legacy] ?? trimmed - } - if (AGENT_DISPLAY_NAMES[lower] !== undefined) { - return AGENT_DISPLAY_NAMES[lower] + const configKey = resolveKnownAgentConfigKey(trimmed) + if (configKey !== undefined) { + return AGENT_DISPLAY_NAMES[configKey] ?? trimmed } return trimmed @@ -150,18 +147,5 @@ export function normalizeAgentForPromptKey(agentName: string | undefined): strin return undefined } - const lower = trimmed.toLowerCase() - const reversed = REVERSE_DISPLAY_NAMES[lower] - if (reversed !== undefined) { - return reversed - } - const legacy = LEGACY_DISPLAY_NAMES[lower] - if (legacy !== undefined) { - return legacy - } - if (AGENT_DISPLAY_NAMES[lower] !== undefined) { - return lower - } - - return trimmed + return resolveKnownAgentConfigKey(trimmed) ?? trimmed }