Skip to content

fix(minimax): rebuild for credit-based Token Plan (dual-window percent schema)#536

Closed
FrankieeW wants to merge 3 commits into
robinebers:mainfrom
FrankieeW:feat/minimax-token-plan-refresh
Closed

fix(minimax): rebuild for credit-based Token Plan (dual-window percent schema)#536
FrankieeW wants to merge 3 commits into
robinebers:mainfrom
FrankieeW:feat/minimax-token-plan-refresh

Conversation

@FrankieeW
Copy link
Copy Markdown
Contributor

@FrankieeW FrankieeW commented Jun 1, 2026

Why

MiniMax overhauled its Coding Plan into a credit/token-based Token Plan, which changed the remains API shape substantially. The current plugin is built on the old model (model-call-count tiers + per-capability companion buckets) and no longer reflects reality:

  • Tiers are now credit-based Plus / Max / Ultra (was Starter/Plus/Max/*-High-Speed/Ultra-High-Speed).
  • The API now returns current_interval_total_count: 0 and instead exposes current_interval_remaining_percent, plus a second weekly window (current_weekly_*), per model_name bucket (general, video).
  • The old companion buckets (speech HD/Turbo, image-01) and the count→tier quota tables no longer appear in the response.

Verified against the live CN API (api.minimaxi.com). Note: GLOBAL could not be tested (no global key available), but it shares the same endpoint/shape.

What changed

plugins/minimax/plugin.js

  • Query the officially documented token_plan/remains endpoint (per the Token Plan FAQ); keep coding_plan/remains as a legacy fallback (identical payload).
  • Drive every line from *_remaining_percent (used = 100 − remaining_percent); render both the 5h interval and weekly windows per bucket.
  • Map general → Session/Weekly, video → Video/Video (Weekly), title-case any other bucket. All lines are percent format.
  • Show Session + Weekly on the overview (matching the claude/codex layout); Video on detail.
  • Plan-name priority: explicit API field → count→tier fallback → MINIMAX_PLAN override → generic Token Plan baseline (never blank).
  • Remove the dead companion-resource classifiers and quota-hint disambiguation.

plugins/minimax/plugin.json — overview lines Session + Weekly; detail lines Video + Video (Weekly).

plugins/minimax/plugin.test.js — rewritten for the live dual-window percent schema (general + video buckets), the token_plan/remains endpoints with legacy fallback, the MINIMAX_PLAN override/baseline, and the existing endpoint/auth/error paths.

docs/providers/minimax.md — documents the new endpoint, dual windows, percent signals, bucket→line mapping, plan-name priority chain, and a Tier detection section explaining (with doc citations) why the tier cannot be derived from the API.

Tier detection note

The credit-based Token Plan exposes no tier/plan field and reports total_count: 0 — every subscription/plan/quota endpoint variant returns 404. The console usage bar (*_remaining_percent) is the only signal MiniMax provides. Tier therefore must be pinned manually via MINIMAX_PLAN=Plus|Max|Ultra; if MiniMax later adds a plan field, the priority chain consumes it automatically.

Test plan

  • npx vitest run plugins/minimax/plugin.test.js — 34/34 pass
  • Verified live against api.minimaxi.com/v1/token_plan/remains: renders Session/Weekly/Video lines as percent; MINIMAX_PLAN=PlusPlus (CN), unset → Token Plan (CN)
  • GLOBAL region not verified (no global key)

Summary by cubic

Rebuilt the MiniMax plugin for the credit-based Token Plan using the token_plan/remains API and percent-based dual windows. Shows Session/Weekly on overview and Video on detail, with CN/Global fallbacks and a resilient plan-name strategy.

  • New Features

    • Query token_plan/remains (official); keep coding_plan/remains as a legacy fallback.
    • Render percent lines from *_remaining_percent (used = 100 − remaining), limit = 100.
    • Map general → Session + Weekly (overview); video → Video + Video (Weekly) (detail); title-case others.
    • Derive resets from end_time/weekly_end_time, or remains_time when missing.
    • Plan name priority: API field → count→tier fallback → MINIMAX_PLAN override → Token Plan; append region suffix.
    • Updated endpoint orders for GLOBAL and CN. Removed dead companion buckets.
  • Migration

    • Set MINIMAX_PLAN=Plus|Max|Ultra if you want your tier shown (the Token Plan API does not expose it).

Written for commit f86a547. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added weekly token usage tracking window for MiniMax provider.
    • Improved remaining token/credit visibility with enhanced plan name resolution.
  • Documentation

    • Updated MiniMax provider documentation with current API endpoint specifications, expanded authentication guidance, and manual tier override capability.

FrankieeW added 3 commits June 1, 2026 23:09
The Token Plan moved from model-call-count tiers to credit/token-based
plans (Plus/Max/Ultra). The remains API now returns current_interval_total_count
as 0 and instead exposes current_interval_remaining_percent plus a second
weekly window (current_weekly_*) per model_name bucket (general, video).

- Query the officially documented token_plan/remains endpoint; keep
  coding_plan/remains as a legacy fallback (identical payload)
- Drive every line from *_remaining_percent (used = 100 - remaining_percent)
- Render both the 5h interval and weekly windows for each bucket
- Map general -> Session/Weekly, video -> Video/Video (Weekly),
  title-case any other bucket; all lines are percent format
- Show Session + Weekly on the overview (matching claude/codex); Video on detail
- Plan name priority: explicit API field -> count->tier fallback ->
  MINIMAX_PLAN override -> generic 'Token Plan' baseline (never blank).
  The credit-based remains API exposes no tier, so MINIMAX_PLAN lets users
  pin Plus/Max/Ultra.
- Drop the dead companion-resource classifiers (speech HD/Turbo, image-01)
  and quota-hint disambiguation; those buckets no longer exist in the response
Replace the model-call-count/companion-bucket fixtures with the live
remains shape (general + video buckets, interval + weekly remaining
percents). Cover the token_plan/remains endpoints with legacy fallback,
percent-driven Session/Weekly/Video lines, count-based tier-inference
fallback, the MINIMAX_PLAN override and generic baseline, reset/period
derivation, and the existing endpoint/auth/error paths.
Describe the token_plan/remains endpoint (with legacy fallback), the 5h
interval + weekly windows, the *_remaining_percent signals, general/video
bucket-to-line mapping, the Session+Weekly overview layout, the plan-name
priority chain with MINIMAX_PLAN override, and a Tier detection section
explaining why the tier cannot be derived from the API.
Copilot AI review requested due to automatic review settings June 1, 2026 22:15
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 1, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d33b3519-3e18-4120-bdc3-01c51a35a871

📥 Commits

Reviewing files that changed from the base of the PR and between 810b122 and f86a547.

📒 Files selected for processing (4)
  • docs/providers/minimax.md
  • plugins/minimax/plugin.js
  • plugins/minimax/plugin.json
  • plugins/minimax/plugin.test.js

📝 Walkthrough

Walkthrough

MiniMax plugin updated to support Token Plan remains API with dual-window (interval and weekly) progress reporting. Endpoints switched from coding_plan to token_plan with legacy fallbacks; payload parsing refactored to extract window data from per-model buckets; progress output changed to percent-based lines; configuration and documentation updated throughout; comprehensive test coverage validates endpoint retry logic, payload variations, and output formatting.

Changes

Token Plan Integration

Layer / File(s) Summary
API Schema & Constants
plugins/minimax/plugin.js
Endpoints switched from coding_plan/remains to token_plan/remains with legacy fallbacks; plan inference mappings updated from prompt limits to model-call limits; window timing constants (5-hour interval, weekly) and plan normalization tables defined.
Window-Based Payload Parsing
plugins/minimax/plugin.js
Core parsing refactored to scan model_remains buckets and extract interval/weekly window data with remaining-percent values; fallback count math when percent is absent; reset timing and duration derivation; multi-entry results with explicit plan name from general bucket, manual override, or fallback.
Progress Output & Rendering
plugins/minimax/plugin.js, plugins/minimax/plugin.json
Probe result formatting converts window entries into percent-based progress lines (limit 100) with optional reset/duration metadata; plan name resolution via parsed inference → manual override → default with region label appended; JSON config expanded to include Session, Weekly, Video, and Video (Weekly) progress entries.
Provider Documentation
docs/providers/minimax.md
Docs describe Token Plan remains API with dual windows, credit/token-based semantics, remaining-percent computation, tier pin override via MINIMAX_PLAN env var, prioritized endpoint fallbacks for global/CN, usage mapping per model bucket, and explicit plan/tier inference priority chain.
Test Fixtures & Endpoint Setup
plugins/minimax/plugin.test.js
Test constants updated with Token Plan and legacy Coding Plan endpoint URLs for global and CN regions; bucket generator helpers (generalBucket, videoBucket) and successPayload fixture refactored to model percent-based remains.
Endpoint Fallback & Error Handling
plugins/minimax/plugin.test.js
Tests verify retry logic from primary to secondary global endpoint, CN primary to CN fallback after failures, auth error escalation across all endpoints, graceful fallback from CN to global when CN key lookup fails, and error messages for missing status codes and exhausted auth attempts.
Payload Format & Output Validation
plugins/minimax/plugin.test.js
Tests validate window entry parsing and output lines for interval/weekly bucket data, multiple bucket types (general, video, unknown models), plan name resolution from API/override/fallback, count-to-percent math when percent absent, camelCase and epoch-second timestamp variants, percent clamping, and title-cased model label rendering.

🎯 3 (Moderate) | ⏱️ ~25 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@FrankieeW
Copy link
Copy Markdown
Contributor Author

Closing as a duplicate — this overlaps with existing open work:

both tracked by #533 (Update MiniMax API endpoint).

Consolidating effort there to avoid duplicate review. Apologies for the noise.

@FrankieeW FrankieeW closed this Jun 1, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR updates the MiniMax provider to use the newer Token Plan usage API and to render usage as percent-based lines for both the 5-hour interval and weekly windows.

Changes:

  • Switch usage endpoints to token_plan/remains with expanded fallback URL lists for GLOBAL and CN.
  • Parse model_remains[] as windowed buckets (interval + weekly) and emit multiple percent-based progress lines (Session/Weekly/Video).
  • Update tests, plugin manifest line definitions, and provider documentation to match the new payload shape and display model.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
plugins/minimax/plugin.js Reworks endpoint selection and payload parsing to percent-based Token Plan windows and adds plan-name normalization/override logic.
plugins/minimax/plugin.test.js Updates/expands tests to cover Token Plan bucket parsing, multi-line output, fallbacks, and plan naming behavior.
plugins/minimax/plugin.json Declares additional progress lines (Weekly/Video) to align with the new multi-window output.
docs/providers/minimax.md Updates provider docs for Token Plan endpoints, window model, tier detection limitations, and new output mapping.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread plugins/minimax/plugin.js
Comment on lines +199 to +225
function computeWindowUsedPercent(item, win) {
const remainingPercent = readNumber(item[win.percentField])
if (remainingPercent !== null) {
return clampPercent(Math.round(100 - remainingPercent))
}

const total = readNumber(item[win.totalField])
if (total === null || total <= 0) return null
const remaining = readNumber(item[win.usageField])
if (remaining === null) return null
return clampPercent(Math.round(((total - remaining) / total) * 100))
}

function computeWindowTiming(ctx, item, win, nowMs) {
const startMs = epochToMs(item[win.startField])
const endMs = epochToMs(item[win.endField])
const remainsRaw = readNumber(item[win.remainsField])
const remainsMs = inferRemainsMs(remainsRaw, endMs, nowMs, win.expectedWindowMs)

let resetsAt = endMs !== null ? ctx.util.toIso(endMs) : null
if (!resetsAt && remainsMs !== null) resetsAt = ctx.util.toIso(nowMs + remainsMs)

let periodDurationMs = null
if (startMs !== null && endMs !== null && endMs > startMs) periodDurationMs = endMs - startMs

return { resetsAt, periodDurationMs }
}
Comment thread plugins/minimax/plugin.js
Comment on lines +160 to +181
const WINDOWS = [
{
key: "interval",
percentField: "current_interval_remaining_percent",
totalField: "current_interval_total_count",
usageField: "current_interval_usage_count",
startField: "start_time",
endField: "end_time",
remainsField: "remains_time",
expectedWindowMs: INTERVAL_WINDOW_MS,
},
{
key: "weekly",
percentField: "current_weekly_remaining_percent",
totalField: "current_weekly_total_count",
usageField: "current_weekly_usage_count",
startField: "weekly_start_time",
endField: "weekly_end_time",
remainsField: "weekly_remains_time",
expectedWindowMs: WEEKLY_WINDOW_MS,
},
]
Comment thread docs/providers/minimax.md

- **Protocol:** HTTPS (JSON)
- **Endpoint:** `GET https://api.minimax.io/v1/api/openplatform/coding_plan/remains`
- **Endpoint:** `GET https://api.minimax.io/v1/token_plan/remains` — the officially documented Token Plan usage endpoint ([FAQ](https://platform.minimax.io/docs/token-plan/faq)). The older `coding_plan/remains` path returns an identical payload and is kept only as a legacy fallback.
Comment thread docs/providers/minimax.md

The subscription tier (`Plus` / `Max` / `Ultra`) **cannot be derived from the API**, by design:

- The only usage endpoint is `token_plan/remains` (every subscription/plan/quota endpoint variant returns `404`). Its `coding_plan/remains` alias is byte-for-byte identical.
Comment on lines +734 to 752
it("falls back to GLOBAL when MINIMAX_CN_API_KEY lookup throws in AUTO mode", async () => {
const ctx = makeCtx()
setEnv(ctx, { MINIMAX_API_KEY: "mini-key" })
ctx.host.http.request.mockReturnValue({
status: 200,
headers: {},
bodyText: JSON.stringify({
base_resp: { status_code: 0 },
model_remains: [
{
current_interval_total_count: 100,
current_interval_usage_count: 25,
start_time: 1700000000,
end_time: 1700018000,
},
],
}),
ctx.host.env.get.mockImplementation((name) => {
if (name === "MINIMAX_CN_API_KEY") throw new Error("cn env unavailable")
if (name === "MINIMAX_API_KEY") return "global-key"
return null
})

const plugin = await loadPlugin()
const result = plugin.probe(ctx)
const line = result.lines[0]
expect(line.periodDurationMs).toBe(18000000)
expect(line.resetsAt).toBe(new Date(1700018000 * 1000).toISOString())
})

it("infers remains_time as milliseconds when value is plausible", async () => {
const ctx = makeCtx()
setEnv(ctx, { MINIMAX_API_KEY: "mini-key" })
vi.spyOn(Date, "now").mockReturnValue(1700000000000)
ctx.host.http.request.mockReturnValue({
status: 200,
headers: {},
bodyText: JSON.stringify({
base_resp: { status_code: 0 },
model_remains: [
{
current_interval_total_count: 100,
current_interval_usage_count: 40,
remains_time: 300000,
},
],
}),
bodyText: JSON.stringify(successPayload()),
})

const plugin = await loadPlugin()
const result = plugin.probe(ctx)
expect(result.lines[0].resetsAt).toBe(new Date(1700000000000 + 300000).toISOString())
})

it("throws parse error when model_remains entries are unusable", async () => {
const ctx = makeCtx()
setEnv(ctx, { MINIMAX_API_KEY: "mini-key" })
ctx.host.http.request.mockReturnValue({
status: 200,
headers: {},
bodyText: JSON.stringify({
base_resp: { status_code: 0 },
model_remains: [null, { current_interval_total_count: 0, current_interval_usage_count: 1 }],
}),
})

const plugin = await loadPlugin()
expect(() => plugin.probe(ctx)).toThrow("Could not parse usage data")
})

it("throws parse error when both used and remaining counts are missing", async () => {
const ctx = makeCtx()
setEnv(ctx, { MINIMAX_API_KEY: "mini-key" })
ctx.host.http.request.mockReturnValue({
status: 200,
headers: {},
bodyText: JSON.stringify({
base_resp: { status_code: 0 },
model_remains: [{ current_interval_total_count: 100 }],
}),
})

const plugin = await loadPlugin()
expect(() => plugin.probe(ctx)).toThrow("Could not parse usage data")
expect(ctx.host.http.request.mock.calls[0][0].url).toBe(PRIMARY_USAGE_URL)
expect(result.plan).toBe("Plus (GLOBAL)")
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants