mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
feat: add sub-agents section to agent info menu
Added a "Sub-Agents" section to the agent info menu dropdown that: - Queries session store for agents where parentAgentId matches current agent - Displays child agents as clickable menu items with chevron icons - Shows "No sub-agents" when the agent has no children - Navigates to child agent screen when tapped 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -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 = (
|
||||
<CreateAgentModal
|
||||
isVisible={showCreateAgentModal}
|
||||
@@ -585,6 +613,36 @@ function AgentScreenContent({ serverId, agentId, onBack }: AgentScreenContentPro
|
||||
|
||||
<View style={styles.menuDivider} />
|
||||
|
||||
{/* Sub-Agents Section */}
|
||||
<View style={styles.menuSubAgentsSection}>
|
||||
<View style={styles.menuSubAgentsHeader}>
|
||||
<Users size={16} color={theme.colors.mutedForeground} />
|
||||
<Text style={styles.menuSubAgentsLabel}>Sub-Agents</Text>
|
||||
</View>
|
||||
{childAgents.length === 0 ? (
|
||||
<Text style={styles.menuSubAgentsEmpty}>No sub-agents</Text>
|
||||
) : (
|
||||
childAgents.map((child) => (
|
||||
<Pressable
|
||||
key={child.id}
|
||||
onPress={() => handleNavigateToChildAgent(child.id)}
|
||||
style={styles.menuSubAgentItem}
|
||||
>
|
||||
<Text
|
||||
style={styles.menuSubAgentText}
|
||||
numberOfLines={1}
|
||||
ellipsizeMode="tail"
|
||||
>
|
||||
{child.title || "Untitled Agent"}
|
||||
</Text>
|
||||
<ChevronRight size={16} color={theme.colors.mutedForeground} />
|
||||
</Pressable>
|
||||
))
|
||||
)}
|
||||
</View>
|
||||
|
||||
<View style={styles.menuDivider} />
|
||||
|
||||
<Pressable onPress={handleViewChanges} style={styles.menuItem}>
|
||||
<GitBranch size={20} color={theme.colors.foreground} />
|
||||
<Text style={styles.menuItemText}>View Changes</Text>
|
||||
@@ -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],
|
||||
},
|
||||
}));
|
||||
|
||||
3
plan.md
3
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.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user