fix(ai): minimax thinking
MiniMax descriptors carried thinkingFormat: "zai", which made
openai-completions emit thinking: { type: "enabled" } in plan mode.
MiniMax's OpenAI-compatible endpoint rejects that field with
`400 invalid params, invalid chat setting (2013)`. Drop thinkingFormat
from both minimax-coding-plan descriptors and add
supportsReasoningEffort: false (MiniMax also ignores reasoning_effort).
Normalize bundled minimax-code/minimax-code-cn entries inside
applyGeneratedModelPolicy so a regenerated models.json cannot
reintroduce the bad flag.
Fixes #955
This commit is contained in:
@@ -314,6 +314,16 @@ function applyGeneratedModelPolicy(model: ApiModel<Api>): void {
|
||||
model.maxTokens = copilotLimits.maxTokens;
|
||||
}
|
||||
|
||||
if (model.api === "openai-completions" && (model.provider === "minimax-code" || model.provider === "minimax-code-cn")) {
|
||||
model.compat = {
|
||||
...model.compat,
|
||||
supportsStore: false,
|
||||
supportsDeveloperRole: false,
|
||||
supportsReasoningEffort: false,
|
||||
reasoningContentField: "reasoning_content",
|
||||
};
|
||||
delete model.compat.thinkingFormat;
|
||||
}
|
||||
const parsedModel = parseKnownModel(model.id);
|
||||
const applyPatchToolType = inferGeneratedApplyPatchToolType(model, parsedModel);
|
||||
if (applyPatchToolType) {
|
||||
|
||||
+16
-16
@@ -18451,7 +18451,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18481,7 +18481,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18508,7 +18508,7 @@
|
||||
},
|
||||
"compat": {
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
@@ -18540,7 +18540,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18570,7 +18570,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18597,7 +18597,7 @@
|
||||
},
|
||||
"compat": {
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"contextWindow": 204800,
|
||||
@@ -18629,7 +18629,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18659,7 +18659,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18691,7 +18691,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18721,7 +18721,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18748,7 +18748,7 @@
|
||||
},
|
||||
"compat": {
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"contextWindow": 1000000,
|
||||
@@ -18780,7 +18780,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18810,7 +18810,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18837,7 +18837,7 @@
|
||||
},
|
||||
"compat": {
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"contextWindow": 204800,
|
||||
@@ -18869,7 +18869,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
@@ -18899,7 +18899,7 @@
|
||||
"compat": {
|
||||
"supportsStore": false,
|
||||
"supportsDeveloperRole": false,
|
||||
"thinkingFormat": "zai",
|
||||
"supportsReasoningEffort": false,
|
||||
"reasoningContentField": "reasoning_content"
|
||||
},
|
||||
"thinking": {
|
||||
|
||||
@@ -2112,7 +2112,7 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_CODING_PLANS: readonly ModelsDevProviderDe
|
||||
compat: {
|
||||
supportsStore: false,
|
||||
supportsDeveloperRole: false,
|
||||
thinkingFormat: "zai",
|
||||
supportsReasoningEffort: false,
|
||||
reasoningContentField: "reasoning_content",
|
||||
},
|
||||
}),
|
||||
@@ -2120,7 +2120,7 @@ const MODELS_DEV_PROVIDER_DESCRIPTORS_CODING_PLANS: readonly ModelsDevProviderDe
|
||||
compat: {
|
||||
supportsStore: false,
|
||||
supportsDeveloperRole: false,
|
||||
thinkingFormat: "zai",
|
||||
supportsReasoningEffort: false,
|
||||
reasoningContentField: "reasoning_content",
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { afterEach, describe, expect, it } from "bun:test";
|
||||
import { getBundledModel } from "@oh-my-pi/pi-ai/models";
|
||||
import { streamOpenAICompletions } from "@oh-my-pi/pi-ai/providers/openai-completions";
|
||||
import type { Context, Model } from "@oh-my-pi/pi-ai/types";
|
||||
|
||||
const originalFetch = global.fetch;
|
||||
|
||||
afterEach(() => {
|
||||
global.fetch = originalFetch;
|
||||
});
|
||||
|
||||
const context: Context = {
|
||||
systemPrompt: ["stable instructions", "cacheable policy"],
|
||||
messages: [{ role: "user", content: "hello", timestamp: Date.now() }],
|
||||
};
|
||||
|
||||
function abortedSignal(): AbortSignal {
|
||||
const controller = new AbortController();
|
||||
controller.abort();
|
||||
return controller.signal;
|
||||
}
|
||||
|
||||
async function capturePayload(model: Model<"openai-completions">): Promise<Record<string, unknown>> {
|
||||
const { promise, resolve } = Promise.withResolvers<Record<string, unknown>>();
|
||||
streamOpenAICompletions(model, context, {
|
||||
apiKey: "test-key",
|
||||
signal: abortedSignal(),
|
||||
reasoning: "high",
|
||||
onPayload: payload => resolve(payload as Record<string, unknown>),
|
||||
});
|
||||
return await promise;
|
||||
}
|
||||
|
||||
describe("issue #955 — MiniMax coding-plan plan mode payload", () => {
|
||||
it.each([
|
||||
["minimax-code", "MiniMax-M2.5"],
|
||||
["minimax-code-cn", "MiniMax-M2.5"],
|
||||
] as const)("omits unsupported thinking fields for %s/%s", async (provider, modelId) => {
|
||||
const model = getBundledModel(provider, modelId) as Model<"openai-completions">;
|
||||
const body = await capturePayload(model);
|
||||
|
||||
expect(body.model).toBe(modelId);
|
||||
expect(body.messages).toEqual([
|
||||
{ role: "system", content: "stable instructions\n\ncacheable policy" },
|
||||
{ role: "user", content: "hello" },
|
||||
]);
|
||||
expect(body.thinking).toBeUndefined();
|
||||
expect(body.reasoning).toBeUndefined();
|
||||
expect(body.reasoning_effort).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user