{"slug": "orcrist-a-coding-agent-using-llm-state-machines", "title": "Orcrist: A Coding Agent using LLM state machines", "summary": "Orcrist is a new domain-specific language for state machines whose states are executed by an LLM, paired with a desktop coding agent that runs on it. Before touching a task, the agent writes an Orcrist machine grounded in the grammar and authoring guide read at runtime from the repo's metamodel/orcrist.langium file, then executes it one state at a time with guards deciding what happens next until a final state is reached. The project requires Node 20 or newer and an API key for Anthropic or OpenAI, or a local Ollama model that supports tool calling.", "body_md": "**Orcrist** is a DSL for state machines whose states are executed by an LLM, and a desktop coding agent that runs on it.\n\nYou give the agent a task. Before touching anything it writes an Orcrist machine for that task, grounded in the grammar and the authoring guide in this repo, and then executes that machine one state at a time. Each state's prompt goes to the model, the model works with real tools, the runtime measures what it can and records what the state is declared to report, and the machine's guards decide what happens next. The run ends when it reaches a `final` state.\n\nThe point is the one the authoring guide makes: a to-do list only contains what was explicitly asked for, and has no answer for what happens when a step doesn't go as planned. A machine has to declare its failure paths, its retry budgets and its escalation states before the work starts.\n\n*A run in progress. The transcript carries the states as they happen; the panel on the right holds the machine, the state now executing with the instruction it was given, and the store, with each location marked by who writes it: the agent, a measurement, or a `set`.*\n\n```\norcrist/\n├── metamodel/\n│   ├── orcrist.langium        the grammar, ground truth for the authoring step\n│   └── authoring-guide.md     the criteria the authoring model is told to follow\n├── examples/*.orc             canonical syntax, shown to the authoring model\n├── src/                       the app: core, language implementation, renderer\n├── electron/                  the main process and the preload bridge\n├── scripts/                   the self-test\n├── prompts/                   project prompts to run the agent against\n├── brand/                     the mark, the lockup, the icons\n├── screens/                   the screenshots in this README\n└── docs/                      how the app works, in depth\n```\n\nThe grammar, the guide and the examples are read **at runtime**, not compiled in: the app walks up from its own folder until it finds `metamodel/orcrist.langium`. Editing the language therefore changes what the authoring step is grounded in without rebuilding anything, and a checkout with `metamodel/` missing has nothing to author machines against.\n\n- **Node 20 or newer** , with npm\n- macOS, Linux or Windows\n- An API key for Anthropic or OpenAI, **or** a local[Ollama](https://ollama.com) with a model that supports tool calling\n\n```\ngit clone <this repo>\ncd orcrist\nnpm install\n```\n\n`npm install` downloads the Electron binary in a postinstall step. If that step fails (see [Troubleshooting](#troubleshooting)), the rest still installs, and `npm test` and `npm run build` work without it.\n\n```\nnpm start\n```\n\nThat compiles the main process, bundles the renderer and launches the app. For iterative work:\n\n```\nnpm run dev\n```\n\nwhich runs the Vite dev server with hot reload and points Electron at it.\n\n```\nnpm run build          # both halves\nnpm run build:main     # main process + core, via tsc\nnpm run build:renderer # renderer, via Vite\n```\n\nOutput goes to `dist/`: `dist/main/` for the Electron side, `dist/renderer/` for the UI. There is no packaging step yet; `npm start` runs the built app in place.\n\n```\nnpm test\n```\n\nThis parses and validates every `.orc` in `examples/`, checks that a set of deliberately broken machines is rejected for the right reasons, runs a machine end to end against a scripted mock provider, and checks the things a real run depends on: that cancelling a run actually stops the request, that a measured value beats a model's claim, that a state restricted to no tools is handed none, and that the store travels with every state instruction.\n\nIt needs no API key and makes no network calls.\n\n1. Open **Settings → Providers** and put in an API key. For Ollama there is no key: the models installed on the machine are listed for you under whichever role you point at it.\n2. In **Settings → Models** , choose the two models. They are separate roles:\n  - **Authoring** writes the machine. Give it the strongest model you have, because it decides the shape of the whole run, what counts as proof that each part works, and what each state is allowed to touch.\n  - **Execution** runs each state. This is where a smaller or local model is affordable, because the machine is what supplies the structure it would otherwise have to hold in its head.\n3. Create a project. A project is a name plus a workspace folder; every shell command and file operation is sandboxed to that folder, and the session history lives inside it under `.orcrist-agent/` .\n4. Send a task.\n\n*The two roles, set separately. Point one at Ollama and the models installed on the machine are listed underneath it, and clicking one uses it.*\n\n**Settings → Palette** changes the whole app's colours. Six palettes ship; each is six seed colours and everything else is derived from them.\n\n**\"Electron failed to install correctly.\"** The postinstall download failed on its own (a network hiccup, a proxy, a GitHub rate limit) while the rest of the install reported success. The symptom is `node_modules/electron/` with no `dist/` inside. Re-run just that step:\n\n```\nnpm run fix:electron\n```\n\nIf it fails again the error says why. Behind a proxy, set `HTTPS_PROXY` and retry. If GitHub is unreachable or rate-limiting, use a mirror:\n\n```\nELECTRON_MIRROR=\"https://npmmirror.com/mirrors/electron/\" npm run fix:electron\n```\n\n**\"Could not find metamodel/orcrist.langium.\"** `metamodel/` is missing from the checkout, or the app was copied somewhere on its own. It looks up the folder chain from its own location, so `metamodel/` and `examples/` belong at the root of the repo, beside `package.json`.\n\n**A run stops at \"no machine for this message\".** The authoring model decided the task is a single question with no process in it, and said so rather than wrapping one step in ceremony. The reason is printed in the transcript.\n\n| document | what it covers | \n|---|---|\n| [`docs/how-it-works.md`](/simone20a/Orcrist/blob/main/docs/how-it-works.md) | how the app works: the authoring loop, the state boundary, claims versus measurements, the tools, the type scale and the palette system | \n| [`metamodel/authoring-guide.md`](/simone20a/Orcrist/blob/main/metamodel/authoring-guide.md) | how to turn a prompt into a machine: the document the authoring model is given verbatim | \n| [`metamodel/orcrist.langium`](/simone20a/Orcrist/blob/main/metamodel/orcrist.langium) | the grammar, and the list of constraints the validator enforces on top of it | \n| [`brand/README.md`](/simone20a/Orcrist/blob/main/brand/README.md) | the mark: why those six colours, and which file to use where |", "url": "https://wpnews.pro/news/orcrist-a-coding-agent-using-llm-state-machines", "canonical_source": "https://github.com/simone20a/Orcrist", "published_at": "2026-09-12 15:45:39+00:00", "updated_at": "2026-09-12 16:17:30.480583+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "large-language-models", "developer-tools", "ai-products"], "entities": ["Orcrist", "Anthropic", "OpenAI", "Ollama", "Electron", "Vite", "Node 20", "Langium"], "alternates": {"html": "https://wpnews.pro/news/orcrist-a-coding-agent-using-llm-state-machines", "markdown": "https://wpnews.pro/news/orcrist-a-coding-agent-using-llm-state-machines.md", "text": "https://wpnews.pro/news/orcrist-a-coding-agent-using-llm-state-machines.txt", "jsonld": "https://wpnews.pro/news/orcrist-a-coding-agent-using-llm-state-machines.jsonld"}}