Repository navigation
Conversation
A licence server's forwarder joins the unit's internal network under the server's own name. It resolved that name for each connection, and the network's DNS then answered with the forwarder itself, so the agent got a closed connection. The forwarder now resolves the name once, before it listens, and keeps every address. Each connection tries the addresses in order and skips an address family this machine lacks. A name that does not resolve ends the forwarder with an "unresolved" event. The unit connects the forwarder to its network only after the forwarder listens.
The docker backend passed the provider's key to each unit's relay as an environment variable, so docker inspect, and anything that dumps container configurations, showed it. The key is now written owner-only in a folder of its own under relay-keys/ in the user's cache, outside the unit's record. Colima and Lima share the user's home with their engine by default, but not the system's temporary folder, so that folder is not used. The file is bind-mounted alone and read-only into the relay's container and passed to the relay with --key-file. The relay no longer reads NULLIUS_RELAY_UPSTREAM_KEY. Nullius removes the folder once the relay listens, and on stop, which a failed start also calls. A job's sweep removes the folders its relays left. Each unit's start and each sweep also remove any key folder older than 10 minutes, which no start takes: a killed run leaves such a folder.
nullius standard run --max-usd USD: every relay of the job, the units' own in this process or in their containers and the benchmark's, books each call in one ledger before sending it. A call is sent only while what was spent, what the calls in flight have booked and its own booking stay within the cap. The first that does not fit is refused by the relay itself (HTTP 402, recorded as refused, never as the provider's error), and so is every call after it. A unit cut off ends as SpendingCapError, an API error outside the agent's rate. Units not begun are not run. result.json carries the cap, what was spent, whether it stopped the run, the units cut off and those not run. A capped run is refused before it starts when a model it calls has no price.
# Conflicts: # app/nullius/standard/container.py # app/nullius/standard/relay.py # app/tests/test_standard_relay.py
🔴 PR judge · 4 of 8 yes · #46 ↔ #14
Acceptance criteria, 2 of 2 met
Checks the script runs itself, 4 of 4 pass
some of the diff was cut before the judge read it |
1 of 9 tasks
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #14
What
nullius standard run --max-usd USDstops a run at a spending cap. Every relay of the job (the units' own, in this process or in their containers, and the benchmark's) books each call in one ledger before sending it (app/nullius/standard/ledger.py): the call's characters over three as input tokens, and as output the limit the call names, else the model's own from its price row, else 4,096 tokens, at the user's prices. A call is sent only while what was spent, what the calls in flight have booked and its own booking stay within the cap. The first that does not fit is refused by the relay itself (HTTP 402, a body and a header that name the relay, recordedrefused), and so is every call after it, so a run stops at one point. A reply turns the booking into what the call cost; a provider's error gives it back; a reply with no token count, or cut off, keeps the whole booking as unsettled.A unit the cap cut off ends as
SpendingCapError, an API error outside the agent's rate, never a miss. Units not begun are not run.result.jsoncarriesbudget:max_usd,spent_usd,unsettled_usdwhen there is some,stopped,cut_offandnot_run. A capped run is refused before it starts when a model it calls has no price.Not in this change, recorded in #45: the cap in the builder and on a host, shards sharing one cap, a cap per unit, and the job page showing the budget.
Stacked on #39 (the user's price list). This branch also carries
mainas of 01dc1cf, merged in because that commit changes the relay container's start, where the ledger is mounted: until #39's branch hasmaintoo, the diff here shows those three commits beside the cap. The cap itself is the commit eddfe3c and the merge's resolution incontainer.py,relay.pyand their tests.Touches
backend · docs and site · the standard
Verified
app/tests/test_standard_ledger.py(10 tests): a call is sent while spent, in flight and its booking fit; the first that does not fit closes the ledger for every later one; an unknown cost keeps its booking and an error gives it back; a ledger that cannot be read lets no call out; 60 calls at once never book past the cap; four processes booking in one ledger lose nothing; what a booking is (the named limit, the model's own, the default, cache-write input, embeddings, an encoded file not counted).test_standard_relay.py: a call that fits is sent and settled at its cost; one that does not is answered 402 by the relay, marked, recordedrefusedand never reaches the provider, and neither does a smaller one after it; a provider's 429 gives the booking back; a reply without tokens keeps it; a model without a price is not sent; a relay without a cap books nothing; the relay as a process of its own books in the ledger it is given.test_standard_run.py: eight units under a cap the fourth call does not fit: three run, one is cut off (SpendingCapError, classified an API error), four are not run,result.jsonsays so and no call went out past the cap; an ample cap changes nothing but the result; no cap, no ledger; a cap without a price for each model, or with a bad amount, is refused before anything is begun.test_classify.py: the cut-off unit is infrastructure for the classifier and the live board.test_standard_container.py: the relay's container is given the ledger and its folder alone.python3 app/tests/parallel.py(1657 tests) and route suite (356 tests), OK, aftermainwas merged in.docs-driftscript: 0 findings.gpt-4o-miniat list price, 0.00024 USD a call, booked 0.0099):--max-usd 0.011: five ran, the sixth was cut off, four were not run, 0.0012 spent, as computed by hand;--backend docker, on the merged code: the containers' relays share the ledger; three ran, one was cut off, two were not run;--price: the run ended and the result carries what was spent;Risk
--max-usd; without it no ledger exists and no call is booked.SpendingCapErrorbeside it, not as an outcome of its own: a new outcome would reach the palette, the judge's vocabulary and the field guide.flockon a file beside the ledger, as an install is locked. On Docker Desktop a benchmark's own relay (an option's embeddings) runs on the machine while the units' relays run in the VM; whether the lock holds between the two was not tested.--priceor an own price): the public list names models as their providers do.Undone by a revert; a job written with
budgetin its result stays readable.