Skip to content

Commit bbb15e7

Browse files
committed
do this elsewhere
1 parent 1c6e951 commit bbb15e7

3 files changed

Lines changed: 50 additions & 198 deletions

File tree

codeflash/api/aiservice.py

Lines changed: 28 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
import concurrent.futures
43
import json
54
import os
65
import platform
@@ -92,7 +91,7 @@ def make_ai_service_request(
9291
return response
9392

9493
def _get_valid_candidates(
95-
self, optimizations_json: list[dict[str, Any]], source: OptimizedCandidateSource, model: str | None = None
94+
self, optimizations_json: list[dict[str, Any]], source: OptimizedCandidateSource
9695
) -> list[OptimizedCandidate]:
9796
candidates: list[OptimizedCandidate] = []
9897
for opt in optimizations_json:
@@ -106,7 +105,7 @@ def _get_valid_candidates(
106105
optimization_id=opt["optimization_id"],
107106
source=source,
108107
parent_id=opt.get("parent_id", None),
109-
model=model,
108+
model=opt.get("model"),
110109
)
111110
)
112111
return candidates
@@ -119,8 +118,6 @@ def optimize_python_code( # noqa: D417
119118
experiment_metadata: ExperimentMetadata | None = None,
120119
*,
121120
is_async: bool = False,
122-
model: str | None = None,
123-
call_sequence: int | None = None,
124121
) -> list[OptimizedCandidate]:
125122
"""Optimize the given python code for performance by making a request to the Django endpoint.
126123
@@ -130,14 +127,15 @@ def optimize_python_code( # noqa: D417
130127
- dependency_code (str): The dependency code used as read-only context for the optimization
131128
- trace_id (str): Trace id of optimization run
132129
- experiment_metadata (Optional[ExperimentalMetadata, None]): Any available experiment metadata for this optimization
133-
- model (str | None): Model name to use ("gpt-4.1" or "claude-sonnet-4-5"). Default is None (server default).
134-
- call_sequence (int | None): Sequence number for multi-model calls (1, 2, 3...). Default is None.
130+
- is_async (bool): Whether the function being optimized is async
135131
136132
Returns
137133
-------
138134
- List[OptimizationCandidate]: A list of Optimization Candidates.
139135
140136
"""
137+
logger.info("Generating optimized candidates…")
138+
console.rule()
141139
start_time = time.perf_counter()
142140
git_repo_owner, git_repo_name = safe_get_repo_owner_and_name()
143141

@@ -152,30 +150,32 @@ def optimize_python_code( # noqa: D417
152150
"repo_owner": git_repo_owner,
153151
"repo_name": git_repo_name,
154152
"is_async": is_async,
155-
"model": model,
156-
"call_sequence": call_sequence,
153+
"lsp_mode": is_LSP_enabled(),
157154
}
158-
logger.debug(f"Sending optimize request: model={model}, trace_id={trace_id}, call_sequence={call_sequence}")
155+
logger.debug(f"Sending optimize request: trace_id={trace_id}, lsp_mode={payload['lsp_mode']}")
159156

160157
try:
161-
response = self.make_ai_service_request("/optimize", payload=payload, timeout=60)
158+
response = self.make_ai_service_request("/optimize", payload=payload, timeout=120)
162159
except requests.exceptions.RequestException as e:
163160
logger.exception(f"Error generating optimized candidates: {e}")
164161
ph("cli-optimize-error-caught", {"error": str(e)})
162+
console.rule()
165163
return []
166164

167165
if response.status_code == 200:
168166
optimizations_json = response.json()["optimizations"]
169167
end_time = time.perf_counter()
170168
logger.debug(f"!lsp|Generating possible optimizations took {end_time - start_time:.2f} seconds.")
171-
logger.debug(f"Backend returned {len(optimizations_json)} optimization(s)")
172-
return self._get_valid_candidates(optimizations_json, OptimizedCandidateSource.OPTIMIZE, model=model)
169+
logger.info(f"!lsp|Received {len(optimizations_json)} optimization candidates.")
170+
console.rule()
171+
return self._get_valid_candidates(optimizations_json, OptimizedCandidateSource.OPTIMIZE)
173172
try:
174173
error = response.json()["error"]
175174
except Exception:
176175
error = response.text
177176
logger.error(f"Error generating optimized candidates: {response.status_code} - {error}")
178177
ph("cli-optimize-error-response", {"response_status_code": response.status_code, "error": error})
178+
console.rule()
179179
return []
180180

181181
def optimize_python_code_line_profiler( # noqa: D417
@@ -185,25 +185,29 @@ def optimize_python_code_line_profiler( # noqa: D417
185185
trace_id: str,
186186
line_profiler_results: str,
187187
experiment_metadata: ExperimentMetadata | None = None,
188-
model: str | None = None,
189-
call_sequence: int | None = None,
190188
) -> list[OptimizedCandidate]:
191-
"""Optimize the given python code for performance by making a request to the Django endpoint.
189+
"""Optimize the given python code for performance using line profiler results.
192190
193191
Parameters
194192
----------
195193
- source_code (str): The python code to optimize.
196194
- dependency_code (str): The dependency code used as read-only context for the optimization
197195
- trace_id (str): Trace id of optimization run
196+
- line_profiler_results (str): Line profiler output to guide optimization
198197
- experiment_metadata (Optional[ExperimentalMetadata, None]): Any available experiment metadata for this optimization
199-
- model (str | None): Model name to use ("gpt-4.1" or "claude-sonnet-4-5"). Default is None (server default).
200-
- call_sequence (int | None): Sequence number for multi-model calls (1, 2, 3...). Default is None.
201198
202199
Returns
203200
-------
204201
- List[OptimizationCandidate]: A list of Optimization Candidates.
205202
206203
"""
204+
if line_profiler_results == "":
205+
logger.info("No LineProfiler results were provided, Skipping optimization.")
206+
return []
207+
208+
logger.info("Generating optimized candidates with line profiler…")
209+
console.rule()
210+
207211
payload = {
208212
"source_code": source_code,
209213
"dependency_code": dependency_code,
@@ -213,130 +217,29 @@ def optimize_python_code_line_profiler( # noqa: D417
213217
"experiment_metadata": experiment_metadata,
214218
"codeflash_version": codeflash_version,
215219
"lsp_mode": is_LSP_enabled(),
216-
"model": model,
217-
"call_sequence": call_sequence,
218220
}
219221

220-
if line_profiler_results == "":
221-
logger.info("No LineProfiler results were provided, Skipping optimization.")
222-
return []
223222
try:
224-
response = self.make_ai_service_request("/optimize-line-profiler", payload=payload, timeout=60)
223+
response = self.make_ai_service_request("/optimize-line-profiler", payload=payload, timeout=120)
225224
except requests.exceptions.RequestException as e:
226225
logger.exception(f"Error generating optimized candidates: {e}")
227226
ph("cli-optimize-error-caught", {"error": str(e)})
227+
console.rule()
228228
return []
229229

230230
if response.status_code == 200:
231231
optimizations_json = response.json()["optimizations"]
232-
logger.debug(f"Backend returned {len(optimizations_json)} LP optimization(s)")
233-
return self._get_valid_candidates(optimizations_json, OptimizedCandidateSource.OPTIMIZE_LP, model=model)
232+
logger.info(f"!lsp|Received {len(optimizations_json)} line profiler optimization candidates.")
233+
console.rule()
234+
return self._get_valid_candidates(optimizations_json, OptimizedCandidateSource.OPTIMIZE_LP)
234235
try:
235236
error = response.json()["error"]
236237
except Exception:
237238
error = response.text
238239
logger.error(f"Error generating optimized candidates: {response.status_code} - {error}")
239240
ph("cli-optimize-error-response", {"response_status_code": response.status_code, "error": error})
240-
return []
241-
242-
def optimize_python_code_multi_model(
243-
self,
244-
source_code: str,
245-
dependency_code: str,
246-
base_trace_id: str,
247-
model_distribution: list[tuple[str, int]],
248-
executor: concurrent.futures.ThreadPoolExecutor,
249-
experiment_metadata: ExperimentMetadata | None = None,
250-
*,
251-
is_async: bool = False,
252-
sequence_offset: int = 0,
253-
) -> tuple[list[OptimizedCandidate], int]:
254-
"""Generate optimizations using multiple models in parallel."""
255-
logger.info("Generating optimized candidates…")
256-
console.rule()
257-
258-
futures: list[tuple[concurrent.futures.Future[list[OptimizedCandidate]], str]] = []
259-
260-
call_index = 0
261-
for model_name, num_calls in model_distribution:
262-
for _ in range(num_calls):
263-
call_trace_id = f"{base_trace_id[:-3]}0{call_index:02x}"
264-
call_sequence = sequence_offset + call_index + 1
265-
call_index += 1
266-
future = executor.submit(
267-
self.optimize_python_code,
268-
source_code,
269-
dependency_code,
270-
call_trace_id,
271-
experiment_metadata,
272-
is_async=is_async,
273-
model=model_name,
274-
call_sequence=call_sequence,
275-
)
276-
futures.append((future, model_name))
277-
278-
concurrent.futures.wait([f for f, _ in futures])
279-
280-
all_candidates: list[OptimizedCandidate] = []
281-
for future, model_name in futures:
282-
try:
283-
candidates = future.result()
284-
all_candidates.extend(candidates)
285-
except Exception as e:
286-
logger.warning(f"Model {model_name} call failed: {e}")
287-
continue
288-
289241
console.rule()
290-
return all_candidates, call_index
291-
292-
def optimize_python_code_line_profiler_multi_model(
293-
self,
294-
source_code: str,
295-
dependency_code: str,
296-
base_trace_id: str,
297-
line_profiler_results: str,
298-
model_distribution: list[tuple[str, int]],
299-
executor: concurrent.futures.ThreadPoolExecutor,
300-
experiment_metadata: ExperimentMetadata | None = None,
301-
sequence_offset: int = 0,
302-
) -> tuple[list[OptimizedCandidate], int]:
303-
"""Generate line profiler optimizations using multiple models in parallel."""
304-
logger.info("Generating optimized candidates with line profiler…")
305-
console.rule()
306-
307-
futures: list[tuple[concurrent.futures.Future[list[OptimizedCandidate]], str]] = []
308-
309-
call_index = 0
310-
for model_name, num_calls in model_distribution:
311-
for _ in range(num_calls):
312-
call_trace_id = f"{base_trace_id[:-3]}1{call_index:02x}"
313-
call_sequence = sequence_offset + call_index + 1
314-
call_index += 1
315-
future = executor.submit(
316-
self.optimize_python_code_line_profiler,
317-
source_code,
318-
dependency_code,
319-
call_trace_id,
320-
line_profiler_results,
321-
experiment_metadata,
322-
model_name,
323-
call_sequence,
324-
)
325-
futures.append((future, model_name))
326-
327-
concurrent.futures.wait([f for f, _ in futures])
328-
329-
all_candidates: list[OptimizedCandidate] = []
330-
for future, model_name in futures:
331-
try:
332-
candidates = future.result()
333-
all_candidates.extend(candidates)
334-
except Exception as e:
335-
logger.warning(f"Line profiler model {model_name} call failed: {e}")
336-
continue
337-
338-
console.rule()
339-
return all_candidates, call_index
242+
return []
340243

341244
def optimize_python_code_refinement(self, request: list[AIServiceRefinerRequest]) -> list[OptimizedCandidate]:
342245
"""Optimize the given python code for performance by making a request to the Django endpoint.

codeflash/code_utils/config_consts.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,20 +32,6 @@
3232
MAX_N_CANDIDATES = 5
3333
MAX_N_CANDIDATES_LP = 6
3434

35-
# Multi-model diversity configuration
36-
# Each tuple is (model_name, num_calls) where each call returns 1 candidate
37-
# Standard mode: 3 GPT-4.1 + 2 Claude Sonnet = 5 candidates
38-
MODEL_DISTRIBUTION: list[tuple[str, int]] = [("gpt-4.1", 3), ("claude-sonnet-4-5", 2)]
39-
40-
# LSP mode: fewer candidates for faster response
41-
MODEL_DISTRIBUTION_LSP: list[tuple[str, int]] = [("gpt-4.1", 2), ("claude-sonnet-4-5", 1)]
42-
43-
# Line profiler mode: 6 candidates total
44-
MODEL_DISTRIBUTION_LP: list[tuple[str, int]] = [("gpt-4.1", 4), ("claude-sonnet-4-5", 2)]
45-
46-
# Line profiler LSP mode
47-
MODEL_DISTRIBUTION_LP_LSP: list[tuple[str, int]] = [("gpt-4.1", 2), ("claude-sonnet-4-5", 1)]
48-
4935
try:
5036
from codeflash.lsp.helpers import is_LSP_enabled
5137

@@ -57,7 +43,5 @@
5743
N_CANDIDATES_LP_EFFECTIVE = min(N_CANDIDATES_LP_LSP if _IS_LSP_ENABLED else N_CANDIDATES_LP, MAX_N_CANDIDATES_LP)
5844
N_TESTS_TO_GENERATE_EFFECTIVE = N_TESTS_TO_GENERATE_LSP if _IS_LSP_ENABLED else N_TESTS_TO_GENERATE
5945
TOTAL_LOOPING_TIME_EFFECTIVE = TOTAL_LOOPING_TIME_LSP if _IS_LSP_ENABLED else TOTAL_LOOPING_TIME
60-
MODEL_DISTRIBUTION_EFFECTIVE = MODEL_DISTRIBUTION_LSP if _IS_LSP_ENABLED else MODEL_DISTRIBUTION
61-
MODEL_DISTRIBUTION_LP_EFFECTIVE = MODEL_DISTRIBUTION_LP_LSP if _IS_LSP_ENABLED else MODEL_DISTRIBUTION_LP
6246

6347
MAX_CONTEXT_LEN_REVIEW = 1000

0 commit comments

Comments
 (0)