diff --git a/packages/app/src/app/agent/[serverId]/[agentId].tsx b/packages/app/src/app/agent/[serverId]/[agentId].tsx
index 12655ddb2..ef597b93a 100644
--- a/packages/app/src/app/agent/[serverId]/[agentId].tsx
+++ b/packages/app/src/app/agent/[serverId]/[agentId].tsx
@@ -14,7 +14,7 @@ import { useSafeAreaInsets } from "react-native-safe-area-context";
import { useReanimatedKeyboardAnimation } from "react-native-keyboard-controller";
import ReanimatedAnimated, { useAnimatedStyle, useSharedValue } from "react-native-reanimated";
import { StyleSheet, useUnistyles } from "react-native-unistyles";
-import { MoreVertical, GitBranch, Folder, RotateCcw, PlusCircle, Download } from "lucide-react-native";
+import { MoreVertical, GitBranch, Folder, RotateCcw, PlusCircle, Download, Users, ChevronRight } from "lucide-react-native";
import { BackHeader } from "@/components/headers/back-header";
import { AgentStreamView } from "@/components/agent-stream-view";
import { AgentInputArea } from "@/components/agent-input-area";
@@ -153,6 +153,20 @@ function AgentScreenContent({ serverId, agentId, onBack }: AgentScreenContentPro
resolvedAgentId ? state.sessions[serverId]?.agents?.get(resolvedAgentId) : undefined
);
+ // Select child agents (agents where parentAgentId === current agentId)
+ const childAgents = useSessionStore((state) => {
+ if (!resolvedAgentId) return [];
+ const agents = state.sessions[serverId]?.agents;
+ if (!agents) return [];
+ const children: Array<{ id: string; title: string | null }> = [];
+ for (const [id, a] of agents) {
+ if (a.parentAgentId === resolvedAgentId) {
+ children.push({ id, title: a.title });
+ }
+ }
+ return children;
+ });
+
// Select only the specific stream state - use stable empty array to avoid infinite loop
const streamItemsRaw = useSessionStore((state) =>
resolvedAgentId ? state.sessions[serverId]?.agentStreamState?.get(resolvedAgentId) : undefined
@@ -439,6 +453,20 @@ function AgentScreenContent({ serverId, agentId, onBack }: AgentScreenContentPro
setShowImportAgentModal(false);
}, []);
+ const handleNavigateToChildAgent = useCallback(
+ (childAgentId: string) => {
+ handleCloseMenu();
+ router.push({
+ pathname: "/agent/[serverId]/[agentId]",
+ params: {
+ serverId: serverId,
+ agentId: childAgentId,
+ },
+ });
+ },
+ [handleCloseMenu, router, serverId]
+ );
+
const createAgentModal = (
+ {/* Sub-Agents Section */}
+
+
+
+ Sub-Agents
+
+ {childAgents.length === 0 ? (
+ No sub-agents
+ ) : (
+ childAgents.map((child) => (
+ handleNavigateToChildAgent(child.id)}
+ style={styles.menuSubAgentItem}
+ >
+
+ {child.title || "Untitled Agent"}
+
+
+
+ ))
+ )}
+
+
+
+
View Changes
@@ -830,4 +888,40 @@ const styles = StyleSheet.create((theme) => ({
color: theme.colors.foreground,
fontWeight: theme.fontWeight.normal,
},
+ menuSubAgentsSection: {
+ gap: theme.spacing[1],
+ },
+ menuSubAgentsHeader: {
+ flexDirection: "row",
+ alignItems: "center",
+ gap: theme.spacing[2],
+ paddingHorizontal: theme.spacing[1],
+ paddingBottom: theme.spacing[1],
+ },
+ menuSubAgentsLabel: {
+ fontSize: theme.fontSize.xs,
+ color: theme.colors.mutedForeground,
+ letterSpacing: 0.5,
+ textTransform: "uppercase",
+ },
+ menuSubAgentsEmpty: {
+ fontSize: theme.fontSize.sm,
+ color: theme.colors.mutedForeground,
+ paddingHorizontal: theme.spacing[3],
+ paddingVertical: theme.spacing[2],
+ },
+ menuSubAgentItem: {
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ paddingVertical: theme.spacing[2],
+ paddingHorizontal: theme.spacing[3],
+ borderRadius: theme.borderRadius.md,
+ },
+ menuSubAgentText: {
+ fontSize: theme.fontSize.sm,
+ color: theme.colors.foreground,
+ flex: 1,
+ marginRight: theme.spacing[2],
+ },
}));
diff --git a/plan.md b/plan.md
index 43b68a3c1..5d1da8309 100644
--- a/plan.md
+++ b/plan.md
@@ -324,7 +324,7 @@ Files requiring modification:
- Run typecheck after changes.
- **Done (2025-12-21 21:45)**: Added filter in `use-aggregated-agents.ts:66-68` to skip agents with `parentAgentId` when building the aggregated agents list. Also included `parentAgentId` in the aggregated agent object. Typecheck passes.
-- [ ] **Implement**: Add sub-agents section to agent info menu.
+- [x] **Implement**: Add sub-agents section to agent info menu.
- In `[agentId].tsx:536`, add a "Sub-Agents" section to the menu
- Query the session store for agents where `parentAgentId === currentAgentId`
@@ -332,6 +332,7 @@ Files requiring modification:
- Tapping a child agent navigates to that agent's screen
- Show "No sub-agents" if none exist
- 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.
- [ ] **Test**: Verify parent/child hierarchy end-to-end.