diff --git a/desktop/src/features/agents/ui/AgentsView.tsx b/desktop/src/features/agents/ui/AgentsView.tsx index acc07363a..c1c0bdbbe 100644 --- a/desktop/src/features/agents/ui/AgentsView.tsx +++ b/desktop/src/features/agents/ui/AgentsView.tsx @@ -74,7 +74,7 @@ export function AgentsView() { isActionPending={isActionPending} isAgentsLoading={agents.managedAgentsQuery.isLoading} startingAgentPubkey={agents.startingAgentPubkey} - startingPersonaId={agents.startingPersonaId} + startingPersonaIds={agents.startingPersonaIds} onBulkRemoveStopped={() => { void agents.handleBulkRemoveStopped(); }} diff --git a/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx b/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx index d69e793c9..2c3f4b5c4 100644 --- a/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx +++ b/desktop/src/features/agents/ui/UnifiedAgentsSection.tsx @@ -37,7 +37,7 @@ type UnifiedAgentsSectionProps = { isActionPending: boolean; isAgentsLoading: boolean; startingAgentPubkey: string | null; - startingPersonaId: string | null; + startingPersonaIds: ReadonlySet; onBulkRemoveStopped: () => void; onBulkStopRunning: () => void; onCreateAgent: () => void; @@ -72,7 +72,7 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) { isActionPending, isAgentsLoading, startingAgentPubkey, - startingPersonaId, + startingPersonaIds, onBulkRemoveStopped, onBulkStopRunning, onCreateAgent, @@ -174,7 +174,7 @@ export function UnifiedAgentsSection(props: UnifiedAgentsSectionProps) { key={group.persona.id} persona={group.persona} startingAgentPubkey={startingAgentPubkey} - startingPersonaId={startingPersonaId} + startingPersonaIds={startingPersonaIds} onOpenAgentProfile={onOpenAgentProfile} onOpenPersonaProfile={onOpenPersonaProfile} onStartAgent={onStartAgent} @@ -253,7 +253,7 @@ function AgentPersonaCard({ agent, persona, startingAgentPubkey, - startingPersonaId, + startingPersonaIds, onOpenAgentProfile, onOpenPersonaProfile, onStartAgent, @@ -262,7 +262,7 @@ function AgentPersonaCard({ agent: ManagedAgent | undefined; persona: AgentPersona; startingAgentPubkey: string | null; - startingPersonaId: string | null; + startingPersonaIds: ReadonlySet; onOpenAgentProfile: ( pubkey: string, options?: ProfilePanelOpenOptions, @@ -307,7 +307,7 @@ function AgentPersonaCard({ activeTestId={`persona-runtime-active-${persona.id}`} avatarUrl={avatarUrl} isActive={false} - isStarting={startingPersonaId === persona.id} + isStarting={startingPersonaIds.has(persona.id)} label={title} startTestId={`persona-runtime-start-${persona.id}`} onStart={() => onStartPersona(persona)} diff --git a/desktop/src/features/agents/ui/useManagedAgentActions.ts b/desktop/src/features/agents/ui/useManagedAgentActions.ts index 5f6436083..fba5b7e2a 100644 --- a/desktop/src/features/agents/ui/useManagedAgentActions.ts +++ b/desktop/src/features/agents/ui/useManagedAgentActions.ts @@ -51,6 +51,10 @@ export function useManagedAgentActions() { React.useState(null); const [createdAgent, setCreatedAgent] = React.useState(null); + const [startingPersonaIds, setStartingPersonaIds] = React.useState< + ReadonlySet + >(() => new Set()); + const startingPersonaIdsRef = React.useRef(new Set()); const [logAgentPubkey, setLogAgentPubkey] = React.useState( null, ); @@ -177,7 +181,22 @@ export function useManagedAgentActions() { return filterAvailableRuntimes(result.data); } + function setPersonaStartPending(personaId: string, pending: boolean) { + const next = new Set(startingPersonaIdsRef.current); + if (pending) { + next.add(personaId); + } else { + next.delete(personaId); + } + startingPersonaIdsRef.current = next; + setStartingPersonaIds(next); + } + async function handleStartPersona(persona: AgentPersona) { + if (startingPersonaIdsRef.current.has(persona.id)) { + return; + } + setPersonaStartPending(persona.id, true); clearFeedback(); try { const runtimes = await getAvailableRuntimesForStart(); @@ -238,6 +257,8 @@ export function useManagedAgentActions() { setActionErrorMessage( error instanceof Error ? error.message : "Failed to start agent.", ); + } finally { + setPersonaStartPending(persona.id, false); } } @@ -436,11 +457,6 @@ export function useManagedAgentActions() { startMutation.isPending && typeof startMutation.variables === "string" ? startMutation.variables : null; - const startingPersonaId = - createAgentMutation.isPending && - typeof createAgentMutation.variables?.personaId === "string" - ? createAgentMutation.variables.personaId - : null; return { relayAgentsQuery, @@ -465,7 +481,7 @@ export function useManagedAgentActions() { actionErrorMessage, setActionErrorMessage, startingAgentPubkey, - startingPersonaId, + startingPersonaIds, handleStart, handleStartPersona, handleStop,