nanocoderagent 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nanocoderagent-0.1.0/.github/workflows/ci.yml +27 -0
- nanocoderagent-0.1.0/.github/workflows/publish.yml +27 -0
- nanocoderagent-0.1.0/.gitignore +17 -0
- nanocoderagent-0.1.0/LICENSE +21 -0
- nanocoderagent-0.1.0/PKG-INFO +194 -0
- nanocoderagent-0.1.0/README.md +169 -0
- nanocoderagent-0.1.0/README_CN.md +169 -0
- nanocoderagent-0.1.0/article/00-index.md +29 -0
- nanocoderagent-0.1.0/article/01-architecture-overview.md +143 -0
- nanocoderagent-0.1.0/article/02-agent-loop.md +237 -0
- nanocoderagent-0.1.0/article/03-tool-system.md +169 -0
- nanocoderagent-0.1.0/article/04-context-compression.md +144 -0
- nanocoderagent-0.1.0/article/05-streaming-executor.md +213 -0
- nanocoderagent-0.1.0/article/06-multi-agent.md +193 -0
- nanocoderagent-0.1.0/article/07-hidden-features.md +98 -0
- nanocoderagent-0.1.0/article/zhihu-guide-series.md +125 -0
- nanocoderagent-0.1.0/article/zhihu-nanocoder.md +182 -0
- nanocoderagent-0.1.0/nanocoder/__init__.py +10 -0
- nanocoderagent-0.1.0/nanocoder/__main__.py +3 -0
- nanocoderagent-0.1.0/nanocoder/agent.py +122 -0
- nanocoderagent-0.1.0/nanocoder/cli.py +214 -0
- nanocoderagent-0.1.0/nanocoder/config.py +32 -0
- nanocoderagent-0.1.0/nanocoder/context.py +196 -0
- nanocoderagent-0.1.0/nanocoder/llm.py +156 -0
- nanocoderagent-0.1.0/nanocoder/prompt.py +33 -0
- nanocoderagent-0.1.0/nanocoder/session.py +68 -0
- nanocoderagent-0.1.0/nanocoder/tools/__init__.py +27 -0
- nanocoderagent-0.1.0/nanocoder/tools/agent.py +58 -0
- nanocoderagent-0.1.0/nanocoder/tools/base.py +27 -0
- nanocoderagent-0.1.0/nanocoder/tools/bash.py +115 -0
- nanocoderagent-0.1.0/nanocoder/tools/edit.py +85 -0
- nanocoderagent-0.1.0/nanocoder/tools/glob_tool.py +47 -0
- nanocoderagent-0.1.0/nanocoder/tools/grep.py +78 -0
- nanocoderagent-0.1.0/nanocoder/tools/read.py +53 -0
- nanocoderagent-0.1.0/nanocoder/tools/write.py +36 -0
- nanocoderagent-0.1.0/pyproject.toml +42 -0
- nanocoderagent-0.1.0/tests/__init__.py +0 -0
- nanocoderagent-0.1.0/tests/test_core.py +98 -0
- nanocoderagent-0.1.0/tests/test_tools.py +196 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ${{ matrix.os }}
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
os: [ubuntu-latest, macos-latest]
|
|
15
|
+
python-version: ["3.10", "3.12"]
|
|
16
|
+
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: pip install -e ".[dev]"
|
|
25
|
+
|
|
26
|
+
- name: Run tests
|
|
27
|
+
run: python -m pytest tests/ -v
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
publish:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
environment: pypi
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-python@v5
|
|
17
|
+
with:
|
|
18
|
+
python-version: "3.12"
|
|
19
|
+
|
|
20
|
+
- name: Install build tools
|
|
21
|
+
run: pip install build
|
|
22
|
+
|
|
23
|
+
- name: Build package
|
|
24
|
+
run: python -m build
|
|
25
|
+
|
|
26
|
+
- name: Publish to PyPI
|
|
27
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yufeng He
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nanocoderagent
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Minimal AI coding agent (~1300 LoC) inspired by Claude Code. Works with any LLM.
|
|
5
|
+
Project-URL: Homepage, https://github.com/he-yufeng/NanoCoder
|
|
6
|
+
Project-URL: Repository, https://github.com/he-yufeng/NanoCoder
|
|
7
|
+
Project-URL: Issues, https://github.com/he-yufeng/NanoCoder/issues
|
|
8
|
+
Author-email: Yufeng He <40085740+he-yufeng@users.noreply.github.com>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,ai,claude-code,cli,coding,llm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Requires-Python: >=3.10
|
|
19
|
+
Requires-Dist: openai>=1.0
|
|
20
|
+
Requires-Dist: prompt-toolkit>=3.0
|
|
21
|
+
Requires-Dist: rich>=13.0
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# NanoCoder
|
|
27
|
+
|
|
28
|
+
[](https://pypi.org/project/nanocoderagent/)
|
|
29
|
+
[](https://python.org)
|
|
30
|
+
[](LICENSE)
|
|
31
|
+
[](https://github.com/he-yufeng/NanoCoder/actions)
|
|
32
|
+
|
|
33
|
+
[中文](README_CN.md) | [English](README.md) | [Claude Code Architecture Deep Dive (7 articles)](article/)
|
|
34
|
+
|
|
35
|
+
**512,000 lines of TypeScript → 1,300 lines of Python.**
|
|
36
|
+
|
|
37
|
+
I spent a weekend reverse-engineering the leaked Claude Code source — all half a million lines. Then I stripped it down to the load-bearing walls and rebuilt them in Python. The result: **every key architectural pattern from Claude Code, in a codebase you can read in one sitting.**
|
|
38
|
+
|
|
39
|
+
NanoCoder is not another AI coding tool. It's a **blueprint** — the [nanoGPT](https://github.com/karpathy/nanoGPT) of coding agents. Read it, fork it, build your own.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
$ nanocoder -m kimi-k2.5
|
|
45
|
+
|
|
46
|
+
You > read main.py and fix the broken import
|
|
47
|
+
|
|
48
|
+
> read_file(file_path='main.py')
|
|
49
|
+
> edit_file(file_path='main.py', ...)
|
|
50
|
+
|
|
51
|
+
--- a/main.py
|
|
52
|
+
+++ b/main.py
|
|
53
|
+
@@ -1 +1 @@
|
|
54
|
+
-from utils import halper
|
|
55
|
+
+from utils import helper
|
|
56
|
+
|
|
57
|
+
Fixed: halper → helper.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## What You Get
|
|
61
|
+
|
|
62
|
+
Claude Code's 512K lines distilled to 7 patterns that actually matter:
|
|
63
|
+
|
|
64
|
+
| Pattern | Claude Code | NanoCoder |
|
|
65
|
+
|---|---|---|
|
|
66
|
+
| Search-and-replace editing (unique match + diff) | FileEditTool | `tools/edit.py` — 70 lines |
|
|
67
|
+
| Parallel tool execution | StreamingToolExecutor (530 lines) | `agent.py` — ThreadPool |
|
|
68
|
+
| 3-layer context compression | HISTORY_SNIP → Microcompact → CONTEXT_COLLAPSE | `context.py` — 145 lines |
|
|
69
|
+
| Sub-agent with isolated context | AgentTool (1,397 lines) | `tools/agent.py` — 50 lines |
|
|
70
|
+
| Dangerous command blocking | BashTool (1,143 lines) | `tools/bash.py` — 95 lines |
|
|
71
|
+
| Session persistence | QueryEngine (1,295 lines) | `session.py` — 65 lines |
|
|
72
|
+
| Dynamic system prompt | prompts.ts (914 lines) | `prompt.py` — 35 lines |
|
|
73
|
+
|
|
74
|
+
Every pattern is a real, runnable implementation — not a diagram or a blog post.
|
|
75
|
+
|
|
76
|
+
## Install
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pip install nanocoderagent
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Pick your model — any OpenAI-compatible API works:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Kimi K2.5
|
|
86
|
+
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://api.moonshot.ai/v1
|
|
87
|
+
nanocoder -m kimi-k2.5
|
|
88
|
+
|
|
89
|
+
# Claude Opus 4.6 (via OpenRouter)
|
|
90
|
+
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://openrouter.ai/api/v1
|
|
91
|
+
nanocoder -m anthropic/claude-opus-4-6
|
|
92
|
+
|
|
93
|
+
# OpenAI GPT-5
|
|
94
|
+
export OPENAI_API_KEY=sk-...
|
|
95
|
+
nanocoder -m gpt-5
|
|
96
|
+
|
|
97
|
+
# DeepSeek V3
|
|
98
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://api.deepseek.com
|
|
99
|
+
nanocoder -m deepseek-chat
|
|
100
|
+
|
|
101
|
+
# Qwen 3.5
|
|
102
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
103
|
+
nanocoder -m qwen-max
|
|
104
|
+
|
|
105
|
+
# Ollama (local)
|
|
106
|
+
export OPENAI_API_KEY=ollama OPENAI_BASE_URL=http://localhost:11434/v1
|
|
107
|
+
nanocoder -m qwen3:32b
|
|
108
|
+
|
|
109
|
+
# One-shot mode
|
|
110
|
+
nanocoder -p "add error handling to parse_config()"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Architecture
|
|
114
|
+
|
|
115
|
+
The whole thing fits in your head:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
nanocoder/
|
|
119
|
+
├── cli.py REPL + commands 160 lines
|
|
120
|
+
├── agent.py Agent loop + parallel tools 120 lines
|
|
121
|
+
├── llm.py Streaming client + retry 150 lines
|
|
122
|
+
├── context.py 3-layer compression 145 lines
|
|
123
|
+
├── session.py Save/resume 65 lines
|
|
124
|
+
├── prompt.py System prompt 35 lines
|
|
125
|
+
├── config.py Env config 30 lines
|
|
126
|
+
└── tools/
|
|
127
|
+
├── bash.py Shell + safety + cd tracking 95 lines
|
|
128
|
+
├── edit.py Search-replace + diff 70 lines
|
|
129
|
+
├── read.py File reading 40 lines
|
|
130
|
+
├── write.py File writing 30 lines
|
|
131
|
+
├── glob_tool.py File search 35 lines
|
|
132
|
+
├── grep.py Content search 65 lines
|
|
133
|
+
└── agent.py Sub-agent spawning 50 lines
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Use as a Library
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
from nanocoder import Agent, LLM
|
|
140
|
+
|
|
141
|
+
llm = LLM(model="kimi-k2.5", api_key="your-key", base_url="https://api.moonshot.ai/v1")
|
|
142
|
+
agent = Agent(llm=llm)
|
|
143
|
+
response = agent.chat("find all TODO comments in this project and list them")
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Add Your Own Tools (~20 lines)
|
|
147
|
+
|
|
148
|
+
```python
|
|
149
|
+
from nanocoder.tools.base import Tool
|
|
150
|
+
|
|
151
|
+
class HttpTool(Tool):
|
|
152
|
+
name = "http"
|
|
153
|
+
description = "Fetch a URL."
|
|
154
|
+
parameters = {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}
|
|
155
|
+
|
|
156
|
+
def execute(self, url: str) -> str:
|
|
157
|
+
import urllib.request
|
|
158
|
+
return urllib.request.urlopen(url).read().decode()[:5000]
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Commands
|
|
162
|
+
|
|
163
|
+
```
|
|
164
|
+
/model <name> Switch model mid-conversation
|
|
165
|
+
/compact Compress context (like Claude Code's /compact)
|
|
166
|
+
/tokens Token usage
|
|
167
|
+
/save Save session to disk
|
|
168
|
+
/sessions List saved sessions
|
|
169
|
+
/reset Clear history
|
|
170
|
+
quit Exit
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## How It Compares
|
|
174
|
+
|
|
175
|
+
| | Claude Code | Claw-Code | Aider | NanoCoder |
|
|
176
|
+
|---|---|---|---|---|
|
|
177
|
+
| Code | 512K lines (closed) | 100K+ lines | 50K+ lines | **1,300 lines** |
|
|
178
|
+
| Models | Anthropic only | Multi | Multi | **Any OpenAI-compatible** |
|
|
179
|
+
| Readable? | No | Hard | Medium | **One afternoon** |
|
|
180
|
+
| Purpose | Use it | Use it | Use it | **Understand it, build yours** |
|
|
181
|
+
|
|
182
|
+
## The Deep Dive
|
|
183
|
+
|
|
184
|
+
I wrote [7 articles](article/) breaking down Claude Code's architecture — the agent loop, tool system, context compression, streaming executor, multi-agent, and 44 hidden feature flags. If you want to understand *why* NanoCoder is designed this way, start there.
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT. Fork it, learn from it, ship something better. A mention of this project is appreciated.
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
Built by **[Yufeng He](https://github.com/he-yufeng)** · Agentic AI Researcher @ Moonshot AI (Kimi)
|
|
193
|
+
|
|
194
|
+
[Claude Code Source Analysis — 170K+ reads, 6000 bookmarks on Zhihu](https://zhuanlan.zhihu.com/p/1898797658343862272)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# NanoCoder
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/nanocoderagent/)
|
|
4
|
+
[](https://python.org)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://github.com/he-yufeng/NanoCoder/actions)
|
|
7
|
+
|
|
8
|
+
[中文](README_CN.md) | [English](README.md) | [Claude Code Architecture Deep Dive (7 articles)](article/)
|
|
9
|
+
|
|
10
|
+
**512,000 lines of TypeScript → 1,300 lines of Python.**
|
|
11
|
+
|
|
12
|
+
I spent a weekend reverse-engineering the leaked Claude Code source — all half a million lines. Then I stripped it down to the load-bearing walls and rebuilt them in Python. The result: **every key architectural pattern from Claude Code, in a codebase you can read in one sitting.**
|
|
13
|
+
|
|
14
|
+
NanoCoder is not another AI coding tool. It's a **blueprint** — the [nanoGPT](https://github.com/karpathy/nanoGPT) of coding agents. Read it, fork it, build your own.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
$ nanocoder -m kimi-k2.5
|
|
20
|
+
|
|
21
|
+
You > read main.py and fix the broken import
|
|
22
|
+
|
|
23
|
+
> read_file(file_path='main.py')
|
|
24
|
+
> edit_file(file_path='main.py', ...)
|
|
25
|
+
|
|
26
|
+
--- a/main.py
|
|
27
|
+
+++ b/main.py
|
|
28
|
+
@@ -1 +1 @@
|
|
29
|
+
-from utils import halper
|
|
30
|
+
+from utils import helper
|
|
31
|
+
|
|
32
|
+
Fixed: halper → helper.
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What You Get
|
|
36
|
+
|
|
37
|
+
Claude Code's 512K lines distilled to 7 patterns that actually matter:
|
|
38
|
+
|
|
39
|
+
| Pattern | Claude Code | NanoCoder |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| Search-and-replace editing (unique match + diff) | FileEditTool | `tools/edit.py` — 70 lines |
|
|
42
|
+
| Parallel tool execution | StreamingToolExecutor (530 lines) | `agent.py` — ThreadPool |
|
|
43
|
+
| 3-layer context compression | HISTORY_SNIP → Microcompact → CONTEXT_COLLAPSE | `context.py` — 145 lines |
|
|
44
|
+
| Sub-agent with isolated context | AgentTool (1,397 lines) | `tools/agent.py` — 50 lines |
|
|
45
|
+
| Dangerous command blocking | BashTool (1,143 lines) | `tools/bash.py` — 95 lines |
|
|
46
|
+
| Session persistence | QueryEngine (1,295 lines) | `session.py` — 65 lines |
|
|
47
|
+
| Dynamic system prompt | prompts.ts (914 lines) | `prompt.py` — 35 lines |
|
|
48
|
+
|
|
49
|
+
Every pattern is a real, runnable implementation — not a diagram or a blog post.
|
|
50
|
+
|
|
51
|
+
## Install
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install nanocoderagent
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Pick your model — any OpenAI-compatible API works:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Kimi K2.5
|
|
61
|
+
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://api.moonshot.ai/v1
|
|
62
|
+
nanocoder -m kimi-k2.5
|
|
63
|
+
|
|
64
|
+
# Claude Opus 4.6 (via OpenRouter)
|
|
65
|
+
export OPENAI_API_KEY=your-key OPENAI_BASE_URL=https://openrouter.ai/api/v1
|
|
66
|
+
nanocoder -m anthropic/claude-opus-4-6
|
|
67
|
+
|
|
68
|
+
# OpenAI GPT-5
|
|
69
|
+
export OPENAI_API_KEY=sk-...
|
|
70
|
+
nanocoder -m gpt-5
|
|
71
|
+
|
|
72
|
+
# DeepSeek V3
|
|
73
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://api.deepseek.com
|
|
74
|
+
nanocoder -m deepseek-chat
|
|
75
|
+
|
|
76
|
+
# Qwen 3.5
|
|
77
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
78
|
+
nanocoder -m qwen-max
|
|
79
|
+
|
|
80
|
+
# Ollama (local)
|
|
81
|
+
export OPENAI_API_KEY=ollama OPENAI_BASE_URL=http://localhost:11434/v1
|
|
82
|
+
nanocoder -m qwen3:32b
|
|
83
|
+
|
|
84
|
+
# One-shot mode
|
|
85
|
+
nanocoder -p "add error handling to parse_config()"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Architecture
|
|
89
|
+
|
|
90
|
+
The whole thing fits in your head:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
nanocoder/
|
|
94
|
+
├── cli.py REPL + commands 160 lines
|
|
95
|
+
├── agent.py Agent loop + parallel tools 120 lines
|
|
96
|
+
├── llm.py Streaming client + retry 150 lines
|
|
97
|
+
├── context.py 3-layer compression 145 lines
|
|
98
|
+
├── session.py Save/resume 65 lines
|
|
99
|
+
├── prompt.py System prompt 35 lines
|
|
100
|
+
├── config.py Env config 30 lines
|
|
101
|
+
└── tools/
|
|
102
|
+
├── bash.py Shell + safety + cd tracking 95 lines
|
|
103
|
+
├── edit.py Search-replace + diff 70 lines
|
|
104
|
+
├── read.py File reading 40 lines
|
|
105
|
+
├── write.py File writing 30 lines
|
|
106
|
+
├── glob_tool.py File search 35 lines
|
|
107
|
+
├── grep.py Content search 65 lines
|
|
108
|
+
└── agent.py Sub-agent spawning 50 lines
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Use as a Library
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from nanocoder import Agent, LLM
|
|
115
|
+
|
|
116
|
+
llm = LLM(model="kimi-k2.5", api_key="your-key", base_url="https://api.moonshot.ai/v1")
|
|
117
|
+
agent = Agent(llm=llm)
|
|
118
|
+
response = agent.chat("find all TODO comments in this project and list them")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Add Your Own Tools (~20 lines)
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from nanocoder.tools.base import Tool
|
|
125
|
+
|
|
126
|
+
class HttpTool(Tool):
|
|
127
|
+
name = "http"
|
|
128
|
+
description = "Fetch a URL."
|
|
129
|
+
parameters = {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}
|
|
130
|
+
|
|
131
|
+
def execute(self, url: str) -> str:
|
|
132
|
+
import urllib.request
|
|
133
|
+
return urllib.request.urlopen(url).read().decode()[:5000]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Commands
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
/model <name> Switch model mid-conversation
|
|
140
|
+
/compact Compress context (like Claude Code's /compact)
|
|
141
|
+
/tokens Token usage
|
|
142
|
+
/save Save session to disk
|
|
143
|
+
/sessions List saved sessions
|
|
144
|
+
/reset Clear history
|
|
145
|
+
quit Exit
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## How It Compares
|
|
149
|
+
|
|
150
|
+
| | Claude Code | Claw-Code | Aider | NanoCoder |
|
|
151
|
+
|---|---|---|---|---|
|
|
152
|
+
| Code | 512K lines (closed) | 100K+ lines | 50K+ lines | **1,300 lines** |
|
|
153
|
+
| Models | Anthropic only | Multi | Multi | **Any OpenAI-compatible** |
|
|
154
|
+
| Readable? | No | Hard | Medium | **One afternoon** |
|
|
155
|
+
| Purpose | Use it | Use it | Use it | **Understand it, build yours** |
|
|
156
|
+
|
|
157
|
+
## The Deep Dive
|
|
158
|
+
|
|
159
|
+
I wrote [7 articles](article/) breaking down Claude Code's architecture — the agent loop, tool system, context compression, streaming executor, multi-agent, and 44 hidden feature flags. If you want to understand *why* NanoCoder is designed this way, start there.
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT. Fork it, learn from it, ship something better. A mention of this project is appreciated.
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
Built by **[Yufeng He](https://github.com/he-yufeng)** · Agentic AI Researcher @ Moonshot AI (Kimi)
|
|
168
|
+
|
|
169
|
+
[Claude Code Source Analysis — 170K+ reads, 6000 bookmarks on Zhihu](https://zhuanlan.zhihu.com/p/1898797658343862272)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# NanoCoder
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [中文](README_CN.md) | [Claude Code 源码深度导读(7 篇)](article/)
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/nanocoderagent/)
|
|
6
|
+
[](https://python.org)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
[](https://github.com/he-yufeng/NanoCoder/actions)
|
|
9
|
+
|
|
10
|
+
**51万行 TypeScript → 1300 行 Python。**
|
|
11
|
+
|
|
12
|
+
我花了一个周末逆向 Claude Code 泄露的全部源码,然后把不承重的部分全扔掉,用 Python 重建了核心。结果:**Claude Code 的每一个关键架构模式,浓缩在一个下午能读完的代码库里。**
|
|
13
|
+
|
|
14
|
+
NanoCoder 不是又一个 AI 编程工具。它是一份**蓝图**,编程 Agent 领域的 [nanoGPT](https://github.com/karpathy/nanoGPT)。读懂它,fork 它,然后造你自己的。
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
$ nanocoder -m kimi-k2.5
|
|
20
|
+
|
|
21
|
+
You > 读一下 main.py,修掉拼错的 import
|
|
22
|
+
|
|
23
|
+
> read_file(file_path='main.py')
|
|
24
|
+
> edit_file(file_path='main.py', ...)
|
|
25
|
+
|
|
26
|
+
--- a/main.py
|
|
27
|
+
+++ b/main.py
|
|
28
|
+
@@ -1 +1 @@
|
|
29
|
+
-from utils import halper
|
|
30
|
+
+from utils import helper
|
|
31
|
+
|
|
32
|
+
修好了:halper → helper。
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 你能得到什么
|
|
36
|
+
|
|
37
|
+
Claude Code 51 万行源码提炼出来的 7 个核心模式:
|
|
38
|
+
|
|
39
|
+
| 设计模式 | Claude Code | NanoCoder |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| 搜索替换编辑(唯一匹配 + diff) | FileEditTool | `tools/edit.py` — 70 行 |
|
|
42
|
+
| 并行工具执行 | StreamingToolExecutor(530行) | `agent.py` — ThreadPool |
|
|
43
|
+
| 三层上下文压缩 | HISTORY_SNIP → Microcompact → CONTEXT_COLLAPSE | `context.py` — 145 行 |
|
|
44
|
+
| 子代理隔离上下文 | AgentTool(1,397行) | `tools/agent.py` — 50 行 |
|
|
45
|
+
| 危险命令拦截 | BashTool(1,143行) | `tools/bash.py` — 95 行 |
|
|
46
|
+
| 会话持久化 | QueryEngine(1,295行) | `session.py` — 65 行 |
|
|
47
|
+
| 动态系统提示词 | prompts.ts(914行) | `prompt.py` — 35 行 |
|
|
48
|
+
|
|
49
|
+
每个模式都是可运行的实现,不是流程图,不是博客文章。
|
|
50
|
+
|
|
51
|
+
## 安装
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install nanocoderagent
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
选你的模型,任何 OpenAI 兼容 API 都行:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Kimi K2.5
|
|
61
|
+
export OPENAI_API_KEY=你的key OPENAI_BASE_URL=https://api.moonshot.ai/v1
|
|
62
|
+
nanocoder -m kimi-k2.5
|
|
63
|
+
|
|
64
|
+
# Claude Opus 4.6(通过 OpenRouter)
|
|
65
|
+
export OPENAI_API_KEY=你的key OPENAI_BASE_URL=https://openrouter.ai/api/v1
|
|
66
|
+
nanocoder -m anthropic/claude-opus-4-6
|
|
67
|
+
|
|
68
|
+
# OpenAI GPT-5
|
|
69
|
+
export OPENAI_API_KEY=sk-...
|
|
70
|
+
nanocoder -m gpt-5
|
|
71
|
+
|
|
72
|
+
# DeepSeek V3
|
|
73
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://api.deepseek.com
|
|
74
|
+
nanocoder -m deepseek-chat
|
|
75
|
+
|
|
76
|
+
# Qwen 3.5
|
|
77
|
+
export OPENAI_API_KEY=sk-... OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
78
|
+
nanocoder -m qwen-max
|
|
79
|
+
|
|
80
|
+
# Ollama(本地)
|
|
81
|
+
export OPENAI_API_KEY=ollama OPENAI_BASE_URL=http://localhost:11434/v1
|
|
82
|
+
nanocoder -m qwen3:32b
|
|
83
|
+
|
|
84
|
+
# 单次模式
|
|
85
|
+
nanocoder -p "给 parse_config() 加上错误处理"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## 架构
|
|
89
|
+
|
|
90
|
+
整个项目一目了然:
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
nanocoder/
|
|
94
|
+
├── cli.py REPL + 命令 160 行
|
|
95
|
+
├── agent.py Agent 循环 + 并行执行 120 行
|
|
96
|
+
├── llm.py 流式客户端 + 重试 150 行
|
|
97
|
+
├── context.py 三层压缩 145 行
|
|
98
|
+
├── session.py 会话保存/恢复 65 行
|
|
99
|
+
├── prompt.py 系统提示词 35 行
|
|
100
|
+
├── config.py 环境变量配置 30 行
|
|
101
|
+
└── tools/
|
|
102
|
+
├── bash.py Shell + 安全 + cd 追踪 95 行
|
|
103
|
+
├── edit.py 搜索替换 + diff 70 行
|
|
104
|
+
├── read.py 文件读取 40 行
|
|
105
|
+
├── write.py 文件写入 30 行
|
|
106
|
+
├── glob_tool.py 文件搜索 35 行
|
|
107
|
+
├── grep.py 内容搜索 65 行
|
|
108
|
+
└── agent.py 子代理生成 50 行
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 当库用
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
from nanocoder import Agent, LLM
|
|
115
|
+
|
|
116
|
+
llm = LLM(model="kimi-k2.5", api_key="your-key", base_url="https://api.moonshot.ai/v1")
|
|
117
|
+
agent = Agent(llm=llm)
|
|
118
|
+
response = agent.chat("找出项目里所有 TODO 注释并列出来")
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## 加自定义工具(约 20 行)
|
|
122
|
+
|
|
123
|
+
```python
|
|
124
|
+
from nanocoder.tools.base import Tool
|
|
125
|
+
|
|
126
|
+
class HttpTool(Tool):
|
|
127
|
+
name = "http"
|
|
128
|
+
description = "请求一个 URL。"
|
|
129
|
+
parameters = {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}
|
|
130
|
+
|
|
131
|
+
def execute(self, url: str) -> str:
|
|
132
|
+
import urllib.request
|
|
133
|
+
return urllib.request.urlopen(url).read().decode()[:5000]
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## 命令
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
/model <名称> 切换模型
|
|
140
|
+
/compact 压缩上下文(对标 Claude Code 的 /compact)
|
|
141
|
+
/tokens 查看 token 用量
|
|
142
|
+
/save 保存会话
|
|
143
|
+
/sessions 列出已保存的会话
|
|
144
|
+
/reset 清空历史
|
|
145
|
+
quit 退出
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## 对比
|
|
149
|
+
|
|
150
|
+
| | Claude Code | Claw-Code | Aider | NanoCoder |
|
|
151
|
+
|---|---|---|---|---|
|
|
152
|
+
| 代码量 | 51万行(闭源) | 10万+行 | 5万+行 | **1300 行** |
|
|
153
|
+
| 模型 | 仅 Anthropic | 多模型 | 多模型 | **任意 OpenAI 兼容** |
|
|
154
|
+
| 能通读吗? | 不能 | 很难 | 有点费劲 | **一个下午** |
|
|
155
|
+
| 适合 | 直接用 | 直接用 | 直接用 | **先看懂,再造自己的** |
|
|
156
|
+
|
|
157
|
+
## 源码导读
|
|
158
|
+
|
|
159
|
+
我还写了 [7 篇 Claude Code 架构深度导读](article/):Agent 循环、工具系统、上下文压缩、流式执行、多 Agent、隐藏功能。想知道 NanoCoder 为什么这样设计,从那里开始。
|
|
160
|
+
|
|
161
|
+
## License
|
|
162
|
+
|
|
163
|
+
MIT。Fork,然后拿去造更好的东西,如果能标注此出处就更好了。
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
作者 **[何宇峰](https://github.com/he-yufeng)** · Agentic AI Researcher @ Moonshot AI (Kimi)
|
|
168
|
+
|
|
169
|
+
[Claude Code 源码分析(知乎 17 万阅读,6000收藏)](https://zhuanlan.zhihu.com/p/1898797658343862272)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Claude Code 源码导读
|
|
2
|
+
|
|
3
|
+
2026 年 3 月 31 日,Anthropic 的 npm 包里残留的 `.map` 文件泄露了 Claude Code 的全部源码。1903 个文件,512,664 行 TypeScript。
|
|
4
|
+
|
|
5
|
+
这是我读完全部源码后写的系列文章。不是面面俱到的文档(那个有 16 万字的完整版),而是我认为最值得开发者了解的 7 个切面。每篇都围绕一个核心问题展开,代码引用精确到行号。
|
|
6
|
+
|
|
7
|
+
如果你在做 AI Agent 相关的工作,这些设计模式迟早会用到。
|
|
8
|
+
|
|
9
|
+
## 目录
|
|
10
|
+
|
|
11
|
+
1. **[从 51 万行说起](01-architecture-overview.md)** — Claude Code 的技术栈、目录结构、十大设计哲学。建立全局心智模型。
|
|
12
|
+
2. **[1729 行的 while(true)](02-agent-loop.md)** — AI Agent 的核心循环:query.ts 如何驱动工具调用、消息编排、中断恢复。
|
|
13
|
+
3. **[让 AI 安全地改你的代码](03-tool-system.md)** — 工具系统的接口设计、两阶段门控、搜索替换编辑的精妙之处。
|
|
14
|
+
4. **[有限窗口,无限任务](04-context-compression.md)** — 四层上下文压缩策略的工程细节,以及它为什么不是简单的"截断旧消息"。
|
|
15
|
+
5. **[边想边做](05-streaming-executor.md)** — StreamingToolExecutor 如何在模型还没说完的时候就开始执行工具。
|
|
16
|
+
6. **[当一个 Claude 不够用](06-multi-agent.md)** — 多 Agent 协作系统:子代理生成、Worktree 隔离、团队编排。
|
|
17
|
+
7. **[Feature Flag 背后的秘密](07-hidden-features.md)** — 44 个未发布功能的技术细节:KAIROS 永驻模式、Buddy 宠物系统、Voice Mode、Bridge Mode。
|
|
18
|
+
|
|
19
|
+
## 配套项目
|
|
20
|
+
|
|
21
|
+
这些文章中讨论的核心架构模式,我用 1300 行 Python 做了一个可运行的参考实现:[NanoCoder](https://github.com/he-yufeng/NanoCoder)。代码和文章可以对照着看。
|
|
22
|
+
|
|
23
|
+
## 完整版
|
|
24
|
+
|
|
25
|
+
如果你想要更详尽的版本(16 篇、16 万字、覆盖构建系统到 MCP 协议的每个子系统),完整导读在[这里](https://github.com/he-yufeng/NanoCoder/tree/main/docs)。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
作者:[何宇峰](https://github.com/he-yufeng) · [知乎:Claude Code 源码分析(17万+ 阅读)](https://zhuanlan.zhihu.com/p/1898797658343862272)
|