2026-02-01 07:36:42 +00:00
<div align="center">
<img src="nanobot_logo.png" alt="nanobot" width="500">
2026-04-05 20:06:38 +00:00
<h1>nanobot: Ultra-Lightweight Personal AI Agent</h1>
2026-02-01 07:36:42 +00:00
<p>
<a href="https://pypi.org/project/nanobot-ai/"><img src="https://img.shields.io/pypi/v/nanobot-ai" alt="PyPI"></a>
2026-02-01 18:18:40 +00:00
<a href="https://pepy.tech/project/nanobot-ai"><img src="https://static.pepy.tech/badge/nanobot-ai" alt="Downloads"></a>
2026-02-01 07:36:42 +00:00
<img src="https://img.shields.io/badge/python-≥3.11-blue" alt="Python">
<img src="https://img.shields.io/badge/license-MIT-green" alt="License">
2026-02-01 18:17:56 +00:00
<a href="./COMMUNICATION.md"><img src="https://img.shields.io/badge/Feishu-Group-E9DBFC?style=flat&logo=feishu&logoColor=white" alt="Feishu"></a>
<a href="./COMMUNICATION.md"><img src="https://img.shields.io/badge/WeChat-Group-C5EAB4?style=flat&logo=wechat&logoColor=white" alt="WeChat"></a>
2026-02-03 12:42:06 +00:00
<a href="https://discord.gg/MnCvHqpUGB"><img src="https://img.shields.io/badge/Discord-Community-5865F2?style=flat&logo=discord&logoColor=white" alt="Discord"></a>
2026-02-01 07:36:42 +00:00
</p>
</div>
2026-03-05 14:46:03 +00:00
🐈 **nanobot** is an **ultra-lightweight** personal AI assistant inspired by [OpenClaw ](https://github.com/openclaw/openclaw ).
2026-02-01 07:36:42 +00:00
2026-04-05 20:06:38 +00:00
⚡️ Delivers core agent functionality with **99% fewer lines of code** .
2026-02-06 07:28:39 +00:00
2026-03-05 14:46:03 +00:00
📏 Real-time line count: run `bash core_agent_lines.sh` to verify anytime.
2026-02-01 07:36:42 +00:00
## 📢 News
2026-04-03 16:18:36 +00:00
- **2026-04-02** 🧱 **Long-running tasks** run more reliably — core runtime hardening.
- **2026-04-01** 🔑 GitHub Copilot auth restored; stricter workspace paths; OpenRouter Claude caching fix.
- **2026-03-31** 🛰️ WeChat multimodal alignment, Discord/Matrix polish, Python SDK facade, MCP and tool fixes.
- **2026-03-30** 🧩 OpenAI-compatible API tightened; composable agent lifecycle hooks.
- **2026-03-29** 💬 WeChat voice, typing, QR/media resilience; fixed-session OpenAI-compatible API.
- **2026-03-28** 📚 Provider docs refresh; skill template wording fix.
2026-03-27 15:16:28 +00:00
- **2026-03-27** 🚀 Released **v0.1.4.post6** — architecture decoupling, litellm removal, end-to-end streaming, WeChat channel, and a security fix. Please see [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post6 ) for details.
- **2026-03-26** 🏗️ Agent runner extracted and lifecycle hooks unified; stream delta coalescing at boundaries.
2026-03-27 15:17:22 +00:00
- **2026-03-25** 🌏 StepFun provider, configurable timezone, Gemini thought signatures.
- **2026-03-24** 🔧 WeChat compatibility, Feishu CardKit streaming, test suite restructured.
2026-04-03 16:18:36 +00:00
<details>
<summary>Earlier news</summary>
2026-03-27 15:16:28 +00:00
- **2026-03-23** 🔧 Command routing refactored for plugins, WhatsApp/WeChat media, unified channel login CLI.
- **2026-03-22** ⚡ End-to-end streaming, WeChat channel, Anthropic cache optimization, `/status` command.
2026-03-24 18:11:03 +00:00
- **2026-03-21** 🔒 Replace `litellm` with native `openai` + `anthropic` SDKs. Please see [commit ](https://github.com/HKUDS/nanobot/commit/3dfdab7 ).
- **2026-03-20** 🧙 Interactive setup wizard — pick your provider, model autocomplete, and you're good to go.
- **2026-03-19** 💬 Telegram gets more resilient under load; Feishu now renders code blocks properly.
2026-03-24 18:11:50 +00:00
- **2026-03-18** 📷 Telegram can now send media via URL. Cron schedules show human-readable details.
2026-03-24 18:11:03 +00:00
- **2026-03-17** ✨ Feishu formatting glow-up, Slack reacts when done, custom endpoints support extra headers, and image handling is more reliable.
2026-03-16 15:28:41 +00:00
- **2026-03-16** 🚀 Released **v0.1.4.post5** — a refinement-focused release with stronger reliability and channel support, and a more dependable day-to-day experience. Please see [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post5 ) for details.
2026-03-16 14:27:28 +00:00
- **2026-03-15** 🧩 DingTalk rich media, smarter built-in skills, and cleaner model compatibility.
- **2026-03-14** 💬 Channel plugins, Feishu replies, and steadier MCP, QQ, and media handling.
- **2026-03-13** 🌐 Multi-provider web search, LangSmith, and broader reliability improvements.
- **2026-03-12** 🚀 VolcEngine support, Telegram reply context, `/restart` , and sturdier memory.
- **2026-03-11** 🔌 WeCom, Ollama, cleaner discovery, and safer tool behavior.
- **2026-03-10** 🧠 Token-based memory, shared retries, and cleaner gateway and Telegram behavior.
- **2026-03-09** 💬 Slack thread polish and better Feishu audio compatibility.
2026-03-08 17:00:46 +00:00
- **2026-03-08** 🚀 Released **v0.1.4.post4** — a reliability-packed release with safer defaults, better multi-instance support, sturdier MCP, and major channel and provider improvements. Please see [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post4 ) for details.
2026-03-08 01:44:06 +00:00
- **2026-03-07** 🚀 Azure OpenAI provider, WhatsApp media, QQ group chats, and more Telegram/Feishu polish.
- **2026-03-06** 🪄 Lighter providers, smarter media handling, and sturdier memory and CLI compatibility.
- **2026-03-05** ⚡️ Telegram draft streaming, MCP SSE support, and broader channel reliability fixes.
- **2026-03-04** 🛠️ Dependency cleanup, safer file reads, and another round of test and Cron fixes.
- **2026-03-03** 🧠 Cleaner user-message merging, safer multimodal saves, and stronger Cron guards.
2026-03-08 01:42:30 +00:00
- **2026-03-02** 🛡️ Safer default access control, sturdier Cron reloads, and cleaner Matrix media handling.
2026-03-08 01:44:06 +00:00
- **2026-03-01** 🌐 Web proxy support, smarter Cron reminders, and Feishu rich-text parsing improvements.
2026-02-28 18:06:56 +00:00
- **2026-02-28** 🚀 Released **v0.1.4.post3** — cleaner context, hardened session history, and smarter agent. Please see [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post3 ) for details.
2026-02-28 18:04:12 +00:00
- **2026-02-27** 🧠 Experimental thinking mode support, DingTalk media messages, Feishu and QQ channel fixes.
- **2026-02-26** 🛡️ Session poisoning fix, WhatsApp dedup, Windows path guard, Mistral compatibility.
- **2026-02-25** 🧹 New Matrix channel, cleaner session context, auto workspace template sync.
2026-02-24 16:34:22 +00:00
- **2026-02-24** 🚀 Released **v0.1.4.post2** — a reliability-focused release with a redesigned heartbeat, prompt cache optimization, and hardened provider & channel stability. See [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post2 ) for details.
2026-02-24 16:35:50 +00:00
- **2026-02-23** 🔧 Virtual tool-call heartbeat, prompt cache optimization, Slack mrkdwn fixes.
- **2026-02-22** 🛡️ Slack thread isolation, Discord typing fix, agent reliability improvements.
2026-02-21 13:20:55 +00:00
- **2026-02-21** 🎉 Released **v0.1.4.post1** — new providers, media support across channels, and major stability improvements. See [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4.post1 ) for details.
2026-02-21 08:33:31 +00:00
- **2026-02-20** 🐦 Feishu now receives multimodal files from users. More reliable memory under the hood.
2026-02-21 08:33:02 +00:00
- **2026-02-19** ✨ Slack now sends files, Discord splits long messages, and subagents work in CLI mode.
- **2026-02-18** ⚡️ nanobot now supports VolcEngine, MCP custom auth headers, and Anthropic prompt caching.
2026-02-18 23:09:55 +08:00
- **2026-02-17** 🎉 Released **v0.1.4** — MCP support, progress streaming, new providers, and multiple channel improvements. Please see [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.4 ) for details.
2026-02-17 08:20:50 +00:00
- **2026-02-16** 🦞 nanobot now integrates a [ClawHub ](https://clawhub.ai ) skill — search and install public agent skills.
2026-02-17 08:19:23 +00:00
- **2026-02-15** 🔑 nanobot now supports OpenAI Codex provider with OAuth login support.
2026-02-15 14:03:51 +00:00
- **2026-02-14** 🔌 nanobot now supports MCP! See [MCP section ](#mcp-model-context-protocol ) for details.
2026-02-18 23:09:55 +08:00
- **2026-02-13** 🎉 Released **v0.1.3.post7** — includes security hardening and multiple improvements. **Please upgrade to the latest version to address security issues** . See [release notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.3.post7 ) for more details.
2026-02-12 15:28:07 +00:00
- **2026-02-12** 🧠 Redesigned memory system — Less code, more reliable. Join the [discussion ](https://github.com/HKUDS/nanobot/discussions/566 ) about it!
2026-02-15 14:03:51 +00:00
- **2026-02-11** ✨ Enhanced CLI experience and added MiniMax support!
2026-02-21 08:33:02 +00:00
- **2026-02-10** 🎉 Released **v0.1.3.post6** with improvements! Check the updates [notes ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.3.post6 ) and our [roadmap ](https://github.com/HKUDS/nanobot/discussions/431 ).
- **2026-02-09** 💬 Added Slack, Email, and QQ support — nanobot now supports multiple chat platforms!
- **2026-02-08** 🔧 Refactored Providers—adding a new LLM provider now takes just 2 simple steps! Check [here ](#providers ).
2026-02-18 23:09:55 +08:00
- **2026-02-07** 🚀 Released **v0.1.3.post5** with Qwen support & several key improvements! Check [here ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.3.post5 ) for details.
2026-02-07 17:52:29 +08:00
- **2026-02-06** ✨ Added Moonshot/Kimi provider, Discord integration, and enhanced security hardening!
2026-02-06 14:14:28 +08:00
- **2026-02-05** ✨ Added Feishu channel, DeepSeek provider, and enhanced scheduled tasks support!
2026-02-18 23:09:55 +08:00
- **2026-02-04** 🚀 Released **v0.1.3.post4** with multi-provider & Docker support! Check [here ](https://github.com/HKUDS/nanobot/releases/tag/v0.1.3.post4 ) for details.
2026-02-06 14:14:28 +08:00
- **2026-02-03** ⚡ Integrated vLLM for local LLM support and improved natural language task scheduling!
- **2026-02-02** 🎉 nanobot officially launched! Welcome to try 🐈 nanobot!
2026-02-01 07:36:42 +00:00
2026-02-18 14:41:13 +00:00
</details>
2026-03-18 15:18:38 +00:00
> 🐈 nanobot is for educational, research, and technical exchange purposes only. It is unrelated to crypto and does not involve any official token or coin.
2026-02-01 07:36:42 +00:00
## Key Features of nanobot:
2026-04-05 20:07:11 +00:00
🪶 **Ultra-Lightweight** : A lightweight implementation built for stable, long-running AI agents.
2026-02-01 07:36:42 +00:00
2026-02-01 20:55:10 +08:00
🔬 **Research-Ready** : Clean, readable code that's easy to understand, modify, and extend for research.
2026-02-01 07:36:42 +00:00
2026-02-01 20:54:22 +08:00
⚡️ **Lightning Fast** : Minimal footprint means faster startup, lower resource usage, and quicker iterations.
2026-02-01 07:36:42 +00:00
2026-02-04 14:08:41 -05:00
💎 **Easy-to-Use** : One-click to deploy and you're ready to go.
2026-02-01 21:50:35 +08:00
2026-02-01 07:36:42 +00:00
## 🏗️ Architecture
<p align="center">
<img src="nanobot_arch.png" alt="nanobot architecture" width="800">
</p>
2026-03-11 08:11:28 +00:00
## Table of Contents
- [News ](#-news )
- [Key Features ](#key-features-of-nanobot )
- [Architecture ](#️ -architecture )
- [Features ](#-features )
- [Install ](#-install )
- [Quick Start ](#-quick-start )
- [Chat Apps ](#-chat-apps )
- [Agent Social Network ](#-agent-social-network )
- [Configuration ](#️ -configuration )
- [Multiple Instances ](#-multiple-instances )
2026-04-04 09:34:37 +00:00
- [Memory ](#-memory )
2026-03-11 08:11:28 +00:00
- [CLI Reference ](#-cli-reference )
2026-04-04 09:34:37 +00:00
- [In-Chat Commands ](#-in-chat-commands )
2026-03-30 18:46:11 +00:00
- [Python SDK ](#-python-sdk )
2026-03-30 14:43:22 +00:00
- [OpenAI-Compatible API ](#-openai-compatible-api )
2026-03-11 08:11:28 +00:00
- [Docker ](#-docker )
- [Linux Service ](#-linux-service )
- [Project Structure ](#-project-structure )
- [Contribute & Roadmap ](#-contribute--roadmap )
- [Star History ](#-star-history )
2026-02-01 07:36:42 +00:00
## ✨ Features
<table align="center">
<tr align="center">
2026-02-01 21:16:40 +08:00
<th><p align="center">📈 24/7 Real-Time Market Analysis</p></th>
<th><p align="center">🚀 Full-Stack Software Engineer</p></th>
2026-02-01 21:17:31 +08:00
<th><p align="center">📅 Smart Daily Routine Manager</p></th>
2026-02-01 21:16:40 +08:00
<th><p align="center">📚 Personal Knowledge Assistant</p></th>
2026-02-01 07:36:42 +00:00
</tr>
<tr>
<td align="center"><p align="center"><img src="case/search.gif" width="180" height="400"></p></td>
<td align="center"><p align="center"><img src="case/code.gif" width="180" height="400"></p></td>
2026-02-04 14:08:41 -05:00
<td align="center"><p align="center"><img src="case/schedule.gif" width="180" height="400"></p></td>
2026-02-01 07:36:42 +00:00
<td align="center"><p align="center"><img src="case/memory.gif" width="180" height="400"></p></td>
</tr>
<tr>
2026-02-01 21:16:40 +08:00
<td align="center">Discovery • Insights • Trends</td>
<td align="center">Develop • Deploy • Scale</td>
<td align="center">Schedule • Automate • Organize</td>
<td align="center">Learn • Memory • Reasoning</td>
2026-02-01 07:36:42 +00:00
</tr>
</table>
## 📦 Install
2026-04-04 09:34:37 +00:00
> [!IMPORTANT]
> This README may describe features that are available first in the latest source code.
> If you want the newest features and experiments, install from source.
> If you want the most stable day-to-day experience, install from PyPI or with `uv`.
**Install from source** (latest features, experimental changes may land here first; recommended for development)
2026-02-01 07:36:42 +00:00
```bash
git clone https://github.com/HKUDS/nanobot.git
cd nanobot
pip install -e .
```
2026-04-04 09:34:37 +00:00
**Install with [uv](https://github.com/astral-sh/uv)** (stable release, fast)
2026-02-02 15:26:17 +07:00
```bash
2026-02-03 07:24:59 +00:00
uv tool install nanobot-ai
```
2026-04-04 09:34:37 +00:00
**Install from PyPI** (stable release)
2026-02-03 07:24:59 +00:00
```bash
pip install nanobot-ai
2026-02-02 15:26:17 +07:00
```
2026-03-08 16:57:28 +00:00
### Update to latest version
**PyPI / pip**
```bash
pip install -U nanobot-ai
nanobot --version
```
**uv**
```bash
uv tool upgrade nanobot-ai
nanobot --version
```
**Using WhatsApp?** Rebuild the local bridge after upgrading:
```bash
rm -rf ~/.nanobot/bridge
2026-03-23 17:00:19 +00:00
nanobot channels login whatsapp
2026-03-08 16:57:28 +00:00
```
2026-02-01 07:36:42 +00:00
## 🚀 Quick Start
> [!TIP]
2026-02-01 16:45:51 +00:00
> Set your API key in `~/.nanobot/config.json`.
2026-03-13 05:44:16 +00:00
> Get API keys: [OpenRouter](https://openrouter.ai/keys) (Global)
>
2026-03-18 05:09:03 +00:00
> For other LLM providers, please see the [Providers](#providers) section.
>
2026-03-13 05:44:16 +00:00
> For web search capability setup, please see [Web Search](#web-search).
2026-02-01 07:36:42 +00:00
**1. Initialize**
```bash
nanobot onboard
```
2026-03-20 07:53:18 +00:00
Use `nanobot onboard --wizard` if you want the interactive setup wizard.
2026-02-01 07:36:42 +00:00
**2. Configure** (`~/.nanobot/config.json` )
2026-03-20 07:53:18 +00:00
Configure these **two parts** in your config (other options have defaults).
2026-02-15 16:41:27 +00:00
*Set your API key* (e.g. OpenRouter, recommended for global users):
2026-02-01 07:36:42 +00:00
```json
{
"providers" : {
"openrouter" : {
"apiKey" : "sk-or-v1-xxx"
}
2026-02-15 16:41:27 +00:00
}
}
```
2026-02-26 02:23:07 +00:00
*Set your model* (optionally pin a provider — defaults to auto-detection):
2026-02-15 16:41:27 +00:00
```json
{
2026-02-01 16:35:59 +00:00
"agents" : {
"defaults" : {
2026-02-26 02:23:07 +00:00
"model" : "anthropic/claude-opus-4-5" ,
"provider" : "openrouter"
2026-02-04 06:45:53 +00:00
}
2026-02-01 07:36:42 +00:00
}
}
```
**3. Chat**
```bash
2026-02-15 16:41:27 +00:00
nanobot agent
2026-02-01 07:36:42 +00:00
```
That's it! You have a working AI assistant in 2 minutes.
## 💬 Chat Apps
2026-03-15 15:32:54 +08:00
Connect nanobot to your favorite chat platform. Want to build your own? See the [Channel Plugin Guide ](./docs/CHANNEL_PLUGIN_GUIDE.md ).
2026-02-01 07:36:42 +00:00
2026-02-17 08:41:09 +00:00
| Channel | What you need |
|---------|---------------|
| **Telegram** | Bot token from @BotFather |
| **Discord** | Bot token + Message Content intent |
2026-03-23 17:17:10 +00:00
| **WhatsApp** | QR code scan (`nanobot channels login whatsapp` ) |
| **WeChat (Weixin)** | QR code scan (`nanobot channels login weixin` ) |
2026-02-17 08:41:09 +00:00
| **Feishu** | App ID + App Secret |
| **DingTalk** | App Key + App Secret |
| **Slack** | Bot token + App-Level token |
2026-03-23 17:17:10 +00:00
| **Matrix** | Homeserver URL + Access token |
2026-02-17 08:41:09 +00:00
| **Email** | IMAP/SMTP credentials |
| **QQ** | App ID + App Secret |
2026-03-11 07:57:12 +00:00
| **Wecom** | Bot ID + Bot Secret |
2026-03-23 17:17:10 +00:00
| **Mochat** | Claw token (auto-setup available) |
2026-02-01 07:36:42 +00:00
<details>
<summary><b>Telegram</b> (Recommended)</summary>
**1. Create a bot**
- Open Telegram, search `@BotFather`
- Send `/newbot` , follow prompts
- Copy the token
**2. Configure**
```json
{
"channels" : {
"telegram" : {
"enabled" : true ,
"token" : "YOUR_BOT_TOKEN" ,
"allowFrom" : [ "YOUR_USER_ID" ]
}
}
}
```
2026-02-09 09:49:43 +03:00
> You can find your **User ID** in Telegram settings. It is shown as `@yourUserId`.
> Copy this value **without the `@` symbol** and paste it into the config file.
2026-02-01 07:36:42 +00:00
**3. Run**
```bash
nanobot gateway
```
</details>
2026-02-09 08:46:47 +00:00
<details>
2026-02-09 08:50:17 +00:00
<summary><b>Mochat (Claw IM)</b></summary>
2026-02-09 08:46:47 +00:00
Uses **Socket.IO WebSocket** by default, with HTTP polling fallback.
2026-02-10 07:22:03 +00:00
**1. Ask nanobot to set up Mochat for you**
2026-02-09 08:46:47 +00:00
2026-02-10 07:22:03 +00:00
Simply send this message to nanobot (replace `xxx@xxx` with your real email):
```
Read https://raw.githubusercontent.com/HKUDS/MoChat/refs/heads/main/skills/nanobot/skill.md and register on MoChat. My Email account is xxx@xxx Bind me as your owner and DM me on MoChat.
```
nanobot will automatically register, configure `~/.nanobot/config.json` , and connect to Mochat.
**2. Restart gateway**
```bash
nanobot gateway
```
That's it — nanobot handles the rest!
<br>
<details>
<summary>Manual configuration (advanced)</summary>
If you prefer to configure manually, add the following to `~/.nanobot/config.json` :
> Keep `claw_token` private. It should only be sent in `X-Claw-Token` header to your Mochat API endpoint.
2026-02-09 08:46:47 +00:00
```json
{
"channels" : {
2026-02-09 08:50:17 +00:00
"mochat" : {
2026-02-09 08:46:47 +00:00
"enabled" : true ,
2026-02-10 07:22:03 +00:00
"base_url" : "https://mochat.io" ,
"socket_url" : "https://mochat.io" ,
"socket_path" : "/socket.io" ,
"claw_token" : "claw_xxx" ,
"agent_user_id" : "6982abcdef" ,
2026-02-09 08:46:47 +00:00
"sessions" : [ "*" ],
"panels" : [ "*" ],
2026-02-10 07:22:03 +00:00
"reply_delay_mode" : "non-mention" ,
"reply_delay_ms" : 120000
2026-02-09 08:46:47 +00:00
}
}
}
```
2026-02-10 07:22:03 +00:00
</details>
2026-02-09 08:46:47 +00:00
</details>
2026-02-02 18:41:17 +05:30
<details>
<summary><b>Discord</b></summary>
**1. Create a bot**
- Go to https://discord.com/developers/applications
- Create an application → Bot → Add Bot
- Copy the bot token
**2. Enable intents**
- In the Bot settings, enable **MESSAGE CONTENT INTENT**
- (Optional) Enable **SERVER MEMBERS INTENT** if you plan to use allow lists based on member data
2026-02-06 07:04:10 +00:00
**3. Get your User ID**
- Discord Settings → Advanced → enable **Developer Mode**
- Right-click your avatar → **Copy User ID**
**4. Configure**
2026-02-02 18:41:17 +05:30
```json
{
"channels" : {
"discord" : {
"enabled" : true ,
"token" : "YOUR_BOT_TOKEN" ,
2026-02-12 17:10:50 +08:00
"allowFrom" : [ "YOUR_USER_ID" ],
"groupPolicy" : "mention"
2026-02-02 18:41:17 +05:30
}
}
}
```
2026-02-12 17:10:50 +08:00
> `groupPolicy` controls how the bot responds in group channels:
> - `"mention"` (default) — Only respond when @mentioned
> - `"open"` — Respond to all messages
> DMs always respond when the sender is in `allowFrom`.
2026-03-24 21:43:22 +01:00
> - If you set group policy to open create new threads as private threads and then @ the bot into it. Otherwise the thread itself and the channel in which you spawned it will spawn a bot session.
2026-02-12 17:10:50 +08:00
2026-02-06 07:04:10 +00:00
**5. Invite the bot**
2026-02-02 18:41:17 +05:30
- OAuth2 → URL Generator
- Scopes: `bot`
- Bot Permissions: `Send Messages` , `Read Message History`
- Open the generated invite URL and add the bot to your server
2026-02-06 07:04:10 +00:00
**6. Run**
2026-02-02 18:41:17 +05:30
```bash
nanobot gateway
```
</details>
2026-02-10 17:50:34 +01:00
<details>
<summary><b>Matrix (Element)</b></summary>
2026-02-26 03:04:01 +00:00
Install Matrix dependencies first:
```bash
pip install nanobot-ai[ matrix]
```
2026-02-10 17:50:34 +01:00
**1. Create/choose a Matrix account**
- Create or reuse a Matrix account on your homeserver (for example `matrix.org` ).
- Confirm you can log in with Element.
**2. Get credentials**
- You need:
- `userId` (example: `@nanobot:matrix.org` )
- `accessToken`
- `deviceId` (recommended so sync tokens can be restored across restarts)
- You can obtain these from your homeserver login API (`/_matrix/client/v3/login` ) or from your client's advanced session settings.
**3. Configure**
```json
{
"channels" : {
"matrix" : {
"enabled" : true ,
"homeserver" : "https://matrix.org" ,
"userId" : "@nanobot:matrix.org" ,
"accessToken" : "syt_xxx" ,
"deviceId" : "NANOBOT01" ,
"e2eeEnabled" : true ,
2026-03-02 06:13:37 +00:00
"allowFrom" : [ "@your_user:matrix.org" ],
2026-02-10 17:50:34 +01:00
"groupPolicy" : "open" ,
"groupAllowFrom" : [],
"allowRoomMentions" : false ,
2026-02-11 10:45:28 +01:00
"maxMediaBytes" : 20971520
2026-02-10 17:50:34 +01:00
}
}
}
```
2026-02-26 03:08:00 +00:00
> Keep a persistent `matrix-store` and stable `deviceId` — encrypted session state is lost if these change across restarts.
| Option | Description |
|--------|-------------|
2026-03-08 16:57:28 +00:00
| `allowFrom` | User IDs allowed to interact. Empty denies all; use `["*"]` to allow everyone. |
2026-02-26 03:08:00 +00:00
| `groupPolicy` | `open` (default), `mention` , or `allowlist` . |
| `groupAllowFrom` | Room allowlist (used when policy is `allowlist` ). |
| `allowRoomMentions` | Accept `@room` mentions in mention mode. |
| `e2eeEnabled` | E2EE support (default `true` ). Set `false` for plaintext-only. |
| `maxMediaBytes` | Max attachment size (default `20MB` ). Set `0` to block all media. |
2026-02-10 17:50:34 +01:00
**4. Run**
```bash
nanobot gateway
```
</details>
2026-02-01 07:36:42 +00:00
<details>
<summary><b>WhatsApp</b></summary>
Requires **Node.js ≥18** .
**1. Link device**
```bash
2026-03-23 17:00:19 +00:00
nanobot channels login whatsapp
2026-02-01 07:36:42 +00:00
# Scan QR with WhatsApp → Settings → Linked Devices
```
**2. Configure**
```json
{
"channels" : {
"whatsapp" : {
"enabled" : true ,
"allowFrom" : [ "+1234567890" ]
}
}
}
```
**3. Run** (two terminals)
```bash
# Terminal 1
2026-03-23 17:00:19 +00:00
nanobot channels login whatsapp
2026-02-01 07:36:42 +00:00
# Terminal 2
nanobot gateway
```
2026-03-07 03:06:19 +00:00
> WhatsApp bridge updates are not applied automatically for existing installations.
2026-03-08 16:57:28 +00:00
> After upgrading nanobot, rebuild the local bridge with:
2026-03-23 17:00:19 +00:00
> `rm -rf ~/.nanobot/bridge && nanobot channels login whatsapp`
2026-03-07 03:06:19 +00:00
2026-02-01 07:36:42 +00:00
</details>
2026-02-04 14:07:45 +08:00
<details>
2026-03-24 15:57:14 +08:00
<summary><b>Feishu</b></summary>
2026-02-04 14:07:45 +08:00
Uses **WebSocket** long connection — no public IP required.
**1. Create a Feishu bot**
- Visit [Feishu Open Platform ](https://open.feishu.cn/app )
2026-02-05 06:05:09 +00:00
- Create a new app → Enable **Bot** capability
2026-03-24 15:57:14 +08:00
- **Permissions**:
- `im:message` (send messages) and `im:message.p2p_msg:readonly` (receive messages)
- **Streaming replies** (default in nanobot): add ** `cardkit:card:write` ** (often labeled **Create and update cards** in the Feishu developer console). Required for CardKit entities and streamed assistant text. Older apps may not have it yet — open **Permission management** , enable the scope, then **publish** a new app version if the console requires it.
- If you **cannot** add `cardkit:card:write` , set `"streaming": false` under `channels.feishu` (see below). The bot still works; replies use normal interactive cards without token-by-token streaming.
2026-02-05 06:05:09 +00:00
- **Events**: Add `im.message.receive_v1` (receive messages)
- Select **Long Connection** mode (requires running nanobot first to establish connection)
- Get **App ID** and **App Secret** from "Credentials & Basic Info"
- Publish the app
2026-02-04 14:07:45 +08:00
**2. Configure**
```json
{
"channels" : {
"feishu" : {
"enabled" : true ,
"appId" : "cli_xxx" ,
"appSecret" : "xxx" ,
2026-02-05 06:05:09 +00:00
"encryptKey" : "" ,
"verificationToken" : "" ,
2026-03-09 17:54:02 +08:00
"allowFrom" : [ "ou_YOUR_OPEN_ID" ],
2026-03-24 15:57:14 +08:00
"groupPolicy" : "mention" ,
"streaming" : true
2026-02-04 14:07:45 +08:00
}
}
}
```
2026-03-24 15:57:14 +08:00
> `streaming` defaults to `true`. Use `false` if your app does not have **`cardkit:card:write`** (see permissions above).
2026-02-05 06:05:09 +00:00
> `encryptKey` and `verificationToken` are optional for Long Connection mode.
2026-03-02 06:13:37 +00:00
> `allowFrom`: Add your open_id (find it in nanobot logs when you message the bot). Use `["*"]` to allow all users.
2026-03-12 04:45:57 +00:00
> `groupPolicy`: `"mention"` (default — respond only when @mentioned), `"open"` (respond to all group messages). Private chats always respond.
2026-02-04 14:07:45 +08:00
**3. Run**
```bash
nanobot gateway
```
> [!TIP]
> Feishu uses WebSocket to receive messages — no webhook or public IP needed!
2026-02-09 15:47:55 +08:00
</details>
<details>
2026-02-09 16:17:35 +00:00
<summary><b>QQ (QQ单聊)</b></summary>
2026-02-09 15:47:55 +08:00
2026-02-09 16:17:35 +00:00
Uses **botpy SDK** with WebSocket — no public IP required. Currently supports **private messages only** .
2026-02-09 15:47:55 +08:00
2026-02-09 16:17:35 +00:00
**1. Register & create bot**
- Visit [QQ Open Platform ](https://q.qq.com ) → Register as a developer (personal or enterprise)
2026-02-09 15:47:55 +08:00
- Create a new bot application
2026-02-09 16:17:35 +00:00
- Go to **开发设置 (Developer Settings)** → copy **AppID** and **AppSecret**
2026-02-09 15:47:55 +08:00
2026-02-09 16:17:35 +00:00
**2. Set up sandbox for testing**
- In the bot management console, find **沙箱配置 (Sandbox Config)**
- Under **在消息列表配置** , click **添加成员** and add your own QQ number
- Once added, scan the bot's QR code with mobile QQ → open the bot profile → tap "发消息" to start chatting
**3. Configure**
2026-03-02 06:13:37 +00:00
> - `allowFrom`: Add your openid (find it in nanobot logs when you message the bot). Use `["*"]` for public access.
2026-03-14 08:25:44 +00:00
> - `msgFormat`: Optional. Use `"plain"` (default) for maximum compatibility with legacy QQ clients, or `"markdown"` for richer formatting on newer clients.
2026-02-09 16:17:35 +00:00
> - For production: submit a review in the bot console and publish. See [QQ Bot Docs](https://bot.q.qq.com/wiki/) for the full publishing flow.
2026-02-09 15:47:55 +08:00
```json
{
"channels" : {
"qq" : {
"enabled" : true ,
"appId" : "YOUR_APP_ID" ,
"secret" : "YOUR_APP_SECRET" ,
2026-03-14 08:25:44 +00:00
"allowFrom" : [ "YOUR_OPENID" ],
"msgFormat" : "plain"
2026-02-09 15:47:55 +08:00
}
}
}
```
2026-02-09 16:17:35 +00:00
**4. Run**
2026-02-09 15:47:55 +08:00
```bash
nanobot gateway
```
2026-02-09 16:17:35 +00:00
Now send a message to the bot from QQ — it should respond!
2026-02-09 15:47:55 +08:00
2026-02-04 14:07:45 +08:00
</details>
2026-02-08 11:37:36 +08:00
<details>
<summary><b>DingTalk (钉钉)</b></summary>
Uses **Stream Mode** — no public IP required.
**1. Create a DingTalk bot**
- Visit [DingTalk Open Platform ](https://open-dev.dingtalk.com/ )
- Create a new app -> Add **Robot** capability
- **Configuration**:
- Toggle **Stream Mode** ON
- **Permissions**: Add necessary permissions for sending messages
- Get **AppKey** (Client ID) and **AppSecret** (Client Secret) from "Credentials"
- Publish the app
**2. Configure**
```json
{
"channels" : {
"dingtalk" : {
"enabled" : true ,
"clientId" : "YOUR_APP_KEY" ,
"clientSecret" : "YOUR_APP_SECRET" ,
2026-03-02 06:13:37 +00:00
"allowFrom" : [ "YOUR_STAFF_ID" ]
2026-02-08 11:37:36 +08:00
}
}
}
```
2026-03-02 06:13:37 +00:00
> `allowFrom`: Add your staff ID. Use `["*"]` to allow all users.
2026-02-08 11:37:36 +08:00
**3. Run**
```bash
nanobot gateway
```
</details>
2026-02-09 11:39:13 +00:00
<details>
<summary><b>Slack</b></summary>
Uses **Socket Mode** — no public URL required.
**1. Create a Slack app**
2026-02-09 16:49:13 +00:00
- Go to [Slack API ](https://api.slack.com/apps ) → **Create New App** → "From scratch"
- Pick a name and select your workspace
2026-02-09 11:39:13 +00:00
2026-02-09 16:49:13 +00:00
**2. Configure the app**
- **Socket Mode**: Toggle ON → Generate an **App-Level Token** with `connections:write` scope → copy it (`xapp-...` )
- **OAuth & Permissions**: Add bot scopes: `chat:write` , `reactions:write` , `app_mentions:read`
- **Event Subscriptions**: Toggle ON → Subscribe to bot events: `message.im` , `message.channels` , `app_mention` → Save Changes
- **App Home**: Scroll to **Show Tabs** → Enable **Messages Tab** → Check ** "Allow users to send Slash commands and messages from the messages tab"**
- **Install App**: Click **Install to Workspace** → Authorize → copy the **Bot Token** (`xoxb-...` )
**3. Configure nanobot**
2026-02-09 11:39:13 +00:00
```json
{
"channels" : {
"slack" : {
"enabled" : true ,
"botToken" : "xoxb-..." ,
"appToken" : "xapp-..." ,
2026-03-02 06:13:37 +00:00
"allowFrom" : [ "YOUR_SLACK_USER_ID" ],
2026-02-09 11:39:13 +00:00
"groupPolicy" : "mention"
}
}
}
```
2026-02-09 16:49:13 +00:00
**4. Run**
2026-02-09 11:39:13 +00:00
```bash
nanobot gateway
```
2026-02-09 16:49:13 +00:00
DM the bot directly or @mention it in a channel — it should respond!
> [!TIP]
> - `groupPolicy`: `"mention"` (default — respond only when @mentioned), `"open"` (respond to all channel messages), or `"allowlist"` (restrict to specific channels).
> - DM policy defaults to open. Set `"dm": {"enabled": false}` to disable DMs.
2026-02-09 11:39:13 +00:00
</details>
2026-02-09 06:19:35 +00:00
<details>
<summary><b>Email</b></summary>
2026-02-09 12:40:24 +00:00
Give nanobot its own email account. It polls **IMAP** for incoming mail and replies via **SMTP** — like a personal email assistant.
2026-02-09 06:19:35 +00:00
**1. Get credentials (Gmail example)**
2026-02-09 12:40:24 +00:00
- Create a dedicated Gmail account for your bot (e.g. `my-nanobot@gmail.com` )
- Enable 2-Step Verification → Create an [App Password ](https://myaccount.google.com/apppasswords )
2026-02-09 06:19:35 +00:00
- Use this app password for both IMAP and SMTP
**2. Configure**
2026-02-09 12:40:24 +00:00
> - `consentGranted` must be `true` to allow mailbox access. This is a safety gate — set `false` to fully disable.
2026-03-02 06:13:37 +00:00
> - `allowFrom`: Add your email address. Use `["*"]` to accept emails from anyone.
2026-02-09 12:40:24 +00:00
> - `smtpUseTls` and `smtpUseSsl` default to `true` / `false` respectively, which is correct for Gmail (port 587 + STARTTLS). No need to set them explicitly.
> - Set `"autoReplyEnabled": false` if you only want to read/analyze emails without sending automatic replies.
2026-02-09 06:19:35 +00:00
```json
{
"channels" : {
"email" : {
"enabled" : true ,
"consentGranted" : true ,
"imapHost" : "imap.gmail.com" ,
"imapPort" : 993 ,
2026-02-09 12:40:24 +00:00
"imapUsername" : "my-nanobot@gmail.com" ,
2026-02-09 06:19:35 +00:00
"imapPassword" : "your-app-password" ,
"smtpHost" : "smtp.gmail.com" ,
"smtpPort" : 587 ,
2026-02-09 12:40:24 +00:00
"smtpUsername" : "my-nanobot@gmail.com" ,
2026-02-09 06:19:35 +00:00
"smtpPassword" : "your-app-password" ,
2026-02-09 12:40:24 +00:00
"fromAddress" : "my-nanobot@gmail.com" ,
"allowFrom" : [ "your-real-email@gmail.com" ]
2026-02-09 06:19:35 +00:00
}
}
}
```
**3. Run**
```bash
nanobot gateway
```
</details>
2026-03-23 16:47:41 +00:00
<details>
<summary><b>WeChat (微信 / Weixin)</b></summary>
Uses **HTTP long-poll** with QR-code login via the ilinkai personal WeChat API. No local WeChat desktop client is required.
2026-03-27 15:16:28 +00:00
**1. Install with WeChat support**
2026-03-23 16:47:41 +00:00
```bash
2026-03-27 15:16:28 +00:00
pip install "nanobot-ai[weixin]"
2026-03-23 16:47:41 +00:00
```
**2. Configure**
```json
{
"channels" : {
"weixin" : {
"enabled" : true ,
"allowFrom" : [ "YOUR_WECHAT_USER_ID" ]
}
}
}
```
> - `allowFrom`: Add the sender ID you see in nanobot logs for your WeChat account. Use `["*"]` to allow all users.
> - `token`: Optional. If omitted, log in interactively and nanobot will save the token for you.
2026-03-24 15:51:15 +08:00
> - `routeTag`: Optional. When your upstream Weixin deployment requires request routing, nanobot will send it as the `SKRouteTag` header.
2026-03-23 16:47:41 +00:00
> - `stateDir`: Optional. Defaults to nanobot's runtime directory for Weixin state.
> - `pollTimeout`: Optional long-poll timeout in seconds.
**3. Login**
```bash
nanobot channels login weixin
```
Use `--force` to re-authenticate and ignore any saved token:
```bash
nanobot channels login weixin --force
```
**4. Run**
```bash
nanobot gateway
```
</details>
2026-03-10 00:53:23 +08:00
<details>
<summary><b>Wecom (企业微信)</b></summary>
2026-03-11 08:04:14 +00:00
> Here we use [wecom-aibot-sdk-python](https://github.com/chengyongru/wecom_aibot_sdk) (community Python version of the official [@wecom/aibot-node-sdk](https://www.npmjs.com/package/@wecom/aibot-node-sdk)).
>
> Uses **WebSocket** long connection — no public IP required.
2026-03-10 00:53:23 +08:00
2026-03-11 07:57:12 +00:00
**1. Install the optional dependency**
2026-03-10 00:53:23 +08:00
2026-03-11 07:57:12 +00:00
```bash
pip install nanobot-ai[ wecom]
```
2026-03-10 00:53:23 +08:00
2026-03-11 07:57:12 +00:00
**2. Create a WeCom AI Bot**
Go to the WeCom admin console → Intelligent Robot → Create Robot → select **API mode** with **long connection** . Copy the Bot ID and Secret.
**3. Configure**
2026-03-10 00:53:23 +08:00
```json
{
"channels" : {
"wecom" : {
"enabled" : true ,
"botId" : "your_bot_id" ,
2026-03-11 07:57:12 +00:00
"secret" : "your_bot_secret" ,
"allowFrom" : [ "your_id" ]
2026-03-10 00:53:23 +08:00
}
}
}
```
2026-03-11 07:57:12 +00:00
**4. Run**
2026-03-10 00:53:23 +08:00
```bash
nanobot gateway
```
</details>
2026-02-11 14:39:20 +00:00
## 🌐 Agent Social Network
🐈 nanobot is capable of linking to the agent social network (agent community). **Just send one message and your nanobot joins automatically!**
| Platform | How to Join (send this message to your bot) |
|----------|-------------|
| [**Moltbook** ](https://www.moltbook.com/ ) | `Read https://moltbook.com/skill.md and follow the instructions to join Moltbook` |
| [**ClawdChat** ](https://clawdchat.ai/ ) | `Read https://clawdchat.ai/skill.md and follow the instructions to join ClawdChat` |
Simply send the command above to your nanobot (via CLI or any chat channel), and it will handle the rest.
2026-02-01 07:36:42 +00:00
## ⚙️ Configuration
2026-02-03 07:17:47 +00:00
Config file: `~/.nanobot/config.json`
2026-04-04 11:35:09 +00:00
> [!NOTE]
> If your config file is older than the current schema, you can refresh it without overwriting your existing values:
> run `nanobot onboard`, then answer `N` when asked whether to overwrite the config.
> nanobot will merge in missing default fields and keep your current settings.
2026-02-03 07:17:47 +00:00
### Providers
2026-02-09 04:51:58 +00:00
> [!TIP]
> - **Groq** provides free voice transcription via Whisper. If configured, Telegram voice messages will be automatically transcribed.
2026-03-18 05:09:03 +00:00
> - **MiniMax Coding Plan**: Exclusive discount links for the nanobot community: [Overseas](https://platform.minimax.io/subscribe/coding-plan?code=9txpdXw04g&source=link) · [Mainland China](https://platform.minimaxi.com/subscribe/token-plan?code=GILTJpMTqZ&source=link)
> - **MiniMax (Mainland China)**: If your API key is from MiniMax's mainland China platform (minimaxi.com), set `"apiBase": "https://api.minimaxi.com/v1"` in your minimax provider config.
2026-03-12 15:22:15 +00:00
> - **VolcEngine / BytePlus Coding Plan**: Use dedicated providers `volcengineCodingPlan` or `byteplusCodingPlan` instead of the pay-per-use `volcengine` / `byteplus` providers.
2026-02-09 04:51:58 +00:00
> - **Zhipu Coding Plan**: If you're on Zhipu's coding plan, set `"apiBase": "https://open.bigmodel.cn/api/coding/paas/v4"` in your zhipu provider config.
2026-03-12 18:23:05 -07:00
> - **Alibaba Cloud BaiLian**: If you're using Alibaba Cloud BaiLian's OpenAI-compatible endpoint, set `"apiBase": "https://dashscope.aliyuncs.com/compatible-mode/v1"` in your dashscope provider config.
2026-03-25 16:32:10 +08:00
> - **Step Fun (Mainland China)**: If your API key is from Step Fun's mainland China platform (stepfun.com), set `"apiBase": "https://api.stepfun.com/v1"` in your stepfun provider config.
2026-02-03 07:21:46 +00:00
2026-02-03 07:17:47 +00:00
| Provider | Purpose | Get API Key |
|----------|---------|-------------|
2026-03-24 17:53:35 +00:00
| `custom` | Any OpenAI-compatible endpoint | — |
2026-02-03 07:17:47 +00:00
| `openrouter` | LLM (recommended, access to all models) | [openrouter.ai ](https://openrouter.ai ) |
2026-03-12 15:22:15 +00:00
| `volcengine` | LLM (VolcEngine, pay-per-use) | [Coding Plan ](https://www.volcengine.com/activity/codingplan?utm_campaign=nanobot&utm_content=nanobot&utm_medium=devrel&utm_source=OWO&utm_term=nanobot ) · [volcengine.com ](https://www.volcengine.com ) |
| `byteplus` | LLM (VolcEngine international, pay-per-use) | [Coding Plan ](https://www.byteplus.com/en/activity/codingplan?utm_campaign=nanobot&utm_content=nanobot&utm_medium=devrel&utm_source=OWO&utm_term=nanobot ) · [byteplus.com ](https://www.byteplus.com ) |
2026-02-03 07:17:47 +00:00
| `anthropic` | LLM (Claude direct) | [console.anthropic.com ](https://console.anthropic.com ) |
2026-03-06 10:37:16 +00:00
| `azure_openai` | LLM (Azure OpenAI) | [portal.azure.com ](https://portal.azure.com ) |
2026-02-03 07:17:47 +00:00
| `openai` | LLM (GPT direct) | [platform.openai.com ](https://platform.openai.com ) |
2026-02-05 08:55:41 +00:00
| `deepseek` | LLM (DeepSeek direct) | [platform.deepseek.com ](https://platform.deepseek.com ) |
2026-02-03 07:17:47 +00:00
| `groq` | LLM + **Voice transcription** (Whisper) | [console.groq.com ](https://console.groq.com ) |
2026-02-22 18:29:09 +00:00
| `minimax` | LLM (MiniMax direct) | [platform.minimaxi.com ](https://platform.minimaxi.com ) |
2026-02-03 07:17:47 +00:00
| `gemini` | LLM (Gemini direct) | [aistudio.google.com ](https://aistudio.google.com ) |
2026-02-07 08:10:05 +00:00
| `aihubmix` | LLM (API gateway, access to all models) | [aihubmix.com ](https://aihubmix.com ) |
2026-02-20 08:45:42 +00:00
| `siliconflow` | LLM (SiliconFlow/硅基流动) | [siliconflow.cn ](https://siliconflow.cn ) |
2026-02-07 02:41:28 +00:00
| `dashscope` | LLM (Qwen) | [dashscope.console.aliyun.com ](https://dashscope.console.aliyun.com ) |
2026-02-08 07:29:31 +00:00
| `moonshot` | LLM (Moonshot/Kimi) | [platform.moonshot.cn ](https://platform.moonshot.cn ) |
| `zhipu` | LLM (Zhipu GLM) | [open.bigmodel.cn ](https://open.bigmodel.cn ) |
2026-04-03 14:40:31 +08:00
| `mimo` | LLM (MiMo) | [platform.xiaomimimo.com ](https://platform.xiaomimimo.com ) |
2026-03-11 08:42:12 +00:00
| `ollama` | LLM (local, Ollama) | — |
2026-03-18 15:38:03 +08:00
| `mistral` | LLM | [docs.mistral.ai ](https://docs.mistral.ai/ ) |
2026-03-25 16:32:10 +08:00
| `stepfun` | LLM (Step Fun/阶跃星辰) | [platform.stepfun.com ](https://platform.stepfun.com ) |
2026-03-18 15:02:47 +08:00
| `ovms` | LLM (local, OpenVINO Model Server) | [docs.openvino.ai ](https://docs.openvino.ai/2026/model-server/ovms_docs_llm_quickstart.html ) |
2026-02-08 07:29:31 +00:00
| `vllm` | LLM (local, any OpenAI-compatible server) | — |
2026-02-16 11:43:36 +00:00
| `openai_codex` | LLM (Codex, OAuth) | `nanobot provider login openai-codex` |
2026-02-18 03:09:09 +00:00
| `github_copilot` | LLM (GitHub Copilot, OAuth) | `nanobot provider login github-copilot` |
2026-04-02 22:16:25 +08:00
| `qianfan` | LLM (Baidu Qianfan) | [cloud.baidu.com ](https://cloud.baidu.com/doc/qianfan/s/Hmh4suq26 ) |
2026-02-03 07:17:47 +00:00
2026-02-01 07:36:42 +00:00
<details>
2026-02-16 11:43:36 +00:00
<summary><b>OpenAI Codex (OAuth)</b></summary>
2026-02-01 07:36:42 +00:00
2026-02-16 11:43:36 +00:00
Codex uses OAuth instead of API keys. Requires a ChatGPT Plus or Pro account.
2026-03-20 19:19:02 +00:00
No `providers.openaiCodex` block is needed in `config.json` ; `nanobot provider login` stores the OAuth session outside config.
2026-02-16 11:43:36 +00:00
**1. Login:**
```bash
nanobot provider login openai-codex
```
**2. Set model** (merge into `~/.nanobot/config.json` ):
2026-02-01 07:36:42 +00:00
```json
{
"agents" : {
"defaults" : {
2026-02-16 11:43:36 +00:00
"model" : "openai-codex/gpt-5.1-codex"
2026-02-01 07:36:42 +00:00
}
2026-02-16 11:43:36 +00:00
}
}
```
**3. Chat:**
```bash
nanobot agent -m "Hello!"
2026-03-06 20:32:10 +00:00
# Target a specific workspace/config locally
2026-03-08 03:24:15 +00:00
nanobot agent -c ~/.nanobot-telegram/config.json -m "Hello!"
# One-off workspace override on top of that config
nanobot agent -c ~/.nanobot-telegram/config.json -w /tmp/nanobot-telegram-test -m "Hello!"
2026-02-16 11:43:36 +00:00
```
> Docker users: use `docker run -it` for interactive OAuth login.
</details>
2026-02-08 07:29:31 +00:00
2026-03-20 16:10:37 +00:00
<details>
2026-03-20 19:19:02 +00:00
<summary><b>GitHub Copilot (OAuth)</b></summary>
2026-03-20 16:10:37 +00:00
2026-03-20 19:19:02 +00:00
GitHub Copilot uses OAuth instead of API keys. Requires a [GitHub account with a plan ](https://github.com/features/copilot/plans ) configured.
No `providers.githubCopilot` block is needed in `config.json` ; `nanobot provider login` stores the OAuth session outside config.
2026-03-20 16:10:37 +00:00
**1. Login:**
```bash
2026-03-20 19:19:02 +00:00
nanobot provider login github-copilot
2026-03-20 16:10:37 +00:00
```
**2. Set model** (merge into `~/.nanobot/config.json` ):
```json
{
"agents" : {
"defaults" : {
"model" : "github-copilot/gpt-4.1"
}
}
}
```
**3. Chat:**
```bash
nanobot agent -m "Hello!"
# Target a specific workspace/config locally
nanobot agent -c ~/.nanobot-telegram/config.json -m "Hello!"
# One-off workspace override on top of that config
nanobot agent -c ~/.nanobot-telegram/config.json -w /tmp/nanobot-telegram-test -m "Hello!"
```
> Docker users: use `docker run -it` for interactive OAuth login.
</details>
2026-02-15 06:02:45 +00:00
<details>
<summary><b>Custom Provider (Any OpenAI-compatible API)</b></summary>
2026-03-24 17:53:35 +00:00
Connects directly to any OpenAI-compatible endpoint — LM Studio, llama.cpp, Together AI, Fireworks, Azure OpenAI, or any self-hosted server. Model name is passed as-is.
2026-02-15 06:02:45 +00:00
```json
{
2026-02-01 07:36:42 +00:00
"providers" : {
2026-02-15 06:02:45 +00:00
"custom" : {
"apiKey" : "your-api-key" ,
"apiBase" : "https://api.your-provider.com/v1"
2026-02-01 07:36:42 +00:00
}
},
2026-02-15 06:02:45 +00:00
"agents" : {
"defaults" : {
"model" : "your-model-name"
}
}
}
```
2026-02-18 02:39:15 +00:00
> For local servers that don't require a key, set `apiKey` to any non-empty string (e.g. `"no-key"`).
2026-02-15 06:02:45 +00:00
</details>
2026-03-11 08:42:12 +00:00
<details>
<summary><b>Ollama (local)</b></summary>
Run a local model with Ollama, then add to config:
**1. Start Ollama** (example):
```bash
ollama run llama3.2
```
**2. Add to config** (partial — merge into `~/.nanobot/config.json` ):
```json
{
"providers" : {
"ollama" : {
"apiBase" : "http://localhost:11434"
2026-02-01 07:36:42 +00:00
}
},
2026-03-11 08:42:12 +00:00
"agents" : {
"defaults" : {
"provider" : "ollama" ,
"model" : "llama3.2"
}
}
}
```
> `provider: "auto"` also works when `providers.ollama.apiBase` is configured, but setting `"provider": "ollama"` is the clearest option.
</details>
2026-03-18 15:02:47 +08:00
<details>
<summary><b>OpenVINO Model Server (local / OpenAI-compatible)</b></summary>
Run LLMs locally on Intel GPUs using [OpenVINO Model Server ](https://docs.openvino.ai/2026/model-server/ovms_docs_llm_quickstart.html ). OVMS exposes an OpenAI-compatible API at `/v3` .
> Requires Docker and an Intel GPU with driver access (`/dev/dri`).
**1. Pull the model** (example):
```bash
mkdir -p ov/models && cd ov
docker run -d \
--rm \
--user $( id -u) :$( id -g) \
-v $( pwd ) /models:/models \
openvino/model_server:latest-gpu \
--pull \
--model_name openai/gpt-oss-20b \
--model_repository_path /models \
--source_model OpenVINO/gpt-oss-20b-int4-ov \
--task text_generation \
--tool_parser gptoss \
--reasoning_parser gptoss \
--enable_prefix_caching true \
--target_device GPU
```
> This downloads the model weights. Wait for the container to finish before proceeding.
**2. Start the server** (example):
```bash
docker run -d \
--rm \
--name ovms \
--user $( id -u) :$( id -g) \
-p 8000:8000 \
-v $( pwd ) /models:/models \
--device /dev/dri \
--group-add= $( stat -c "%g" /dev/dri/render* | head -n 1) \
openvino/model_server:latest-gpu \
--rest_port 8000 \
--model_name openai/gpt-oss-20b \
--model_repository_path /models \
--source_model OpenVINO/gpt-oss-20b-int4-ov \
--task text_generation \
--tool_parser gptoss \
--reasoning_parser gptoss \
--enable_prefix_caching true \
--target_device GPU
```
**3. Add to config** (partial — merge into `~/.nanobot/config.json` ):
```json
{
"providers" : {
"ovms" : {
"apiBase" : "http://localhost:8000/v3"
}
},
"agents" : {
"defaults" : {
"provider" : "ovms" ,
"model" : "openai/gpt-oss-20b"
}
}
}
```
> OVMS is a local server — no API key required. Supports tool calling (`--tool_parser gptoss`), reasoning (`--reasoning_parser gptoss`), and streaming.
> See the [official OVMS docs](https://docs.openvino.ai/2026/model-server/ovms_docs_llm_quickstart.html) for more details.
</details>
2026-02-15 16:41:27 +00:00
<details>
<summary><b>vLLM (local / OpenAI-compatible)</b></summary>
Run your own model with vLLM or any OpenAI-compatible server, then add to config:
**1. Start the server** (example):
```bash
vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000
```
**2. Add to config** (partial — merge into `~/.nanobot/config.json` ):
*Provider (key can be any non-empty string for local):*
```json
{
"providers" : {
"vllm" : {
"apiKey" : "dummy" ,
"apiBase" : "http://localhost:8000/v1"
}
}
}
```
*Model:*
```json
{
"agents" : {
"defaults" : {
"model" : "meta-llama/Llama-3.1-8B-Instruct"
2026-02-01 07:36:42 +00:00
}
}
}
```
</details>
2026-02-08 07:29:31 +00:00
<details>
<summary><b>Adding a New Provider (Developer Guide)</b></summary>
nanobot uses a **Provider Registry** (`nanobot/providers/registry.py` ) as the single source of truth.
Adding a new provider only takes **2 steps** — no if-elif chains to touch.
**Step 1.** Add a `ProviderSpec` entry to `PROVIDERS` in `nanobot/providers/registry.py` :
```python
ProviderSpec (
name = "myprovider" , # config field name
keywords = ( "myprovider" , "mymodel" ), # model-name keywords for auto-matching
2026-03-24 17:53:35 +00:00
env_key = "MYPROVIDER_API_KEY" , # env var name
2026-02-08 07:29:31 +00:00
display_name = "My Provider" , # shown in `nanobot status`
2026-03-24 17:53:35 +00:00
default_api_base = "https://api.myprovider.com/v1" , # OpenAI-compatible endpoint
2026-02-08 07:29:31 +00:00
)
```
**Step 2.** Add a field to `ProvidersConfig` in `nanobot/config/schema.py` :
```python
class ProvidersConfig ( BaseModel ):
...
myprovider : ProviderConfig = ProviderConfig ()
```
2026-03-24 17:53:35 +00:00
That's it! Environment variables, model routing, config matching, and `nanobot status` display will all work automatically.
2026-02-08 07:29:31 +00:00
**Common `ProviderSpec` options:**
| Field | Description | Example |
|-------|-------------|---------|
2026-03-24 17:53:35 +00:00
| `default_api_base` | OpenAI-compatible base URL | `"https://api.deepseek.com"` |
2026-02-08 07:29:31 +00:00
| `env_extras` | Additional env vars to set | `(("ZHIPUAI_API_KEY", "{api_key}"),)` |
| `model_overrides` | Per-model parameter overrides | `(("kimi-k2.5", {"temperature": 1.0}),)` |
| `is_gateway` | Can route any model (like OpenRouter) | `True` |
| `detect_by_key_prefix` | Detect gateway by API key prefix | `"sk-or-"` |
| `detect_by_base_keyword` | Detect gateway by API base URL | `"openrouter"` |
2026-03-24 17:53:35 +00:00
| `strip_model_prefix` | Strip provider prefix before sending to gateway | `True` (for AiHubMix) |
2026-03-27 13:10:04 +03:00
| `supports_max_completion_tokens` | Use `max_completion_tokens` instead of `max_tokens` ; required for providers that reject both being set simultaneously (e.g. VolcEngine) | `True` |
2026-02-08 07:29:31 +00:00
</details>
2026-02-03 07:17:47 +00:00
2026-03-25 18:37:32 +08:00
### Channel Settings
Global settings that apply to all channels. Configure under the `channels` section in `~/.nanobot/config.json` :
```json
{
"channels" : {
"sendProgress" : true ,
"sendToolHints" : false ,
"sendMaxRetries" : 3 ,
"telegram" : { ... }
}
}
```
| Setting | Default | Description |
|---------|---------|-------------|
| `sendProgress` | `true` | Stream agent's text progress to the channel |
| `sendToolHints` | `false` | Stream tool-call hints (e.g. `read_file("…")` ) |
2026-03-25 14:34:37 +00:00
| `sendMaxRetries` | `3` | Max delivery attempts per outbound message, including the initial send (0-10 configured, minimum 1 actual attempt) |
2026-03-25 18:37:32 +08:00
#### Retry Behavior
2026-04-03 18:57:44 +00:00
Retry is intentionally simple.
2026-03-25 18:37:32 +08:00
2026-04-03 18:57:44 +00:00
When a channel `send()` raises, nanobot retries at the channel-manager layer. By default, `channels.sendMaxRetries` is `3` , and that count includes the initial send.
- **Attempt 1**: Send immediately
- **Attempt 2**: Retry after `1s`
- **Attempt 3**: Retry after `2s`
- **Higher retry budgets**: Backoff continues as `1s` , `2s` , `4s` , then stays capped at `4s`
- **Transient failures**: Network hiccups and temporary API limits often recover on the next attempt
- **Permanent failures**: Invalid tokens, revoked access, or banned channels will exhaust the retry budget and fail cleanly
2026-03-25 18:37:32 +08:00
> [!NOTE]
2026-04-03 18:57:44 +00:00
> This design is deliberate: channel implementations should raise on delivery failure, and the channel manager owns the shared retry policy.
>
> Some channels may still apply small API-specific retries internally. For example, Telegram separately retries timeout and flood-control errors before surfacing a final failure to the manager.
>
> If a channel is completely unreachable, nanobot cannot notify the user through that same channel. Watch logs for `Failed to send to {channel} after N attempts` to spot persistent delivery failures.
2026-02-03 07:17:47 +00:00
2026-03-13 05:44:16 +00:00
### Web Search
2026-03-13 05:54:51 +00:00
> [!TIP]
> Use `proxy` in `tools.web` to route all web requests (search + fetch) through a proxy:
> ```json
> { "tools": { "web": { "proxy": "http://127.0.0.1:7890" } } }
> ```
2026-03-13 05:44:16 +00:00
nanobot supports multiple web search providers. Configure in `~/.nanobot/config.json` under `tools.web.search` .
2026-04-03 18:44:46 +00:00
By default, web tools are enabled and web search uses `duckduckgo` , so search works out of the box without an API key.
If you want to disable all built-in web tools entirely, set `tools.web.enable` to `false` . This removes both `web_search` and `web_fetch` from the tool list sent to the LLM.
2026-04-04 11:35:09 +00:00
If you need to allow trusted private ranges such as Tailscale / CGNAT addresses, you can explicitly exempt them from SSRF blocking with `tools.ssrfWhitelist` :
```json
{
"tools" : {
"ssrfWhitelist" : [ "100.64.0.0/10" ]
}
}
```
2026-03-13 05:44:16 +00:00
| Provider | Config fields | Env var fallback | Free |
|----------|--------------|------------------|------|
2026-04-03 18:44:46 +00:00
| `brave` | `apiKey` | `BRAVE_API_KEY` | No |
2026-03-13 05:44:16 +00:00
| `tavily` | `apiKey` | `TAVILY_API_KEY` | No |
| `jina` | `apiKey` | `JINA_API_KEY` | Free tier (10M tokens) |
| `searxng` | `baseUrl` | `SEARXNG_BASE_URL` | Yes (self-hosted) |
2026-04-03 18:44:46 +00:00
| `duckduckgo` (default) | — | — | Yes |
2026-03-13 05:44:16 +00:00
2026-04-03 18:44:46 +00:00
**Disable all built-in web tools:**
```json
{
"tools" : {
"web" : {
"enable" : false
}
}
}
```
2026-03-13 05:44:16 +00:00
2026-04-03 18:44:46 +00:00
**Brave:**
2026-03-13 05:44:16 +00:00
```json
{
"tools" : {
"web" : {
"search" : {
"provider" : "brave" ,
"apiKey" : "BSA..."
}
}
}
}
```
**Tavily:**
```json
{
"tools" : {
"web" : {
"search" : {
"provider" : "tavily" ,
"apiKey" : "tvly-..."
}
}
}
}
```
**Jina** (free tier with 10M tokens):
```json
{
"tools" : {
"web" : {
"search" : {
"provider" : "jina" ,
"apiKey" : "jina_..."
}
}
}
}
```
**SearXNG** (self-hosted, no API key needed):
```json
{
"tools" : {
"web" : {
"search" : {
"provider" : "searxng" ,
"baseUrl" : "https://searx.example"
}
}
}
}
```
**DuckDuckGo** (zero config):
```json
{
"tools" : {
"web" : {
"search" : {
"provider" : "duckduckgo"
}
}
}
}
```
| Option | Type | Default | Description |
|--------|------|---------|-------------|
2026-04-03 18:44:46 +00:00
| `enable` | boolean | `true` | Enable or disable all built-in web tools (`web_search` + `web_fetch` ) |
| `proxy` | string or null | `null` | Proxy for all web requests, for example `http://127.0.0.1:7890` |
#### `tools.web.search`
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `provider` | string | `"duckduckgo"` | Search backend: `brave` , `tavily` , `jina` , `searxng` , `duckduckgo` |
2026-03-13 05:44:16 +00:00
| `apiKey` | string | `""` | API key for Brave or Tavily |
| `baseUrl` | string | `""` | Base URL for SearXNG |
| `maxResults` | integer | `5` | Results per search (1– 10) |
2026-02-15 07:00:27 +00:00
### MCP (Model Context Protocol)
> [!TIP]
> The config format is compatible with Claude Desktop / Cursor. You can copy MCP server configs directly from any MCP server's README.
nanobot supports [MCP ](https://modelcontextprotocol.io/ ) — connect external tool servers and use them as native agent tools.
Add MCP servers to your `config.json` :
```json
{
"tools" : {
"mcpServers" : {
"filesystem" : {
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/path/to/dir" ]
2026-02-20 08:31:52 +08:00
},
2026-02-20 08:49:49 +00:00
"my-remote-mcp" : {
"url" : "https://example.com/mcp/" ,
"headers" : {
"Authorization" : "Bearer xxxxx"
}
2026-02-15 07:00:27 +00:00
}
}
}
}
```
Two transport modes are supported:
| Mode | Config | Example |
|------|--------|---------|
| **Stdio** | `command` + `args` | Local process via `npx` / `uvx` |
2026-02-20 08:49:49 +00:00
| **HTTP** | `url` + `headers` (optional) | Remote endpoint (`https://mcp.example.com/sse` ) |
2026-02-15 07:00:27 +00:00
2026-02-22 18:04:13 +00:00
Use `toolTimeout` to override the default 30s per-call timeout for slow servers:
```json
{
"tools" : {
"mcpServers" : {
"my-slow-server" : {
"url" : "https://example.com/mcp/" ,
"toolTimeout" : 120
}
}
}
}
```
2026-02-15 07:00:27 +00:00
2026-03-14 10:26:15 +00:00
Use `enabledTools` to register only a subset of tools from an MCP server:
```json
{
"tools" : {
"mcpServers" : {
"filesystem" : {
"command" : "npx" ,
"args" : [ "-y" , "@modelcontextprotocol/server-filesystem" , "/path/to/dir" ],
"enabledTools" : [ "read_file" , "mcp_filesystem_write_file" ]
}
}
}
}
```
`enabledTools` accepts either the raw MCP tool name (for example `read_file` ) or the wrapped nanobot tool name (for example `mcp_filesystem_write_file` ).
- Omit `enabledTools` , or set it to `["*"]` , to register all tools.
- Set `enabledTools` to `[]` to register no tools from that server.
- Set `enabledTools` to a non-empty list of names to register only that subset.
2026-02-15 07:00:27 +00:00
MCP tools are automatically discovered and registered on startup. The LLM can use them alongside built-in tools — no extra configuration needed.
2026-02-06 09:34:11 +00:00
### Security
2026-02-01 07:36:42 +00:00
2026-02-15 16:41:27 +00:00
> [!TIP]
2026-04-05 19:28:46 +00:00
> For production deployments, set `"restrictToWorkspace": true` and `"tools.exec.sandbox": "bwrap"` in your config to sandbox the agent.
2026-03-08 16:57:28 +00:00
> In `v0.1.4.post3` and earlier, an empty `allowFrom` allowed all senders. Since `v0.1.4.post4`, empty `allowFrom` denies all access by default. To allow all senders, set `"allowFrom": ["*"]`.
2026-02-06 09:34:11 +00:00
| Option | Default | Description |
|--------|---------|-------------|
| `tools.restrictToWorkspace` | `false` | When `true` , restricts **all** agent tools (shell, file read/write/edit, list) to the workspace directory. Prevents path traversal and out-of-scope access. |
2026-04-05 19:28:46 +00:00
| `tools.exec.sandbox` | `""` | Sandbox backend for shell commands. Set to `"bwrap"` to wrap exec calls in a [bubblewrap ](https://github.com/containers/bubblewrap ) sandbox — the process can only see the workspace (read-write) and media directory (read-only); config files and API keys are hidden. Automatically enables `restrictToWorkspace` for file tools. **Linux only** — requires `bwrap` installed (`apt install bubblewrap` ; pre-installed in the Docker image). Not available on macOS or Windows (bwrap depends on Linux kernel namespaces). |
2026-03-20 17:24:40 +00:00
| `tools.exec.enable` | `true` | When `false` , the shell `exec` tool is not registered at all. Use this to completely disable shell command execution. |
2026-02-25 15:57:50 +00:00
| `tools.exec.pathAppend` | `""` | Extra directories to append to `PATH` when running shell commands (e.g. `/usr/sbin` for `ufw` ). |
2026-03-08 16:57:28 +00:00
| `channels.*.allowFrom` | `[]` (deny all) | Whitelist of user IDs. Empty denies all; use `["*"]` to allow everyone. |
2026-02-01 07:36:42 +00:00
2026-04-05 19:28:46 +00:00
**Docker security** : The official Docker image runs as a non-root user (`nanobot` , UID 1000) with bubblewrap pre-installed. When using `docker-compose.yml` , the container drops all Linux capabilities except `SYS_ADMIN` (required for bwrap's namespace isolation).
2026-02-01 07:36:42 +00:00
2026-03-25 10:15:47 +00:00
### Timezone
Time is context. Context should be precise.
By default, nanobot uses `UTC` for runtime time context. If you want the agent to think in your local time, set `agents.defaults.timezone` to a valid [IANA timezone name ](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones ):
```json
{
"agents" : {
"defaults" : {
"timezone" : "Asia/Shanghai"
}
}
}
```
2026-03-25 10:24:26 +00:00
This affects runtime time strings shown to the model, such as runtime context and heartbeat prompts. It also becomes the default timezone for cron schedules when a cron expression omits `tz` , and for one-shot `at` times when the ISO datetime has no explicit offset.
2026-03-25 10:15:47 +00:00
Common examples: `UTC` , `America/New_York` , `America/Los_Angeles` , `Europe/London` , `Europe/Berlin` , `Asia/Tokyo` , `Asia/Shanghai` , `Asia/Singapore` , `Australia/Sydney` .
> Need another timezone? Browse the full [IANA Time Zone Database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
2026-03-08 03:03:25 +00:00
## 🧩 Multiple Instances
2026-03-02 22:01:02 +08:00
2026-03-17 05:58:13 +00:00
Run multiple nanobot instances simultaneously with separate configs and runtime data. Use `--config` as the main entrypoint. Optionally pass `--workspace` during `onboard` when you want to initialize or update the saved workspace for a specific instance.
2026-03-06 17:57:21 +08:00
### Quick Start
2026-03-02 22:01:02 +08:00
2026-03-17 05:58:13 +00:00
If you want each instance to have its own dedicated workspace from the start, pass both `--config` and `--workspace` during onboarding.
2026-03-09 16:17:01 +08:00
**Initialize instances:**
```bash
2026-03-17 05:58:13 +00:00
# Create separate instance configs and workspaces
nanobot onboard --config ~/.nanobot-telegram/config.json --workspace ~/.nanobot-telegram/workspace
nanobot onboard --config ~/.nanobot-discord/config.json --workspace ~/.nanobot-discord/workspace
nanobot onboard --config ~/.nanobot-feishu/config.json --workspace ~/.nanobot-feishu/workspace
2026-03-09 16:17:01 +08:00
```
**Configure each instance:**
2026-03-17 05:58:13 +00:00
Edit `~/.nanobot-telegram/config.json` , `~/.nanobot-discord/config.json` , etc. with different channel settings. The workspace you passed during `onboard` is saved into each config as that instance's default workspace.
2026-03-09 16:17:01 +08:00
**Run instances:**
2026-03-02 22:01:02 +08:00
```bash
# Instance A - Telegram bot
2026-03-06 17:57:21 +08:00
nanobot gateway --config ~/.nanobot-telegram/config.json
2026-03-02 22:01:02 +08:00
2026-03-06 17:57:21 +08:00
# Instance B - Discord bot
nanobot gateway --config ~/.nanobot-discord/config.json
2026-03-02 22:01:02 +08:00
2026-03-06 17:57:21 +08:00
# Instance C - Feishu bot with custom port
nanobot gateway --config ~/.nanobot-feishu/config.json --port 18792
2026-03-02 22:01:02 +08:00
```
2026-03-08 02:58:25 +00:00
### Path Resolution
2026-03-02 22:01:02 +08:00
2026-03-08 02:58:25 +00:00
When using `--config` , nanobot derives its runtime data directory from the config file location. The workspace still comes from `agents.defaults.workspace` unless you override it with `--workspace` .
2026-03-02 22:01:02 +08:00
2026-03-06 20:32:10 +00:00
To open a CLI session against one of these instances locally:
```bash
2026-03-08 03:24:15 +00:00
nanobot agent -c ~/.nanobot-telegram/config.json -m "Hello from Telegram instance"
nanobot agent -c ~/.nanobot-discord/config.json -m "Hello from Discord instance"
# Optional one-off workspace override
nanobot agent -c ~/.nanobot-telegram/config.json -w /tmp/nanobot-telegram-test
2026-03-06 20:32:10 +00:00
```
> `nanobot agent` starts a local CLI agent using the selected workspace/config. It does not attach to or proxy through an already running `nanobot gateway` process.
2026-03-08 03:24:15 +00:00
2026-03-08 02:58:25 +00:00
| Component | Resolved From | Example |
|-----------|---------------|---------|
| **Config** | `--config` path | `~/.nanobot-A/config.json` |
| **Workspace** | `--workspace` or config | `~/.nanobot-A/workspace/` |
| **Cron Jobs** | config directory | `~/.nanobot-A/cron/` |
| **Media / runtime state** | config directory | `~/.nanobot-A/media/` |
2026-03-06 20:32:10 +00:00
2026-03-08 02:58:25 +00:00
### How It Works
2026-03-02 22:01:02 +08:00
2026-03-08 02:58:25 +00:00
- `--config` selects which config file to load
- By default, the workspace comes from `agents.defaults.workspace` in that config
- If you pass `--workspace` , it overrides the workspace from the config file
2026-03-06 17:57:21 +08:00
2026-03-08 02:58:25 +00:00
### Minimal Setup
2026-03-06 17:57:21 +08:00
2026-03-08 02:58:25 +00:00
1. Copy your base config into a new instance directory.
2. Set a different `agents.defaults.workspace` for that instance.
3. Start the instance with `--config` .
2026-03-06 17:57:21 +08:00
2026-03-08 02:58:25 +00:00
Example config:
2026-03-06 17:57:21 +08:00
```json
{
"agents" : {
"defaults" : {
"workspace" : "~/.nanobot-telegram/workspace" ,
"model" : "anthropic/claude-sonnet-4-6"
}
},
"channels" : {
"telegram" : {
"enabled" : true ,
"token" : "YOUR_TELEGRAM_BOT_TOKEN"
}
},
"gateway" : {
"port" : 18790
}
}
```
2026-03-08 02:58:25 +00:00
Start separate instances:
2026-03-06 17:57:21 +08:00
```bash
nanobot gateway --config ~/.nanobot-telegram/config.json
nanobot gateway --config ~/.nanobot-discord/config.json
```
2026-03-08 02:58:25 +00:00
Override workspace for one-off runs when needed:
2026-03-06 17:57:21 +08:00
```bash
2026-03-08 02:58:25 +00:00
nanobot gateway --config ~/.nanobot-telegram/config.json --workspace /tmp/nanobot-telegram-test
2026-03-06 17:57:21 +08:00
```
2026-03-08 02:58:25 +00:00
### Common Use Cases
2026-03-06 17:57:21 +08:00
2026-03-08 02:58:25 +00:00
- Run separate bots for Telegram, Discord, Feishu, and other platforms
- Keep testing and production instances isolated
- Use different models or providers for different teams
- Serve multiple tenants with separate configs and runtime data
2026-03-06 17:57:21 +08:00
### Notes
2026-03-08 02:58:25 +00:00
- Each instance must use a different port if they run at the same time
- Use a different workspace per instance if you want isolated memory, sessions, and skills
- `--workspace` overrides the workspace defined in the config file
- Cron jobs and runtime media/state are derived from the config directory
2026-03-02 22:01:02 +08:00
2026-04-04 09:34:37 +00:00
## 🧠 Memory
nanobot uses a layered memory system designed to stay light in the moment and durable over
time.
- `memory/history.jsonl` stores append-only summarized history
- `SOUL.md` , `USER.md` , and `memory/MEMORY.md` store long-term knowledge managed by Dream
- `Dream` runs on a schedule and can also be triggered manually
- memory changes can be inspected and restored with built-in commands
If you want the full design, see [docs/MEMORY.md ](docs/MEMORY.md ).
2026-03-08 03:03:25 +00:00
## 💻 CLI Reference
2026-02-01 07:36:42 +00:00
| Command | Description |
|---------|-------------|
2026-03-09 16:17:01 +08:00
| `nanobot onboard` | Initialize config & workspace at `~/.nanobot/` |
2026-03-20 07:53:18 +00:00
| `nanobot onboard --wizard` | Launch the interactive onboarding wizard |
2026-03-17 05:58:13 +00:00
| `nanobot onboard -c <config> -w <workspace>` | Initialize or refresh a specific instance config and workspace |
2026-02-01 07:36:42 +00:00
| `nanobot agent -m "..."` | Chat with the agent |
2026-03-06 20:32:10 +00:00
| `nanobot agent -w <workspace>` | Chat against a specific workspace |
| `nanobot agent -w <workspace> -c <config>` | Chat against a specific workspace/config |
2026-02-01 07:36:42 +00:00
| `nanobot agent` | Interactive chat mode |
2026-02-08 21:51:13 +00:00
| `nanobot agent --no-markdown` | Show plain-text replies |
| `nanobot agent --logs` | Show runtime logs during chat |
2026-03-30 14:43:22 +00:00
| `nanobot serve` | Start the OpenAI-compatible API |
2026-02-01 07:36:42 +00:00
| `nanobot gateway` | Start the gateway |
| `nanobot status` | Show status |
2026-02-13 18:37:21 +08:00
| `nanobot provider login openai-codex` | OAuth login for providers |
2026-03-23 17:00:19 +00:00
| `nanobot channels login <channel>` | Authenticate a channel interactively |
2026-02-01 07:36:42 +00:00
| `nanobot channels status` | Show channel status |
2026-02-08 21:51:13 +00:00
Interactive mode exits: `exit` , `quit` , `/exit` , `/quit` , `:q` , or `Ctrl+D` .
2026-04-04 09:34:37 +00:00
## 💬 In-Chat Commands
These commands work inside chat channels and interactive agent sessions:
| Command | Description |
|---------|-------------|
| `/new` | Start a new conversation |
| `/stop` | Stop the current task |
| `/restart` | Restart the bot |
| `/status` | Show bot status |
| `/dream` | Run Dream memory consolidation now |
| `/dream-log` | Show the latest Dream memory change |
| `/dream-log <sha>` | Show a specific Dream memory change |
| `/dream-restore` | List recent Dream memory versions |
| `/dream-restore <sha>` | Restore memory to the state before a specific change |
| `/help` | Show available in-chat commands |
2026-02-01 07:36:42 +00:00
<details>
2026-02-23 08:08:01 +00:00
<summary><b>Heartbeat (Periodic Tasks)</b></summary>
2026-02-01 07:36:42 +00:00
2026-02-23 08:08:01 +00:00
The gateway wakes up every 30 minutes and checks `HEARTBEAT.md` in your workspace (`~/.nanobot/workspace/HEARTBEAT.md` ). If the file has tasks, the agent executes them and delivers results to your most recently active chat channel.
2026-02-01 07:36:42 +00:00
2026-02-23 08:08:01 +00:00
**Setup:** edit `~/.nanobot/workspace/HEARTBEAT.md` (created automatically by `nanobot onboard` ):
2026-02-01 07:36:42 +00:00
2026-02-23 08:08:01 +00:00
```markdown
## Periodic Tasks
- [ ] Check weather forecast and send a summary
- [ ] Scan inbox for urgent emails
2026-02-01 07:36:42 +00:00
```
2026-02-23 08:08:01 +00:00
The agent can also manage this file itself — ask it to "add a periodic task" and it will update `HEARTBEAT.md` for you.
> **Note:** The gateway must be running (`nanobot gateway`) and you must have chatted with the bot at least once so it knows which channel to deliver to.
2026-02-01 07:36:42 +00:00
</details>
2026-03-30 18:46:11 +00:00
## 🐍 Python SDK
Use nanobot as a library — no CLI, no gateway, just Python:
```python
from nanobot import Nanobot
bot = Nanobot . from_config ()
result = await bot . run ( "Summarize the README" )
print ( result . content )
```
Each call carries a `session_key` for conversation isolation — different keys get independent history:
```python
await bot . run ( "hi" , session_key = "user-alice" )
await bot . run ( "hi" , session_key = "task-42" )
```
Add lifecycle hooks to observe or customize the agent:
```python
from nanobot.agent import AgentHook , AgentHookContext
class AuditHook ( AgentHook ):
async def before_execute_tools ( self , ctx : AgentHookContext ) -> None :
for tc in ctx . tool_calls :
print ( f "[tool] { tc . name } " )
result = await bot . run ( "Hello" , hooks = [ AuditHook ()])
```
See [docs/PYTHON_SDK.md ](docs/PYTHON_SDK.md ) for the full SDK reference.
2026-03-30 14:43:22 +00:00
## 🔌 OpenAI-Compatible API
nanobot can expose a minimal OpenAI-compatible endpoint for local integrations:
```bash
pip install "nanobot-ai[api]"
nanobot serve
```
2026-03-30 18:46:11 +00:00
By default, the API binds to `127.0.0.1:8900` . You can change this in `config.json` .
2026-03-30 14:43:22 +00:00
### Behavior
2026-03-30 18:46:11 +00:00
- Session isolation: pass `"session_id"` in the request body to isolate conversations; omit for a shared default session (`api:default` )
2026-03-30 14:43:22 +00:00
- Single-message input: each request must contain exactly one `user` message
- Fixed model: omit `model` , or pass the same model shown by `/v1/models`
- No streaming: `stream=true` is not supported
### Endpoints
- `GET /health`
- `GET /v1/models`
- `POST /v1/chat/completions`
### curl
```bash
curl http://127.0.0.1:8900/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
2026-03-30 18:46:11 +00:00
"messages": [{"role": "user", "content": "hi"}],
"session_id": "my-session"
2026-03-30 14:43:22 +00:00
}'
```
### Python (`requests`)
```python
import requests
resp = requests . post (
"http://127.0.0.1:8900/v1/chat/completions" ,
json = {
2026-03-30 18:46:11 +00:00
"messages" : [{ "role" : "user" , "content" : "hi" }],
"session_id" : "my-session" , # optional: isolate conversation
2026-03-30 14:43:22 +00:00
},
timeout = 120 ,
)
resp . raise_for_status ()
print ( resp . json ()[ "choices" ][ 0 ][ "message" ][ "content" ])
```
### Python (`openai`)
```python
from openai import OpenAI
client = OpenAI (
base_url = "http://127.0.0.1:8900/v1" ,
api_key = "dummy" ,
)
resp = client . chat . completions . create (
model = "MiniMax-M2.7" ,
messages = [{ "role" : "user" , "content" : "hi" }],
2026-03-30 18:46:11 +00:00
extra_body = { "session_id" : "my-session" }, # optional: isolate conversation
2026-03-30 14:43:22 +00:00
)
print ( resp . choices [ 0 ] . message . content )
```
2026-02-03 07:17:47 +00:00
## 🐳 Docker
2026-02-03 07:21:46 +00:00
> [!TIP]
> The `-v ~/.nanobot:/root/.nanobot` flag mounts your local config directory into the container, so your config and workspace persist across container restarts.
2026-02-17 17:55:48 +00:00
### Docker Compose
2026-02-17 18:50:03 +05:30
```bash
2026-02-17 17:55:48 +00:00
docker compose run --rm nanobot-cli onboard # first-time setup
vim ~/.nanobot/config.json # add API keys
docker compose up -d nanobot-gateway # start gateway
2026-02-17 18:50:03 +05:30
```
2026-02-17 17:55:48 +00:00
```bash
docker compose run --rm nanobot-cli agent -m "Hello!" # run CLI
docker compose logs -f nanobot-gateway # view logs
docker compose down # stop
```
2026-02-17 18:50:03 +05:30
2026-02-17 17:55:48 +00:00
### Docker
2026-02-03 07:17:47 +00:00
```bash
# Build the image
docker build -t nanobot .
# Initialize config (first time only)
docker run -v ~/.nanobot:/root/.nanobot --rm nanobot onboard
# Edit config on host to add API keys
vim ~/.nanobot/config.json
2026-02-09 08:50:17 +00:00
# Run gateway (connects to enabled channels, e.g. Telegram/Discord/Mochat)
2026-02-03 07:17:47 +00:00
docker run -v ~/.nanobot:/root/.nanobot -p 18790:18790 nanobot gateway
# Or run a single command
docker run -v ~/.nanobot:/root/.nanobot --rm nanobot agent -m "Hello!"
docker run -v ~/.nanobot:/root/.nanobot --rm nanobot status
```
2026-02-21 20:55:54 +01:00
## 🐧 Linux Service
2026-02-22 17:51:23 +00:00
Run the gateway as a systemd user service so it starts automatically and restarts on failure.
2026-02-21 20:55:54 +01:00
2026-02-22 17:51:23 +00:00
**1. Find the nanobot binary path:**
```bash
which nanobot # e.g. /home/user/.local/bin/nanobot
```
**2. Create the service file** at `~/.config/systemd/user/nanobot-gateway.service` (replace `ExecStart` path if needed):
2026-02-21 20:55:54 +01:00
```ini
[Unit]
Description = Nanobot Gateway
After = network.target
[Service]
Type = simple
ExecStart = %h/.local/bin/nanobot gateway
Restart = always
RestartSec = 10
NoNewPrivileges = yes
ProtectSystem = strict
ReadWritePaths = %h
[Install]
WantedBy = default.target
```
2026-02-22 17:51:23 +00:00
**3. Enable and start:**
2026-02-21 20:55:54 +01:00
```bash
systemctl --user daemon-reload
systemctl --user enable --now nanobot-gateway
```
2026-02-22 17:51:23 +00:00
**Common operations:**
2026-02-21 20:55:54 +01:00
```bash
2026-02-22 17:51:23 +00:00
systemctl --user status nanobot-gateway # check status
systemctl --user restart nanobot-gateway # restart after config changes
journalctl --user -u nanobot-gateway -f # follow logs
2026-02-21 20:55:54 +01:00
```
2026-02-22 17:51:23 +00:00
If you edit the `.service` file itself, run `systemctl --user daemon-reload` before restarting.
2026-02-21 20:55:54 +01:00
2026-02-22 17:51:23 +00:00
> **Note:** User services only run while you are logged in. To keep the gateway running after logout, enable lingering:
2026-02-21 20:55:54 +01:00
>
> ```bash
> loginctl enable-linger $USER
> ```
2026-02-01 07:36:42 +00:00
## 📁 Project Structure
```
nanobot/
├── agent/ # 🧠 Core agent logic
│ ├── loop.py # Agent loop (LLM ↔ tool execution)
│ ├── context.py # Prompt builder
│ ├── memory.py # Persistent memory
│ ├── skills.py # Skills loader
2026-02-01 16:38:13 +00:00
│ ├── subagent.py # Background task execution
│ └── tools/ # Built-in tools (incl. spawn)
2026-02-01 07:36:42 +00:00
├── skills/ # 🎯 Bundled skills (github, weather, tmux...)
2026-03-13 15:26:55 +00:00
├── channels/ # 📱 Chat channel integrations (supports plugins)
2026-02-01 07:36:42 +00:00
├── bus/ # 🚌 Message routing
├── cron/ # ⏰ Scheduled tasks
2026-02-01 16:38:13 +00:00
├── heartbeat/ # 💓 Proactive wake-up
2026-02-01 07:36:42 +00:00
├── providers/ # 🤖 LLM providers (OpenRouter, etc.)
├── session/ # 💬 Conversation sessions
├── config/ # ⚙️ Configuration
└── cli/ # 🖥️ Commands
```
2026-02-02 12:52:05 +00:00
## 🤝 Contribute & Roadmap
2026-02-01 07:36:42 +00:00
2026-02-02 12:52:05 +00:00
PRs welcome! The codebase is intentionally small and readable. 🤗
2026-03-15 02:30:09 +08:00
### Branching Strategy
| Branch | Purpose |
|--------|---------|
| `main` | Stable releases — bug fixes and minor improvements |
| `nightly` | Experimental features — new features and breaking changes |
**Unsure which branch to target?** See [CONTRIBUTING.md ](./CONTRIBUTING.md ) for details.
2026-02-02 12:52:05 +00:00
**Roadmap** — Pick an item and [open a PR ](https://github.com/HKUDS/nanobot/pulls )!
2026-02-01 07:36:42 +00:00
- [ ] **Multi-modal** — See and hear (images, voice, video)
- [ ] **Long-term memory** — Never forget important context
- [ ] **Better reasoning** — Multi-step planning and reflection
2026-02-09 11:39:13 +00:00
- [ ] **More integrations** — Calendar and more
2026-02-01 07:36:42 +00:00
- [ ] **Self-improvement** — Learn from feedback and mistakes
2026-02-02 12:52:05 +00:00
### Contributors
<a href="https://github.com/HKUDS/nanobot/graphs/contributors">
2026-02-10 03:07:27 +00:00
<img src="https://contrib.rocks/image?repo=HKUDS/nanobot&max=100&columns=12&updated=20260210" alt="Contributors" />
2026-02-02 12:52:05 +00:00
</a>
2026-02-01 07:36:42 +00:00
2026-02-02 12:59:36 +08:00
## ⭐ Star History
<div align="center">
<a href="https://star-history.com/#HKUDS/nanobot &Date">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=HKUDS/nanobot&type=Date&theme=dark" />
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=HKUDS/nanobot&type=Date" />
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=HKUDS/nanobot&type=Date" style="border-radius: 15px; box-shadow: 0 0 30px rgba(0, 217, 255, 0.3);" />
</picture>
</a>
</div>
2026-02-01 23:24:09 +08:00
<p align="center">
<em> Thanks for visiting ✨ nanobot!</em><br><br>
<img src="https://visitor-badge.laobi.icu/badge?page_id=HKUDS.nanobot&style=for-the-badge&color=00d4ff" alt="Views">
</p>
2026-02-03 11:53:21 +00:00
<p align="center">
<sub>nanobot is for educational, research, and technical exchange purposes only</sub>
</p>