Files
odysseus/tests/test_web_search_raw_json_tool_call.py
2026-06-15 15:19:38 +09:00

72 lines
2.3 KiB
Python

"""Local text models can leak web_search calls as prose plus bare JSON.
gpt-oss-20b sometimes writes:
Need to do web_search for ...
{"query":"...", "time_filter":"week"}
That is an intended tool call in non-native/textual tool mode, but older parsing
only recognized fenced blocks, [TOOL_CALL], XML invoke, and tool_code markup.
"""
import json
import sys
from unittest.mock import MagicMock
for mod in ['src.agent_tools', 'src.tool_parsing', 'src.tool_schemas', 'src.tool_execution']:
sys.modules.pop(mod, None)
for mod in [
'sqlalchemy', 'sqlalchemy.orm', 'sqlalchemy.ext', 'sqlalchemy.ext.declarative',
'sqlalchemy.ext.hybrid', 'sqlalchemy.sql', 'sqlalchemy.sql.expression',
'src.database', 'core.models', 'core.database', 'core.auth'
]:
if mod not in sys.modules:
sys.modules[mod] = MagicMock()
import src.agent_tools # noqa: E402, F401
from src.tool_parsing import parse_tool_blocks, strip_tool_blocks # noqa: E402
def test_raw_json_after_web_search_phrase_runs_as_web_search():
text = (
"Need to do web_search for best chocolate chip cookies. Use web_search function.\n\n"
'{"query":"best chocolate chip cookie recipe","time_filter":"week"}'
)
blocks = parse_tool_blocks(text)
assert len(blocks) == 1
assert blocks[0].tool_type == "web_search"
payload = json.loads(blocks[0].content)
assert payload == {
"query": "best chocolate chip cookie recipe",
"time_filter": "week",
}
def test_raw_json_without_web_tool_name_is_ignored():
text = 'Here is a saved search config:\n\n{"query":"private customer name"}'
assert parse_tool_blocks(text) == []
def test_raw_json_fallback_is_disabled_for_native_parser_gate():
text = (
"Need to do web_search for best chocolate chip cookies.\n\n"
'{"query":"best chocolate chip cookie recipe"}'
)
assert parse_tool_blocks(text, skip_fenced=True) == []
def test_strip_tool_blocks_removes_executed_raw_json():
text = (
"Need to do web_search for best chocolate chip cookies. Use web_search function.\n\n"
'{"query":"best chocolate chip cookie recipe","time_filter":"week"}'
)
cleaned = strip_tool_blocks(text)
assert '{"query"' not in cleaned
assert "best chocolate chip cookie recipe" not in cleaned
assert "Need to do web_search" in cleaned