nanobot Documentation

repository·main·Indexed 23 days ago

https://github.com/obot-platform/nanobot

A platform for agentic automation featuring a browser-use skill for web interaction, CAPTCHA solving via human-in-the-loop VNC, and a CLI-driven interface. It supports directory-based agent configuration using Markdown files with YAML front-matter, Model Context Protocol (MCP) server integration, and a flexible CLI for calling tools, agents, and flows.

Tokens
14.7K
Snippets
17
Records
108
Agent score
79%

What's inside nanobot

  1. Configure Browser Modes

    main

    Choose a browser mode based on your isolation and authentication needs:

    • chromium: Fast and isolated. Recommended default is to use --browser chromium --headed to ensure the browser is visible in the Nanobot BrowserView for debugging and manual intervention.
    • real: Uses the user's actual Chrome installation, including cookies, extensions, and logged-in sessions. Use this when you need to access sites where the user is already authenticated.
    • Headless Mode: Omit the --headed flag (e.g., browser-use --browser chromium open <url>) for faster, background execution. Note that in headless mode, you cannot see the browser via VNC.
  2. Configure the integration test agent

    main

    The integration test harness loads the builtin nanobot agent using config.Load(".nanobot/", true).

    To customize the agent's behavior for a test run without modifying the test source code, create a .nanobot/ directory in your working directory. The harness will merge this directory's configuration into the agent's settings. This allows you to:

    • Override agent instructions.
    • Add MCP (Model Context Protocol) servers.
    • Adjust other agent settings.
  3. How Scheduled Tasks work in nanobot

    main

    Scheduled tasks are persistent task definitions managed via the nanobot.tasks tools. Unlike standard chat interactions, when a scheduled task triggers, nanobot initiates a new chat thread and executes the saved prompt within that fresh context.

    Because each run starts a new thread, prompts must be self-contained. They should not rely on transient context from the conversation that created them. A good task prompt should:

    • State the exact action to perform.
    • Explicitly name files, outputs, or deliverables.
    • Mention specific workflows to run by name if the task is intended to trigger a workflow.
  4. Scheduled Tasks vs Workflows

    main

    It is important to distinguish between these two abstractions:

    • Workflows: Reusable, multi-step procedures stored under workflows/. Use these when a user wants a repeatable process.
    • Scheduled Tasks: Deciders for when nanobot should start a future chat thread. Use these for time-based automation (reminders, reports, periodic syncs).

    Pattern: Scheduling a Workflow To run a workflow on a schedule, do not attempt to combine them into one object. Instead:

    1. Create or update the desired workflow.
    2. Create a scheduled task with a prompt that instructs nanobot to execute that specific workflow.
  5. Follow output conventions for Python scripts

    main

    To ensure compatibility with the platform, follow these output conventions:

    • Structured data: Print the final result as JSON to stdout.
    • Progress/debug info: Print logs, status updates, or debug information to stderr so they do not pollute the primary data output.
    • Errors: Print error messages to stderr and exit the process with a non-zero exit code.
    import sys
    import json
    
    # Output result (to stdout)
    print(json.dumps({"items": [...], "count": 42}))
    
    # Debug info (to stderr - won't pollute output)
    print("Processed 42 items", file=sys.stderr)
  6. Run integration tests

    main

    Integration tests in nanobot are end-to-end tests that run against a real LLM. They are excluded from standard go test ./... commands by default. To run them, you must use the integration build tag and provide a valid LLM API key (e.g., ANTHROPIC_API_KEY).

    Use the -runs flag to specify how many times each prompt should be executed per test (the default is 5).

    ANTHROPIC_API_KEY=... go test -tags integration ./integration_test/ -runs 5
  7. Solve CAPTCHAs via BrowserView

    main

    Since CAPTCHAs require human interaction, you must use --headed mode to make the browser visible in the Nanobot UI's BrowserView pane.

    Workflow for CAPTCHAs:

    1. Run the browser in --headed mode: browser-use --browser chromium --headed open <url>.
    2. Detect the CAPTCHA challenge using browser-use state.
    3. Pause automation and inform the user that manual intervention is required.
    4. Instruct the user to open the BrowserView pane in the Nanobot UI and solve the CAPTCHA.
    5. Once the user confirms completion, resume automation by running browser-use state to verify the challenge is gone.
  8. Manage Chrome Profiles with --browser real

    main

    When using --browser real, you can specify which Chrome profile to use. This is useful for selecting specific logged-in accounts (e.g., Work vs. Personal).

    1. List available local profiles: browser-use profile list-local.
    2. Open a specific profile: browser-use --browser real --profile "Profile Name" open <url>.
    3. Open without a specific profile (fresh session): browser-use --browser real open <url>.
    browser-use profile list-local
    
    browser-use --browser real --profile "Profile 1" open https://gmail.com
    
    browser-use --browser real open https://gmail.com
  9. Write Python scripts with inline dependencies using uv

    main

    You can define script dependencies directly within the Python file using a # /// script block. The uv tool will automatically install these dependencies when the script is executed.

    Ensure you include the requires-python and dependencies keys within the block.

    #!/usr/bin/env python3
    # /// script
    # requires-python = ">=3.11"
    # dependencies = [
    #     "requests",
    # ]
    # ///
    
    import json
    import requests
    
    data = requests.get("https://api.example.com/data").json()
    print(json.dumps(data))
  10. Add a new integration test

    main

    Integration tests use a shared testing harness to manage the agent lifecycle and intercept tool calls.

    Core Tooling

    • newTestRuntime(t, completer, recorder): Creates a Runtime wired with a recording/intercepting system server. Returns a context and an agent service (svc) ready for execution.
    • runAgent(ctx, svc, prompt): Executes the agent with a specific user prompt.
    • newRecorder(handlers): Creates a toolCallRecorder with custom ToolHandlers.
      • Note on Tool Behavior: By default, config and getSkill tools pass through to the real server. All other tools will return an error unless you register a handler in newRecorder.
    • recorder.find(name): Returns the first recorded call for a specific tool name, or nil if no call was made.
    • recorder.summary(): Returns a formatted string listing all tool calls and their arguments, which is useful for debugging test failures.