Skip to content

Commit 045215f

Browse files
feat: implement ADKSessionWorker to execute isolated pipeline agent sessions for search tree node expansion and pre/post processing
1 parent 6d951b0 commit 045215f

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

MaxKernel/auto_search/worker.py

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
import logging
2+
import os
3+
from typing import Any, Dict, Optional
4+
5+
from auto_agent.agent import root_agent
6+
from auto_agent.agent_client.auto_agent_client import AutoAgentClient
7+
from auto_agent.subagents.pipeline_agent import AutonomousPipelineAgent
8+
from auto_search.graph import EvaluationResult, Node
9+
10+
logger = logging.getLogger(__name__)
11+
12+
13+
class ADKSessionWorker:
14+
async def expand_node(
15+
self,
16+
session_id: str,
17+
parent_node: Node,
18+
session_dir: str,
19+
strategy: Optional[str] = None,
20+
agent_config: Optional[Dict[str, Any]] = None,
21+
) -> Node:
22+
"""Expand an ADK session to get a new optimized kernel."""
23+
os.makedirs(session_dir, exist_ok=True)
24+
25+
# Prepare inputs files for the agent based on parent_node
26+
self._prepare_inputs(session_dir, parent_node)
27+
28+
# Run the agent and process results
29+
try:
30+
state = await self._run_agent(
31+
session_id=session_id,
32+
session_dir=session_dir,
33+
strategy=strategy,
34+
agent_config=agent_config,
35+
)
36+
return self._process_results(
37+
session_id=session_id,
38+
parent_node=parent_node,
39+
strategy=strategy,
40+
state=state,
41+
)
42+
except Exception as e:
43+
logger.exception(f"Session {session_id} failed: {e}")
44+
return Node(
45+
node_id=session_id,
46+
parent_id=parent_node.node_id,
47+
session_id=session_id,
48+
code="",
49+
plan="",
50+
depth=parent_node.depth + 1,
51+
strategy_applied=strategy,
52+
execution_status="FAIL",
53+
execution_error=str(e),
54+
evaluation=EvaluationResult(correct=False),
55+
)
56+
57+
def _prepare_inputs(self, session_dir: str, parent_node: Node) -> None:
58+
"""Writes the parent node code and plan to the session directory."""
59+
base_kernel_path = os.path.join(session_dir, "base_kernel.py")
60+
with open(base_kernel_path, "w") as f:
61+
f.write(parent_node.code)
62+
63+
optimized_kernel_path = os.path.join(session_dir, "optimized_kernel.py")
64+
with open(optimized_kernel_path, "w") as f:
65+
f.write(parent_node.code)
66+
67+
kernel_plan_path = None
68+
if parent_node.plan:
69+
kernel_plan_path = os.path.join(session_dir, "base_kernel_plan.md")
70+
with open(kernel_plan_path, "w") as f:
71+
f.write(parent_node.plan)
72+
73+
async def _run_agent(
74+
self,
75+
session_id: str,
76+
session_dir: str,
77+
strategy: Optional[str],
78+
agent_config: Optional[Dict[str, Any]] = None,
79+
) -> Dict[str, Any]:
80+
"""Sets up a custom AutonomousPipelineAgent and runs the client."""
81+
agent_config = agent_config or {}
82+
83+
custom_agent = AutonomousPipelineAgent(
84+
name="AutonomousPipelineAgent",
85+
plan_agent=root_agent.plan_agent,
86+
implement_agent=root_agent.implement_agent,
87+
validate_agent=root_agent.validate_agent,
88+
test_gen_agent=root_agent.test_gen_agent,
89+
test_run_agent=root_agent.test_run_agent,
90+
autotune_agent=root_agent.autotune_agent,
91+
profile_agent=root_agent.profile_agent,
92+
session_dir=session_dir,
93+
**agent_config,
94+
)
95+
96+
strategy_query = f"Focus on: {strategy}. " if strategy else ""
97+
query = (
98+
"Optimize the code for peak performance with pallas kernel. "
99+
f"{strategy_query}"
100+
"Base code is at base_kernel.py."
101+
)
102+
client = AutoAgentClient(
103+
user_id="orchestrator",
104+
session_id=session_id,
105+
query=query,
106+
agent=custom_agent,
107+
)
108+
await client.create_session()
109+
await client.run_async()
110+
return client.get_state()
111+
112+
def _process_results(
113+
self,
114+
session_id: str,
115+
parent_node: Node,
116+
strategy: Optional[str],
117+
state: Dict[str, Any],
118+
) -> Node:
119+
"""Reads optimized code/plan and extracts metrics to construct a new Node."""
120+
history = state.get("history", [])
121+
best_iter = state.get("best_iteration", -1)
122+
123+
best_run = {}
124+
if best_iter != -1:
125+
best_run = next(
126+
(run for run in history if run.get("iteration") == best_iter), {}
127+
)
128+
elif history:
129+
best_run = history[-1]
130+
131+
comp_status = best_run.get("compilation_status", {})
132+
compiled = comp_status.get("success", False)
133+
compilation_error = comp_status.get("message") if not compiled else None
134+
135+
test_status = best_run.get("test_status", {})
136+
correct = test_status.get("success", False)
137+
test_error = test_status.get("output") if not correct else None
138+
139+
latency_ms = best_run.get("latency_ms")
140+
profiling_summary = best_run.get("profiling_summary")
141+
142+
# Read optimized code if it exists
143+
opt_path = state.get("optimized_kernel_path")
144+
optimized_code = ""
145+
if opt_path and os.path.exists(opt_path):
146+
with open(opt_path, "r") as f:
147+
optimized_code = f.read()
148+
149+
# Read optimized plan if it exists
150+
plan_path = state.get("kernel_plan_path")
151+
optimized_plan = ""
152+
if plan_path and os.path.exists(plan_path):
153+
with open(plan_path, "r") as f:
154+
optimized_plan = f.read()
155+
156+
return Node(
157+
node_id=session_id,
158+
parent_id=parent_node.node_id,
159+
session_id=session_id,
160+
code=optimized_code,
161+
plan=optimized_plan,
162+
depth=parent_node.depth + 1,
163+
strategy_applied=strategy,
164+
execution_status="SUCCESS",
165+
evaluation=EvaluationResult(
166+
compiled=compiled,
167+
correct=correct,
168+
latency_ms=latency_ms,
169+
profiling_summary=profiling_summary,
170+
compilation_error=compilation_error,
171+
test_error=test_error,
172+
),
173+
)

0 commit comments

Comments
 (0)