From 8b5c06babf9ff34c04db9bf5102498985a9b7f0d Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Mon, 26 Oct 2026 11:56:02 +0800 Subject: [PATCH 1/2] chore: deprecate MiniMax M3 in model selectors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move MiniMax M3 into the deprecated group across dashboard selections and read-only discovery. Keep explicit model routes and API access available, and update regression coverage and the packaged API skill. 中文:将 MiniMax M3 归入已弃用模型分组,同步仪表盘选择器和只读 API 的发现结果。保留显式模型路由与 API 访问,并更新回归测试及 API skill。 --- .../app/api/v1/views/options/route.test.ts | 9 +++++++++ .../latest-image/latest-image-utils.test.ts | 3 ++- .../app/src/lib/catalog/data-mappings.test.ts | 5 +++++ packages/app/src/lib/catalog/data-mappings.ts | 2 +- .../src/lib/overview/overview-data.test.ts | 19 +++++++++++++++---- .../lib/routing/inference-model-slug.test.ts | 10 ++++++++++ .../app/src/lib/views-api/docs/options.ts | 7 +++++++ .../skills/inferencex-api/integrity.json | 2 +- .../references/dashboard-views.md | 3 +++ 9 files changed, 53 insertions(+), 7 deletions(-) diff --git a/packages/app/src/app/api/v1/views/options/route.test.ts b/packages/app/src/app/api/v1/views/options/route.test.ts index 79433cf0d..5d0dc6076 100644 --- a/packages/app/src/app/api/v1/views/options/route.test.ts +++ b/packages/app/src/app/api/v1/views/options/route.test.ts @@ -57,6 +57,15 @@ describe('GET /api/v1/views/options', () => { expect(dsv4.dbKeys).toContain('dsv4'); expect(typeof dsv4.category).toBe('string'); expect(body.models.every((m: { dbKeys: string[] }) => m.dbKeys.length > 0)).toBe(true); + expect(body.models.find((m: { name: string }) => m.name === 'MiniMax-M3')).toMatchObject({ + dbKeys: ['minimaxm3'], + category: 'deprecated', + }); + expect( + body.models.find((m: { name: string }) => m.name === 'MiniMax-M3.1-Flash'), + ).toMatchObject({ + category: 'default', + }); }); it('describes sequences with isl/osl and deprecation flags', async () => { diff --git a/packages/app/src/components/latest-image/latest-image-utils.test.ts b/packages/app/src/components/latest-image/latest-image-utils.test.ts index 05fef140e..b57214dc5 100644 --- a/packages/app/src/components/latest-image/latest-image-utils.test.ts +++ b/packages/app/src/components/latest-image/latest-image-utils.test.ts @@ -315,7 +315,7 @@ describe('isActiveImageRow', () => { expect(isActiveImageRow(imageRow('dsv4', 'agentic'))).toBe(true); expect(isActiveImageRow(imageRow('qwen3.5', '8k/1k'))).toBe(true); expect(isActiveImageRow(imageRow('qwen3.5', 'agentic'))).toBe(true); - expect(isActiveImageRow(imageRow('minimaxm3', 'agentic'))).toBe(true); + expect(isActiveImageRow(imageRow('minimaxm31flash', 'agentic'))).toBe(true); expect(isActiveImageRow(imageRow('dsr1', '8k/1k'))).toBe(true); }); @@ -332,6 +332,7 @@ describe('isActiveImageRow', () => { }); it('drops deprecated models on every scenario, including point-release buckets', () => { + expect(isActiveImageRow(imageRow('minimaxm3', 'agentic'))).toBe(false); expect(isActiveImageRow(imageRow('kimik2.5', '8k/1k'))).toBe(false); expect(isActiveImageRow(imageRow('kimik2.6', '8k/1k'))).toBe(false); expect(isActiveImageRow(imageRow('minimaxm2.5', '8k/1k'))).toBe(false); diff --git a/packages/app/src/lib/catalog/data-mappings.test.ts b/packages/app/src/lib/catalog/data-mappings.test.ts index cf1468c03..86509ab62 100644 --- a/packages/app/src/lib/catalog/data-mappings.test.ts +++ b/packages/app/src/lib/catalog/data-mappings.test.ts @@ -175,6 +175,11 @@ describe('isModelDeprecated', () => { expect(isModelDeprecated(Model.MiniMax_M2_5)).toBe(true); }); + it('moves MiniMax M3 to deprecated while keeping M3.1 Flash active', () => { + expect(isModelDeprecated(Model.MiniMax_M3)).toBe(true); + expect(isModelDeprecated(Model.MiniMax_M3_1_Flash)).toBe(false); + }); + it('returns true for deprecated model GptOss', () => { expect(isModelDeprecated(Model.GptOss)).toBe(true); }); diff --git a/packages/app/src/lib/catalog/data-mappings.ts b/packages/app/src/lib/catalog/data-mappings.ts index 8a30f496c..b6530f06d 100644 --- a/packages/app/src/lib/catalog/data-mappings.ts +++ b/packages/app/src/lib/catalog/data-mappings.ts @@ -109,7 +109,7 @@ const MODEL_CONFIG: Record = { [Model.MiniMax_M3]: { label: 'MiniMax M3 428B', prefix: 'minimaxm3', - category: 'default', + category: 'deprecated', openRouterModelId: 'minimax/minimax-m3', logo: 'minimax-color.svg', }, diff --git a/packages/app/src/lib/overview/overview-data.test.ts b/packages/app/src/lib/overview/overview-data.test.ts index 221fffac6..ae57ed46d 100644 --- a/packages/app/src/lib/overview/overview-data.test.ts +++ b/packages/app/src/lib/overview/overview-data.test.ts @@ -1322,7 +1322,6 @@ describe('assembleOverviewPageData over the overview-rows fixture', () => { `${Model.DeepSeek_V4_Pro}/agentx`, `${Model.DeepSeek_V4_1_Flash}/agentx`, `${Model.Kimi_K3}/agentx`, - `${Model.MiniMax_M3}/agentx`, `${Model.MiniMax_M3_1_Flash}/agentx`, `${Model.GLM_5_2}/agentx`, `${Model.Qwen3_5}/agentx`, @@ -1366,7 +1365,14 @@ describe('assembleOverviewPageData over the overview-rows fixture', () => { ), ).toBe(false); - const minimax = page.models.find( + const allModelsPage = assembleOverviewPageData( + overviewRowsFixture as unknown as Record, + 50, + 'community', + 'b200', + 'all', + ); + const minimax = allModelsPage.models.find( (m) => m.model === Model.MiniMax_M3 && m.scenario === 'agentx', )!; const mmGb300 = headlinePairOf(minimax, 'gb300-vs-b200')!; @@ -1442,6 +1448,8 @@ describe('overview model scope', () => { const page = assembleOverviewPageData({}); expect(new Set(page.models.map((m) => m.model))).toEqual(new Set(DEFAULT_MODELS)); expect(page.modelScope).toBe('default'); + expect(page.models.some((m) => m.model === Model.MiniMax_M3)).toBe(false); + expect(page.models.some((m) => m.model === Model.MiniMax_M3_1_Flash)).toBe(true); }); it("appends maintenance then deprecated rows after defaults under scope 'all'", () => { @@ -1450,7 +1458,8 @@ describe('overview model scope', () => { expect(orderedUniqueModels).toEqual([ ...DEFAULT_MODELS, ...MAINTENANCE_MODELS, - ...DEPRECATED_MODELS, + Model.MiniMax_M3, + ...[...DEPRECATED_MODELS].filter((model) => model !== Model.MiniMax_M3), ]); expect(page.modelScope).toBe('all'); }); @@ -1462,6 +1471,7 @@ describe('overview model scope', () => { expect(categoryOf(Model.DeepSeek_R1)).toBe('maintenance'); expect(categoryOf(Model.GLM_5)).toBe('deprecated'); expect(categoryOf(Model.GptOss)).toBe('deprecated'); + expect(categoryOf(Model.MiniMax_M3)).toBe('deprecated'); }); it('forwards the model scope through the historical assembler', () => { @@ -1471,7 +1481,8 @@ describe('overview model scope', () => { expect(orderedUniqueModels).toEqual([ ...DEFAULT_MODELS, ...MAINTENANCE_MODELS, - ...DEPRECATED_MODELS, + Model.MiniMax_M3, + ...[...DEPRECATED_MODELS].filter((model) => model !== Model.MiniMax_M3), ]); expect(page.modelScope).toBe('all'); }); diff --git a/packages/app/src/lib/routing/inference-model-slug.test.ts b/packages/app/src/lib/routing/inference-model-slug.test.ts index 4f77cfcd8..9fbd47334 100644 --- a/packages/app/src/lib/routing/inference-model-slug.test.ts +++ b/packages/app/src/lib/routing/inference-model-slug.test.ts @@ -42,6 +42,16 @@ describe('INFERENCE_MODEL_SLUGS registry', () => { expect(INFERENCE_MODEL_SLUGS).toContain(entry); } }); + + it('keeps the MiniMax M3 page addressable without promoting it as active', () => { + expect(getInferenceModelBySlug('minimax-m3')?.model).toBe(Model.MiniMax_M3); + expect(ACTIVE_INFERENCE_MODEL_SLUGS.some((entry) => entry.model === Model.MiniMax_M3)).toBe( + false, + ); + expect( + ACTIVE_INFERENCE_MODEL_SLUGS.some((entry) => entry.model === Model.MiniMax_M3_1_Flash), + ).toBe(true); + }); }); describe('getInferenceModelBySlug', () => { diff --git a/packages/app/src/lib/views-api/docs/options.ts b/packages/app/src/lib/views-api/docs/options.ts index a4c6f227e..dbd471f94 100644 --- a/packages/app/src/lib/views-api/docs/options.ts +++ b/packages/app/src/lib/views-api/docs/options.ts @@ -122,6 +122,13 @@ const responseExample = { releaseDate: '2026-06-30', compareSlug: 'deepseek-v4-pro', }, + { + name: 'MiniMax-M3', + dbKeys: ['minimaxm3'], + category: 'deprecated', + releaseDate: '2026-06-07', + compareSlug: 'minimax-m3', + }, ], sequences: [ { diff --git a/packages/skills/skills/inferencex-api/integrity.json b/packages/skills/skills/inferencex-api/integrity.json index 2485e84c6..cbcac8a4e 100644 --- a/packages/skills/skills/inferencex-api/integrity.json +++ b/packages/skills/skills/inferencex-api/integrity.json @@ -9,7 +9,7 @@ "references/cli-contract.md": "4f070877eeefffad2860c58f79f68432fbe27aa21fc578a1c696f0309a3d7d7b", "references/cli.md": "11e1183f7ed70d669019e8435ac16a6a9f873de027507b8850a9943f6659bfd9", "references/collectivex.md": "f79cf8e2779a9289ab69f79f4a4b338e0b9a5f76a3750a3e969f33a744e726a1", - "references/dashboard-views.md": "f66cc6bb944cde6480b6aad674c1aa847b3167272dd30e3deecac8b19b29ca55", + "references/dashboard-views.md": "1e2a0848c4efb9bca66fbf708082aa87402f32fff43fcda3d0638658cba0b90b", "references/offline-exports.md": "95aa565dcd4c9e592159baa560a9a58217bc61e395de1c6daf0576795c7f4ec9", "references/pareto.md": "1b4d2d163f982e3f2d97addce310789eae9c1e5badd82dd7501708c9e0385027", "references/powerx.md": "5af5527d54a7e6191a5769080c122638b333b1ceb59e19fdee7df662a5cd3c8f", diff --git a/packages/skills/skills/inferencex-api/references/dashboard-views.md b/packages/skills/skills/inferencex-api/references/dashboard-views.md index bd7a04852..0f2955f16 100644 --- a/packages/skills/skills/inferencex-api/references/dashboard-views.md +++ b/packages/skills/skills/inferencex-api/references/dashboard-views.md @@ -33,6 +33,9 @@ results or treat its interpolated values as separately measured operating points for static model, hardware, sequence and metric registries; use each specialized view's `options`, `configurations`, `workloads`, or raw run-list operation for data-dependent choices. + MiniMax M3 has `category=deprecated` in `options.models`; it remains selectable + through explicit model parameters and overview `modelScope=all`. MiniMax M3.1 + Flash remains in the default model group. 2. Build one public HTTPS GET URL using `URLSearchParams`, especially for JSON costs, commas, slashes, and run-specific comparison dates. No credentials are required. Unknown or repeated parameter names return 400. From 71601eec14ca3d5f0e6cd0341c801687f563af06 Mon Sep 17 00:00:00 2001 From: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Date: Mon, 26 Oct 2026 12:09:56 +0800 Subject: [PATCH 2/2] test: align model E2E expectations with MiniMax M3 deprecation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update overview and current-image assertions for deprecated M3 while keeping explicit M3 coverage. Select M3 by its full label in the profit estimator to avoid matching M3.1 Flash. 中文:更新概览页与当前镜像的 E2E 断言,验证 MiniMax M3 已移入弃用分组且仍可显式访问。利润估算器使用完整模型名称选择 M3,避免误选 M3.1 Flash。 --- .../e2e/current-inferencex-image.cy.ts | 15 +++++------ packages/app/cypress/e2e/overview.cy.ts | 25 ++++++++++--------- .../app/cypress/e2e/profit-estimator.cy.ts | 2 +- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/packages/app/cypress/e2e/current-inferencex-image.cy.ts b/packages/app/cypress/e2e/current-inferencex-image.cy.ts index 2cefa98fc..ecf6c7e4a 100644 --- a/packages/app/cypress/e2e/current-inferencex-image.cy.ts +++ b/packages/app/cypress/e2e/current-inferencex-image.cy.ts @@ -318,7 +318,7 @@ describe('Current InferenceX Image localized routes', () => { cy.viewport(1440, 900); const retiredImage = 'lmsysorg/sglang:v0.4.9-minimax-8k1k-retired'; const retiredDeepSeekImage = 'vllm/vllm-openai:v0.10.0-dsv4-8k1k-retired'; - const activeMiniMaxImage = 'lmsysorg/sglang:v0.5.2-minimax-agentic'; + const activeFlashImage = 'lmsysorg/sglang:v0.5.2-minimax-m31flash-agentic'; const deprecatedModelImage = 'vllm/vllm-openai:v0.9.0-kimi-k2.5'; cy.intercept('GET', '**/api/v1/latest-images', [ ...imageRows, @@ -332,12 +332,12 @@ describe('Current InferenceX Image localized routes', () => { }, { ...imageRows[0], - model: 'minimaxm3', + model: 'minimaxm31flash', framework: 'sglang', isl: null, osl: null, benchmark_type: 'agentic_traces', - image: activeMiniMaxImage, + image: activeFlashImage, date: today, }, { ...imageRows[1], model: 'kimik2.5', image: deprecatedModelImage }, @@ -363,16 +363,17 @@ describe('Current InferenceX Image localized routes', () => { cy.get('#image-model-select').click(); cy.get('[data-slot="select-item"]').should('not.contain.text', 'Kimi-K2.5'); - cy.get('[data-slot="select-item"]').contains('MiniMax-M3').click(); + cy.get('[data-slot="select-item"]').should(($items) => { + expect([...$items].map((item) => item.textContent?.trim())).not.to.include('MiniMax-M3'); + }); + cy.get('[data-slot="select-item"]').contains('MiniMax-M3.1-Flash').click(); cy.get('#image-sequence-select').should('contain.text', 'Agentic'); cy.get('#image-sequence-select').click(); cy.get('[data-slot="select-item"]').should('have.length', 1).and('contain.text', 'Agentic'); cy.get('[data-slot="select-item"]').contains('Agentic').click(); cy.get('[data-testid="current-image-result-count"]').should('contain.text', '1 configuration'); - cy.get('table') - .should('contain.text', activeMiniMaxImage) - .and('not.contain.text', retiredImage); + cy.get('table').should('contain.text', activeFlashImage).and('not.contain.text', retiredImage); }); it('keeps full configuration and long image tags readable while filtering the catalog', () => { cy.viewport(1440, 900); diff --git a/packages/app/cypress/e2e/overview.cy.ts b/packages/app/cypress/e2e/overview.cy.ts index 17176e9cf..0a2d16884 100644 --- a/packages/app/cypress/e2e/overview.cy.ts +++ b/packages/app/cypress/e2e/overview.cy.ts @@ -5,7 +5,6 @@ const MODEL_LABELS = [ 'DeepSeek V4 Pro 0813 1.6T', 'DeepSeek V4.1 Flash 552B', 'Kimi K3 2.8T', - 'MiniMax M3 428B', 'MiniMax M3.1 Flash 428B', 'GLM5.2/GLM5.3', 'Qwen3.5 397B', @@ -21,7 +20,7 @@ const PLATFORM_HEADERS = [ ]; const SINGLE_TURN = 'single_turn_8k1k'; -const MATRIX_ROWS = 10; +const MATRIX_ROWS = 9; const AGENTX = 'agentx'; const AGENTX_LABEL = 'Long Context Multi-Turn Realistic Agentic Scenario (AgentX)'; const AGENTX_LABEL_ZH = '长上下文、多轮交互的真实智能体场景(AgentX)'; @@ -393,6 +392,7 @@ describe('Overview page', () => { cy.viewport(1280, 900); cy.visit('/overview'); cy.get('[data-testid="overview-desktop-model"][data-model="gpt-oss-120b"]').should('not.exist'); + desktopModel('MiniMax-M3').should('not.exist'); cy.get('[data-testid="overview-model-scope-toggle"]') .find('[data-overview-model-scope="all"]') @@ -404,6 +404,9 @@ describe('Overview page', () => { .should('have.attr', 'data-category', 'deprecated') .and('contain.text', 'Deprecated') .and('contain.text', 'Model is no longer actively benchmarked.'); + desktopModel('MiniMax-M3', AGENTX) + .find('[data-testid="overview-model-category-badge"]') + .should('have.attr', 'data-category', 'deprecated'); desktopModel('DeepSeek-R1-0528') .find('[data-testid="overview-model-category-badge"]') .should('have.attr', 'data-category', 'maintenance'); @@ -426,6 +429,7 @@ describe('Overview page', () => { .click(); cy.location('search').should('eq', '?tier=75'); cy.get('[data-testid="overview-desktop-model"][data-model="gpt-oss-120b"]').should('not.exist'); + desktopModel('MiniMax-M3').should('not.exist'); }); it('uses a selectable hardware reference and preserves it across overview controls', () => { @@ -931,7 +935,7 @@ describe('Overview page', () => { it('prefers speculative decode and falls back to labelled standard-decode reads', () => { cy.viewport(1280, 900); - cy.visit('/overview'); + cy.visit('/overview?models=all'); desktopModel('Qwen-3.5-397B-A17B', SINGLE_TURN).within(() => { platform('gb300').should('contain.text', 'SGLang · FP8 · STP'); @@ -984,7 +988,7 @@ describe('Overview page', () => { it('color-grades the whole cell against B200 and badges a missing baseline with a neutral ∞', () => { cy.viewport(1280, 900); - cy.visit('/overview'); + cy.visit('/overview?models=all'); desktopModel('Qwen-3.5-397B-A17B', SINGLE_TURN).within(() => { platform('b200').find('[data-testid="overview-cost-delta"]').should('not.exist'); @@ -1103,13 +1107,7 @@ describe('Overview page', () => { for (const label of MODEL_LABELS) { cy.get('[data-testid="overview-desktop-matrix"]').should('contain.text', label); } - for (const model of [ - 'DeepSeek-V4-Pro', - 'DeepSeek-V4.1-Flash', - 'Kimi-K3', - 'GLM-5.2', - 'MiniMax-M3', - ]) { + for (const model of ['DeepSeek-V4-Pro', 'DeepSeek-V4.1-Flash', 'Kimi-K3', 'GLM-5.2']) { desktopModel(model).within(() => { expectAgentxScenario(AGENTX_LABEL); }); @@ -1251,7 +1249,7 @@ describe('Overview page', () => { it('distinguishes per-platform and whole-row missing results with a plain dash', () => { cy.viewport(1280, 900); - cy.visit('/overview'); + cy.visit('/overview?models=all'); desktopModel('DeepSeek-V4-Pro', AGENTX).within(() => { platform('mi355x').within(() => { @@ -1656,6 +1654,9 @@ describe('Overview page', () => { desktopModel('DeepSeek-V4-Pro', AGENTX).within(() => { platform('b200').should('contain.text', 'SGLang · FP4').and('not.contain.text', 'STP'); }); + cy.get('[data-testid="overview-model-scope-toggle"]') + .find('[data-overview-model-scope="all"]') + .click(); desktopModel('MiniMax-M3', AGENTX).within(() => { platform('gb300') .find('[data-testid="overview-cost-delta"]') diff --git a/packages/app/cypress/e2e/profit-estimator.cy.ts b/packages/app/cypress/e2e/profit-estimator.cy.ts index 83c17f76a..e1779eed7 100644 --- a/packages/app/cypress/e2e/profit-estimator.cy.ts +++ b/packages/app/cypress/e2e/profit-estimator.cy.ts @@ -1310,7 +1310,7 @@ describe('Profit Estimator — MiniMax M3', () => { cy.get('[data-testid="profit-lab-cut-input"]').should('have.value', '20'); cy.get('[data-testid="profit-model-selector"]').click(); - cy.contains('[role="option"]', 'MiniMax M3').click(); + cy.contains('[role="option"]', 'MiniMax M3 428B').click(); cy.location('pathname').should('eq', '/profit-estimator-per-gigawatt/minimax-m3'); cy.get('[data-testid="profit-caption"] h2') .should('contain.text', 'MiniMax M3')