@@ -480,7 +480,8 @@ fn pack_impl(
480480 let snippet_limit = remaining. saturating_sub ( full_limit) ;
481481
482482 let mut full_budget = make_budget_like ( budget. target , full_limit) ;
483- let mut snippet_budget = make_budget_like ( budget. target , snippet_limit) ;
483+ let mut snippet_budget_limit = snippet_limit;
484+ let mut snippet_budget = make_budget_like ( budget. target , snippet_budget_limit) ;
484485
485486 let max_full_units = units_from_tokens ( config. content . max_full_tokens , budget. target ) ;
486487 let max_snippet_units =
@@ -555,6 +556,16 @@ fn pack_impl(
555556 }
556557 }
557558
559+ // If full-content pool went unused (e.g. files exceed max_full_tokens),
560+ // roll the unused budget into the snippet pool.
561+ if !full_budget. is_exhausted ( ) {
562+ let extra = full_budget. remaining ( ) ;
563+ if extra > 0 {
564+ snippet_budget_limit = snippet_budget_limit. saturating_add ( extra) ;
565+ snippet_budget = make_budget_like ( budget. target , snippet_budget_limit) ;
566+ }
567+ }
568+
558569 let total_remaining = remaining_candidates. len ( ) ;
559570 for ( idx, candidate) in remaining_candidates. into_iter ( ) . enumerate ( ) {
560571 if budget. is_exhausted ( ) || snippet_budget. is_exhausted ( ) {
@@ -571,7 +582,11 @@ fn pack_impl(
571582 per_file_limit = 1 ;
572583 }
573584 if max_snippet_units > 0 {
574- per_file_limit = per_file_limit. min ( max_snippet_units) ;
585+ let max_total = max_snippet_units. saturating_mul ( files_left) ;
586+ // Only enforce the per-file cap when the snippet pool is tight.
587+ if snippet_budget. remaining ( ) <= max_total {
588+ per_file_limit = per_file_limit. min ( max_snippet_units) ;
589+ }
575590 }
576591 let max_units = per_file_limit
577592 . min ( snippet_budget. remaining ( ) )
0 commit comments