From 6e68015389b8dc175d3aebb138b939a00122f5d6 Mon Sep 17 00:00:00 2001 From: bashrusakh <127580858+bashrusakh@users.noreply.github.com> Date: Wed, 24 Jun 2026 06:34:51 +1100 Subject: [PATCH] fix(agents): use isPrimaryMode consistently across all agent pickers (#1713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(agents): use isPrimaryMode filter for agent picker Fix #1527: agent picker filtered by mode !== 'subagent' which missed agents with unexpected mode values. Now uses isPrimaryMode() which only includes 'primary', 'all', undefined, and null — the semantically correct set of agents that should appear in the picker. * fix(agents): use isPrimaryMode consistently across all agent pickers Updated AgentSelector.tsx to use isPrimaryMode instead of mode !== 'subagent'. Removed duplicate isPrimaryMode definition from useConfigStore.ts and imported the shared helper from mobileControlsUtils. --------- Co-authored-by: Leonid Skorobogatyy --- packages/ui/src/components/chat/ModelControls.tsx | 4 ++-- packages/ui/src/components/multirun/AgentSelector.tsx | 3 ++- packages/ui/src/stores/useConfigStore.ts | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/ui/src/components/chat/ModelControls.tsx b/packages/ui/src/components/chat/ModelControls.tsx index 6aacf888..aaaca165 100644 --- a/packages/ui/src/components/chat/ModelControls.tsx +++ b/packages/ui/src/components/chat/ModelControls.tsx @@ -35,7 +35,7 @@ import { getSessionMaterializationStatus } from '@/sync/materialization'; import { useUIStore } from '@/stores/useUIStore'; import { useModelLists } from '@/hooks/useModelLists'; import { useIsTextTruncated } from '@/hooks/useIsTextTruncated'; -import { formatEffortLabel, getCycledPrimaryAgentName, type MobileControlsPanel } from './mobileControlsUtils'; +import { formatEffortLabel, getCycledPrimaryAgentName, isPrimaryMode, type MobileControlsPanel } from './mobileControlsUtils'; import { getCurrentIntlLocale, useI18n } from '@/lib/i18n'; import { useOpenCodeReadiness } from '@/hooks/useOpenCodeReadiness'; import { eventMatchesShortcut, getEffectiveShortcutCombo, normalizeCombo } from '@/lib/shortcuts'; @@ -492,7 +492,7 @@ export const ModelControls: React.FC = ({ }, [isAgentSelectorOpen, isCompact]); const selectableDesktopAgents = React.useMemo(() => { - return agents.filter((agent) => agent.mode !== 'subagent'); + return agents.filter((agent) => isPrimaryMode(agent.mode)); }, [agents]); const sortedAndFilteredAgents = React.useMemo(() => { diff --git a/packages/ui/src/components/multirun/AgentSelector.tsx b/packages/ui/src/components/multirun/AgentSelector.tsx index 8de702ac..50b8c0c7 100644 --- a/packages/ui/src/components/multirun/AgentSelector.tsx +++ b/packages/ui/src/components/multirun/AgentSelector.tsx @@ -8,6 +8,7 @@ import { SelectValue, } from '@/components/ui/select'; import { cn } from '@/lib/utils'; +import { isPrimaryMode } from '@/components/chat/mobileControlsUtils'; import { useConfigStore } from '@/stores/useConfigStore'; import { useI18n } from '@/lib/i18n'; @@ -44,7 +45,7 @@ export const AgentSelector: React.FC = ({ const defaultAgentName = useConfigStore((state) => state.currentAgentName); const agents = getVisibleAgents(); const selectableAgents = React.useMemo( - () => agents.filter((agent) => agent.mode !== 'subagent'), + () => agents.filter((agent) => isPrimaryMode(agent.mode)), [agents] ); diff --git a/packages/ui/src/stores/useConfigStore.ts b/packages/ui/src/stores/useConfigStore.ts index 21dbe1bb..246e994b 100644 --- a/packages/ui/src/stores/useConfigStore.ts +++ b/packages/ui/src/stores/useConfigStore.ts @@ -7,6 +7,7 @@ import { scopeMatches, subscribeToConfigChanges } from "@/lib/configSync"; import type { ModelMetadata } from "@/types"; import { getSafeStorage } from "./utils/safeStorage"; import { filterVisibleAgents } from "./useAgentsStore"; +import { isPrimaryMode } from "@/components/chat/mobileControlsUtils"; import { useSessionUIStore } from "@/sync/session-ui-store"; import { useSelectionStore } from "@/sync/selection-store"; import { getRegisteredRuntimeAPIs } from "@/contexts/runtimeAPIRegistry"; @@ -179,8 +180,6 @@ const parseModelString = (modelString: string): { providerId: string; modelId: s const normalizeProviderId = (value: string) => value?.toLowerCase?.() ?? ''; -const isPrimaryMode = (mode?: string) => mode === "primary" || mode === "all" || mode === undefined || mode === null; - type ProviderModel = Provider["models"][string]; type ProviderWithModelList = Omit & { models: ProviderModel[] };