44import os
55import platform
66import time
7+ from itertools import count
78from typing import TYPE_CHECKING , Any , cast
89
910import requests
@@ -39,6 +40,11 @@ class AiServiceClient:
3940 def __init__ (self ) -> None :
4041 self .base_url = self .get_aiservice_base_url ()
4142 self .headers = {"Authorization" : f"Bearer { get_codeflash_api_key ()} " , "Connection" : "close" }
43+ self .llm_call_counter = count (1 )
44+
45+ def get_next_sequence (self ) -> int :
46+ """Get the next LLM call sequence number."""
47+ return next (self .llm_call_counter )
4248
4349 def get_aiservice_base_url (self ) -> str :
4450 if os .environ .get ("CODEFLASH_AIS_SERVER" , default = "prod" ).lower () == "local" :
@@ -105,6 +111,7 @@ def _get_valid_candidates(
105111 optimization_id = opt ["optimization_id" ],
106112 source = source ,
107113 parent_id = opt .get ("parent_id" , None ),
114+ model = opt .get ("model" ),
108115 )
109116 )
110117 return candidates
@@ -114,7 +121,6 @@ def optimize_python_code( # noqa: D417
114121 source_code : str ,
115122 dependency_code : str ,
116123 trace_id : str ,
117- num_candidates : int = 10 ,
118124 experiment_metadata : ExperimentMetadata | None = None ,
119125 * ,
120126 is_async : bool = False ,
@@ -126,21 +132,22 @@ def optimize_python_code( # noqa: D417
126132 - source_code (str): The python code to optimize.
127133 - dependency_code (str): The dependency code used as read-only context for the optimization
128134 - trace_id (str): Trace id of optimization run
129- - num_candidates (int): Number of optimization variants to generate. Default is 10.
130135 - experiment_metadata (Optional[ExperimentalMetadata, None]): Any available experiment metadata for this optimization
136+ - is_async (bool): Whether the function being optimized is async
131137
132138 Returns
133139 -------
134140 - List[OptimizationCandidate]: A list of Optimization Candidates.
135141
136142 """
143+ logger .info ("Generating optimized candidates…" )
144+ console .rule ()
137145 start_time = time .perf_counter ()
138146 git_repo_owner , git_repo_name = safe_get_repo_owner_and_name ()
139147
140148 payload = {
141149 "source_code" : source_code ,
142150 "dependency_code" : dependency_code ,
143- "n_candidates" : num_candidates ,
144151 "trace_id" : trace_id ,
145152 "python_version" : platform .python_version (),
146153 "experiment_metadata" : experiment_metadata ,
@@ -149,22 +156,25 @@ def optimize_python_code( # noqa: D417
149156 "repo_owner" : git_repo_owner ,
150157 "repo_name" : git_repo_name ,
151158 "is_async" : is_async ,
159+ "lsp_mode" : is_LSP_enabled (),
160+ "call_sequence" : self .get_next_sequence (),
152161 }
162+ logger .debug (f"Sending optimize request: trace_id={ trace_id } , lsp_mode={ payload ['lsp_mode' ]} " )
153163
154- logger .info ("!lsp|Generating optimized candidates…" )
155- console .rule ()
156164 try :
157165 response = self .make_ai_service_request ("/optimize" , payload = payload , timeout = 60 )
158166 except requests .exceptions .RequestException as e :
159167 logger .exception (f"Error generating optimized candidates: { e } " )
160168 ph ("cli-optimize-error-caught" , {"error" : str (e )})
169+ console .rule ()
161170 return []
162171
163172 if response .status_code == 200 :
164173 optimizations_json = response .json ()["optimizations" ]
165- console .rule ()
166174 end_time = time .perf_counter ()
167175 logger .debug (f"!lsp|Generating possible optimizations took { end_time - start_time :.2f} seconds." )
176+ logger .info (f"!lsp|Received { len (optimizations_json )} optimization candidates." )
177+ console .rule ()
168178 return self ._get_valid_candidates (optimizations_json , OptimizedCandidateSource .OPTIMIZE )
169179 try :
170180 error = response .json ()["error" ]
@@ -184,21 +194,28 @@ def optimize_python_code_line_profiler( # noqa: D417
184194 num_candidates : int = 8 ,
185195 experiment_metadata : ExperimentMetadata | None = None ,
186196 ) -> list [OptimizedCandidate ]:
187- """Optimize the given python code for performance by making a request to the Django endpoint .
197+ """Optimize the given python code for performance using line profiler results .
188198
189199 Parameters
190200 ----------
191201 - source_code (str): The python code to optimize.
192202 - dependency_code (str): The dependency code used as read-only context for the optimization
193203 - trace_id (str): Trace id of optimization run
194- - num_candidates (int ): Number of optimization variants to generate. Default is 10.
204+ - line_profiler_results (str ): Line profiler output to guide optimization
195205 - experiment_metadata (Optional[ExperimentalMetadata, None]): Any available experiment metadata for this optimization
196206
197207 Returns
198208 -------
199209 - List[OptimizationCandidate]: A list of Optimization Candidates.
200210
201211 """
212+ if line_profiler_results == "" :
213+ logger .info ("No LineProfiler results were provided, Skipping optimization." )
214+ return []
215+
216+ logger .info ("Generating optimized candidates with line profiler…" )
217+ console .rule ()
218+
202219 payload = {
203220 "source_code" : source_code ,
204221 "dependency_code" : dependency_code ,
@@ -209,25 +226,20 @@ def optimize_python_code_line_profiler( # noqa: D417
209226 "experiment_metadata" : experiment_metadata ,
210227 "codeflash_version" : codeflash_version ,
211228 "lsp_mode" : is_LSP_enabled (),
229+ "call_sequence" : self .get_next_sequence (),
212230 }
213231
214- console .rule ()
215- if line_profiler_results == "" :
216- logger .info ("No LineProfiler results were provided, Skipping optimization." )
217- console .rule ()
218- return []
219232 try :
220233 response = self .make_ai_service_request ("/optimize-line-profiler" , payload = payload , timeout = 60 )
221234 except requests .exceptions .RequestException as e :
222235 logger .exception (f"Error generating optimized candidates: { e } " )
223236 ph ("cli-optimize-error-caught" , {"error" : str (e )})
237+ console .rule ()
224238 return []
225239
226240 if response .status_code == 200 :
227241 optimizations_json = response .json ()["optimizations" ]
228- logger .info (
229- f"!lsp|Generated { len (optimizations_json )} candidate optimizations using line profiler information."
230- )
242+ logger .info (f"!lsp|Received { len (optimizations_json )} line profiler optimization candidates." )
231243 console .rule ()
232244 return self ._get_valid_candidates (optimizations_json , OptimizedCandidateSource .OPTIMIZE_LP )
233245 try :
@@ -265,6 +277,7 @@ def optimize_python_code_refinement(self, request: list[AIServiceRefinerRequest]
265277 "trace_id" : opt .trace_id ,
266278 "function_references" : opt .function_references ,
267279 "python_version" : platform .python_version (),
280+ "call_sequence" : self .get_next_sequence (),
268281 }
269282 for opt in request
270283 ]
@@ -399,6 +412,7 @@ def get_new_explanation( # noqa: D417
399412 "throughput_improvement" : throughput_improvement ,
400413 "function_references" : function_references ,
401414 "codeflash_version" : codeflash_version ,
415+ "call_sequence" : self .get_next_sequence (),
402416 }
403417 logger .info ("loading|Generating explanation" )
404418 console .rule ()
@@ -561,6 +575,7 @@ def generate_regression_tests( # noqa: D417
561575 "python_version" : platform .python_version (),
562576 "codeflash_version" : codeflash_version ,
563577 "is_async" : function_to_optimize .is_async ,
578+ "call_sequence" : self .get_next_sequence (),
564579 }
565580 try :
566581 response = self .make_ai_service_request ("/testgen" , payload = payload , timeout = 90 )
@@ -647,6 +662,7 @@ def get_optimization_review(
647662 "codeflash_version" : codeflash_version ,
648663 "calling_fn_details" : calling_fn_details ,
649664 "python_version" : platform .python_version (),
665+ "call_sequence" : self .get_next_sequence (),
650666 }
651667 console .rule ()
652668 try :
0 commit comments