Repository navigation
fix(core): preserve declared MiniMax Messages effort levels - #56510
rudycelekli wants to merge 2 commits into
Conversation
|
The following comment was made by an LLM, it may be inaccurate: |
There was a problem hiding this comment.
The fix works. On the base, Variant.resolve returns no variants for MiniMax-M3.1-Flash-Preview when the catalog declares an effort ladder. With this PR it returns low…max, each sending output_config.effort, and no none. MiniMax-M3 (toggle) and MiniMax-M2.7 behave as before. The issue's repro.sh couldn't run from source in either checkout because the standalone server stops before it's ready, so I checked by calling Variant.resolve directly. In packages/core, the variant and model-resolver tests pass (68/68). With your test files copied onto the base, the 3 new tests fail there. Typecheck passes.
The public API is unchanged.
The only thing I'd change is the new model-resolver test, which is heavier than it needs to be (see the inline comment).
Signed-off-by: Rudy Celekli <[email protected]>
|
The released I confirmed the request shape this PR produces against the live API. With a config override that sends |
benjaminkincses
left a comment
There was a problem hiding this comment.
checked this against #54801. the bug is real: a declared effort ladder hit configurable=false and returned []. this branch sits after the m2 guard and before the toggle fallback, so m2 still returns [] and m3 with no values still gets none/thinking. the resolver test covers the part that matters: no disabled thinking variant in the prepared body, since the api rejects it. looks right.
|
Alternative implementation for the same branch, with the coverage this report names (the The difference is the spelling. That PR uses Both produce the same request body, and both keep |
isHeSatoshi
left a comment
There was a problem hiding this comment.
Reviewed from #62265, which touches the same branch. The mapping itself is right; this is about the spelling.
body: { output_config: { effort } } vs settings: { effort }
The overlay is applied at the transport layer, after the protocol has built the request body, so it wins over anything the protocol produced for that model. A request-level effort is therefore ignored:
// model variant -> body overlay
const model = MiniMax.model("MiniMax-M3.1-Flash", { apiKey: "k", body: { output_config: { effort: "low" } } })
// request -> providerOptions: { effort: "high" }| spelling | wire body |
|---|---|
body: { output_config: { effort: "low" } } |
output_config: {"effort":"low"} — the request's high is dropped |
settings: { effort: "low" } |
output_config: {"effort":"high"} — the request wins |
mergeProviderOptions() merges model options under request options, so the typed option keeps a per-request effort working; the overlay cannot, because it is merged last, on top of the protocol body.
Two more points for the typed spelling:
- It is what the sibling Anthropic-compatible route already does.
moonshotMessagesmaps its ladder tosettings: { effort }, andMessagesOptionsInputthere declareseffort?: ReasoningEffort(packages/ai/src/providers/moonshot.ts). The MiniMax Messages route is the same kind of route, so the same spelling keeps one convention for Anthropic-compatible providers. - The MiniMax provider package then advertises the option instead of only the variant using it:
MessagesOptionsInput.effortbecomes part of the provider surface, andpackages/ai/test/provider-options/minimax.types.tscan assert it the way the Moonshot one does.
Coverage this PR is missing
The test here uses minimax-coding-plan with MiniMax-M3.1-Flash-Preview. The catalog declares the same ladder for the shipping MiniMax-M3.1-Flash on all four hosts (minimax, minimax-coding-plan, minimax-cn, minimax-cn-coding-plan), and minimax (the minimax.io API) is the one most people use. A test that resolves a variant for both minimax and minimax-coding-plan and asserts the request body would cover the report in #62264.
One assertion worth adding either way
The current test asserts resolved.route.defaults.http?.body and prepared.body, but prepared.body is the protocol body — the overlay is merged later, at transport time. Asserting the prepared transport body (or the merged JSON) is what proves the effort reaches the wire.
|
Concrete test for the coverage gap, adapted to the overlay spelling in this PR. It resolves a variant for both providers the report in #62264 names, on the shipping it.effect("sends declared MiniMax Messages effort levels", () =>
Effect.gen(function* () {
// The minimax.io API and the Token Plan both serve M3.1 Flash through the Messages route.
for (const providerID of ["minimax", "minimax-coding-plan"]) {
const base = model(Provider.aisdk("@ai-sdk/anthropic"), {
providerID: Provider.ID.make(providerID),
modelID: "MiniMax-M3.1-Flash",
})
const catalog = Info.make({
...base,
variants: Variant.resolve(base, [{ type: "effort", values: ["low", "max"] }]),
})
const resolved = yield* ModelResolver.resolveModel(
catalog,
VariantID.make("low"),
Credential.Key.make({ type: "key", key: "fixture" }),
)
const prepared = yield* compileRequest(ai.request({ model: resolved, prompt: "Hello" }))
expect(resolved.route.id).toBe("minimax-messages")
expect(resolved.options?.http?.body).toMatchObject({ output_config: { effort: "low" } })
// Thinking cannot be turned off on this model, so no toggle is sent.
expect(prepared.body.thinking).toBeUndefined()
}
}),
)The catalog declares the same ladder for Verified locally on this branch: decoding the live catalog with the fix applied yields the five effort variants for |
|
Scope note on the review above: the report this follows up is about the shipping |
Issue for this PR
Closes #54801
Type of change
What does this PR do?
Map catalog-declared MiniMax Messages effort levels to
body.output_config.effort. Preserve M3’s existing toggle and M2’s guard, without adding a disabled-thinking variant to the declared ladder. Follows the diagnosis recorded by @argszero and @drakeo338 in the issue.How did you verify your code works?
Screenshots / recordings
No visual UI code changed; variant definitions and outgoing request bodies are asserted.
Checklist