fix(agent-key): remove ZWSP from config object keys (RFC 7230)

Object keys containing ZWSP characters cause HTTP header validation
failures in OpenCode 1.4.0+, breaking agent registration.

- Use getAgentDisplayName() (no ZWSP) for object keys
- Keep getAgentRuntimeName() (with ZWSP) only in name field for sorting
- Maintains ZWSP sorting for Sisyphus, Hephaestus, Prometheus, Atlas

Fixes #3220
This commit is contained in:
YeonGyu-Kim
2026-04-13 11:16:03 +09:00
parent 42df1c3cbb
commit 35fdd22d36
5 changed files with 11 additions and 11 deletions
+3 -3
View File
@@ -2,7 +2,7 @@ import { createBuiltinAgents } from "../agents";
import { createSisyphusJuniorAgentWithOverrides } from "../agents/sisyphus-junior"; import { createSisyphusJuniorAgentWithOverrides } from "../agents/sisyphus-junior";
import type { OhMyOpenCodeConfig } from "../config"; import type { OhMyOpenCodeConfig } from "../config";
import { isTaskSystemEnabled, log, migrateAgentConfig } from "../shared"; import { isTaskSystemEnabled, log, migrateAgentConfig } from "../shared";
import { getAgentRuntimeName } from "../shared/agent-display-names"; import { getAgentDisplayName, getAgentRuntimeName } from "../shared/agent-display-names";
import { AGENT_NAME_MAP } from "../shared/migration"; import { AGENT_NAME_MAP } from "../shared/migration";
import { registerAgentName } from "../features/claude-code-session-state"; import { registerAgentName } from "../features/claude-code-session-state";
import { import {
@@ -159,10 +159,10 @@ export async function applyAgentConfig(params: {
if (isSisyphusEnabled && builtinAgents.sisyphus) { if (isSisyphusEnabled && builtinAgents.sisyphus) {
if (configuredDefaultAgent) { if (configuredDefaultAgent) {
(params.config as { default_agent?: string }).default_agent = (params.config as { default_agent?: string }).default_agent =
getAgentRuntimeName(configuredDefaultAgent); getAgentDisplayName(configuredDefaultAgent);
} else { } else {
(params.config as { default_agent?: string }).default_agent = (params.config as { default_agent?: string }).default_agent =
getAgentRuntimeName("sisyphus"); getAgentDisplayName("sisyphus");
} }
// Assembly order: Sisyphus -> Hephaestus -> Prometheus -> Atlas // Assembly order: Sisyphus -> Hephaestus -> Prometheus -> Atlas
+2 -2
View File
@@ -1,4 +1,4 @@
import { getAgentListDisplayName, getAgentRuntimeName } from "../shared/agent-display-names" import { getAgentDisplayName, getAgentRuntimeName } from "../shared/agent-display-names"
function rewriteAgentNameForListDisplay( function rewriteAgentNameForListDisplay(
key: string, key: string,
@@ -21,7 +21,7 @@ export function remapAgentKeysToDisplayNames(
const result: Record<string, unknown> = {} const result: Record<string, unknown> = {}
for (const [key, value] of Object.entries(agents)) { for (const [key, value] of Object.entries(agents)) {
const displayName = getAgentListDisplayName(key) const displayName = getAgentDisplayName(key)
if (displayName && displayName !== key) { if (displayName && displayName !== key) {
result[displayName] = rewriteAgentNameForListDisplay(key, value) result[displayName] = rewriteAgentNameForListDisplay(key, value)
// Regression guard: do not also assign result[key]. // Regression guard: do not also assign result[key].
+2 -2
View File
@@ -1,4 +1,4 @@
import { getAgentListDisplayName } from "../shared/agent-display-names" import { getAgentDisplayName } from "../shared/agent-display-names"
/** /**
* CRITICAL: This is the ONLY source of truth for core agent ordering. * CRITICAL: This is the ONLY source of truth for core agent ordering.
@@ -25,7 +25,7 @@ const CORE_AGENT_ORDER: ReadonlyArray<{
order: number order: number
}> = CANONICAL_CORE_AGENT_ORDER.map((configKey, index) => ({ }> = CANONICAL_CORE_AGENT_ORDER.map((configKey, index) => ({
configKey, configKey,
displayName: getAgentListDisplayName(configKey), displayName: getAgentDisplayName(configKey),
order: index + 1, order: index + 1,
})) }))
@@ -1,7 +1,7 @@
import type { OhMyOpenCodeConfig } from "../config"; import type { OhMyOpenCodeConfig } from "../config";
import { import {
getAgentConfigKey, getAgentConfigKey,
getAgentListDisplayName, getAgentDisplayName,
} from "../shared/agent-display-names"; } from "../shared/agent-display-names";
import { import {
loadUserCommands, loadUserCommands,
@@ -99,7 +99,7 @@ export async function applyCommandConfig(params: {
function remapCommandAgentFields(commands: Record<string, Record<string, unknown>>): void { function remapCommandAgentFields(commands: Record<string, Record<string, unknown>>): void {
for (const cmd of Object.values(commands)) { for (const cmd of Object.values(commands)) {
if (cmd?.agent && typeof cmd.agent === "string") { if (cmd?.agent && typeof cmd.agent === "string") {
cmd.agent = getAgentListDisplayName(getAgentConfigKey(cmd.agent)); cmd.agent = getAgentDisplayName(getAgentConfigKey(cmd.agent));
} }
} }
} }
+2 -2
View File
@@ -1,5 +1,5 @@
import type { OhMyOpenCodeConfig } from "../config"; import type { OhMyOpenCodeConfig } from "../config";
import { getAgentDisplayName, getAgentListDisplayName } from "../shared/agent-display-names"; import { getAgentDisplayName } from "../shared/agent-display-names";
import { isTaskSystemEnabled } from "../shared"; import { isTaskSystemEnabled } from "../shared";
type AgentWithPermission = { permission?: Record<string, unknown> }; type AgentWithPermission = { permission?: Record<string, unknown> };
@@ -16,7 +16,7 @@ function getConfigQuestionPermission(): string | null {
} }
function agentByKey(agentResult: Record<string, unknown>, key: string): AgentWithPermission | undefined { function agentByKey(agentResult: Record<string, unknown>, key: string): AgentWithPermission | undefined {
return (agentResult[getAgentListDisplayName(key)] ?? agentResult[getAgentDisplayName(key)] ?? agentResult[key]) as return (agentResult[getAgentDisplayName(key)] ?? agentResult[key]) as
| AgentWithPermission | AgentWithPermission
| undefined; | undefined;
} }