Threadmill is a scaffold for running an agent on tasks that outlive a single context window. It's built on the Ralph loop: call an agent over and over with the same prompt, and let it carry state forward in files instead of in memory. Threadmill adds one thing on top of that — a meta loop that gives the agent a fresh start whenever its current run has hit a dead end.
Three levels, each nested inside the last:
- Turn (
run.sh) — a single agent call. It does one step of work, then its context ends. - Loop (
loop.sh) — repeats turns in the same working directory until aSTOPfile shows up. Nothing survives in the agent's memory between turns; everything that matters is written to disk (NOTES.md,TODO.md,STATE.md, the code itself). That's what lets the loop run indefinitely without running out of context. - Meta loop (
meta_loop.sh) — when a loop stops, this spins up a newgeneration_N/directory and starts a fresh loop inside it. Think of it as a generation restart: if a run accumulates noise, wanders into a dead end, or just collapses, the task itself survives and picks back up clean.
Copy the SDK into its own directory for your experiment:
cp -R threadmill my_experiment
cd my_experimentWrite down what you want done in MAIN_GOAL.md, adjust AGENTS.md if you
need to, then pick how you want to run it:
./run.sh # one agent turn
./loop.sh # keep looping turns until STOP
./meta_loop.sh # loop across generations, restarting on dead endsTo stop a generation in progress:
printf 'done\n' > STOPNeed to send a running agent a note mid-task? Drop it in INBOX.md — this
SDK's agent instructions have it read that file at the start of every turn.
run.sh doesn't run the agent directly — it drives an adapter under
harnesses/. Pick one with THREADMILL_HARNESS:
THREADMILL_HARNESS=free_code bash meta_loop.sh
THREADMILL_HARNESS=claude THREADMILL_MODEL=claude-opus-4-7 bash meta_loop.sh
THREADMILL_HARNESS=codex THREADMILL_MODEL=gpt-5.5 bash meta_loop.sh
THREADMILL_HARNESS=deepagents THREADMILL_MODEL=openai:gpt-4o bash meta_loop.shConfiguration can live in a local threadmill.env (copy
threadmill.env.example to start), or you can skip the built-in harnesses
entirely and point at your own CLI:
THREADMILL_HARNESS_CMD='my-agent --task-file "$THREADMILL_PROMPT_FILE"' bash run.shThat command runs via bash -lc from inside the task directory. The task
text is available both on stdin and at the path in $THREADMILL_PROMPT_FILE.
Note on
deepagents: its model must be given asprovider:model(e.g.openai:gpt-4o,anthropic:claude-opus-4-7,gigachat:GigaChat-3-Ultra) — in non-interactive mode the CLI has no default to fall back on.
You can also override the binary or pass extra args per harness:
THREADMILL_CLAUDE_BIN=/path/to/claude THREADMILL_CLAUDE_ARGS='--permission-mode bypassPermissions' bash run.sh
THREADMILL_FREE_CODE_BIN=/path/to/free-code bash run.sh
THREADMILL_CODEX_BIN=/path/to/codex THREADMILL_CODEX_ARGS='--full-auto' bash run.sh
THREADMILL_DEEPAGENTS_BIN=/path/to/deepagents THREADMILL_DEEPAGENTS_ARGS='--mcp-config ./mcp.json' bash run.shA harness is just harnesses/name.sh, and it needs to:
- run from the task directory
- read the prompt path from
THREADMILL_PROMPT_FILE - read the task directory from
THREADMILL_TASK_DIR - optionally read the model from
THREADMILL_MODEL - write its output to stdout/stderr
- exit non-zero if the run failed
Once that's in place, use it with THREADMILL_HARNESS=name bash meta_loop.sh.
| Path | What it's for |
|---|---|
MAIN_GOAL.md |
Template for describing the long-running task |
AGENTS.md |
Rules that shape how the agent behaves |
run.sh |
A single agent turn |
loop.sh |
The Ralph loop — repeats run.sh until STOP |
meta_loop.sh |
The meta loop — manages generation_N/ directories |
harnesses/ |
Adapters: free-code, claude, codex, deepagents, agy, custom |
threadmill.env.example |
Example local configuration |
examples/ |
Public experiments built on this SDK |
Runtime artifacts — STOP, INBOX.md, .free-code-logs/, a local
threadmill.env, .DS_Store — aren't meant to be committed to the SDK
itself. generation_N/ directories are fair game to commit if you want to
preserve an experiment's history, as the examples do.
Threadmill is an English-language fork of
anima_sdk.
MIT — see LICENSE.