From e1ce7e345cc9253f4b5381447ee82b548bcf162b Mon Sep 17 00:00:00 2001 From: octo-patch <266937838+octo-patch@users.noreply.github.com> Date: Thu, 30 Jul 2026 05:11:23 +0000 Subject: [PATCH 1/2] feat(pi-ai): refresh MiniMax-M3 video input and adaptive thinking MiniMax-M3 accepts video inputs in addition to text and image, and exposes adaptive and disabled thinking modes over its Anthropic-compatible endpoint. Extend the model input modality vocabulary with "video", teach the generator to emit the video modality and forceAdaptiveThinking for M3, and refresh the generated catalog and its regression test to match. --- packages/pi-ai/scripts/generate-models.ts | 22 +++++++++++++++++--- packages/pi-ai/src/model-catalog.ts | 2 +- packages/pi-ai/src/models.generated.json | 12 +++++++++-- packages/pi-ai/src/models.generated.ts | 6 ++++-- packages/pi-ai/src/types.ts | 2 +- packages/pi-ai/test/generated-models.test.ts | 3 ++- 6 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/pi-ai/scripts/generate-models.ts b/packages/pi-ai/scripts/generate-models.ts index a36dacfeff..a35300b852 100644 --- a/packages/pi-ai/scripts/generate-models.ts +++ b/packages/pi-ai/scripts/generate-models.ts @@ -268,6 +268,15 @@ function applyThinkingLevelMetadata(model: Model): void { ) { mergeAnthropicMessagesCompat(model, { forceAdaptiveThinking: true }); } + if ( + (model.provider === "minimax" || model.provider === "minimax-cn") && + model.api === "anthropic-messages" && + model.id === "MiniMax-M3" + ) { + // M3 exposes adaptive and disabled thinking modes over the Anthropic-compatible + // endpoint, so force adaptive thinking instead of the budget-based default. + mergeAnthropicMessagesCompat(model, { forceAdaptiveThinking: true }); + } if (model.api === "openai-completions" && model.id.includes("deepseek-v4")) { mergeThinkingLevelMap(model, DEEPSEEK_V4_THINKING_LEVEL_MAP); } @@ -1786,12 +1795,16 @@ async function generateModels() { } } - const minimaxDirectModelOverrides = new Map([ + const minimaxDirectModelOverrides = new Map< + string, + { contextWindow: number; maxTokens: number; input?: ("text" | "image" | "video")[] } + >([ ["MiniMax-M2.7", { contextWindow: 204800, maxTokens: 131072 }], ["MiniMax-M2.7-highspeed", { contextWindow: 204800, maxTokens: 131072 }], // MiniMax's API overview advertises a 1M context window for M3; models.dev - // currently reports the documented guaranteed 512K floor. - ["MiniMax-M3", { contextWindow: 1000000, maxTokens: 131072 }], + // currently reports the documented guaranteed 512K floor. M3 also accepts + // video inputs alongside text and image, which models.dev does not report. + ["MiniMax-M3", { contextWindow: 1000000, maxTokens: 131072, input: ["text", "image", "video"] }], ]); const minimaxDirectSupportedIds = new Set(minimaxDirectModelOverrides.keys()); @@ -1804,6 +1817,9 @@ async function generateModels() { if (override) { candidate.contextWindow = override.contextWindow; candidate.maxTokens = override.maxTokens; + if (override.input) { + candidate.input = override.input; + } } } } diff --git a/packages/pi-ai/src/model-catalog.ts b/packages/pi-ai/src/model-catalog.ts index d998f9a549..c34986491a 100644 --- a/packages/pi-ai/src/model-catalog.ts +++ b/packages/pi-ai/src/model-catalog.ts @@ -111,7 +111,7 @@ const ModelCatalogEntrySchema = Type.Object({ baseUrl: Type.String(), reasoning: Type.Boolean(), thinkingLevelMap: Type.Optional(ThinkingLevelMapSchema), - input: Type.Array(Type.Union([Type.Literal("text"), Type.Literal("image")]), { minItems: 1 }), + input: Type.Array(Type.Union([Type.Literal("text"), Type.Literal("image"), Type.Literal("video")]), { minItems: 1 }), cost: Type.Object({ input: Type.Number(), output: Type.Number(), diff --git a/packages/pi-ai/src/models.generated.json b/packages/pi-ai/src/models.generated.json index ffc2230fee..5df2a079f8 100644 --- a/packages/pi-ai/src/models.generated.json +++ b/packages/pi-ai/src/models.generated.json @@ -7694,10 +7694,14 @@ "api": "anthropic-messages", "provider": "minimax", "baseUrl": "https://api.minimax.io/anthropic", + "compat": { + "forceAdaptiveThinking": true + }, "reasoning": true, "input": [ "text", - "image" + "image", + "video" ], "cost": { "input": 0.6, @@ -7754,10 +7758,14 @@ "api": "anthropic-messages", "provider": "minimax-cn", "baseUrl": "https://api.minimaxi.com/anthropic", + "compat": { + "forceAdaptiveThinking": true + }, "reasoning": true, "input": [ "text", - "image" + "image", + "video" ], "cost": { "input": 0.6, diff --git a/packages/pi-ai/src/models.generated.ts b/packages/pi-ai/src/models.generated.ts index 0ded61628f..a5db0f87d5 100644 --- a/packages/pi-ai/src/models.generated.ts +++ b/packages/pi-ai/src/models.generated.ts @@ -6132,8 +6132,9 @@ export const MODELS = { api: "anthropic-messages", provider: "minimax", baseUrl: "https://api.minimax.io/anthropic", + compat: {"forceAdaptiveThinking":true}, reasoning: true, - input: ["text", "image"], + input: ["text", "image", "video"], cost: { input: 0.6, output: 2.4, @@ -6185,8 +6186,9 @@ export const MODELS = { api: "anthropic-messages", provider: "minimax-cn", baseUrl: "https://api.minimaxi.com/anthropic", + compat: {"forceAdaptiveThinking":true}, reasoning: true, - input: ["text", "image"], + input: ["text", "image", "video"], cost: { input: 0.6, output: 2.4, diff --git a/packages/pi-ai/src/types.ts b/packages/pi-ai/src/types.ts index d839b5724c..864a9e6b12 100644 --- a/packages/pi-ai/src/types.ts +++ b/packages/pi-ai/src/types.ts @@ -609,7 +609,7 @@ export interface Model { * Missing keys use provider defaults. null marks a level as unsupported. */ thinkingLevelMap?: ThinkingLevelMap; - input: ("text" | "image")[]; + input: ("text" | "image" | "video")[]; cost: { input: number; // $/million tokens output: number; // $/million tokens diff --git a/packages/pi-ai/test/generated-models.test.ts b/packages/pi-ai/test/generated-models.test.ts index 763eb2d95b..6b584eb911 100644 --- a/packages/pi-ai/test/generated-models.test.ts +++ b/packages/pi-ai/test/generated-models.test.ts @@ -180,7 +180,8 @@ describe("models.generated.ts", () => { provider, baseUrl, reasoning: true, - input: ["text", "image"], + input: ["text", "image", "video"], + compat: { forceAdaptiveThinking: true }, cost: { input: 0.6, output: 2.4, From 9418f2de0e9b4d1aace02cc5878aedbbe4d62188 Mon Sep 17 00:00:00 2001 From: Jeremy McSpadden Date: Fri, 31 Jul 2026 15:41:14 -0500 Subject: [PATCH 2/2] fix(pi-coding-agent): widen discovery provider default input type for video modality The pi-ai Model.input type now includes "video", so deriving the discovery provider defaults from the first catalog model no longer assigns to the narrower ("text" | "image")[] declaration. Reference Model["input"] directly so the default stays in sync with the catalog type. --- packages/pi-coding-agent/src/core/model-registry.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/pi-coding-agent/src/core/model-registry.ts b/packages/pi-coding-agent/src/core/model-registry.ts index 391e611e29..0594f9bc29 100644 --- a/packages/pi-coding-agent/src/core/model-registry.ts +++ b/packages/pi-coding-agent/src/core/model-registry.ts @@ -1167,7 +1167,7 @@ export class ModelRegistry { private getDiscoveryProviderDefaults(provider: string): { api: Api; baseUrl: string; - input: ("text" | "image")[]; + input: Model["input"]; contextWindow: number; maxTokens: number; } {