test: trim #90322 regression to one invariant, drop the hint-splitting workaround
The credentials test no longer has to strip trailing text before json.loads; the new file keeps the single behaviour contract (truncated output round-trips through json.loads and carries the next offset) — the existing TestSearchHints cases already cover offset arithmetic.
This commit is contained in:
@@ -150,7 +150,7 @@ def test_search_tool_filters_credential_results(fake_home, tmp_path, monkeypatch
|
||||
path=str(fake_home),
|
||||
task_id="search-filter-credentials",
|
||||
)
|
||||
out = json.loads(search_response.split("\n\n[Hint:", 1)[0])
|
||||
out = json.loads(search_response)
|
||||
raw = json.dumps(out)
|
||||
returned_paths = {
|
||||
match["path"] for match in out.get("matches", [])
|
||||
|
||||
@@ -1,64 +1,27 @@
|
||||
"""Regression tests for search_files truncation output staying pure JSON (#90322).
|
||||
"""search_files output is one JSON document even when truncated (#90322).
|
||||
|
||||
The truncated-results hint used to be appended as plain text after the
|
||||
serialized JSON payload (``{...}\\n\\n[Hint: ...]``), so the tool result was
|
||||
no longer parseable JSON — downstream tool-message handling on providers
|
||||
strict about tool-content formatting could reject or mishandle it. The hint
|
||||
now rides inside the payload as a structured ``_hint`` field, matching the
|
||||
existing ``_omitted``/``_warning`` side-channel convention in the same
|
||||
function.
|
||||
The pagination hint used to be appended as text after the serialized payload,
|
||||
so json.loads on the tool result failed (execute_code RPC, strict tool-message
|
||||
providers). It now rides inside the payload as ``_hint``.
|
||||
"""
|
||||
|
||||
import json
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
class _FakeSearchResult:
|
||||
"""Minimal stand-in for FileOperations.search return value."""
|
||||
|
||||
def __init__(self, truncated=False):
|
||||
self.matches = []
|
||||
self._truncated = truncated
|
||||
class _TruncatedSearch:
|
||||
matches = []
|
||||
|
||||
def to_dict(self, densify=False):
|
||||
payload = {"matches": [{"file": "test.py", "line": 1, "text": "match"}]}
|
||||
if self._truncated:
|
||||
payload["truncated"] = True
|
||||
payload["total_count"] = 20
|
||||
return payload
|
||||
return {"matches": [{"file": "t.py", "line": 1, "text": "m"}], "truncated": True, "total_count": 20}
|
||||
|
||||
|
||||
def _make_fake_file_ops(truncated):
|
||||
def test_truncated_search_result_round_trips_json():
|
||||
fake = MagicMock()
|
||||
fake.search = lambda **kw: _FakeSearchResult(truncated=truncated)
|
||||
return fake
|
||||
|
||||
|
||||
class TestSearchTruncationStaysJson:
|
||||
@patch("tools.file_tools._get_file_ops", return_value=_make_fake_file_ops(True))
|
||||
def test_truncated_result_is_parseable_json(self, _mock_ops):
|
||||
"""The whole tool output must round-trip through json.loads — no
|
||||
text appended after the serialized payload."""
|
||||
from tools.file_tools import search_tool
|
||||
|
||||
raw = search_tool("def main", offset=0, limit=20, task_id="t1")
|
||||
parsed = json.loads(raw) # raises on main: trailing "[Hint: ...]" text
|
||||
assert parsed["truncated"] is True
|
||||
|
||||
@patch("tools.file_tools._get_file_ops", return_value=_make_fake_file_ops(True))
|
||||
def test_truncation_hint_is_a_structured_field(self, _mock_ops):
|
||||
fake.search = lambda **kw: _TruncatedSearch()
|
||||
with patch("tools.file_tools._get_file_ops", return_value=fake):
|
||||
from tools.file_tools import search_tool
|
||||
|
||||
parsed = json.loads(search_tool("def main", offset=0, limit=20, task_id="t1"))
|
||||
assert "_hint" in parsed
|
||||
assert "offset=20" in parsed["_hint"]
|
||||
|
||||
@patch("tools.file_tools._get_file_ops", return_value=_make_fake_file_ops(False))
|
||||
def test_untruncated_result_has_no_hint(self, _mock_ops):
|
||||
from tools.file_tools import search_tool
|
||||
|
||||
parsed = json.loads(search_tool("def main", task_id="t1"))
|
||||
assert "truncated" not in parsed
|
||||
assert "_hint" not in parsed
|
||||
assert parsed["truncated"] is True
|
||||
assert "offset=20" in parsed["_hint"]
|
||||
|
||||
Reference in New Issue
Block a user