agent-zero/tests/test_response_tool_validation.py
Alessandro c6136da08b fix(response): keep completions on the tool path
Route native Responses output text through the normalized response-tool executor instead of ending the monologue directly. Preserve active goal overrides and Responses state cleanup, wait for complete native streams, and reject empty response payloads.
2026-07-25 00:44:56 +02:00

78 lines
1.8 KiB
Python

import sys
from pathlib import Path
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from helpers.errors import RepairableException
from tools.response import ResponseTool
@pytest.mark.asyncio
@pytest.mark.parametrize("args", [{"text": "ok"}, {"message": "ok"}])
async def test_response_tool_accepts_text_or_message(args) -> None:
tool = ResponseTool(None, "response", None, args, "", None)
response = await tool.execute()
assert response.message == "ok"
assert response.break_loop is True
@pytest.mark.asyncio
async def test_response_tool_uses_non_empty_legacy_message_fallback() -> None:
tool = ResponseTool(
None,
"response",
None,
{"text": "", "message": "legacy"},
"",
None,
)
response = await tool.execute()
assert response.message == "legacy"
assert response.break_loop is True
@pytest.mark.asyncio
@pytest.mark.parametrize(
"args",
[
{},
{"text": ""},
{"text": " "},
{"text": None},
{"message": "\n\t"},
],
)
async def test_response_tool_rejects_empty_arguments(args) -> None:
tool = ResponseTool(None, "response", None, args, "", None)
with pytest.raises(RepairableException, match="non-empty top-level"):
await tool.execute()
@pytest.mark.asyncio
async def test_response_tool_rejects_nested_response_args() -> None:
tool = ResponseTool(
None,
"response",
None,
{
"thoughts": [],
"headline": "Providing exact payload",
"tool_name": "response",
"tool_args": {"text": "nested"},
},
"",
None,
)
with pytest.raises(RepairableException, match="non-empty top-level"):
await tool.execute()