nanocode
Minimal Claude Code alternative using DSPy RLM! Single Python file, ~390 lines.
Built using Claude Code, then used to build itself.
Features
- Full agentic loop with tool use via DSPy RLM
- Tools:
read,write,edit,glob,grep,bash - Conversation history with context
- Colored terminal output
- Modaic Integration: Push, version, and share as a Modaic autoprogram
Prerequisites
Before using nanocode (or any DSPy RLM-based program), you need to install the Deno code interpreter:
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:
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)
export OPENROUTER_API_KEY="your-key"
python nanocode.py
To use a specific model:
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:
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
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.
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.
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.
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:
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 - Framework for programming language models
- Modaic - Hub for sharing and versioning DSPy programs
- OpenRouter API key (for accessing language models)
Install dependencies:
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
