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

WriteHERE lets the planner write the plan, and its licence is claimed in a badge with no licence file in the tree

An Open-Source AI Writing Project.

975 stars146 forksPythonLicense varies

At a glance

What is it?
A research framework for long-form writing that interleaves task decomposition with execution and shows the agent's plan as a graph. The dependency file pins its web layer to 2020 releases, names a third model provider nobody is told to get a key for, and the demo link is a bare cloud address.
Who is it for?
Judge it as a research artifact from a conference paper, because that is what it is, and the value is in seeing a planner whose decomposition is produced by the same model that does the writing. The graph and cache files are the parts to read if you are building something similar.
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 30 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 October 3, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A permissive licence and a non-commercial intent in the same list

The open source philosophy section is a four item list, and two of the items contradict each other. The first says all code is freely available for use, modification and distribution under the MIT License, and the MIT badge sits in the same header block. The second says the project is non-commercial and was developed for research and educational purposes without commercial interests.

MIT permits commercial use. Both statements cannot be the licensing position, and neither is a licence. In the repository, no licence name is recorded and no licence file appears at the top level, which holds a readme, a setup script, a shell launcher, a shell launcher for a specific package manager, a setup file, a configuration file, three project directories, a data directory, a troubleshooting document and an image.

So the permissive grant is asserted in prose and a badge, and the restriction that would override it is stated in the same bullet list. For a research project that is a reasonable thing to say informally. For anyone who intends to build on it, it needs a real answer from the authors.

The demo link is a bare cloud address

The header carries four badges. Three of them are conventional: a link to the paper on a preprint server, a link to the permissive licence page, and a link to the project's own page hosted as repository documentation.

The fourth is a bare hostname with a numeric address, an elastic compute instance in one region, reachable over plain HTTP with no domain name. It sits in the same badge row as the paper link, which means a live demo server on somebody's cloud account is presented the same way as a citation.

A hosted demo is genuinely useful in a research project, and this one is presumably there so reviewers can see the planner run. The problem is durability rather than intent. A raw compute address disappears when the instance is stopped, has no certificate, and says nothing about who maintains it. The project page and the paper are the links that will still resolve in a year.

A third model provider is required, and no key for it is documented

The prerequisite list asks for three API keys, and two of them are for model providers: one for the OpenAI family and one for the Anthropic family. The third is a search API, described as being for search functionality in report generation.

The dependency file disagrees. It requires the Google generative client library, pinned to a minimum version, alongside the OpenAI and Anthropic clients. So a Google model provider is a hard install requirement while nothing in the setup asks you to configure it, and the two documented working examples use one of the other two providers.

Two more requirements have no documented purpose at all. The AWS command line interface and its core library are both required, and neither the feature list nor the setup mentions object storage, queuing, or anything else that would need them. Combined with a text extraction library, a search library, a text splitter, a documentation parser, a registry helper, a serialisation library and a logging library, the dependency list is much wider than the feature set describes.

The web layer is pinned to 2020 releases, and test tools are in the same file

The dependency file is organised with comment headers into core, web and API, and development sections. The web section is where the age shows. The web framework is pinned to an exact version from 2020, its underlying toolkit to another exact 2020 version, the cross-origin extension to a fixed release, and the production server to a fixed version from the same year. Every other entry in the file uses a minimum version instead.

The pattern is deliberate and it is the right one for a server that runs in someone else's cluster, since exact pins are reproducible. The problem is that four of the pinned packages are the oldest things in the file, and an assistant framework that has to be driven by a recent model client is being served by a web stack that predates the client.

The development section is the other surprise. A test runner and a rapid prototyping interface are listed there, in the same file, with no separate extras. So a plain install of the core engine also installs a test runner and a prototyping tool that the batch path never uses.

Four ways to set two ports, through three different mechanisms

The one step launcher starts two servers, a backend on one port and a frontend on another, and then opens a browser at the frontend address. Both ports can be changed, and the same two flags are accepted by the second launcher, the one that builds a dedicated environment for a specific package manager.

The manual path uses different mechanisms for the same two values. The backend takes a port as a command line flag, and the frontend takes its port as an environment variable in front of the start command. So the same two numbers are set by shell flags in one route, by a command line argument in the second, and by an environment variable in the third.

That is not a design problem so much as an artefact of the frontend being a separate project from the backend. A single configuration file shared by both would be cleaner, but as written, a reader assembling the stack by hand has to read three different sections to find out the same two defaults.

The engine takes a done-flag file, which is a batch contract

The engine is invoked directly with five positional style options, and one of them is unusual. Alongside an input file, an output file, a model name and a mode, there is a flag taking the path of a done-flag file.

That shape is for batch work rather than for an interactive session. The engine writes results to the output file, touches a marker file when it has finished, and the caller can poll for the marker. Both worked examples follow the pattern, writing into a per-project output directory and a matching done file beside it, with the input taken from a data directory one level up.

The mode is the other meaningful option, with two values:

bash
python engine.py --filename ../test_data/meta_fiction.jsonl --output-filename ./project/story/output.jsonl --done-flag-file ./project/story/done.txt --model gpt-4o --mode story

So the two modes are not just prompt variants. The story example points at a meta-fiction data file and a current OpenAI model, while the report example points at a question answering data file and a Claude model, so they differ in data, in provider and in code path, and the report path is the one that needs the search key.

The structure diagram stops in the middle of a comment

The project structure section is a single code block, and it ends partway through. The block lists the three top level directories, a backend, a frontend and the core engine directory, then breaks the engine directory into four subdirectories for the agent, the executor, the model integrations and the utilities, followed by four named files: a cache, the planning and execution engine, a task graph representation, and a memory module.

The last line is cut off mid-word. The memory module's description begins and stops after a few characters, and the block closes there. Nothing indicates that more entries follow, because there is no continuation marker, so a reader sees a tree that appears complete and is not.

The visible part is still the useful part, and it describes the design accurately. A separate graph file for the task representation and a separate cache file both being first class rather than buried in the agent explains how the visualisation interface gets something to show.

The setup file is five lines and the real metadata is next door

The packaging entry point is a script with a shebang, one import, and a single call with no arguments. Everything it would normally declare is not there. It exists so that an editable install works, and the metadata lives in a separate configuration file beside it.

That is a two file arrangement for something that could be one, and it means anyone reading the packaging code to find the version or the dependencies has to know to look elsewhere.

The rest of the top level explains the two run routes. Two shell launchers plus a third for a specific package manager sit next to the setup script, and the manual path depends on the directories the structure block listed. There is a troubleshooting document linked from the setup section, an image used in the header, a package-level init file at the repository root, and a data directory holding the two example input files the engine examples reference.

Editorial conclusion

Judge it as a research artifact from a conference paper, because that is what it is, and the value is in seeing a planner whose decomposition is produced by the same model that does the writing. The graph and cache files are the parts to read if you are building something similar. Two things to check before you build on it. The licence position is inconsistent, since a permissive licence and a stated non-commercial intent appear in the same list, so ask the authors rather than assume. And the dependency file is dated, with a web layer four years behind and a Google client library for a provider the setup never asks you to configure.

Frequently asked questions

What licence does WriteHERE use?

The page claims the MIT License in one bullet and MIT in a badge, while a second bullet in the same list describes the project as non-commercial. No licence name is recorded in the repository metadata and no licence file appears in the top level listing.

Which API keys does WriteHERE need?

The prerequisite list asks for keys for two model providers and one search API used in report generation, while the dependency file also requires the Google generative client library without documenting a key for it.

How do I run the WriteHERE engine without the web interface?

Install the package in a virtual environment, copy the example key file to the engine directory and fill it in, then run the engine script from that directory with an input file, an output file, a done flag file, a model name and a mode of either story or report.

Which model providers do the WriteHERE examples use?

The story example uses a current OpenAI model with a meta-fiction data file, and the report example uses a Claude model with a question answering data file, so the two modes differ in data and provider as well as in prompt.

How do I change the ports for the WriteHERE web interface?

The two shell launchers accept backend and frontend port flags, while the manual route sets the backend port as a command line argument on the server script and the frontend port as an environment variable in front of the start command.

Official sources

  1. Issues
  2. principia-ai/WriteHERE on GitHub
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/principia-ai-writehere.svg)](https://hysenlabs.com/projects/principia-ai-writehere)