Plugin System
Mia’s plugin system abstracts AI providers behind a common interface. You can swap between backends without changing your workflow, and configure automatic fallback chains.
Plugin Interface
Section titled “Plugin Interface”Every plugin implements the CodingPlugin interface:
interface CodingPlugin { name: string version: string initialize(config: PluginConfig): Promise<void> dispatch(prompt, context, options, callbacks): Promise<PluginDispatchResult> isAvailable(): Promise<boolean> getSession(conversationId: string): string | undefined clearSession(conversationId: string): void abort(taskId: string): Promise<void> getRunningTaskCount(): number cleanup(maxAgeMs?: number): number}Key Methods
Section titled “Key Methods”| Method | Purpose |
|---|---|
dispatch() | Send a prompt with context, receive streamed response |
isAvailable() | Check if the plugin’s binary/API is accessible |
getSession() | Retrieve session state for multi-turn conversations |
abort() | Cancel a running dispatch |
cleanup() | Remove stale sessions older than threshold |
Available Plugins
Section titled “Available Plugins”Claude Code
Section titled “Claude Code”- Binary:
claude - Provider: Anthropic
- Features: Session resumption, tool use, multi-turn context
- Auth: Claude Max/Pro browser login or
ANTHROPIC_API_KEY
OpenAI Codex
Section titled “OpenAI Codex”- Binary:
codex - Provider: OpenAI
- Features: CLI-based dispatch, streaming output
- Auth:
OPENAI_API_KEY
Google Gemini
Section titled “Google Gemini”- Binary:
gemini(CLI) or API - Provider: Google
- Features: OAuth authentication, large context windows
- Auth:
GEMINI_API_KEYor browser OAuth flow
OpenCode
Section titled “OpenCode”- Binary:
opencode - Provider: Various (configurable)
- Features: Multi-provider routing
- Auth: Provider-specific API keys
Plugin Configuration
Section titled “Plugin Configuration”Each plugin is configured in ~/.mia/mia.json:
{ "activePlugin": "claude-code", "fallbackPlugins": ["opencode", "codex"], "plugins": { "claude-code": { "name": "claude-code", "enabled": true, "binary": "claude", "model": "claude-sonnet-4-6-20250929", "maxConcurrency": 3, "timeoutMs": 1800000 }, "gemini": { "name": "gemini", "enabled": true, "model": "gemini-2.5-pro" } }}Dispatch Flow
Section titled “Dispatch Flow”When a prompt is dispatched:
- Load active plugin from registry
- Check availability (cached result, refreshed periodically)
- If unavailable, try fallback chain in order
- Build context (workspace, memory, git state)
- Spawn plugin process or call API
- Stream NDJSON callbacks (tokens, tool calls, results)
- Accumulate output, handle errors
- Capture git changes made during dispatch
Base Spawn Plugin
Section titled “Base Spawn Plugin”CLI-based plugins (Claude Code, Codex) share a common base class BaseSpawnPlugin that handles:
- Process spawning with proper environment
- Stdin/stdout streaming (NDJSON protocol)
- Session management (resume conversation by ID)
- Timeout handling (kill process after configurable duration)
- Stall detection (kill if no output for 120 seconds)
- Concurrency limiting
Fallback Chain
Section titled “Fallback Chain”When the active plugin fails or is unavailable:
Active plugin → Fallback #1 → Fallback #2 → ErrorConfigure in mia.json:
{ "activePlugin": "claude-code", "fallbackPlugins": ["gemini", "codex"], "pluginDispatch": { "fallback": { "enabled": true, "onDispatchError": false } }}enabled: Activate fallback for availability failuresonDispatchError: Also retry fallback chain on dispatch errors (aggressive)
Error Handling
Section titled “Error Handling”All plugins throw standardized PluginError with error codes:
| Code | Meaning |
|---|---|
TIMEOUT | Plugin didn’t respond within timeout |
SPAWN_FAILURE | Couldn’t start the plugin process |
PROCESS_EXIT | Plugin process exited unexpectedly |
BUFFER_OVERFLOW | Output exceeded buffer limits |
CONCURRENCY_LIMIT | Max concurrent tasks reached |
PROVIDER_ERROR | AI provider returned an error |
SESSION_ERROR | Session state issue |
UNKNOWN | Catch-all |