agent-ecosystem/src/renderer/store/slices/subagentSlice.ts
matt 7fa2f96ed4 feat(http): implement HTTP server and route handlers for configuration, notifications, projects, sessions, and SSH management
- Introduced an HTTP server to facilitate communication with the application.
- Added route handlers for managing application configuration, including getting and updating settings.
- Implemented notification operations with routes for retrieving, marking, and deleting notifications.
- Created project and session management routes to list projects, sessions, and their details.
- Developed SSH connection management routes for connecting, disconnecting, and retrieving SSH state and configuration.
- Enhanced the application architecture to support real-time event streaming via Server-Sent Events (SSE).

This commit significantly expands the application's capabilities by integrating an HTTP server and various management routes, improving user interaction and functionality.
2026-02-12 15:04:56 +09:00

145 lines
3.9 KiB
TypeScript

/**
* Subagent slice - manages subagent drill-down state.
*/
import { api } from '@renderer/api';
import type { AppState, BreadcrumbItem } from '../types';
import type { SubagentDetail } from '@renderer/types/data';
import type { StateCreator } from 'zustand';
// =============================================================================
// Slice Interface
// =============================================================================
export interface SubagentSlice {
// State
drillDownStack: BreadcrumbItem[];
currentSubagentDetail: SubagentDetail | null;
subagentDetailLoading: boolean;
subagentDetailError: string | null;
// Actions
drillDownSubagent: (
projectId: string,
sessionId: string,
subagentId: string,
description: string
) => Promise<void>;
navigateToBreadcrumb: (index: number) => void;
closeSubagentModal: () => void;
}
// =============================================================================
// Slice Creator
// =============================================================================
export const createSubagentSlice: StateCreator<AppState, [], [], SubagentSlice> = (set, get) => ({
// Initial state
drillDownStack: [],
currentSubagentDetail: null,
subagentDetailLoading: false,
subagentDetailError: null,
// Drill down into a subagent
drillDownSubagent: async (
projectId: string,
sessionId: string,
subagentId: string,
description: string
) => {
set({ subagentDetailLoading: true, subagentDetailError: null });
try {
const detail = await api.getSubagentDetail(projectId, sessionId, subagentId);
if (!detail) {
set({
subagentDetailError: 'Failed to load subagent details',
subagentDetailLoading: false,
});
return;
}
// Add to breadcrumb stack
const currentStack = get().drillDownStack;
set({
drillDownStack: [...currentStack, { id: subagentId, description }],
currentSubagentDetail: detail,
subagentDetailLoading: false,
});
} catch (error) {
set({
subagentDetailError: error instanceof Error ? error.message : 'Failed to load subagent',
subagentDetailLoading: false,
});
}
},
// Navigate to a specific breadcrumb (pop stack to that level)
navigateToBreadcrumb: (index: number) => {
const state = get();
// If navigating to index 0 or negative, close modal
if (index <= 0) {
set({
drillDownStack: [],
currentSubagentDetail: null,
subagentDetailError: null,
});
return;
}
// Pop stack to the specified index
const newStack = state.drillDownStack.slice(0, index);
if (newStack.length === 0) {
set({
drillDownStack: [],
currentSubagentDetail: null,
subagentDetailError: null,
});
return;
}
// Reload detail for the target level
const targetItem = newStack[newStack.length - 1];
const projectId = state.selectedProjectId;
const sessionId = state.selectedSessionId;
if (!projectId || !sessionId) return;
set({ subagentDetailLoading: true, subagentDetailError: null });
api
.getSubagentDetail(projectId, sessionId, targetItem.id)
.then((detail) => {
if (detail) {
set({
drillDownStack: newStack,
currentSubagentDetail: detail,
subagentDetailLoading: false,
});
} else {
set({
subagentDetailError: 'Failed to load subagent details',
subagentDetailLoading: false,
});
}
})
.catch((error) => {
set({
subagentDetailError: error instanceof Error ? error.message : 'Failed to load subagent',
subagentDetailLoading: false,
});
});
},
// Close the subagent modal
closeSubagentModal: () => {
set({
drillDownStack: [],
currentSubagentDetail: null,
subagentDetailError: null,
});
},
});