7.8 KiB
Agent Architecture - Surviving Next.js Restarts
Problem Statement
When using the Automaker app to iterate on itself:
- Agent modifies code files
- Next.js hot-reloads and restarts
- API routes are killed
- Agent conversation is lost
Solution: Electron Main Process Agent
The agent now runs in the Electron main process instead of Next.js API routes. This provides:
- ✅ Survives Next.js restarts - Main process is independent of renderer
- ✅ Persistent state - Conversations saved to disk automatically
- ✅ Real-time streaming - IPC events for live updates
- ✅ Session recovery - Reconnects automatically after restart
Architecture Overview
┌─────────────────────────────────────────┐
│ Electron Main Process │
│ ┌───────────────────────────────┐ │
│ │ Agent Service │ │
│ │ - Manages sessions │ │
│ │ - Runs Claude Agent SDK │ │
│ │ - Persists to disk │ │
│ │ - Streams via IPC │ │
│ └───────────────────────────────┘ │
└──────────────┬──────────────────────────┘
│ IPC (survives restarts)
┌──────────────┴──────────────────────────┐
│ Electron Renderer (Next.js) │
│ ┌───────────────────────────────┐ │
│ │ React Frontend │ │
│ │ - useElectronAgent hook │ │
│ │ - Auto-reconnects │ │
│ │ - Real-time updates │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────────┘
Key Components
1. Agent Service (electron/agent-service.js)
The core service running in the Electron main process:
- Session Management: Tracks multiple conversations by session ID
- State Persistence: Saves conversations to
userData/agent-sessions/*.json - Streaming: Sends real-time updates to renderer via IPC
- Tool Support: Full Read/Write/Edit/Bash/Grep/Glob capabilities
- Error Recovery: Continues after errors, saves state
2. IPC Handlers (electron/main.js)
Electron main process handlers:
agent:start- Initialize or resume a sessionagent:send- Send a message (returns immediately)agent:getHistory- Retrieve conversation historyagent:stop- Stop current executionagent:clear- Clear conversationagent:stream- Event emitted for streaming updates
3. Preload Bridge (electron/preload.js)
Secure IPC bridge exposed to renderer:
window.electronAPI.agent.start(sessionId, workingDir);
window.electronAPI.agent.send(sessionId, message, workingDir);
window.electronAPI.agent.onStream(callback);
4. React Hook (src/hooks/use-electron-agent.ts)
Easy-to-use React hook:
const {
messages, // Conversation history
isProcessing, // Agent is working
isConnected, // Session initialized
sendMessage, // Send user message
stopExecution, // Stop current task
clearHistory, // Clear conversation
error, // Error state
} = useElectronAgent({
sessionId: "project_xyz",
workingDirectory: "/path/to/project",
onToolUse: (tool) => console.log("Using:", tool),
});
5. Frontend Component (src/components/views/agent-view.tsx)
Updated to use IPC instead of HTTP:
- Generates session ID from project path
- Auto-reconnects on mount
- Shows tool usage in real-time
- Displays connection status
Data Flow
Sending a Message
- User types message in React UI
sendMessage()callswindow.electronAPI.agent.send()- IPC handler in main process receives message
- Agent service starts processing
- Main process streams updates via
agent:streamevents - React hook receives events and updates UI
- Conversation saved to disk
Surviving a Restart
- Agent is modifying code → Next.js restarts
- React component unmounts
- Main process keeps running (agent continues)
- React component remounts after restart
- Calls
agent:startwith same session ID - Main process returns full conversation history
- Subscribes to
agent:streamevents - UI shows complete conversation + live updates
Session Storage
Sessions are stored in:
<userData>/agent-sessions/<sessionId>.json
Each session file contains:
[
{
"id": "msg_1234_abc",
"role": "user",
"content": "Add a new feature...",
"timestamp": "2024-12-07T12:00:00.000Z"
},
{
"id": "msg_1235_def",
"role": "assistant",
"content": "I'll help you add that feature...",
"timestamp": "2024-12-07T12:00:05.000Z"
}
]
Session ID Generation
Session IDs are generated from project paths:
const sessionId = `project_${projectPath.replace(/[^a-zA-Z0-9]/g, "_")}`;
This ensures:
- Each project has its own conversation
- Conversations persist across app restarts
- Multiple projects can run simultaneously
Streaming Events
The agent emits these event types:
message
User message added to conversation
stream
Assistant response streaming (updates in real-time)
tool_use
Agent is using a tool (Read, Write, Edit, etc.)
complete
Agent finished processing
error
Error occurred during processing
Configuration
The agent is configured with:
{
model: "claude-opus-4-5-20251101",
maxTurns: 20,
cwd: workingDirectory,
allowedTools: [
"Read", "Write", "Edit", "Glob", "Grep",
"Bash", "WebSearch", "WebFetch"
],
permissionMode: "acceptEdits", // Auto-approve file edits
sandbox: {
enabled: true, // Sandboxed bash execution
autoAllowBashIfSandboxed: true
}
}
Benefits
For Self-Iteration
Now you can ask the agent to modify Automaker itself:
User: "Add a dark mode toggle to the settings"
Agent: *modifies files*
→ Next.js restarts
→ Agent continues working
→ UI reconnects automatically
→ Shows full conversation history
For Long-Running Tasks
The agent can work on complex tasks that take multiple turns:
User: "Implement authentication with GitHub OAuth"
Agent:
1. Creates auth API routes
2. Next.js restarts
3. Agent continues: Adds middleware
4. Next.js restarts again
5. Agent continues: Updates UI components
6. All changes tracked, conversation preserved
Testing
To test the architecture:
- Open a project in Automaker
- Ask the agent to modify a file in
src/ - Watch Next.js restart
- Verify the conversation continues
- Check that history is preserved
- Restart the entire Electron app
- Verify conversation loads from disk
Troubleshooting
"Electron API not available"
- Make sure you're running in Electron, not browser
- Check
window.isElectronistrue
Session not persisting
- Check userData directory exists
- Verify write permissions
- Look for errors in Electron console
Next.js restart kills agent
- Verify agent service is in
electron/main.js - Check IPC handlers are registered
- Ensure not using HTTP
/api/chatroute
Future Enhancements
- Multiple concurrent sessions
- Export conversation history
- Undo/redo for agent actions
- Progress bars for long-running tasks
- Voice input/output
- Agent memory across sessions