Skip to content

feat(search): return the code with semantic search hits - #1119

Merged
1 commit merged into
stagingfrom
feat/search-include-source
Nov 6, 2026
Merged

1 commit merged into
stagingfrom
feat/search-include-source

Conversation

@tirth8205

Copy link
Copy Markdown
Owner

What this does

  • semantic_search_nodes_tool can return the code with the hits: include_source=True adds each hit's source, expand_neighbors=True also adds the direct callers and callees of the top hits. max_source_lines caps each snippet and one budget caps the whole reply. A stored path outside the repo is never read.
  • Search puts test code below real code unless the query asks about tests (kind="Test" or words like "test", "spec", "fixture", "mock").
  • The installed instruction block points agents at the new options. It still says not to change code from graph output alone. The old block is kept in _legacy_instructions.py so upgrade and uninstall still find it.
  • README (all 5 languages) and docs/REPRODUCING.md publish the 2026-09-22 agent_baseline capture: median 6.65x across 18 questions on 6 repos. The 6 CSVs are added. The 2026-05-25 impact_accuracy CSVs are removed; the 2026-08-02 captures replace them.
  • Adds .beads/issues.jsonl.

Known gap

include_source is ignored when detail_level="minimal", and some platform skill texts tell agents to pass minimal everywhere. 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

  • ruff and mypy clean.
  • Full suite (excluding browser and upgrade markers) in 6 shards with HOME and XDG dirs isolated: all green.

🤖 Generated with Claude Code

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>
@github-actions

Copy link
Copy Markdown

code-review-graph review

Overall 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

Risk Level Symbol Location Tested
0.85 critical code_review_graph/tools/query.py::_SourceBudget.attach code_review_graph/tools/query.py:1164 indirect
0.80 high code_review_graph/tools/query.py::_SourceBudget code_review_graph/tools/query.py:1128 indirect
0.80 high code_review_graph/tools/query.py::_SourceBudget._lines code_review_graph/tools/query.py:1144 indirect
0.75 high code_review_graph/tools/query.py::semantic_search_nodes code_review_graph/tools/query.py:1249 yes
0.55 medium code_review_graph/main.py::detect_changes_tool code_review_graph/main.py:913 yes
0.55 medium code_review_graph/search.py::hybrid_search code_review_graph/search.py:878 yes
0.55 medium code_review_graph/tools/query.py::_neighbor_entry code_review_graph/tools/query.py:1191 indirect
0.55 medium code_review_graph/tools/query.py::_attach_neighbors code_review_graph/tools/query.py:1202 indirect
0.50 medium code_review_graph/tools/query.py::_SourceBudget.__init__ code_review_graph/tools/query.py:1136 yes
0.40 medium code_review_graph/main.py::run_postprocess_tool code_review_graph/main.py:305 no

Affected execution flows

  • build_or_update_graph_tool — criticality 0.73, 619 node(s) across 24 file(s)
  • refactor_tool — criticality 0.72, 159 node(s) across 12 file(s)
  • main — criticality 0.72, 925 node(s) across 40 file(s)
  • run_token_benchmark — criticality 0.70, 45 node(s) across 5 file(s)
  • semantic_search_nodes_tool — criticality 0.70, 103 node(s) across 13 file(s)
  • ...and 36 more affected flow(s)

Test gaps

  • code_review_graph/main.py::build_or_update_graph_tool (code_review_graph/main.py:249)
  • code_review_graph/main.py::run_postprocess_tool (code_review_graph/main.py:305)
  • code_review_graph/main.py::semantic_search_nodes_tool (code_review_graph/main.py:522)
  • code_review_graph/main.py::embed_graph_tool (code_review_graph/main.py:574)
  • code_review_graph/main.py::generate_wiki_tool (code_review_graph/main.py:1051)

Reached only through a caller

No 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.

  • code_review_graph/tools/query.py::_SourceBudget (code_review_graph/tools/query.py:1128) — via code_review_graph/tools/query.py::semantic_search_nodes, 1 hop(s)
  • code_review_graph/tools/query.py::_SourceBudget._lines (code_review_graph/tools/query.py:1144) — via code_review_graph/tools/query.py::semantic_search_nodes, 2 hop(s)
  • code_review_graph/tools/query.py::_SourceBudget.attach (code_review_graph/tools/query.py:1164) — via code_review_graph/tools/query.py::semantic_search_nodes, 1 hop(s)
  • code_review_graph/tools/query.py::_neighbor_entry (code_review_graph/tools/query.py:1191) — via code_review_graph/tools/query.py::semantic_search_nodes, 2 hop(s)
  • code_review_graph/tools/query.py::_attach_neighbors (code_review_graph/tools/query.py:1202) — via code_review_graph/tools/query.py::semantic_search_nodes, 1 hop(s)

Powered by code-review-graph — local-first analysis; no code leaves the CI runner.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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
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

Comment thread code_review_graph/main.py
Comment on lines +530 to +531
include_source: bool = False,
expand_neighbors: bool = False,
if span <= 0:
self.omitted += 1
return False
snippet = lines[start - 1:start - 1 + span]
Comment on lines +1183 to +1187
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)
Comment on lines +1312 to +1318
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)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 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

Review effort: Balanced

@tirth8205 tirth8205 closed this pull request by merging all changes into staging in 0160eb0 Nov 6, 2026
gowrishacv pushed a commit to gowrishacv/code-review-graph that referenced this pull request Nov 6, 2026
…w of tirth8205#1119)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gowrishacv pushed a commit to gowrishacv/code-review-graph that referenced this pull request Nov 6, 2026
…05#1119)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gowrishacv pushed a commit to gowrishacv/code-review-graph that referenced this pull request Nov 6, 2026
# Conflicts:
#	code_review_graph/main.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants