fix: minor issue fixes

This commit is contained in:
Alex committed 2026-06-30 18:36:06 +02:00
1 parent 99484e02c8
commit 75e07af78f
16 files changed
+950 -43

No files matched your search

+60
View File
@@ -759,6 +759,66 @@ class TestHandleToolCalls:
assistant_ids = {tc["id"] for tc in assistant_msg["tool_calls"]}
assert tool_msg["tool_call_id"] in assistant_ids
def test_create_tool_message_failure_no_duplicate_assistant(self):
"""A tool that succeeds but returns an unserializable result makes
create_tool_message raise *after* the success path appended the
assistant tool_calls message. The except branch must reuse that
message, not append a second one — exactly one assistant(tool_calls)
precedes the role:"tool" error, or the next completion 400s."""
class _SerializingHandler(ConcreteHandler):
def create_tool_message(
self, tool_call: ToolCall, result: Any
) -> Dict:
# Mirror real handlers: JSON-encode non-str results, which
# raises on a value the encoder can't serialize. The error
# path passes a plain string, so only the success path trips.
import json as _json
content = (
result
if isinstance(result, str)
else _json.dumps(result)
)
return {
"role": "tool",
"tool_call_id": tool_call.id,
"content": content,
}
handler = _SerializingHandler()
agent = self._make_agent()
agent.tool_executor._name_to_tool = {}
# Tool runs fine but returns a value json.dumps can't encode.
def fake_execute(tools_dict, call):
yield {"type": "tool_call", "data": {"status": "pending"}}
return (object(), call.id)
agent._execute_tool_action = Mock(side_effect=fake_execute)
call = ToolCall(id="c1", name="action_1", arguments="{}")
gen = handler.handle_tool_calls(agent, [call], {"1": {"name": "t"}}, [])
try:
while True:
next(gen)
except StopIteration as e:
messages, _pending = e.value
# Exactly one assistant(tool_calls) for c1, then the tool error — the
# buggy path produced [assistant, assistant, tool].
assert [m["role"] for m in messages] == ["assistant", "tool"]
assistant_msgs = [
m for m in messages
if m.get("role") == "assistant"
and any(tc["id"] == "c1" for tc in m.get("tool_calls", []))
]
assert len(assistant_msgs) == 1
tool_msg = messages[-1]
assert tool_msg["role"] == "tool"
assert tool_msg["tool_call_id"] == "c1"
assert "Error executing tool" in tool_msg["content"]
def test_partial_batch_failure_answers_every_tool_call(self):
"""One tool raises, others succeed: every assistant tool_call must
get a matching role:"tool" reply (OpenAI rejects unanswered ids)."""