Forge is a lightweight LLM-based agent runtime built around a router + tool execution model. Instead of relying on a monolithic prompt or complex reasoning loops, Forge delegates actions to explicit tools selected by a structured LLM router.
It runs on the machines it is written on — a Steam Deck and a small home server — which is what most of the design decisions here are downstream of.
User Input
↓
LLM Router (structured JSON decision)
↓
Capability Registry → Policy Engine
├── chat (conversational response)
├── code (code generation)
├── files (sandboxed read/write/list)
├── shell (sandboxed subprocess)
├── git (read-only git operations)
├── memory (remember/recall, vector search)
├── recall (search memory → synthesize, one call)
├── test (sandboxed pytest/ruff runner)
├── review (read a file, optionally test it, analyze)
├── web_fetch (fetch a known URL)
├── web_search (SearXNG links/snippets, no synthesis)
├── research (search → fetch → synthesize, one call)
├── sysadmin (discover → collect → synthesize, read-only diagnosis)
└── delegate (draft a spec, hand off to Claude Code)
The model must output a strict JSON instruction ({"tool": "...", "content": "..."})
describing which tool to invoke. The router is resilient: it handles JSON,
XML tool-call format (Qwen HERETIC), markdown code fences, and plain text as
fallbacks, in that order. Repeated tokens, leaked prompt instructions, and
empty outputs are detected and replaced with a clean placeholder.
A choice that can be enumerated goes in a grammar or in code, never in a prompt. Not a preference — the record. Thirteen times now a rule written in the prompt has been followed most of the time and silently broken the rest, and each one was replaced by something that cannot break it: a GBNF grammar whose alternation makes the wrong token unsamplable, a check on the shape of the turn, an arithmetic gate between two texts.
The corollary is that defaults here are earned rather than chosen. Every
mechanism with a knob ships off until a harness in bench/ has
measured it against a copy of the real store — and several shipped off
because of what the harness said. docs/campaigns.md is
the long version: every campaign, its numbers, and what it settled — including
the ones that ended by killing the mechanism they were measuring.
git clone https://github.com/Kurtisone/forge.git
cd forge
cp .env.example .env # set API_TOKEN, at minimum
pip install -r requirements.txt
PYTHONPATH=src python -m forge.main # REPL
PYTHONPATH=src uvicorn forge.api:app # HTTP API + web UI on :8000Or with a container:
podman compose build forge
podman compose up -d --no-deps forgeForge refuses to start without API_TOKEN — that is deliberate, not a
papercut. Full instructions in docs/usage.md.
Everything past "how do I start it" lives in docs/:
- Architecture — how a turn flows, and why the boundaries are where they are
- Usage — REPL, web UI, CLI, container
- Configuration — the settings you are likely to touch
- Tools — what each tool does, refuses, and costs
- Memory, RAG and traces — the three stores and how they differ
- The measurement record — what was measured, and what each campaign settled
- HTTP API — routes, auth, delegation jobs
- Development — tests, CI, measurement harnesses
- Version history and roadmap — what landed when
Plus, at the root: ARCHITECTURE.md for the long-term direction, SECURITY.md for the threat model, and .env.example as the exhaustive configuration reference.
Forge dispatches model-chosen tools on your own machine, sometimes
against data it fetched from elsewhere. SECURITY.md
states the threat model it is built for (one operator, one machine,
private network, public repo), what is enforced deterministically in
code rather than asked of the model, and the limits that are known and
accepted -- including the one worth reading before you edit
ENABLED_TOOLS: files and test together are equivalent to
shell.
Forge is an experimental local runtime, not a production framework. The public API (orchestrator, tool registry, providers, graph engine) is stabilising from v3.0 onward; v3.22 is current, and docs/roadmap.md says what each version actually did.
MIT