Skip to content

DenSmolonski/threadmill

Repository files navigation

Threadmill

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.

How it works

Three levels, each nested inside the last:

  1. Turn (run.sh) — a single agent call. It does one step of work, then its context ends.
  2. Loop (loop.sh) — repeats turns in the same working directory until a STOP file 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.
  3. Meta loop (meta_loop.sh) — when a loop stops, this spins up a new generation_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.

Quickstart

Copy the SDK into its own directory for your experiment:

cp -R threadmill my_experiment
cd my_experiment

Write 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 ends

To stop a generation in progress:

printf 'done\n' > STOP

Need 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.

Choosing a harness

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.sh

Configuration 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.sh

That 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 as provider: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.sh

Writing your own harness

A 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.

What's in the SDK

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.

Attribution

Threadmill is an English-language fork of anima_sdk.

License

MIT — see LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages