A minimalistic Python library for building AI agents using functional, immutable DAG operations.
Functional & Immutable - The DAG is immutable. Every operation returns a new instance. No hidden state, no mutations, easy to reason about.
dag = DAG()
dag = dag.system("You are helpful.") # New DAG
dag = dag.user("Hello") # New DAG
dag = dag.assistant(response.content) # New DAGConversation Graph - Everything is a node in a directed acyclic graph: system prompts, messages, tool calls, results. Branch and merge for parallel tool execution.
Built-in Tools - BashTool, ReadTool, WriteTool, EditTool, GlobTool, GrepTool, StatTool, PythonTool, TodoWriteTool, WebFetchTool.
Sub-Agents - Tools can spawn their own agents using SubAgentTool. Supports recursive nesting and parallel execution.
Visualization - Print any DAG to see the conversation flow, or export to HTML:
SYSTEM: You are helpful.
│
▼
USER: What files are here?
│
▼
TOOL_USE: Bash
│
▼
TOOL_RESULT: file1.py, file2.py
│
▼
ASSISTANT: I found 2 Python files...
dag.save("conversation.json") # Save the graphuv run nano-agent-viewer conversation.json # Creates conversation.htmlMulti-Provider - Works with Claude API, Claude Code OAuth, or Gemini API.
import asyncio
from nano_agent import ClaudeAPI, DAG, BashTool, run
async def main():
api = ClaudeAPI() # Uses ANTHROPIC_API_KEY
dag = (
DAG()
.system("You are a helpful assistant.")
.tools(BashTool())
.user("What is the current date?")
)
dag = await run(api, dag)
print(dag)
asyncio.run(main())git clone https://github.com/NTT123/nano-agent.git
cd nano-agent
uv sync# Install pre-commit hooks (required for contributing)
uv run pre-commit install
# Run tests
uv run pytest
# Type checking
uv run mypy .
# Format code
uv run pre-commit run --all-filesnano-cli is a lightweight, terminal-based AI coding assistant similar to Claude Code or Cursor. It provides an agentic loop that can read files, execute commands, edit code, and browse the web—all from your terminal.
- Agentic execution: Automatically handles tool calls in a loop until the task is complete
- Session persistence: Auto-saves conversations and can resume from where you left off
- Multi-provider: Works with Claude (via Claude Code OAuth) or Gemini APIs
- Rich TUI: Syntax-highlighted output, streaming responses, and interactive confirmations
- Project context: Automatically loads
CLAUDE.mdfrom your current directory as context - Built-in tools: Bash, Read, Write, Edit, Glob, Grep, Stat, TodoWrite, WebFetch, Python
Install the CLI globally using uv:
uv tool install git+https://github.com/NTT123/nano-agent.gitCapture your Claude Code auth credentials first:
nano-agent-capture-authOnce installed, you can use nano-cli from any project directory:
cd your-project
nano-cliAdditional options:
# Run with Gemini instead of Claude
nano-cli --gemini
nano-cli --gemini gemini-2.5-flash # specific model
# Continue from saved session
nano-cli --continue
nano-cli --continue my-session.json
# Debug mode (show raw response blocks)
nano-cli --debug| Command | Description |
|---|---|
/quit, /exit, /q |
Exit the application |
/clear |
Reset conversation and clear screen |
/continue, /c |
Continue agent execution without user message |
/save [filename] |
Save session to file (default: session.json) |
/load [filename] |
Load session from file |
/renew |
Refresh OAuth token (for 401 errors) |
/render |
Re-render history (after terminal resize) |
/debug |
Show DAG as JSON |
/help |
Show help message |
| Key | Action |
|---|---|
| Enter | Send message |
| \ + Enter | Insert new line (for multiline input) |
| Esc | Cancel current operation (during execution) |
| Ctrl+D | Exit |
Note: Ctrl+J and Shift+Enter are not supported.
nano-discord-bot is an AI assistant that runs 24/7 as a Discord bot. It uses the same nano-agent core and tools to provide an agentic coding assistant directly in Discord channels and threads.
- Queue-based messaging: User messages are queued and processed asynchronously, so the bot handles concurrent messages gracefully
- Channel workers: Each channel gets a dedicated worker that processes messages in order
- Discord tools: Send messages, send files, create threads, explore guild/channel structure, and call the Discord REST API
- Session persistence: Message queues are persisted to disk and recovered on restart
- All built-in tools: Bash, Read, Write, Edit, Glob, Grep, Stat, Python, WebFetch, and more
# Set your Discord bot token
export DISCORD_BOT_TOKEN=your-token-here
# Run the bot
uv run nano-discord-bot| Command | Description |
|---|---|
/clear |
Clear conversation history in the current channel/thread |
/queue |
Show queued user messages |
/cd <path> |
Change working directory |
/cwd |
Show current working directory |
/thread <topic> |
Start a new conversation in a Discord thread |
/renew |
Refresh Claude Code OAuth token |
/explore |
Explore visible Discord context (guild/channels/threads) |
Create tools that spawn their own agents using SubAgentTool:
from dataclasses import dataclass
from typing import Annotated
from nano_agent import SubAgentTool, TextContent, ReadTool
from nano_agent.tools.base import Desc
@dataclass
class CodeReviewInput:
file_path: Annotated[str, Desc("Path to the file to review")]
@dataclass
class CodeReviewTool(SubAgentTool):
name: str = "CodeReview"
description: str = "Spawn a sub-agent to review code"
async def __call__(self, input: CodeReviewInput) -> TextContent:
summary = await self.spawn(
system_prompt="You are an expert code reviewer...",
user_message=f"Review: {input.file_path}",
tools=[ReadTool()],
)
return TextContent(text=summary)Features:
- Recursive nesting: Sub-agents can spawn their own sub-agents (with depth limits)
- Parallel execution: Multiple sub-agent tools can run concurrently
- Graph visualization: Sub-agent graphs are captured and viewable in HTML export
See examples/parallel_sub_agents.py and examples/recursive_sub_agents.py for complete examples.
MIT