Repository navigation
fix(llm): keep the SSE keep-alive fallback for thinking-disabled MiniMax M3 streams - #18015
Conversation
…Max M3 streams stream_can_defer_all_output used the request-only reasoning gate, so a MiniMax M3 force_nonempty_content stream with thinking_mode=disabled (or reasoning_effort=none) reported that it defers nothing. Since ai-dynamo#17120 the stream builder keeps the M3 parser on when the rendered prompt leaves reasoning open, so such a stream can withhold every data frame with no keep-alive. Treat the M3 reasoning parser as possibly deferring, as the release-branch fix in ai-dynamo#17197 does. Refs DYN-5298 Signed-off-by: svc-glamr@nvidia.com <svc-glamr@nvidia.com>
|
👋 Hi glamr-agent! Thank you for contributing to ai-dynamo/dynamo. Just a reminder: The 🚀 |
|
factory: Initial validation snapshot. Validation status: complete
No live MiniMax M3 stream ran: the weights do not fit the single GPU available. The unit tests cover the keep-alive decision for the reported request, not a real 90-second reasoning stream. Detailed evidence — validation completeLeft out of the table because CI repeats them: none. Evidence: 1/1 validated. Advisory AI assessment: sound. Validation result: pass. The new M3 keep-alive assertions fail on main's predicate and pass with the fix. Workspace check, workspace Clippy, sidecar tests, and Commands and results [1/1 validated]Generated from the commands recorded during this run. Check 1Checks the changed Rust crates with Result: Passed ( Command: Not shown because the exact command contained private run data. |
|
No description provided. |
|
factory: @dynamo-ops please run full CI for a13eea9 |
|
/ok to test a13eea9 |
|
No actionable comments were generated in the recent review. WalkthroughThe preprocessor now treats MiniMax M3 as able to defer all output when forced nonempty content is enabled, even if thinking is disabled. Tests cover both M3 parser aliases and confirm that other parsers retain their existing behavior. ChangesMiniMax M3 deferred-output eligibility
Estimated code review effort: 2 (Simple) | ~10 minutes Merge Risk:
|
✅ Dynamo PR CI passed — run 41898892806 (attempt 1) on
|
Signed-off-by: GLAMR <svc-glamr@nvidia.com>
|
nursery: Merged the base fix in commit e869932 to address Devin’s finding. In |
|
nursery: @dynamo-ops please run full CI for e869932 |
|
/ok to test e869932 |
Signed-off-by: GLAMR <svc-glamr@nvidia.com>
|
nursery: @dynamo-ops please run full CI for 9eee0aa |
|
/ok to test 9eee0aa |
Failure behavior
A MiniMax M3 stream can send nothing for a long time and be cut off by an idle timeout. The reported setup is the public M3.1 Flash template, a streaming request with
reasoning_effort: "none"andforce_nonempty_content: true, noDYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MS, and about 90 seconds of reasoning. No frame goes on the wire during that time.Since #17120, the M3 reasoning parser still runs for a thinking-disabled request when the rendered prompt leaves reasoning open. This template ignores
thinking_mode, so it does. Withforce_nonempty_content, the stream then holds back every data frame while the model reasons. The HTTP handlers choose the 15-second fallback keep-alive before the prompt is rendered. They still use the request-only check, which says this request holds nothing back, so they send no keep-alive. The defect is in Dynamo.falsefor an M3force_nonempty_contentrequest with thinking disabled, so the stream got no fallback keep-alive. With the fix, both returntrue.Proposed fix
The frontend now treats every M3 stream with
force_nonempty_contentas one that may hold back all output, even when the request disables thinking. This applies to chat completions, Responses, and Anthropic Messages. It matches the fix on the release branch (#17197). The result is conservative: when an M3 template does close the reasoning, the stream still gets comment frames. A configuredDYN_HTTP_SSE_KEEP_ALIVE_INTERVAL_MSstill wins.force_nonempty_content: trueforce_nonempty_contentOpen #17381 sends a keep-alive on every Anthropic stream. If it merges first, the Anthropic part of this fix is redundant but harmless.
Validation
This PR adds one unit test to
lib/llm/src/preprocessor.rsand extends one unit test inlib/llm/src/http/service/openai.rs. Both run on CPU withcargo test -p dynamo-llm --lib, with no model and no GPU.minimax_m3_disabled_thinking_force_nonempty_stream_can_defer_all_output, and changed unit testresponses_force_nonempty_request_requires_fallback_keep_alive, which had no M3 case before this PR; also the reproduction aboveadaptivestill gets the fallbackforce_nonempty_contentgets no fallbackkimi_k25) that disables thinking still gets no fallbackThe before-fix run stopped at the new test's first assertion, so its later control assertions did not run without the fix.
Relates to #17120 and #17197.
Closes DYN-5298.
Summary by CodeRabbit