diff --git a/packages/server/src/server/agent/agent-manager.ts b/packages/server/src/server/agent/agent-manager.ts index 9a10ac2a4..c6272dc57 100644 --- a/packages/server/src/server/agent/agent-manager.ts +++ b/packages/server/src/server/agent/agent-manager.ts @@ -22,8 +22,6 @@ import type { } from "./agent-sdk-types.js"; import { resolveAgentModel } from "./model-resolver.js"; import type { AgentRegistry } from "./agent-registry.js"; -import { VALID_CLAUDE_MODES } from "./providers/claude-agent.js"; -import { VALID_CODEX_MODES } from "./providers/codex-agent.js"; export const AGENT_LIFECYCLE_STATUSES = [ "initializing", @@ -164,27 +162,6 @@ function isAgentBusy(status: AgentLifecycleStatus): boolean { return BUSY_STATUSES.includes(status); } -function getValidModesForProvider(provider: AgentProvider): Set { - switch (provider) { - case "claude": - return VALID_CLAUDE_MODES; - case "codex": - return VALID_CODEX_MODES; - default: - return new Set(); - } -} - -function validateMode(provider: AgentProvider, modeId: string): void { - const validModes = getValidModesForProvider(provider); - if (!validModes.has(modeId)) { - const validModesList = Array.from(validModes).join(", "); - throw new Error( - `Invalid mode '${modeId}' for provider '${provider}'. Valid modes: ${validModesList}` - ); - } -} - function createAbortError( signal: AbortSignal | undefined, fallbackMessage: string @@ -315,12 +292,6 @@ export class AgentManager { agentId?: string ): Promise { const normalizedConfig = await this.normalizeConfig(config); - - // Validate mode if provided - if (normalizedConfig.modeId) { - validateMode(normalizedConfig.provider, normalizedConfig.modeId); - } - const client = this.requireClient(normalizedConfig.provider); const session = await client.createSession(normalizedConfig); return this.registerSession( @@ -342,12 +313,6 @@ export class AgentManager { provider: handle.provider, } as AgentSessionConfig; const normalizedConfig = await this.normalizeConfig(mergedConfig); - - // Validate mode if provided - if (normalizedConfig.modeId) { - validateMode(handle.provider, normalizedConfig.modeId); - } - const resumeOverrides = normalizedConfig.model !== mergedConfig.model ? { ...overrides, model: normalizedConfig.model } @@ -409,10 +374,6 @@ export class AgentManager { async setAgentMode(agentId: string, modeId: string): Promise { const agent = this.requireAgent(agentId); - - // Validate mode before attempting to set it - validateMode(agent.provider, modeId); - await agent.session.setMode(modeId); agent.currentModeId = modeId; this.emitState(agent); diff --git a/packages/server/src/server/agent/providers/claude-agent.ts b/packages/server/src/server/agent/providers/claude-agent.ts index 0a1470136..68253b42d 100644 --- a/packages/server/src/server/agent/providers/claude-agent.ts +++ b/packages/server/src/server/agent/providers/claude-agent.ts @@ -72,7 +72,7 @@ const DEFAULT_MODES: AgentMode[] = [ }, ]; -export const VALID_CLAUDE_MODES = new Set( +const VALID_CLAUDE_MODES = new Set( DEFAULT_MODES.map((mode) => mode.id) ); @@ -271,6 +271,15 @@ class ClaudeAgentSession implements AgentSession { this.claudeSessionId = handle?.sessionId ?? handle?.nativeHandle ?? null; this.pendingLocalId = this.claudeSessionId ?? `claude-${randomUUID()}`; this.persistence = handle ?? null; + + // Validate mode if provided + if (config.modeId && !VALID_CLAUDE_MODES.has(config.modeId)) { + const validModesList = Array.from(VALID_CLAUDE_MODES).join(", "); + throw new Error( + `Invalid mode '${config.modeId}' for Claude provider. Valid modes: ${validModesList}` + ); + } + this.currentMode = (config.modeId as PermissionMode) ?? "default"; if (this.claudeSessionId) { this.loadPersistedHistory(this.claudeSessionId); @@ -386,6 +395,14 @@ class ClaudeAgentSession implements AgentSession { } async setMode(modeId: string): Promise { + // Validate mode + if (!VALID_CLAUDE_MODES.has(modeId)) { + const validModesList = Array.from(VALID_CLAUDE_MODES).join(", "); + throw new Error( + `Invalid mode '${modeId}' for Claude provider. Valid modes: ${validModesList}` + ); + } + const normalized = modeId as PermissionMode; const query = await this.ensureQuery(); await query.setPermissionMode(normalized); diff --git a/packages/server/src/server/agent/providers/codex-agent.ts b/packages/server/src/server/agent/providers/codex-agent.ts index 29a01aafa..f82de1dae 100644 --- a/packages/server/src/server/agent/providers/codex-agent.ts +++ b/packages/server/src/server/agent/providers/codex-agent.ts @@ -69,7 +69,7 @@ const CODEX_MODES: AgentMode[] = [ }, ]; -export const VALID_CODEX_MODES = new Set( +const VALID_CODEX_MODES = new Set( CODEX_MODES.map((mode) => mode.id) ); @@ -294,6 +294,15 @@ class CodexAgentSession implements AgentSession { constructor(codex: Codex, config: CodexAgentConfig, handle?: AgentPersistenceHandle) { this.codex = codex; this.config = { ...config }; + + // Validate mode if provided + if (config.modeId && !VALID_CODEX_MODES.has(config.modeId)) { + const validModesList = Array.from(VALID_CODEX_MODES).join(", "); + throw new Error( + `Invalid mode '${config.modeId}' for Codex provider. Valid modes: ${validModesList}` + ); + } + this.currentMode = this.config.modeId ?? DEFAULT_CODEX_MODE_ID; this.threadOptions = this.buildThreadOptions(this.currentMode); this.codexSessionDir = this.resolveCodexSessionDir(handle); @@ -424,8 +433,13 @@ class CodexAgentSession implements AgentSession { if (modeId === this.currentMode) { return; } - if (!this.availableModes.some((mode) => mode.id === modeId)) { - throw new Error(`Mode '${modeId}' not supported by Codex`); + + // Validate mode + if (!VALID_CODEX_MODES.has(modeId)) { + const validModesList = Array.from(VALID_CODEX_MODES).join(", "); + throw new Error( + `Invalid mode '${modeId}' for Codex provider. Valid modes: ${validModesList}` + ); } this.currentMode = modeId;