@@ -246,18 +246,34 @@ impl ScratchpadAbstract for FillInTheMiddleScratchpad {
246246 let ccx_locked = ccx. lock ( ) . await ;
247247 ccx_locked. postprocess_parameters . clone ( )
248248 } ;
249- let extra_context = retrieve_ast_based_extra_context (
250- self . global_context . clone ( ) ,
251- self . ast_service . clone ( ) ,
252- & self . t ,
253- & cpath,
254- & pos,
255- ( fim_line1, fim_line2) ,
256- pp_settings,
257- rag_tokens_n,
258- & mut self . context_used
259- ) . await ;
260- prompt = format ! ( "{extra_context}{prompt}" ) ;
249+
250+ // NOTE: why do we need this loop?
251+ // postprocess_context_files doesn't care about additional tokens after lines skip
252+ // in real world retrieve_ast_based_extra_context can produce context that doesn't fit in the budget
253+ // if so we need to reduce budget and retrieve context again
254+ let mut extra_content_collect_counter = 0 ;
255+ let mut content_tokens_budget = rag_tokens_n as i32 ;
256+ loop {
257+ let extra_context = retrieve_ast_based_extra_context (
258+ self . global_context . clone ( ) ,
259+ self . ast_service . clone ( ) ,
260+ & self . t ,
261+ & cpath,
262+ & pos,
263+ ( fim_line1, fim_line2) ,
264+ pp_settings. clone ( ) ,
265+ content_tokens_budget as usize ,
266+ & mut self . context_used
267+ ) . await ;
268+ let content_tokens_n = self . t . count_tokens ( & extra_context. as_str ( ) ) ?;
269+ if content_tokens_n <= content_tokens_budget || extra_content_collect_counter > 1 {
270+ prompt = format ! ( "{extra_context}{prompt}" ) ;
271+ break ;
272+ } else {
273+ content_tokens_budget -= content_tokens_n - content_tokens_budget;
274+ extra_content_collect_counter += 1 ;
275+ }
276+ }
261277 }
262278
263279 if DEBUG {
0 commit comments