fix(reasoning-tags): strip MiniMax mm: namespaced reasoning tags#93767
Conversation
MiniMax M3 (e.g. via Fireworks) emits its chain-of-thought inline in the content stream wrapped in `<mm:think>…</mm:think>` rather than in a separate `reasoning_content` field. The reasoning-tag stripper only recognized the `antml:` namespace, so `mm:`-namespaced tags slipped through QUICK_TAG_RE and leaked the model's hidden reasoning into visible chat output. Accept the `mm:` prefix alongside `antml:` in the shared sanitizer (reasoning-tags.ts) and in the Telegram reasoning-lane coordinator's tag regex and prefix list. Adds unit tests covering mm: think/thinking/thought blocks, truncated-open orphan close recovery, and code-fence preservation. Co-Authored-By: Claude Opus 4.8 <[email protected]>
a8a20ae to
c5e0dcb
Compare
|
ClawSweeper review: did not complete due to Codex infrastructure failure. Reviewed June 16, 2026, 4:36 PM ET / 20:36 UTC. Summary PR surface: Source +6, Tests +15. Total +21 across 3 files. Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path. Review metrics: none identified. Merge readiness This is a ClawSweeper/Codex infrastructure failure, not a PR readiness or patch-quality verdict. Risk before merge
Maintainer options:
Next step before merge
Review detailsBest possible solution: Retry the Codex review after fixing the execution failure. Do we have a high-confidence way to reproduce the issue? Unclear. The review failed before ClawSweeper could establish a reproduction path. Is this the best way to solve the issue? Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model internal, reasoning high; reviewed against d211d49011ba. Evidence reviewedPR surface: Source +6, Tests +15. Total +21 across 3 files. View PR surface stats
What I checked:
Likely related people:
How this review workflow works
|
|
Maintainer review and repair complete. This now handles MiniMax Verification:
Known proof gaps: none. |
…d stream gates PR openclaw#93767 added MiniMax `mm:`-namespaced reasoning-tag support across the shared sanitizer and Telegram lane coordinator, but two production reasoning-tag recognizers were missed and still only matched the `antml:` namespace: - src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe` drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+ call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY` reply was not recognized as silent, leaking the wrapper into delivery. - src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE` gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the test, so the visible stream was not recomputed and the hidden reasoning leaked. Add the `mm:` alternative alongside `antml:` in all three regexes, matching the exact `(?:antml:|mm:)?` form used by openclaw#93767. Identification-only change, no other regex logic touched.
…d stream gates PR openclaw#93767 added MiniMax `mm:`-namespaced reasoning-tag support across the shared sanitizer and Telegram lane coordinator, but two production reasoning-tag recognizers were missed and still only matched the `antml:` namespace: - src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe` drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+ call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY` reply was not recognized as silent, leaking the wrapper into delivery. - src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE` gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the test, so the visible stream was not recomputed and the hidden reasoning leaked. Add the `mm:` alternative alongside `antml:` in all three regexes, matching the exact `(?:antml:|mm:)?` form used by openclaw#93767. Identification-only change, no other regex logic touched.
…ming paths missed by #93767 (#93806) * fix(reasoning-tags): accept MiniMax mm: prefix in silent-detection and stream gates PR #93767 added MiniMax `mm:`-namespaced reasoning-tag support across the shared sanitizer and Telegram lane coordinator, but two production reasoning-tag recognizers were missed and still only matched the `antml:` namespace: - src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe` drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+ call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY` reply was not recognized as silent, leaking the wrapper into delivery. - src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE` gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the test, so the visible stream was not recomputed and the hidden reasoning leaked. Add the `mm:` alternative alongside `antml:` in all three regexes, matching the exact `(?:antml:|mm:)?` form used by #93767. Identification-only change, no other regex logic touched. * test(agents): cover MiniMax reasoning regressions --------- Co-authored-by: Vincent Koc <[email protected]>
…penclaw#93767) * fix(reasoning-tags): strip MiniMax `mm:` namespaced reasoning tags MiniMax M3 (e.g. via Fireworks) emits its chain-of-thought inline in the content stream wrapped in `<mm:think>…</mm:think>` rather than in a separate `reasoning_content` field. The reasoning-tag stripper only recognized the `antml:` namespace, so `mm:`-namespaced tags slipped through QUICK_TAG_RE and leaked the model's hidden reasoning into visible chat output. Accept the `mm:` prefix alongside `antml:` in the shared sanitizer (reasoning-tags.ts) and in the Telegram reasoning-lane coordinator's tag regex and prefix list. Adds unit tests covering mm: think/thinking/thought blocks, truncated-open orphan close recovery, and code-fence preservation. Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(reasoning): handle MiniMax tags in streams --------- Co-authored-by: DrHack1 <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: Vincent Koc <[email protected]>
…ming paths missed by openclaw#93767 (openclaw#93806) * fix(reasoning-tags): accept MiniMax mm: prefix in silent-detection and stream gates PR openclaw#93767 added MiniMax `mm:`-namespaced reasoning-tag support across the shared sanitizer and Telegram lane coordinator, but two production reasoning-tag recognizers were missed and still only matched the `antml:` namespace: - src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe` drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+ call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY` reply was not recognized as silent, leaking the wrapper into delivery. - src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE` gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the test, so the visible stream was not recomputed and the hidden reasoning leaked. Add the `mm:` alternative alongside `antml:` in all three regexes, matching the exact `(?:antml:|mm:)?` form used by openclaw#93767. Identification-only change, no other regex logic touched. * test(agents): cover MiniMax reasoning regressions --------- Co-authored-by: Vincent Koc <[email protected]>
…penclaw#93767) * fix(reasoning-tags): strip MiniMax `mm:` namespaced reasoning tags MiniMax M3 (e.g. via Fireworks) emits its chain-of-thought inline in the content stream wrapped in `<mm:think>…</mm:think>` rather than in a separate `reasoning_content` field. The reasoning-tag stripper only recognized the `antml:` namespace, so `mm:`-namespaced tags slipped through QUICK_TAG_RE and leaked the model's hidden reasoning into visible chat output. Accept the `mm:` prefix alongside `antml:` in the shared sanitizer (reasoning-tags.ts) and in the Telegram reasoning-lane coordinator's tag regex and prefix list. Adds unit tests covering mm: think/thinking/thought blocks, truncated-open orphan close recovery, and code-fence preservation. Co-Authored-By: Claude Opus 4.8 <[email protected]> * fix(reasoning): handle MiniMax tags in streams --------- Co-authored-by: DrHack1 <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]> Co-authored-by: Vincent Koc <[email protected]>
…ming paths missed by openclaw#93767 (openclaw#93806) * fix(reasoning-tags): accept MiniMax mm: prefix in silent-detection and stream gates PR openclaw#93767 added MiniMax `mm:`-namespaced reasoning-tag support across the shared sanitizer and Telegram lane coordinator, but two production reasoning-tag recognizers were missed and still only matched the `antml:` namespace: - src/auto-reply/tokens.ts: `taggedReasoningPrefixRe` / `openReasoningPrefixRe` drive `stripLeadingReasoningBlocks` and `isSilentReplyPayloadText`, which 14+ call sites use to detect NO_REPLY silent payloads. A `<mm:think>…</mm:think>NO_REPLY` reply was not recognized as silent, leaking the wrapper into delivery. - src/agents/embedded-agent-subscribe.handlers.messages.ts: `REASONING_TAG_RE` gates `shouldRecomputeFullStream`. A `<mm:think>` streaming chunk failed the test, so the visible stream was not recomputed and the hidden reasoning leaked. Add the `mm:` alternative alongside `antml:` in all three regexes, matching the exact `(?:antml:|mm:)?` form used by openclaw#93767. Identification-only change, no other regex logic touched. * test(agents): cover MiniMax reasoning regressions --------- Co-authored-by: Vincent Koc <[email protected]>
…tion guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept)
…or replies Mirrors openclaw#93874 (slack monitor) for the matrix extension. The matrix reply delivery path checks shouldSuppressReasoningReplyText to drop reasoning-only payloads before they reach the Matrix room; the THINKING_TAG_RE / THINKING_BLOCK_RE patterns only matched bare, antml:, or antthinking variants, so MiniMax <mm:think>…</mm:think> payloads were treated as ordinary replies and the reasoning text was sent into the Matrix room (a reasoning leak, not just a missed preview). Align the regexes with src/shared/text/reasoning-tags.ts and openclaw#93767's precedent by adding an optional (?:antml:|mm:)? prefix on think/thinking/thought; antthinking is left unprefixed. Adds a regression test that streams three mm: namespaced reasoning-only replies and asserts only the visible answer reaches sendMessageMatrix.
…tion guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept)
…tion guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept)
…tion guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept)
…rd (completes #93767) (#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR #93767). This is the remaining channel-monitor complement of #93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]>
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]>
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]>
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]>
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]>
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]> (cherry picked from commit 076da56)
…eplies The THINKING_TAG_RE and THINKING_BLOCK_RE regex patterns in the Matrix monitor replies module were missing the mm: namespace prefix for detecting MiniMax reasoning tags. This caused mm:think/mm:thought reasoning content to leak into Matrix room messages. Add (?:antml:|mm:)? prefix to think(?:ing)?|thought alternatives in both regexes, consistent with the pattern already applied in reasoning-tags.ts and other channel modules (see openclaw#93767, openclaw#93806, openclaw#93820). Fixes openclaw#99412
…eplies The THINKING_TAG_RE and THINKING_BLOCK_RE regex patterns in the Matrix monitor replies module were missing the mm: namespace prefix for detecting MiniMax reasoning tags. This caused mm:think/mm:thought reasoning content to leak into Matrix room messages. Add (?:antml:|mm:)? prefix to think(?:ing)?|thought alternatives in both regexes, consistent with the pattern already applied in reasoning-tags.ts and other channel modules (see openclaw#93767, openclaw#93806, openclaw#93820). Fixes openclaw#99412
…rd (completes openclaw#93767) (openclaw#93820) * fix(imessage): detect MiniMax mm: namespaced reasoning tags in reflection guard The iMessage reflection guard's THINKING_TAG_RE only matched bare `<think>/<thought>` tags, so MiniMax's `<mm:think>` namespaced reasoning tags (and Anthropic's `antml:` prefix) were not recognized as reflected assistant content. When such reasoning leaked back inbound, the guard treated it as a normal user message instead of dropping it, allowing recursive echo amplification. Accept the known reasoning-tag namespace prefixes `(?:antml:|mm:)?` on the think/thought alternatives, mirroring the shared reasoning-tag contract in src/shared/text/reasoning-tags.ts (PR openclaw#93767). This is the remaining channel-monitor complement of openclaw#93767 for the iMessage path; the optional prefix is a pure recognition enhancement with no change to the bare-tag, code-region exemption, or other reflection patterns. Verified by driving the real detectReflectedContent export: <mm:think>secret</mm:think>visible -> isReflection=true (was false) <think>...</think> -> isReflection=true <think>secret</think> -> isReflection=true (no regression) "thinking about minimax algorithms" -> isReflection=false (no false-positive) `<mm:think>x</mm:think>` in code -> isReflection=false (code exemption kept) * chore: retrigger CI for real behavior proof check * refactor(imessage): tighten reflection guard coverage --------- Co-authored-by: Peter Steinberger <[email protected]> (cherry picked from commit 076da56)
Problem
MiniMax M3 (e.g. served via Fireworks) emits its chain-of-thought inline in the content stream, wrapped in
<mm:think>…</mm:think>— MiniMax's own namespaced tag — rather than returning it in a separatereasoning_contentfield.The reasoning-tag stripper only recognizes the
antml:namespace:So
<mm:think>fails theQUICK_TAG_REguard instripReasoningTagsFromText, the function early-returns the text unchanged, and the model's hidden reasoning leaks into visible chat output. Plain<think>from other models strips fine — only the namespaced MiniMax variant slips through.Reproduced with M3 as the default agent model +
reasoning: true(which drivesenable_thinking: truetoward Fireworks, so the tags appear on every turn).Fix
Accept the
mm:prefix alongsideantml:, mirroring the existing namespace handling:src/shared/text/reasoning-tags.ts—QUICK_TAG_REandTHINKING_TAG_RE(the shared delivery sanitizer).extensions/telegram/src/reasoning-lane-coordinator.ts— localTHINKING_TAG_REandREASONING_TAG_PREFIXES.Added unit cases to
reasoning-tags.test.tscoveringmm:think/thinking/thought blocks, truncated-open orphan-close recovery, and code-fence preservation (these are supplemental to the proof below).Real behavior proof
Behavior or issue addressed: MiniMax M3 emits chain-of-thought wrapped in
<mm:think>…</mm:think>; the sanitizer only knew theantml:namespace, so that reasoning leaked verbatim into visible chat replies. This change makes the sanitizer recognize themm:namespace.Real environment tested: Local OpenClaw install, v2026.5.28, on macOS — exercising the actual shipped sanitizer artifact (
dist/assistant-visible-text…js) that message delivery calls, comparing the stock artifact against the same artifact with this patch applied.Exact steps or command run after this patch: Imported the shipped
stripReasoningTagsFromTextexport from both the stock artifact and the patched artifact, then ran one<mm:think>payload through each:Evidence after fix: Console output copied from that live
noderun against the real artifact:Observed result after fix: The stock artifact passes the entire
<mm:think>…</mm:think>reasoning block straight through to visible output. With the patch applied, only"Here is your answer."is delivered and the reasoning is removed. Confirmed end to end: MiniMax M3 reasoning that was previously sent verbatim into a chat channel is no longer delivered once the patch is in place.What was not tested: The other duplicated tag lists noted below (slack/imessage/matrix monitors and the progress-draft paths) were not exercised in this run.
Out-of-scope follow-ups
The same
antml:-only / no-namespace tag pattern is duplicated in several other spots (embedded-agent-utils.ts,reasoning-tag-text-partitioner.ts,auto-reply/tokens.ts,channels/progress-draft-compositor.ts, and the slack/imessage/matrix monitors). This PR fixes the two paths that produce the user-visible leak; consolidating these into a single shared tag-name constant would prevent future drift. Happy to extend this PR to cover them if preferred.Related
Complements #89473 (MiniMax M3 reasoning tokens leaking to chat channels). That issue is about
stripThinkingTagsFromText/sanitizeAssistantVisibleTextnot being applied as a final safety net on some delivery paths; this PR is the orthogonal half — making that sanitizer actually recognize MiniMax'smm:-namespaced tags (<mm:think>) so they are stripped once it runs. Both are needed to fully close the MiniMax leak. Also in the same reasoning-leak area: #90684, #87712.