# OpenCode Process Manager ## Overview This document explains the OpenCode Process Manager implementation, which optimizes resource usage by managing OpenCode sessions through a singleton instance manager. ## Problem Statement Previously, the application spawned a **new OpenCode process for every message** sent by users. This meant: - Multiple concurrent sessions resulted in dozens of separate OpenCode processes - High memory and CPU overhead from process spawning - No process reuse or pooling - Inefficient resource utilization ## Solution The `OpencodeProcessManager` class provides a singleton manager that: 1. **Tracks all OpenCode sessions** in a centralized location 2. **Monitors process execution** with detailed logging 3. **Prepares for future optimization** when OpenCode supports server/daemon mode 4. **Falls back gracefully** to per-message spawning when server mode is unavailable ## Current Implementation ### Architecture ``` ┌─────────────────────────────────────┐ │ Multiple User Sessions │ │ (Session A, B, C, D...) │ └───────────┬─────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ OpencodeProcessManager (Singleton) │ │ - Tracks all sessions │ │ - Monitors execution │ │ - Manages process lifecycle │ └───────────┬─────────────────────────┘ │ ▼ ┌─────────────────────────────────────┐ │ OpenCode CLI Execution │ │ (Currently: per-message processes) │ │ (Future: single daemon instance) │ └─────────────────────────────────────┘ ``` ### Key Features 1. **Singleton Pattern**: Only one `OpencodeProcessManager` instance exists across the entire application 2. **Session Tracking**: Maps session IDs to their workspace directories 3. **Process Monitoring**: Logs execution time, active processes, and resource usage 4. **Graceful Degradation**: Falls back to per-message spawning if server mode unavailable 5. **Lifecycle Management**: Properly initialized on startup and cleaned up on shutdown ### Code Locations - **Manager Class**: Lines ~575-836 in [server.js](chat/server.js) - **Singleton Instance**: Line ~838 in [server.js](chat/server.js) - **Integration**: Line ~6165 in [server.js](chat/server.js) (sendToOpencode function) - **Initialization**: Lines ~11239-11246 in [server.js](chat/server.js) (bootstrap function) - **Shutdown**: Line ~981 in [server.js](chat/server.js) (gracefulShutdown function) - **Status Endpoint**: Lines ~9832-9867 in [server.js](chat/server.js) ## Current Behavior ### What Happens Now Since OpenCode doesn't currently support a persistent server/daemon mode, the manager: 1. **Tracks each execution** with detailed logging 2. **Reports statistics** via the `/api/opencode/status` endpoint 3. **Routes through `executeStandalone`** which spawns per-message processes 4. **Logs process lifecycle** (start, duration, completion) This provides: - ✅ Better visibility into OpenCode usage - ✅ Centralized execution management - ✅ Foundation for future optimization - ⚠️ Still spawns separate processes per message (but tracked) ## Future Optimization ### When OpenCode Adds Server Mode If/when OpenCode supports a persistent server/daemon mode (e.g., `opencode serve` or `opencode daemon`): 1. **Update `getServerModeArgs()`** to return the correct command arguments 2. **The manager will automatically**: - Start a single OpenCode process on server startup - Route all sessions through this single instance - Maintain persistent connections - Dramatically reduce resource overhead ### Expected Benefits (Future) When server mode is available: - **90%+ reduction** in process spawning overhead - **Faster response times** (no process startup delay) - **Lower memory usage** (one process vs. many) - **Better session continuity** (persistent state) ## Monitoring ### Status Endpoint Check OpenCode manager status: ```bash curl http://localhost:3000/api/opencode/status ``` Response includes: ```json { "available": true, "version": "...", "runningProcesses": 3, "activeStreams": 2, "processManager": { "isRunning": false, "isReady": true, "pendingRequests": 0, "activeSessions": 5, "lastActivity": 1234567890, "idleTime": 1234, "mode": "per-session", "description": "Each message spawns separate OpenCode process" } } ``` ### Logging The manager logs: - Process execution start/end - Duration of each command - Active process count - Session workspace mapping - Errors and failures Look for log entries with: - `"OpenCode process manager..."` - `"Executing OpenCode command (standalone)"` - `"OpenCode command completed"` ## Implementation Details ### OpencodeProcessManager Class #### Properties - `process`: Reference to the persistent OpenCode process (when in server mode) - `isReady`: Boolean indicating if the manager is ready to accept requests - `pendingRequests`: Map of in-flight requests awaiting responses - `sessionWorkspaces`: Map of session IDs to their workspace directories - `lastActivity`: Timestamp of last activity (for idle detection) - `heartbeatInterval`: Timer for keeping persistent connection alive #### Methods **`start()`** - Initializes the manager - Attempts to start OpenCode in server mode - Falls back to per-session mode if unavailable **`executeInSession(sessionId, workspaceDir, command, args, options)`** - Main execution method - Routes through persistent process (future) or standalone spawning (current) - Tracks session -> workspace mapping **`executeStandalone(workspaceDir, command, args, options)`** - Current fallback implementation - Spawns individual OpenCode process - Logs execution metrics **`stop()`** - Gracefully shuts down manager - Terminates persistent process if running - Cleans up resources **`getStats()`** - Returns current manager statistics - Used by monitoring endpoint ### Integration Points 1. **Bootstrap** (startup): Manager initialized after all state is loaded 2. **sendToOpencode**: Routes all OpenCode executions through manager 3. **gracefulShutdown**: Stops manager before server shutdown 4. **Status endpoint**: Exposes manager statistics ## Testing ### Verify Installation 1. Start the server: ```bash node chat/server.js ``` 2. Check the logs for: ``` Initializing OpenCode process manager... OpenCode does not support server mode, will use per-session approach OpenCode process manager initialized ``` 3. Check status endpoint: ```bash curl http://localhost:3000/api/opencode/status | jq . ``` 4. Send a message in a session and observe logs: ``` Executing OpenCode command (standalone) { processId: '...', activeProcesses: 1 } OpenCode command completed { processId: '...', duration: 1234 } ``` ### Multiple Concurrent Sessions 1. Open multiple builder sessions in different browser tabs 2. Send messages in each 3. Check `/api/opencode/status` to see `runningProcesses` count 4. Each process should be logged with start/end times ## Configuration No configuration required. The manager automatically: - Detects if OpenCode supports server mode - Falls back to per-session spawning - Adapts to available capabilities ## Performance Impact ### Current (Per-Session Mode) - ✅ Better tracking and visibility - ✅ Centralized management - ✅ Foundation for future optimization - ➖ No performance improvement yet (still spawns separate processes) ### Future (Server Mode) - ✅ 90%+ reduction in process overhead - ✅ Faster response times - ✅ Lower memory usage - ✅ Better resource utilization ## Migration Notes This change is **backward compatible**: - No changes to session management - No changes to API endpoints (except enhanced status response) - No changes to client behavior - Existing sessions continue to work ## Troubleshooting ### Manager Not Starting Check logs for: `"OpenCode process manager initialization failed"` - This is expected if OpenCode doesn't support server mode - Manager falls back to per-session spawning automatically ### Multiple Processes Still Running This is **expected behavior** in current mode: - Each message spawns a separate process - This will change when OpenCode adds server mode support - All processes are now tracked and logged ### Status Endpoint Not Responding 1. Verify server is running 2. Check that route is registered in `routeInternal()` 3. Look for initialization errors in logs ## Future Enhancements 1. **Add Server Mode Support**: Update `getServerModeArgs()` when available 2. **Request Batching**: Queue and batch multiple requests 3. **Connection Pooling**: Maintain pool of persistent connections 4. **Load Balancing**: Distribute across multiple OpenCode instances 5. **Health Checks**: Monitor and restart unresponsive instances ## Summary The OpenCode Process Manager provides: - ✅ Centralized session management - ✅ Comprehensive execution tracking - ✅ Foundation for future optimization - ✅ Graceful fallback to current behavior - ✅ Enhanced monitoring and debugging While currently operating in per-session mode, it's ready to leverage OpenCode's server mode as soon as it becomes available, providing significant resource savings and performance improvements.