mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 14:22:02 +00:00
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
286 lines
7.8 KiB
Markdown
286 lines
7.8 KiB
Markdown
# Agent Architecture - Surviving Next.js Restarts
|
|
|
|
## Problem Statement
|
|
|
|
When using the Automaker app to iterate on itself:
|
|
|
|
1. Agent modifies code files
|
|
2. Next.js hot-reloads and restarts
|
|
3. API routes are killed
|
|
4. 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 session
|
|
- `agent:send` - Send a message (returns immediately)
|
|
- `agent:getHistory` - Retrieve conversation history
|
|
- `agent:stop` - Stop current execution
|
|
- `agent:clear` - Clear conversation
|
|
- `agent:stream` - Event emitted for streaming updates
|
|
|
|
### 3. Preload Bridge (`electron/preload.js`)
|
|
|
|
Secure IPC bridge exposed to renderer:
|
|
|
|
```javascript
|
|
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:
|
|
|
|
```typescript
|
|
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
|
|
|
|
1. User types message in React UI
|
|
2. `sendMessage()` calls `window.electronAPI.agent.send()`
|
|
3. IPC handler in main process receives message
|
|
4. Agent service starts processing
|
|
5. Main process streams updates via `agent:stream` events
|
|
6. React hook receives events and updates UI
|
|
7. Conversation saved to disk
|
|
|
|
### Surviving a Restart
|
|
|
|
1. Agent is modifying code → Next.js restarts
|
|
2. React component unmounts
|
|
3. **Main process keeps running** (agent continues)
|
|
4. React component remounts after restart
|
|
5. Calls `agent:start` with same session ID
|
|
6. Main process returns full conversation history
|
|
7. Subscribes to `agent:stream` events
|
|
8. UI shows complete conversation + live updates
|
|
|
|
## Session Storage
|
|
|
|
Sessions are stored in:
|
|
|
|
```
|
|
<userData>/agent-sessions/<sessionId>.json
|
|
```
|
|
|
|
Each session file contains:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"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:
|
|
|
|
```typescript
|
|
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:
|
|
|
|
```javascript
|
|
{
|
|
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:
|
|
|
|
1. Open a project in Automaker
|
|
2. Ask the agent to modify a file in `src/`
|
|
3. Watch Next.js restart
|
|
4. Verify the conversation continues
|
|
5. Check that history is preserved
|
|
6. Restart the entire Electron app
|
|
7. Verify conversation loads from disk
|
|
|
|
## Troubleshooting
|
|
|
|
### "Electron API not available"
|
|
|
|
- Make sure you're running in Electron, not browser
|
|
- Check `window.isElectron` is `true`
|
|
|
|
### 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/chat` route
|
|
|
|
## 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
|