# OpenClaw Parity Design: Flynn Feature Roadmap ## Overview Plan to evolve Flynn from a multi-model chat wrapper into a full self-hosted OpenClaw alternative. Bottom-up approach: tools first, then gateway, then channels, then skills/advanced features. **Build approach**: Use Sonnet/Haiku via GitHub Copilot for implementation subagents. **Current state**: Flynn v0.1.0 covers ~22% of OpenClaw features. Strong in model routing (4 providers, tiered fallback) and session management (SQLite, transfer). Zero tool execution capability. --- ## Phase 1: Agent Tool Framework + Agent Loop **Goal**: Turn Flynn from a chatbot into an agent that can execute tools with multi-step reasoning. ### 1.1 Tool Definition System ``` src/tools/ ├── types.ts # Tool, ToolCall, ToolResult interfaces ├── registry.ts # ToolRegistry: register, lookup, list, serialize for providers ├── executor.ts # ToolExecutor: run tools, enforce hooks, timeout, truncation ├── builtin/ │ ├── shell.ts # shell.exec - run bash commands (cwd, timeout, max output) │ ├── file-read.ts # file.read - read file contents (path, offset, limit) │ ├── file-write.ts # file.write - write/create files (path, content) │ ├── file-edit.ts # file.edit - find-and-replace (path, oldString, newString) │ ├── file-list.ts # file.list - glob/list directory (pattern, path) │ └── web-fetch.ts # web.fetch - HTTP GET with markdown conversion (url, format) ``` **Tool interface**: ```typescript interface Tool { name: string; // e.g. "shell.exec" description: string; // For the model's tool selection inputSchema: Record; // JSON Schema for parameters execute(args: unknown): Promise; } interface ToolResult { success: boolean; output: string; error?: string; } interface ToolCall { id: string; // Provider-assigned call ID name: string; // Tool name args: unknown; // Parsed arguments } ``` **ToolRegistry**: Collects tools, serializes to Anthropic format (`{ name, description, input_schema }`) or OpenAI format (`{ type: "function", function: { name, description, parameters } }`). **ToolExecutor**: Wraps execution with: - Hook engine check (confirm/log/silent) before execution - Configurable timeout (default 30s for shell, 10s for file ops) - Output truncation (max 50KB, with "truncated" marker) - Error capture (catches exceptions, returns as ToolResult.error) ### 1.2 Model Provider Tool Support Update `ChatRequest` to accept optional `tools: Tool[]`. **Anthropic** (`src/models/anthropic.ts`): - Pass tools as `tools` parameter to `messages.create()`/`messages.stream()` - Parse `tool_use` content blocks from response (id, name, input) - Accept `tool_result` content blocks in messages (tool_use_id, content) - Handle `stop_reason: "tool_use"` to signal tool call response **OpenAI** (`src/models/openai.ts`): - Pass tools as `tools` parameter with `type: "function"` wrapper - Parse `tool_calls` from response choices - Accept `role: "tool"` messages with `tool_call_id` - Handle `finish_reason: "tool_calls"` to signal tool call response **Types updates** (`src/models/types.ts`): - Add `ToolCall` to `ChatResponse` - Add `tool_use` and `tool_result` message roles - Add `tools` to `ChatRequest` - Add `tool_calls` stream event type ### 1.3 Agent Loop Replace single-turn NativeAgent with iterative tool-use loop: ``` User message -> Model call (with tools in request) -> If response contains tool_use: -> For each tool call: -> Check hooks (confirm/log/silent) -> If confirm: wait for approval (Telegram inline keyboard / TUI prompt) -> Execute tool via ToolExecutor -> Collect ToolResult -> Append tool_results to conversation -> Loop back to model call -> If text response (no tool_use): -> Return final response to user -> If max iterations reached (default 10): -> Return partial response with warning ``` **Streaming during tool execution**: Emit status events: - `{ event: "tool_start", tool: "shell.exec", args: { command: "ls" } }` - `{ event: "tool_end", tool: "shell.exec", result: { success: true, output: "..." } }` - These render as status lines in TUI and Telegram **Abort support**: - TUI: Escape key sets abort flag, checked before each tool execution - Telegram: `/cancel` command sets abort flag on active session - Agent loop checks abort flag before each iteration ### 1.4 Frontend Updates **Telegram**: - Show tool execution as status messages ("Running shell.exec: `ls -la`...") - Confirmation buttons already exist, wire to tool executor - Show final response after tool loop completes **TUI (both modes)**: - Show tool calls inline with dimmed formatting - Show tool results with output (truncated in UI if long) - Streaming text interleaved with tool status - Escape aborts the agent loop ### 1.5 Deliverables - [ ] `src/tools/types.ts` - Tool, ToolCall, ToolResult interfaces - [ ] `src/tools/registry.ts` - ToolRegistry with provider serialization - [ ] `src/tools/executor.ts` - ToolExecutor with hooks, timeout, truncation - [ ] `src/tools/builtin/shell.ts` - Shell exec tool - [ ] `src/tools/builtin/file-read.ts` - File read tool - [ ] `src/tools/builtin/file-write.ts` - File write tool - [ ] `src/tools/builtin/file-edit.ts` - File edit tool - [ ] `src/tools/builtin/file-list.ts` - File list/glob tool - [ ] `src/tools/builtin/web-fetch.ts` - Web fetch tool - [ ] `src/models/types.ts` - Add tool-related types - [ ] `src/models/anthropic.ts` - Add tool use support - [ ] `src/models/openai.ts` - Add tool use support - [ ] `src/backends/native/agent.ts` - Agent loop with tool execution - [ ] `src/frontends/telegram/bot.ts` - Tool status messages - [ ] `src/frontends/tui/minimal.ts` - Tool display in minimal TUI - [ ] `src/frontends/tui/components/App.tsx` - Tool display in fullscreen TUI - [ ] Tests for all new modules --- ## Phase 2: WebSocket Gateway **Goal**: Central control plane that multiple clients connect to. Decouples frontends from the agent. ### 2.1 Gateway Core ``` src/gateway/ ├── server.ts # WebSocket server (ws library), configurable port ├── protocol.ts # JSON-RPC-style message types ├── router.ts # Routes methods to handlers ├── auth.ts # Token + password auth, Tailscale identity headers ├── session-bridge.ts # Maps WS client connections to sessions └── handlers/ ├── agent.ts # agent.send, agent.cancel, agent.status ├── sessions.ts # sessions.list, sessions.history, sessions.send ├── tools.ts # tools.list, tools.invoke ├── config.ts # config.get, config.patch └── system.ts # system.health, system.restart ``` ### 2.2 Protocol JSON-RPC-like over WebSocket: ``` Request: { id: number, method: string, params: object } Response: { id: number, result: object } Error: { id: number, error: { code: number, message: string } } Event: { id: number, event: string, data: object } // streaming ``` Event types for agent.send streaming: - `content` - text chunk from model - `tool_start` - tool execution beginning - `tool_end` - tool execution complete - `thinking` - model reasoning (if exposed) - `done` - final response ### 2.3 Control UI Minimal web dashboard served from gateway port: ``` src/gateway/ui/ ├── index.html # Dashboard: sessions, model info, config ├── chat.html # WebChat: WS-connected chat interface └── assets/ # CSS + minimal JS (no framework, or Preact) ``` ### 2.4 Daemon Refactor Gateway becomes the hub: - Owns session manager, tool registry, model router - Telegram adapter connects as a gateway client (in-process bridge) - TUI connects as a gateway client (in-process or WS) - WebChat connects via WS from browser ### 2.5 Deliverables - [ ] `src/gateway/server.ts` - WebSocket server - [ ] `src/gateway/protocol.ts` - Message type definitions - [ ] `src/gateway/router.ts` - Method routing - [ ] `src/gateway/auth.ts` - Authentication - [ ] `src/gateway/session-bridge.ts` - Client-to-session mapping - [ ] Gateway handlers (agent, sessions, tools, config, system) - [ ] `src/gateway/ui/` - Control UI + WebChat - [ ] Refactor daemon to use gateway as hub - [ ] Refactor Telegram as gateway client - [ ] Tests for gateway protocol and handlers --- ## Phase 3: Channel Adapters **Goal**: Multi-channel inbox. One assistant accessible from WhatsApp, Telegram, Discord, Slack, and WebChat. ### 3.1 Channel Adapter Interface ``` src/channels/ ├── types.ts # ChannelAdapter interface ├── registry.ts # ChannelRegistry: load/unload at runtime ├── telegram/ # Refactored from src/frontends/telegram/ ├── discord/ # discord.js ├── whatsapp/ # Baileys ├── slack/ # Bolt (Socket Mode) └── webchat/ # Gateway WS built-in ``` **ChannelAdapter interface**: ```typescript interface ChannelAdapter { name: string; connect(): Promise; disconnect(): Promise; send(peerId: string, message: OutboundMessage): Promise; onMessage(handler: (msg: InboundMessage) => void): void; } ``` ### 3.2 Build Order 1. Telegram (refactor existing) 2. Discord (discord.js) 3. WhatsApp (Baileys) 4. Slack (Bolt Socket Mode) 5. WebChat (gateway built-in) ### 3.3 Security Per Channel Every adapter implements: - DM pairing: unknown senders get pairing code, must be approved via CLI/UI - Allowlists: `channels..allowFrom` config array - Group mention gating: `channels..groups.*.requireMention` - Rate limiting: per-sender throttle (configurable) - Message size limits per channel ### 3.4 Deliverables - [ ] `src/channels/types.ts` - ChannelAdapter interface - [ ] `src/channels/registry.ts` - Channel registry - [ ] `src/channels/telegram/` - Refactored Telegram adapter - [ ] `src/channels/discord/` - Discord adapter - [ ] `src/channels/whatsapp/` - WhatsApp adapter - [ ] `src/channels/slack/` - Slack adapter - [ ] `src/channels/webchat/` - WebChat adapter - [ ] DM pairing system - [ ] Per-channel security (allowlists, mention gating, rate limiting) - [ ] Tests per adapter --- ## Phase 4: Skills + MCP **Goal**: Extensible capability system with community skills and MCP tool servers. ### 4.1 Skills System ``` src/skills/ ├── types.ts # Skill, SkillManifest interfaces ├── loader.ts # Load SKILL.md + scripts from skill directories ├── registry.ts # Discovery, gating (OS/bin/env checks) └── installer.ts # Auto-install dependencies (with user confirmation) ``` Skill directory structure: ``` ~/.flynn/workspace/skills// ├── SKILL.md # Instructions injected into system prompt ├── manifest.json # Requirements, permissions, dependencies └── scripts/ # Executable helpers ``` Three tiers: bundled (shipped with Flynn), managed (installed via CLI), workspace (user-created). ### 4.2 MCP Integration ``` src/mcp/ ├── client.ts # MCP client (stdio transport) ├── bridge.ts # Convert MCP tools -> Flynn tool registry entries └── manager.ts # Lifecycle: start/stop/restart MCP servers per config ``` Wire the existing `mcp.servers` config to actually start MCP server processes, discover their tools, and register them in the tool registry. MCP tools appear alongside builtins -- the agent doesn't know the difference. ### 4.3 Deliverables - [ ] Skills types, loader, registry, installer - [ ] MCP client, bridge, manager - [ ] Wire MCP config to runtime - [ ] Bundled skills (at least: web-search, git, system-info) - [ ] Tests --- ## Phase 5: Advanced Features Build after core is solid. Each is independent. | Feature | Module | Description | |---------|--------|-------------| | Cron/scheduling | `src/automation/cron.ts` | Cron expressions trigger agent messages | | Webhooks | `src/automation/webhooks.ts` | Inbound HTTP triggers | | Browser tool | `src/tools/builtin/browser.ts` | Playwright headless browser | | Agent-to-agent | `sessions_list/history/send` tools | Multi-agent coordination | | Sub-agents | `src/backends/native/subagent.ts` | Spawn scoped child sessions | | Sandboxing | `src/sandbox/` | Docker per-session isolation | | Voice | `src/voice/` | STT (Whisper) + TTS (ElevenLabs) | | Canvas/A2UI | `src/gateway/ui/canvas/` | Agent-driven web workspace | | CLI surface | `src/cli/` | `flynn gateway`, `flynn agent`, `flynn send`, etc. | | Mobile nodes | Separate repos | iOS (Swift) + Android (Kotlin) companion apps | | Onboarding wizard | `src/cli/onboard.ts` | Guided setup flow | | Doctor diagnostics | `src/cli/doctor.ts` | Config + health validation | --- ## Implementation Notes ### Model Selection for Subagents Use cheaper/faster models via GitHub Copilot for implementation: - **Sonnet**: Complex implementation tasks (agent loop, gateway, protocol) - **Haiku**: Mechanical tasks (individual tool implementations, adapter boilerplate, tests) - **Opus**: Design review, architecture decisions only ### Testing Strategy - Unit tests for all tools (mock filesystem/network) - Unit tests for tool registry serialization (Anthropic + OpenAI formats) - Integration tests for agent loop (mock model returns tool_use, verify execution) - Integration tests for gateway protocol (WS client/server) - E2E tests for tool execution (real shell commands in temp dirs) ### Migration Path - Phase 1 is additive (no breaking changes to existing code) - Phase 2 refactors daemon (breaking, but internal only) - Phase 3 moves Telegram (file rename, adapter interface) - Each phase is a separate feature branch --- *Design Version: 1.0* *Created: 2026-02-05* *Approach: Bottom-up (tools -> gateway -> channels -> skills -> advanced)*