Repository navigation
feat(quota-bottle): show the Token Plan quota from your own credential - #116
Conversation
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
Thanks for this, the quota bottle is a genuinely useful idea. Three things need to change before we can merge:
- Don't borrow the desktop's signed-in session.
miniapp/node/desktop-lease.mjsreads<data root>/run/mcode-auth-lease-v1.capand takes a lease on MiniMax Code's token. The host reserves that lease for its built-in tools; it isn't open to MiniApps. Please remove this path and rely only on an API key or OAuth the user configures themselves. - Don't remove fields from the user's
~/.mmx/config.json. When the user signs in from the panel,saveOauthinauth/auth.mjsdeletes their existingapi_keyandbase_url. The UI says the token will be saved there, but not that anything gets removed. Please store credentials in the plugin's own data directory, or if you must write the shared config, ask first and keep existing fields. - Make reading the host database optional and off by default. Reading
v2/sqlite/runtime-state.sqlitedepends on an unpublished host schema that can break on upgrade, and it touches local usage data. Please put it behind a default-off switch and document in the README what it reads and why.
Ping me when it's updated and I'll take another look.
| * The lease endpoint lives next to the runtime state, not inside it. | ||
| * @param {string} dataDir | ||
| */ | ||
| export function resolveDesktopDataRoot(dataDir) { |
There was a problem hiding this comment.
This walks up from the plugin's dataDir to locate the host's data root. MiniApps shouldn't depend on or reach into the host's directory layout.
| if (signal?.aborted) return { ok: false, code: 'desktop_unavailable' }; | ||
| let capability; | ||
| try { | ||
| capability = (await readFile(capabilityFile, 'utf8')).trim(); |
There was a problem hiding this comment.
Reading the host's mcode-auth-lease-v1.cap is the core issue: the lease is reserved for the host's built-in tools, not MiniApps. Please remove this path.
| // The client's region is not ours to know: the first read discovers it, | ||
| // and later reads start with the region that answered. | ||
| const preferred = lastLiveRegion ?? (await readConfiguredRegion()); | ||
| const session = await fetchDesktopSessionQuota(context, { |
There was a problem hiding this comment.
The desktop-session path is the default here. Once the lease path is removed, this should fall back to the user's own API key / OAuth.
| export async function saveOauth(region, credentials, signal) { | ||
| await updateConfigFile((raw) => { | ||
| if (signal?.aborted) throw new Error('aborted'); | ||
| delete raw.api_key; |
There was a problem hiding this comment.
This silently deletes the user's existing api_key in the shared CLI config. Please don't remove fields the user set.
| delete raw.api_key; | ||
| raw.oauth = { ...credentials, region }; | ||
| raw.region = region; | ||
| delete raw.base_url; |
There was a problem hiding this comment.
Same for base_url. Prefer storing credentials in the plugin's own data directory.
…usage Review follow-up on MiniMax-AI#116. - Remove the host auth-lease path; the live quota now comes only from a device-code login stored under context.dataDir or a read-only API key / OAuth access token the user configured in the CLI config. - Stop rewriting ~/.mmx/config.json. Login and refresh write dataDir/credentials.json; CLI fields are never removed. - Make the host SQLite usage scan opt-in (default off) with a panel switch, and resolve its data root only from MINIMAX_DATA_DIR / MAVIS_HOME / ~/.minimax. - Accept the account service's absolute 48-hour token expiry; the old 24-hour cap made a successful login look like an error. - Fill the ears, neck and mouth at 100%, and show the reset countdown, weekly quota and video usage in the floating window. Version 1.15.3.
An octopus-shaped glass bottle that floats in a 220 × 300 window and shows the remaining Token Plan quota the desktop itself reports, with a device-code login and a local token-usage estimate as fallbacks. - Quota source: the desktop's own session, borrowed through its auth lease. One GET /v1/api/openplatform/coding_plan/remains with the leased token; no client signature and no group lookup. - The account region is discovered, not guessed: the leased token is offered to both Token Plan origins and the one that answers is the client's. - The page follows the client's language (Chinese or English) and carries a 中 / EN switch. - The window is dragged from page code with screen coordinates, because -webkit-app-region is inert in a webview guest; the page also asks for its size again when the client remembers another one. - The page paints no backdrop, so the window is transparent on the native renderer; on the webview backend the guest surface is opaque, a client limitation tracked in MiniMax-AI/minimax-code#597. Verification: node --test "tests/*.test.mjs" passes 84 tests; node scripts/validate.mjs plugins/7723qqq/quota-bottle reports OK; a live desktop session on the CN region returned a quota without a second login.
…usage Review follow-up on MiniMax-AI#116. - Remove the host auth-lease path; the live quota now comes only from a device-code login stored under context.dataDir or a read-only API key / OAuth access token the user configured in the CLI config. - Stop rewriting ~/.mmx/config.json. Login and refresh write dataDir/credentials.json; CLI fields are never removed. - Make the host SQLite usage scan opt-in (default off) with a panel switch, and resolve its data root only from MINIMAX_DATA_DIR / MAVIS_HOME / ~/.minimax. - Accept the account service's absolute 48-hour token expiry; the old 24-hour cap made a successful login look like an error. - Fill the ears, neck and mouth at 100%, and show the reset countdown, weekly quota and video usage in the floating window. Version 1.15.3.
526618a to
80857c2
Compare
|
Updated — rebased onto latest The three review items are addressed:
Also fixed the login failure: the account service returns Ready for another look. @MyPrototypeWhat |
|
Thanks, all three points are addressed: the auth-lease path is gone, the plugin now keeps its own token in its data dir and only reads |
|
Done — dropped the 提示词优化 row from |
MyPrototypeWhat
left a comment
There was a problem hiding this comment.
Looks good, thanks!
Adds
quota-bottle: an octopus-shaped glass bottle that floats in a 220 × 300 window and shows how much Token Plan quota is left. The liquid level and its opacity follow the remaining share; at 100% the liquid reaches the mouth, so the ears, neck and mouth are filled too.Review follow-up
This revision addresses the three review items and the login failure found while testing it.
desktop-lease.mjs,desktop-session.mjsand their tests are removed. The bottle no longer readsmcode-auth-lease-v1.capor any other Host credential.<context.dataDir>/credentials.json.~/.mmx/config.jsonis read-only; itsapi_key,base_urland other fields are never removed.MINIMAX_DATA_DIR,MAVIS_HOMEor~/.minimax; the path and schema are documented as unpublished Host layout.expired_inas an absolute millisecond timestamp about 48 hours out. The old 24-hour cap treated a successful login as an error; token expiry now allows a 30-day horizon while a device code keeps the 24-hour cap.Version 1.15.3.
Where the number comes from
The live quota has one source: a credential you configure yourself.
<context.dataDir>/credentials.jsonand refreshes it there.GET <baseUrl>/v1/token_plan/remainswithAuthorization: Bearer <token>.~/.mmx/config.json(or$MMX_CONFIG_DIR/config.json) is read, never written: an API key, or an OAuth access token that is still valid. A CLI-owned token is not refreshed or rotated; when it expires the panel offers its own login.If neither can answer, the page falls back to a manual total plus an opt-in local token-usage estimate. The scan is off by default; when on, it reads a read-only SQLite snapshot of
<data root>/v2/sqlite/runtime-state.sqlite, tablelocal_runtime_token_usage, and removes the snapshot after the query. Usage above the saved total is reported as its own state, not clamped into a believable-looking empty bottle.The window
surface.windowis 220 × 300, frameless, transparent, always-on-top, non-resizable. Two client behaviours are handled:-webkit-app-region: draghandle for renderers that honour it, and the page also moves the window itself in screen coordinates, because a webview guest ignores the app-region. Only one path is ever live: where the drag region exists it swallows the pointer events first.The compact meter shows the percentage and token amount, then the reset countdown, the weekly quota and the video model's used share when the response carries them.
Known client-side limitation. On the
webviewrenderer backend the guest surface is opaque, so the window is a black rectangle even though the page paints nothing (a headless render of the same page has alpha 0 at all four corners). The same package is transparent on the native backend. Tracked in MiniMax-AI/minimax-code#597.Interface
Chinese and English. The page follows the client's language on first run (
navigator.language) and the 中 / EN buttons in the header switch it and remember the choice.Data & access
<context.dataDir>/credentials.json;~/.mmx/config.jsonor$MMX_CONFIG_DIR/config.jsonread-only;<data root>/v2/sqlite/runtime-state.sqliteread-only and only when the usage scan is on; its own page,quota.jsonandsettings.json.<context.dataDir>/credentials.json;<context.dataDir>/quota.json;<context.dataDir>/settings.json; temporary SQLite snapshots underdataDir, only when the scan is on, removed after each read. No CLI or Host file is written.account.minimaxi.com/account.minimax.io,api.minimaxi.com/api.minimax.io. Credentialed requests never follow redirects. Tokens never reach the page, a log, or an error response.agentAccess,toolAccessordeviceAccess: no Agent turns, no conversations read, no tools called, no microphone.Verification
node --test "tests/*.test.mjs": 85 tests pass.node scripts/validate.mjs plugins/7723qqq/quota-bottle: OK.Open in [code]smith · Need help with this PR? Tag
@codesmith-botwith what you need.