Reduce unnecessary re-renders in agent panel and input components
Narrow zustand selectors to only subscribe to fields each component actually uses. Split nested objects (availableModes, projectPlacement) into separate selectors with structural equality checks. Remove the updatedAt processing-spinner hack in agent-input-area — the server already guarantees agent status is "running" before ACKing the send request, so isProcessing can clear on submit success directly.
This commit is contained in:
@@ -693,6 +693,7 @@ export function useAgentFormState(options: UseAgentFormStateOptions = {}): UseAg
|
||||
const agentDefinition = providerDefinitionMap.get(formState.provider);
|
||||
const modeOptions = agentDefinition?.modes ?? [];
|
||||
const effectiveModel = resolveEffectiveModel(availableModels, formState.model);
|
||||
const resolvedModelId = effectiveModel?.id ?? formState.model;
|
||||
const availableThinkingOptions = effectiveModel?.thinkingOptions ?? [];
|
||||
const isModelLoading = providerModelsQuery.isLoading || providerModelsQuery.isFetching;
|
||||
const modelError =
|
||||
@@ -709,7 +710,7 @@ export function useAgentFormState(options: UseAgentFormStateOptions = {}): UseAg
|
||||
setProviderFromUser,
|
||||
selectedMode: formState.modeId,
|
||||
setModeFromUser,
|
||||
selectedModel: formState.model,
|
||||
selectedModel: resolvedModelId,
|
||||
setModelFromUser,
|
||||
selectedThinkingOptionId: formState.thinkingOptionId,
|
||||
setThinkingOptionFromUser,
|
||||
@@ -735,7 +736,7 @@ export function useAgentFormState(options: UseAgentFormStateOptions = {}): UseAg
|
||||
formState.serverId,
|
||||
formState.provider,
|
||||
formState.modeId,
|
||||
formState.model,
|
||||
resolvedModelId,
|
||||
formState.thinkingOptionId,
|
||||
formState.workingDir,
|
||||
setSelectedServerId,
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
import { useRef } from "react";
|
||||
import type { Agent } from "@/contexts/session-context";
|
||||
|
||||
export interface AgentScreenAgent {
|
||||
serverId: string;
|
||||
id: string;
|
||||
status: "initializing" | "idle" | "running" | "error" | "closed";
|
||||
cwd: string;
|
||||
projectPlacement?: {
|
||||
checkout?: {
|
||||
cwd?: string;
|
||||
isGit?: boolean;
|
||||
};
|
||||
} | null;
|
||||
}
|
||||
|
||||
export type AgentScreenMissingState =
|
||||
| { kind: "idle" }
|
||||
@@ -8,8 +20,8 @@ export type AgentScreenMissingState =
|
||||
| { kind: "error"; message: string };
|
||||
|
||||
export interface AgentScreenMachineInput {
|
||||
agent: Agent | null;
|
||||
placeholderAgent: Agent | null;
|
||||
agent: AgentScreenAgent | null;
|
||||
placeholderAgent: AgentScreenAgent | null;
|
||||
missingAgentState: AgentScreenMissingState;
|
||||
isConnected: boolean;
|
||||
isArchivingCurrentAgent: boolean;
|
||||
@@ -31,7 +43,7 @@ export type AgentScreenToastLatch = "none" | "history_refresh" | "sync_error";
|
||||
|
||||
export interface AgentScreenMachineMemory {
|
||||
hasRenderedReady: boolean;
|
||||
lastReadyAgent: Agent | null;
|
||||
lastReadyAgent: AgentScreenAgent | null;
|
||||
activeToastLatch: AgentScreenToastLatch;
|
||||
hadInitialSyncFailure: boolean;
|
||||
}
|
||||
@@ -70,7 +82,7 @@ export type AgentScreenViewState =
|
||||
}
|
||||
| {
|
||||
tag: "ready";
|
||||
agent: Agent;
|
||||
agent: AgentScreenAgent;
|
||||
source: "authoritative" | "optimistic" | "stale";
|
||||
sync: AgentScreenReadySyncState;
|
||||
isArchiving: boolean;
|
||||
|
||||
Reference in New Issue
Block a user