From 3dae11d2927cc3aed2bda41a39b56485c0e55bdb Mon Sep 17 00:00:00 2001 From: Ryan Swift Date: Sat, 2 May 2026 00:46:27 -0400 Subject: [PATCH] fix(opencode): include all-mode agents in mode picker (#606) --- .../agent/providers/opencode-agent.test.ts | 9 ++++ .../server/agent/providers/opencode-agent.ts | 41 ++++++++++--------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/packages/server/src/server/agent/providers/opencode-agent.test.ts b/packages/server/src/server/agent/providers/opencode-agent.test.ts index 77f467028..0c94767c9 100644 --- a/packages/server/src/server/agent/providers/opencode-agent.test.ts +++ b/packages/server/src/server/agent/providers/opencode-agent.test.ts @@ -554,6 +554,15 @@ describe("OpenCode adapter context-window normalization", () => { }, ]); }); + + test("treats primary and all OpenCode agents as selectable modes", () => { + expect(__openCodeInternals.isSelectableOpenCodeAgent({ mode: "primary" })).toBe(true); + expect(__openCodeInternals.isSelectableOpenCodeAgent({ mode: "all" })).toBe(true); + expect(__openCodeInternals.isSelectableOpenCodeAgent({ mode: "subagent" })).toBe(false); + expect(__openCodeInternals.isSelectableOpenCodeAgent({ mode: "all", hidden: true })).toBe( + false, + ); + }); }); describe("OpenCode adapter startTurn error handling", () => { diff --git a/packages/server/src/server/agent/providers/opencode-agent.ts b/packages/server/src/server/agent/providers/opencode-agent.ts index 96bb847c4..1ff7ecf79 100644 --- a/packages/server/src/server/agent/providers/opencode-agent.ts +++ b/packages/server/src/server/agent/providers/opencode-agent.ts @@ -424,6 +424,10 @@ function resolveOpenCodeRuntimeAgentId(modeId: string | null | undefined): strin : normalizedModeId; } +function isSelectableOpenCodeAgent(agent: { mode?: string; hidden?: boolean }): boolean { + return (agent.mode === "primary" || agent.mode === "all") && agent.hidden !== true; +} + function mergeOpenCodeModes(discoveredModes: AgentMode[]): AgentMode[] { const modesById = new Map(DEFAULT_MODES.map((mode) => [mode.id, mode])); for (const mode of discoveredModes) { @@ -728,6 +732,7 @@ export const __openCodeInternals = { reconcileOpenCodeSessionClose, resolveOpenCodeModelLookupKeyFromAssistantMessage, resolveOpenCodeSelectedModelContextWindow, + isSelectableOpenCodeAgent, get OpenCodeAgentSession() { return OpenCodeAgentSession; }, @@ -1191,16 +1196,14 @@ export class OpenCodeAgentClient implements AgentClient { return DEFAULT_MODES; } - const discovered = response.data - .filter((agent) => agent.mode === "primary" && agent.hidden !== true) - .map((agent) => ({ - id: agent.name, - label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1), - description: - typeof agent.description === "string" && agent.description.trim().length > 0 - ? agent.description.trim() - : DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description, - })); + const discovered = response.data.filter(isSelectableOpenCodeAgent).map((agent) => ({ + id: agent.name, + label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1), + description: + typeof agent.description === "string" && agent.description.trim().length > 0 + ? agent.description.trim() + : DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description, + })); return mergeOpenCodeModes(discovered); } finally { @@ -2462,16 +2465,14 @@ class OpenCodeAgentSession implements AgentSession { }); const agents = response.error || !response.data ? [] : response.data; - const discoveredModes = agents - .filter((agent) => agent.mode === "primary" && agent.hidden !== true) - .map((agent) => ({ - id: agent.name, - label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1), - description: - typeof agent.description === "string" && agent.description.trim().length > 0 - ? agent.description.trim() - : DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description, - })); + const discoveredModes = agents.filter(isSelectableOpenCodeAgent).map((agent) => ({ + id: agent.name, + label: agent.name.charAt(0).toUpperCase() + agent.name.slice(1), + description: + typeof agent.description === "string" && agent.description.trim().length > 0 + ? agent.description.trim() + : DEFAULT_MODES.find((mode) => mode.id === agent.name)?.description, + })); this.availableModesCache = mergeOpenCodeModes(discoveredModes); return this.availableModesCache;