Skip to content

page-model-quota: the tokens each model has left, across accounts - #932

Open
1sh1ro wants to merge 2 commits into
magpie-community:mainfrom
1sh1ro:contribute-page-model-quota
Open

1sh1ro wants to merge 2 commits into
magpie-community:mainfrom
1sh1ro:contribute-page-model-quota

Conversation

@1sh1ro

@1sh1ro 1sh1ro commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Moves Model Quota into the community repository as @magpie-community/page-model-quota, so it is listed under Plugins -> Discover -> Pages with the community badge instead of only by search.

What the page shows: how many tokens each model has left, merged across every account and every provider. Each quota window is turned into tokens from the local usage history (tokens spent over the percentage that round dropped, median over complete rounds), then split by each model's share inside that window and added up per model.

  • page/ is the launcher; lib/server.mjs is the local service, started by index.mjs and stopped with the plugin; lib/report.mjs holds the estimation and has no I/O.
  • No runtime dependencies. Reads usage.jsonl, quota-history.json, quotas.json and the local gateway's /v1/magpie/quotas.
  • permissions is empty: the page reads nothing through the bridge.
  • Service binds 127.0.0.1 only, on 3496. Host must be the bound address; every /api route except /api/ping needs a key generated at each start and injected into the HTML, which is served only to navigations. Origin: null is accepted only with the key.
  • �un test covers the guards, the estimate and the launcher; �un scripts/check.mjs page-model-quota passes.

The registry entry is renamed in the same commit: the npm name it lists has to be the package this repository publishes. The magpie-model-quota package on npm stays as it is, for installs by name.

@yetone yetone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for bringing Model Quota into the repo. To be clear about what this PR is: it is the same plugin as magpie-model-quota 0.1.2 on npm, the one #919 listed earlier today, moved in under @magpie-community/page-model-quota. lib/report.mjs is byte for byte the same. The server changes are the port (3497 to 3496) and how startServer gets its options. The registry entry is swapped in the same commit. That's fine, and it doesn't overlap magpie's own quota views, which show each account's windows as percentages, not tokens per model across accounts.

What I ran at 660ad42, in WSL (Ubuntu 24.04):

  • node --test test/*.test.mjs and bun test: 10/10 pass. bun scripts/check.mjs: passes.
  • Server in a sandbox HOME with the gateway unreachable:
    • Wrong Host (attacker.localhost, 127.0.0.2, another port, no port, localhost., [::1], evil.com) gets 403.
    • Origin: null without the key gets 401. A foreign Origin with the key gets 403. No key or a wrong key gets 401.
    • index.html requested with Sec-Fetch-Mode cors or no-cors gets 403. Path traversal (.., %2e%2e, ..%2f, ..%5c) gets 404.
    • With the key, a request from 127.0.0.1, from localhost with its own Origin, and from Origin: null each gets 200.
    • A restart gives a new key, and the old key gets 401. Nothing is written under HOME. The only fetches go to magpie's gateway and to its own /api/ping.
  • I broke the Host check, the Origin check, the key check and the navigate-only rule by hand, one at a time. A test goes red for each one.

One thing to fix before merge: i18n. The English page shows Chinese text, because the server puts Chinese strings into the report and ui/app.js displays them as they are:

  • lib/report.mjs: a pool with no model split is named "(未分模型)". app.js renders model.name || model.id || t.unassigned, so t.unassigned never shows. Please send an empty name (or a flag) and let the UI pick the word.
  • lib/report.mjs: a pool key for an account with no user is built with "(无账号)". That key is shown in the Window column and in the detail rows.
  • ui/app.js: the low-confidence cell is built as "(" + t.historical + ")", so English gets full-width brackets. Please put the brackets in the words strings.

Not blocking:

  • zh-TW gets Simplified Chinese. The other page packages do the same.
  • ui/index.html keeps lang="en" when the page is in Chinese.
  • Users who installed magpie-model-quota by name keep that copy. An npm deprecate magpie-model-quota "moved to @magpie-community/page-model-quota" would point them to this one.

Once those three are fixed, I'll run everything again and merge.

@1sh1ro
1sh1ro force-pushed the contribute-page-model-quota branch from 3dd7c9e to a5d9a8c Compare November 10, 2026 14:09
@1sh1ro

1sh1ro commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

i18n fixed in a5d9a8c, and the branch is rebased onto main (4a06364); the registry conflict with page-harnessweight is resolved by keeping both entries.

  • lib/report.mjs no longer puts words into the report. A pool with no model split sends an empty name, so �pp.js shows .unassigned. method is now median / single / sparse with usableRounds, and �lockedAccounts carries window instead of a sentence.
  • A pool key for an account with no user is provider·window, with no placeholder word.
  • ui/app.js: the low-confidence cell is mtTokens(tokens) + t.historical, and historical holds its own brackets in each language.
  • Also set document.documentElement.lang from the page's language, so ui/index.html no longer stays en on a Chinese page.

A new est/i18n.test.mjs fails if any Chinese string literal appears in lib/report.mjs, if the unassigned name or the no-account key comes back, or if the brackets go back outside words.

�un test packages/page-model-quota: 14 pass. �un scripts/check.mjs: passes.

On the two non-blocking notes: zh-TW keeping Simplified Chinese matches the other page packages, and the
pm deprecate for magpie-model-quota needs your npm account — I can do it if you want, or leave the old package as it is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants