Repository navigation
feat(queen): endpoint pools and a worker ceiling of 1024, onto the branch production builds - #485
Merged
gHashTag merged 4 commits intoSep 17, 2026
Conversation
…URL was the whole pool Measured on 2026-09-17 in production: ten working Z.ai keys carried sixteen bees while three working NVIDIA keys sat unused beside them. A key handed to a bee is only as good as the URL the bee sends it to, and the deployment has exactly one: TRIOS_QUEEN_WORKER_BASE_URL, one model, every generic key sent there. Putting an NVIDIA key into TRIOS_QUEEN_WORKER_API_KEY_n would not widen the swarm, it would hand a bee a 401 that arrives blamed on the work. So there are now numbered endpoint pools. The FIRST pool is the variables that already exist, unchanged in name and meaning. Further pools start at 2: TRIOS_QUEEN_WORKER_POOL_<n>_BASE_URL the endpoint (required) TRIOS_QUEEN_WORKER_POOL_<n>_MODEL the model that endpoint serves (required) TRIOS_QUEEN_WORKER_POOL_<n>_PROVIDER openai-compatible (default) or zai TRIOS_QUEEN_WORKER_POOL_<n>_CONTEXT that model's context window TRIOS_QUEEN_WORKER_POOL_<n>_API_KEY, _API_KEY_2 ... _API_KEY_16 What travels to /chat - provider, base URL, model, context window - comes from the same pool as the key. One allocator runs over the concatenated list, so a wave of bees takes one credential of every pool before any key carries a second lane: the rule availableKeyIndex already applied inside one pool. queen_dispatch.key_index is one integer, read back every tick to learn which credentials are busy. First-pool keys keep the index they have always had, so rows in flight across the deploy still mean the same key. A key of pool n is (n - 1) * POOL_KEY_STRIDE + position (pool 2 starts at 1000). The pool NUMBER is used rather than its rank among today's valid pools, so disconnecting pool 2 does not rename every busy key of pool 3. Deliberately not changed: - A single endpoint takes the old code path byte for byte; every existing test passes untouched (66 before, 78 after). - The closed breakdown (browseros-ai#1308) stays three integers. Lanes per credential stay one number for the deployment, which keeps it an exact statement: credentials x lanes, bounded by the policy ceiling. No pool name, URL or variable name enters it. - An explicit endpoint stays authoritative, including its refusal: a valid second pool does not take over from a first pool with no key. - A local Ollama stays one measured inference slot and reads no pools. - The model is required per pool and never inherited: the first pool's model name sent to another provider is a 404. - One secret named by two pools is one credential (browseros-ai#1293). A pool someone began to configure and dispatch ignored reads as configured in a variable editor and supplies nothing. endpointPoolProblems() names the missing variable (names only, never a value), and the "every key is busy" refusal carries it, because that is the moment an operator asks why the swarm is narrower than the variables suggest. The dispatch detail printed `key ${keyIndex + 1}`; with a durable index of 1002 that would read "key 1003/3". It now prints the pool and the position in it. Applies cleanly to fix/queen-worker-provider-and-prompt-size (the branch production deploys from) as well as to feat/queen-supervisor. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…here a loop ended keysFor() read the unsuffixed variable and then _2 ... _16. Sixteen was never a measurement: it is where the loop happened to stop, and it equals the policy ceiling on bees only by coincidence. They are different quantities. The ceiling bounds how many bees RUN. The key list bounds how many credentials the rotation may SPREAD them over - and a free key refuses its third concurrent request in under half a second (1302), so a swarm at the ceiling wants more keys than bees, not the same number. A TRIOS_QUEEN_WORKER_API_KEY_17 was therefore read by nothing and reported by nothing: it looks configured in a variable editor and supplies nothing, the zero-length-key trap one step to the right. The suffix now runs to MAX_KEYS_PER_POOL = 1000, for every pool and for the legacy provider variables alike (they share keysFor). Widening the list does not widen the swarm: queenWorkerLimit() still answers at most 16, and a test pins seventeen credentials to a capacity of sixteen. POOL_KEY_STRIDE moves from 1000 to 10000 with it. The durable index of pool n starts at (n - 1) * stride, so a pool that could hold `stride` keys would have its last key collide with the next pool's first. Nothing has been written with the old stride - it exists only in this pull request - and a test now holds MAX_KEYS_PER_POOL below POOL_KEY_STRIDE so the two cannot drift. Dispatch tests: 81 pass (78 before this commit). Typecheck clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…g of 1024 MAX_KEYS_PER_POOL becomes 1024. With one lane per credential a swarm of N bees needs N keys, so a key bound under the worker bound is a second, hidden ceiling that reports nothing when it is hit. The operator is asking for the policy ceiling to be raised to 1024; a round thousand would have been that hidden ceiling the day it was. The worker ceiling itself is NOT changed here - it is a policy with a Swift mirror, and raising it is a separate, deliberate decision. Dispatch tests: 81 pass. Typecheck clean. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…s deployment The policy clamped TRIOS_QUEEN_MAX_WORKERS to 16 in three places. Sixteen was not a measurement of this deployment: it is where the number happened to be written when the swarm had one endpoint. Once a deployment could connect a second provider's endpoint and its keys, that clamp sat BELOW the credentials already paid for - and a clamp says nothing when it clamps, so the capacity a swarm did not get was reported by no line anywhere. The bound moves to 1024, which is a guard against a typo rather than a working value. What a deployment runs is decided by connected credentials times lanes per credential, and by the number the operator sets. "Review cost is linear in running workers" is still true and is exactly why that number is chosen by measurement - raised in steps until container memory, worktree disk, the remaining GitHub API quota or the review backlog is the thing that binds. That is a reason for the value in the environment, not for a constant in code. The three copies move together in this one commit, because the failure this number already had was drift: the TypeScript side was raised alone once and the swarm reported `capacity: 12` while every tick refused at "limit 4". The default is untouched. Unset, unreadable or below one still means four. Verified against the compiled policy rather than the source: unset -> 4, 64 -> 64, 5000 -> 1024, unparseable -> 4; and on the dispatch side seventeen credentials under a ceiling of 64 now answer 17 instead of 16. - rings/SR-00/QueenDelegation.swift - agent-server/queen-core/Sources/QueenPolicy/QueenDelegation.swift (byte-identical) - agent-server/apps/server/src/api/services/queen-dispatch.ts queen-core-sync reports QueenDelegation.swift in sync, queen-core compiles, ring00_parity is green (it pins the default of 4, which did not move), and queen-dispatch.test.ts is 82 pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
merged commit Sep 17, 2026
d513a72
into
fix/queen-worker-provider-and-prompt-size
17 of 20 checks passed
❌ Tests failed — 7/2144 failed
Failed tests
|
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.
Railway's
trios-agent-serverdeploys fromfix/queen-worker-provider-and-prompt-size(confirmed against the Railway API:repoTriggers.branch, roottrios/agent-server). #484 and the ceiling commit landed onfeat/queen-supervisor, which production does not build. This carries the same four commits here so the change reaches the running container.Cherry-picked, unmodified:
f8f23f391numbered endpoint pools (feat(queen): a second provider's keys had nowhere to go, because one URL was the whole pool #484, commit 1)9e98cab55the key list runs toMAX_KEYS_PER_POOL(feat(queen): a second provider's keys had nowhere to go, because one URL was the whole pool #484, commit 2)31e1190a0MAX_KEYS_PER_POOL = 1024, belowPOOL_KEY_STRIDE(feat(queen): a second provider's keys had nowhere to go, because one URL was the whole pool #484, commit 3)c4e80e7f4the worker ceiling moves 16 -> 1024 in all three copies at onceVerified on this branch
bun test tests/api/queen-dispatch.test.ts: 82 pass, 0 fail.QueenDelegation.swiftare byte-identical.grep "parsed, 16"over the three policy sources returns nothing.64-> 64,5000-> 1024, unparseable -> 4. The default did not move.Pre-existing on this branch, not introduced here
bun run typecheckreports two errors inqueen-tick.ts(2197, 2202). They are present on0e37000d8before any of these commits; this branch is behind the mainline where that was fixed.Not done here
TRIOS_QUEEN_MAX_WORKERSis not changed. 1024 is a bound against a typo; the working value is chosen by measurement.Co-Authored-By: Claude Opus 5 noreply@anthropic.com
🤖 Generated with Claude Code