Wren is a small attention-only model which turns short, frequent commands into proposed calls on a fixed set of targets. You can train your own model from self-defined targets, examples and test commands conveniently on a CPU. Wren is intended to be part of Fluksio but also works as a standalone library.
The shipped demo model answers in a median 52 ms on a CPU and packs into 535 kB of memory, making it ideal for local inference. See Research and benchmarks for measurement conditions, accuracy and historical comparisons.
You need Python 3.12 or newer and Git. In an activated virtual environment:
python -m pip install git+https://github.com/stroblme/wrenThe distribution is named wren-lm and imports as wren. Use the Git
URL: the package named wren on PyPI is unrelated.
To train through Python, install the training extra:
python -m pip install "wren-lm[train] @ git+https://github.com/stroblme/wren"For CLI training and development, install uv and clone the repo:
git clone https://github.com/stroblme/wren.git
cd wren
uv sync --locked
uv run fluksio serveKeep the Fluksio engine running for CLI training.
The default environment includes training and quality-check tools.
Inference (Numpy) and Python fit (JAX) can run without Fluksio.
See Development for CPU/GPU setup, tests and documentation builds.
Run a command with the shipped demo model:
wren "turn on the kitchen light"
# >> set(kitchen_light, true) 1.00The demo uses wren/home.json (20 targets).
Save an installation of your own as home.json:
{
"targets": [
{"name": "kitchen_light", "type": "bool", "value": false},
{"name": "canopy", "type": "str", "value": "UP", "values": ["UP", "DOWN", "STOP"], "description": "awning over the patio"}
],
"examples": [
{"command": "close the awning in 10 minutes", "calls": [["canopy", "DOWN", 600]]}
],
"tests": [
{"command": "turn on the kitchen light", "calls": [["kitchen_light", true]]},
{"command": "lower the awning in half an hour", "calls": [["canopy", "DOWN", 1800]]}
]
}From a checkout with the engine running, train in another terminal:
uv run wren --train home.jsonThis records the training run and saves home.bin.
Alternatively, train directly with Python fit, then load the pack for inference:
import json
from pathlib import Path
from wren import Target, accept, act, load_pack
from wren.train import fit
home = json.loads(Path("home.json").read_text())
targets = [Target(**t) for t in home["targets"]]
fit(
targets,
out="home.bin",
examples=home["examples"],
calibration=home.get("calibration", []),
tests=home["tests"],
)
model = load_pack("home.bin")
calls = act("close the awning in 10 minutes", targets, model=model)
applied = accept(calls, model=model)
print(applied)act returns calls without executing or filtering them.
accept applies the pack's threshold and policy; your code executes calls and schedules delays.
New packs accept all generated calls together or reject the answer.
The threshold comes from separate calibration samples and optional installation calibration records. Tests measure the frozen policy.
Note that unfamiliar wording can still produce confident errors.
The How-to covers targets, examples, tests, the threshold, group targets, learning from the caller's log and the demo model's limits.
For manual inspection after training:
wren --targets home.json --model home.bin "close the awning in 10 minutes"The CLI prints all returned calls and rounded confidences, including calls below the threshold. The Reference lists the API, training options and C runtime usage.