boost exact-match seeds and stop hubs hijacking query output - #638
Closed
ReverendJack3000 wants to merge 1 commit into
Closed
boost exact-match seeds and stop hubs hijacking query output#638ReverendJack3000 wants to merge 1 commit into
ReverendJack3000 wants to merge 1 commit into
Conversation
Single-token queries against an identifier (e.g. `graphify query "pasteFromClipboard"`) used to surface high-degree hub modules like `app.js` first because two issues compound: 1. _score_nodes only used substring matching, so the function and every sibling that mentioned it tied at score 1; ties broke alphabetically on node id. 2. _subgraph_to_text always re-sorted the rendered nodes by G.degree(n) desc, so even when the right seed reached the BFS, the hub it expanded into rendered first. Fix: - Add EXACT_MATCH_BONUS in _score_nodes when a query term equals norm_label or norm_label without trailing parens (the AST extractor emits function labels as `foo()`). - Give _subgraph_to_text an optional `seeds` arg; seeds render first in the supplied order, the rest fall back to degree desc. seeds=None matches the legacy ordering, so other call sites are untouched. - Plumb seeds through _tool_query_graph (MCP) and the `query` CLI handler. Six new tests cover the bonus, the trailing-parens strip, the seed renders-first invariant, the legacy back-compat path, and the full score -> bfs -> render pipeline. Full suite (447 tests) green.
safishamsi
added a commit
that referenced
this pull request
May 1, 2026
Collaborator
|
The requested changes have been implemented in 3fdae8f. Added |
matzls
pushed a commit
to matzls/graphify
that referenced
this pull request
May 10, 2026
…bs#638 Graphify-Labs#589 Graphify-Labs#586 Graphify-Labs#593: kimi thinking, manifest, inline comments, query boost, cache race, markdownify, content hash Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
_score_nodesgets anEXACT_MATCH_BONUSfor terms that equal a node'snorm_label(ornorm_labelwith trailing()stripped, since the AST extractor emits function labels asfoo()), and_subgraph_to_textaccepts an optionalseedsarg so the rendered output emits seeds first in score order before the BFS expansion sorted by degree desc.Why
Single-token identifier queries — by far the most common usage — get buried under high-degree hub modules. Two issues compound:
_score_nodesonly used substring matching, so the seed function and every sibling that mentioned the symbol tied at score 1; ties broke alphabetically on node id._subgraph_to_textalways re-sorted the rendered nodes byG.degree(n)descending, so even when_score_nodesreturned the right seed, the hub it expanded into (e.g.app.js,controller.js) always rendered first.Before
pasteFromClipboard()does not appear in the first 30 NODE lines on a ~6k-node graph.After
Scope of behavior change
seeds=Nonein_subgraph_to_textpreserves the previous degree-desc ordering exactly. The only call sites updated to passseeds=are_tool_query_graph(MCP) and thequeryCLI handler in__main__.py._tool_shortest_pathand thepathCLI use_score_nodesonly for endpoint resolution and do not render via_subgraph_to_text, so they automatically benefit from the bonus without further changes.term == norm_labelexactly. Substring scoring is untouched.EXACT_MATCH_BONUS = 100.0swamps any plausible substring sum (substring score caps at ~1.5/term).Tests
Six new cases in
tests/test_serve.py:test_score_nodes_exact_match_beats_substring— exact match outranks substring distractors on the same graph.test_score_nodes_exact_match_strips_function_parens—saveDiagram()matches termsavediagram.test_score_nodes_exact_match_no_false_positive— unrelated term still returns no matches.test_subgraph_to_text_seeds_render_first— seed before hub whenseeds=[...].test_subgraph_to_text_no_seeds_preserves_legacy_order—seeds=Nonematches no-arg call (back-compat guard) and hub still wins on degree.test_query_pipeline_exact_match_ranks_above_hub— end-to-end_score_nodes -> _bfs -> _subgraph_to_text(seeds=...).Full suite (447 tests) green.