Skip to content

Commit 18212a9

Browse files
Copilotzhimin-z
andauthored
Redesign README with a visually appealing layout
Agent-Logs-Url: https://github.com/Engineering4AI/AutoHarness/sessions/41c799bc-19cc-4b51-a054-76f308ff2c92 Co-authored-by: zhimin-z <8592144+zhimin-z@users.noreply.github.com>
1 parent e750756 commit 18212a9

1 file changed

Lines changed: 99 additions & 98 deletions

File tree

README.md

Lines changed: 99 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,57 @@
11
# AutoHarness
22

3-
A self-evolving coding agent in Rust — the smallest possible implementation that actually works. This README reflects the current evolution iteration of the agent.
3+
<p align="center">
4+
<strong>A self-evolving coding agent in Rust.</strong><br/>
5+
Chat with it, let it reflect, and let it improve itself.
6+
</p>
47

5-
<img width="1200" height="800" alt="AutoResearch" src="https://github.com/user-attachments/assets/805635cc-88d4-4f26-9467-07ef8ca99b7b" />
8+
<p align="center">
9+
<img alt="Rust" src="https://img.shields.io/badge/Rust-stable-orange?logo=rust"/>
10+
<img alt="Single binary" src="https://img.shields.io/badge/Architecture-single--binary-blue"/>
11+
<img alt="Self evolving" src="https://img.shields.io/badge/Mode-self--evolving-purple"/>
12+
</p>
613

7-
The agent has two modes: an interactive CLI where you give it tasks, and a self-evolution loop where it reads its own source, proposes improvements, verifies them, and repeats. The LLM is the judge — no numeric scoring.
14+
<p align="center">
15+
<img width="1100" alt="AutoHarness" src="https://github.com/user-attachments/assets/805635cc-88d4-4f26-9467-07ef8ca99b7b" />
16+
</p>
817

9-
## How it works
18+
---
19+
20+
## ✨ What is AutoHarness?
21+
22+
AutoHarness is a compact Rust agent with two modes:
23+
24+
- **Interactive chat mode** for normal task execution
25+
- **Evolution mode** where it reflects on trajectories and rewrites parts of itself
26+
27+
It logs everything, verifies self-edits with `cargo build --release`, and uses the LLM as the judge (no numeric reward model).
28+
29+
---
30+
31+
## 🚀 Quick Start
32+
33+
```bash
34+
# Build
35+
cargo build --release
36+
37+
# Run chat mode
38+
./target/release/auto-harness
39+
40+
# Run evolution mode
41+
./target/release/auto-harness evolve
42+
```
43+
44+
Use any OpenAI-compatible backend:
45+
46+
```bash
47+
export OPENROUTER_API_KEY=anything
48+
export INFERENCE_BASE_URL=http://localhost:11434/v1
49+
export MODEL_NAME=llama3
50+
```
51+
52+
---
53+
54+
## 🧠 How It Works
1055

1156
```mermaid
1257
flowchart TD
@@ -15,143 +60,99 @@ flowchart TD
1560
B -->|evolve| D[evolve mode]
1661
1762
C --> C1[async stdin queue]
18-
C1 --> C2[LLM judge: NEW task or CONTINUE?]
19-
C2 --> C3[send to LLM print reply]
63+
C1 --> C2[LLM judge: NEW or CONTINUE]
64+
C2 --> C3[send to LLM and print reply]
2065
C3 --> C4[run tool if present]
2166
C4 --> C1
2267
2368
D --> D1[reflect on unprocessed trajs]
24-
D1 --> D2[evolution loop\nup to MAX_ITERS]
69+
D1 --> D2[evolution loop up to MAX_ITERS]
2570
D2 --> D3{LLM reply}
2671
D3 -->|SKIP| D5[exit loop]
2772
D3 -->|write_self| D4[backup → write → cargo build]
28-
D4 -->|fail| D6[restore + report error to LLM]
73+
D4 -->|fail| D6[restore and report error]
2974
D6 --> D2
3075
D4 -->|pass| D8{improved?}
3176
D3 -->|write_file| D9[write prompts / AGENTS.md]
3277
D9 --> D8
33-
D8 -->|yes: reset streak| D2
34-
D8 -->|no: streak++| D10{streak ≥ PATIENCE?}
35-
D10 -->|no| D2
36-
D10 -->|yes| D5
78+
D8 -->|yes| D2
79+
D8 -->|no and streak >= PATIENCE| D5
3780
D5 --> D7[doc update: CLAUDE.md + README.md]
3881
D7 --> D11[cargo clippy -D warnings]
3982
D11 --> D12[cargo test --release]
40-
D12 --> D13[log lint_result + test_result to traj]
4183
```
4284

43-
### Chat mode
85+
---
4486

45-
Interactive REPL. Stdin is read in a background thread and pushed to a queue so you can keep typing while the LLM is processing. Each reply is printed; everything else is logged to `.evo/sessions/<ts>/traj.jsonl`.
87+
## 🔧 Modes
4688

47-
The LLM automatically groups your messages into tasks — if a new message starts a different topic, artifacts go into a new `outputs/<ts>/task_N` directory.
89+
### Chat Mode (default)
90+
- REPL with async stdin queue (`VecDeque`)
91+
- LLM decides if each message starts a **new task** or **continues** the current one
92+
- Artifacts are separated into `outputs/<ts>/task_N`
93+
- Events are logged to `.evo/sessions/<ts>/traj.jsonl`
4894

49-
### Evolve mode
95+
### Evolve Mode (`auto-harness evolve`)
96+
1. **Reflect:** analyze unprocessed trajectories and produce one concrete improvement
97+
2. **Evolve:** iterate up to `MAX_ITERS`, applying one LLM-proposed change per iteration
98+
3. **Doc update:** rewrite `CLAUDE.md` and `README.md`
99+
4. **Validate:** run `cargo clippy -- -D warnings` and `cargo test --release`
50100

51-
1. **Reflect** — reads chat session trajs newer than the last watermark, asks the LLM for one concrete improvement suggestion, logs it.
52-
2. **Evolve** — up to `MAX_ITERS` iterations. Each iteration: show LLM current `src/main.rs` and `src/AGENTS.md` → propose one change → verify with `cargo build`. Stops on `SKIP` or `PATIENCE` consecutive non-improving iters.
53-
3. **Doc update** — after the loop, the LLM rewrites `CLAUDE.md` and `README.md` to match the current implementation.
54-
4. **Lint + test**`cargo clippy -- -D warnings` then `cargo test --release`; results logged to traj; failures print a WARNING to stderr.
101+
---
55102

56-
### What the agent can evolve
103+
## 🧩 Evolvable Artifacts
57104

58-
Beyond just its own source code, the agent can improve all of these via `write_file`:
59-
60-
| Artifact | Purpose |
105+
| Artifact | How it evolves |
61106
|---|---|
62-
| `src/main.rs` | Core agent logic (atomic rewrite with build verification) |
63-
| `src/AGENTS.md` | Agent orchestration best practices guide |
64-
| `src/prompts/chat_system.txt` | Chat mode persona and rules |
65-
| `src/prompts/reflect_system.txt` | Trajectory analysis instructions |
66-
| `src/prompts/evolve_system.txt` | Evolution loop instructions |
67-
| `src/prompts/doc_system.txt` | Doc update instructions |
107+
| `src/main.rs` | `write_self` (atomic rewrite + build verification) |
108+
| `src/AGENTS.md` | `write_file` |
109+
| `src/prompts/chat_system.txt` | `write_file` |
110+
| `src/prompts/reflect_system.txt` | `write_file` |
111+
| `src/prompts/evolve_system.txt` | `write_file` |
112+
| `src/prompts/doc_system.txt` | `write_file` |
113+
| `CLAUDE.md` | `write_file` (doc update step) |
114+
| `README.md` | `write_file` (doc update step) |
68115

69-
### Tool dispatch
116+
---
70117

71-
The LLM emits plain-text XML-like tags — no framework, no function-calling schema:
118+
## 🗂️ Project Layout
72119

73-
```
74-
<tool name="shell">cargo test 2>&1</tool>
75-
<tool name="write_self">...full new src/main.rs...</tool>
76-
<tool name="write_file">path/to/file
77-
...full content...</tool>
78-
```
79-
80-
`write_self` is atomic: backup → write → `cargo build --release` → restore on failure, reporting the exact compiler error back to the LLM so it can self-correct.
81-
82-
### Progressive disclosure
83-
84-
Every LLM call site is bounded — no unbounded context growth:
85-
86-
- **Reflection**: traj stripped to metadata-only (no content blobs), capped at 8 000 chars
87-
- **Task judge**: last 6 messages only
88-
- **Chat history**: sliding window of 20 messages
89-
- **Shell output**: capped at 2 000 chars
90-
- **Build errors**: capped at 400 chars
91-
92-
## Installation
93-
94-
```bash
95-
# Install Rust (if not already installed)
96-
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
97-
source $HOME/.cargo/env
98-
99-
# Clone the repository
100-
git clone https://github.com/Engineering4AI/AutoHarness
101-
cd AutoHarness
102-
103-
# Set API key
104-
echo "OPENROUTER_API_KEY=sk-or-..." > .env
105-
106-
# Build and run
107-
cargo build --release
108-
./target/release/auto-harness # interactive chat
109-
./target/release/auto-harness evolve # self-evolution loop
110-
```
111-
112-
Any OpenAI-compatible endpoint works (Ollama, vLLM, Together, etc.):
113-
114-
```bash
115-
export OPENROUTER_API_KEY=anything
116-
export INFERENCE_BASE_URL=http://localhost:11434/v1
117-
export MODEL_NAME=llama3
118-
```
119-
120-
## File layout
121-
122-
```
120+
```text
123121
.
124122
├── Cargo.toml
123+
├── README.md
124+
├── CLAUDE.md
125125
├── src/
126-
│ ├── main.rs # the entire agent (~420 lines)
127-
│ ├── AGENTS.md # agent orchestration guide (self-evolving)
126+
│ ├── main.rs
127+
│ ├── AGENTS.md
128128
│ └── prompts/
129-
│ ├── chat_system.txt # chat mode system prompt
129+
│ ├── chat_system.txt
130130
│ ├── reflect_system.txt
131131
│ ├── evolve_system.txt
132132
│ └── doc_system.txt
133-
├── .env # API keys (not committed)
134133
├── .evo/
135-
│ ├── sessions/<ts>/ # one dir per run, contains traj.jsonl
136-
│ └── learned_until.txt # reflection watermark
137-
└── outputs/<ts>/
138-
├── task_1/ # artifacts for task 1
139-
└── task_2/ # artifacts for task 2 (if new task detected)
134+
│ ├── sessions/<ts>/traj.jsonl
135+
│ └── learned_until.txt
136+
└── outputs/<ts>/task_N
140137
```
141138

142-
## Configuration
139+
---
140+
141+
## ⚙️ Configuration
143142

144143
| Variable | Default | Description |
145144
|---|---|---|
146-
| `OPENROUTER_API_KEY` | | OpenRouter key (required) |
147-
| `INFERENCE_BASE_URL` | `https://openrouter.ai/api/v1` | Any OpenAI-compat base URL |
145+
| `OPENROUTER_API_KEY` | required | API key |
146+
| `INFERENCE_BASE_URL` | `https://openrouter.ai/api/v1` | OpenAI-compatible API endpoint |
148147
| `MODEL_NAME` | `anthropic/claude-opus-4` | Model identifier |
149148

150-
`MAX_ITERS` (default `10`) and `PATIENCE` (default `3`) are compile-time constants in `src/main.rs`.
149+
Core constants in `src/main.rs`:
150+
- `MAX_ITERS = 10`
151+
- `PATIENCE = 3`
151152

152-
## Citation
153+
---
153154

154-
If you use AutoHarness in your research, please cite:
155+
## 📚 Citation
155156

156157
```bibtex
157158
@software{autoharness2026,

0 commit comments

Comments
 (0)