hermes - ✅(Solved) Fix feat: Add Xiaomi MiMo Anthropic-compatible endpoint support for thinking mode [2 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
NousResearch/hermes-agent#24884Fetched 2026-05-14 03:50:57
View on GitHub
Comments
1
Participants
2
Timeline
9
Reactions
0
Author
Timeline (top)
labeled ×5cross-referenced ×2commented ×1subscribed ×1

Error Message

When using Xiaomi MiMo model (mimo-v2.5-pro) via Anthropic-compatible endpoint (https://token-plan-cn.xiaomimimo.com/anthropic), enabling thinking mode (reasoning_effort: medium/high) causes HTTP 400 error: This causes Xiaomi's API to not receive the required reasoning_content, resulting in a 400 error.

Root Cause

Xiaomi's /anthropic endpoint, like Kimi and DeepSeek, uses the Anthropic Messages protocol but has special requirements for thinking mode:

  1. Requires reasoning_content (in the form of unsigned thinking blocks) to be passed back to the API in subsequent requests
  2. Cannot validate Anthropic's proprietary signatures

However, the convert_messages_to_anthropic function in agent/anthropic_adapter.py strips all thinking blocks when a third-party endpoint is detected (lines 1780-1788):

elif _is_third_party or idx != last_assistant_idx:
    stripped = [
        b for b in m["content"]
        if not (isinstance(b, dict) and b.get("type") in _THINKING_TYPES)
    ]
    m["content"] = stripped or [{"type": "text", "text": "(thinking elided)"}]

This causes Xiaomi's API to not receive the required reasoning_content, resulting in a 400 error.

Fix Action

Solution

Following the approach used for Kimi and DeepSeek, add Xiaomi endpoint support in agent/anthropic_adapter.py:

1. Add Xiaomi endpoint detection function

def _is_xiaomi_anthropic_endpoint(base_url: str | None) -> bool:
    """Return True for Xiaomi MiMo's Anthropic-compatible endpoint."""
    normalized = _normalize_base_url_text(base_url)
    if not normalized:
        return False
    normalized = normalized.rstrip("/").lower()
    return "xiaomimimo.com" in normalized and "/anthropic" in normalized

2. Modify thinking block handling logic

Add Xiaomi endpoint to the _preserve_unsigned_thinking condition:

_preserve_unsigned_thinking = (
    _is_kimi_family_endpoint(base_url, model)
    or _is_deepseek_anthropic_endpoint(base_url)
    or _is_xiaomi_anthropic_endpoint(base_url)  # Added
)

This preserves unsigned thinking blocks synthesized from reasoning_content while stripping Anthropic's signed blocks.


Note: This issue and solution were submitted by ClaudeCode powered by MiMo-2.5-Pro.

PR fix notes

PR #24887: feat: add Xiaomi MiMo Anthropic-compatible endpoint support for thinking mode

Description (problem / solution / changelog)

Summary

Add support for Xiaomi MiMo's Anthropic-compatible endpoint (/anthropic) for thinking mode. This fix resolves HTTP 400 errors when using Xiaomi MiMo models with thinking/reasoning enabled.

Problem

When using Xiaomi MiMo model (mimo-v2.5-pro) via Anthropic-compatible endpoint (https://token-plan-cn.xiaomimimo.com/anthropic), enabling thinking mode causes HTTP 400 error:

HTTP 400: Param Incorrect
The reasoning_content in the thinking mode must be passed back to the API.

Root Cause

Xiaomi's /anthropic endpoint, like Kimi and DeepSeek, uses the Anthropic Messages protocol but requires unsigned thinking blocks to be preserved when thinking mode is enabled. The current code strips all thinking blocks for third-party endpoints, causing Xiaomi's API to not receive the required reasoning_content.

Solution

Following the approach used for Kimi and DeepSeek endpoints:

  1. Added _is_xiaomi_anthropic_endpoint() detection function
  2. Added Xiaomi endpoint to _preserve_unsigned_thinking condition in convert_messages_to_anthropic()

This preserves unsigned thinking blocks synthesized from reasoning_content while stripping Anthropic's signed blocks, matching the behavior for Kimi and DeepSeek endpoints.

Test plan

  • Test Xiaomi MiMo model with thinking mode enabled (reasoning_effort: medium/high)
  • Verify no HTTP 400 errors when using thinking mode
  • Verify thinking blocks are properly preserved in multi-turn conversations
  • Verify existing Kimi and DeepSeek endpoints still work correctly

Related issues

Closes #24884


Note: This PR was created by ClaudeCode powered by MiMo-2.5-Pro.

Changed files

  • agent/anthropic_adapter.py (modified, +30/-6)

PR #24893: fix: preserve Xiaomi MiMo thinking blocks

Description (problem / solution / changelog)

Summary

  • Add a Xiaomi MiMo Anthropic-compatible endpoint detector for *.xiaomimimo.com/anthropic.
  • Preserve unsigned reasoning_content-derived thinking blocks for Xiaomi MiMo replay turns, matching the existing Kimi/DeepSeek strip-signed/keep-unsigned policy.
  • Add a specification-driven development note plus focused regression coverage for Xiaomi MiMo, signed-block stripping, cache-control stripping, and non-Xiaomi third-party behavior.

Test Plan

  • RED observed before implementation: python -m pytest --tb=short -q tests/agent/test_xiaomi_mimo_anthropic_thinking.py failed with missing detector / thinking blocks stripped.
  • /Users/gen/.hermes/hermes-agent/venv/bin/python -m pytest --tb=short -q tests/agent/test_xiaomi_mimo_anthropic_thinking.py tests/agent/test_deepseek_anthropic_thinking.py → 18 passed.
  • /Users/gen/.hermes/hermes-agent/venv/bin/python -m pytest --tb=short -q tests/agent/test_xiaomi_mimo_anthropic_thinking.py tests/agent/test_deepseek_anthropic_thinking.py tests/agent/test_kimi_coding_anthropic_thinking.py → 35 passed.
  • /Users/gen/.hermes/hermes-agent/venv/bin/python -m ruff check agent/anthropic_adapter.py tests/agent/test_xiaomi_mimo_anthropic_thinking.py → All checks passed.

Docker / containerization

  • No Dockerfile, dependency, or environment-variable changes were needed; the existing container image copies these Python source/test changes normally.
  • Local docker build -t hermes-agent:issue-24884 . was attempted but failed before project build steps while resolving debian:13.4 from Docker Hub due local Docker proxy DNS (lookup http.docker.internal ... connection refused). This appears environment/network-related rather than code-related.

Closes #24884

Changed files

  • agent/anthropic_adapter.py (modified, +25/-6)
  • docs/specs/24884-xiaomi-mimo-thinking.md (added, +283/-0)
  • tests/agent/test_xiaomi_mimo_anthropic_thinking.py (added, +235/-0)

Code Example

HTTP 400: Param Incorrect
The reasoning_content in the thinking mode must be passed back to the API.

---

elif _is_third_party or idx != last_assistant_idx:
    stripped = [
        b for b in m["content"]
        if not (isinstance(b, dict) and b.get("type") in _THINKING_TYPES)
    ]
    m["content"] = stripped or [{"type": "text", "text": "(thinking elided)"}]

---

def _is_xiaomi_anthropic_endpoint(base_url: str | None) -> bool:
    """Return True for Xiaomi MiMo's Anthropic-compatible endpoint."""
    normalized = _normalize_base_url_text(base_url)
    if not normalized:
        return False
    normalized = normalized.rstrip("/").lower()
    return "xiaomimimo.com" in normalized and "/anthropic" in normalized

---

_preserve_unsigned_thinking = (
    _is_kimi_family_endpoint(base_url, model)
    or _is_deepseek_anthropic_endpoint(base_url)
    or _is_xiaomi_anthropic_endpoint(base_url)  # 新增
)

---

HTTP 400: Param Incorrect
The reasoning_content in the thinking mode must be passed back to the API.

---

elif _is_third_party or idx != last_assistant_idx:
    stripped = [
        b for b in m["content"]
        if not (isinstance(b, dict) and b.get("type") in _THINKING_TYPES)
    ]
    m["content"] = stripped or [{"type": "text", "text": "(thinking elided)"}]

---

def _is_xiaomi_anthropic_endpoint(base_url: str | None) -> bool:
    """Return True for Xiaomi MiMo's Anthropic-compatible endpoint."""
    normalized = _normalize_base_url_text(base_url)
    if not normalized:
        return False
    normalized = normalized.rstrip("/").lower()
    return "xiaomimimo.com" in normalized and "/anthropic" in normalized

---

_preserve_unsigned_thinking = (
    _is_kimi_family_endpoint(base_url, model)
    or _is_deepseek_anthropic_endpoint(base_url)
    or _is_xiaomi_anthropic_endpoint(base_url)  # Added
)
RAW_BUFFERClick to expand / collapse

中文

问题描述

使用小米 MiMo 模型(mimo-v2.5-pro)通过 Anthropic 兼容端点(https://token-plan-cn.xiaomimimo.com/anthropic)时,启用 thinking 模式(reasoning_effort: medium/high)会导致 HTTP 400 错误:

HTTP 400: Param Incorrect
The reasoning_content in the thinking mode must be passed back to the API.

原因分析

小米的 /anthropic 端点与 Kimi、DeepSeek 一样,使用 Anthropic Messages 协议,但在 thinking 模式下有特殊要求:

  1. 需要将 reasoning_content(以 unsigned thinking blocks 形式)在后续请求中传回 API
  2. 不能验证 Anthropic 的专有签名(signature)

然而,agent/anthropic_adapter.py 中的 convert_messages_to_anthropic 函数在检测到第三方端点时,会剥离所有 thinking blocks(第 1780-1788 行):

elif _is_third_party or idx != last_assistant_idx:
    stripped = [
        b for b in m["content"]
        if not (isinstance(b, dict) and b.get("type") in _THINKING_TYPES)
    ]
    m["content"] = stripped or [{"type": "text", "text": "(thinking elided)"}]

这导致小米 API 收不到必需的 reasoning_content,返回 400 错误。

解决方案

参考 Kimi 和 DeepSeek 的处理方式,在 agent/anthropic_adapter.py 中添加小米端点的支持:

1. 添加小米端点检测函数

def _is_xiaomi_anthropic_endpoint(base_url: str | None) -> bool:
    """Return True for Xiaomi MiMo's Anthropic-compatible endpoint."""
    normalized = _normalize_base_url_text(base_url)
    if not normalized:
        return False
    normalized = normalized.rstrip("/").lower()
    return "xiaomimimo.com" in normalized and "/anthropic" in normalized

2. 修改 thinking block 处理逻辑

将小米端点添加到 _preserve_unsigned_thinking 条件中:

_preserve_unsigned_thinking = (
    _is_kimi_family_endpoint(base_url, model)
    or _is_deepseek_anthropic_endpoint(base_url)
    or _is_xiaomi_anthropic_endpoint(base_url)  # 新增
)

这样可以保留从 reasoning_content 合成的 unsigned thinking blocks,同时剥离 Anthropic 的 signed blocks。


English

Problem Description

When using Xiaomi MiMo model (mimo-v2.5-pro) via Anthropic-compatible endpoint (https://token-plan-cn.xiaomimimo.com/anthropic), enabling thinking mode (reasoning_effort: medium/high) causes HTTP 400 error:

HTTP 400: Param Incorrect
The reasoning_content in the thinking mode must be passed back to the API.

Root Cause

Xiaomi's /anthropic endpoint, like Kimi and DeepSeek, uses the Anthropic Messages protocol but has special requirements for thinking mode:

  1. Requires reasoning_content (in the form of unsigned thinking blocks) to be passed back to the API in subsequent requests
  2. Cannot validate Anthropic's proprietary signatures

However, the convert_messages_to_anthropic function in agent/anthropic_adapter.py strips all thinking blocks when a third-party endpoint is detected (lines 1780-1788):

elif _is_third_party or idx != last_assistant_idx:
    stripped = [
        b for b in m["content"]
        if not (isinstance(b, dict) and b.get("type") in _THINKING_TYPES)
    ]
    m["content"] = stripped or [{"type": "text", "text": "(thinking elided)"}]

This causes Xiaomi's API to not receive the required reasoning_content, resulting in a 400 error.

Solution

Following the approach used for Kimi and DeepSeek, add Xiaomi endpoint support in agent/anthropic_adapter.py:

1. Add Xiaomi endpoint detection function

def _is_xiaomi_anthropic_endpoint(base_url: str | None) -> bool:
    """Return True for Xiaomi MiMo's Anthropic-compatible endpoint."""
    normalized = _normalize_base_url_text(base_url)
    if not normalized:
        return False
    normalized = normalized.rstrip("/").lower()
    return "xiaomimimo.com" in normalized and "/anthropic" in normalized

2. Modify thinking block handling logic

Add Xiaomi endpoint to the _preserve_unsigned_thinking condition:

_preserve_unsigned_thinking = (
    _is_kimi_family_endpoint(base_url, model)
    or _is_deepseek_anthropic_endpoint(base_url)
    or _is_xiaomi_anthropic_endpoint(base_url)  # Added
)

This preserves unsigned thinking blocks synthesized from reasoning_content while stripping Anthropic's signed blocks.


Note: This issue and solution were submitted by ClaudeCode powered by MiMo-2.5-Pro.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING