MiniMax: usage summary dashboard UI#1982
Conversation
Add token_plan_credit enrichment for cookie-backed refreshes, MiniMax Agent desktop cookie import, API-token web enrichment resolver, and menu credit display. Co-authored-by: Cursor <cursoragent@cursor.com>
Surface console usage-summary KPIs, cost trends, and token usage details in the menu card and hosted submenus, stacked on the credit enrichment foundation. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Codex review: needs changes before merge. Reviewed July 8, 2026, 12:10 AM ET / 04:10 UTC. Summary Reproducibility: yes. Source inspection at the PR head reproduces the review blockers in formatter behavior, menu reachability, MiniMax auth parsing, group validation, Keychain access, and Codex credits fallback. Review metrics: 3 noteworthy metrics.
Root-cause cluster Members:
Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything. 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
Maintainer decision needed
Security Review findings
Review detailsBest possible solution: Land the MiniMax usage dashboard only after #1981 is resolved and this branch preserves existing formatting/Codex credits behavior, correctly gates cookies and Keychain access, validates MiniMax group identity, and wires the dashboard menu section. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection at the PR head reproduces the review blockers in formatter behavior, menu reachability, MiniMax auth parsing, group validation, Keychain access, and Codex credits fallback. Is this the best way to solve the issue? No. The feature direction may be useful, but this implementation is not yet the narrowest maintainable solution because it changes auth/session and existing menu behavior without preserving current safety guards. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against aa401f1d8b74. 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
Review history (2 earlier review cycles)
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a82bb6aae3
ℹ️ 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".
| import CodexBarCore | ||
|
|
||
| extension StatusItemController { | ||
| func addMiniMaxUsageSummarySectionIfNeeded(to menu: NSMenu, context: MenuCardContext) { |
There was a problem hiding this comment.
Wire MiniMax usage summary section into menu assembly
This new section is never called (repo-wide rg addMiniMaxUsageSummarySectionIfNeeded only finds this definition), so the Token usage details submenu plus the web-session recovery/source rows are not inserted into the MiniMax provider menu even after a summary is fetched. Daily-only summaries and re-import/login recovery actions are therefore unreachable; please call this from the provider-menu assembly path alongside the other provider-specific sections.
Useful? React with 👍 / 👎.
|
|
||
| enum MiniMaxUsageSummaryParser { | ||
| static func parse(data: Data) throws -> MiniMaxUsageSummary { | ||
| let payload = try JSONDecoder().decode(MiniMaxUsageSummaryPayload.self, from: data) |
There was a problem hiding this comment.
Decode MiniMax error payloads before requiring summary arrays
When the usage-summary endpoint returns a MiniMax base_resp-only error payload (for example a 200 JSON body with status_code: 1004 and no daily_token_usage/date_model_usage arrays), this decode throws keyNotFound before the status handling below can convert it to MiniMaxUsageError.invalidCredentials. In attemptWebEnrichment that falls into the generic catch, so expired cached web sessions are treated as endpoint failures and are not cleared; decode/check base_resp first or default the arrays to empty.
Useful? React with 👍 / 👎.
| region: context.region, | ||
| environment: context.environment, | ||
| transport: context.transport) | ||
| return snapshot.withPointsBalanceIfMissing(credit.balance, expiresAt: credit.expiresAt) |
There was a problem hiding this comment.
Validate the group before attaching token-plan credit
When a web quota fetch is scoped with a groupID but the token-plan credit response contains credit_packages_details for a different group, this helper still attaches that balance to the quota snapshot. attemptWebEnrichment already treats the same mismatch as accountMismatch, so a stale browser/local-storage group can now mix quota data for one MiniMax group with credit data for another; check credit.groupIDs against resolvedGroupID before calling withPointsBalanceIfMissing.
Useful? React with 👍 / 👎.
| KeychainNoUIQuery.apply(to: &query) | ||
|
|
||
| var result: AnyObject? | ||
| let status = KeychainSecurity.copyMatching(query as CFDictionary, &result) |
There was a problem hiding this comment.
Respect disabled Keychain access in desktop import
When MiniMax Agent has encrypted cookies and the user has enabled “Disable Keychain access”, this path still calls SecItemCopyMatching because the new desktop importer is invoked directly from MiniMax availability/enrichment instead of going through BrowserCookieAccessGate. That setting is supposed to disable Keychain reads, so guard safeStoragePassword/importSession with KeychainAccessGate.isDisabled before attempting to derive Chromium keys.
Useful? React with 👍 / 👎.
|
|
||
| #expect(BrowserCookieAccessGate.shouldAttempt(.arc, now: start.addingTimeInterval(3)) == false) | ||
| #expect(BrowserCookieAccessGate.shouldAttempt(.edge, now: start.addingTimeInterval(3)) == false) | ||
| #expect(BrowserCookieAccessGate.shouldAttempt(.chrome) == true) |
There was a problem hiding this comment.
Keep browser-cookie tests aligned with explicit retry
This expectation contradicts the implementation: BrowserCookieAccessGate.shouldAttempt only permits an interaction-required Chromium keychain source during a user-initiated withExplicitRetry scope, and this test sets .userInitiated without that scope. As written the assertion returns false (and the later Chrome-after-Dia assertion is also blocked by the family cooldown), so the updated test suite will fail unless the production gate behavior is changed too.
Useful? React with 👍 / 👎.
Drop duplicate instant-open helper, remove prewarm test without implementation, and align browser gate tests with upstream. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
For Codex cards where credits and error are both nil, this fallback now returns the metadata hint instead of no credits line, so a normal initial/disabled-credits state renders a credits bar saying credits are unavailable even though no failure occurred. Restore the Codex nil case before falling back to creditsHint, while keeping real errors and fetched credit values visible.
ℹ️ 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 summaryEnrichedSnapshot = try await self.attachingUsageSummaryIfAvailable( | ||
| to: enrichedSnapshot, | ||
| context: context, | ||
| groupID: groupID) |
There was a problem hiding this comment.
Honor optional-usage toggle before MiniMax web enrichments
When includeBillingHistory is false (wired from context.includeOptionalUsage in MiniMaxCodingPlanFetchStrategy.fetch), this method now skips only billing but still calls the usage-summary and token-plan-credit enrichments. Users who turned off optional credits/extra usage still trigger these extra MiniMax web endpoints even though the UI hides the results, so keep the previous early return or gate these enrichments behind includeBillingHistory as well.
Useful? React with 👍 / 👎.
| guard let snapshot = await self.costUsageFetcher.loadCachedCodexTokenSnapshot( | ||
| now: now, | ||
| codexHomePath: scope.codexHomePath, | ||
| historyDays: historyDays) |
There was a problem hiding this comment.
Preserve cached Codex refresh timestamps
Switching to the snapshot-only cache load means hydrateCachedTokenSnapshots no longer seeds lastTokenFetchAt/lastTokenFetchScope from the cache's lastRefreshAt. On app launch with a fresh Codex scan cache, the card hydrates cached data but the next non-forced token refresh sees no TTL marker and immediately starts another full cost scan, undoing the cache hydration performance benefit.
Useful? React with 👍 / 👎.
| if let fetchedSummary { | ||
| enriched = enriched.withUsageSummary(fetchedSummary) |
There was a problem hiding this comment.
Keep summary data when credit lookup fails
For API-token users with a valid web session, fetchedSummary is only attached inside the token-plan-credit success branch. If the usage-summary endpoint succeeds but the credit endpoint is unavailable, returns no matching groups, or cannot parse a balance, the summary is discarded and the session is reported as not enriched, so the new token usage details/cost dashboard stay hidden even though the useful summary data was fetched.
Useful? React with 👍 / 👎.
| return (Double(input) * inputRate) | ||
| + (Double(cacheRead) * cacheReadRate) |
There was a problem hiding this comment.
Avoid double-charging cache-read input tokens
When a MiniMax summary has cache_read_token > 0, total_input_token already includes those cache hits (the UI derives cache-miss input as input minus cache-read), but this formula charges all input at the full input rate and then charges the cached subset again at the cache-read rate. Cached-heavy usage will show inflated daily/7d/30d spend; bill only non-cache input at inputRate plus cache reads at cacheReadRate.
Useful? React with 👍 / 👎.
Summary
Split from #1821 (PR B). Merge after #1981.
usage_summarywith pricing projectionTest plan
swift buildswift test --filter MiniMaxUsageSummaryswift test --filter MiniMaxUsagePricingMerge order
Made with Cursor