Skip to content

Upgrading ​

Each release that changes what a caller meets has a section here, the newest first. In none of them does a verdict change: every kept run reads to the same category. The site follows main, so a release not yet out says so.

Just after a release, uv may still answer from its cache that the new version does not exist; --refresh-package midwife makes it look again.


To 0.8.0 ​

0.8.0's unified battery speaks to the router only through the router's own headers, its data policy, its endpoint pins and its report of what served a call, and needs a router that takes them.

In 0.7In 0.8.0What to do
The unified battery asked for endpoints that keep no data with a field in each request's bodyEach call goes under the router's X-Codex-Router-Data-Policy: deny, unless the frame names its model under trainsOnInputsNothing, with a router that takes it
A call went to the router unaskedBefore the first call, the battery reads the router's GET /health, and refuses to run, a BatteryError (6), when the router does not list the policy or cannot be askedUpdate the router, or start it
A model whose provider trains, by the router's list but not Gadfly's, went out with that fieldThe router refuses it, and the call comes back as an opening that names the modelChoose another model, or name it under trainsOnInputs
battery.endpoints went out as a field in each request's bodyIt goes as the router's X-Codex-Router-Endpoints, up to 16 tags with no comma or space, and a router whose GET /health does not list endpoint pins is refused before any callUpdate the router; keep a pin to 16 tags
served named the model, and an endpoint only when a header the router never sent was thereIt names the model, then the provider the router reports, or the tag of a single pinned endpoint; a provider the router does not yet know is left outNothing; read the provider from served when it is there

To 0.7.0 ​

0.7.0 changes what the command line prints and how it ends, and how Gadfly raises what it refuses; this lists what a caller of 0.6.0 meets, and what to do. 0.7.1 changes nothing a caller meets: one test that read a refusal's message now passes on Python 3.14 and later, as on 3.13.

The command line ​

In 0.6.0In 0.7.0What to do
A refusal printed gadfly: <reason> and exited with 2It prints Type: message, then each note on a line of its own, and exits with its class's status: UsageError 2, FrameError 4, RecordsError 5, BatteryError 6, a file error 7Read the status or the class; Troubleshooting tables each message
Any other exception was Python's traceback, exiting with 1It is a bug: its traceback, and 70Report it
check-frame exited with 1 on a problemIt prints each problem as a FrameError and exits with 4Read 4 as refused
A run its budget cut short exited with 0, after a stopped: lineIt exits with 3, after a StoppedWarningRead 3 as a partial run, or raise the budget
Openings were an openings: line in run's summaryThey are an OpeningWarning; run exits with 1 only when every call opened, as beforeRead the warning instead of the line
A shortened flag, such as --stop, was takenFlags are named in full; -o and --output name --outWrite each flag in full
A closed reader, as with | head, ended gadfly with a tracebackIt ends quietly, with 141Nothing

Any file Gadfly reads may now be -, standard input, which is refused at a terminal. run --out - streams the records to standard output and its summary to standard error, and a run with nothing left to ask makes its file, empty.

JSON output ​

CommandIn 0.6.0In 0.7.0
any refusal with --jsongadfly: <reason> on standard error, as textOne object on standard error, {"error": {"type", "exit", "message", "notes", "help"}}
run --jsonstopped and openings in its resultIts result also holds exit, and warnings, each with the status it gives
check-frame --json{"ok": false, ...} on standard output for a refused frameOne FrameError object on standard error that lists problems, each with its notes; {"ok": true, ...} on standard output for an accepted one

Frames and Python callers ​

In 0.6.0In 0.7.0What to do
A frame's name, span ids, input ids and labels could hold ": " or a line breakEach must be one plain name, or the frame is refusedRename it; a new name is a new frame, with a new hash
A refusal was a ValueError, and a missing eGemma key or router token a RuntimeErrorEach refusal is a class in midwife.errors, still a ValueError; the missing key or token is a BatteryErrorCatch midwife.errors.GadflyError, or the class you mean
run() reported openings and a stop only in its resultIt also raises OpeningWarning and StoppedWarning with warnings.warnFilter them, or make them errors, as with -W error::midwife.errors.OpeningWarning
A Ctrl-C in run() raised a plain KeyboardInterruptIts running says how many calls are still outRead it before you exit

New, and opt-in: run(stop_unresolved=True) and --stop-unresolved, a sham drawn from another kind (sham.kind), plan's line naming what no answers can make a frame read, and the egemma battery's "reasoning": true, which needs an eGemma newer than its v0.5.0.