What makes furb different
Most harnesses give a model a menu of tools and read one JSON call at a time. furb gives the model a Python module, and each answer of the model is a program that runs in it.
- One answer, one program. In one word, the model can read files, run commands, ask other models, wait, and combine the results with loops and conditions. It does not have to spend one turn on each call.
- The system prompt is one file that you can read. The engine is
src/furb/engine.py. Minified, it is the whole system prompt, and it costs fewer than 6500 tokens. No text is hidden from you. - Every word is checked before it runs. A type checker reads each word first. A word that it refuses never runs, so it has no effects, and the model reads why.
- Work runs side by side. A command, a question to a model, and a wait are acts that a word can await together. Chains work in parallel, and each chain has its own module and folder.
- A scratch directory for each session. A word keeps its notes and scratch files in
scratch://, and a command finds them in$TMPDIR. A resumed session finds them again, and the record makes again the files that its words wrote. - Rewind to any point. A new chain can start from any point of another chain. In the TUI, press Escape twice to open the rewind tree.
- You see what the model sees. The transcript is the exact text that the model reads. The record holds every act of the operator and every answer of the World, and a later run replays it. Work that was interrupted starts again when you resume it, but for a command, which ends as interrupted, so the model sees that it was cut and runs it again if it wants.
- Limits that hold. A chain pauses when it reaches a dollar ceiling or a share of the context window.
- No permissions, by design. Each act runs with the rights of the user who runs furb, and the record shows who made each act. For isolation, run furb in a virtual machine. An extension can ask you before an act, but furb has none built in.
- The model can ask you. A question to the operator waits in the feed until you answer it.
- Extensions are words. An extension is Python that each chain runs as a rung, which the model reads in its turns.
The official ones tell a chain the
CLAUDE.mdfiles of its project and the skills it can read. The system prompt stays the engine alone, so an extension never breaks what a provider caches. - One contract, proven twice.
src/furb/engine.pyiholds each law of the engine as one sentence, and the suite has one test for each sentence. The suite runs on CPython, and on monty, a Python interpreter written in Rust.
Try it
pip install furb # The engine, and furb, the command line. It needs Python 3.14 or later.
furb is a program of Rust. It runs the engine in monty. It asks the models of the claude command line, the models of
each provider whose credential, such as ANTHROPIC_API_KEY, stands in the environment, and the models of the local
server whose address FURB_LOCAL_URL names:
furb # The TUI, when furb finds one.
furb --mode rpc # A JSON-RPC on stdin and stdout, with no TUI.
furb prompt "How many lines does a.txt hold?" --shape int
furb run "close(1 + 1)" # A Python word, run on the root chain.
furb turns --record session.jsonl # The turns of a life made again from its record, which it only reads.
furb extensions # The extensions that a life runs here.
MAX_THINKING_TOKENS gives the most tokens of thought of a model in one turn, as it does for Claude Code, and 0 turns
the thought off. The key max_thinking_tokens of .furb/config.json gives it for a project, and the environment wins
over the config. When neither gives it, it is 32768. The claude command line inherits it from the environment of furb,
and else furb sets it for claude to the number of the config or to 32768. Claude Code reads it as a fixed budget of
thought beside the effort: a model with adaptive reasoning, as Opus 5.5, Sonnet 5.5, Haiku 5.5 or a Fable model, thinks
as its effort says and cannot turn its thought off.
A local server serves the chat completions of OpenAI under /v1 and lists its models at /v1/models, as llama.cpp, LM
Studio, Ollama, vLLM and Strata do. FURB_LOCAL_KEY gives its key when it takes one. furb names each model for chat
that the server lists local: and its id, as in --model local:qwen3. Such a model costs nothing, takes the efforts off, low, medium and
high, which it reads as enable_thinking false or as reasoning_effort, as in --model local:qwen3/medium, and
writes a quarter of its window at most in one turn, or the number that FURB_LOCAL_TOKENS gives. Past the most tokens
of thought of a turn, furb asks the model again with that thought and with its thought turned off, so it writes its word
at once, and at a most of 0 furb asks it with its thought off from the first request. Every model reads the
doctrine of furb, DOCTRINE.md, once on each chain that asks it, in the paragraph that asks it for its first word,
and it reads nothing more of it. Its window is the one
that the server gives, or the number that FURB_LOCAL_WINDOW gives, and furb offers no model whose window neither
gives. Ollama serves a model in the num_ctx of its parameters, or in OLLAMA_CONTEXT_LENGTH: set it to 32768 or more,
since the system prompt of furb is about 9000 tokens. Ollama tells that window only for a model that it loaded, so give
the same number to FURB_LOCAL_WINDOW. furb asks the server only for a name of the provider local or of a provider
that furb does not know, as local:qwen3 or qwen3:8b, when a host lists the models, as the TUI and the scripts do,
and when no other model stands for the default actor. local: and the id is the sure name, as
local:mistral:7b, since mistral:7b names the provider mistral. A list that the server gave holds for the process,
but for a model that it did not list or gave no window of, which furb asks for again after 30 seconds, as it asks
again a server that answered nothing. When furb finds
no claude command line, the default actor is a model of a provider of the network whose credential stands, and then a
model of the local server.
The TUI runs from a clone of this repository. It needs uv, the Rust toolchain, and Bun 1.4.2 or later:
uv sync # The Python environment, with furb, which the build reads.
bun install && bun run build # The TUI, and the engine that it runs through the crate.
bun run demo # A scripted life on a sample project. It asks no model.
bun run tui # A real life, through the claude command line.
Then uv run furb opens the TUI of the clone, and so does a furb built from it. A furb from anywhere else runs the
program that FURB_TUI names, or the furb-tui on PATH.
Learn more
- The examples: short programs in python, TypeScript and Rust that show a durable life, a tree of chains, a prompt to the operator, a grant and a door.
- The TUI: the views, the keys, the commands, and a gallery of each screen.
- The desktop preview: how to build the desktop app, start it, and read a record in a window.
- The JSON-RPC: the commands and the events of
furb --mode rpc. - The extensions: what an extension is, the configs that turn one on, and the official ones.
- The developer guide: the tools to install, how a word runs, and how to change the TUI.
- The contract: every law of the engine, one sentence per line.
License
Copyright (C) 2026 Abel Lucas. furb is free software under the GNU Affero General Public License, version 3, which
LICENSEholds. You may use, study, change, and share it. Anyone who ships it, or who runs a changed furb as a service, must offer the source under the same terms. The engine carries no notice of its own, because its text is the system prompt of a model and every word of it counts.
Metadata
Release files for furb 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| furb-0.2.0.tar.gz | 76.9 kB | Without provenance | Details for furb-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| furb-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for furb-0.2.0-py3-none-any.whl |
Total release size: 152.3 kB
Release files / furb-0.2.0.tar.gz
| Download URL | furb-0.2.0.tar.gz |
|---|---|
| Size | 76.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c8de8a7c1f9fd9425f7f1d82260916b557007eb2dce5e591c7cba29c76201203
|
|
BLAKE2b-256 checksum How to use checksums |
ec8c3f59c4c4af3f3825b8a800f43a11d9269b70ca8a8eb97fde988a138657ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / furb-0.2.0-py3-none-any.whl
| Download URL | furb-0.2.0-py3-none-any.whl |
|---|---|
| Size | 75.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
53c499a29c901361d43d71c2434fb620cb898089756786ec27306bba57853fea
|
|
BLAKE2b-256 checksum How to use checksums |
530ab9ee160b544c3a024ab8e59065a446cdbd2f2e524d5db0ced214c8c6e6e3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.17 {"installer":{"name":"uv","version":"0.12.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for furb 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.