# NousResearch/hermes-agent · DeepSeek/Kimi reasoning field promotion bug fixes

## Open now

- Nothing open on GitHub.

Multiple fixes and related regression reports targeting correct placement and promotion of the reasoning_content field in DeepSeek/Kimi assistant messages, particularly during tool-call turns. The cluster centers on a specific regression introduced by an earlier change and subsequent attempts to restore correct behavior.

## TL;DR

- 5 member(s): 0 open issue(s), 1 closed issue(s), 0 open PR(s), 2 merged PR(s), 2 PR(s) closed without merging.
- A fix was merged to main in PR #15478. Verify it addresses your case.
- **Recommended:** read PR #15478 (and any competing PRs below) before filing. Confirm the merged change covers your symptom.

## Maintainer resolution verdict

- Internal-tracker verdict over this cluster's issue members: `resolved` · deciding PR(s): `pr-16097`. This is distinct from the fix status above. Weigh it yourself.

## How this cluster was grouped

- Link evidence (`STRUCTURAL_SPANNING`): every member is connected by structural evidence: shared changed files, or a closing/superseded reference.
- Pairwise link density `0.40`: the share of member pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36. `1.00` means every pair is linked.

## Closed / duplicate issues

- #15812: regression: #15749 breaks reasoning field promotion for DeepSeek/Kimi tool-call messages

## Prior & competing PRs

- **#15478: fix: DeepSeek/Kimi thinking mode requires reasoning_content on ALL assistant messages**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `run_agent.py`, `tests/run_agent/test_deepseek_reasoning_content_echo.py`
  - fix hunks:
  - `run_agent.py`

    ```diff
    @@ -7785,7 +7785,17 @@ def _copy_reasoning_content_for_api(self, source_msg: dict, api_msg: dict) -> No
                 api_msg["reasoning_content"] = normalized_reasoning
                 return
     
    -        # 4. reasoning_content was present but not a string (e.g. None after
    +        # 4. DeepSeek / Kimi thinking mode: all assistant messages need
    +        # reasoning_content. Inject "" to satisfy the provider's requirement
    +        # when no explicit reasoning content is present.
    +        if (
    +            self._needs_kimi_tool_reasoning()
    +            or self._needs_deepseek_tool_reasoning()
    +        ):
    +            api_msg["reasoning_content"] = ""
    +            return
    +
    +        # 5. reasoning_content was present but not a string (e.g. None after
             # context compaction).  Don't pass null to the API.
             api_msg.pop("reasoning_content", None)
     
    ```
  - `tests/run_agent/test_deepseek_reasoning_content_echo.py`

    ```diff
    @@ -88,13 +88,13 @@ def test_deepseek_tool_call_poisoned_history_gets_empty_string(self) -> None:
             agent._copy_reasoning_content_for_api(source, api_msg)
             assert api_msg.get("reasoning_content") == ""
     
    -    def test_deepseek_assistant_no_tool_call_left_alone(self) -> None:
    -        """Plain assistant turns without tool_calls don't get padded."""
    +    def test_deepseek_assistant_no_tool_call_gets_padded(self) -> None:
    +        """DeepSeek thinking mode pads ALL assistant turns, even without tool_calls."""
             agent = _make_agent(provider="deepseek", model="deepseek-v4-flash")
             source = {"role": "assistant", "content": "hello"}
             api_msg: dict = {}
             agent._copy_reasoning_content_for_api(source, api_msg)
    -        assert "reasoning_content" not in api_msg
    +        assert api_msg.get("reasoning_content") == ""
     
         def test_deepseek_explicit_reasoning_content_preserved(self) -> None:
             """When reasoning_content is already set, it's copied verbatim."""
    ```
- **#16097: fix(run_agent): restore reasoning field promotion on DeepSeek/Kimi tool-call turns (salvage #15883)**. merged to main · fix tier `verified`
  - maintainer direction: category `merged`; implication `superseded`
  - files: `run_agent.py`, `scripts/release.py`
- **#15830: fix(reasoning): promote reasoning field before empty-pad for DeepSeek/Kimi (#15812)**. closed without merge
  - maintainer direction: category `implemented_elsewhere`; implication `superseded`; refs `93a2d6b30`, `d58b305ad`, `ad0ac8947`, `5ae608152`, `ad0ac8947`, `9daa0620a`, `63bf7a29b`, `#16500`
- **#15883: fix(run_agent): prevent reasoning_content regression in DeepSeek/Kimi tool-call replay (#15812)**. closed without merge
  - maintainer direction: category `merged_via`; implication `superseded`; refs `63bf7a29b`, `#16097`, `#15478`

## Fix status

- Merged to main in PR #15478 (cited above). No release data is tracked. Verify downstream.
- Fix last verified (merged) `2026-04-26`.
