fix(FN-2116): show paused agents and cap vitest workers

This commit is contained in:
gsxdsm
2026-04-18 17:34:44 -07:00
parent 301faefbd6
commit e70f9aebc0
16 changed files with 63 additions and 46 deletions

View File

@@ -257,23 +257,17 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
const hierarchy = useAgentHierarchy(agents, projectId);
// Filter agents for display: hide terminated agents in default "All States" view
// but show them when the user explicitly filters to "terminated"
// Always filter out ephemeral agents (task-workers and spawned children)
// Filter agents for display. "All States" means all non-ephemeral agents,
// including disabled/terminated agents that still carry configuration.
const displayAgents = useMemo(() => {
let filtered = agents.filter(a => !isEphemeralAgent(a));
if (filterState === "all") {
filtered = filtered.filter(a => a.state !== "terminated");
}
return filtered;
}, [agents, filterState]);
return agents.filter(a => !isEphemeralAgent(a));
}, [agents]);
// Filter org tree to exclude terminated and ephemeral agents in default view
// Filter org tree to exclude ephemeral agents in default view.
const displayOrgTree = useMemo(() => {
// Recursively filter out terminated and ephemeral agents from the org tree
// Recursively filter out ephemeral agents from the org tree.
const filterNode = (node: OrgTreeNode): OrgTreeNode | null => {
if (isEphemeralAgent(node.agent)) return null;
if (filterState === "all" && node.agent.state === "terminated") return null;
return {
...node,
children: node.children
@@ -284,7 +278,7 @@ export function AgentsView({ addToast, projectId }: AgentsViewProps) {
return orgTree
.map(filterNode)
.filter((n): n is OrgTreeNode => n !== null);
}, [orgTree, filterState]);
}, [orgTree]);
const loadAgents = useCallback(async () => {
setIsLoading(true);

View File

@@ -140,8 +140,7 @@ describe("AgentsView", () => {
expect(screen.getAllByText("idle").length).toBeGreaterThanOrEqual(1);
expect(screen.getAllByText("active").length).toBeGreaterThanOrEqual(1);
expect(screen.getAllByText("paused").length).toBeGreaterThanOrEqual(1);
// Terminated agents are hidden in default "All States" view
expect(screen.queryAllByText("terminated").length).toBe(0);
expect(screen.getAllByText("terminated").length).toBeGreaterThanOrEqual(1);
});
});
@@ -212,8 +211,7 @@ describe("AgentsView", () => {
await waitFor(() => {
const boardCards = document.querySelectorAll(".agent-board-card");
// 4 agents total, but terminated (agent-004) is filtered out in default view
expect(boardCards.length).toBe(3);
expect(boardCards.length).toBe(4);
});
});
@@ -782,18 +780,15 @@ describe("AgentsView", () => {
});
describe("delete agent", () => {
it("shows Delete button for idle agents in default view (terminated filtered out)", async () => {
it("shows Delete button for idle and terminated agents in default view", async () => {
render(<AgentsView addToast={mockAddToast} />);
await waitFor(() => {
// In default "All States" view, only idle agent (agent-001) should show Delete button
// Terminated agents (agent-004) are filtered out
const deleteButtons = screen.getAllByTitle("Delete");
expect(deleteButtons.length).toBeGreaterThanOrEqual(1);
expect(deleteButtons.length).toBeGreaterThanOrEqual(2);
});
// Verify terminated agent is not visible
expect(screen.queryByText("Test Agent 4")).toBeNull();
expect(screen.getByText("Test Agent 4")).toBeTruthy();
});
it("shows Delete button for terminated agents when explicitly filtered", async () => {
@@ -909,8 +904,6 @@ describe("AgentsView", () => {
render(<AgentsView addToast={mockAddToast} />);
await waitFor(() => {
// Only idle agent (agent-001) should have delete button in default view
// Terminated agent (agent-004) is filtered out
const deleteButtons = screen.getAllByTitle("Delete");
expect(deleteButtons.length).toBeGreaterThanOrEqual(1);
});

View File

@@ -1,10 +1,10 @@
import { defineConfig } from "vitest/config";
import react from "@vitejs/plugin-react";
import { resolve } from "node:path";
import { availableParallelism } from "node:os";
const defaultMaxWorkers = Math.max(1, Math.min(4, Math.ceil(availableParallelism() / 4)));
const maxWorkers = Number.parseInt(process.env.VITEST_MAX_WORKERS ?? String(defaultMaxWorkers), 10);
const defaultMaxWorkers = 1;
const requestedMaxWorkers = Number.parseInt(process.env.VITEST_MAX_WORKERS ?? String(defaultMaxWorkers), 10);
const maxWorkers = Math.max(1, Math.min(1, Number.isFinite(requestedMaxWorkers) ? requestedMaxWorkers : defaultMaxWorkers));
export default defineConfig({
plugins: [react()],