Directory Tree
Core Components
Agent (agent/)
The heart of nanobot. Contains the main agent loop and all tool implementations.
Key Files:
loop.py(400 lines) - Main processing loopcontext.py(200 lines) - Prompt building and context managementmemory.py(100 lines) - Persistent memory interfaceskills.py(150 lines) - Load skills from~/.nanobot/skills/subagent.py(200 lines) - Background task spawning
shell.py- Execute shell commands, supports timeouts and PATH customizationfilesystem.py- 4 tools: read, write, edit (diff-based), listweb.py- Web search (Brave) and fetch (HTTP GET)spawn.py- Create independent subagent taskscron.py- Schedule/list/delete periodic jobsmessage.py- Send messages to specific channelsmcp.py- Model Context Protocol server integration
Channels (channels/)
Chat platform integrations. Each channel is ~300-500 lines.
Design Pattern: All implement BaseChannel with start(), send(), stop().
Transport Methods:
- Long Polling: Telegram
- WebSocket: Discord, Feishu, QQ, DingTalk, Matrix, Mochat
- Socket Mode: Slack
- Bridge: WhatsApp (Node.js bridge)
- IMAP/SMTP: Email
- Access control (
allowFromlists) - Media handling (images, voice, files)
- Typing indicators (Telegram, Discord)
- Thread support (Discord, Slack)
- Markdown formatting conversion
Bus (bus/)
Decouples channels from agent logic. Simple publish/subscribe pattern.
Key Classes:
InboundMessage- User message → AgentOutboundMessage- Agent response → UserMessageBus- Routes messages between channels and agent
Providers (providers/)
Abstracts LLM API differences. Most providers use LiteLLM wrapper.
Registry Pattern:
ProviderSpectuples inregistry.pydefine all metadata- No if-elif chains needed
- Auto-detection by model name, API key prefix, or base URL
custom_provider.py- Direct OpenAI-compatible (bypasses LiteLLM)openai_codex_provider.py- OAuth-based authenticationtranscription.py- Groq Whisper for voice-to-text
Session (session/)
Conversation history storage. One session per user (or thread).
Storage: ~/.nanobot/sessions/{session_id}.json
Format: OpenAI message format
- Auto-save after each turn
/newcommand clears history- Thread-scoped sessions (Discord, Slack)
Config (config/)
Pydantic-based configuration validation.
Key Files:
schema.py- All config classes (Providers, Channels, Tools, Agents)loader.py- Load from~/.nanobot/config.json
Cron (cron/)
Scheduled task execution using cron expressions.
Storage: ~/.nanobot/workspace/cron/jobs.json
Features:
- Natural language parsing (“every day at 9am”)
- Persistent across restarts
- Agent can manage via
CronTool
Heartbeat (heartbeat/)
Proactive task execution. Gateway wakes up every 30 minutes.
How it works:
- Read
~/.nanobot/workspace/HEARTBEAT.md - If tasks found, spawn agent to execute
- Send results to most recent chat channel
CLI (cli/)
Command-line interface using click.
Commands:
nanobot onboard- Initialize workspace and confignanobot agent- Interactive chat or one-off messagenanobot gateway- Start channel gatewaynanobot status- Show configuration statusnanobot provider login- OAuth login for providersnanobot channels login- WhatsApp QR code loginnanobot channels status- Show channel status
-w, --workspace- Custom workspace directory-c, --config- Custom config file-p, --port- Gateway port-m, --message- Single message mode--logs- Show runtime logs--no-markdown- Plain text output
Skills (skills/)
Markdown files that augment the agent’s capabilities.
Bundled Skills:
github.md- GitHub operations (create PR, issue, etc.)weather.md- Weather query instructionstmux.md- Tmux session managementclawhub.md- ClawHub skill search/installmochat.md- Mochat registrationmoltbook.md- Moltbook communityclawdchat.md- ClawdChat community
~/.nanobot/skills/ on startup.
Templates (templates/)
Template files for workspace initialization.
Files:
memory/MEMORY.md- Empty memory templatememory/HEARTBEAT.md- Empty heartbeat template
~/.nanobot/workspace/ on nanobot onboard.
Utils (utils/)
Utility functions and helpers.
Current: Minimal (project prefers inline code over abstractions).
File Size Distribution
By Component (Approximate Lines)
| Component | Lines | Description |
|---|---|---|
agent/ | ~2,500 | Core agent logic + tools |
channels/ | ~3,500 | 10 channel integrations |
providers/ | ~1,500 | LLM provider abstractions |
bus/ | ~200 | Message routing |
session/ | ~150 | Session management |
config/ | ~800 | Configuration schemas |
cron/ | ~300 | Task scheduling |
heartbeat/ | ~100 | Proactive tasks |
cli/ | ~400 | CLI commands |
skills/ | ~500 | Bundled skills (markdown) |
templates/ | ~50 | Workspace templates |
utils/ | ~100 | Utilities |
| Total | ~10,000 | Complete codebase |
Workspace Directory
User data stored in~/.nanobot/:
Import Structure
Internal Imports
External Dependencies
Core:loguru- Loggingpydantic- Config validationclick- CLI frameworklitellm- LLM provider abstraction
python-telegram-bot- Telegramdiscord.py- Discordwhatsapp-bridge- WhatsAppfeishu-api- Feishuslack-sdk- Slackmatrix-nio- Matrixbotpy- QQdingtalk-stream- DingTalkpython-socketio- Mochat
aiohttp- HTTP client (web_fetch)beautifulsoup4- HTML parsingcroniter- Cron expression parsing
groq- Voice transcriptionbrave-search- Web search
Code Style
Principles
- Explicit over implicit
- Simple over clever
- Readable over compact
- Flat over nested
Example
Good ✅:Docstrings
Use simple docstrings for public APIs:Error Handling
Log and continue (don’t crash):Design Patterns
1. Registry Pattern
Used in providers and tools:2. Message Bus Pattern
Decouples channels from agent logic:3. Strategy Pattern
Tools implement common interface:4. Template Method Pattern
Channels implement base lifecycle:Testing Approach
Current State
Manual testing focused:- CLI testing:
nanobot agent -m "..." - Gateway testing: Real channel integration
- Multi-provider testing: Try different LLMs
- Tool testing: Execute each tool manually
Future Improvements
- Unit tests for core logic (agent loop, tools)
- Integration tests for channels
- Mock LLM responses for deterministic testing
- CI/CD pipeline with automated tests
Performance Characteristics
Startup Time
- CLI mode: Less than 1 second
- Gateway mode: 2-5 seconds (channel connections)
Memory Usage
- Base: ~50MB (Python runtime)
- Per session: ~1KB (message history)
- Per channel: ~5-10MB (WebSocket connections)
Response Latency
- Network: 10-50ms (channel → bus → agent)
- LLM: 0.5-3 seconds (provider-dependent)
- Tools: Varies (shell: less than 1s, web: 1-5s)
Security Model
Access Control Layers
- Channel-level:
allowFromlists - Tool-level:
restrictToWorkspacesandbox - File-level: Path validation and restrictions
Workspace Isolation
WhenrestrictToWorkspace: true:
- File operations restricted to
~/.nanobot/workspace/ - Path traversal attempts blocked
- Shell commands allowed but file access controlled
API Key Storage
- Stored in
~/.nanobot/config.json(600 permissions) - Never logged or exposed
- Environment variables set per-request
Extension Points
Easy places to add functionality:- New Channel: Implement
BaseChannel, add tomanager.py - New Provider: Add
ProviderSpec, add config field - New Tool: Implement
BaseTool, register inAgentLoop - New Skill: Drop markdown file in
~/.nanobot/skills/ - New Command: Add to
cli/commands.pywith@click.command()