diff --git a/src/fastcontext/agent/tool/grep.md b/src/fastcontext/agent/tool/grep.md index dd3f6e5..63bb408 100644 --- a/src/fastcontext/agent/tool/grep.md +++ b/src/fastcontext/agent/tool/grep.md @@ -6,5 +6,5 @@ Usage: - Output modes: "content" shows matching lines (default), "files_with_matches" shows only file paths, "count" shows match counts - Pattern syntax: Uses ripgrep (not grep) - literal braces need escaping (use interface\{\} to find interface{} in Go code) - Multiline matching: By default patterns match within single lines only. For cross-line patterns like struct \{[\s\S]*?field, use multiline: true -- Results are capped to several thousand output lines for responsiveness; when truncation occurs, the results report "at least" counts, but are otherwise accurate. +- Output is capped at the first 100 lines by default for responsiveness; raise or lower this with the head_limit parameter. When truncation occurs, the output ends with a "Results truncated to first N lines" note. - Content output formatting closely follows ripgrep output format: '-' for context lines, ':' for match lines, and all context/match lines below each file group. \ No newline at end of file diff --git a/tests/test_grep_doc_cap.py b/tests/test_grep_doc_cap.py new file mode 100644 index 0000000..d25dfea --- /dev/null +++ b/tests/test_grep_doc_cap.py @@ -0,0 +1,30 @@ +import asyncio +import json +import tempfile +from pathlib import Path + +from fastcontext.agent.tool.grep import GrepTool + + +def test_grep_doc_describes_real_cap(): + """The Grep description must describe the real 100-line cap and the + actual truncation note, not the fictional 'several thousand'/'at least' + behavior.""" + desc = GrepTool().description + assert "several thousand" not in desc + assert "at least" not in desc + assert "100" in desc + assert "head_limit" in desc + # The documented truncation wording must match what the tool actually emits. + assert "Results truncated to first" in desc + + +def test_grep_doc_matches_runtime_truncation(): + """Cross-check: the truncation note produced at runtime uses exactly the + phrasing the doc promises.""" + grep = GrepTool() + with tempfile.TemporaryDirectory() as cwd: + (Path(cwd) / "haystack.txt").write_text("\n".join("MATCH" for _ in range(150)), encoding="utf-8") + out = asyncio.run(grep.call(json.dumps({"pattern": "MATCH", "output_mode": "content"}), cwd=cwd)) + assert "Results truncated to first 100 lines" in out + assert "Results truncated to first" in GrepTool().description