mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-12 11:12:21 +02:00
fix(agent): drop the empty assistant turn from an approved-action replay (#6124)
The approved-action replay appends the sealed tool result with no assistant prose for that round, which produced an assistant message with content "". Anthropic's Messages API rejects a non-final assistant message with empty content, so a resumed turn after a tool approval failed before the model saw the result. A turn carrying neither prose nor reasoning has nothing to say to any provider, so it is no longer appended. A round with prose, and a reasoning-only round that DeepSeek thinking mode needs, both still append.
This commit is contained in:
+11
-4
@@ -3081,10 +3081,17 @@ def _append_tool_results(
|
||||
messages.append(result_message)
|
||||
else:
|
||||
tool_output_text = "\n\n".join(tool_results)
|
||||
msg = {"role": "assistant", "content": round_response}
|
||||
if round_reasoning:
|
||||
msg["reasoning_content"] = round_reasoning
|
||||
messages.append(msg)
|
||||
# An approved-action replay injects the sealed tool result with no
|
||||
# assistant prose for that round, which used to append an assistant turn
|
||||
# whose content was "". Anthropic's Messages API rejects a non-final
|
||||
# assistant message with empty content (HTTP 400), so the resumed turn
|
||||
# died before the model saw the result. A turn carrying neither prose nor
|
||||
# reasoning has nothing to say to any provider, so skip it entirely.
|
||||
if round_response.strip() or round_reasoning:
|
||||
msg = {"role": "assistant", "content": round_response}
|
||||
if round_reasoning:
|
||||
msg["reasoning_content"] = round_reasoning
|
||||
messages.append(msg)
|
||||
# Tool output (shell/python stdout, file reads, fetched pages, email
|
||||
# bodies, MCP results) is sourced from outside the server. Wrap it as
|
||||
# untrusted data so prompt-injection inside a tool result is treated as
|
||||
|
||||
Reference in New Issue
Block a user