@@ -183,30 +183,37 @@ async def _query_callers_async(
183183 """Async simple caller query (depth 1).
184184
185185 Supports class-level queries: for "MyClass", also matches callers of "MyClass.method".
186+ Also supports suffix matching for symbols stored with full module paths
187+ (e.g., "RecursiveReranker" matches "scripts.rerank_recursive.RecursiveReranker").
186188 """
187189 symbol_prefix = f"{ symbol } ."
190+ symbol_suffix = f".{ symbol } " # For matching full module paths like "module.ClassName"
188191 if repo and repo != "*" :
189192 query = """
190193 MATCH (caller:Symbol {collection: $collection})-[r:CALLS]->(callee:Symbol {collection: $collection})
191- WHERE (callee.name = $symbol OR callee.name STARTS WITH $symbol_prefix)
194+ WHERE (callee.name = $symbol
195+ OR callee.name STARTS WITH $symbol_prefix
196+ OR callee.name ENDS WITH $symbol_suffix)
192197 AND r.collection = $collection AND (r.repo = $repo OR callee.repo = $repo)
193198 RETURN caller.name as symbol, r.caller_path as path,
194199 r.start_line as start_line, r.end_line as end_line,
195200 r.language as language, callee.repo as repo
196201 LIMIT $limit
197202 """
198- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
203+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
199204 else :
200205 query = """
201206 MATCH (caller:Symbol {collection: $collection})-[r:CALLS]->(callee:Symbol {collection: $collection})
202- WHERE (callee.name = $symbol OR callee.name STARTS WITH $symbol_prefix)
207+ WHERE (callee.name = $symbol
208+ OR callee.name STARTS WITH $symbol_prefix
209+ OR callee.name ENDS WITH $symbol_suffix)
203210 AND r.collection = $collection
204211 RETURN caller.name as symbol, r.caller_path as path,
205212 r.start_line as start_line, r.end_line as end_line,
206213 r.language as language, callee.repo as repo
207214 LIMIT $limit
208215 """
209- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
216+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
210217
211218 return await backend .run_query_async (query , params )
212219
@@ -221,30 +228,36 @@ async def _query_callees_async(
221228 """Async simple callee query (depth 1).
222229
223230 Supports class-level queries: for "MyClass", also matches callees of "MyClass.method".
231+ Also supports suffix matching for symbols stored with full module paths.
224232 """
225233 symbol_prefix = f"{ symbol } ."
234+ symbol_suffix = f".{ symbol } " # For matching full module paths
226235 if repo and repo != "*" :
227236 query = """
228237 MATCH (caller:Symbol {collection: $collection})-[r:CALLS]->(callee:Symbol {collection: $collection})
229- WHERE (caller.name = $symbol OR caller.name STARTS WITH $symbol_prefix)
238+ WHERE (caller.name = $symbol
239+ OR caller.name STARTS WITH $symbol_prefix
240+ OR caller.name ENDS WITH $symbol_suffix)
230241 AND r.collection = $collection AND (r.repo = $repo OR caller.repo = $repo)
231242 RETURN callee.name as symbol, r.caller_path as path,
232243 r.start_line as start_line, r.end_line as end_line,
233244 r.language as language, caller.repo as repo
234245 LIMIT $limit
235246 """
236- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
247+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
237248 else :
238249 query = """
239250 MATCH (caller:Symbol {collection: $collection})-[r:CALLS]->(callee:Symbol {collection: $collection})
240- WHERE (caller.name = $symbol OR caller.name STARTS WITH $symbol_prefix)
251+ WHERE (caller.name = $symbol
252+ OR caller.name STARTS WITH $symbol_prefix
253+ OR caller.name ENDS WITH $symbol_suffix)
241254 AND r.collection = $collection
242255 RETURN callee.name as symbol, r.caller_path as path,
243256 r.start_line as start_line, r.end_line as end_line,
244257 r.language as language, caller.repo as repo
245258 LIMIT $limit
246259 """
247- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
260+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
248261
249262 return await backend .run_query_async (query , params )
250263
@@ -261,15 +274,17 @@ async def _query_transitive_callers_async(
261274 """Async multi-hop caller traversal.
262275
263276 Supports class-level queries: for "MyClass", also matches callers of "MyClass.method".
277+ Also supports suffix matching for symbols stored with full module paths.
264278 """
265279 safe_depth = max (1 , min (10 , int (depth )))
266280 symbol_prefix = f"{ symbol } ."
281+ symbol_suffix = f".{ symbol } " # For matching full module paths
267282
268283 if include_paths :
269284 if repo and repo != "*" :
270285 query = f"""
271286 MATCH path = (caller:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(target:Symbol {{collection: $collection}})
272- WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix)
287+ WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix OR target.name ENDS WITH $symbol_suffix )
273288 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
274289 WITH caller, path, length(path) as hop
275290 RETURN caller.name as symbol, hop,
@@ -278,11 +293,11 @@ async def _query_transitive_callers_async(
278293 ORDER BY hop
279294 LIMIT $limit
280295 """
281- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
296+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
282297 else :
283298 query = f"""
284299 MATCH path = (caller:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(target:Symbol {{collection: $collection}})
285- WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix)
300+ WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix OR target.name ENDS WITH $symbol_suffix )
286301 AND all(r IN relationships(path) WHERE r.collection = $collection)
287302 WITH caller, path, length(path) as hop
288303 RETURN caller.name as symbol, hop,
@@ -291,28 +306,28 @@ async def _query_transitive_callers_async(
291306 ORDER BY hop
292307 LIMIT $limit
293308 """
294- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
309+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
295310 else :
296311 if repo and repo != "*" :
297312 query = f"""
298313 MATCH path = (caller:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(target:Symbol {{collection: $collection}})
299- WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix)
314+ WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix OR target.name ENDS WITH $symbol_suffix )
300315 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
301316 WITH DISTINCT caller
302317 RETURN caller.name as symbol, caller.repo as repo
303318 LIMIT $limit
304319 """
305- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
320+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
306321 else :
307322 query = f"""
308323 MATCH path = (caller:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(target:Symbol {{collection: $collection}})
309- WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix)
324+ WHERE (target.name = $symbol OR target.name STARTS WITH $symbol_prefix OR target.name ENDS WITH $symbol_suffix )
310325 AND all(r IN relationships(path) WHERE r.collection = $collection)
311326 WITH DISTINCT caller
312327 RETURN caller.name as symbol, caller.repo as repo
313328 LIMIT $limit
314329 """
315- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
330+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
316331
317332 return await backend .run_query_async (query , params )
318333
@@ -329,15 +344,17 @@ async def _query_transitive_callees_async(
329344 """Async multi-hop callee traversal.
330345
331346 Supports class-level queries: for "MyClass", also matches callees of "MyClass.method".
347+ Also supports suffix matching for symbols stored with full module paths.
332348 """
333349 safe_depth = max (1 , min (10 , int (depth )))
334350 symbol_prefix = f"{ symbol } ."
351+ symbol_suffix = f".{ symbol } " # For matching full module paths
335352
336353 if include_paths :
337354 if repo and repo != "*" :
338355 query = f"""
339356 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(callee:Symbol {{collection: $collection}})
340- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
357+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
341358 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
342359 WITH callee, path, length(path) as hop
343360 RETURN callee.name as symbol, hop,
@@ -346,11 +363,11 @@ async def _query_transitive_callees_async(
346363 ORDER BY hop
347364 LIMIT $limit
348365 """
349- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
366+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
350367 else :
351368 query = f"""
352369 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(callee:Symbol {{collection: $collection}})
353- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
370+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
354371 AND all(r IN relationships(path) WHERE r.collection = $collection)
355372 WITH callee, path, length(path) as hop
356373 RETURN callee.name as symbol, hop,
@@ -359,28 +376,28 @@ async def _query_transitive_callees_async(
359376 ORDER BY hop
360377 LIMIT $limit
361378 """
362- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
379+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
363380 else :
364381 if repo and repo != "*" :
365382 query = f"""
366383 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(callee:Symbol {{collection: $collection}})
367- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
384+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
368385 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
369386 WITH DISTINCT callee
370387 RETURN callee.name as symbol, callee.repo as repo
371388 LIMIT $limit
372389 """
373- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
390+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
374391 else :
375392 query = f"""
376393 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS*1..{ safe_depth } ]->(callee:Symbol {{collection: $collection}})
377- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
394+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
378395 AND all(r IN relationships(path) WHERE r.collection = $collection)
379396 WITH DISTINCT callee
380397 RETURN callee.name as symbol, callee.repo as repo
381398 LIMIT $limit
382399 """
383- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
400+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
384401
385402 return await backend .run_query_async (query , params )
386403
@@ -397,31 +414,33 @@ async def _query_dependencies_async(
397414 """Async query both calls and imports for full dependency analysis.
398415
399416 Supports class-level queries: for "MyClass", also matches dependencies of "MyClass.method".
417+ Also supports suffix matching for symbols stored with full module paths.
400418 """
401419 safe_depth = max (1 , min (10 , int (depth )))
402420 symbol_prefix = f"{ symbol } ."
421+ symbol_suffix = f".{ symbol } " # For matching full module paths
403422 _ = include_paths # Reserved for future use
404423
405424 if repo and repo != "*" :
406425 query = f"""
407426 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS|IMPORTS*1..{ safe_depth } ]->(dep:Symbol {{collection: $collection}})
408- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
427+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
409428 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
410429 WITH DISTINCT dep
411430 RETURN dep.name as symbol, dep.repo as repo
412431 LIMIT $limit
413432 """
414- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
433+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
415434 else :
416435 query = f"""
417436 MATCH path = (source:Symbol {{collection: $collection}})-[:CALLS|IMPORTS*1..{ safe_depth } ]->(dep:Symbol {{collection: $collection}})
418- WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix)
437+ WHERE (source.name = $symbol OR source.name STARTS WITH $symbol_prefix OR source.name ENDS WITH $symbol_suffix )
419438 AND all(r IN relationships(path) WHERE r.collection = $collection)
420439 WITH DISTINCT dep
421440 RETURN dep.name as symbol, dep.repo as repo
422441 LIMIT $limit
423442 """
424- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
443+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
425444
426445 return await backend .run_query_async (query , params )
427446
@@ -436,12 +455,14 @@ async def _query_cycles_async(
436455 """Async detect circular dependencies involving the symbol.
437456
438457 Supports class-level queries: for "MyClass", also detects cycles involving "MyClass.method".
458+ Also supports suffix matching for symbols stored with full module paths.
439459 """
440460 symbol_prefix = f"{ symbol } ."
461+ symbol_suffix = f".{ symbol } " # For matching full module paths
441462 if repo and repo != "*" :
442463 query = """
443464 MATCH path = (s:Symbol {collection: $collection})-[:CALLS*2..10]->(s)
444- WHERE (s.name = $symbol OR s.name STARTS WITH $symbol_prefix)
465+ WHERE (s.name = $symbol OR s.name STARTS WITH $symbol_prefix OR s.name ENDS WITH $symbol_suffix )
445466 AND all(r IN relationships(path) WHERE r.collection = $collection AND r.repo = $repo)
446467 WITH s, path, length(path) as cycle_length
447468 RETURN [n in nodes(path) | n.name] as cycle_path,
@@ -450,11 +471,11 @@ async def _query_cycles_async(
450471 ORDER BY cycle_length
451472 LIMIT $limit
452473 """
453- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "repo" : repo , "collection" : collection , "limit" : limit }
474+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " repo" : repo , "collection" : collection , "limit" : limit }
454475 else :
455476 query = """
456477 MATCH path = (s:Symbol {collection: $collection})-[:CALLS*2..10]->(s)
457- WHERE (s.name = $symbol OR s.name STARTS WITH $symbol_prefix)
478+ WHERE (s.name = $symbol OR s.name STARTS WITH $symbol_prefix OR s.name ENDS WITH $symbol_suffix )
458479 AND all(r IN relationships(path) WHERE r.collection = $collection)
459480 WITH s, path, length(path) as cycle_length
460481 RETURN [n in nodes(path) | n.name] as cycle_path,
@@ -463,7 +484,7 @@ async def _query_cycles_async(
463484 ORDER BY cycle_length
464485 LIMIT $limit
465486 """
466- params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "collection" : collection , "limit" : limit }
487+ params = {"symbol" : symbol , "symbol_prefix" : symbol_prefix , "symbol_suffix" : symbol_suffix , " collection" : collection , "limit" : limit }
467488
468489 return await backend .run_query_async (query , params )
469490
0 commit comments