Skip to content

Latest commit

 

History

History
66 lines (57 loc) · 3.58 KB

providers.md

File metadata and controls

66 lines (57 loc) · 3.58 KB

Which model a run asks

A gate says what "done" means. This says what to do when the model that has to reach it keeps missing, and what to do when the work turns out not to have needed the model you started with. [app.io-cli.routing] holds two optional rules, each written as a sub-table because a rule is a threshold and a model that only mean anything together — a threshold with no model and a model with no threshold are both half a rule, and a sub-table makes the pair the unit the file itself enforces:

[app.io-cli.routing.escalate_after]
failures = 3
model = "a-stronger-model"

[app.io-cli.routing.downshift_under]
bytes = 2000
model = "a-cheaper-model"

escalate_after moves up after that many consecutive failed gate attempts — the gates above, counted consecutively rather than cumulatively, because a run that fails, recovers, and fails again much later is a run doing hard work rather than one that needs a bigger model. downshift_under asks the cheaper model while the run has written fewer than that many bytes to disk, measured on what was actually written rather than on what was planned, so it is a fact about the run rather than a forecast of it. Neither key defaults: half a rule is a parse error naming the key you left out, rather than a threshold quietly reading as zero and escalating on the first gate attempt of every turn.

Escalation happens once and does not come back down, and escalation wins over downshifting where both apply. Both of those are io-harness's rules rather than io-cli's: it owns the consecutive-failure count, the byte total and the decision, taken after every step of the run. io-cli evaluates none of it, because a second implementation here would be a second answer that drifts from the one the run actually used.

Routing does not reach a contained turn, and that is the first thing to know about it. io-harness applies routing in its flat workspace loop only; a turn run under [app.io-cli.containment] takes each agent's model from that agent's own roster entry and never consults the rules. So for an operator who has configured containment, the section parses, is listed by /config, reaches the contract — and never fires. A session that has both is told so at three moments: at start, when /config is opened on the keys themselves, and when /contain on is typed — which is the one that matters most, because that operator began uncontained, was told nothing because nothing applied, and has just moved into the mode where their rules do not fire. A session with containment off is told nothing, because a caveat attached to a feature that is working is how an operator learns to stop reading the notices. A turn taken with /contain off routes normally, and io exec uses the flat loop, so routing works there. Nothing in io-cli can close this: the loop that would have to consult the rules is the dependency's, and what this interface owes you meanwhile is the disclosure.

There is no require_primary key, and its absence is a decision rather than an omission. io-harness's own Routing carries the field, and it gates on Provider::reachable — a defaulted trait method whose body answers yes, and which no provider in io-harness 0.71.0 overrides. A key for it would be offered on a surface, accepted from a file, and permanently inert: you would set it, believe an unattended overnight run now refuses to start against a dead endpoint, and get exactly the behaviour you had before. It goes in when a provider answers the question.


README · All guides · What you may depend on