@@ -247,25 +247,38 @@ pub async fn semantic_context_for_diff(
247247 embedding_adapter : Option < & dyn LLMAdapter > ,
248248 limit : usize ,
249249 min_similarity : f32 ,
250+ preferred_files : & [ PathBuf ] ,
250251) -> Vec < LLMContextChunk > {
251252 let query_texts = build_query_texts ( diff, file_content) ;
252253 if query_texts. is_empty ( ) {
253254 return Vec :: new ( ) ;
254255 }
255256
256257 let query_embeddings = embed_texts_with_fallback ( embedding_adapter, & query_texts) . await ;
257- let matches =
258- find_related_chunks_for_diff ( index, & query_embeddings, diff, limit, min_similarity) ;
258+ let matches = find_related_chunks_for_diff (
259+ index,
260+ & query_embeddings,
261+ diff,
262+ limit,
263+ min_similarity,
264+ preferred_files,
265+ ) ;
266+ let preferred_file_ranks = build_preferred_file_ranks ( preferred_files) ;
259267
260268 let mut seen = HashSet :: new ( ) ;
261269 let mut chunks = Vec :: new ( ) ;
262270 for semantic_match in matches {
263271 if !seen. insert ( semantic_match. chunk . key . clone ( ) ) {
264272 continue ;
265273 }
274+ let ranking_note = preferred_file_ranks
275+ . get ( & semantic_match. chunk . file_path )
276+ . map ( |rank| format ! ( ", graph-ranked file #{}" , rank + 1 ) )
277+ . unwrap_or_default ( ) ;
266278 let content = format ! (
267- "Semantic match (similarity {:.2})\n Symbol: {}\n Summary: {}\n Code:\n {}" ,
279+ "Semantic match (similarity {:.2}{} )\n Symbol: {}\n Summary: {}\n Code:\n {}" ,
268280 semantic_match. similarity,
281+ ranking_note,
269282 semantic_match. chunk. symbol_name,
270283 semantic_match. chunk. summary,
271284 semantic_match. chunk. code_excerpt,
@@ -323,8 +336,10 @@ fn find_related_chunks_for_diff(
323336 diff : & UnifiedDiff ,
324337 limit : usize ,
325338 min_similarity : f32 ,
339+ preferred_files : & [ PathBuf ] ,
326340) -> Vec < SemanticMatch > {
327341 let changed_ranges = changed_line_ranges ( diff) ;
342+ let preferred_file_ranks = build_preferred_file_ranks ( preferred_files) ;
328343 let mut best_matches: HashMap < String , SemanticMatch > = HashMap :: new ( ) ;
329344
330345 for query_embedding in query_embeddings {
@@ -351,11 +366,34 @@ fn find_related_chunks_for_diff(
351366 }
352367
353368 let mut matches = best_matches. into_values ( ) . collect :: < Vec < _ > > ( ) ;
354- matches. sort_by ( |a, b| b. similarity . total_cmp ( & a. similarity ) ) ;
369+ matches. sort_by ( |a, b| {
370+ let a_rank = preferred_file_ranks
371+ . get ( & a. chunk . file_path )
372+ . copied ( )
373+ . unwrap_or ( usize:: MAX ) ;
374+ let b_rank = preferred_file_ranks
375+ . get ( & b. chunk . file_path )
376+ . copied ( )
377+ . unwrap_or ( usize:: MAX ) ;
378+ a_rank
379+ . cmp ( & b_rank)
380+ . then_with ( || b. similarity . total_cmp ( & a. similarity ) )
381+ . then_with ( || a. chunk . key . cmp ( & b. chunk . key ) )
382+ } ) ;
355383 matches. truncate ( limit. max ( 1 ) ) ;
356384 matches
357385}
358386
387+ fn build_preferred_file_ranks ( preferred_files : & [ PathBuf ] ) -> HashMap < PathBuf , usize > {
388+ let mut preferred_file_ranks = HashMap :: new ( ) ;
389+ for ( rank, file_path) in preferred_files. iter ( ) . enumerate ( ) {
390+ preferred_file_ranks
391+ . entry ( file_path. clone ( ) )
392+ . or_insert ( rank) ;
393+ }
394+ preferred_file_ranks
395+ }
396+
359397pub fn find_similar_feedback_examples (
360398 store : & SemanticFeedbackStore ,
361399 query_embedding : & [ f32 ] ,
@@ -622,8 +660,76 @@ mod tests {
622660 } ] ,
623661 } ;
624662
625- let chunks = semantic_context_for_diff ( & index, & diff, None , None , 3 , 0.1 ) . await ;
663+ let chunks = semantic_context_for_diff ( & index, & diff, None , None , 3 , 0.1 , & [ ] ) . await ;
626664 assert_eq ! ( chunks. len( ) , 1 ) ;
627665 assert ! ( chunks[ 0 ] . content. contains( "Semantic match" ) ) ;
628666 }
667+
668+ #[ test]
669+ fn find_related_chunks_for_diff_prioritizes_graph_ranked_files ( ) {
670+ let mut index = SemanticIndex :: default ( ) ;
671+ index. entries . insert (
672+ "src/graph.rs:helper:1:5" . to_string ( ) ,
673+ SemanticChunk {
674+ key : "src/graph.rs:helper:1:5" . to_string ( ) ,
675+ file_path : PathBuf :: from ( "src/graph.rs" ) ,
676+ symbol_name : "graph_helper" . to_string ( ) ,
677+ line_range : ( 1 , 5 ) ,
678+ summary : "Graph-ranked helper" . to_string ( ) ,
679+ embedding_text : "graph-ranked helper" . to_string ( ) ,
680+ code_excerpt : "fn graph_helper() {}" . to_string ( ) ,
681+ embedding : vec ! [ 0.8 , 0.6 ] ,
682+ content_hash : "graph" . to_string ( ) ,
683+ } ,
684+ ) ;
685+ index. entries . insert (
686+ "src/other.rs:helper:1:5" . to_string ( ) ,
687+ SemanticChunk {
688+ key : "src/other.rs:helper:1:5" . to_string ( ) ,
689+ file_path : PathBuf :: from ( "src/other.rs" ) ,
690+ symbol_name : "other_helper" . to_string ( ) ,
691+ line_range : ( 1 , 5 ) ,
692+ summary : "Higher-similarity helper" . to_string ( ) ,
693+ embedding_text : "higher-similarity helper" . to_string ( ) ,
694+ code_excerpt : "fn other_helper() {}" . to_string ( ) ,
695+ embedding : vec ! [ 1.0 , 0.0 ] ,
696+ content_hash : "other" . to_string ( ) ,
697+ } ,
698+ ) ;
699+
700+ let diff = UnifiedDiff {
701+ old_content : None ,
702+ new_content : None ,
703+ file_path : PathBuf :: from ( "src/current.rs" ) ,
704+ is_new : false ,
705+ is_deleted : false ,
706+ is_binary : false ,
707+ hunks : vec ! [ DiffHunk {
708+ old_start: 1 ,
709+ old_lines: 0 ,
710+ new_start: 1 ,
711+ new_lines: 1 ,
712+ context: String :: new( ) ,
713+ changes: vec![ DiffLine {
714+ old_line_no: None ,
715+ new_line_no: Some ( 1 ) ,
716+ change_type: ChangeType :: Added ,
717+ content: "graph-aware semantic ranking" . to_string( ) ,
718+ } ] ,
719+ } ] ,
720+ } ;
721+
722+ let matches = find_related_chunks_for_diff (
723+ & index,
724+ & [ vec ! [ 1.0 , 0.0 ] ] ,
725+ & diff,
726+ 2 ,
727+ 0.1 ,
728+ & [ PathBuf :: from ( "src/graph.rs" ) ] ,
729+ ) ;
730+
731+ assert_eq ! ( matches. len( ) , 2 ) ;
732+ assert_eq ! ( matches[ 0 ] . chunk. file_path, PathBuf :: from( "src/graph.rs" ) ) ;
733+ assert_eq ! ( matches[ 1 ] . chunk. file_path, PathBuf :: from( "src/other.rs" ) ) ;
734+ }
629735}
0 commit comments