Skip to content

Reference

The public package exports Target, Call, act, accept and load_pack. Inference needs only NumPy. Import training functions from wren.train after installing the train extra.

Target

Target(name, type, value, values=None, range=None, description="", unit=None, readonly=False)

Field Meaning
name Unique snake_case name. Its words help select the target.
type "bool", "int", "float" or "str".
value Current value, matching the target's type. Supply it on every request.
values Allowed string values, case-sensitive. None leaves strings unrestricted at parsing time; the generator needs a nonempty list to generate string-setting commands.
range Inclusive [low, high] for numbers. Without it, parsing allows any value of the numeric type; generated values stay near the listed value.
description Words used for selection. The text before its first comma is also a generated name when it has at most five words.
unit Metadata for your code; absent from the prompt.
readonly Defaults to False. When True, setting the target rejects the answer; generated commands ask for readings.

The dataclass stores these fields without validating the installation. Use valid, distinct names and consistent types, values and constraints. Descriptions help selection and training; the prompt itself contains only name=value lines and the command.

Call

Call(target, value=None, delay_s=None, confidence=1.0)

Field Meaning
target Name from the supplied targets.
value Value to set, or None to request a reading.
delay_s Delay in seconds, or None to run now. Generated delays use whole seconds.
confidence Minimum byte probability on this call's line and the answer's closing blank line.

Calls describe work for your application. Wren does not execute them.

act and load_pack

from wren import Target, act, load_pack

targets = [Target("kitchen_light", "bool", False)]
calls = act("turn on the kitchen light", targets)

act(command, targets, *, model=None) -> list[Call] selects targets, builds a prompt, decodes greedily and parses the answer. With no model, it loads and caches the packaged demo model. A custom model is the dictionary returned by load_pack(path).

accept(calls, *, model=None) -> list[Call] applies the pack's saved threshold and acceptance policy. "answer" accepts all calls only when each passes; "call" filters each call separately. Packs without this metadata field use "call". Omitted model uses the packaged model. The helper cannot detect omitted calls and does not execute anything.

act does not filter by confidence or verify that the supplied target definitions match the model's training metadata. [] can mean abstention or rejection of an invalid or incomplete answer.

load_pack(path) -> dict accepts a string or pathlib.Path and loads configuration (cfg), NumPy weight arrays and metadata (meta). It expands the packed attention weights to float32 in memory, so pack size is not the runtime memory footprint. Packs without metadata have meta == {}.

Prompt and answer limits

The default model has a 384-byte context. act reserves 96 bytes for the answer, leaving 288 bytes for the command, newlines and target lines. These are UTF-8 bytes, not characters; long names and non-ASCII text use more of the budget.

Selection uses words from target names and descriptions, lowercased and split on underscores and punctuation, with common function words removed and a simple plural s removal. Targets sharing the most words with the command get space first; ties use input order. The selected targets appear in their original order. A line that is too large is skipped so later targets can still fit. act rejects a command that alone exceeds the prompt budget; it does not discard its beginning. The lower-level raw runtimes still retain the tail of overlong prompts.

From wren.targets, select(targets, command, budget=288) and prompt(selected_targets, command) expose these steps. For example:

canopy=UP
close the awning in 10 minutes

Answers contain one call per line and a closing blank line:

>> set(canopy, DOWN) in 10m

Readings use >> read(outdoor_temperature). Delays use integer h, m or s suffixes. An answer consisting only of a blank line means abstention. An answer that is malformed, incomplete, names a target outside the supplied list, sets a read-only target or violates a value constraint is rejected in full. Parsing checks against the complete supplied list, including targets omitted from the prompt by selection.

fit

from wren.train import fit

result = fit(targets, out="home.bin", examples=[], calibration=[], tests=[])

out is required. examples, calibration and tests default to empty sequences and use the installation record format. All options after targets are keyword-only.

Python option CLI flag Default Meaning
dim --dim 256 Model width.
n_layers --n-layers 4 Attention-only block count.
n_heads --n-heads 4 Attention heads; dim / n_heads must be an even integer.
steps --steps 4000 Optimizer updates.
batch_size --batch-size 16 384-byte windows per update.
lr --lr 0.003 Initial learning rate, decaying to zero along a cosine.
n_train --n-train 200000 Generated training samples.
n_calibration --n-calibration 1000 Generated samples used to choose the threshold.
n_eval --n-eval 1000 Independent samples with held-out phrasing families.
precision --precision 0.99 Requested precision under the acceptance policy, measured on calibration.
acceptance --acceptance answer Complete-answer precision and acceptance; call selects the previous per-call policy.
seed --seed 0 Model/training seed; calibration uses seed + 1, evaluation seed + 2.

Keep counts positive and provide enough training text for a full window. The default installation model has about 1.12M parameters and a 535 kB pack.

Two callbacks are available through Python only:

  • on_log(step, loss) runs after each training step, with a zero-based step and a float loss.
  • paraphrase(command) -> list[str] supplies alternate training phrasings. Preserve meaning and numbers as digits. Results are cached per distinct complete command during corpus generation, including delays and durations. Evaluation does not use the callback.

Results

fit returns a dictionary:

Key Meaning
exact_match Fraction of generated evaluation samples with exactly the expected calls before confidence filtering.
threshold Cutoff chosen on generated and installation calibration sets, each checked separately under the saved acceptance policy.
coverage Fraction of generated evaluation samples with exactly the expected calls after filtering. Includes correct abstentions.
test_exact_match, test_coverage The same sample metrics on supplied tests; absent when no tests are given.
positive_coverage Fraction of commands requiring calls that are handled completely and correctly after acceptance.
call_precision, command_precision Correct calls / accepted calls; complete correct answers / nonempty accepted answers.
accepted_commands, accepted_calls Counts supporting the precision estimates.
partial_commands Nonempty accepted answers that contain only some of the expected calls.
wrong_commands Accepted answers containing any unexpected call.
missed_commands Commands requiring calls for which none were accepted.
by_kind Counts and metrics for abstentions, reads, sets, multiple calls, delays and durations.
calibration, calibration_tests, tests Detailed metrics for each separate set; optional installation sets are absent when empty.
selection, test_selection Required-target/state recall, byte-limit failures and affected commands.
corpus Training generation counts: attempted, accepted, reserved-text exclusions and selection/byte-limit rejections.
final_loss Last training step's mean next-byte cross-entropy, in nats.
n_params Parameter count.
seconds End-to-end elapsed time, including corpus generation, evaluation and export.

Installation metrics compare target, value and delay, ignoring call order and confidence.

Rates with empty denominators are None. Precision is an empirical calibration estimate, not a guarantee on new commands. Generated calibration must retain at least one accepted prediction; an installation calibration set may retain none. Tests never influence the threshold. Include positive and negative tests to measure useful coverage and incorrect actions.

The pack's metadata stores targets (without current values), threshold, precision, acceptance, steps, date (UTC date), evaluation metrics, split sizes/seed, and test_exact_match when tests are supplied. It does not store the examples, complete training configuration or optimizer state. The evaluation metrics name the commands of failed tests and failed generated samples. Keep the installation JSON and training settings with the pack. fit always starts a new model; it does not resume from a pack.

Evaluate an existing pack

Use installation tests to check a saved model without retraining:

from wren.dataset import as_case
from wren.eval import metrics, selection

cases = [as_case(targets, record) for record in home["tests"]]
predicted = [act(command, state, model=model) for command, state, _ in cases]
expected = [calls for _, _, calls in cases]
print(
    metrics(
        predicted,
        expected,
        model["meta"]["threshold"],
        policy=model["meta"].get("acceptance", "call"),
    )
)
print(selection(cases, required_state=[r.get("state", {}) for r in home["tests"]]))

Here home, targets and model are loaded as in the How-to, and the test list must be nonempty. as_case uses listed values for state keys not specified in the test. It validates labels but retains commands that fail selection or byte limits. corpus(..., filter_unlearnable=False, diagnostics=counts) similarly retains generated failures for evaluation; training filters them by default.

C runtime

In a checkout, compile with a C compiler and the math library:

cc -O3 -o wren-rt runtime/wren.c -lm
printf 'kitchen_light=false\nturn on the kitchen light\n' | ./wren-rt wren/wren.bin
# >> set(kitchen_light, true)

./wren-rt PACK [-n BYTES] [PROMPT] accepts a prompt argument or reads stdin. The default output budget is 96 bytes. A prompt argument gets a trailing newline automatically; stdin must include it. For the Python prompt builder, use wren.targets.prompt(wren.targets.select(targets, command), command).

The C runtime runs single-threaded and prints raw model output. It does not select targets, validate calls, provide confidence scores or use pack metadata. Your integration must handle those steps if needed. The pack format is version 1; Wren's package version is independent.

For custom low-level training, export a saved Wren .npz checkpoint with python -m wren.export weights.npz out.bin. This NumPy-only command adds no metadata or calibrated threshold; fit handles both automatically.