fix: use useShallow for childAgents selector to prevent infinite loop

The childAgents selector in the agent screen was creating a new array
on every render, causing an infinite loop when combined with zustand's
store subscription. Added useShallow wrapper to perform shallow
comparison and prevent unnecessary re-renders.

Also updated plan.md with test results:
- PARTIAL PASS: Fixed infinite loop, agent screen loads correctly
- Sub-Agents menu section displays properly
- Parent/child MCP creation works but parentAgentId not auto-injected
- Added fix task for auto-injecting parentAgentId in MCP server

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Mohamed Boudra
2025-12-21 17:30:34 +00:00
co-authored by Claude Opus 4.5
parent cdc17006da
commit 99338d3b34
2 changed files with 34 additions and 12 deletions
@@ -1,4 +1,5 @@
import { useEffect, useMemo, useRef, useCallback, useState } from "react"; import { useEffect, useMemo, useRef, useCallback, useState } from "react";
import { useShallow } from "zustand/shallow";
import { import {
View, View,
Text, Text,
@@ -154,18 +155,21 @@ function AgentScreenContent({ serverId, agentId, onBack }: AgentScreenContentPro
); );
// Select child agents (agents where parentAgentId === current agentId) // Select child agents (agents where parentAgentId === current agentId)
const childAgents = useSessionStore((state) => { // Use useShallow to avoid creating new array references on every render
if (!resolvedAgentId) return []; const childAgents = useSessionStore(
const agents = state.sessions[serverId]?.agents; useShallow((state) => {
if (!agents) return []; if (!resolvedAgentId) return [];
const children: Array<{ id: string; title: string | null }> = []; const agents = state.sessions[serverId]?.agents;
for (const [id, a] of agents) { if (!agents) return [];
if (a.parentAgentId === resolvedAgentId) { const children: Array<{ id: string; title: string | null }> = [];
children.push({ id, title: a.title }); for (const [id, a] of agents) {
if (a.parentAgentId === resolvedAgentId) {
children.push({ id, title: a.title });
}
} }
} return children;
return children; })
}); );
// Select only the specific stream state - use stable empty array to avoid infinite loop // Select only the specific stream state - use stable empty array to avoid infinite loop
const streamItemsRaw = useSessionStore((state) => const streamItemsRaw = useSessionStore((state) =>
+19 -1
View File
@@ -334,7 +334,7 @@ Files requiring modification:
- Run typecheck after changes. - Run typecheck after changes.
- **Done (2025-12-21 22:00)**: Added Sub-Agents section to agent info menu in `[agentId].tsx`. Added `childAgents` selector to query agents with matching `parentAgentId`. Added `handleNavigateToChildAgent` callback for navigation. UI shows "No sub-agents" when empty, or clickable list of child agents with chevron icons. Typecheck passes. - **Done (2025-12-21 22:00)**: Added Sub-Agents section to agent info menu in `[agentId].tsx`. Added `childAgents` selector to query agents with matching `parentAgentId`. Added `handleNavigateToChildAgent` callback for navigation. UI shows "No sub-agents" when empty, or clickable list of child agents with chevron icons. Typecheck passes.
- [ ] **Test**: Verify parent/child hierarchy end-to-end. - [x] **Test**: Verify parent/child hierarchy end-to-end.
- Create a root agent via the UI - Create a root agent via the UI
- Use MCP to spawn a child agent from within the root agent - Use MCP to spawn a child agent from within the root agent
@@ -343,6 +343,24 @@ Files requiring modification:
- Click child agent in menu, verify navigation works - Click child agent in menu, verify navigation works
- Verify back button returns to parent agent screen - Verify back button returns to parent agent screen
- If issues found: add fix tasks + re-test task. - If issues found: add fix tasks + re-test task.
- **Done (2025-12-21 22:30)**: PARTIAL PASS with issues found. Fixed infinite loop bug (added `useShallow` to `childAgents` selector). Agent screen loads correctly. Sub-Agents menu section shows "No sub-agents". Parent agent successfully created child via MCP `create_agent`. However, child appears on homepage because `parentAgentId` not set - MCP server doesn't auto-inject calling agent's ID. Fix task added.
- [ ] **Fix**: Auto-inject parentAgentId in MCP create_agent tool.
- The MCP server needs to know which agent is calling it
- Explore passing agent ID context when MCP transport is created
- Or: Have each agent's MCP session be scoped to that agent
- Update `create_agent` handler to automatically set `parentAgentId`
- Run typecheck after changes.
- [ ] **Test**: Re-verify parent/child hierarchy after MCP fix.
- Create a root agent via the UI
- Use MCP to spawn a child agent from within the root agent
- Verify child agent has `parentAgentId` set automatically
- Verify homepage only shows the root agent (not the child)
- Verify root agent's menu shows the child in "Sub-Agents" section
- Click child agent in menu, verify navigation works
- [ ] **Plan**: Re-audit agent hierarchy after initial implementation. - [ ] **Plan**: Re-audit agent hierarchy after initial implementation.