From 01b4f11e563e6fcb32127657b0d49941cae0dc32 Mon Sep 17 00:00:00 2001 From: Bohdan Triapitsyn Date: Sat, 18 Apr 2026 13:47:24 +0300 Subject: [PATCH] fix(agent-selector): read agents from active-directory config store AgentSelector used useAgentsStore which is only warm after a chat session loads, so the todo send dialog opened from the project context panel showed an empty agent list. Prefer useConfigStore.agents (the same source ModelControls uses in chat) with useAgentsStore as fallback, and load both on mount when neither is populated. Also set the primary-mode filter on the scheduled task editor agent selector to keep its options consistent with the other flows. --- .../sections/commands/AgentSelector.tsx | 28 +++++++++++++++---- .../session/ScheduledTaskEditorDialog.tsx | 2 ++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/packages/ui/src/components/sections/commands/AgentSelector.tsx b/packages/ui/src/components/sections/commands/AgentSelector.tsx index 289d4a30..309362f9 100644 --- a/packages/ui/src/components/sections/commands/AgentSelector.tsx +++ b/packages/ui/src/components/sections/commands/AgentSelector.tsx @@ -1,11 +1,13 @@ import React from 'react'; +import type { Agent } from '@opencode-ai/sdk/v2'; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, } from '@/components/ui/dropdown-menu'; -import { useAgentsStore } from '@/stores/useAgentsStore'; +import { useAgentsStore, filterVisibleAgents } from '@/stores/useAgentsStore'; +import { useConfigStore } from '@/stores/useConfigStore'; import { useUIStore } from '@/stores/useUIStore'; import { useDeviceInfo } from '@/lib/device'; import { RiArrowDownSLine, RiRobot2Line } from '@remixicon/react'; @@ -16,15 +18,27 @@ interface AgentSelectorProps { agentName: string; onChange: (agentName: string) => void; className?: string; + filter?: (agent: Agent) => boolean; } export const AgentSelector: React.FC = ({ agentName, onChange, - className + className, + filter, }) => { - const { loadAgents, getVisibleAgents } = useAgentsStore(); - const agents = getVisibleAgents(); + const configAgents = useConfigStore((state) => state.agents); + const agentsStoreAgents = useAgentsStore((state) => state.agents); + const loadAgentsStore = useAgentsStore((state) => state.loadAgents); + const loadConfigAgents = useConfigStore((state) => state.loadAgents); + const rawAgents = React.useMemo(() => { + if (Array.isArray(configAgents) && configAgents.length > 0) return configAgents; + return Array.isArray(agentsStoreAgents) ? agentsStoreAgents : []; + }, [configAgents, agentsStoreAgents]); + const agents = React.useMemo(() => { + const visible = filterVisibleAgents(rawAgents); + return filter ? visible.filter(filter) : visible; + }, [rawAgents, filter]); const isMobile = useUIStore(state => state.isMobile); const { isMobile: deviceIsMobile } = useDeviceInfo(); const isActuallyMobile = isMobile || deviceIsMobile; @@ -32,8 +46,10 @@ export const AgentSelector: React.FC = ({ const [isMobilePanelOpen, setIsMobilePanelOpen] = React.useState(false); React.useEffect(() => { - loadAgents(); - }, [loadAgents]); + if (rawAgents.length > 0) return; + void loadConfigAgents(); + void loadAgentsStore(); + }, [rawAgents.length, loadConfigAgents, loadAgentsStore]); const closeMobilePanel = () => setIsMobilePanelOpen(false); diff --git a/packages/ui/src/components/session/ScheduledTaskEditorDialog.tsx b/packages/ui/src/components/session/ScheduledTaskEditorDialog.tsx index d379309e..3c0d7508 100644 --- a/packages/ui/src/components/session/ScheduledTaskEditorDialog.tsx +++ b/packages/ui/src/components/session/ScheduledTaskEditorDialog.tsx @@ -12,6 +12,7 @@ import { toast } from '@/components/ui'; import { RiAddLine, RiCloseLine, RiCalendarLine, RiArrowLeftSLine, RiArrowRightSLine, RiArrowDownSLine } from '@remixicon/react'; import { ModelSelector } from '@/components/sections/agents/ModelSelector'; import { AgentSelector } from '@/components/sections/commands/AgentSelector'; +import { isPrimaryMode } from '@/components/chat/mobileControlsUtils'; import { CommandAutocomplete, type CommandAutocompleteHandle } from '@/components/chat/CommandAutocomplete'; import { FileMentionAutocomplete, type FileMentionHandle } from '@/components/chat/FileMentionAutocomplete'; import { useConfigStore } from '@/stores/useConfigStore'; @@ -1308,6 +1309,7 @@ export function ScheduledTaskEditorDialog(props: { Agent isPrimaryMode(agent.mode)} onChange={(agent) => setDraft((prev) => ({ ...prev, execution: {