MiniMax: recharge credits, usage dashboard, and quota utilization#1821
MiniMax: recharge credits, usage dashboard, and quota utilization#1821Yuxin-Qiao wants to merge 37 commits into
Conversation
MiniMax API remains responses omit the console recharge-credit balance. Fetch it from token_plan_credit when a browser session cookie is available, including API-token refreshes that also have cached or manual cookies. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Codex review: needs changes before merge. Reviewed July 3, 2026, 2:12 PM ET / 18:12 UTC. Summary Reproducibility: yes. for the review findings: source inspection shows the API enrichment path calls a candidate chain that omits MiniMax Agent cookies and reads saved manual cookies without checking Review metrics: 2 noteworthy metrics.
Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Fix the remaining source-selection and packaging safeguards before merge, then land the MiniMax feature with focused resolver/importer/package tests and the existing live proof. Do we have a high-confidence way to reproduce the issue? Yes for the review findings: source inspection shows the API enrichment path calls a candidate chain that omits MiniMax Agent cookies and reads saved manual cookies without checking Is this the best way to solve the issue? No: the feature direction is useful, but the current implementation is not the narrowest maintainable solution until cookie-source precedence and package path deletion are made explicit and tested. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against 61ff93208255. Label changesLabel changes:
Label justifications:
Evidence reviewedSecurity concerns:
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88dfac6c95
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| usage = await MiniMaxUsageFetcher.attachingTokenPlanCreditIfAvailable( | ||
| to: usage, | ||
| context: fetchContext, | ||
| groupID: MiniMaxCookieHeader.override(from: cookieHeader)?.groupID) |
There was a problem hiding this comment.
Preserve MiniMax group IDs from cookie overrides
When the configured cookie value is a curl command whose group is only present as x-group-id or a GroupId URL parameter, resolveCookieHeader has already stripped the raw value down to just the Cookie header before this re-parse runs. That drops the group ID even though MiniMaxCookieHeader.override supports extracting it, so the token_plan_credit request omits x-group-id and can fetch no balance or the wrong group balance for multi-group accounts; carry the original MiniMaxCookieOverride through this path instead.
Useful? React with 👍 / 👎.
| return MiniMaxCookieHeader.override(from: raw)?.cookieHeader | ||
| } | ||
| #if os(macOS) | ||
| return CookieHeaderCache.load(provider: .minimax)?.cookieHeader |
There was a problem hiding this comment.
Avoid merging cached cookies into unrelated API results
When a user has a MiniMax API key for one account but the cached browser cookie belongs to another, this automatic cache fallback supplies that cookie to the API strategy and the new enrichment attaches the cookie account's pointsBalance to the API-key quota. The cache entry is not compared with any account or group in the API response, so this can render and export a balance for a different account; require an explicit cookie for API enrichment or verify the account before merging.
Useful? React with 👍 / 👎.
| let fetchContext = MiniMaxUsageFetcher.WebFetchContext( | ||
| cookie: cookie, | ||
| authorizationToken: nil, | ||
| region: region, |
There was a problem hiding this comment.
Use the region that actually served the API quota
For API-key users who leave the region at the default, fetchUsage(apiToken:region:) first tries global and then silently retries China when the global host rejects the key (see the existing retries china host when global rejects token coverage). If that China retry succeeds, this enrichment context still uses the original .global region, so the balance request goes to www.minimax.io instead of www.minimaxi.com and misses the cookie-authenticated credit balance for those existing China-region accounts.
Useful? React with 👍 / 👎.
| if let host = MiniMaxSettingsReader.hostOverride(environment: environment), | ||
| let hostURL = URL(string: "https://\(host)")? | ||
| .appendingPathComponent("backend/account/token_plan_credit") |
There was a problem hiding this comment.
Keep credit fetches on the web host under host overrides
When users set the documented general override such as MINIMAX_HOST=platform.minimaxi.com (or an API host), this branch rewrites the new credit endpoint to https://platform.minimaxi.com/backend/account/token_plan_credit. The endpoint added in this patch defaults to the www.minimaxi.com/www.minimax.io web hosts, so these valid existing host-override setups silently lose the recharge balance after the 404 is swallowed; either keep the default web host for this endpoint or require the specific MINIMAX_TOKEN_PLAN_CREDIT_URL override for proxies.
Useful? React with 👍 / 👎.
Propagate cancellation from token-plan credit enrichment, keep credit fetches on www hosts under MINIMAX_HOST overrides, use the API region that actually served quota, preserve curl group IDs, and only merge explicit cookies into API refreshes. Fix released changelog structure and expand regression tests. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@clawsweeper re-review Addressed the review items in 972cffa:
Proof: API-only diagnose from the built PR CLI is attached in the updated PR body. Full recharge-balance proof still needs an explicit MiniMax cookie on the contributor account (manual settings or |
|
🦞🧹 I asked ClawSweeper to review this item again. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 972cffac68
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if let override = MiniMaxSettingsReader.tokenPlanCreditURL(environment: environment) { | ||
| return override | ||
| } | ||
| return region.tokenPlanCreditURL |
There was a problem hiding this comment.
Respect host override when choosing credit region
When MiniMax is configured only through the documented MINIMAX_HOST=platform.minimaxi.com env override and no persisted region, quota/billing requests resolve to the China host, but this fallback ignores that override and still sends the new credit lookup to region.tokenPlanCreditURL (defaulting to www.minimax.io). Fresh evidence after the prior host-override comment is that the updated resolver now avoids the platform host but still uses the global web host for China MINIMAX_HOST setups, so those existing env-based users silently lose pointsBalance unless they also know to set MINIMAX_TOKEN_PLAN_CREDIT_URL.
Useful? React with 👍 / 👎.
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
No code changes; prior macOS test shards were cancelled by cancel-in-progress from rapid pushes. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8d40b54e3c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let resolved = MiniMaxAPIRegion(rawValue: region), | ||
| self.settings.minimaxAPIRegion != resolved | ||
| else { return } | ||
| self.settings.minimaxAPIRegion = resolved |
There was a problem hiding this comment.
Avoid persisting detected MiniMax region across accounts
When a selected MiniMax token account only succeeds after the global→China retry, this writes .cn into the provider-wide setting. That setting is then reused for other MiniMax token accounts, and fetchAPITokenUsage does not try the global host when the preferred region is already .cn, so any configured global account can start failing on later refreshes until the user manually changes the shared region back. Keep the auto-detected region scoped to the current account/fetch, or only persist it when there are no token accounts to mix.
Useful? React with 👍 / 👎.
Route credit lookups from MINIMAX_HOST, fall back to env cookies when manual settings are empty, and relax the gated live balance assertion. Co-authored-by: Cursor <cursoragent@cursor.com>
|
@clawsweeper re-review Addressed the open findings in 227ed49:
|
|
🦞🧹 I asked ClawSweeper to review this item again. |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6c49ef2925
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| var providerConfig = config.providerConfig(for: provider) ?? ProviderConfig(id: provider) | ||
| guard providerConfig.region != trimmed else { return } | ||
| providerConfig.region = trimmed | ||
| config.setProviderConfig(providerConfig) | ||
| try store.save(config) |
There was a problem hiding this comment.
Avoid persisting region from env-only CLI probes
When codexbar usage/diagnose is run with only a temporary MINIMAX_CODING_API_KEY in the environment and the global request falls back to China, this CLI updater creates or updates the persisted MiniMax provider config and saves region = cn. This separate CLI path means a one-shot env probe changes later app/CLI refreshes, and because fetchAPITokenUsage does not try global once the preferred region is .cn, a subsequent global key can fail until the user manually resets the setting; skip this updater for env-backed credentials or scope it to a stored MiniMax config.
Useful? React with 👍 / 👎.
|
@codex review Addressed the remaining MiniMax region findings in
This prevents env-only probes and mixed global/China credentials from changing later routing. SwiftFormat and |
|
🦞🧹 I asked ClawSweeper to review this item again. |
Rebase onto latest PR fixes, add expiry UX with validated cache reuse on API enrichment, and prebuild MiniMax merged-menu content after open to cut first-switch latency. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 21857510e4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if let status = payload.baseResp?.statusCode, status != 0 { | ||
| let message = payload.baseResp?.statusMessage ?? "status_code \(status)" | ||
| throw MiniMaxUsageError.apiError(message) |
There was a problem hiding this comment.
Map usage-summary login errors to invalid credentials
When usage_summary returns HTTP 200 with base_resp.status_code like 1004/"not login" for an expired cookie, this throws apiError instead of invalidCredentials. attemptWebEnrichment only sets rejectedCredentials for invalidCredentials, so if the credit endpoint is unavailable or 404 the expired cached/explicit web session is reported as endpointsUnavailable and the cache/re-import path is not triggered; map login/cookie status messages here the same way the credit parser does.
Useful? React with 👍 / 👎.
| var components = DateComponents() | ||
| components.calendar = Calendar.current | ||
| components.timeZone = TimeZone.current | ||
| components.year = Calendar.current.component(.year, from: Date()) |
There was a problem hiding this comment.
Use the fetch year for daily-only summaries
When MiniMax omits date_model_usage and only provides daily_token_usage, last_update_time is just month/day, but this fills the year from the machine clock. Around New Year, e.g. viewing a 12-31 summary on January 1, 2027, the synthesized trend bars are dated December 2027 instead of December 2026; choose the fetch/snapshot year or nearest non-future date. Fresh evidence is that the updated anchoring still derives the year from Date() here.
Useful? React with 👍 / 👎.
| case .minimax: | ||
| guard let snapshot = self.snapshots[provider] else { return false } | ||
| return !self.planUtilizationSeriesSamples( | ||
| provider: provider, | ||
| snapshot: snapshot, | ||
| capturedAt: snapshot.updatedAt).isEmpty |
There was a problem hiding this comment.
Use the passed MiniMax snapshot for history recording
When multiple MiniMax token accounts are refreshed, recordFetchedTokenAccountPlanUtilizationHistory passes each non-selected account's snapshot into recordPlanUtilizationHistorySample, but this guard decides whether to persist by looking at the provider-wide self.snapshots[.minimax] instead. If the selected/current snapshot is nil or lacks MiniMax quota lanes, valid samples for the other account are dropped, so its Subscription Utilization history never persists; base this check on the already-computed sample/snapshot being recorded.
Useful? React with 👍 / 👎.
| SELECT host_key, name, value | ||
| FROM cookies | ||
| WHERE host_key LIKE '%minimax%' |
There was a problem hiding this comment.
Read encrypted MiniMax Agent cookie values
When the MiniMax Agent/Electron cookie DB stores secure cookies in the Chromium encrypted_value column with value empty, this query never retrieves those bytes and the import loop drops the row as an empty value. That makes the new desktop-session path miss _token/session cookies for logged-in Agent installs that use encrypted cookie storage; select and decrypt encrypted_value like the other Chromium cookie importers, or fall back to browser import instead of treating the desktop DB as empty.
Useful? React with 👍 / 👎.
Complete it/tr/id/pl catalogs after the session recovery strings landed in en, and mirror the same keys in zh-Hant. Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
Resolve CHANGELOG, menu usage-history cluster, and widget package reference conflicts while keeping MiniMax usage-summary sections. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 143ac2e193
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| static func apiEnrichmentCandidates(context: ProviderFetchContext) -> [Candidate] { | ||
| var candidates = self.explicitCandidates(context: context) | ||
| #if os(macOS) | ||
| candidates.append(contentsOf: self.cachedAndBrowserCandidates(context: context)) |
There was a problem hiding this comment.
Try MiniMax Agent cookies during API enrichment
When an API-token refresh succeeds, MiniMaxAPIFetchStrategy only asks apiEnrichmentCandidates for optional web data, but this candidate chain skips MiniMaxDesktopCookieImporter.importSession() even though the cookie-first web chain includes it. For users with a valid API key and a logged-in MiniMax Agent session but no manual cookie/cached browser import, quota data loads while pointsBalance and usage-summary enrichment stay unavailable despite the new automatic Agent source; add the desktop candidate here before the cached/browser candidates.
Useful? React with 👍 / 👎.
|
|
||
| extension StatusMenuTests { | ||
| @Test | ||
| func `merged menu prewarms MiniMax content before first switch`() { |
There was a problem hiding this comment.
Remove the duplicate MiniMax prewarm test
This test method is also declared in Tests/CodexBarTests/StatusMenuInstantOpenTests.swift with the same backticked name and no parameters, so the macOS test target hits an invalid redeclaration error before any tests can run. Rename or keep only one copy so swift test/make check can compile the suite.
Useful? React with 👍 / 👎.
| if let settings = context.settings?.minimax, | ||
| let header = settings.manualCookieHeader?.trimmingCharacters(in: .whitespacesAndNewlines), | ||
| !header.isEmpty, | ||
| let override = MiniMaxCookieHeader.override(from: header) |
There was a problem hiding this comment.
Respect MiniMax cookie source for API enrichment
When a user switches MiniMax cookies back to Auto/Off after pasting a manual cookie, this still adds the stored manual header as the first API-enrichment candidate; unlike the web fetch path, it does not require cookieSource == .manual. If that stale cookie is still valid for another account, the usage-summary/credit data from it is attached to the API-token quota and the loop stops before trying the cached/browser session the user selected.
Useful? React with 👍 / 👎.
| enrichedSnapshot = snapshot | ||
| } | ||
|
|
||
| guard includeBillingHistory else { return enrichedSnapshot } |
There was a problem hiding this comment.
Continue credit enrichment when billing history is off
When includeBillingHistory is false, this new guard returns before the usage-summary and token_plan_credit enrichment calls below, so the updated no-billing path never fetches pointsBalance/expiry or summary data even though only the billing-history request was meant to be skipped. Keep the billing-history fetch conditional, but let the later web enrichments run for valid cookie sessions.
Useful? React with 👍 / 👎.
- Remove duplicate merged-menu prewarm test from StatusMenuInstantOpenTests - Bundle provider-switcher perf timings into a struct for SwiftLint - Extract menuUpdateContext helper to shorten populateMenu body Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
Billing history toggles account/amount fetches only; token-plan credit and usage-summary enrichment should still run when includeBillingHistory is false. Co-authored-by: Yuxin Qiao <Yuxin-Qiao@users.noreply.github.com>
Summary
Token Plan recharge credit balance
GET /backend/account/token_plan_creditonwww.minimaxi.com/www.minimax.iowhen a web session cookie is available.MiniMaxWebEnrichmentResolver, trying candidates in order: manual/env cookie → MiniMax Agent desktop cookies → cached browser cookies → live browser import.MINIMAX_HOSTselects the matchingwww.*credit host for MiniMax-owned domains; custom proxy hosts route through the override path. UseMINIMAX_TOKEN_PLAN_CREDIT_URLfor a full custom credit URL.region: cninto config.pointsBalance; menu rendering reuses the existingMiniMax points balancecost row.Console usage-summary dashboard
usage_summary) alongside quota/credit enrichment when a web cookie is available.Web session enrichment (no MiniMax Code required)
~/Library/Application Support/MiniMax/Cookiesautomatically — no Chrome Keychain prompt.platform.minimaxi.com/www.minimaxi.comin Chrome, then press ⌘R once and approve the Keychain prompt if macOS asks for Chrome safe-storage access.Cookie:header into Preferences → Providers → MiniMax, or setMINIMAX_COOKIE.docs/minimax.mdwith the full source priority and capture steps.Follow-up fixes in this branch
platform.*.com/console/usage(not the Coding Plan page). Settings Open Token Plan still opens the Coding Plan page.remains_timevalues and falls back toend_time.MINIMAX_HOSTcustom proxies also routeusage_summaryenrichment; MiniMax-owned host overrides still map to the matchingwww.*summary host.cache_read_tokenseparately frominput_token.MenuCardModelTests) that failed CI on UTC runners.Review follow-up
Round 1 (
30cf613a/ ClawSweeper)MINIMAX_HOST/ resolved region instead of always using globalwww.minimax.iodiagnose/usageoutput (below)MINIMAX_LIVE_TEST_EXPECTED_BALANCEfor exact assertsMINIMAX_COOKIE/ env when manual cookie settings are emptyRound 2 (
@chatgpt-codex-connector)MINIMAX_HOSToverrides for usage-summary enrichmentMotivation
Users with recharge credits (for example 20,000 points in the MiniMax console) saw quota data via API key but
providerCostPresent: falsein diagnostics and no balance in the menu. The balance lives on a separate cookie-authenticated endpoint discovered from the platform web bundle.The console also exposes a separate usage-summary API with token/cost trends, cache-hit stats, and model breakdowns that CodexBar previously did not fetch or render. This PR adds that enrichment plus Codex-style quota utilization history without duplicating KPI blocks between the main card and submenus.
UI evidence (live Plus account, 2026-07-02)
Main card inline dashboard + credits
Shows 5h / Weekly quota rows, 6 KPI grid, cost trend, top-model line, pricing disclaimer, and 20,000 recharge credits with expiry.
Menu card usage notes (Settings preview)
Subscription Utilization (Session / Weekly history)
Codex-style quota utilization chart with Session/Weekly lanes; footer shows reset time + used %.
Token usage details submenu
7d/30d segmented trend, daily spend, per-model token/cost rows, and window spend KPIs.
Test plan
make checkswift test --filter MiniMaxswift test --filter MiniMaxTokenPlanCreditTestsswift test --filter MiniMaxUsageSummaryswift test --filter MiniMaxResetDescriptionTestsswift test --filter MenuBarMiniMaxResetTimeDisplayTestsswift test --filter UsageStorePlanUtilizationTestsswift test --filter MiniMaxDesktopCookieImporterTestsswift test --filter MiniMaxWebEnrichmentResolverTestsTZ=UTC swift test --filter 'minimax token plan model shows weekly quota'remaining_credits,balance_breakdown.total_balance, andtotal_credits - used_creditsProviderHTTPTransportStubconsole/usage$0.33for 1M input + 500k cache reads on M2.7)./Scripts/compile_and_run.sh— menu card, Usage Dashboard link, and both submenus verified locallyBehavior proof
API-only account (no web session): built PR CLI on this branch
→
source: api, quota present,pointsBalanceomitted (expected; web cookie required).API key + web session cookie (MiniMax Agent desktop or browser/manual): built PR CLI on this branch, 2026-07-02
{ "source": "api", "planName": "Plus", "pointsBalance": 20000, "usageSummaryPresent": true, "providerCost": { "period": "MiniMax points balance", "used": 20000 } }Commands:
Direct endpoint sanity check (same session cookie, redacted):
GET https://www.minimaxi.com/backend/account/token_plan_credit→remaining_credits: 20000,base_resp.status_code: 0.Notes for reviewers
token_plan_credit(console returnsnot login); a web_tokencookie is required for the balance.MINIMAX_TOKEN_PLAN_CREDIT_URL, plus existingMINIMAX_HOST/ remains / coding-plan overrides.docs/minimax.mddocs/screenshots/minimax-usage/for stable PR references.