weco 0.2.14__py3-none-any.whl → 0.2.16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- weco/__init__.py +1 -1
- weco/api.py +39 -56
- weco/cli.py +16 -23
- weco/panels.py +15 -10
- {weco-0.2.14.dist-info → weco-0.2.16.dist-info}/METADATA +6 -6
- weco-0.2.16.dist-info/RECORD +12 -0
- {weco-0.2.14.dist-info → weco-0.2.16.dist-info}/WHEEL +1 -1
- weco-0.2.14.dist-info/RECORD +0 -12
- {weco-0.2.14.dist-info → weco-0.2.16.dist-info}/entry_points.txt +0 -0
- {weco-0.2.14.dist-info → weco-0.2.16.dist-info}/licenses/LICENSE +0 -0
- {weco-0.2.14.dist-info → weco-0.2.16.dist-info}/top_level.txt +0 -0
weco/__init__.py
CHANGED
weco/api.py
CHANGED
|
@@ -28,33 +28,28 @@ def start_optimization_session(
|
|
|
28
28
|
) -> Dict[str, Any]:
|
|
29
29
|
"""Start the optimization session."""
|
|
30
30
|
with console.status("[bold green]Starting Optimization..."):
|
|
31
|
-
|
|
32
|
-
#
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"evaluator": evaluator_config,
|
|
43
|
-
"search_policy": search_policy_config,
|
|
44
|
-
},
|
|
45
|
-
"metadata": {"client_name": "cli", "client_version": __pkg_version__, **api_keys},
|
|
31
|
+
response = requests.post(
|
|
32
|
+
f"{__base_url__}/sessions", # Path is relative to base_url
|
|
33
|
+
json={
|
|
34
|
+
"source_code": source_code,
|
|
35
|
+
"additional_instructions": additional_instructions,
|
|
36
|
+
"objective": {"evaluation_command": evaluation_command, "metric_name": metric_name, "maximize": maximize},
|
|
37
|
+
"optimizer": {
|
|
38
|
+
"steps": steps,
|
|
39
|
+
"code_generator": code_generator_config,
|
|
40
|
+
"evaluator": evaluator_config,
|
|
41
|
+
"search_policy": search_policy_config,
|
|
46
42
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
"metadata": {"client_name": "cli", "client_version": __pkg_version__, **api_keys},
|
|
44
|
+
},
|
|
45
|
+
headers=auth_headers, # Add headers
|
|
46
|
+
timeout=timeout,
|
|
47
|
+
)
|
|
48
|
+
response.raise_for_status()
|
|
49
|
+
return response.json()
|
|
54
50
|
|
|
55
51
|
|
|
56
52
|
def evaluate_feedback_then_suggest_next_solution(
|
|
57
|
-
console: rich.console.Console,
|
|
58
53
|
session_id: str,
|
|
59
54
|
execution_output: str,
|
|
60
55
|
additional_instructions: str = None,
|
|
@@ -63,41 +58,29 @@ def evaluate_feedback_then_suggest_next_solution(
|
|
|
63
58
|
timeout: int = 800,
|
|
64
59
|
) -> Dict[str, Any]:
|
|
65
60
|
"""Evaluate the feedback and suggest the next solution."""
|
|
66
|
-
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
response.raise_for_status()
|
|
79
|
-
return response.json()
|
|
80
|
-
except requests.exceptions.HTTPError as e:
|
|
81
|
-
handle_api_error(e=e, console=console)
|
|
61
|
+
response = requests.post(
|
|
62
|
+
f"{__base_url__}/sessions/{session_id}/suggest", # Path is relative to base_url
|
|
63
|
+
json={
|
|
64
|
+
"execution_output": execution_output,
|
|
65
|
+
"additional_instructions": additional_instructions,
|
|
66
|
+
"metadata": {**api_keys},
|
|
67
|
+
},
|
|
68
|
+
headers=auth_headers, # Add headers
|
|
69
|
+
timeout=timeout,
|
|
70
|
+
)
|
|
71
|
+
response.raise_for_status()
|
|
72
|
+
return response.json()
|
|
82
73
|
|
|
83
74
|
|
|
84
75
|
def get_optimization_session_status(
|
|
85
|
-
|
|
86
|
-
session_id: str,
|
|
87
|
-
include_history: bool = False,
|
|
88
|
-
auth_headers: dict = {},
|
|
89
|
-
timeout: int = 800, # Add auth_headers
|
|
76
|
+
session_id: str, include_history: bool = False, auth_headers: dict = {}, timeout: int = 800
|
|
90
77
|
) -> Dict[str, Any]:
|
|
91
78
|
"""Get the current status of the optimization session."""
|
|
92
|
-
|
|
93
|
-
#
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
response.raise_for_status()
|
|
101
|
-
return response.json()
|
|
102
|
-
except requests.exceptions.HTTPError as e:
|
|
103
|
-
handle_api_error(e=e, console=console)
|
|
79
|
+
response = requests.get(
|
|
80
|
+
f"{__base_url__}/sessions/{session_id}", # Path is relative to base_url
|
|
81
|
+
params={"include_history": include_history},
|
|
82
|
+
headers=auth_headers,
|
|
83
|
+
timeout=timeout,
|
|
84
|
+
)
|
|
85
|
+
response.raise_for_status()
|
|
86
|
+
return response.json()
|
weco/cli.py
CHANGED
|
@@ -256,23 +256,20 @@ def main() -> None:
|
|
|
256
256
|
maximize = args.maximize == "true"
|
|
257
257
|
steps = args.steps
|
|
258
258
|
code_generator_config = {"model": args.model}
|
|
259
|
-
evaluator_config = {
|
|
260
|
-
"model": args.model,
|
|
261
|
-
"include_analysis": False, # NOTE: False for now
|
|
262
|
-
}
|
|
259
|
+
evaluator_config = {"model": args.model, "include_analysis": True}
|
|
263
260
|
search_policy_config = {
|
|
264
261
|
"num_drafts": max(1, math.ceil(0.15 * steps)),
|
|
265
262
|
"debug_prob": 0.5,
|
|
266
263
|
"max_debug_depth": max(1, math.ceil(0.1 * steps)),
|
|
267
264
|
}
|
|
265
|
+
# API request timeout
|
|
266
|
+
timeout = 800
|
|
268
267
|
# Read additional instructions
|
|
269
268
|
additional_instructions = read_additional_instructions(additional_instructions=args.additional_instructions)
|
|
270
269
|
# Read source code path
|
|
271
270
|
source_fp = pathlib.Path(args.source)
|
|
272
271
|
# Read source code content
|
|
273
272
|
source_code = read_from_path(fp=source_fp, is_json=False)
|
|
274
|
-
# API request timeout
|
|
275
|
-
timeout = 800
|
|
276
273
|
|
|
277
274
|
# --- Panel Initialization ---
|
|
278
275
|
summary_panel = SummaryPanel(
|
|
@@ -310,9 +307,8 @@ def main() -> None:
|
|
|
310
307
|
runs_dir = pathlib.Path(args.log_dir) / session_id
|
|
311
308
|
runs_dir.mkdir(parents=True, exist_ok=True)
|
|
312
309
|
|
|
313
|
-
#
|
|
314
|
-
|
|
315
|
-
write_to_path(fp=runs_copy_source_fp, content=source_code)
|
|
310
|
+
# Write the initial code string to the logs
|
|
311
|
+
write_to_path(fp=runs_dir / f"step_0{source_fp.suffix}", content=session_response["code"])
|
|
316
312
|
|
|
317
313
|
# Write the initial code string to the source file path (if not preserving)
|
|
318
314
|
if not args.preserve_source:
|
|
@@ -380,7 +376,8 @@ def main() -> None:
|
|
|
380
376
|
transition_delay=0.1,
|
|
381
377
|
)
|
|
382
378
|
|
|
383
|
-
|
|
379
|
+
# Starting from step 1 to steps (inclusive) because the baseline solution is step 0, so we want to optimize for steps worth of steps
|
|
380
|
+
for step in range(1, steps + 1):
|
|
384
381
|
# Re-read instructions from the original source (file path or string) BEFORE each suggest call
|
|
385
382
|
current_additional_instructions = read_additional_instructions(
|
|
386
383
|
additional_instructions=args.additional_instructions
|
|
@@ -388,7 +385,6 @@ def main() -> None:
|
|
|
388
385
|
|
|
389
386
|
# Send feedback and get next suggestion
|
|
390
387
|
eval_and_next_solution_response = evaluate_feedback_then_suggest_next_solution(
|
|
391
|
-
console=console,
|
|
392
388
|
session_id=session_id,
|
|
393
389
|
execution_output=term_out,
|
|
394
390
|
additional_instructions=current_additional_instructions, # Pass current instructions
|
|
@@ -408,11 +404,7 @@ def main() -> None:
|
|
|
408
404
|
# Get the optimization session status for
|
|
409
405
|
# the best solution, its score, and the history to plot the tree
|
|
410
406
|
status_response = get_optimization_session_status(
|
|
411
|
-
|
|
412
|
-
session_id=session_id,
|
|
413
|
-
include_history=True,
|
|
414
|
-
timeout=timeout,
|
|
415
|
-
auth_headers=auth_headers,
|
|
407
|
+
session_id=session_id, include_history=True, timeout=timeout, auth_headers=auth_headers
|
|
416
408
|
)
|
|
417
409
|
|
|
418
410
|
# Update the step of the progress bar
|
|
@@ -493,7 +485,6 @@ def main() -> None:
|
|
|
493
485
|
|
|
494
486
|
# Ensure we pass evaluation results for the last step's generated solution
|
|
495
487
|
eval_and_next_solution_response = evaluate_feedback_then_suggest_next_solution(
|
|
496
|
-
console=console,
|
|
497
488
|
session_id=session_id,
|
|
498
489
|
execution_output=term_out,
|
|
499
490
|
additional_instructions=current_additional_instructions,
|
|
@@ -510,7 +501,7 @@ def main() -> None:
|
|
|
510
501
|
# Get the optimization session status for
|
|
511
502
|
# the best solution, its score, and the history to plot the tree
|
|
512
503
|
status_response = get_optimization_session_status(
|
|
513
|
-
|
|
504
|
+
session_id=session_id, include_history=True, timeout=timeout, auth_headers=auth_headers
|
|
514
505
|
)
|
|
515
506
|
# Build the metric tree
|
|
516
507
|
tree_panel.build_metric_tree(nodes=status_response["history"])
|
|
@@ -553,9 +544,7 @@ def main() -> None:
|
|
|
553
544
|
best_solution_score = None
|
|
554
545
|
|
|
555
546
|
if best_solution_code is None or best_solution_score is None:
|
|
556
|
-
best_solution_content = (
|
|
557
|
-
f"# Weco could not find a better solution\n\n{read_from_path(fp=runs_copy_source_fp, is_json=False)}"
|
|
558
|
-
)
|
|
547
|
+
best_solution_content = f"# Weco could not find a better solution\n\n{read_from_path(fp=runs_dir / f'step_0{source_fp.suffix}', is_json=False)}"
|
|
559
548
|
else:
|
|
560
549
|
# Format score for the comment
|
|
561
550
|
best_score_str = (
|
|
@@ -577,7 +566,11 @@ def main() -> None:
|
|
|
577
566
|
console.print(end_optimization_layout)
|
|
578
567
|
|
|
579
568
|
except Exception as e:
|
|
580
|
-
|
|
569
|
+
try:
|
|
570
|
+
error_message = e.response.json()["detail"]
|
|
571
|
+
except Exception:
|
|
572
|
+
error_message = str(e)
|
|
573
|
+
console.print(Panel(f"[bold red]Error: {error_message}", title="[bold red]Error", border_style="red"))
|
|
581
574
|
# Print traceback for debugging
|
|
582
|
-
console.print_exception(show_locals=
|
|
575
|
+
# console.print_exception(show_locals=False)
|
|
583
576
|
sys.exit(1)
|
weco/panels.py
CHANGED
|
@@ -121,6 +121,7 @@ class Node:
|
|
|
121
121
|
self.metric = metric
|
|
122
122
|
self.is_buggy = is_buggy
|
|
123
123
|
self.evaluated = True
|
|
124
|
+
self.name = ""
|
|
124
125
|
|
|
125
126
|
|
|
126
127
|
class MetricTree:
|
|
@@ -181,16 +182,17 @@ class MetricTreePanel:
|
|
|
181
182
|
nodes.sort(key=lambda x: x["step"])
|
|
182
183
|
|
|
183
184
|
# Finally build the new tree
|
|
184
|
-
for node in nodes:
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
is_buggy=node["is_buggy"],
|
|
192
|
-
)
|
|
185
|
+
for i, node in enumerate(nodes):
|
|
186
|
+
node = Node(
|
|
187
|
+
id=node["solution_id"],
|
|
188
|
+
parent_id=node["parent_id"],
|
|
189
|
+
code=node["code"],
|
|
190
|
+
metric=node["metric_value"],
|
|
191
|
+
is_buggy=node["is_buggy"],
|
|
193
192
|
)
|
|
193
|
+
if i == 0:
|
|
194
|
+
node.name = "baseline"
|
|
195
|
+
self.metric_tree.add_node(node)
|
|
194
196
|
|
|
195
197
|
def set_unevaluated_node(self, node_id: str):
|
|
196
198
|
"""Set the unevaluated node."""
|
|
@@ -232,12 +234,15 @@ class MetricTreePanel:
|
|
|
232
234
|
style = None
|
|
233
235
|
text = f"{node.metric:.3f}"
|
|
234
236
|
|
|
237
|
+
# add the node name info
|
|
238
|
+
text = f"{node.name} {text}".strip()
|
|
239
|
+
|
|
235
240
|
s = f"[{f'{style} ' if style is not None else ''}{color}]● {text}"
|
|
236
241
|
subtree = tree.add(s)
|
|
237
242
|
for child in node.children:
|
|
238
243
|
append_rec(child, subtree)
|
|
239
244
|
|
|
240
|
-
tree = Tree("
|
|
245
|
+
tree = Tree("", hide_root=True)
|
|
241
246
|
for n in self.metric_tree.get_draft_nodes():
|
|
242
247
|
append_rec(n, tree)
|
|
243
248
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: weco
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.16
|
|
4
4
|
Summary: Documentation for `weco`, a CLI for using Weco AI's code optimizer.
|
|
5
5
|
Author-email: Weco AI Team <contact@weco.ai>
|
|
6
6
|
License: MIT
|
|
@@ -20,7 +20,7 @@ Requires-Dist: build; extra == "dev"
|
|
|
20
20
|
Requires-Dist: setuptools_scm; extra == "dev"
|
|
21
21
|
Dynamic: license-file
|
|
22
22
|
|
|
23
|
-
# Weco: The
|
|
23
|
+
# Weco: The AI Research Engineer
|
|
24
24
|
|
|
25
25
|
[](https://www.python.org)
|
|
26
26
|
[](https://badge.fury.io/py/weco)
|
|
@@ -30,11 +30,11 @@ Weco systematically optimizes your code, guided directly by your evaluation metr
|
|
|
30
30
|
|
|
31
31
|
Example applications include:
|
|
32
32
|
|
|
33
|
-
- **GPU Kernel Optimization**: Reimplement PyTorch functions using CUDA
|
|
33
|
+
- **GPU Kernel Optimization**: Reimplement PyTorch functions using CUDA or Triton optimizing for `latency`, `throughput`, or `memory_bandwidth`.
|
|
34
34
|
- **Model Development**: Tune feature transformations or architectures, optimizing for `validation_accuracy`, `AUC`, or `Sharpe Ratio`.
|
|
35
35
|
- **Prompt Engineering**: Refine prompts for LLMs, optimizing for `win_rate`, `relevance`, or `format_adherence`
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+

|
|
38
38
|
|
|
39
39
|
---
|
|
40
40
|
|
|
@@ -42,7 +42,7 @@ https://github.com/user-attachments/assets/cb724ef1-bff6-4757-b457-d3b2201ede81
|
|
|
42
42
|
|
|
43
43
|
The `weco` CLI leverages a tree search approach guided by Large Language Models (LLMs) to iteratively explore and refine your code. It automatically applies changes, runs your evaluation script, parses the results, and proposes further improvements based on the specified goal.
|
|
44
44
|
|
|
45
|
-
[image](https://github.com/user-attachments/assets/a6ed63fa-9c40-498e-aa98-a873e5786509)
|
|
45
|
+

|
|
46
46
|
|
|
47
47
|
---
|
|
48
48
|
|
|
@@ -101,7 +101,7 @@ This command starts the optimization process.
|
|
|
101
101
|
|
|
102
102
|
This basic example shows how to optimize a simple PyTorch function for speedup.
|
|
103
103
|
|
|
104
|
-
For more advanced examples, including
|
|
104
|
+
For more advanced examples, including [Triton](/examples/triton/README.md), [CUDA kernel optimization](/examples/cuda/README.md)**, and **[ML model optimization](/examples/spaceship-titanic/README.md)**, please see the `README.md` files within the corresponding subdirectories under the [`examples/`](./examples/) folder.
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
107
|
# Navigate to the example directory
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
weco/__init__.py,sha256=HyOG-766A8if3MM5YvAM6CMJobEib3oM54UAJMk9GFA,426
|
|
2
|
+
weco/api.py,sha256=0OU1hEhN7sbIZ1zj8TeeB0tMaxXk6n6qw82FmcdK0ec,3111
|
|
3
|
+
weco/auth.py,sha256=IPfiLthcNRkPyM8pWHTyDLvikw83sigacpY1PmeA03Y,2343
|
|
4
|
+
weco/cli.py,sha256=DPObmIes3tRAVswBGYOx5G_8zIjeIJFufOGnFt__XwE,28869
|
|
5
|
+
weco/panels.py,sha256=8DoTQC-epGpGjn-xDBcqelC5BKaX7JXnrJ97LInEbRU,13561
|
|
6
|
+
weco/utils.py,sha256=hhIebUPnetFMfNSFfcsKVw1TSpeu_Zw3rBPPnxDie0U,3911
|
|
7
|
+
weco-0.2.16.dist-info/licenses/LICENSE,sha256=p_GQqJBvuZgkLNboYKyH-5dhpTDlKs2wq2TVM55WrWE,1065
|
|
8
|
+
weco-0.2.16.dist-info/METADATA,sha256=CFe6w8pRnMh-zDuyebtqIOFfIuf6JEJFqgVdUPSTO6s,10749
|
|
9
|
+
weco-0.2.16.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
|
10
|
+
weco-0.2.16.dist-info/entry_points.txt,sha256=ixJ2uClALbCpBvnIR6BXMNck8SHAab8eVkM9pIUowcs,39
|
|
11
|
+
weco-0.2.16.dist-info/top_level.txt,sha256=F0N7v6e2zBSlsorFv-arAq2yDxQbzX3KVO8GxYhPUeE,5
|
|
12
|
+
weco-0.2.16.dist-info/RECORD,,
|
weco-0.2.14.dist-info/RECORD
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
weco/__init__.py,sha256=q4zeQ8CJq8NJyRcBMmST6zCzmK_HjNSFChrNBzJ9oks,426
|
|
2
|
-
weco/api.py,sha256=z2DCe0kQJaaBHo-Vml52GRc9nwQBnrKATXoY3UfPojw,3842
|
|
3
|
-
weco/auth.py,sha256=IPfiLthcNRkPyM8pWHTyDLvikw83sigacpY1PmeA03Y,2343
|
|
4
|
-
weco/cli.py,sha256=7pGJiyoBO7n6Xocwusx9iVqsaPj8OuPaJ1A2ks83Ekw,28961
|
|
5
|
-
weco/panels.py,sha256=gB4rZbCvqzewUCBcILvyyU4fnOQLwFgHCGmtn-ZlgSo,13385
|
|
6
|
-
weco/utils.py,sha256=hhIebUPnetFMfNSFfcsKVw1TSpeu_Zw3rBPPnxDie0U,3911
|
|
7
|
-
weco-0.2.14.dist-info/licenses/LICENSE,sha256=p_GQqJBvuZgkLNboYKyH-5dhpTDlKs2wq2TVM55WrWE,1065
|
|
8
|
-
weco-0.2.14.dist-info/METADATA,sha256=855avaVBC-wUyFDWIvITw0t4o_v4s90Us-t_3lQnPGw,10851
|
|
9
|
-
weco-0.2.14.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
|
|
10
|
-
weco-0.2.14.dist-info/entry_points.txt,sha256=ixJ2uClALbCpBvnIR6BXMNck8SHAab8eVkM9pIUowcs,39
|
|
11
|
-
weco-0.2.14.dist-info/top_level.txt,sha256=F0N7v6e2zBSlsorFv-arAq2yDxQbzX3KVO8GxYhPUeE,5
|
|
12
|
-
weco-0.2.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|