# nanocode Minimal Claude Code alternative using DSPy RLM! Single Python file, ~390 lines. Built using Claude Code, then used to build itself. ![screenshot](https://d1pz4mbco29rws.cloudfront.net/public/nanocode.png) ## Features - Full agentic loop with tool use via [DSPy RLM](https://dspy.ai/) - Tools: `read`, `write`, `edit`, `glob`, `grep`, `bash` - Conversation history with context - Colored terminal output - **Modaic Integration**: Push, version, and share as a [Modaic](https://modaic.dev) autoprogram --- ## Prerequisites Before using nanocode (or any DSPy RLM-based program), you need to install the Deno code interpreter: ```bash brew install deno ``` This is required for the RLM's code execution capabilities. --- ## Quick Start ### Option 1: Use as a Modaic AutoProgram Load and run nanocode directly from the Modaic Hub without cloning: ```python from modaic import AutoProgram # Load the precompiled nanocode agent from Modaic Hub agent = AutoProgram.from_precompiled( "farouk1/nanocode", config={ "lm": "openrouter/anthropic/claude-3.5-sonnet", "max_iters": 20 } ) # Run a coding task result = agent(task="What Python files are in this directory?") print(result.answer) print(result.affected_files) ``` ### Option 2: Run Locally (Interactive CLI) ```bash export OPENROUTER_API_KEY="your-key" python nanocode.py ``` To use a specific model: ```bash export OPENROUTER_API_KEY="your-key" export MODEL="openai/gpt-4" python nanocode.py ``` --- ## Configuration When using as a Modaic AutoProgram, you can configure these options: | Parameter | Type | Default | Description | |-----------|------|---------|-------------| | `lm` | str | `openrouter/anthropic/claude-3.5-sonnet` | Primary language model | | `sub_lm` | str | `openrouter/openai/gpt-4.1` | Sub-LM for reasoning steps | | `max_iters` | int | `20` | Maximum agent iterations | | `api_base` | str | `https://openrouter.ai/api/v1` | API base URL | | `max_tokens` | int | `16000` | Maximum tokens per request | | `max_output_chars` | int | `100000` | Maximum output character limit | | `verbose` | bool | `False` | Enable verbose logging | Example with custom configuration: ```python from modaic import AutoProgram agent = AutoProgram.from_precompiled( "farouk1/nanocode", config={ "lm": "openrouter/openai/gpt-4", "sub_lm": "openrouter/openai/gpt-3.5-turbo", "max_iters": 30, "max_tokens": 8000, "verbose": True } ) ``` --- ## CLI Commands | Command | Description | |---------|-------------| | `/c` | Clear conversation history | | `/q` or `exit` | Quit the application | --- ## Tools The agent has access to the following tools: | Tool | Function | Description | |------|----------|-------------| | `readfile` | `read_file(path, offset, limit)` | Read file contents with line numbers | | `writefile` | `write_file(path, content)` | Write content to a file | | `editfile` | `edit_file(path, old, new, replace_all)` | Replace text in a file (old must be unique unless `replace_all=True`) | | `globfiles` | `glob_files(pattern, path)` | Find files matching a glob pattern, sorted by modification time | | `grepfiles` | `grep_files(pattern, path)` | Search files for a regex pattern | | `runbash` | `run_bash(cmd)` | Run a shell command and return output | --- ## Example Usage ### Interactive CLI ``` ──────────────────────────────────────── ❯ what files are here? ──────────────────────────────────────── ⏺ Thinking... ⏺ globfiles(pattern='**/*', path='.') ⏺ I found the following files: - nanocode.py - README.md - modaic/SKILL.md ``` ### Programmatic Usage ```python from modaic import AutoProgram agent = AutoProgram.from_precompiled("farouk1/nanocode") # Read a file result = agent(task="Read the first 10 lines of nanocode.py") print(result.answer) # Search for patterns result = agent(task="Find all functions that contain 'file' in their name") print(result.answer) # Make edits result = agent(task="Add a comment at the top of README.md") print(result.affected_files) # ['README.md'] ``` --- ## Architecture ### Overview ``` nanocode.py ├── File Operations │ ├── read_file() - Read with line numbers │ ├── write_file() - Write content │ └── edit_file() - Find & replace ├── Search Operations │ ├── glob_files() - Pattern matching │ └── grep_files() - Regex search ├── Shell Operations │ └── run_bash() - Execute commands ├── DSPy Components │ ├── CodingAssistant (Signature) │ └── RLMCodingProgram (PrecompiledProgram) └── Modaic Integration └── RLMCodingConfig (PrecompiledConfig) ``` ### Key Classes #### `RLMCodingConfig` Configuration class extending `PrecompiledConfig` for experiment-specific parameters. ```python class RLMCodingConfig(PrecompiledConfig): max_iters: int = 20 lm: str = "openrouter/anthropic/claude-3.5-sonnet" sub_lm: str = "openrouter/openai/gpt-4.1" api_base: str = "https://openrouter.ai/api/v1" max_tokens: int = 16000 max_output_chars: int = 100000 verbose: bool = False ``` #### `RLMCodingProgram` Main program class extending `PrecompiledProgram`. Wraps a DSPy RLM agent with coding tools. ```python class RLMCodingProgram(PrecompiledProgram): config: RLMCodingConfig def forward(self, task: str) -> dspy.Prediction: # Returns prediction with .answer and .affected_files return self.agent(task=task) ``` #### `CodingAssistant` DSPy Signature defining the agent's input/output schema. ```python class CodingAssistant(dspy.Signature): task: str = dspy.InputField() answer: str = dspy.OutputField() affected_files: list[str] = dspy.OutputField() ``` --- ## Publishing Your Own Version If you modify nanocode and want to publish your own version to Modaic Hub: ```python from nanocode import RLMCodingProgram, RLMCodingConfig # Create and optionally optimize your program program = RLMCodingProgram(RLMCodingConfig()) # Push to your Modaic Hub repo program.push_to_hub( "your-username/my-nanocode", commit_message="My customized nanocode", with_code=True # Include source code for AutoProgram loading ) ``` --- ## Dependencies - [DSPy](https://dspy.ai/) - Framework for programming language models - [Modaic](https://modaic.ai/) - Hub for sharing and versioning DSPy programs - OpenRouter API key (for accessing language models) Install dependencies: ```bash pip install dspy modaic # or with uv uv add dspy modaic ``` --- ## Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `OPENROUTER_API_KEY` | Yes | Your OpenRouter API key | | `MODEL` | No | Override the default model selection | | `MODAIC_TOKEN` | For Hub | Required for pushing/loading from Modaic Hub | --- ## License MIT