Skip to content

Surface grep_search file-name matching + matchedByName flag (#375)#16

Open
rodion-m wants to merge 1 commit intomainfrom
fix/grep-matched-by-name-375
Open

Surface grep_search file-name matching + matchedByName flag (#375)#16
rodion-m wants to merge 1 commit intomainfrom
fix/grep-matched-by-name-375

Conversation

@rodion-m
Copy link
Copy Markdown
Member

Summary

Pairs with CodeAlive-AI/backend#376. The backend's grep_search now also matches file names/paths for literal queries and flags name-only hits with matchedByName: true. This MCP-side change surfaces that signal to LLM agents — previously the transformer dropped the field entirely, so the new behaviour would have reached the API but not any MCP consumer.

Changes

  • response_transformer.transform_grep_response forwards matchedByName into the MCP dict output, only when the backend set it (mirrors System.Text.Json's WhenWritingNull wire semantics so content-match responses stay byte-identical to the pre-change shape).
  • grep_search tool docstring updated:
    • description mentions literal file-name matching
    • explains the Form.xml use case (issue #375)
    • documents the matchedByName contract: empty matches, location points at line 1 as a file-level reference, must not be interpreted as a content match
    • flags the Phase 1 limitation that regex=true still only searches content
  • README.md one-line summary of grep_search extended accordingly.
  • New test test_grep_forwards_matched_by_name_flag asserts name-only hits surface the flag and content hits do not.

Test plan

  • 17/17 response_transformer tests pass (16 pre-existing + 1 new)
  • 249/249 full MCP unit suite passes
  • Smoke-test after rebuild: connect any MCP client (Claude Code, Cursor), invoke grep_search("Form.xml") against the BITERP workspace, verify the new tool description renders and that name-only hits carry matchedByName: true

🤖 Generated with Claude Code

Pairs with CodeAlive-AI/backend#376. The backend's grep_search now also
matches file names/paths for literal queries and flags name-only hits
with matchedByName=true (omitted when null via global JsonIgnoreCondition
on the .NET side). Previously the MCP layer dropped matchedByName
entirely in transform_grep_response, so the new signal never reached
LLM agents even though the backend emitted it.

Changes:
- response_transformer.transform_grep_response now forwards
  matchedByName into the MCP dict output, only when the backend set it
  (mirrors the backend's omit-on-null wire semantics so content-match
  responses stay byte-identical to the pre-change shape).
- grep_search tool docstring updated: mentions literal file-name
  matching, explains the Form.xml use case, documents the matchedByName
  contract (empty matches, location points at line 1 as a file-level
  reference — do NOT interpret it as a content match), and flags the
  Phase 1 limitation that regex=true still only searches content.
- README.md one-line summary of grep_search extended accordingly.
- Unit test test_grep_forwards_matched_by_name_flag asserts name-only
  hits surface the flag and content hits do not.

Tests: 17/17 response_transformer tests pass (16 pre-existing + 1 new).
Full MCP unit suite: 249 passed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request enhances the grep_search tool by adding support for literal file-name and path matching alongside existing content searches. The changes include updates to the tool's documentation, the response transformer to handle a new matchedByName flag, and a new test case to verify this behavior. A review comment points out a discrepancy in the grep_search docstring, suggesting that it should refer to startLine instead of location.line to accurately reflect the field names in the transformed output.

Comment thread src/tools/search.py
Comment on lines +297 to +298
`matches` is empty and `location.line` defaults to 1 as a
file-level reference — do NOT interpret `location.line` as an
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The docstring refers to location.line, but the transform_grep_response function (via _build_result_dict) flattens the nested backend structure into startLine and endLine in the final output. To avoid confusing LLM agents that rely on this documentation to parse the tool response, the docstring should use the actual field names present in the transformed JSON.

Suggested change
`matches` is empty and `location.line` defaults to 1 as a
file-level referencedo NOT interpret `location.line` as an
`matches` is empty and `startLine` defaults to 1 as a
file-level referencedo NOT interpret `startLine` as an

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.

1 participant