Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 13 additions & 13 deletions src/agents/models/chatcmpl_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,19 +754,19 @@ def ensure_assistant_message() -> ChatCompletionAssistantMessageParam:
for c in all_output_content
if c.get("type") == "text"
]
if not tool_result_content:
message = (
"Chat Completions tool outputs cannot be empty or contain only "
"non-text content unless preserve_tool_output_all_content=True."
)
if strict_feature_validation:
raise UserError(message)
logger.warning(
"%s Replacing the tool output with a placeholder; enable strict "
"feature validation to raise an error instead.",
message,
)
tool_result_content = _OMITTED_TOOL_OUTPUT_PLACEHOLDER
if not tool_result_content:
message = (
"Chat Completions tool outputs cannot be empty or contain only "
"non-text content unless preserve_tool_output_all_content=True."
)
if strict_feature_validation:
raise UserError(message)
logger.warning(
"%s Replacing the tool output with a placeholder; enable strict "
"feature validation to raise an error instead.",
message,
)
tool_result_content = _OMITTED_TOOL_OUTPUT_PLACEHOLDER
msg: ChatCompletionToolMessageParam = {
"role": "tool",
"tool_call_id": func_output["call_id"],
Expand Down
33 changes: 33 additions & 0 deletions tests/models/test_openai_chatcompletions_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,39 @@ def test_items_to_messages_with_empty_function_output_raises_in_strict_mode():
Converter.items_to_messages([func_output_item], strict_feature_validation=True)


def test_items_to_messages_with_empty_string_function_output_uses_placeholder_by_default(
caplog: pytest.LogCaptureFixture,
):
"""Default conversion should not send an empty-string tool message."""
func_output_item: FunctionCallOutput = {
"type": "function_call_output",
"call_id": "somecall",
"output": "",
}

with caplog.at_level(logging.WARNING, logger="openai.agents"):
messages = Converter.items_to_messages([func_output_item])

assert len(messages) == 1
tool_msg = messages[0]
assert tool_msg["role"] == "tool"
assert tool_msg["tool_call_id"] == func_output_item["call_id"]
assert tool_msg["content"] == "[tool output omitted]"
assert "Replacing the tool output with a placeholder" in caplog.text


def test_items_to_messages_with_empty_string_function_output_raises_in_strict_mode():
"""Strict validation should fail explicitly instead of sending empty-string output."""
func_output_item: FunctionCallOutput = {
"type": "function_call_output",
"call_id": "somecall",
"output": "",
}

with pytest.raises(UserError, match="cannot be empty or contain only non-text content"):
Converter.items_to_messages([func_output_item], strict_feature_validation=True)


def test_items_to_messages_with_mixed_function_output_keeps_text_by_default(
caplog: pytest.LogCaptureFixture,
):
Expand Down