Files
paseo/packages/app/src/screens/workspace/workspace-agent-visibility.ts
T
Mohamed Boudra 48924626df fix(app): reduce workspace screen re-renders and fix archived agent handling
Replace greedy agents Map subscription with a Zustand selector that
derives workspace agent visibility (ID sets only) with custom equality,
so the workspace screen only re-renders when agents are added, removed,
or archived — not on every status/activity update.

Fix tab pruning to check against all known agents (including archived)
instead of only active agents, so archived agent tabs survive
reconciliation. Remove the auto-unarchive effect that called
refreshAgent() as a workaround. Hide input area for archived agents.
2026-03-20 21:07:51 +07:00

87 lines
2.1 KiB
TypeScript

import type { Agent } from "@/stores/session-store";
import { normalizeWorkspaceIdentity } from "@/utils/workspace-identity";
function normalizeWorkspaceId(value: string | null | undefined): string {
return normalizeWorkspaceIdentity(value) ?? "";
}
export interface WorkspaceAgentVisibility {
activeAgentIds: Set<string>;
knownAgentIds: Set<string>;
}
export function deriveWorkspaceAgentVisibility(input: {
sessionAgents: Map<string, Agent> | undefined;
workspaceId: string;
}): WorkspaceAgentVisibility {
const { sessionAgents, workspaceId } = input;
const normalizedWorkspaceId = normalizeWorkspaceId(workspaceId);
if (!sessionAgents || !workspaceId) {
return {
activeAgentIds: new Set<string>(),
knownAgentIds: new Set<string>(),
};
}
const activeAgentIds = new Set<string>();
const knownAgentIds = new Set<string>();
for (const agent of sessionAgents.values()) {
if (normalizeWorkspaceId(agent.cwd) !== normalizedWorkspaceId) {
continue;
}
knownAgentIds.add(agent.id);
if (!agent.archivedAt) {
activeAgentIds.add(agent.id);
}
}
return { activeAgentIds, knownAgentIds };
}
export function workspaceAgentVisibilityEqual(
a: WorkspaceAgentVisibility,
b: WorkspaceAgentVisibility,
): boolean {
return setsEqual(a.activeAgentIds, b.activeAgentIds) && setsEqual(a.knownAgentIds, b.knownAgentIds);
}
function setsEqual(a: Set<string>, b: Set<string>): boolean {
if (a.size !== b.size) {
return false;
}
for (const item of a) {
if (!b.has(item)) {
return false;
}
}
return true;
}
export function canOpenAgentTabFromRoute(input: {
agentId: string;
agentsHydrated: boolean;
knownAgentIds: Set<string>;
}): boolean {
if (!input.agentId.trim()) {
return false;
}
if (!input.agentsHydrated) {
return true;
}
return input.knownAgentIds.has(input.agentId);
}
export function shouldPruneWorkspaceAgentTab(input: {
agentId: string;
agentsHydrated: boolean;
knownAgentIds: Set<string>;
}): boolean {
if (!input.agentId.trim()) {
return false;
}
if (!input.agentsHydrated) {
return false;
}
return !input.knownAgentIds.has(input.agentId);
}