Local branch had diverged from origin/master (sibling commits on the same base). Rewrote local history linearly on top of origin/master, folding in all local content: exa/hot-platform discovery hunters, leaks ledger, nightly sweep orchestrator, updated .gitignore and skill docs, plus the latest hunt output and vault state. Remote-only files (vault keys, channel scripts) were restored rather than dropped, so the resulting tree is a full union of both sides.
1 line
527 KiB
JSON
1 line
527 KiB
JSON
{"repo": "14790897/miqi", "files": {"README.md": {"082a61c2945e6d4512a82b82cf49602eeb37f31f": {"t": 1785747242.618759, "n": 13890, "h": "766f8be98a28949e", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n#### E2E Tests\n\n```bash\n# Electron E2E (full desktop app + bridge + LLM)\ncd apps/desktop\nnpm run build && npx playwright test --config=playwright.config.ts --project=electron\n```\n\n| Platform | E2E Coverage | Notes |\n|---|---|---|\n| **Linux** (Ubuntu CI) | Full suite ✓ | bwrap sandbox + all specs |\n| **Windows** (WSL CI) | Full suite ✓ | WSL bwrap sandbox + all specs (needs `MIQI_RUN_SANDBOX_E2E=1`) |\n| **macOS** (CI) | Non-sandbox only | bwrap not available; sandbox specs excluded via `--grep-invert` |\n\n> **macOS known limitation**: The \"restart recall\" E2E test (`session-context-recall.spec.ts`) is skipped only when `process.env.CI && process.platform === 'darwin'` (local macOS runs still exercise the test). After a full app restart on macOS ARM64 CI runners, session history (chat messages) fails to render in `<main>` even though the sidebar session title loads correctly and the bridge reports `running / initialized`. This is likely a bridge IPC timing issue or APFS/SQLite WAL checkpoint race on cold start — needs native debugging. The non-restart session-switch recall test still validates #490 behavior on macOS.\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\ntest\n"}, "ecaed54ff6b58ac6688c6e33f1d40d54daef4dd2": {"t": 1785771663.7472968, "n": 13890, "h": "766f8be98a28949e", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n#### E2E Tests\n\n```bash\n# Electron E2E (full desktop app + bridge + LLM)\ncd apps/desktop\nnpm run build && npx playwright test --config=playwright.config.ts --project=electron\n```\n\n| Platform | E2E Coverage | Notes |\n|---|---|---|\n| **Linux** (Ubuntu CI) | Full suite ✓ | bwrap sandbox + all specs |\n| **Windows** (WSL CI) | Full suite ✓ | WSL bwrap sandbox + all specs (needs `MIQI_RUN_SANDBOX_E2E=1`) |\n| **macOS** (CI) | Non-sandbox only | bwrap not available; sandbox specs excluded via `--grep-invert` |\n\n> **macOS known limitation**: The \"restart recall\" E2E test (`session-context-recall.spec.ts`) is skipped only when `process.env.CI && process.platform === 'darwin'` (local macOS runs still exercise the test). After a full app restart on macOS ARM64 CI runners, session history (chat messages) fails to render in `<main>` even though the sidebar session title loads correctly and the bridge reports `running / initialized`. This is likely a bridge IPC timing issue or APFS/SQLite WAL checkpoint race on cold start — needs native debugging. The non-restart session-switch recall test still validates #490 behavior on macOS.\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\ntest\n"}, "4f0e4b608b4e387e25d118c68fc740ac3a178aaf": {"t": 1785771665.4658759, "n": 12757, "h": "d4c907dfb99f861b", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\ntest\n"}, "530b35cde35ab21d314e05287a1d57dcc56ea634": {"t": 1785771667.168424, "n": 12752, "h": "35fe7564f1abe700", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "97781a2eb2cd78c191220f7275f4465e107fc5ec": {"t": 1785771670.0329354, "n": 7317, "h": "5df9d1e2f0ff88e6", "c": "# MiQi Desktop\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with AI agent |\n| **Multi-provider Support** | Supports OpenAI, Anthropic, Gemini, OpenRouter, and more LLM providers |\n| **Multi-channel** | Connect via Feishu, WeChat, DingTalk and more message channels |\n| **Memory System** | Manage long-term memory snapshots and self-improvement lessons |\n| **Session Management** | Browse, search, and compact conversation history |\n| **Task Scheduler** | Create and manage scheduled tasks (Cron support) |\n| **Skill System** | Configure and enable various agent skills |\n| **Sandbox Isolation** | Per-session bwrap sandbox on WSL2 for safe code execution |\n| **File Management** | Workspace file system operations |\n| **Real-time Logs** | Monitor agent activity and debug information |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** - Required to run MiQi backend\n- **Node.js 20+** - Required to run Electron frontend\n- **uv** - Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Usage Guide\n\n### First Run\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n\n### Core Features\n\n**Chat Interface**\n- Markdown format support\n- Real-time tool call progress\n- Code syntax highlighting\n\n**Provider Management**\n- Add/edit LLM provider configurations\n- Test connection status\n- Switch default models\n\n**Memory Management**\n- View long-term memory snapshots\n- Manage self-improvement lessons\n- Import/export memory data\n\n**Task Scheduler**\n- Create scheduled tasks (Cron expressions supported)\n- Enable/disable tasks\n- Manually trigger task execution\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json` and contains the following main configuration options:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"gpt-4o\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 50\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React + TypeScript │\n│ ├── Tailwind CSS │\n│ └── Radix UI Components │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdout/stderr JSON protocol │\n│ ├── State synchronization │\n│ └── Log forwarding │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Python Runtime │\n│ ├── AgentLoop (Core agent engine) │\n│ ├── Memory System │\n│ ├── Tool Registry │\n│ ├── Provider Interface │\n│ └── Channel Bus (Feishu / WeChat / DingTalk) │\n├─────────────────────────────────────────────────────────────┤\n│ Sandbox Layer (WSL2 + bwrap) │\n│ ├── Per-session isolation │\n│ ├── Filesystem sandboxing │\n│ └── Safe code execution │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend code\n│ ├── agent/ # Core agent logic & tool registry\n│ ├── bridge/ # Bridge service for Electron communication\n│ ├── providers/ # LLM provider implementations\n│ ├── channels/ # Message channel adapters (Feishu/WeChat/DingTalk)\n│ ├── sandbox/ # bwrap sandbox manager (WSL2)\n│ └── ...\n├── apps/\n│ └── desktop/ # Electron frontend application\n│ ├── src/\n│ │ ├── main/ # Main process (IPC handlers, BridgeManager)\n│ │ ├── renderer/ # Renderer process (React UI)\n│ │ └── preload/ # Preload scripts (contextBridge)\n│ └── electron-builder.yml\n└── ...\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests\nuv run pytest\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "648d711b0acc0160cdd515265c3d7ef99f3166d7": {"t": 1785771672.2682447, "n": 12796, "h": "54798a9c2dc6b31a", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi is a personal AI agent framework that combines a powerful **Python runtime engine** with an **Electron desktop application**. It provides a typed application server protocol, request validation, multi-provider LLM support, sandboxed command execution, and a plugin/skills ecology — all with a local-first, privacy-respecting architecture.\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "fb5b53c93bf536b16ffe3be2f5806e3f49a6b7b9": {"t": 1785771674.5593827, "n": 12770, "h": "84be61bfad84c40e", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi is a personal AI agent framework that combines a powerful **Python runtime engine** with an **Electron desktop application**. It provides a typed application server protocol, request validation, multi-provider LLM support, sandboxed command execution, and a plugin/skills ecology — all with a local-first, privacy-respecting architecture.\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "a09ba1e0bf0b59608c9b3e1cac8352b9c0b5263f": {"t": 1785771675.750211, "n": 11782, "h": "7aa076fb17aaaea2", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi is a personal AI agent framework that combines a powerful **Python runtime engine** with an **Electron desktop application**. It provides a typed application server protocol, request validation, multi-provider LLM support, sandboxed command execution, and a plugin/skills ecology — all with a local-first, privacy-respecting architecture.\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n```bash\n# Build frontend code\ncd apps/desktop\nnpm run build\n\n# Package as desktop application\nnpx electron-builder\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "bb6122c0c4edc55e69c1fe2122effbefbbadbed1": {"t": 1785771677.2536845, "n": 10734, "h": "e3759b6ede0876ab", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi is a personal AI agent framework that combines a powerful **Python runtime engine** with an **Electron desktop application**. It provides a Codex-style application server protocol, typed request validation, multi-provider LLM support, sandboxed command execution, and a plugin/skills ecology — all with a local-first, privacy-respecting architecture.\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Codex-Style Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Codex Protocol** | Typed AppServer with 31 method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n```bash\n# Build frontend code\ncd apps/desktop\nnpm run build\n\n# Package as desktop application\nnpx electron-builder\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Codex-Style Protocol) │\n│ ├── ProtocolRegistry (31 typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Turn Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n### Codex Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── execution/ # Sandbox, permissions, approval, hooks\n│ ├── providers/ # LLM provider implementations\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ └── observability/ # OpenTelemetry integration\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~1800+ tests)\n│ ├── runtime/ # Runtime unit and integration tests\n│ └── bridge/ # Bridge protocol and audit tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "20f2b10f4c648b045b76eb1690cd435ef12b7f67": {"t": 1785771679.1773524, "n": 5721, "h": "518cee9080a4b81d", "c": "# MiQi Desktop\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with AI agent |\n| **Multi-provider Support** | Supports OpenAI, Anthropic, Gemini, OpenRouter, and more LLM providers |\n| **Memory System** | Manage long-term memory snapshots and self-improvement lessons |\n| **Session Management** | Browse, search, and compact conversation history |\n| **Task Scheduler** | Create and manage scheduled tasks (Cron support) |\n| **Skill System** | Configure and enable various agent skills |\n| **File Management** | Workspace file system operations |\n| **Real-time Logs** | Monitor agent activity and debug information |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** - Required to run MiQi backend\n- **Node.js 20+** - Required to run Electron frontend\n- **uv** - Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n```bash\n# Build frontend code\ncd apps/desktop\nnpm run build\n\n# Package as desktop application\nnpx electron-builder\n```\n\n---\n\n## Usage Guide\n\n### First Run\n\n1. Launch the application\n2. Go through the setup wizard\n3. Configure LLM providers (e.g., OpenAI, OpenRouter)\n4. Enter your API keys\n5. Start chatting with the AI agent\n\n### Core Features\n\n**Chat Interface**\n- Markdown format support\n- Real-time tool call progress\n- Code syntax highlighting\n\n**Provider Management**\n- Add/edit LLM provider configurations\n- Test connection status\n- Switch default models\n\n**Memory Management**\n- View long-term memory snapshots\n- Manage self-improvement lessons\n- Import/export memory data\n\n**Task Scheduler**\n- Create scheduled tasks (Cron expressions supported)\n- Enable/disable tasks\n- Manually trigger task execution\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json` and contains the following main configuration options:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"gpt-4o\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 50\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React + TypeScript │\n│ ├── Tailwind CSS │\n│ └── shadcn/ui Components │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdout/stderr JSON protocol │\n│ ├── State synchronization │\n│ └── Log forwarding │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Python Runtime │\n│ ├── RuntimeSession/TaskRunner/TurnRunner (Core runtime engine) │\n│ ├── Memory System │\n│ ├── Tool Registry │\n│ └── Provider Interface │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend code\n│ ├── agent/ # Core agent logic\n│ ├── bridge/ # Bridge service for Electron communication\n│ ├── providers/ # LLM provider implementations\n│ └── ...\n├── apps/\n│ └── desktop/ # Electron frontend application\n│ ├── src/\n│ │ ├── main/ # Main process code\n│ │ ├── renderer/ # Renderer process code\n│ │ └── preload/ # Preload scripts\n│ └── electron-builder.yml\n└── ...\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests\nuv run pytest\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "c01c52def1081a335fbada72a144ca631ed3f03d": {"t": 1785771680.719649, "n": 7290, "h": "4c3c61b17e778862", "c": "# MiQi Desktop\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with AI agent |\n| **Multi-provider Support** | Supports OpenAI, Anthropic, Gemini, OpenRouter, and more LLM providers |\n| **Multi-channel** | Connect via Feishu, WeChat, DingTalk and more message channels |\n| **Memory System** | Manage long-term memory snapshots and self-improvement lessons |\n| **Session Management** | Browse, search, and compact conversation history |\n| **Task Scheduler** | Create and manage scheduled tasks (Cron support) |\n| **Skill System** | Configure and enable various agent skills |\n| **Sandbox Isolation** | Per-session bwrap sandbox on WSL2 for safe code execution |\n| **File Management** | Workspace file system operations |\n| **Real-time Logs** | Monitor agent activity and debug information |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** - Required to run MiQi backend\n- **Node.js 20+** - Required to run Electron frontend\n- **uv** - Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Usage Guide\n\n### First Run\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n\n### Core Features\n\n**Chat Interface**\n- Markdown format support\n- Real-time tool call progress\n- Code syntax highlighting\n\n**Provider Management**\n- Add/edit LLM provider configurations\n- Test connection status\n- Switch default models\n\n**Memory Management**\n- View long-term memory snapshots\n- Manage self-improvement lessons\n- Import/export memory data\n\n**Task Scheduler**\n- Create scheduled tasks (Cron expressions supported)\n- Enable/disable tasks\n- Manually trigger task execution\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json` and contains the following main configuration options:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"gpt-4o\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 50\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React + TypeScript │\n│ ├── Tailwind CSS │\n│ └── Radix UI Components │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdout/stderr JSON protocol │\n│ ├── State synchronization │\n│ └── Log forwarding │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Python Runtime │\n│ ├── AgentLoop (Core agent engine) │\n│ ├── Memory System │\n│ ├── Tool Registry │\n│ ├── Provider Interface │\n│ └── Channel Bus (Feishu / WeChat / DingTalk) │\n├─────────────────────────────────────────────────────────────┤\n│ Sandbox Layer (WSL2 + bwrap) │\n│ ├── Per-session isolation │\n│ ├── Filesystem sandboxing │\n│ └── Safe code execution │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend code\n│ ├── agent/ # Core agent logic & tool registry\n│ ├── bridge/ # Bridge service for Electron communication\n│ ├── providers/ # LLM provider implementations\n│ ├── channels/ # Message channel adapters (Feishu/WeChat/DingTalk)\n│ ├── sandbox/ # bwrap sandbox manager (WSL2)\n│ └── ...\n├── apps/\n│ └── desktop/ # Electron frontend application\n│ ├── src/\n│ │ ├── main/ # Main process (IPC handlers, BridgeManager)\n│ │ ├── renderer/ # Renderer process (React UI)\n│ │ └── preload/ # Preload scripts (contextBridge)\n│ └── electron-builder.yml\n└── ...\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests\nuv run pytest\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "3d9e26e5337aa292d5670c770861c1fa1982df43": {"t": 1785771682.2215066, "n": 7086, "h": "fcea5744bf586707", "c": "# MiQi Desktop\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with AI agent |\n| **Multi-provider Support** | Supports OpenAI, Anthropic, Gemini, OpenRouter, and more LLM providers |\n| **Multi-channel** | Connect via Feishu, WeChat, DingTalk and more message channels |\n| **Memory System** | Manage long-term memory snapshots and self-improvement lessons |\n| **Session Management** | Browse, search, and compact conversation history |\n| **Task Scheduler** | Create and manage scheduled tasks (Cron support) |\n| **Skill System** | Configure and enable various agent skills |\n| **Sandbox Isolation** | Per-session bwrap sandbox on WSL2 for safe code execution |\n| **File Management** | Workspace file system operations |\n| **Real-time Logs** | Monitor agent activity and debug information |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** - Required to run MiQi backend\n- **Node.js 20+** - Required to run Electron frontend\n- **uv** - Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Usage Guide\n\n### First Run\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n\n### Core Features\n\n**Chat Interface**\n- Markdown format support\n- Real-time tool call progress\n- Code syntax highlighting\n\n**Provider Management**\n- Add/edit LLM provider configurations\n- Test connection status\n- Switch default models\n\n**Memory Management**\n- View long-term memory snapshots\n- Manage self-improvement lessons\n- Import/export memory data\n\n**Task Scheduler**\n- Create scheduled tasks (Cron expressions supported)\n- Enable/disable tasks\n- Manually trigger task execution\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json` and contains the following main configuration options:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"gpt-4o\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 50\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React + TypeScript │\n│ ├── Tailwind CSS │\n│ └── Radix UI Components │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdout/stderr JSON protocol │\n│ ├── State synchronization │\n│ └── Log forwarding │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Python Runtime │\n│ ├── AgentLoop (Core agent engine) │\n│ ├── Memory System │\n│ ├── Tool Registry │\n│ ├── Provider Interface │\n│ └── Channel Bus (Feishu / WeChat / DingTalk) │\n├─────────────────────────────────────────────────────────────┤\n│ Sandbox Layer (WSL2 + bwrap) │\n│ ├── Per-session isolation │\n│ ├── Filesystem sandboxing │\n│ └── Safe code execution │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend code\n│ ├── agent/ # Core agent logic\n│ ├── bridge/ # Bridge service for Electron communication\n│ ├── providers/ # LLM provider implementations\n│ └── ...\n├── apps/\n│ └── desktop/ # Electron frontend application\n│ ├── src/\n│ │ ├── main/ # Main process code\n│ │ ├── renderer/ # Renderer process code\n│ │ └── preload/ # Preload scripts\n│ └── electron-builder.yml\n└── ...\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests\nuv run pytest\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "d4cf1111ef1c8eccaa7b17c856e9d0be73076798": {"t": 1785771683.5375104, "n": 5716, "h": "54d44dbec9a2a33a", "c": "# MiQi Desktop\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with AI agent |\n| **Multi-provider Support** | Supports OpenAI, Anthropic, Gemini, OpenRouter, and more LLM providers |\n| **Memory System** | Manage long-term memory snapshots and self-improvement lessons |\n| **Session Management** | Browse, search, and compact conversation history |\n| **Task Scheduler** | Create and manage scheduled tasks (Cron support) |\n| **Skill System** | Configure and enable various agent skills |\n| **File Management** | Workspace file system operations |\n| **Real-time Logs** | Monitor agent activity and debug information |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** - Required to run MiQi backend\n- **Node.js 20+** - Required to run Electron frontend\n- **uv** - Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n```bash\n# Build frontend code\ncd apps/desktop\nnpm run build\n\n# Package as desktop application\nnpx electron-builder\n```\n\n---\n\n## Usage Guide\n\n### First Run\n\n1. Launch the application\n2. Go through the setup wizard\n3. Configure LLM providers (e.g., OpenAI, OpenRouter)\n4. Enter your API keys\n5. Start chatting with the AI agent\n\n### Core Features\n\n**Chat Interface**\n- Markdown format support\n- Real-time tool call progress\n- Code syntax highlighting\n\n**Provider Management**\n- Add/edit LLM provider configurations\n- Test connection status\n- Switch default models\n\n**Memory Management**\n- View long-term memory snapshots\n- Manage self-improvement lessons\n- Import/export memory data\n\n**Task Scheduler**\n- Create scheduled tasks (Cron expressions supported)\n- Enable/disable tasks\n- Manually trigger task execution\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json` and contains the following main configuration options:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"gpt-4o\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 50\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React + TypeScript │\n│ ├── Tailwind CSS │\n│ └── shadcn/ui Components │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdout/stderr JSON protocol │\n│ ├── State synchronization │\n│ └── Log forwarding │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Python Runtime │\n│ ├── AgentLoop (Core agent engine) │\n│ ├── Memory System │\n│ ├── Tool Registry │\n│ └── Provider Interface │\n└─────────────────────────────────────────────────────────────┘\n```\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend code\n│ ├── agent/ # Core agent logic\n│ ├── bridge/ # Bridge service for Electron communication\n│ ├── providers/ # LLM provider implementations\n│ └── ...\n├── apps/\n│ └── desktop/ # Electron frontend application\n│ ├── src/\n│ │ ├── main/ # Main process code\n│ │ ├── renderer/ # Renderer process code\n│ │ └── preload/ # Preload scripts\n│ └── electron-builder.yml\n└── ...\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests\nuv run pytest\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n"}, "b9f08bca92e25f98de8d057b827a03bc6cc9121c": {"t": 1785771685.429297, "n": 22762, "h": "a06da4e9c9c456f9", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu is wired in the packaged gateway today; additional adapter modules for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat are present in the repository for extension work |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first long-term snapshots, lesson extraction, and append-only JSONL session history under the configured workspace |\n| **Agent Runtime** | Safe concurrent tool execution for read-only batches, iteration-budget safeguards, MCP heartbeat progress, and optional embedded routing/compression hooks |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n#### Using [uv](https://docs.astral.sh/uv/) (Recommended)\n\n[uv](https://github.com/astral-sh/uv) is a fast Python package manager that uses the `uv.lock` lockfile shipped in this repository for reproducible installs.\n\n```bash\n# Install uv (skip if already installed)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# Verify uv\nuv --version # e.g. uv 0.11.x\n\n# Clone and install\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\nuv sync # creates .venv, installs locked dependencies + miqi\n\n# Activate the virtual environment\nsource .venv/bin/activate\n\n# Verify\nmiqi --version\n```\n\n#### Using pip\n\n```bash\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\n\npython3 -m venv .venv\nsource .venv/bin/activate\n\npip install --upgrade pip\npip install -e .\n\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\n# uv (recommended) — installs pytest, ruff, pytest-asyncio\nuv sync --extra dev\n\n# pip alternative\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n> **Note — single source of truth for LLM-backed MCPs.**\n> Any bundled MCP that needs an LLM (currently `pdf2zh`) automatically uses\n> the model and provider you set with `miqi onboard` / `miqi config defaults`.\n> To switch the model for everything in one step, run:\n>\n> ```bash\n> miqi config defaults --model <new-model>\n> miqi config sync-llm # also performed at the end of configure_mcps.sh\n> ```\n>\n> Do **not** pass `-m` / `--model` to `miqi config pdf2zh` directly — the\n> next `sync-llm` run would overwrite it anyway.\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd MiQi\ngit pull --recurse-submodules\n\n# Reinstall core\nuv sync # or: pip install -e .\n\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.1\n }\n },\n \"channels\": {},\n \"tools\": {},\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (for example `APP-Code` on AiHubMix) for each provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `maxToolResultChars`, `contextLimitChars`, `memoryWindow`, and the workspace path.\n- **`agents.memory`** — Flush cadence plus in-memory short-term window sizing. Runtime files live under `<workspace>/memory/`.\n- **`agents.sessions`** — JSONL session compaction thresholds and saved-tool-result truncation. The schema also exposes `useSqlite` for the shipped SQLite+FTS5 session backend module, but the packaged CLI/gateway path still instantiates the JSONL `SessionManager` by default.\n- **`agents.selfImprovement`** — Lesson extraction settings such as `maxLessonsInPrompt`, `minLessonConfidence`, `feedbackMaxMessageChars`, and promotion controls.\n- **`agents.smartRouting`** — Cheap-model routing settings. `AgentLoop` supports them programmatically; the packaged CLI/gateway path currently leaves this disabled unless you embed the runtime yourself.\n- **`agents.commandApproval`** — Schema for interactive dangerous-command approval. The repository ships the helper module, while the default `exec` tool path still relies on static deny-pattern guards.\n- **`channels`** — Global channel delivery flags (`sendProgress`, `sendToolHints`, `sendQueueNotifications`) plus Feishu gateway configuration. Other adapter modules exist in the repo but are not currently surfaced by the public config schema.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). Docker Compose binds the published port to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings, shell execution policy (`tools.exec.timeout`, `tools.exec.envPassthrough`), the global `restrictToWorkspace` flag, and MCP server definitions.\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval for long-running MCP tools. Set `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout before a single MCP tool call is cancelled. Default `30`.\n - **`tools.mcpServers.<name>.lazy`** — Register one lightweight gateway tool instead of all server tools up front.\n - **`tools.mcpServers.<name>.description`** — LLM-facing description for lazy gateway mode.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive behaviors.\n- **`cron`** — Scheduler-wide job timeout (`jobTimeoutSeconds`; default `86400`).\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. See [docs/security.md](docs/security.md) for the current security model and operational limits.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall, persisted by default as append-only JSONL files under `<workspace>/sessions/`\n- **Long-term snapshots** — periodic persistence with audit trails under `<workspace>/memory/`\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Agent Runtime Controls\n\n- **Iteration budget** — the main loop injects pressure hints as it approaches `maxToolIterations`\n- **Concurrent dispatch** — safe read-only or path-disjoint tool batches run via `asyncio.gather`\n- **Embedded hooks** — the `AgentLoop` constructor exposes optional smart-routing and context-compression controls for programmatic use\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s), increase `toolTimeout` for compute-heavy operations, and use `lazy` mode when a server exposes a large tool surface.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/index.md](docs/index.md)\n- [docs/getting-started.md](docs/getting-started.md)\n- [docs/configuration.md](docs/configuration.md)\n- [docs/cli-reference.md](docs/cli-reference.md)\n- [docs/mcp-integration.md](docs/mcp-integration.md)\n- [docs/architecture.md](docs/architecture.md)\n- [docs/memory-system.md](docs/memory-system.md)\n- [docs/self-improvement.md](docs/self-improvement.md)\n- [docs/security.md](docs/security.md)\n- [docs/developer-guide.md](docs/developer-guide.md)\n- [docs/changelog.md](docs/changelog.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## Desktop App (Electron)\n\nMiQi Desktop is a native desktop application built with Electron, providing a modern GUI interface for managing the MiQi AI agent.\n\n### Features\n\n- **Chat Interface** — Interactive chat session with the AI agent\n- **Provider Management** — Configure LLM providers and API keys\n- **Memory Management** — View and manage long-term memory snapshots and lessons\n- **Session Explorer** — Browse and compact conversation history\n- **Cron Scheduler** — Manage scheduled jobs\n- **Skill Management** — Configure and enable/disable agent skills\n- **Workspace Management** — File system operations\n- **Real-time Logs** — Monitor agent activity\n\n### Development\n\n**Prerequisites:**\n- Node.js 20+\n- npm or yarn\n\n**Installation:**\n\n```bash\ncd apps/desktop\nnpm install\n```\n\n**Development Mode:**\n\n```bash\n# Start the Electron app with hot-reload\nnpm run dev\n```\n\n**Build:**\n\n```bash\n# Build for production\nnpm run build\n```\n\n**Type Checking:**\n\n```bash\nnpm run typecheck\n```\n\n**Testing:**\n\n```bash\nnpm run test\n```\n\n### Runtime Bridge\n\nThe desktop app communicates with the MiQi Python runtime via a subprocess bridge. The `BridgeManager` handles:\n- Starting/stopping the MiQi gateway\n- IPC communication between Electron and Python\n- State synchronization\n- Log forwarding\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "0423cfbb710d7c36487e36b8a6725e2cd7ce7749": {"t": 1785771689.8097417, "n": 21470, "h": "57e6e8332d14945d", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu is wired in the packaged gateway today; additional adapter modules for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat are present in the repository for extension work |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first long-term snapshots, lesson extraction, and append-only JSONL session history under the configured workspace |\n| **Agent Runtime** | Safe concurrent tool execution for read-only batches, iteration-budget safeguards, MCP heartbeat progress, and optional embedded routing/compression hooks |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n#### Using [uv](https://docs.astral.sh/uv/) (Recommended)\n\n[uv](https://github.com/astral-sh/uv) is a fast Python package manager that uses the `uv.lock` lockfile shipped in this repository for reproducible installs.\n\n```bash\n# Install uv (skip if already installed)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# Verify uv\nuv --version # e.g. uv 0.11.x\n\n# Clone and install\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\nuv sync # creates .venv, installs locked dependencies + miqi\n\n# Activate the virtual environment\nsource .venv/bin/activate\n\n# Verify\nmiqi --version\n```\n\n#### Using pip\n\n```bash\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\n\npython3 -m venv .venv\nsource .venv/bin/activate\n\npip install --upgrade pip\npip install -e .\n\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\n# uv (recommended) — installs pytest, ruff, pytest-asyncio\nuv sync --extra dev\n\n# pip alternative\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n> **Note — single source of truth for LLM-backed MCPs.**\n> Any bundled MCP that needs an LLM (currently `pdf2zh`) automatically uses\n> the model and provider you set with `miqi onboard` / `miqi config defaults`.\n> To switch the model for everything in one step, run:\n>\n> ```bash\n> miqi config defaults --model <new-model>\n> miqi config sync-llm # also performed at the end of configure_mcps.sh\n> ```\n>\n> Do **not** pass `-m` / `--model` to `miqi config pdf2zh` directly — the\n> next `sync-llm` run would overwrite it anyway.\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd MiQi\ngit pull --recurse-submodules\n\n# Reinstall core\nuv sync # or: pip install -e .\n\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.1\n }\n },\n \"channels\": {},\n \"tools\": {},\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (for example `APP-Code` on AiHubMix) for each provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `maxToolResultChars`, `contextLimitChars`, `memoryWindow`, and the workspace path.\n- **`agents.memory`** — Flush cadence plus in-memory short-term window sizing. Runtime files live under `<workspace>/memory/`.\n- **`agents.sessions`** — JSONL session compaction thresholds and saved-tool-result truncation. The schema also exposes `useSqlite` for the shipped SQLite+FTS5 session backend module, but the packaged CLI/gateway path still instantiates the JSONL `SessionManager` by default.\n- **`agents.selfImprovement`** — Lesson extraction settings such as `maxLessonsInPrompt`, `minLessonConfidence`, `feedbackMaxMessageChars`, and promotion controls.\n- **`agents.smartRouting`** — Cheap-model routing settings. `AgentLoop` supports them programmatically; the packaged CLI/gateway path currently leaves this disabled unless you embed the runtime yourself.\n- **`agents.commandApproval`** — Schema for interactive dangerous-command approval. The repository ships the helper module, while the default `exec` tool path still relies on static deny-pattern guards.\n- **`channels`** — Global channel delivery flags (`sendProgress`, `sendToolHints`, `sendQueueNotifications`) plus Feishu gateway configuration. Other adapter modules exist in the repo but are not currently surfaced by the public config schema.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). Docker Compose binds the published port to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings, shell execution policy (`tools.exec.timeout`, `tools.exec.envPassthrough`), the global `restrictToWorkspace` flag, and MCP server definitions.\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval for long-running MCP tools. Set `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout before a single MCP tool call is cancelled. Default `30`.\n - **`tools.mcpServers.<name>.lazy`** — Register one lightweight gateway tool instead of all server tools up front.\n - **`tools.mcpServers.<name>.description`** — LLM-facing description for lazy gateway mode.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive behaviors.\n- **`cron`** — Scheduler-wide job timeout (`jobTimeoutSeconds`; default `86400`).\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. See [docs/security.md](docs/security.md) for the current security model and operational limits.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall, persisted by default as append-only JSONL files under `<workspace>/sessions/`\n- **Long-term snapshots** — periodic persistence with audit trails under `<workspace>/memory/`\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Agent Runtime Controls\n\n- **Iteration budget** — the main loop injects pressure hints as it approaches `maxToolIterations`\n- **Concurrent dispatch** — safe read-only or path-disjoint tool batches run via `asyncio.gather`\n- **Embedded hooks** — the `AgentLoop` constructor exposes optional smart-routing and context-compression controls for programmatic use\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s), increase `toolTimeout` for compute-heavy operations, and use `lazy` mode when a server exposes a large tool surface.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/index.md](docs/index.md)\n- [docs/getting-started.md](docs/getting-started.md)\n- [docs/configuration.md](docs/configuration.md)\n- [docs/cli-reference.md](docs/cli-reference.md)\n- [docs/mcp-integration.md](docs/mcp-integration.md)\n- [docs/architecture.md](docs/architecture.md)\n- [docs/memory-system.md](docs/memory-system.md)\n- [docs/self-improvement.md](docs/self-improvement.md)\n- [docs/security.md](docs/security.md)\n- [docs/developer-guide.md](docs/developer-guide.md)\n- [docs/changelog.md](docs/changelog.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "f5cdfe5031a1dcef0a07eb9524d97eab882e8d85": {"t": 1785771691.2531707, "n": 20937, "h": "d70ab336ab5c5675", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu is wired in the packaged gateway today; additional adapter modules for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat are present in the repository for extension work |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first long-term snapshots, lesson extraction, and append-only JSONL session history under the configured workspace |\n| **Agent Runtime** | Safe concurrent tool execution for read-only batches, iteration-budget safeguards, MCP heartbeat progress, and optional embedded routing/compression hooks |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n#### Using [uv](https://docs.astral.sh/uv/) (Recommended)\n\n[uv](https://github.com/astral-sh/uv) is a fast Python package manager that uses the `uv.lock` lockfile shipped in this repository for reproducible installs.\n\n```bash\n# Install uv (skip if already installed)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# Verify uv\nuv --version # e.g. uv 0.11.x\n\n# Clone and install\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\nuv sync # creates .venv, installs locked dependencies + miqi\n\n# Activate the virtual environment\nsource .venv/bin/activate\n\n# Verify\nmiqi --version\n```\n\n#### Using pip\n\n```bash\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\n\npython3 -m venv .venv\nsource .venv/bin/activate\n\npip install --upgrade pip\npip install -e .\n\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\n# uv (recommended) — installs pytest, ruff, pytest-asyncio\nuv sync --extra dev\n\n# pip alternative\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd MiQi\ngit pull --recurse-submodules\n\n# Reinstall core\nuv sync # or: pip install -e .\n\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.1\n }\n },\n \"channels\": {},\n \"tools\": {},\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (for example `APP-Code` on AiHubMix) for each provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `maxToolResultChars`, `contextLimitChars`, `memoryWindow`, and the workspace path.\n- **`agents.memory`** — Flush cadence plus in-memory short-term window sizing. Runtime files live under `<workspace>/memory/`.\n- **`agents.sessions`** — JSONL session compaction thresholds and saved-tool-result truncation. The schema also exposes `useSqlite` for the shipped SQLite+FTS5 session backend module, but the packaged CLI/gateway path still instantiates the JSONL `SessionManager` by default.\n- **`agents.selfImprovement`** — Lesson extraction settings such as `maxLessonsInPrompt`, `minLessonConfidence`, `feedbackMaxMessageChars`, and promotion controls.\n- **`agents.smartRouting`** — Cheap-model routing settings. `AgentLoop` supports them programmatically; the packaged CLI/gateway path currently leaves this disabled unless you embed the runtime yourself.\n- **`agents.commandApproval`** — Schema for interactive dangerous-command approval. The repository ships the helper module, while the default `exec` tool path still relies on static deny-pattern guards.\n- **`channels`** — Global channel delivery flags (`sendProgress`, `sendToolHints`, `sendQueueNotifications`) plus Feishu gateway configuration. Other adapter modules exist in the repo but are not currently surfaced by the public config schema.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). Docker Compose binds the published port to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings, shell execution policy (`tools.exec.timeout`, `tools.exec.envPassthrough`), the global `restrictToWorkspace` flag, and MCP server definitions.\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval for long-running MCP tools. Set `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout before a single MCP tool call is cancelled. Default `30`.\n - **`tools.mcpServers.<name>.lazy`** — Register one lightweight gateway tool instead of all server tools up front.\n - **`tools.mcpServers.<name>.description`** — LLM-facing description for lazy gateway mode.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive behaviors.\n- **`cron`** — Scheduler-wide job timeout (`jobTimeoutSeconds`; default `86400`).\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. See [docs/security.md](docs/security.md) for the current security model and operational limits.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall, persisted by default as append-only JSONL files under `<workspace>/sessions/`\n- **Long-term snapshots** — periodic persistence with audit trails under `<workspace>/memory/`\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Agent Runtime Controls\n\n- **Iteration budget** — the main loop injects pressure hints as it approaches `maxToolIterations`\n- **Concurrent dispatch** — safe read-only or path-disjoint tool batches run via `asyncio.gather`\n- **Embedded hooks** — the `AgentLoop` constructor exposes optional smart-routing and context-compression controls for programmatic use\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s), increase `toolTimeout` for compute-heavy operations, and use `lazy` mode when a server exposes a large tool surface.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/index.md](docs/index.md)\n- [docs/getting-started.md](docs/getting-started.md)\n- [docs/configuration.md](docs/configuration.md)\n- [docs/cli-reference.md](docs/cli-reference.md)\n- [docs/mcp-integration.md](docs/mcp-integration.md)\n- [docs/architecture.md](docs/architecture.md)\n- [docs/memory-system.md](docs/memory-system.md)\n- [docs/self-improvement.md](docs/self-improvement.md)\n- [docs/security.md](docs/security.md)\n- [docs/developer-guide.md](docs/developer-guide.md)\n- [docs/changelog.md](docs/changelog.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "c8af5a68eba8e4739dfe43eee8825240509bf001": {"t": 1785771693.4342408, "n": 21115, "h": "75603bef63c5993d", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu is wired in the packaged gateway today; additional adapter modules for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat are present in the repository for extension work |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first long-term snapshots, lesson extraction, and append-only JSONL session history under the configured workspace |\n| **Agent Runtime** | Safe concurrent tool execution for read-only batches, iteration-budget safeguards, MCP heartbeat progress, and optional embedded routing/compression hooks |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n#### Using [uv](https://docs.astral.sh/uv/) (Recommended)\n\n[uv](https://github.com/astral-sh/uv) is a fast Python package manager that uses the `uv.lock` lockfile shipped in this repository for reproducible installs.\n\n```bash\n# Install uv (skip if already installed)\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n# Verify uv\nuv --version # e.g. uv 0.11.x\n\n# Clone and install\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\nuv sync # creates .venv, installs locked dependencies + miqi\n\n# Activate the virtual environment\nsource .venv/bin/activate\n\n# Verify\nmiqi --version\n```\n\n#### Using pip\n\n```bash\ngit clone https://github.com/lichman0405/MiQi.git\ncd MiQi\n\npython3 -m venv .venv\nsource .venv/bin/activate\n\npip install --upgrade pip\npip install -e .\n\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\n# uv (recommended) — installs pytest, ruff, pytest-asyncio\nuv sync --extra dev\n\n# pip alternative\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd MiQi\ngit pull --recurse-submodules\n\n# Reinstall core\nuv sync # or: pip install -e .\n\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.1\n }\n },\n \"channels\": {},\n \"tools\": {},\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (for example `APP-Code` on AiHubMix) for each provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `maxToolResultChars`, `contextLimitChars`, `memoryWindow`, and the workspace path.\n- **`agents.memory`** — Flush cadence plus in-memory short-term window sizing. Runtime files live under `<workspace>/memory/`.\n- **`agents.sessions`** — JSONL session compaction thresholds and saved-tool-result truncation. The schema also exposes `useSqlite` for the shipped SQLite+FTS5 session backend module, but the packaged CLI/gateway path still instantiates the JSONL `SessionManager` by default.\n- **`agents.selfImprovement`** — Lesson extraction settings such as `maxLessonsInPrompt`, `minLessonConfidence`, `feedbackMaxMessageChars`, and promotion controls.\n- **`agents.smartRouting`** — Cheap-model routing settings. `AgentLoop` supports them programmatically; the packaged CLI/gateway path currently leaves this disabled unless you embed the runtime yourself.\n- **`agents.commandApproval`** — Schema for interactive dangerous-command approval. The repository ships the helper module, while the default `exec` tool path still relies on static deny-pattern guards.\n- **`channels`** — Global channel delivery flags (`sendProgress`, `sendToolHints`, `sendQueueNotifications`) plus Feishu gateway configuration. Other adapter modules exist in the repo but are not currently surfaced by the public config schema.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). Docker Compose binds the published port to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings, shell execution policy (`tools.exec.timeout`, `tools.exec.envPassthrough`), the global `restrictToWorkspace` flag, and MCP server definitions.\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval for long-running MCP tools. Set `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout before a single MCP tool call is cancelled. Default `30`.\n - **`tools.mcpServers.<name>.lazy`** — Register one lightweight gateway tool instead of all server tools up front.\n - **`tools.mcpServers.<name>.description`** — LLM-facing description for lazy gateway mode.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive behaviors.\n- **`cron`** — Scheduler-wide job timeout (`jobTimeoutSeconds`; default `86400`).\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. See [docs/security.md](docs/security.md) for the current security model and operational limits.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `miqi provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall, persisted by default as append-only JSONL files under `<workspace>/sessions/`\n- **Long-term snapshots** — periodic persistence with audit trails under `<workspace>/memory/`\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Agent Runtime Controls\n\n- **Iteration budget** — the main loop injects pressure hints as it approaches `maxToolIterations`\n- **Concurrent dispatch** — safe read-only or path-disjoint tool batches run via `asyncio.gather`\n- **Embedded hooks** — the `AgentLoop` constructor exposes optional smart-routing and context-compression controls for programmatic use\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s), increase `toolTimeout` for compute-heavy operations, and use `lazy` mode when a server exposes a large tool surface.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/index.md](docs/index.md)\n- [docs/getting-started.md](docs/getting-started.md)\n- [docs/configuration.md](docs/configuration.md)\n- [docs/cli-reference.md](docs/cli-reference.md)\n- [docs/mcp-integration.md](docs/mcp-integration.md)\n- [docs/architecture.md](docs/architecture.md)\n- [docs/memory-system.md](docs/memory-system.md)\n- [docs/self-improvement.md](docs/self-improvement.md)\n- [docs/security.md](docs/security.md)\n- [docs/developer-guide.md](docs/developer-guide.md)\n- [docs/changelog.md](docs/changelog.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "ca85f1037d497fa32404aea603c35a0374356d83": {"t": 1785771695.1140718, "n": 20440, "h": "4a4005814b79aea5", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu is wired in the packaged gateway today; additional adapter modules for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat are present in the repository for extension work |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first long-term snapshots, lesson extraction, and append-only JSONL session history under the configured workspace |\n| **Agent Runtime** | Safe concurrent tool execution for read-only batches, iteration-budget safeguards, MCP heartbeat progress, and optional embedded routing/compression hooks |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/miqi.git\ncd miqi\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install MiQi\npip install --upgrade pip\npip install -e .\n\n# Verify\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd miqi\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.1\n }\n },\n \"channels\": {},\n \"tools\": {},\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (for example `APP-Code` on AiHubMix) for each provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `maxToolResultChars`, `contextLimitChars`, `memoryWindow`, and the workspace path.\n- **`agents.memory`** — Flush cadence plus in-memory short-term window sizing. Runtime files live under `<workspace>/memory/`.\n- **`agents.sessions`** — JSONL session compaction thresholds and saved-tool-result truncation. The schema also exposes `useSqlite` for the shipped SQLite+FTS5 session backend module, but the packaged CLI/gateway path still instantiates the JSONL `SessionManager` by default.\n- **`agents.selfImprovement`** — Lesson extraction settings such as `maxLessonsInPrompt`, `minLessonConfidence`, `feedbackMaxMessageChars`, and promotion controls.\n- **`agents.smartRouting`** — Cheap-model routing settings. `AgentLoop` supports them programmatically; the packaged CLI/gateway path currently leaves this disabled unless you embed the runtime yourself.\n- **`agents.commandApproval`** — Schema for interactive dangerous-command approval. The repository ships the helper module, while the default `exec` tool path still relies on static deny-pattern guards.\n- **`channels`** — Global channel delivery flags (`sendProgress`, `sendToolHints`, `sendQueueNotifications`) plus Feishu gateway configuration. Other adapter modules exist in the repo but are not currently surfaced by the public config schema.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). Docker Compose binds the published port to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings, shell execution policy (`tools.exec.timeout`, `tools.exec.envPassthrough`), the global `restrictToWorkspace` flag, and MCP server definitions.\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval for long-running MCP tools. Set `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout before a single MCP tool call is cancelled. Default `30`.\n - **`tools.mcpServers.<name>.lazy`** — Register one lightweight gateway tool instead of all server tools up front.\n - **`tools.mcpServers.<name>.description`** — LLM-facing description for lazy gateway mode.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive behaviors.\n- **`cron`** — Scheduler-wide job timeout (`jobTimeoutSeconds`; default `86400`).\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. See [docs/security.md](docs/security.md) for the current security model and operational limits.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `miqi provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall, persisted by default as append-only JSONL files under `<workspace>/sessions/`\n- **Long-term snapshots** — periodic persistence with audit trails under `<workspace>/memory/`\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Agent Runtime Controls\n\n- **Iteration budget** — the main loop injects pressure hints as it approaches `maxToolIterations`\n- **Concurrent dispatch** — safe read-only or path-disjoint tool batches run via `asyncio.gather`\n- **Embedded hooks** — the `AgentLoop` constructor exposes optional smart-routing and context-compression controls for programmatic use\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s), increase `toolTimeout` for compute-heavy operations, and use `lazy` mode when a server exposes a large tool surface.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/index.md](docs/index.md)\n- [docs/getting-started.md](docs/getting-started.md)\n- [docs/configuration.md](docs/configuration.md)\n- [docs/cli-reference.md](docs/cli-reference.md)\n- [docs/mcp-integration.md](docs/mcp-integration.md)\n- [docs/architecture.md](docs/architecture.md)\n- [docs/memory-system.md](docs/memory-system.md)\n- [docs/self-improvement.md](docs/self-improvement.md)\n- [docs/security.md](docs/security.md)\n- [docs/developer-guide.md](docs/developer-guide.md)\n- [docs/changelog.md](docs/changelog.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "eb7a764edeb7dce54b4130d69b5cff269c89418b": {"t": 1785771697.4943438, "n": 19275, "h": "99b26649f36c9663", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nMiQi is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nMiQi is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/miqi.git\ncd miqi\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install MiQi\npip install --upgrade pip\npip install -e .\n\n# Verify\nmiqi --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nmiqi onboard\n\n# Send a one-shot message\nmiqi agent -m \"hello\"\n\n# Start an interactive chat session\nmiqi agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nmiqi gateway\n```\n\n`miqi onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build miqi-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm miqi-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.miqi` |\n| Container | `/home/miqi/.miqi` |\n\n> **Security:** The container runs as unprivileged user `miqi` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.miqi/config.json\nmiqi onboard\n\n# Verify the config\nmiqi status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/miqi.service`:\n\n```ini\n[Unit]\nDescription=MiQi AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=miqi\nWorkingDirectory=/home/miqi\nExecStart=/home/miqi/.local/bin/miqi gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/miqi\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now miqi\nsudo journalctl -u miqi -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name miqi.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd miqi\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart miqi / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nMiQi reads from `~/.miqi/config.json`. The interactive wizard (`miqi onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.miqi/config.json` |\n| Workspace | `~/.miqi/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"miqi\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`. Default `30`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. Set strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `MIQI_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nMIQI_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat miqi agent\n\n# Inject an API key without editing config.json\nMIQI_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx miqi gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `miqi onboard` | Interactive setup wizard |\n| `miqi agent` | Start an interactive chat session |\n| `miqi agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `miqi gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `miqi status` | Show runtime and provider status |\n| `miqi channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `miqi memory status` | Show memory snapshot and stats |\n| `miqi memory flush` | Force-persist pending memory updates immediately |\n| `miqi memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `miqi memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `miqi memory delete <id>` | Remove a snapshot entry by ID |\n| `miqi memory lessons status` | Show self-improvement lesson stats |\n| `miqi memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `miqi memory lessons enable <id>` | Re-enable a disabled lesson |\n| `miqi memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `miqi memory lessons delete <id>` | Permanently remove a lesson |\n| `miqi memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `miqi memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `miqi session compact --session <id>` | Compact a single conversation session |\n| `miqi session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `miqi cron list` | List all scheduled jobs |\n| `miqi cron add` | Add a new scheduled job |\n| `miqi cron run <id>` | Trigger a job manually |\n| `miqi cron enable <id>` | Enable a job |\n| `miqi cron disable <id>` | Disable a job |\n| `miqi cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `miqi config show` | Print all non-default config values |\n| `miqi config provider <name>` | Set or update a provider's API key / base URL |\n| `miqi config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `miqi config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `miqi config mcp list` | List all configured MCP servers |\n| `miqi config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `miqi config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `miqi provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nMiQi uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), MiQi automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), MiQi queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `miqi.*` |\n| CLI command | `assistant` | `miqi` |\n| Runtime directory | `~/.assistant` | `~/.miqi` |\n| Workspace directory | `~/.assistant/workspace` | `~/.miqi/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nMiQi ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/miqi.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with miqi**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `miqi config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.miqi/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SECURITY_IMPROVEMENTS.md](docs/SECURITY_IMPROVEMENTS.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.miqi/config.json`\n\n### Skills Docs (`miqi/skills/`)\n\n- [miqi/skills/README.md](miqi/skills/README.md)\n- [miqi/skills/cron/SKILL.md](miqi/skills/cron/SKILL.md)\n- [miqi/skills/feishu-report/SKILL.md](miqi/skills/feishu-report/SKILL.md)\n- [miqi/skills/github/SKILL.md](miqi/skills/github/SKILL.md)\n- [miqi/skills/memory/SKILL.md](miqi/skills/memory/SKILL.md)\n- [miqi/skills/paper-research/SKILL.md](miqi/skills/paper-research/SKILL.md)\n- [miqi/skills/skill-creator/SKILL.md](miqi/skills/skill-creator/SKILL.md)\n- [miqi/skills/summarize/SKILL.md](miqi/skills/summarize/SKILL.md)\n- [miqi/skills/tmux/SKILL.md](miqi/skills/tmux/SKILL.md)\n- [miqi/skills/weather/SKILL.md](miqi/skills/weather/SKILL.md)\n- [miqi/skills/workspace-cleanup/SKILL.md](miqi/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`miqi/templates/`)\n\n- [miqi/templates/AGENTS.md](miqi/templates/AGENTS.md)\n- [miqi/templates/HEARTBEAT.md](miqi/templates/HEARTBEAT.md)\n- [miqi/templates/SOUL.md](miqi/templates/SOUL.md)\n- [miqi/templates/TOOLS.md](miqi/templates/TOOLS.md)\n- [miqi/templates/USER.md](miqi/templates/USER.md)\n- [miqi/templates/memory/MEMORY.md](miqi/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "a88c651f52a298cfd7dfe99231810fbc9c797666": {"t": 1785771699.8383176, "n": 20164, "h": "c60f91f7fb3dd974", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/home/featherflow/.featherflow` |\n\n> **Security:** The container runs as unprivileged user `featherflow` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.featherflow/config.json\nfeatherflow onboard\n\n# Verify the config\nfeatherflow status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/featherflow.service`:\n\n```ini\n[Unit]\nDescription=FeatherFlow AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=featherflow\nWorkingDirectory=/home/featherflow\nExecStart=/home/featherflow/.local/bin/featherflow gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/featherflow\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now featherflow\nsudo journalctl -u featherflow -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name featherflow.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd featherflow\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart featherflow / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`. Default `30`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. Set strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nFeatherFlow ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/featherflow.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with featherflow**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `featherflow config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.featherflow/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SECURITY_IMPROVEMENTS.md](docs/SECURITY_IMPROVEMENTS.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.featherflow/config.json`\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/feishu-report/SKILL.md](featherflow/skills/feishu-report/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/paper-research/SKILL.md](featherflow/skills/paper-research/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n- [featherflow/skills/workspace-cleanup/SKILL.md](featherflow/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "8ab05ab1278d0b5ce027b915abe7340bd148a4ad": {"t": 1785771703.2639484, "n": 20279, "h": "639e17c3bcd71ed1", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/home/featherflow/.featherflow` |\n\n> **Security:** The container runs as unprivileged user `featherflow` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.featherflow/config.json\nfeatherflow onboard\n\n# Verify the config\nfeatherflow status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/featherflow.service`:\n\n```ini\n[Unit]\nDescription=FeatherFlow AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=featherflow\nWorkingDirectory=/home/featherflow\nExecStart=/home/featherflow/.local/bin/featherflow gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/featherflow\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now featherflow\nsudo journalctl -u featherflow -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name featherflow.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd featherflow\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart featherflow / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`. Default `30`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. Set strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nFeatherFlow ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/featherflow.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with featherflow**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `featherflow config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.featherflow/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SECURITY_IMPROVEMENTS.md](docs/SECURITY_IMPROVEMENTS.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.featherflow/config.json`\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/feishu-report/SKILL.md](featherflow/skills/feishu-report/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/paper-research/SKILL.md](featherflow/skills/paper-research/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n- [featherflow/skills/workspace-cleanup/SKILL.md](featherflow/skills/workspace-cleanup/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "6f3b19829e7667cbde56454ad8e3af68b30a8d33": {"t": 1785771705.4211018, "n": 20079, "h": "5a4c88440e5eecea", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/home/featherflow/.featherflow` |\n\n> **Security:** The container runs as unprivileged user `featherflow` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.featherflow/config.json\nfeatherflow onboard\n\n# Verify the config\nfeatherflow status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/featherflow.service`:\n\n```ini\n[Unit]\nDescription=FeatherFlow AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=featherflow\nWorkingDirectory=/home/featherflow\nExecStart=/home/featherflow/.local/bin/featherflow gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/featherflow\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now featherflow\nsudo journalctl -u featherflow -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name featherflow.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd featherflow\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart featherflow / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`. Default `30`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Config files are automatically saved with `0600` permissions (owner-read-only) to protect API keys. Set strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nFeatherFlow ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/featherflow.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with featherflow**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `featherflow config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.featherflow/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SECURITY_IMPROVEMENTS.md](docs/SECURITY_IMPROVEMENTS.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.featherflow/config.json`\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "1443914db4be46d1da84c9a0206d0c18f190ca73": {"t": 1785771706.8290436, "n": 20026, "h": "c998abbdd8c45f41", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/home/featherflow/.featherflow` |\n\n> **Security:** The container runs as unprivileged user `featherflow` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n### Bare-Metal (Non-Docker) Deployment\n\nFor running the gateway directly on a Linux/macOS host as a long-running service:\n\n**1. Prepare configuration** (if not done already):\n\n```bash\n# Interactive setup — creates ~/.featherflow/config.json\nfeatherflow onboard\n\n# Verify the config\nfeatherflow status\n```\n\n**2. (Optional) Set up MCP servers:**\n\n```bash\nbash scripts/setup_mcps.sh # install isolated venvs\nbash scripts/configure_mcps.sh # register MCPs into config\n```\n\n**3. Run with systemd** (Linux, recommended):\n\nCreate `/etc/systemd/system/featherflow.service`:\n\n```ini\n[Unit]\nDescription=FeatherFlow AI Agent Gateway\nAfter=network.target\n\n[Service]\nType=simple\nUser=featherflow\nWorkingDirectory=/home/featherflow\nExecStart=/home/featherflow/.local/bin/featherflow gateway\nRestart=on-failure\nRestartSec=10\nEnvironment=HOME=/home/featherflow\n\n[Install]\nWantedBy=multi-user.target\n```\n\n```bash\nsudo systemctl daemon-reload\nsudo systemctl enable --now featherflow\nsudo journalctl -u featherflow -f # tail logs\n```\n\nOn macOS, use `launchd` or a process manager like `supervisord` instead.\n\n**4. Reverse proxy** (optional, for external access):\n\nThe gateway listens on `127.0.0.1:18790`. To expose it, place it behind Nginx:\n\n```nginx\nserver {\n listen 443 ssl;\n server_name featherflow.example.com;\n\n location / {\n proxy_pass http://127.0.0.1:18790;\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n }\n}\n```\n\n### Upgrading\n\n```bash\ncd featherflow\ngit pull --recurse-submodules\npip install -e . # reinstall core\nbash scripts/setup_mcps.sh # update MCP venvs\nbash scripts/configure_mcps.sh # re-register MCPs (idempotent)\n# then restart the gateway (systemctl restart featherflow / docker compose up --build)\n```\n\n> **Note:** The Docker image does **not** include MCP submodules — MCP servers run as separate stdio subprocesses on the host. When using Docker, mount or install MCP venvs on the host and configure `tools.mcpServers` commands to point at host-side interpreters, or run MCP servers as separate containers and use HTTP transport (`url` instead of `command`).\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nFeatherFlow ships with seven domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material science, epitaxial surface analysis, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **miqrophi** | `mcps/miqrophi-mcp` | 3.10+ | Epitaxial lattice matching — CIF surface analysis, substrate screening, strain calculation |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/featherflow.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with featherflow**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `featherflow config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.featherflow/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SECURITY_IMPROVEMENTS.md](docs/SECURITY_IMPROVEMENTS.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.featherflow/config.json`\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "c60093a66ae3b0ab34237b6df0ccc8e463c8f801": {"t": 1785771708.5843554, "n": 17627, "h": "97207ef8d0ab3a0f", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/home/featherflow/.featherflow` |\n\n> **Security:** The container runs as unprivileged user `featherflow` (UID 1000) — not root. The gateway port (`18790`) is bound to `127.0.0.1` by default and is **not** exposed to the network. Use a reverse proxy (e.g. Nginx) to expose it externally.\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790` for bare-metal runs). When using Docker Compose the port is bound to `127.0.0.1:18790` by default.\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`.\n - **`tools.mcpServers.<name>.allowedTools`** — Optional allowlist of tool names. When non-empty, only the listed tools from this MCP server are registered. All others are silently dropped.\n - **`tools.mcpServers.<name>.deniedTools`** — Optional denylist of tool names. Any tool whose name appears here is never registered, regardless of `allowedTools`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## MCP Ecosystem\n\nFeatherFlow ships with six domain-specific MCP servers as git submodules under `mcps/`.\nThey cover porous-material simulation, PDF translation, and team collaboration.\n\n### Bundled MCP Servers\n\n| Name | Submodule | Python | Description |\n|---|---|---|---|\n| **zeopp** | `mcps/zeopp-backend` | 3.10+ | Zeo++ porous material geometry (volume, pore size, channels) |\n| **raspa2** | `mcps/raspa-mcp` | 3.11+ | RASPA2 molecular simulation — input templates, output parsing |\n| **mofstructure** | `mcps/mofstructure-mcp` | 3.9+ | MOF structural analysis — building blocks, topology, metal nodes |\n| **mofchecker** | `mcps/mofchecker-mcp` | **<3.11** | MOF structure validation — CIF integrity, geometry defects |\n| **pdf2zh** | `mcps/pdftranslate-mcp` | 3.10–3.12 | PDF paper translation preserving LaTeX layout (needs OpenAI key) |\n| **feishu** | `mcps/feishu-mcp` | 3.11+ | Feishu/Lark — messaging, docs, tasks (needs App ID & Secret) |\n\n### Setup\n\n**1. Clone with submodules** (one-time):\n\n```bash\ngit clone --recurse-submodules https://github.com/lichman0405/featherflow.git\n# or, if you already cloned without --recurse-submodules:\ngit submodule update --init --recursive\n```\n\n**2. Install Python venvs** for each MCP:\n\n```bash\nbash scripts/setup_mcps.sh\n```\n\nThe script uses [`uv`](https://docs.astral.sh/uv/) and pins the correct Python version per MCP\n(notably `mofchecker` requires Python 3.10; `pdf2zh` requires ≤3.12).\n\n**3. Register MCPs with featherflow**:\n\n```bash\nbash scripts/configure_mcps.sh\n```\n\nThis calls `featherflow config mcp add` for every server with recommended timeouts and lazy-mode settings.\n\n**4. Add credentials** for the two servers that need them — open `~/.featherflow/config.json` and fill in:\n\n```jsonc\n\"tools\": {\n \"mcpServers\": {\n \"pdf2zh\": {\n \"env\": {\n \"OPENAI_BASE_URL\": \"https://api.openai.com/v1\",\n \"OPENAI_API_KEY\": \"sk-...\",\n \"OPENAI_MODEL\": \"gpt-4o\"\n }\n },\n \"feishu\": {\n \"env\": {\n \"FEISHU_APP_ID\": \"cli_...\",\n \"FEISHU_APP_SECRET\": \"...\"\n }\n }\n }\n}\n```\n\n> **Security note**: MCP subprocesses launched via the stdio transport inherit only a minimal environment\n> (`HOME`, `PATH`, `SHELL`, `USER`, `TERM`, `LOGNAME`) — your LLM provider API keys are never exposed\n> to MCP servers unless you explicitly add them to `cfg.env` as shown above.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Scripts (`scripts/`)\n\n- [scripts/setup_mcps.sh](scripts/setup_mcps.sh) — Create isolated Python venvs for all bundled MCP servers\n- [scripts/configure_mcps.sh](scripts/configure_mcps.sh) — Register all bundled MCPs into `~/.featherflow/config.json`\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "20ce164920bebf22f8e59222c5b92ff1973404d6": {"t": 1785771710.410071, "n": 14277, "h": "f508115abd6c962c", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel), `sendToolHints` (stream tool-call hints), and `sendQueueNotifications` (notify users about task queue position).\n - **`channels.feishu.requireMentionInGroups`** — When `true` (default), the bot only responds to group messages where it is @mentioned. Private chats are unaffected.\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790`).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n - **`tools.mcpServers.<name>.progressIntervalSeconds`** — Heartbeat interval (seconds) for long-running MCP tool calls. Set to `0` to disable. Default `15`.\n - **`tools.mcpServers.<name>.toolTimeout`** — Timeout in seconds before a tool call is cancelled. For scientific computing MCP servers (e.g. raspa, mofstructure), set to `300`–`600`.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\nFor long-running MCP tools (e.g. scientific computing), FeatherFlow automatically sends periodic heartbeat progress messages to the user so they know the task is still running. Configure `progressIntervalSeconds` per MCP server (default 15s) and increase `toolTimeout` for compute-heavy operations.\n\n### Task Queue Awareness\n\nWhen multiple users send messages simultaneously (e.g. in a group chat), FeatherFlow queues tasks and notifies each user of their queue position. Users see when their task starts processing and how many tasks are ahead. This is enabled by default via `channels.sendQueueNotifications`.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "6f194e3c189b1eebb962108a16d98925ee3e5fea": {"t": 1785771713.3943017, "n": 13084, "h": "489b053484a46553", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, Groq, Moonshot, MiniMax, ZhipuAI, DashScope (Qwen), SiliconFlow, VolcEngine, AiHubMix, vLLM, Ollama, OpenAI Codex (OAuth), GitHub Copilot (OAuth), and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys, custom `apiBase` URLs, and optional `extraHeaders` (e.g. `APP-Code` for AiHubMix) for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, `maxTokens`, `maxToolIterations`, `memoryWindow`, and agent identity (`name`, `workspace`).\n- **`agents.memory`** — Memory flush cadence (`flushEveryUpdates`, `flushIntervalSeconds`) and short-term window sizes.\n- **`agents.sessions`** — Session compaction thresholds (`compactThresholdMessages`, `compactThresholdBytes`, `compactKeepMessages`).\n- **`agents.selfImprovement`** — Lesson extraction settings: `enabled`, `maxLessonsInPrompt`, `minLessonConfidence`, `maxLessons`, `promotionEnabled`, etc.\n- **`channels`** — Channel configuration for each IM adapter; also controls `sendProgress` (stream text to channel) and `sendToolHints` (stream tool-call hints).\n- **`gateway`** — HTTP gateway listen address (`host`, `port`; default `0.0.0.0:18790`).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy (`tools.exec.timeout`), `restrictToWorkspace` flag, and MCP server definitions (`tools.mcpServers`).\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n### Environment Variable Overrides\n\nEvery config field can be overridden at runtime via environment variables using the prefix `FEATHERFLOW_` and `__` as the nesting delimiter:\n\n```bash\n# Override the default model\nFEATHERFLOW_AGENTS__DEFAULTS__MODEL=deepseek/deepseek-chat featherflow agent\n\n# Inject an API key without editing config.json\nFEATHERFLOW_PROVIDERS__OPENROUTER__API_KEY=sk-or-v1-xxx featherflow gateway\n```\n\nThis is particularly useful in containerised deployments where secrets are injected as environment variables rather than mounted files.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n\n**Memory Management**\n\n| Command | Description |\n|---|---|\n| `featherflow memory status` | Show memory snapshot and stats |\n| `featherflow memory flush` | Force-persist pending memory updates immediately |\n| `featherflow memory compact [--max-items N]` | Prune long-term snapshot to at most N items |\n| `featherflow memory list [--limit N] [--session S]` | Browse long-term snapshot entries |\n| `featherflow memory delete <id>` | Remove a snapshot entry by ID |\n| `featherflow memory lessons status` | Show self-improvement lesson stats |\n| `featherflow memory lessons list` | List lessons (filter by `--scope`, `--session`, `--limit`) |\n| `featherflow memory lessons enable <id>` | Re-enable a disabled lesson |\n| `featherflow memory lessons disable <id>` | Suppress a lesson from future prompts |\n| `featherflow memory lessons delete <id>` | Permanently remove a lesson |\n| `featherflow memory lessons compact [--max-lessons N]` | Prune lessons to at most N entries |\n| `featherflow memory lessons reset` | Wipe all lessons |\n\n**Session Management**\n\n| Command | Description |\n|---|---|\n| `featherflow session compact --session <id>` | Compact a single conversation session |\n| `featherflow session compact --all` | Compact all stored sessions |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Configuration**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print all non-default config values |\n| `featherflow config provider <name>` | Set or update a provider's API key / base URL |\n| `featherflow config feishu` | One-shot Feishu channel + feishu-mcp setup |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP server (auto-fills LLM credentials) |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add <name>` | Add or update an MCP server (stdio or HTTP) |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login openai-codex` | Authenticate with OpenAI Codex (OAuth) |\n| `featherflow provider login github-copilot` | Authenticate with GitHub Copilot (OAuth) |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "74a1490e1f114e74f00051d6f5b7e85dc2964b09": {"t": 1785771715.685564, "n": 13055, "h": "d5e1088c331ff5f9", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys and base URLs for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, token limits, and agent identity.\n- **`channels`** — Channel configuration for each IM adapter (see individual channel docs).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy, and MCP server definitions.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n| `featherflow memory status` | Show memory snapshot and stats |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login <provider>` | Authenticate with an LLM provider |\n\n**Config (interactive wizards)**\n\n| Command | Description |\n|---|---|\n| `featherflow config show` | Print current config (keys masked) |\n| `featherflow config provider <name>` | Set API key / base URL for a provider |\n| `featherflow config feishu` | Configure Feishu channel **and** feishu-mcp in one step |\n| `featherflow config pdf2zh` | Configure pdf2zh MCP, auto-filling credentials from your provider |\n| `featherflow config mcp list` | List all configured MCP servers |\n| `featherflow config mcp add` | Add a custom MCP server interactively |\n| `featherflow config mcp remove <name>` | Remove an MCP server |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent.\nMCP servers are defined under `tools.mcpServers` in your config — but you don't need to edit JSON by hand.\nUse the `featherflow config` commands described below.\n\n---\n\n## Chat App Setup\n\nThis guide walks through connecting FeatherFlow to a Feishu group with PDF translation.\nAll steps use the interactive `featherflow config` wizards — no JSON editing required.\n\n### Prerequisites\n\n1. **Feishu Open Platform app** — create an in-house app at <https://open.feishu.cn/>, note down:\n - **App ID** — looks like `cli_xxxxxxxxxxxxxxxxxx`\n - **App Secret** — 32-character hex string\n - Grant permissions: `im:message`, `im:chat.members:read`, `drive:drive`, `docx:document`, `drive:permission:write`\n - Add bot to your target group: Group Settings → Group Bots → Add Bot\n\n2. **feishu-mcp installed** in a venv:\n ```bash\n git clone https://github.com/lichman0405/feishu-mcp ~/feishu-mcp\n cd ~/feishu-mcp && python3 -m venv .venv && .venv/bin/pip install -e .\n ```\n\n3. *(Optional)* **pdftranslate-mcp installed** in a separate Python 3.12 venv\n (required because its dependencies need Python < 3.13):\n ```bash\n git clone https://github.com/lichman0405/pdftranslate-mcp ~/pdftranslate-mcp\n cd ~/pdftranslate-mcp\n uv venv .venv --python 3.12 # or: python3.12 -m venv .venv\n .venv/bin/pip install -e .\n ```\n\n---\n\n### Step 1 — Configure Feishu channel + feishu-mcp\n\n```bash\nfeatherflow config feishu\n```\n\nWhat it asks:\n\n| Prompt | What to enter |\n|---|---|\n| `Feishu App ID` | `cli_xxxxxxxxxxxxxxxxxx` from the open platform |\n| `Feishu App Secret` | the 32-char secret (input is hidden) |\n| `Path to feishu-mcp Python executable` | auto-detected from `~/feishu-mcp/.venv/bin/python`; press Enter to accept, or paste the path manually |\n\nThis writes both `channels.feishu` and `tools.mcpServers.feishu-mcp` in one shot.\n\n---\n\n### Step 2 — Configure pdf2zh MCP (optional)\n\n```bash\nfeatherflow config pdf2zh\n```\n\nWhat it asks:\n\n| Prompt | What to enter |\n|---|---|\n| `Model name for translation` | defaults to your current model — press Enter to keep it, or type e.g. `kimi-k2.5` |\n| `Path to pdf2zh Python executable` | auto-detected from `~/pdftranslate-mcp/.venv/bin/python`; press Enter or paste path |\n\n> **Note:** API key and base URL are copied automatically from the provider you configured during `featherflow onboard`. You do **not** need to re-enter them.\n\nIf your provider base URL doesn't already end in `/v1`, the command appends it automatically.\n\n---\n\n### Step 3 — Start the gateway\n\n```bash\nfeatherflow gateway\n```\n\nFeatherFlow will connect to Feishu via WebSocket long connection and start the MCP servers as child processes. Send a message to the bot in your Feishu group to verify.\n\n---\n\n### Verify configuration\n\n```bash\nfeatherflow config show # see full config (keys masked)\nfeatherflow config mcp list # confirm feishu-mcp and pdf2zh are listed\nfeatherflow channels status # check Feishu WebSocket connection\n```\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "aa4718f76ccae98e4b461159aafd724284901d91": {"t": 1785771717.5417442, "n": 9727, "h": "29f809a98c94c9cd", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), cron scheduler, sub-agent spawning |\n| **Channels** | Channel adapters exist for Feishu/Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat (runtime wiring via config) |\n| **MCP Integration** | Connect any MCP-compatible tool server (e.g. [feishu-mcp](https://github.com/lichman0405/feishu-mcp)) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys and base URLs for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, token limits, and agent identity.\n- **`channels`** — Channel configuration for each IM adapter (see individual channel docs).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy, and MCP server definitions.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n| `featherflow memory status` | Show memory snapshot and stats |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login <provider>` | Authenticate with an LLM provider |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under `tools.mcpServers` in your config. For example, connect [feishu-mcp](https://github.com/lichman0405/feishu-mcp) to bring Feishu collaboration capabilities (messages, calendar, tasks, documents) into the agent via a clean MCP interface.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "59f6bf2da61a7b13c6b3012b51c75d1f35b214a7": {"t": 1785771719.6076615, "n": 10766, "h": "96d98d8e5af3077e", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project, optimized for Feishu-first production workflows. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details/download), Feishu collaboration (doc/calendar/task/drive/handoff), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu (WebSocket, runtime enabled) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n> Channel adapters for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat may exist in code, but current runtime wiring is Feishu-only.\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n- Optional Feishu channel setup (can be skipped; secure defaults preserved)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n \"feishu\": {\n \"enabled\": true,\n \"appId\": \"cli_xxx\",\n \"appSecret\": \"xxx\",\n \"allowFrom\": []\n }\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys and base URLs for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, token limits, and agent identity.\n- **`channels`** — Feishu channel credentials and access-control settings (`allowFrom`, group read policy, reaction behavior).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy, and MCP server definitions.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n| `featherflow memory status` | Show memory snapshot and stats |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login <provider>` | Authenticate with an LLM provider |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under the `tools.mcp` section of your config.\n\n### Feishu Collaboration Workflow\n\nFeatherFlow includes a Feishu-first delivery flow for group collaboration:\n\n- `paper_download`: downloads open-access PDFs into workspace and rejects common paywall/login HTML pages with structured errors.\n- `feishu_drive`: creates Drive folders and uploads local artifacts from workspace.\n- `feishu_doc` / `feishu_task` / `feishu_calendar`: creates cloud docs, tasks, and calendar events.\n- `feishu_handoff`: generic handoff orchestration that combines uploads + optional summary doc + optional task + optional calendar event.\n\nFor group assignment (`assignees` / `attendees`), user resolution follows this order:\n- explicit `open_id`\n- current message mentions\n- group member exact name match\n- group member fuzzy name match\n\nIf multiple users match the same name, tools return candidates and fail safely instead of guessing.\n\nFeishu Open Platform permission checklist for these tools is documented in [docs/API.md](docs/API.md).\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "f3b3dbd338bab5906f5cd6dccf5bda87a44a9f3d": {"t": 1785771720.9689004, "n": 9733, "h": "b8de97c48f42e6cf", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project, optimized for Feishu-first production workflows. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu (WebSocket, runtime enabled) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n> Channel adapters for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat may exist in code, but current runtime wiring is Feishu-only.\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n- Optional Feishu channel setup (can be skipped; secure defaults preserved)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n \"feishu\": {\n \"enabled\": true,\n \"appId\": \"cli_xxx\",\n \"appSecret\": \"xxx\",\n \"allowFrom\": []\n }\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys and base URLs for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, token limits, and agent identity.\n- **`channels`** — Feishu channel credentials and access-control settings (`allowFrom`, group read policy, reaction behavior).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy, and MCP server definitions.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n| `featherflow memory status` | Show memory snapshot and stats |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login <provider>` | Authenticate with an LLM provider |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under the `tools.mcp` section of your config.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## Documentation Index\n\n### Root Documents\n\n- [README.md](README.md)\n- [CHANGELOG.md](CHANGELOG.md)\n- [CONTRIBUTING.md](CONTRIBUTING.md)\n\n### Project Docs (`docs/`)\n\n- [docs/API.md](docs/API.md)\n- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)\n- [docs/DEVELOPER_GUIDE.md](docs/DEVELOPER_GUIDE.md)\n- [docs/RAM_FIRST_MEMORY_CHECKPOINT.md](docs/RAM_FIRST_MEMORY_CHECKPOINT.md)\n- [docs/SECURITY.md](docs/SECURITY.md)\n- [docs/SELF_DEVELOPMENT.md](docs/SELF_DEVELOPMENT.md)\n\n### Skills Docs (`featherflow/skills/`)\n\n- [featherflow/skills/README.md](featherflow/skills/README.md)\n- [featherflow/skills/clawhub/SKILL.md](featherflow/skills/clawhub/SKILL.md)\n- [featherflow/skills/cron/SKILL.md](featherflow/skills/cron/SKILL.md)\n- [featherflow/skills/github/SKILL.md](featherflow/skills/github/SKILL.md)\n- [featherflow/skills/memory/SKILL.md](featherflow/skills/memory/SKILL.md)\n- [featherflow/skills/skill-creator/SKILL.md](featherflow/skills/skill-creator/SKILL.md)\n- [featherflow/skills/summarize/SKILL.md](featherflow/skills/summarize/SKILL.md)\n- [featherflow/skills/tmux/SKILL.md](featherflow/skills/tmux/SKILL.md)\n- [featherflow/skills/weather/SKILL.md](featherflow/skills/weather/SKILL.md)\n\n### Template Docs (`featherflow/templates/`)\n\n- [featherflow/templates/AGENTS.md](featherflow/templates/AGENTS.md)\n- [featherflow/templates/HEARTBEAT.md](featherflow/templates/HEARTBEAT.md)\n- [featherflow/templates/SOUL.md](featherflow/templates/SOUL.md)\n- [featherflow/templates/TOOLS.md](featherflow/templates/TOOLS.md)\n- [featherflow/templates/USER.md](featherflow/templates/USER.md)\n- [featherflow/templates/memory/MEMORY.md](featherflow/templates/memory/MEMORY.md)\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "7d61087d1e2c52d7d52f5fc66c6031d02e8800ce": {"t": 1785771723.251241, "n": 8069, "h": "ce9da7209d81ffcf", "c": "# FeatherFlow\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework for production automation and conversational workflows.</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\" /></a>\n <a href=\"https://github.com/astral-sh/uv\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json\" alt=\"uv\" /></a>\n <img src=\"https://img.shields.io/badge/docker-supported-2496ED?logo=docker&logoColor=white\" alt=\"Docker Supported\" />\n</p>\n\n---\n\n## Overview\n\nFeatherFlow is a compact AI agent runtime designed for developers who want a self-hosted, programmable assistant. It connects to any OpenAI-compatible LLM provider and exposes a rich toolset — file operations, shell execution, web search, scheduled tasks, sub-agents, and external MCP servers — all configurable via a single JSON file.\n\nFeatherFlow is a domain-focused evolution of the upstream [`nanobot`](https://github.com/HKUDS/nanobot) project, optimized for Feishu-first production workflows. Full credit to the upstream team for the excellent engineering baseline in runtime design and tool abstraction.\n\n> **Reference baseline:** `nanobot` @ [`30361c9`](https://github.com/HKUDS/nanobot/commit/30361c9307f9014f49530d80abd5717bc97f554a) (2026-02-23)\n\n---\n\n## Features\n\n| Category | Capabilities |\n|---|---|\n| **LLM Providers** | OpenRouter, OpenAI, Anthropic, DeepSeek, Gemini, and any OpenAI-compatible endpoint |\n| **Built-in Tools** | File system, shell, web fetch/search, paper research (search/details), cron scheduler, sub-agent spawning |\n| **Channels** | Feishu (WebSocket, runtime enabled) |\n| **Memory** | RAM-first with snapshots, lesson extraction, and compact session history |\n| **Extensibility** | MCP server integration, skill files, custom provider plugins |\n| **CLI** | Interactive onboarding, agent chat, gateway mode, cron and memory management |\n\n> Channel adapters for Telegram/Discord/Slack/Email/QQ/DingTalk/MoChat may exist in code, but current runtime wiring is Feishu-only.\n\n---\n\n## Quick Start\n\n### Installation\n\n```bash\n# Clone the repository\ngit clone https://github.com/lichman0405/featherflow.git\ncd featherflow\n\n# Create and activate a virtual environment\npython3 -m venv .venv\nsource .venv/bin/activate\n\n# Install FeatherFlow\npip install --upgrade pip\npip install -e .\n\n# Verify\nfeatherflow --version\n```\n\n### First Run\n\n```bash\n# Interactive setup wizard — configures your provider, model, and identity\nfeatherflow onboard\n\n# Send a one-shot message\nfeatherflow agent -m \"hello\"\n\n# Start an interactive chat session\nfeatherflow agent\n\n# Launch the long-running gateway (channels + scheduled jobs)\nfeatherflow gateway\n```\n\n`featherflow onboard` now also supports:\n\n- Paper research tool configuration (`tools.papers` provider, API key, limits)\n- Optional Feishu channel setup (can be skipped; secure defaults preserved)\n\n---\n\n## Installation Options\n\n### With Dev Dependencies\n\n```bash\npip install -e '.[dev]'\n```\n\n### Docker (Recommended for Production)\n\n```bash\n# Start the gateway\ndocker compose up --build featherflow-gateway\n\n# Run a one-off CLI command in the container\ndocker compose --profile cli run --rm featherflow-cli status\n```\n\n**Runtime data directory mapping:**\n\n| Location | Path |\n|---|---|\n| Host | `~/.featherflow` |\n| Container | `/root/.featherflow` |\n\n---\n\n## Configuration\n\nFeatherFlow reads from `~/.featherflow/config.json`. The interactive wizard (`featherflow onboard`) can generate this file for you.\n\n**Default paths:**\n\n| Item | Path |\n|---|---|\n| Config file | `~/.featherflow/config.json` |\n| Workspace | `~/.featherflow/workspace` |\n\n### Configuration Skeleton\n\n```json\n{\n \"providers\": {\n \"openrouter\": {\n \"apiKey\": \"sk-or-v1-xxx\"\n }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"anthropic/claude-opus-4-5\",\n \"name\": \"featherflow\",\n \"temperature\": 0.7\n }\n },\n \"channels\": {\n \"feishu\": {\n \"enabled\": true,\n \"appId\": \"cli_xxx\",\n \"appSecret\": \"xxx\",\n \"allowFrom\": []\n }\n },\n \"tools\": {\n \"web\": {\n \"enabled\": true\n }\n },\n \"heartbeat\": {\n \"enabled\": true,\n \"intervalSeconds\": 1800\n }\n}\n```\n\n### Key Sections\n\n- **`providers`** — API keys and base URLs for each LLM provider.\n- **`agents.defaults`** — Default model, temperature, token limits, and agent identity.\n- **`channels`** — Feishu channel credentials and access-control settings (`allowFrom`, group read policy, reaction behavior).\n- **`tools`** — Web/search/fetch behavior, paper research provider settings (`tools.papers`), shell execution policy, and MCP server definitions.\n- **`heartbeat`** — Periodic background prompts (`enabled`, `intervalSeconds`) for proactive agent behaviors.\n\n> **Security:** Set file permissions to `0600` on your config file and configure strict `allowFrom` lists before exposing to any channel. See [`docs/SECURITY.md`](docs/SECURITY.md) for full guidance.\n\n---\n\n## CLI Reference\n\n**Agent & Gateway**\n\n| Command | Description |\n|---|---|\n| `featherflow onboard` | Interactive setup wizard |\n| `featherflow agent` | Start an interactive chat session |\n| `featherflow agent -m \"<prompt>\"` | Send a single prompt and exit |\n| `featherflow gateway` | Run the long-running gateway (channels + cron) |\n\n**Status & Diagnostics**\n\n| Command | Description |\n|---|---|\n| `featherflow status` | Show runtime and provider status |\n| `featherflow channels status` | Show channel connection status |\n| `featherflow memory status` | Show memory snapshot and stats |\n\n**Cron Scheduler**\n\n| Command | Description |\n|---|---|\n| `featherflow cron list` | List all scheduled jobs |\n| `featherflow cron add` | Add a new scheduled job |\n| `featherflow cron run <id>` | Trigger a job manually |\n| `featherflow cron enable <id>` | Enable a job |\n| `featherflow cron disable <id>` | Disable a job |\n| `featherflow cron remove <id>` | Remove a job permanently |\n\n**Providers**\n\n| Command | Description |\n|---|---|\n| `featherflow provider login <provider>` | Authenticate with an LLM provider |\n\n---\n\n## Core Capabilities\n\n### Memory & Self-Improvement\n\nFeatherFlow uses a RAM-first memory architecture:\n\n- **Session window** — unconsolidated recent context for fast recall\n- **Long-term snapshots** — periodic persistence with audit trails\n- **Lesson extraction** — automatically distills insights from user feedback and tool outcomes\n- **Configurable confidence thresholds** — controls promotion of lessons to long-term memory\n\n### Scheduled Tasks\n\nJobs can be defined as:\n\n- **Interval jobs** — run every N seconds/minutes/hours\n- **Cron expression jobs** — full cron syntax support\n- **One-time jobs** — execute at a specific datetime\n\nAll jobs can be toggled, triggered manually, or removed via the CLI.\n\n### MCP Integration\n\nConnect any MCP-compatible tool server and expose its tools directly to the agent. Define MCP servers under the `tools.mcp` section of your config.\n\n---\n\n## Development\n\n### Prerequisites\n\n- Python 3.11+\n- Linux or macOS (recommended)\n\n### Run Tests\n\n```bash\nPYTHONPATH=. .venv/bin/pytest -q\n```\n\n### Lint\n\n```bash\n.venv/bin/ruff check .\n```\n\n---\n\n## Migration Guide\n\nIf upgrading from a previous version or migrating from `nanobot`:\n\n| Item | Old | New |\n|---|---|---|\n| Python package | `nanobot.*` | `featherflow.*` |\n| CLI command | `assistant` | `featherflow` |\n| Runtime directory | `~/.assistant` | `~/.featherflow` |\n| Workspace directory | `~/.assistant/workspace` | `~/.featherflow/workspace` |\n\nBackward-compatible fallbacks for old config and data paths are retained where possible.\n\n---\n\n## License\n\n[MIT](LICENSE)\n"}, "691573a3e512ea1ba5515c589f950b83ede200ad": {"t": 1786068116.8425698, "n": 13890, "h": "766f8be98a28949e", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n#### E2E Tests\n\n```bash\n# Electron E2E (full desktop app + bridge + LLM)\ncd apps/desktop\nnpm run build && npx playwright test --config=playwright.config.ts --project=electron\n```\n\n| Platform | E2E Coverage | Notes |\n|---|---|---|\n| **Linux** (Ubuntu CI) | Full suite ✓ | bwrap sandbox + all specs |\n| **Windows** (WSL CI) | Full suite ✓ | WSL bwrap sandbox + all specs (needs `MIQI_RUN_SANDBOX_E2E=1`) |\n| **macOS** (CI) | Non-sandbox only | bwrap not available; sandbox specs excluded via `--grep-invert` |\n\n> **macOS known limitation**: The \"restart recall\" E2E test (`session-context-recall.spec.ts`) is skipped only when `process.env.CI && process.platform === 'darwin'` (local macOS runs still exercise the test). After a full app restart on macOS ARM64 CI runners, session history (chat messages) fails to render in `<main>` even though the sidebar session title loads correctly and the bridge reports `running / initialized`. This is likely a bridge IPC timing issue or APFS/SQLite WAL checkpoint race on cold start — needs native debugging. The non-restart session-switch recall test still validates #490 behavior on macOS.\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\ntest\n"}, "e72ed495b7268934f8a8eed06ad2dd8d15ebb64b": {"t": 1786068576.2810388, "n": 13890, "h": "766f8be98a28949e", "c": "# MiQi\n\n<p align=\"center\">\n <em>🐈⬛🪶 A lightweight, extensible personal AI agent framework with a modern desktop interface</em>\n</p>\n\n<p align=\"center\">\n <img src=\"https://img.shields.io/badge/python-3.11%20%7C%203.12-blue\" alt=\"Python 3.11 | 3.12\" />\n <img src=\"https://img.shields.io/badge/node.js-20+-green\" alt=\"Node.js 20+\" />\n <img src=\"https://img.shields.io/badge/status-alpha-orange\" alt=\"Development Status: Alpha\" />\n <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-green\" alt=\"MIT License\" /></a>\n</p>\n\n---\n\n## Overview\n\nMiQi Desktop is an Electron-based desktop application that provides a modern graphical interface for the MiQi AI agent. It combines powerful AI agent capabilities with an intuitive user interface, supporting chat interaction, memory management, task scheduling, and more.\n\n\n### Core Positioning\n\n- 🎯 **Personal AI Agent** — not just a chatbot: persistent memory, learned skills, file operations, and scheduled tasks\n- 🔧 **Highly Extensible** — MCP protocol for external tools, custom skills, and pluggable LLM providers\n- 🖥️ **Native Desktop Experience** — Electron with system-level integration (WSL2 sandbox, filesystem operations)\n- 🔒 **Local-First** — all data stored locally; non-destructive file editing with versioned snapshots\n- 📋 **Typed Application Protocol** — typed AppServer with JSON Schema catalog, method stability tracking, and handler-boundary validation\n\n### Tech Stack\n\n| Layer | Technology | Version |\n|-------|-----------|---------|\n| Desktop Framework | Electron | 35.2 |\n| Frontend UI | React + TypeScript | 19.1 / 5.8 |\n| CSS | Tailwind CSS 4 | 4.x |\n| Component Library | Radix UI + Lucide Icons | — |\n| Python Runtime | Python (asyncio) | 3.11+ |\n| Data Validation | Pydantic v2 | 2.12+ |\n| CLI Framework | Typer | 0.20+ |\n| Build (Desktop) | electron-vite + electron-builder | 3.1 / 26.0 |\n| Build (Python) | PyInstaller + Hatchling | 6.20+ |\n\n---\n\n## Key Features\n\n| Feature | Description |\n|---|---|\n| **Smart Chat** | Natural language conversation with streaming responses and tool-call progress |\n| **Multi-Provider** | OpenAI, Anthropic, Gemini, OpenRouter, DeepSeek, and more — with provider resilience |\n| **Typed Protocol** | Typed AppServer with method specs, JSON Schema catalog, and handler-boundary validation |\n| **Memory System** | Long-term memory snapshots, self-improvement lessons, and cross-session recall |\n| **Task Scheduler** | Cron-based scheduled tasks with timezone support |\n| **Skill System** | Create, upload, and manage agent skills; SkillHub registry integration |\n| **Plugin Ecology** | MCP servers, plugins, and marketplace with deterministic catalog |\n| **Sandbox Execution** | bwrap-based sandbox with LANDLOCK filesystem rules, streaming I/O, and process lifecycle |\n| **File Management** | Workspace FS with watch, fuzzy search, snapshot/versioning, and non-destructive editing |\n| **Replay & Debug** | Deterministic replay of turns, timeline, and messages for inspection |\n| **Session Management** | Browse, search, archive, import/export conversation history |\n| **Desktop App** | 15+ feature pages with real-time streaming, typewriter animation, and context menus |\n\n---\n\n## Quick Start\n\n### Prerequisites\n\n- **Python 3.11+** — to run MiQi backend\n- **Node.js 20+** — to run Electron frontend\n- **uv** — Python package manager (recommended)\n\n### Installation\n\n```bash\n# 1. Clone the repository\ngit clone http://git.miqroera.com/intership/miqi-desktop.git\ncd miqi-desktop\n\n# 2. Install Python dependencies\nuv sync\n\n# 3. Install frontend dependencies\ncd apps/desktop\nnpm install\n```\n\n### Development Mode\n\n```bash\n# Start Electron dev server with hot-reload\ncd apps/desktop\nnpm run dev\n```\n\n### Production Build\n\n**One-step build** (recommended):\n\n```bash\ncd apps/desktop\nnpm run build:all # Python backend → Frontend compile → Electron package\n```\n\n**Step-by-step build**:\n\n```bash\ncd apps/desktop\n\n# 1. Build Python backend (generates dist/miqi-bridge.exe)\nnpm run build:bridge\n\n# 2. Compile frontend\nnpm run build\n\n# 3. Package as desktop application\nnpx electron-builder --win --publish never\n```\n\nThe packaged `miqi-bridge.exe` is a self-contained binary (PyInstaller onefile) that includes Python and all dependencies — no system Python installation required on the target machine. It also supports a `--check` flag for environment validation:\n\n```bash\nmiqi-bridge.exe --check\n# Output: {\"ok\": true, \"python_version\": \"3.12.10\", \"issues\": []}\n```\n\n---\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────┐\n│ MiQi Desktop App │\n├─────────────────────────────────────────────────────────────┤\n│ Electron Frontend │\n│ ├── React 19 + TypeScript │\n│ ├── Tailwind CSS 4 + shadcn/ui │\n│ └── 15+ Feature Pages (Chat, Agents, Skills, MCPs, ...) │\n├─────────────────────────────────────────────────────────────┤\n│ Bridge (IPC Communication) │\n│ ├── stdin/stdout JSON-line protocol │\n│ ├── State synchronization + Log forwarding │\n│ └── BridgeRuntimeLoop (persistent asyncio event loop) │\n├─────────────────────────────────────────────────────────────┤\n│ AppServer (Typed Protocol Layer) │\n│ ├── ProtocolRegistry (typed method specs) │\n│ ├── Typed Envelopes (Pydantic v2) │\n│ ├── JSON Schema Draft 2020-12 Catalog │\n│ └── Handler Typed Validation │\n├─────────────────────────────────────────────────────────────┤\n│ MiQi Runtime Engine │\n│ ├── RuntimeSession / TaskRunner / TurnRunner │\n│ ├── HistoryRuntime + LedgerRuntime (SQLite persistence) │\n│ ├── ContextRuntime (compaction, token budgeting) │\n│ ├── ThreadRuntime (fork, rollback, import/export) │\n│ └── ReplayRuntime (deterministic replay inspection) │\n├─────────────────────────────────────────────────────────────┤\n│ Execution & Sandbox │\n│ ├── ToolOrchestrator (approval → sandbox → execute) │\n│ ├── PermissionEngine + ApprovalPolicy + HookRuntime │\n│ ├── bwrap Sandbox (LANDLOCK, streaming, cancellation) │\n│ └── Workbench Process Runtime (command/exec, process/*) │\n├─────────────────────────────────────────────────────────────┤\n│ Tools & Integrations │\n│ ├── Built-in Tools (filesystem, shell, web, papers, ...) │\n│ ├── MCP Client (external tool servers) │\n│ ├── Plugin Manager + Skill Loader │\n│ └── Office Document Tools (docx, pptx, xlsx) │\n└─────────────────────────────────────────────────────────────┘\n```\n\n1. Launch the application\n2. Go through the setup wizard:\n - **Environment Check** — validates Python and dependencies (bundled exe auto-detects; dev mode checks system Python)\n - **WSL2 Setup** — (Windows only) auto-detects and installs WSL2 for sandbox support\n - **LLM Provider** — configure API keys and default model\n3. Start chatting with the AI agent\n### Protocol Method Families\n\n| Family | Scope | Methods |\n|--------|-------|---------|\n| `turn/*` | Turn | start, interrupt, steer |\n| `thread/*` | Thread | list, get, rollback, fork, delete, compact/start, inject_items |\n| `fs/*` | Filesystem | readFile, writeFile, createDirectory, getMetadata, readDirectory, remove, copy, watch, unwatch |\n| `fuzzyFileSearch/*` | Filesystem | sessionStart, sessionUpdate, sessionStop |\n| `command/exec` | Process | exec, exec/write, exec/resize, exec/terminate |\n| `process/*` | Process | spawn, writeStdin, resizePty, kill, list, get, snapshot |\n| `replay.*` | Debug | turns, timeline, messages |\n| `config/*` | Session | get, batchWrite |\n| `model/*` | Session | list, get |\n| `feature/*` | Session | list, set |\n| `permission/*` | Session | listProfiles, getProfile |\n| `plugin/*` | Session | list, install, uninstall, enable, disable, configure |\n| `skills/*` | Session | list, get, create, upload, delete, setExtraRoots |\n| `mcp/*` | Session | listServers, getServer, status |\n| `agent/*` | Session | list, get, spawn, kill |\n| `protocol/*` | Connection | catalog, method_names, schema |\n\n---\n\n## Configuration\n\nThe application configuration file is located at `~/.miqi/config.json`:\n\n```json\n{\n \"providers\": {\n \"openai\": { \"apiKey\": \"sk-...\" },\n \"anthropic\": { \"apiKey\": \"sk-ant-...\" }\n },\n \"agents\": {\n \"defaults\": {\n \"model\": \"claude-sonnet-4-6\",\n \"temperature\": 0.1,\n \"maxToolIterations\": 100\n }\n },\n \"tools\": {\n \"restrictToWorkspace\": true\n }\n}\n```\n\n### Environment Variables\n\n| Variable | Description |\n|---|---|\n| `MIQI_PYTHON_PATH` | Custom Python interpreter path |\n| `MIQI_AGENTS__DEFAULTS__MODEL` | Override default model |\n\n---\n\n## Development Guide\n\n### Project Structure\n\n```\nmiqi-desktop/\n├── miqi/ # Python backend\n│ ├── runtime/ # Runtime engine (AppServer, Session, Turn, Thread, Replay, Agent, MCP, ...)\n│ ├── agent/ # Agent logic, tools, memory, trace, context compression, smart routing\n│ ├── bridge/ # Electron bridge service (IPC protocol)\n│ ├── bus/ # Internal message bus (async in/out queues)\n│ ├── execution/ # Tool orchestrator, permissions, approval, hooks, sandbox policy\n│ ├── providers/ # LLM provider implementations + resilience\n│ ├── protocol/ # Typed commands, events, permissions (runtime-frontend protocol)\n│ ├── channels/ # Chat channel adapters (Feishu, Slack, Discord, Telegram, ...)\n│ ├── sandbox/ # bwrap sandbox manager\n│ ├── skills/ # Built-in skills (cron, paper-research, feishu-report, ...)\n│ ├── session/ # Session management (Manager, SQLite store)\n│ ├── config/ # Configuration loader and schema\n│ ├── cli/ # CLI commands (agent, gateway, trace, config)\n│ ├── cron/ # Cron scheduler service\n│ ├── context/ # Context fragments, thread store\n│ ├── heartbeat/ # Heartbeat service\n│ ├── plan/ # Plan tracker and tool\n│ ├── documents/ # Office document tools (docx, pptx, xlsx)\n│ ├── observability/ # OpenTelemetry integration\n│ ├── server/ # Server assets and configuration\n│ ├── templates/ # Templates\n│ ├── tui/ # Terminal UI (Textual-based)\n│ └── utils/ # Utility functions\n├── apps/\n│ └── desktop/ # Electron frontend\n│ ├── src/main/ # Main process (BridgeManager, IPC handlers)\n│ ├── src/renderer/ # Renderer (React pages and components)\n│ └── src/preload/ # Preload scripts (contextBridge API)\n├── tests/ # Test suite (~150+ test files)\n│ ├── runtime/ # Runtime unit and integration tests (~70+ files)\n│ ├── bridge/ # Bridge protocol and audit tests (~20+ files)\n│ ├── execution/ # Sandbox, permissions, orchestration tests\n│ ├── providers/ # LLM provider tests\n│ ├── protocol/ # Protocol commands/events/permissions tests\n│ └── agent/tools/ # Tool-level tests\n├── docs/ # Documentation (MkDocs)\n├── plan/ # Implementation plans (not in VCS deliverables)\n└── scripts/ # Build and utility scripts\n```\n\n### Code Standards\n\n- **Python**: Ruff for linting (line-length 100)\n- **TypeScript**: ESLint for linting\n- **Commit Messages**: Conventional Commits format\n\n### Testing\n\n```bash\n# Python backend tests (~1800+ tests)\nuv run pytest\n\n# Skip sandbox/subprocess tests for quick feedback\nuv run pytest -m \"not sandbox and not subprocess\"\n\n# Frontend tests\ncd apps/desktop\nnpm run test\n```\n\n#### E2E Tests\n\n```bash\n# Electron E2E (full desktop app + bridge + LLM)\ncd apps/desktop\nnpm run build && npx playwright test --config=playwright.config.ts --project=electron\n```\n\n| Platform | E2E Coverage | Notes |\n|---|---|---|\n| **Linux** (Ubuntu CI) | Full suite ✓ | bwrap sandbox + all specs |\n| **Windows** (WSL CI) | Full suite ✓ | WSL bwrap sandbox + all specs (needs `MIQI_RUN_SANDBOX_E2E=1`) |\n| **macOS** (CI) | Non-sandbox only | bwrap not available; sandbox specs excluded via `--grep-invert` |\n\n> **macOS known limitation**: The \"restart recall\" E2E test (`session-context-recall.spec.ts`) is skipped only when `process.env.CI && process.platform === 'darwin'` (local macOS runs still exercise the test). After a full app restart on macOS ARM64 CI runners, session history (chat messages) fails to render in `<main>` even though the sidebar session title loads correctly and the bridge reports `running / initialized`. This is likely a bridge IPC timing issue or APFS/SQLite WAL checkpoint race on cold start — needs native debugging. The non-restart session-switch recall test still validates #490 behavior on macOS.\n\n---\n\n## Documentation\n\n- [Getting Started](docs/getting-started.md)\n- [Architecture](docs/architecture.md)\n- [Configuration](docs/configuration.md)\n- [MCP Integration](docs/mcp-integration.md)\n- [Developer Guide](docs/developer-guide.md)\n- [Internal Alpha Smoke](docs/internal-alpha-smoke.md)\n\n---\n\n## License\n\n[MIT License](LICENSE)\n\n---\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\ntest\n"}}, "miqi/providers/registry.py": {"73a40664b663d992d67ec29266962be605079903": {"t": 1785809880.983749, "n": 15289, "h": "ade489268094b728", "c": "\"\"\"\nProvider Registry — single source of truth for LLM provider metadata.\n\nAdding a new provider:\n 1. Add a ProviderSpec to PROVIDERS below.\n 2. Add a field to ProvidersConfig in config/schema.py.\n Done. Env vars, prefixing, config matching, status display all derive from here.\n\nOrder matters — it controls match priority and fallback. Gateways first.\nEvery entry writes out all fields so you can copy-paste as a template.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any\n\n\n@dataclass(frozen=True)\nclass ProviderSpec:\n \"\"\"One LLM provider's metadata. See PROVIDERS below for real examples.\n\n Placeholders in env_extras values:\n {api_key} — the user's API key\n {api_base} — api_base from config, or this spec's default_api_base\n \"\"\"\n\n # identity\n name: str # config field name, e.g. \"dashscope\"\n keywords: tuple[str, ...] # model-name keywords for matching (lowercase)\n env_key: str # API key env var, e.g. \"DASHSCOPE_API_KEY\"\n display_name: str = \"\" # shown in `miqi status`\n\n # provider routing and model prefixing\n provider_type: str = \"openai\" # \"openai\" | \"anthropic\" | \"gemini\"\n model_prefix: str = \"\" # prefix to strip from model name before API call\n skip_prefixes: tuple[str, ...] = () # kept for reference\n\n # extra env vars, e.g. ((\"ZHIPUAI_API_KEY\", \"{api_key}\"),)\n env_extras: tuple[tuple[str, str], ...] = ()\n\n # gateway / local detection\n is_gateway: bool = False # routes any model (OpenRouter, AiHubMix)\n is_local: bool = False # local deployment (vLLM, Ollama)\n detect_by_key_prefix: str = \"\" # match api_key prefix, e.g. \"sk-or-\"\n detect_by_base_keyword: str = \"\" # match substring in api_base URL\n default_api_base: str = \"\" # fallback base URL\n\n # gateway behavior\n strip_model_prefix: bool = False # strip \"provider/\" before re-prefixing\n\n # per-model param overrides, e.g. ((\"kimi-k2.5\", {\"temperature\": 1.0}),)\n model_overrides: tuple[tuple[str, dict[str, Any]], ...] = ()\n\n # Direct providers use their own SDK (e.g., CustomProvider)\n is_direct: bool = False\n\n # Provider supports cache_control on content blocks (e.g. Anthropic prompt caching)\n supports_prompt_caching: bool = False\n\n # Provider requires reasoning_content preserved in message history for multi-turn\n # conversations (DeepSeek official API for deepseek-reasoner requires this).\n supports_reasoning_history: bool = False\n\n @property\n def label(self) -> str:\n return self.display_name or self.name.title()\n\n\n# ---------------------------------------------------------------------------\n# PROVIDERS — the registry. Order = priority. Copy any entry as template.\n# ---------------------------------------------------------------------------\n\nPROVIDERS: tuple[ProviderSpec, ...] = (\n\n # === Custom (direct OpenAI-compatible endpoint, uses CustomProvider) ======\n ProviderSpec(\n name=\"custom\",\n keywords=(),\n env_key=\"\",\n display_name=\"Custom\",\n model_prefix=\"\",\n is_direct=True,\n ),\n\n # === Gateways (detected by api_key / api_base, not model name) =========\n # Gateways can route any model, so they win in fallback.\n\n # OpenRouter: global gateway, keys start with \"sk-or-\"\n ProviderSpec(\n name=\"openrouter\",\n keywords=(\"openrouter\",),\n env_key=\"OPENROUTER_API_KEY\",\n display_name=\"OpenRouter\",\n model_prefix=\"openrouter\", # strip 'openrouter/' before passing to API\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"sk-or-\",\n detect_by_base_keyword=\"openrouter\",\n default_api_base=\"https://openrouter.ai/api/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_prompt_caching=True,\n ),\n\n # AiHubMix: global gateway, OpenAI-compatible interface.\n # strip_model_prefix=True: strips any 'provider/' to get bare model name.\n ProviderSpec(\n name=\"aihubmix\",\n keywords=(\"aihubmix\",),\n env_key=\"OPENAI_API_KEY\", # OpenAI-compatible\n display_name=\"AiHubMix\",\n model_prefix=\"\", # strip_model_prefix=True handles stripping\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"aihubmix\",\n default_api_base=\"https://aihubmix.com/v1\",\n strip_model_prefix=True, # anthropic/claude-3 → claude-3 → openai/claude-3\n model_overrides=(),\n ),\n\n # SiliconFlow (硅基流动): OpenAI-compatible gateway, model names keep org prefix\n ProviderSpec(\n name=\"siliconflow\",\n keywords=(\"siliconflow\",),\n env_key=\"SILICONFLOW_API_KEY\",\n display_name=\"SiliconFlow\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"siliconflow\",\n default_api_base=\"https://api.siliconflow.cn/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # VolcEngine (火山引擎): OpenAI-compatible gateway\n ProviderSpec(\n name=\"volcengine\",\n keywords=(\"volcengine\", \"volces\", \"ark\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"VolcEngine\",\n model_prefix=\"volcengine\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"volces\",\n default_api_base=\"https://ark.cn-beijing.volces.com/api/v3\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Standard providers (matched by model-name keywords) ===============\n\n ProviderSpec(\n name=\"anthropic\",\n keywords=(\"anthropic\", \"claude\"),\n env_key=\"ANTHROPIC_API_KEY\",\n display_name=\"Anthropic\",\n provider_type=\"anthropic\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_prompt_caching=True,\n ),\n\n ProviderSpec(\n name=\"openai\",\n keywords=(\"openai\", \"gpt\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"OpenAI\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # DeepSeek: deepseek-reasoner (R1) requires reasoning_content in multi-turn history.\n ProviderSpec(\n name=\"deepseek\",\n keywords=(\"deepseek\",),\n env_key=\"DEEPSEEK_API_KEY\",\n display_name=\"DeepSeek\",\n model_prefix=\"deepseek\",\n skip_prefixes=(\"deepseek/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.deepseek.com/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_reasoning_history=True, # R1 multi-turn needs reasoning_content back\n ),\n\n ProviderSpec(\n name=\"gemini\",\n keywords=(\"gemini\",),\n env_key=\"GEMINI_API_KEY\",\n display_name=\"Gemini\",\n provider_type=\"gemini\",\n model_prefix=\"gemini\",\n skip_prefixes=(\"gemini/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\", # GeminiProvider uses its own fixed endpoint\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n ProviderSpec(\n name=\"zhipu\",\n keywords=(\"zhipu\", \"glm\", \"zai\"),\n env_key=\"ZAI_API_KEY\",\n display_name=\"Zhipu AI\",\n model_prefix=\"zai\",\n skip_prefixes=(\"zhipu/\", \"zai/\", \"openrouter/\", \"hosted_vllm/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://open.bigmodel.cn/api/paas/v4/\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n ProviderSpec(\n name=\"dashscope\",\n keywords=(\"qwen\", \"dashscope\"),\n env_key=\"DASHSCOPE_API_KEY\",\n display_name=\"DashScope\",\n model_prefix=\"dashscope\",\n skip_prefixes=(\"dashscope/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Moonshot: Kimi models. Kimi K2.5 API enforces temperature >= 1.0.\n ProviderSpec(\n name=\"moonshot\",\n keywords=(\"moonshot\", \"kimi\"),\n env_key=\"MOONSHOT_API_KEY\",\n display_name=\"Moonshot\",\n model_prefix=\"moonshot\",\n skip_prefixes=(\"moonshot/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.moonshot.ai/v1\", # intl; use api.moonshot.cn for China\n strip_model_prefix=False,\n model_overrides=(\n (\"kimi-k2.5\", {\"temperature\": 1.0}),\n ),\n ),\n\n # MiniMax: Token Plan API lives at api.minimaxi.com/v1.\n ProviderSpec(\n name=\"minimax\",\n keywords=(\"minimax\",),\n env_key=\"MINIMAX_API_KEY\",\n display_name=\"MiniMax\",\n model_prefix=\"minimax\",\n skip_prefixes=(\"minimax/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.minimaxi.com/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Ollama Cloud: hosted Ollama API, requires API key.\n ProviderSpec(\n name=\"ollama_cloud\",\n keywords=(\"ollama_cloud\", \"ollama-cloud\", \"-cloud\", \":cloud\"),\n env_key=\"OLLAMA_API_KEY\",\n display_name=\"Ollama Cloud\",\n model_prefix=\"ollama\",\n skip_prefixes=(\"ollama/\", \"ollama_chat/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://ollama.com/api\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Local deployment (matched by config key, NOT by api_base) =========\n\n # vLLM / any OpenAI-compatible local server.\n # Detected when config key is \"vllm\" (provider_name=\"vllm\").\n ProviderSpec(\n name=\"vllm\",\n keywords=(\"vllm\",),\n env_key=\"HOSTED_VLLM_API_KEY\",\n display_name=\"vLLM/Local\",\n model_prefix=\"hosted_vllm\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=True,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\", # user must provide in config\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Ollama local server.\n # Detected when config key is \"ollama_local\" (provider_name=\"ollama_local\").\n ProviderSpec(\n name=\"ollama_local\",\n keywords=(\"ollama_local\", \"ollama-local\", \"ollama\"),\n env_key=\"OLLAMA_API_KEY\",\n display_name=\"Ollama Local\",\n model_prefix=\"ollama\",\n skip_prefixes=(\"ollama/\", \"ollama_chat/\"),\n env_extras=(),\n is_gateway=False,\n is_local=True,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"http://localhost:11434\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Auxiliary (not a primary LLM provider) ============================\n\n # Groq: mainly used for Whisper voice transcription, also usable for LLM.\n ProviderSpec(\n name=\"groq\",\n keywords=(\"groq\",),\n env_key=\"GROQ_API_KEY\",\n display_name=\"Groq\",\n model_prefix=\"groq\",\n skip_prefixes=(\"groq/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.groq.com/openai/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n)\n\n\n# ---------------------------------------------------------------------------\n# Lookup helpers\n# ---------------------------------------------------------------------------\n\ndef find_by_model(model: str) -> ProviderSpec | None:\n \"\"\"Match a standard provider by model-name keyword (case-insensitive).\n Skips gateways/local — those are matched by api_key/api_base instead.\"\"\"\n model_lower = model.lower()\n model_normalized = model_lower.replace(\"-\", \"_\")\n model_prefix = model_lower.split(\"/\", 1)[0] if \"/\" in model_lower else \"\"\n normalized_prefix = model_prefix.replace(\"-\", \"_\")\n std_specs = [s for s in PROVIDERS if not s.is_gateway and not s.is_local]\n\n # Prefer explicit provider prefix match to avoid ambiguous keyword fallbacks.\n for spec in std_specs:\n if model_prefix and normalized_prefix == spec.name:\n return spec\n\n for spec in std_specs:\n if any(kw in model_lower or kw.replace(\"-\", \"_\") in model_normalized for kw in spec.keywords):\n return spec\n return None\n\n\ndef find_gateway(\n provider_name: str | None = None,\n api_key: str | None = None,\n api_base: str | None = None,\n) -> ProviderSpec | None:\n \"\"\"Detect gateway/local provider.\n\n Priority:\n 1. provider_name — if it maps to a gateway/local spec, use it directly.\n 2. api_key prefix — e.g. \"sk-or-\" → OpenRouter.\n 3. api_base keyword — e.g. \"aihubmix\" in URL → AiHubMix.\n\n A standard provider with a custom api_base (e.g. DeepSeek behind a proxy)\n will NOT be mistaken for vLLM — the old fallback is gone.\n \"\"\"\n # 1. Direct match by config key\n if provider_name:\n spec = find_by_name(provider_name)\n if spec and (spec.is_gateway or spec.is_local):\n return spec\n\n # 2. Auto-detect by api_key prefix / api_base keyword\n for spec in PROVIDERS:\n if spec.detect_by_key_prefix and api_key and api_key.startswith(spec.detect_by_key_prefix):\n return spec\n if spec.detect_by_base_keyword and api_base and spec.detect_by_base_keyword in api_base:\n return spec\n\n return None\n\n\ndef find_by_name(name: str) -> ProviderSpec | None:\n \"\"\"Find a provider spec by config field name, e.g. \"dashscope\".\"\"\"\n for spec in PROVIDERS:\n if spec.name == name:\n return spec\n return None\n"}, "e8d30628ee228326516cdaf9e67f3aed9ad92572": {"t": 1785846988.5163603, "n": 15289, "h": "ade489268094b728", "c": "\"\"\"\nProvider Registry — single source of truth for LLM provider metadata.\n\nAdding a new provider:\n 1. Add a ProviderSpec to PROVIDERS below.\n 2. Add a field to ProvidersConfig in config/schema.py.\n Done. Env vars, prefixing, config matching, status display all derive from here.\n\nOrder matters — it controls match priority and fallback. Gateways first.\nEvery entry writes out all fields so you can copy-paste as a template.\n\"\"\"\n\nfrom __future__ import annotations\n\nfrom dataclasses import dataclass\nfrom typing import Any\n\n\n@dataclass(frozen=True)\nclass ProviderSpec:\n \"\"\"One LLM provider's metadata. See PROVIDERS below for real examples.\n\n Placeholders in env_extras values:\n {api_key} — the user's API key\n {api_base} — api_base from config, or this spec's default_api_base\n \"\"\"\n\n # identity\n name: str # config field name, e.g. \"dashscope\"\n keywords: tuple[str, ...] # model-name keywords for matching (lowercase)\n env_key: str # API key env var, e.g. \"DASHSCOPE_API_KEY\"\n display_name: str = \"\" # shown in `miqi status`\n\n # provider routing and model prefixing\n provider_type: str = \"openai\" # \"openai\" | \"anthropic\" | \"gemini\"\n model_prefix: str = \"\" # prefix to strip from model name before API call\n skip_prefixes: tuple[str, ...] = () # kept for reference\n\n # extra env vars, e.g. ((\"ZHIPUAI_API_KEY\", \"{api_key}\"),)\n env_extras: tuple[tuple[str, str], ...] = ()\n\n # gateway / local detection\n is_gateway: bool = False # routes any model (OpenRouter, AiHubMix)\n is_local: bool = False # local deployment (vLLM, Ollama)\n detect_by_key_prefix: str = \"\" # match api_key prefix, e.g. \"sk-or-\"\n detect_by_base_keyword: str = \"\" # match substring in api_base URL\n default_api_base: str = \"\" # fallback base URL\n\n # gateway behavior\n strip_model_prefix: bool = False # strip \"provider/\" before re-prefixing\n\n # per-model param overrides, e.g. ((\"kimi-k2.5\", {\"temperature\": 1.0}),)\n model_overrides: tuple[tuple[str, dict[str, Any]], ...] = ()\n\n # Direct providers use their own SDK (e.g., CustomProvider)\n is_direct: bool = False\n\n # Provider supports cache_control on content blocks (e.g. Anthropic prompt caching)\n supports_prompt_caching: bool = False\n\n # Provider requires reasoning_content preserved in message history for multi-turn\n # conversations (DeepSeek official API for deepseek-reasoner requires this).\n supports_reasoning_history: bool = False\n\n @property\n def label(self) -> str:\n return self.display_name or self.name.title()\n\n\n# ---------------------------------------------------------------------------\n# PROVIDERS — the registry. Order = priority. Copy any entry as template.\n# ---------------------------------------------------------------------------\n\nPROVIDERS: tuple[ProviderSpec, ...] = (\n\n # === Custom (direct OpenAI-compatible endpoint, uses CustomProvider) ======\n ProviderSpec(\n name=\"custom\",\n keywords=(),\n env_key=\"\",\n display_name=\"Custom\",\n model_prefix=\"\",\n is_direct=True,\n ),\n\n # === Gateways (detected by api_key / api_base, not model name) =========\n # Gateways can route any model, so they win in fallback.\n\n # OpenRouter: global gateway, keys start with \"sk-or-\"\n ProviderSpec(\n name=\"openrouter\",\n keywords=(\"openrouter\",),\n env_key=\"OPENROUTER_API_KEY\",\n display_name=\"OpenRouter\",\n model_prefix=\"openrouter\", # strip 'openrouter/' before passing to API\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"sk-or-\",\n detect_by_base_keyword=\"openrouter\",\n default_api_base=\"https://openrouter.ai/api/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_prompt_caching=True,\n ),\n\n # AiHubMix: global gateway, OpenAI-compatible interface.\n # strip_model_prefix=True: strips any 'provider/' to get bare model name.\n ProviderSpec(\n name=\"aihubmix\",\n keywords=(\"aihubmix\",),\n env_key=\"OPENAI_API_KEY\", # OpenAI-compatible\n display_name=\"AiHubMix\",\n model_prefix=\"\", # strip_model_prefix=True handles stripping\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"aihubmix\",\n default_api_base=\"https://aihubmix.com/v1\",\n strip_model_prefix=True, # anthropic/claude-3 → claude-3 → openai/claude-3\n model_overrides=(),\n ),\n\n # SiliconFlow (硅基流动): OpenAI-compatible gateway, model names keep org prefix\n ProviderSpec(\n name=\"siliconflow\",\n keywords=(\"siliconflow\",),\n env_key=\"SILICONFLOW_API_KEY\",\n display_name=\"SiliconFlow\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"siliconflow\",\n default_api_base=\"https://api.siliconflow.cn/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # VolcEngine (火山引擎): OpenAI-compatible gateway\n ProviderSpec(\n name=\"volcengine\",\n keywords=(\"volcengine\", \"volces\", \"ark\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"VolcEngine\",\n model_prefix=\"volcengine\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=True,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"volces\",\n default_api_base=\"https://ark.cn-beijing.volces.com/api/v3\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Standard providers (matched by model-name keywords) ===============\n\n ProviderSpec(\n name=\"anthropic\",\n keywords=(\"anthropic\", \"claude\"),\n env_key=\"ANTHROPIC_API_KEY\",\n display_name=\"Anthropic\",\n provider_type=\"anthropic\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_prompt_caching=True,\n ),\n\n ProviderSpec(\n name=\"openai\",\n keywords=(\"openai\", \"gpt\"),\n env_key=\"OPENAI_API_KEY\",\n display_name=\"OpenAI\",\n model_prefix=\"\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # DeepSeek: deepseek-reasoner (R1) requires reasoning_content in multi-turn history.\n ProviderSpec(\n name=\"deepseek\",\n keywords=(\"deepseek\",),\n env_key=\"DEEPSEEK_API_KEY\",\n display_name=\"DeepSeek\",\n model_prefix=\"deepseek\",\n skip_prefixes=(\"deepseek/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.deepseek.com/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n supports_reasoning_history=True, # R1 multi-turn needs reasoning_content back\n ),\n\n ProviderSpec(\n name=\"gemini\",\n keywords=(\"gemini\",),\n env_key=\"GEMINI_API_KEY\",\n display_name=\"Gemini\",\n provider_type=\"gemini\",\n model_prefix=\"gemini\",\n skip_prefixes=(\"gemini/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\", # GeminiProvider uses its own fixed endpoint\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n ProviderSpec(\n name=\"zhipu\",\n keywords=(\"zhipu\", \"glm\", \"zai\"),\n env_key=\"ZAI_API_KEY\",\n display_name=\"Zhipu AI\",\n model_prefix=\"zai\",\n skip_prefixes=(\"zhipu/\", \"zai/\", \"openrouter/\", \"hosted_vllm/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://open.bigmodel.cn/api/paas/v4/\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n ProviderSpec(\n name=\"dashscope\",\n keywords=(\"qwen\", \"dashscope\"),\n env_key=\"DASHSCOPE_API_KEY\",\n display_name=\"DashScope\",\n model_prefix=\"dashscope\",\n skip_prefixes=(\"dashscope/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Moonshot: Kimi models. Kimi K2.5 API enforces temperature >= 1.0.\n ProviderSpec(\n name=\"moonshot\",\n keywords=(\"moonshot\", \"kimi\"),\n env_key=\"MOONSHOT_API_KEY\",\n display_name=\"Moonshot\",\n model_prefix=\"moonshot\",\n skip_prefixes=(\"moonshot/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.moonshot.ai/v1\", # intl; use api.moonshot.cn for China\n strip_model_prefix=False,\n model_overrides=(\n (\"kimi-k2.5\", {\"temperature\": 1.0}),\n ),\n ),\n\n # MiniMax: Token Plan API lives at api.minimaxi.com/v1.\n ProviderSpec(\n name=\"minimax\",\n keywords=(\"minimax\",),\n env_key=\"MINIMAX_API_KEY\",\n display_name=\"MiniMax\",\n model_prefix=\"minimax\",\n skip_prefixes=(\"minimax/\", \"openrouter/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.minimaxi.com/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Ollama Cloud: hosted Ollama API, requires API key.\n ProviderSpec(\n name=\"ollama_cloud\",\n keywords=(\"ollama_cloud\", \"ollama-cloud\", \"-cloud\", \":cloud\"),\n env_key=\"OLLAMA_API_KEY\",\n display_name=\"Ollama Cloud\",\n model_prefix=\"ollama\",\n skip_prefixes=(\"ollama/\", \"ollama_chat/\"),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://ollama.com/api\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Local deployment (matched by config key, NOT by api_base) =========\n\n # vLLM / any OpenAI-compatible local server.\n # Detected when config key is \"vllm\" (provider_name=\"vllm\").\n ProviderSpec(\n name=\"vllm\",\n keywords=(\"vllm\",),\n env_key=\"HOSTED_VLLM_API_KEY\",\n display_name=\"vLLM/Local\",\n model_prefix=\"hosted_vllm\",\n skip_prefixes=(),\n env_extras=(),\n is_gateway=False,\n is_local=True,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"\", # user must provide in config\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # Ollama local server.\n # Detected when config key is \"ollama_local\" (provider_name=\"ollama_local\").\n ProviderSpec(\n name=\"ollama_local\",\n keywords=(\"ollama_local\", \"ollama-local\", \"ollama\"),\n env_key=\"OLLAMA_API_KEY\",\n display_name=\"Ollama Local\",\n model_prefix=\"ollama\",\n skip_prefixes=(\"ollama/\", \"ollama_chat/\"),\n env_extras=(),\n is_gateway=False,\n is_local=True,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"http://localhost:11434\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n\n # === Auxiliary (not a primary LLM provider) ============================\n\n # Groq: mainly used for Whisper voice transcription, also usable for LLM.\n ProviderSpec(\n name=\"groq\",\n keywords=(\"groq\",),\n env_key=\"GROQ_API_KEY\",\n display_name=\"Groq\",\n model_prefix=\"groq\",\n skip_prefixes=(\"groq/\",),\n env_extras=(),\n is_gateway=False,\n is_local=False,\n detect_by_key_prefix=\"\",\n detect_by_base_keyword=\"\",\n default_api_base=\"https://api.groq.com/openai/v1\",\n strip_model_prefix=False,\n model_overrides=(),\n ),\n)\n\n\n# ---------------------------------------------------------------------------\n# Lookup helpers\n# ---------------------------------------------------------------------------\n\ndef find_by_model(model: str) -> ProviderSpec | None:\n \"\"\"Match a standard provider by model-name keyword (case-insensitive).\n Skips gateways/local — those are matched by api_key/api_base instead.\"\"\"\n model_lower = model.lower()\n model_normalized = model_lower.replace(\"-\", \"_\")\n model_prefix = model_lower.split(\"/\", 1)[0] if \"/\" in model_lower else \"\"\n normalized_prefix = model_prefix.replace(\"-\", \"_\")\n std_specs = [s for s in PROVIDERS if not s.is_gateway and not s.is_local]\n\n # Prefer explicit provider prefix match to avoid ambiguous keyword fallbacks.\n for spec in std_specs:\n if model_prefix and normalized_prefix == spec.name:\n return spec\n\n for spec in std_specs:\n if any(kw in model_lower or kw.replace(\"-\", \"_\") in model_normalized for kw in spec.keywords):\n return spec\n return None\n\n\ndef find_gateway(\n provider_name: str | None = None,\n api_key: str | None = None,\n api_base: str | None = None,\n) -> ProviderSpec | None:\n \"\"\"Detect gateway/local provider.\n\n Priority:\n 1. provider_name — if it maps to a gateway/local spec, use it directly.\n 2. api_key prefix — e.g. \"sk-or-\" → OpenRouter.\n 3. api_base keyword — e.g. \"aihubmix\" in URL → AiHubMix.\n\n A standard provider with a custom api_base (e.g. DeepSeek behind a proxy)\n will NOT be mistaken for vLLM — the old fallback is gone.\n \"\"\"\n # 1. Direct match by config key\n if provider_name:\n spec = find_by_name(provider_name)\n if spec and (spec.is_gateway or spec.is_local):\n return spec\n\n # 2. Auto-detect by api_key prefix / api_base keyword\n for spec in PROVIDERS:\n if spec.detect_by_key_prefix and api_key and api_key.startswith(spec.detect_by_key_prefix):\n return spec\n if spec.detect_by_base_keyword and api_base and spec.detect_by_base_keyword in api_base:\n return spec\n\n return None\n\n\ndef find_by_name(name: str) -> ProviderSpec | None:\n \"\"\"Find a provider spec by config field name, e.g. \"dashscope\".\"\"\"\n for spec in PROVIDERS:\n if spec.name == name:\n return spec\n return None\n"}}}} |