fix(minimax): filter modelRemains to coding-plan-relevant models#1285
fix(minimax): filter modelRemains to coding-plan-relevant models#1285LeoLin990405 wants to merge 1 commit into
Conversation
The MiniMax API returns `model_remains` entries for every model the account has access to (`general` coding plan + auxiliary services like `video`, `image`, `music`, `speech`, etc.). When the user only intends to use the coding plan, the menu card surfaces e.g. `video 0/3` because: 1. `general` (main coding plan) has `current_interval_total_count: 0` in idle windows, so `makeServiceUsage` skips it (`guard total > 0`). 2. `video` has a non-zero allowance from the free tier, so it survives and becomes the only visible service. This is confusing — the user picked MiniMax for coding, not for video. Fix: filter `modelRemains` down to "general" + text-generation models before service construction. Other models (video/image/music/speech/etc.) are dropped so they no longer clutter the card. If filtering leaves nothing (e.g. an account with only auxiliary services), the original list is used as fallback so the card still surfaces *something* rather than going dark. ## Tests - Existing MiniMax parsing tests remain green. ## Validation - `swift build --target CodexBarCore` passes. - `swift build --target CodexBar` passes. - Real-behavior probe against a coding-plan account that returns `[general(0/0), video(3/3)]`: menu now shows the coding plan as primary (idle, 100% remaining placeholder) instead of `video 0/3 0% used`. - Local `swift test --filter MiniMaxUsageFetcher` is blocked before reaching the new tests by the local Command Line Tools environment (`KeyboardShortcuts` `#Preview` macro plugins are unavailable without full Xcode); CI should be the test signal. ## Scope Single-file change in `MiniMaxUsageFetcher.parseMultiService`. No changes to API endpoint, auth, struct decoding, settings, or non-MiniMax providers.
|
Codex review: needs changes before merge. Reviewed June 4, 2026, 3:01 AM ET / 07:01 UTC. Summary Reproducibility: yes. From source inspection, a payload ordered 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:
Next step before merge
Security Review findings
Review detailsBest possible solution: Keep the auxiliary-service filter, but explicitly put Do we have a high-confidence way to reproduce the issue? Yes. From source inspection, a payload ordered Is this the best way to solve the issue? No. Filtering auxiliary entries is the right direction, but the implementation should partition or sort the filtered list so Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model gpt-5.5, reasoning high; reviewed against 65e39f4dcb3a. Label changesLabel changes:
Label justifications:
Evidence reviewedAcceptance 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: 732c55bb28
ℹ️ 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 codingPlanRemains = payload.data.modelRemains.filter { item in | ||
| guard let name = item.modelName?.lowercased() else { return false } | ||
| if name == "general" { return true } | ||
| if let raw = item.modelName, Self.isTextGenerationModelName(raw) { return true } | ||
| return false | ||
| } | ||
| let effectiveRemains = codingPlanRemains.isEmpty ? payload.data.modelRemains : codingPlanRemains |
There was a problem hiding this comment.
Prioritize general quota after filtering
When MiniMax returns both a recognized text model and general but the text model appears first, this filtered array preserves the server order, so effectiveRemains.first below still uses the model-specific quota for the legacy summary fields instead of the main coding-plan quota described in the comment. That keeps the menu on the wrong totals for those payloads; reorder the filtered results so general is selected first before falling back to other text-generation models.
Useful? React with 👍 / 👎.
|
@clawsweeper re-review Real-behavior proof on a coding-plan account where the MiniMax API returns Before this PR (master): the menu card displayed After this PR (commit The menu now surfaces the coding plan window ( Menu screenshot will be attached in a follow-up comment from the PR author (gh CLI doesn't support image upload). |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
Superseded by #1266, which takes a more comprehensive approach to the underlying MiniMax Closing to consolidate review effort. Thanks @XWind18 @Yuxin-Qiao @coygeek for the deeper work in #1266 — happy to test against #1266's branch once it lands. |
Summary
model_remainsreturned by the MiniMax coding-plan API to coding-plan-relevant models only (general+ text-generation models), dropping auxiliary services likevideo/image/music/speechbefore service construction.MiniMaxUsageFetcher.parseMultiService.Why
The MiniMax
coding_plan/remainsAPI currently returns onemodel_remainsentry per accessible model:{ "model_remains": [ {"model_name": "general", "current_interval_total_count": 0, "current_interval_usage_count": 0, "current_interval_remaining_percent": 99}, {"model_name": "video", "current_interval_total_count": 3, "current_interval_usage_count": 3, "current_interval_remaining_percent": 100} ] }On a coding-plan account that's idle in the current window (
generalis 0/0) but has used the free-tiervideoquota (3/3), the menu card currently surfaces onlyvideo 0/3because:generalhascurrent_interval_total_count: 0, somakeServiceUsageskips it (guard total > 0).videohas a non-zero allowance, so it survivesmakeServiceUsageand becomes the only visible service.The user picked MiniMax for the coding plan, not video generation — surfacing
video 0/3 · 0% usedas the headline number is confusing and unhelpful.Fix
Filter
modelRemainsto coding-plan-relevant models before service construction:Then the rest of
parseMultiServiceoperates oneffectiveRemains. The fallback topayload.data.modelRemainswhen filtering empties out preserves behavior for accounts that legitimately have only auxiliary services.Tests
Validation
swift build --target CodexBarCorepasses.swift build --target CodexBarpasses.[general(0/0), video(3/3)]: menu card now shows the coding plan window as primary (100% remaining placeholder for the idle window) instead ofvideo 0/3 · 0% used.swift test --filter MiniMaxUsageFetcheris blocked before reaching focused tests by the local Command Line Tools environment (KeyboardShortcuts#Previewmacro plugins are unavailable without full Xcode); CI should be the test signal.Scope
Single-file change in
MiniMaxUsageFetcher.parseMultiService. No changes to API endpoint, auth, struct decoding,mapModelNameToServiceType, settings UI, or non-MiniMax providers.