Open-source project
principia-ai/WriteHERE avatar
principia-ai/WriteHERE

WriteHERE: recursive planning for long-form generation, and what its engine actually requires

An Open-Source AI Writing Project.

976 stars145 forksPythonLicense varies

At a glance

What is it?
WriteHERE is a Python framework that interleaves recursive task decomposition with execution for fiction and technical report writing. Its README describes a two-mode engine, a Flask backend with a React frontend, and a dependency on three external API keys.
Who is it for?
Adopt WriteHERE if you need a research-grade, inspectable planning engine for long-form fiction or report generation and you already hold OpenAI, Anthropic, and SerpAPI credentials, since the README lists all three as prerequisites and the report mode depends on search. Do not adopt it if you need a stable released artifact, a documented Python version policy beyond 3.6+, or a workflow that runs without external model calls.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 12 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap WriteHERE targets is planning, not prose

Most AI writing tools described in the README follow what it calls predetermined workflows: a fixed pipeline of outline, draft, revise. WriteHERE's stated premise is that long-form writing needs the plan itself to change while the work is underway. The project frames this as three capabilities working together: recursive planning, which breaks a writing task into subtasks; heterogeneous integration, which mixes retrieval, reasoning, and composition inside one run; and dynamic adaptation, which adjusts the process as context accumulates. The audience is narrow and specific. This is for researchers and engineers who want to inspect and modify how a long document gets decomposed, and who are comfortable running a Python engine from the command line or standing up a Flask backend plus a React frontend to watch the process. It is not aimed at someone who wants a hosted editor. The README states the project is non-commercial and developed for research and educational purposes, which sets expectations about support and release cadence rather than about the licence, which is MIT.

Recursive decomposition interleaved with execution

The mechanism the README describes is a planning loop that alternates between decomposing a task and executing the pieces, rather than committing to a full plan up front. The repository layout supports this reading: recursive/ holds the core engine, with recursive/agent/ for agent implementation and prompts and recursive/executor/ for task execution. That split matters if you intend to change behaviour. Prompt changes live in one directory and execution logic in another, so a new task type is not necessarily a change to the planner. The engine takes a mode flag that selects between story and report, and the two modes differ in what they pull in. Report generation uses SerpAPI for search, which the README lists as a prerequisite, while the story path is exercised against test_data/meta_fiction.jsonl in the documented example. The claim that this approach outperforms state-of-the-art methods across evaluation metrics comes from the project's own evaluations, and the paper is cited as arXiv 2503.08275, accepted as an oral presentation at EMNLP 2025. Treat that as the authors' reported result, not an independent measurement.

Running the engine without the interface

The simplest path skips the web stack. Create a virtual environment, install the package in editable mode, copy the API key template, and edit it. The README gives these commands: python -m venv venv, source venv/bin/activate, pip install -v -e ., then cp recursive/api_key.env.example recursive/api_key.env followed by editing that file. With keys in place, the engine runs from the recursive directory: python engine.py --filename <input_file> --output-filename <output_file> --done-flag-file <done_file> --model <model_name> --mode <story|report>. The documented story example passes ../test_data/meta_fiction.jsonl, writes to ./project/story/output.jsonl, uses ./project/story/done.txt as the done flag, and specifies gpt-4o. The report example passes ../test_data/qa_test.jsonl, writes ./project/qa/result.jsonl, and specifies claude-3-sonnet. The done-flag file is the detail worth noticing. It implies the engine is expected to be polled or wrapped by something else, which fits batch processing more than interactive use.

The visualization path and its two servers

For real-time visualization the README offers a one-step route: ./setup_env.sh once, then ./start.sh. According to the documentation this creates a clean Python virtual environment, installs dependencies, starts the backend on port 5001 and the frontend on port 3000, and opens a browser at localhost:3000. Both ports are configurable, as in ./start.sh --backend-port 8080 --frontend-port 8000. Anaconda users are directed to ./run_with_anaconda.sh, which creates an environment named writehere and accepts the same port arguments. The manual route is more explicit about the moving parts: pip install -r backend/requirements.txt, then python server.py from the backend directory (with --port for a custom port), and separately npm install and npm start in the frontend directory, where PORT=8000 npm start changes the frontend port. Two runtimes, two dependency trees, and three API keys is the real cost of the visual mode. If you only need generated output files, the engine-only path avoids the Node.js requirement entirely.

Keys, versions, and the missing release history

Three external services are named as prerequisites: OpenAI for GPT models, Anthropic for Claude models, and SerpAPI for search in report generation. The README does not describe fallback behaviour when a key is absent, so whether report mode degrades or fails is not stated in the material available. The stated Python floor is 3.6+, which is unusually permissive for a project whose dependencies include a Flask backend and a React frontend; the README does not pin a tested upper bound, and the Anaconda script exists precisely because dependency conflicts occur. There are no retrieved releases, so there is no version to pin and no changelog to read. The last push is dated 2026-09-03, but without releases the practical upgrade path is tracking the main branch, which means a git pull can change prompt files under recursive/agent/ without a version number to signal it. Budget for re-reading diffs in that directory before pulling, particularly if you have local prompt modifications.

Where the framework is the wrong instrument

The clearest failure mode is cost and latency under recursive decomposition. Every split and every subtask is a model call, and the README does not describe a budget cap, a maximum recursion depth, or a token accounting mechanism. For a short piece, a single-pass generation with one prompt is cheaper and easier to reason about; the planning overhead only pays off when the document is long enough that a fixed outline would need rewriting. The second limitation is reproducibility. Dynamic adaptation means the plan depends on what the model returns mid-run, so two runs with the same input file and the same --model flag are not guaranteed to produce the same structure. If you need deterministic output for regression tests, this design works against you. Third, the README's evaluation claim covers fiction and technical report generation. Nothing in the supplied material indicates the framework has been assessed on code documentation, legal drafting, or structured data-to-prose tasks, and the two modes are the only ones the engine exposes.

How this differs from a LangChain-style chain

The obvious comparison is a general agent framework such as LangChain, where you compose a chain or graph of steps in advance and the runtime follows it. WriteHERE inverts that. The plan is an output of the run rather than an input to it, which is why the README frames predetermined workflows as the thing being eliminated. The practical difference shows up when the task changes shape halfway through: a fixed chain needs a branch you wrote in advance, while a recursive planner can decompose a newly discovered subtask at the point it appears. The trade is control. With a hand-built chain you can read the graph and know every path; with WriteHERE you read the prompts in recursive/agent/ and the executor in recursive/executor/ and reason about behaviour indirectly, then watch the run through the frontend to see what it decided. That is a real cost for teams that need to explain why a document came out the way it did. The paper, arXiv 2503.08275, is the place to look for the evaluation methodology behind the outperformance claim.

Licence and what to confirm before relying on it

The README states the project is MIT licensed and the badge links to opensource.org/licenses/MIT, but the repository metadata supplied here lists the licence as unknown, so confirm the LICENSE file in the tree before you depend on the terms. MIT is permissive, which permits commercial use even though the project describes itself as non-commercial and research-oriented; the two statements are not in conflict, but the non-commercial framing tells you where maintainer attention goes. Verify three things first. That recursive/api_key.env.example matches the key names your accounts issue, since the README only says to edit the file. That the engine actually writes both the output file and the done-flag file for your input, which the story example against test_data/meta_fiction.jsonl will demonstrate. And that TROUBLESHOOTING.md covers whichever of the two installation paths you chose, because the Anaconda script's existence suggests dependency resolution is the most common place this setup breaks.

Editorial conclusion

Adopt WriteHERE if you need a research-grade, inspectable planning engine for long-form fiction or report generation and you already hold OpenAI, Anthropic, and SerpAPI credentials, since the README lists all three as prerequisites and the report mode depends on search. Do not adopt it if you need a stable released artifact, a documented Python version policy beyond 3.6+, or a workflow that runs without external model calls. Before committing, verify that recursive/api_key.env.example maps cleanly onto your key names, run the story example against test_data/meta_fiction.jsonl to confirm the engine writes the output and done-flag files as described, and check TROUBLESHOOTING.md for the failure mode you are most likely to hit.

Official sources

  1. Issues
  2. principia-ai/WriteHERE on GitHub
  3. Project website
  4. README
Community notes

Community notes