nanobot AI Assistant Framework

repository·main·Indexed 13 days ago

https://github.com/hkuds/nanobot

An ultra-lightweight, open-source, self-hosted personal AI agent framework. nanobot provides a runtime for AI agents accessible via WebUI, terminal, or chat apps like Telegram and Discord. It supports tools, long-term memory, MCP integrations, and a Python SDK. Version 0.3.0 allows for custom skill creation, model fallbacks, and OpenAI-compatible API endpoints.

Tokens
124.1K
Snippets
368
Records
555
Agent score
94%

What's inside nanobot

  1. Connect nanobot to chat platforms

    main

    nanobot can be connected to various chat platforms to act as an AI agent. Supported platforms include Telegram, Discord, Slack, Feishu, WhatsApp, WeChat, QQ, Email, and Mattermost.

    Before attempting to configure a chat app, verify that your local CLI is functioning correctly by running a test agent command. Chat apps also require the nanobot gateway to remain running after the channel is configured.

    Supported Platforms Reference:

    • Telegram
    • Discord
    • Slack
    • Feishu
    • WhatsApp
    • WeChat
    • QQ
    • Email
    • Mattermost
    • Others (via custom channel packages)
    nanobot agent -m "Hello!"
  2. Explore nanobot Task Guides

    main

    The nanobot task guides provide specific instructions for achieving various outcomes, ranging from building personal agents to integrating with external platforms.

    Prerequisite: Before following any specific guide, you should first complete the Install and Quick Start process and successfully receive at least one reply from the agent.

    Guides are categorized into four main areas:

    1. Start and Use: Building personal agents, using the WebUI, self-hosting, running long-running goals, and adding long-term memory.
    2. Connect a Chat App: Integrating the agent with platforms like Telegram, Discord, Slack, WhatsApp, etc. Setup is typically managed via Settings → Channels in the WebUI.
    3. Integrate from Code: Using the Python SDK or exposing an OpenAI-compatible /v1/chat/completions API.
    4. Configure and Operate: Advanced configurations including MCP tools, web search, model fallbacks, OpenAI-compatible providers, Ollama prompt caching, Langfuse observability, and security.
  3. How provider resolution works in nanobot

    main

    nanobot determines which model and provider to use based on a hierarchy of configuration settings. The recommended approach is to use named presets via agents.defaults.modelPreset.

    Resolution Order:

    1. The parameters defined in the named modelPresets entry referenced by agents.defaults.modelPreset.
    2. If no preset is specified, the implicit default preset is built from the direct fields in agents.defaults (e.g., provider, model, maxTokens, contextWindowTokens, temperature).

    Provider Selection Rules:

    • Explicit Provider: If provider is explicitly set in a preset or the default config, it takes precedence.
    • provider: "auto": nanobot attempts to infer the provider by checking model-name keywords, configured API keys, local base URLs, and gateway providers.
    • Prefix-based Inference: When provider is set to "auto", a model name like family/model-name can trigger provider selection. However, if you use a gateway like OpenRouter, you should pin the provider (e.g., provider: "openrouter") to ensure the model name is routed correctly through the gateway's catalog.
    • Custom Providers: If you use a custom provider (e.g., provider: "companyProxy"), the model name is sent exactly as written (e.g., openai/gpt-4o-mini is sent to companyProxy).
  4. Customize the agent loop with Hooks

    main

    Hooks allow you to observe or modify the agent's execution lifecycle. To use them, subclass AgentHook and override the specific lifecycle methods required for your task. You can pass one or multiple hooks to the bot.run() method via the hooks argument.

    Hook Lifecycle Methods:

    MethodPurpose
    wants_streaming()Return True to enable on_stream() callbacks for token-by-token processing.
    before_iteration(context)Executed before every LLM call.
    on_stream(context, delta)Executed on each streamed token (only if wants_streaming() returns True).
    on_stream_end(context, *, resuming)Executed when the streaming process completes.
    before_execute_tools(context)Executed before any tools are called.
    after_iteration(context)Executed after each iteration of the agent loop.
    finalize_content(context, content)A pipeline method used to transform the final output text. Each hook in the pipeline receives the output from the previous one.

    AgentHookContext Fields: When implementing hooks, the AgentHookContext object provides access to:

    • iteration: The current loop index.
    • messages: The conversation history.
    • response: The LLM response.
    • usage: Token usage statistics.
    • tool_calls: List of requested tool calls.
    • tool_results: Results from executed tools.
    • tool_events: Events related to tool execution.
    • final_content: The final text generated by the agent.
    • stop_reason: Why the LLM stopped generating.
    • error: Any error encountered during the loop.
    from nanobot.agent import AgentHook, AgentHookContext
    
    class MyCustomHook(AgentHook):
        async def before_iteration(self, context: AgentHookContext) -> None:
            print(f"Starting iteration {context.iteration}")
    
    # Usage
    result = await bot.run("Hello", hooks=[MyCustomHook()])
  5. Enable Unified Sessions for Cross-Channel Continuity

    main

    By default, each channel × chat ID combination has its own session. If you want to use nanobot across multiple channels (e.g., Telegram and Discord) and maintain the same conversation, enable unifiedSession.

    When unifiedSession: true:

    • All messages from any channel are routed into a single shared session (unified:default).
    • /new clears the shared session.
    • /stop finds tasks by the shared session.
    • Existing session_key_override settings are still respected.
    {
      "agents": {
        "defaults": {
          "unifiedSession": true
        }
      }
    }
  6. Understand SSRF security for web tools

    main

    nanobot implements an SSRF (Server-Side Request Forgery) guard for web fetch and HTTP MCP.

    • Default Behavior: Private, loopback, link-local, and cloud metadata addresses are blocked by default.
    • Customization: Use tools.ssrfWhitelist to allow specific, narrow, and trusted CIDR ranges.
    • Warning: Avoid giving public chat users unrestricted web and shell access without thorough review.
  7. Distinguish between AgentLoop and AgentRunner

    main

    When debugging or extending nanobot, it is critical to know which component is responsible for a behavior:

    • Use AgentLoop (nanobot/agent/loop.py) if the issue involves:
      • Channel routing or inbound/outbound message delivery.
      • Session keys and workspace selection.
      • Context construction and metadata.
    • Use AgentRunner (nanobot/agent/runner.py) if the issue involves:
      • Provider (LLM) calls and streaming deltas.
      • Reasoning blocks and tool execution.
      • Iteration limits and tool result feedback loops.
  8. Using the Composer for Input and Mentions

    main

    The Composer is the primary input area for interacting with agents. It supports:

    • Text & Images: Plain text messages and image attachments.
    • Voice: Voice input (requires transcription configuration).
    • Slash Commands: Special commands starting with /.
    • @ Mentions: Use @ to reference installed Apps or MCP presets. You can also select other topics from the @ menu to attach them as stable references.

    Note: In Restricted chats, @ mentions only show topics from the same project. In Full Access chats, you can reference any WebUI topic.

  9. Choose an automation type

    main

    Nanobot provides three types of automations depending on your use case. Choose based on how the task should be triggered and how much noise it should make:

    1. Scheduled automation: Best for recurring reminders, summaries, or one-time future tasks. Created by asking nanobot in a target topic to use the cron tool.
    2. Local trigger: Best for CI jobs, webhooks, or shell scripts. Created using the /trigger <name> command in a target topic. It allows external processes to inject messages into a session.
    3. Heartbeat: Best for quiet, recurring background checks (e.g., monitoring for failures) that should only report actionable results. Managed via <workspace>/HEARTBEAT.md and enabled by default in the gateway.
  10. Understand Agent-Owned State vs Project Context

    main

    nanobot distinguishes between the agent's own configuration and the specific project it is currently working on:

    • Agent-Owned Workspace: Contains long-term data like Sessions, SOUL.md, USER.md, memory, and custom skills. This is the configured agent workspace.
    • Effective Project Workspace: The scope of the current task/session. It contains AGENTS.md, relative tool paths, and defines the shell working directory. A WebUI chat might select a project different from the agent's default workspace.
    • Session Workspace Scope: Controls access modes and project metadata.
  11. Manage Memory and Sessions

    main

    nanobot manages context through two distinct storage mechanisms within the workspace:

    1. Sessions: Stored in <workspace>/sessions/*.jsonl. These contain recent conversation turns that are replayed into the context for active chats.
    2. Memory: Stored in <workspace>/memory/MEMORY.md and <workspace>/memory/history.jsonl. This is for long-term facts and consolidated history.

    The Dream Job

    Dream is a periodic background consolidation job (enabled via agents.defaults.dream.enabled). It reads accumulated session history and updates the long-term MEMORY.md so context survives beyond the immediate session replay window.

  12. Use the cron tool to schedule tasks and reminders

    main

    The cron tool allows you to schedule reminders or recurring tasks that report back to the originating chat or session upon execution.

    Important Usage Note: Do not use cron for periodic background checks that should remain silent if no useful information is found. For silent background checks, use the HEARTBEAT.md mechanism instead, which uses a protected heartbeat job and a notification gate to filter results.