mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
refactor(deepseek-reasoning): consolidate detection into helpers + regression tests
Extracts _needs_kimi_tool_reasoning() for symmetry with the existing _needs_deepseek_tool_reasoning() helper, so _copy_reasoning_content_for_api uses the same detection logic as _build_assistant_message. Future changes to either provider's signals now only touch one function. Adds tests/run_agent/test_deepseek_reasoning_content_echo.py covering: - All 3 DeepSeek detection signals (provider, model, host) - Poisoned history replay (empty string fallback) - Plain assistant turns NOT padded - Explicit reasoning_content preserved - Reasoning field promoted to reasoning_content - Existing Kimi/Moonshot detection intact - Non-thinking providers left alone 21 tests, all pass.
This commit is contained in:
parent
e93cc934c7
commit
d58b305adf
2 changed files with 238 additions and 15 deletions
40
run_agent.py
40
run_agent.py
|
|
@ -7706,13 +7706,26 @@ class AIAgent:
|
|||
|
||||
return msg
|
||||
|
||||
def _needs_kimi_tool_reasoning(self) -> bool:
|
||||
"""Return True when the current provider is Kimi / Moonshot thinking mode.
|
||||
|
||||
Kimi ``/coding`` and Moonshot thinking mode both require
|
||||
``reasoning_content`` on every assistant tool-call message; omitting
|
||||
it causes the next replay to fail with HTTP 400.
|
||||
"""
|
||||
return (
|
||||
self.provider in {"kimi-coding", "kimi-coding-cn"}
|
||||
or base_url_host_matches(self.base_url, "api.kimi.com")
|
||||
or base_url_host_matches(self.base_url, "moonshot.ai")
|
||||
or base_url_host_matches(self.base_url, "moonshot.cn")
|
||||
)
|
||||
|
||||
def _needs_deepseek_tool_reasoning(self) -> bool:
|
||||
"""Return True when the current provider is DeepSeek thinking mode.
|
||||
|
||||
Used to decide whether to store reasoning_content on tool-call
|
||||
assistant messages. DeepSeek V4 thinking mode requires this field
|
||||
on every assistant tool-call turn; omitting it causes HTTP 400
|
||||
when the message is replayed in a subsequent API request (#15250).
|
||||
DeepSeek V4 thinking mode requires ``reasoning_content`` on every
|
||||
assistant tool-call turn; omitting it causes HTTP 400 when the
|
||||
message is replayed in a subsequent API request (#15250).
|
||||
"""
|
||||
provider = (self.provider or "").lower()
|
||||
model = (self.model or "").lower()
|
||||
|
|
@ -7737,17 +7750,14 @@ class AIAgent:
|
|||
api_msg["reasoning_content"] = normalized_reasoning
|
||||
return
|
||||
|
||||
provider = (self.provider or "").lower()
|
||||
model = (self.model or "").lower()
|
||||
needs_tool_reasoning_echo = (
|
||||
provider in {"kimi-coding", "kimi-coding-cn", "deepseek"}
|
||||
or "deepseek" in model
|
||||
or base_url_host_matches(self.base_url, "api.kimi.com")
|
||||
or base_url_host_matches(self.base_url, "moonshot.ai")
|
||||
or base_url_host_matches(self.base_url, "moonshot.cn")
|
||||
or base_url_host_matches(self.base_url, "api.deepseek.com")
|
||||
)
|
||||
if needs_tool_reasoning_echo and source_msg.get("tool_calls"):
|
||||
# Providers that require an echoed reasoning_content on every
|
||||
# assistant tool-call turn. Detection logic lives in the per-provider
|
||||
# helpers so both the creation path (_build_assistant_message) and
|
||||
# this replay path stay in sync.
|
||||
if source_msg.get("tool_calls") and (
|
||||
self._needs_kimi_tool_reasoning()
|
||||
or self._needs_deepseek_tool_reasoning()
|
||||
):
|
||||
api_msg["reasoning_content"] = ""
|
||||
|
||||
@staticmethod
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue