Files
nanocode/README.md

280 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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.dev/) - 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