Repository navigation
Conversation
…urons The usage() hook returned amount: null on the premise that Cloudflare publishes no API for per-account Neurons. magpie renders a null amount as a full allowance (10,000 / 10,000, 100% left), so an account that had already burned its whole day showed as untouched while every request failed with 'used up your daily free allocation'. Cloudflare's GraphQL Analytics API does report per-account Neurons (aiInferenceAdaptiveGroups.sum.totalNeurons). Sum today's buckets into amount; keep null (with a display hint naming the missing scope) when the token lacks Account Analytics -> Read, the payload carries errors, or the request fails. An empty bucket list stays a real zero.
UsageWindow.span is documented as seconds (internal/plugin/providers.go), but the window carried DAY_MS (86,400,000). magpie reads it as seconds and derives the window start as resetsAt - span: 2026-10-25 minus 1,000 days lands on 2024-01-29, the bogus '1月29日' the quota card chart showed.
|
Added 5241c21: the window's |
magpie's router benches an exhausted channel on the window's used percent (Allowance.Full), not on Amount/Limit — Amount only feeds the card. With amount known, also report used = min(100, 100*amount/limit) so a spent account rests until resetsAt (next UTC midnight) instead of cycling the 15-minute no-reset quota backoff.
|
Added 1e3bd71 after verifying the routing path in magpie's source: the router benches an exhausted channel on the window's |
Problem
The
usage()hook hard-codedamount: nullon the premise that "Cloudflare publishes no REST for per-account Neurons (dashboard only)". magpie renders a null amount as a full allowance, so an account that had already burned its entire daily 10,000 Neurons showed as 10,000 / 10,000 · 100% remaining while every inference request failed with:Verified live on 2026-10-24: the account consumed 10,756.27 Neurons in one 16-minute window (Cloudflare GraphQL Analytics), after which the gateway silently stopped routing to Workers AI members for the rest of the day — and the quota card still read 100% remaining.
Fix
Workers AI indeed has no REST endpoint for Neurons, but the GraphQL Analytics API does —
POST /client/v4/graphql,aiInferenceAdaptiveGroups.sum.totalNeurons, filterable bydatetimeHour.usage()now:amount(an empty bucket list is a real zero; a missing list, anerrorspayload, or a failed request keepsnullwith adisplayhint naming the missingAccount Analytics → Readscope);usedpercent (min(100, 100 · amount / limit)) — this is what the router acts on (see below);spanin seconds per the contract (internal/plugin/providers.go:// seconds); the previous86,400,000(ms) made magpie derive the window start asresetsAt − span= 2026-10-25 minus 1,000 days = the bogus2024-01-29the card chart showed;resetsAt, plan detection, fallbacks).Verified against the real API: a token without the Analytics scope returns
200+{"code":"authz","message":"not authorized for that account"}— handled as unknown, no crash, no fake zero. Same query against a token with the scope returns the true consumed amount (10,756.27 for the account above).Routing-layer effect (why this matters beyond the card)
Cloudflare's 429 carries no reset hint — no
Retry-Afterheader, no timestamp in the body (verified against the live endpoint). magpie's router then falls back toquotaRest = 15 * time.Minute(internal/gateway/routing.go: "out of quota, with no word of when it resets"): the channel is retried every 15 minutes, eats a 429, and rests again — for the ~10 hours until 00:00 UTC, while the card's countdown shows a meaningless "recovers in ~14 minutes".Once this plugin reports
used ≥ ~100%with the window'sresetsAt, the router takes the other branch:Allowance.Full(internal/provider/routing.go) benches the channel until the window renews (capped atlongestQuota = 8 days; seeTestRoutingHoldsAWindowRestToLongestQuota). So the fix is not cosmetic — it is what finally tells magpie when the quota is back. Note the router keys on theusedpercent, not onamount/limit(those only feed the card) — hence theusedfield in the window.Tests
test/plugin.test.mjs(sum → amount + used%, 403 → null, errors-payload → null + empty-day → 0):node --testpasses 18/18Account Analytics → Readscope and the misleading-full-allowance symptom in TroubleshootingNote for reviewers: magpie core still renders
amount: nullas an untouched allowance (UsageWindow.Amount float64+app.jsw.amount || 0), which amplifies this — tracked in yetone/magpie#3487.