Overview
nanobot is designed to be ultra-lightweight (~10,000 total lines, ~4,000 core agent lines) while delivering full AI agent capabilities.Core Philosophy
Design Principles
- Simplicity: Every line of code should be necessary and understandable
- Modularity: Components are loosely coupled and independently replaceable
- Extensibility: Easy to add new providers, channels, and tools
- Research-Ready: Clean, readable code for experimentation and learning
Architecture Diagram
Component Architecture
1. Channels (nanobot/channels/)
Purpose: Connect nanobot to chat platforms.
Pattern: All channels implement BaseChannel:
telegram.py- Telegram bot (polling)discord.py- Discord bot (WebSocket)whatsapp.py- WhatsApp (via bridge)feishu.py- Feishu/Lark (WebSocket)email.py- Email (IMAP/SMTP)slack.py- Slack (Socket Mode)qq.py- QQ (WebSocket)dingtalk.py- DingTalk (Stream Mode)matrix.py- Matrix/Element (E2EE support)mochat.py- Mochat/Claw IM (Socket.IO)
- Access control via
allowFromlists - Media handling (images, voice, files)
- Typing indicators and reactions
- Thread/group support
2. Message Bus (nanobot/bus/)
Purpose: Decouple channels from agent logic.
Key Classes:
- Channel receives message from platform
- Channel publishes
InboundMessageto bus - AgentLoop processes message
- AgentLoop publishes
OutboundMessageto bus - Channel sends message to platform
3. Agent Loop (nanobot/agent/loop.py)
Purpose: Core processing engine.
Main Loop:
- Session management (per user/chat)
- Memory integration (MEMORY.md)
- Skill loading (from
~/.nanobot/skills/) - Tool execution with timeouts
- Subagent spawning for background tasks
- MCP server integration
4. Providers (nanobot/providers/)
Purpose: Abstract LLM API differences.
Pattern: All providers implement LLMProvider:
litellm_provider.py- LiteLLM wrapper (most providers)custom_provider.py- Direct OpenAI-compatible APIopenai_codex_provider.py- OAuth-based providers
registry.py):
- Add
ProviderSpectoPROVIDERStuple - Add config field to
ProvidersConfig
5. Tools (nanobot/agent/tools/)
Purpose: Give the agent capabilities.
Built-in Tools:
shell.py- Execute shell commandsfilesystem.py- Read/write/edit/list filesweb.py- Web search and fetchspawn.py- Create background subagentscron.py- Schedule tasksmessage.py- Send messages to channelsmcp.py- Model Context Protocol servers
BaseTool:
6. Session Management (nanobot/session/)
Purpose: Track conversation history per user/chat.
- Per-user sessions (isolated history)
- Thread-scoped sessions (Discord/Slack threads)
- Automatic persistence
- Session reset via
/newcommand
7. Memory (nanobot/agent/memory.py)
Purpose: Long-term persistent memory.
Implementation:
- Stored in
~/.nanobot/workspace/MEMORY.md - Agent can read/update via prompts
- Markdown format for human readability
- Injected into every context
8. Context Builder (nanobot/agent/context.py)
Purpose: Assemble prompts for the LLM.
Context Structure:
- Token counting and truncation
- Skill injection
- Memory injection
- Tool schema formatting
9. Cron Service (nanobot/cron/)
Purpose: Schedule periodic tasks.
Features:
- Natural language scheduling (“every day at 9am”)
- Persistent job storage (
~/.nanobot/workspace/cron/jobs.json) - Agent can create/list/delete jobs via
CronTool
10. Heartbeat (nanobot/heartbeat/)
Purpose: Proactive task execution.
How It Works:
- Gateway wakes up every 30 minutes
- Reads
~/.nanobot/workspace/HEARTBEAT.md - If file has tasks, spawns agent to execute them
- Results sent to most recent chat channel
Data Flow Example
User sends “What’s the weather?” via Telegram:Extension Points
Adding a New Channel
- Create
nanobot/channels/mychannel.py - Implement
BaseChannel - Add config to
config/schema.py - Register in
channels/manager.py
Adding a New Provider
- Add
ProviderSpectoproviders/registry.py - Add config field to
config/schema.py
Adding a New Tool
- Create
nanobot/agent/tools/mytool.py - Implement
BaseTool - Register in
AgentLoop.__init__
Performance Characteristics
Memory Usage
- Base: ~50MB (Python runtime + libraries)
- Per session: ~1KB (message history)
- Per channel: ~5-10MB (WebSocket connections)
Startup Time
- CLI mode: Less than 1 second
- Gateway mode: 2-5 seconds (channel connections)
Response Time
- Network latency: 10-50ms (channel → bus → agent)
- LLM latency: 0.5-3 seconds (provider-dependent)
- Tool execution: Varies by tool (shell: less than 1s, web: 1-5s)
Security Architecture
Access Control
- Channel-level:
allowFromlists - Tool-level:
restrictToWorkspacesandbox - File operations: Path validation and workspace restriction
Workspace Isolation
WhenrestrictToWorkspace: true:
- All file operations restricted to
~/.nanobot/workspace/ - Shell commands allowed but file access controlled
- Path traversal attempts blocked
API Key Management
- Stored in
~/.nanobot/config.json(600 permissions) - Never logged or exposed to users
- Environment variables set per-request, not globally
Logging and Debugging
Log Levels
Enable Debug Logging
Testing Strategy
Currently manual testing focused:- CLI testing:
nanobot agent -m "..." - Gateway testing: Real channel integration
- Provider testing: Multiple LLM providers
- Tool testing: Execute each tool manually
Performance Optimization
Current Optimizations
- Prompt caching: Anthropic prompt caching support
- Session persistence: Avoid re-reading from disk
- Tool timeouts: Prevent hanging on slow operations
- Connection pooling: Reuse HTTP connections
Future Optimizations
- Streaming responses: Real-time output
- Parallel tool execution: Run independent tools concurrently
- Message batching: Reduce bus overhead