Repository navigation
feat(search): return the code with semantic search hits - #1119
1 commit merged into
Conversation
semantic_search_nodes_tool takes include_source, expand_neighbors and max_source_lines. With include_source each hit carries its source lines; with expand_neighbors the top hits also carry their direct callers and callees with source. A shared line budget caps the response, and a stored path that resolves outside the repository is never read. Search ranks test code below production code unless the query asks about tests, so a short test stub no longer outranks the implementation. The installed instruction block points agents at the new options and still says not to change code from graph output alone. The previous block is kept in _legacy_instructions.py so upgrade and uninstall still recognise it. The README and docs/REPRODUCING.md publish the 2026-09-22 agent_baseline capture (median 6.65x across 18 questions on 6 repos). The 2026-05-25 impact_accuracy CSVs are removed; the 2026-08-02 captures replace them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
code-review-graph reviewOverall risk: 0.85 (CRITICAL) — 28 changed function(s)/class(es), 41 affected flow(s), 10 test gap(s) (5 with no tested caller found, 5 reached only through a caller) Risk-scored changes
Affected execution flows
Test gaps
Reached only through a callerNo test names these directly, but a tested caller reaches them along the call path shown. That is a path in the call graph, not a record of execution -- the caller's tests may never take this branch. Treat it as where to look, not as coverage: these count as gaps and are scored as untested.
Powered by code-review-graph — local-first analysis; no code leaves the CI runner. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved issues can return incorrect notebook snippets, lose neighbor results or trigger excessive lookups, and allow oversized source responses despite line limits.
6 open issues
Expose max_source_lines in the MCP signature · New Reconstruct notebook source before slicing snippets · New Enforce a shared character or token limit for snippets · New Preserve raw qualified names for edge lookups · New Stop neighbor expansion when the source budget is exhausted · New Expand top hits before lower-ranked hits consume the budget · New
What changed in this PR
This PR adds optional source snippets and caller/callee context to semantic search, helping agents explore code with fewer separate file reads.
Changes:
- Adds source extraction, shared line budgets, neighbor expansion, and regression tests.
- Downweights test code unless the query indicates test intent, including in the grep benchmark.
- Updates installed guidance, preserves legacy instruction recognition, and publishes benchmark captures and documentation.
| File | Description |
|---|---|
tests/test_tools.py |
Tests source snippets, neighbors, truncation, and minimal mode. |
tests/test_search.py |
Tests production-code ranking and test intent. |
README.zh-CN.md |
Publishes benchmark results and retrieval-cost caveats in Chinese. |
README.md |
Publishes benchmark results and explains source-inclusive search. |
README.ko-KR.md |
Updates Korean benchmark documentation. |
README.ja-JP.md |
Updates Japanese benchmark documentation. |
README.hi-IN.md |
Updates Hindi benchmark documentation. |
evaluate/results/httpx_impact_accuracy_2026-05-25.csv |
Removes the superseded HTTPX capture. |
evaluate/results/httpx_agent_baseline_2026-09-22.csv |
Adds HTTPX agent-baseline results. |
evaluate/results/gin_impact_accuracy_2026-05-25.csv |
Removes the superseded Gin capture. |
evaluate/results/gin_agent_baseline_2026-09-22.csv |
Adds Gin agent-baseline results. |
evaluate/results/flask_impact_accuracy_2026-05-25.csv |
Removes the superseded Flask capture. |
evaluate/results/flask_agent_baseline_2026-09-22.csv |
Adds Flask agent-baseline results. |
evaluate/results/fastapi_impact_accuracy_2026-05-25.csv |
Removes the superseded FastAPI capture. |
evaluate/results/fastapi_agent_baseline_2026-09-22.csv |
Adds FastAPI agent-baseline results. |
evaluate/results/express_impact_accuracy_2026-05-25.csv |
Removes the superseded Express capture. |
evaluate/results/express_agent_baseline_2026-09-22.csv |
Adds Express agent-baseline results. |
evaluate/results/code-review-graph_impact_accuracy_2026-05-25.csv |
Removes the superseded project capture. |
evaluate/results/code-review-graph_agent_baseline_2026-09-22.csv |
Adds project agent-baseline results. |
docs/REPRODUCING.md |
Documents the capture, reproduction command, and measurement limits. |
code_review_graph/tools/query.py |
Implements source snippets, line budgets, and neighbor expansion. |
code_review_graph/skills.py |
Updates installed exploration guidance. |
code_review_graph/search.py |
Applies test-code ranking penalties unless test intent is detected. |
code_review_graph/main.py |
Exposes source and neighbor options; shortens tool docstrings. |
code_review_graph/eval/benchmarks/agent_baseline.py |
Applies test-file downweighting to grep ranking. |
code_review_graph/_legacy_instructions.py |
Preserves previous blocks for upgrade and uninstall recognition. |
CHANGELOG.md |
Records search features, ranking changes, and benchmark publication. |
.beads/issues.jsonl |
Adds an issue-tracker export. |
Review effort: Balanced
| include_source: bool = False, | ||
| expand_neighbors: bool = False, |
| if span <= 0: | ||
| self.omitted += 1 | ||
| return False | ||
| snippet = lines[start - 1:start - 1 + span] |
| target["source"] = "\n".join(snippet) | ||
| target["source_lines"] = [start, start + len(snippet) - 1] | ||
| if end - start + 1 > len(snippet): | ||
| target["source_truncated"] = True | ||
| self._left -= len(snippet) |
| stops the caller opening the same files by hand. | ||
| """ | ||
| for hit in results[:_MAX_EXPANDED_HITS]: | ||
| qname = hit.get("qualified_name") |
| if not other or other in seen or other == qname: | ||
| continue | ||
| seen.add(other) | ||
| node = store.get_node(other) |
| for hit in results: | ||
| budget.attach( | ||
| hit, hit.get("file_path"), | ||
| hit.get("line_start"), hit.get("line_end"), | ||
| ) | ||
| if expand_neighbors: | ||
| _attach_neighbors(results, store, budget) |
There was a problem hiding this comment.
🔵 Needs a closer look
Unresolved defects allow oversized source payloads and incorrect notebook snippets, suppress valid neighbors through budget exhaustion, and leave the advertised snippet limit unavailable to MCP clients.
6 open issues
Expand top hits before lower-ranked hits consume the budget Stop neighbor expansion when the source budget is exhausted Preserve raw qualified names for edge lookups Enforce a shared character or token limit for snippets Reconstruct notebook source before slicing snippets Expose max_source_lines in the MCP signature
Review effort: Balanced
…w of tirth8205#1119) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…05#1119) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # code_review_graph/main.py

What this does
semantic_search_nodes_toolcan return the code with the hits:include_source=Trueadds each hit's source,expand_neighbors=Truealso adds the direct callers and callees of the top hits.max_source_linescaps each snippet and one budget caps the whole reply. A stored path outside the repo is never read.kind="Test"or words like "test", "spec", "fixture", "mock")._legacy_instructions.pyso upgrade and uninstall still find it.docs/REPRODUCING.mdpublish the 2026-09-22agent_baselinecapture: median 6.65x across 18 questions on 6 repos. The 6 CSVs are added. The 2026-05-25impact_accuracyCSVs are removed; the 2026-08-02 captures replace them..beads/issues.jsonl.Known gap
include_sourceis ignored whendetail_level="minimal", and some platform skill texts tell agents to passminimaleverywhere. An agent that follows both gets locations only. This is documented in the tool docstring; a follow-up can decide which wins.Checks run locally
browserandupgrademarkers) in 6 shards with HOME and XDG dirs isolated: all green.🤖 Generated with Claude Code