Repository navigation
v21.0.0
·
5 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
A major release that makes assistants event-driven and lets them choose when to speak. A structured reply replaces answer pointers and status checks, a gate decides whether a scheduled run needs the model, an assistant can schedule its own next run, and one post channel replaces output routing. The brain format (version: 8), records, notes, the search cache and the queue format are unchanged; bf.yaml assistants need manual edits. Follow the upgrade steps below.
Breaking changes
replyreplacestextandstatus. An assistant withreply: {path: POINTER}reads a structured{say, wake}object from its harness's JSON stdout, such as/structured_output, and{{schema}}passes the harness that schema. Output that is not a JSON object, a missing reply or one that does not match the schema fails the attempt like a nonzero exit, which also catches a harness that exits 0 after a model error or its own timeout.nullor blanksaystays silent, except in answer to a message, where it fails as an empty answer did.bf validatereportsassistants.NAME.text: Extra inputs are not permittedand the same forstatus(structured replies). Withoutreply, stdout is still the plain message.postreplacesoutputs. A message is answered in its own conversation, asreply: {}did, and every other run, manual ones included, posts to the one channelpostnames.outputs,reply: {}andwhenare gone:bf validatereportsassistants.NAME.outputs: Extra inputs are not permitted. One answer makes at most one delivery; to notify a second channel, declare a second assistant or let the channel's script fan out.- Input channels need
send. Every channel an assistant reads must declaresend, so its messages can be answered:assistants.NAME.inputs: channel X requires send to answer its messages. - Runs of kind
wake.BF_TRIGGER,{{context}}'skind, a record'sattributes.triggerandbf update --dry-runrows may now bewake, and records may carryattributes.wake. Scripts that match the run kinds need the new value.
Added
- Gates. A schedule's optional
gate: {command: [...]}runs a deterministic program before the harness. It prints{"events": [...]}, at most 64 events and 64 KiB; no event completes the job without starting the model, and events reach the prompt in{{context}}. A failed gate retries by itself, since no harness ran, and a retried job reuses the events its gate saved, so a gate can keep "already reported" state inBF_STATE_DIR(gates). - Wakes. With
wake: {min, max}, a structured reply'swake: {in, reason}schedules one later run, clamped to those bounds. A newer request replaces the pending one, a failed run asks for none, and the wake run receives its reason in{{context}}.bf queuelistswakesby assistant, due time and the job running it (wakes). bf schema --kind assistant-replyprints the reply schema, for a harness that reads it from a file, such ascodex exec --output-schema FILE; it is published asassistant-reply.schema.json.
Changed
- Literal
}}in arguments. A command argument may hold}}, such as the end of inline JSON settings; only an unknown{{…}}placeholder fails. Before,}}had to be written} }. - Assistant safety. Keep prompts safe now states that an assistant with a shell or write tools can be steered by the mail, chat or web content it reads, whatever BF labels as data.
bf validateno longer checks an assistant's queue space per answer: with one delivery per answer and the 4 MiBmax_bytesbound, every answer fits.
Fixed
- The assistant guide stated that an
idempotentassistant retries up to 5 attempts after5 × 2^(n−1)seconds; it retries after 2, 4, … up to 300 seconds, for up to 20 attempts, as the code always did.
Upgrade from v20
- With v20 still installed, stop
bf watch, its service or timers and any script callingbf run,bf channelorbf queue. - Drain the assistant queue: run
bf update --kind assistant, then retry or cancel each pending, failed or uncertain job untilbf queuecountsshow onlycompleteandcancelled. A job v20 queued snapshots its old settings, which v21 cannot run: after upgrading, cancel any you missed withbf queue ID --cancel. - Upgrade with
uv tool upgrade brain-framework, or update a pinned brain's pin, and checkbf --version. - In
bf.yaml, for each assistant:- Replace
outputswithpost: CHANNEL, naming the channel its scheduled runs posted to, and deletereply: {}andwhen. Manual runs now post there too. - Add
sendto each channel listed ininputsthat lacks it. - Either switch to a structured reply: pass the schema, such as
--json-schema "{{schema}}"for Claude Code or Antigravity, setreply: {path: /structured_output}and deletetextandstatus; or keep a plain answer: deletetextandstatusand make the harness print plain text, since its whole stdout becomes the message. - Replace
} }workarounds in arguments with}}if you like; both work.
- Replace
- With a structured reply, rewrite each prompt's answer section: fill
say, ornullwhen nothing needs the owner. Delete rules such as "answer exactly-", answer marker lines and wrapper scripts that strip harness chatter. Move deduplication and threshold rules into a schedule'sgate, and addwake: {min, max}where the assistant should schedule its own follow-up. - Update scripts and prompts that match
BF_TRIGGER,attributes.triggeror{{context}}'skindfor the newwakekind. - Run
bf validate,bf skills DIRfor each skills folder,bf run NAMEonce per assistant andbf status --check, then restart watch.