1616with git clone enabled.
1717"""
1818
19- import asyncio
2019import logging
2120from typing import Optional
2221
2322from sqlalchemy .orm import Session
2423
2524from app .models .subtask import Subtask
2625from app .models .task import TaskResource
27- from app .schemas .kind import Task
2826from app .services .workspace_archive import archive_service
27+ from shared .models import ExecutionRequest
2928
3029logger = logging .getLogger (__name__ )
3130
@@ -74,17 +73,15 @@ async def recover(
7473 db : Session ,
7574 subtask : Subtask ,
7675 task : TaskResource ,
77- user_id : int ,
78- user_name : str ,
76+ request : ExecutionRequest ,
7977 ) -> bool :
8078 """Recover executor Pod for a task.
8179
8280 Args:
8381 db: Database session
8482 subtask: Subtask with executor_deleted_at=True
8583 task: Parent task
86- user_id: User ID
87- user_name: Username
84+ request: Execution request carrying the normal executor config
8885
8986 Returns:
9087 True if recovery successful, False otherwise
@@ -122,8 +119,7 @@ async def recover(
122119 db = db ,
123120 subtask = subtask ,
124121 task = task ,
125- user_id = user_id ,
126- user_name = user_name ,
122+ request = request ,
127123 )
128124 else :
129125 logger .info (
@@ -134,8 +130,7 @@ async def recover(
134130 db = db ,
135131 subtask = subtask ,
136132 task = task ,
137- user_id = user_id ,
138- user_name = user_name ,
133+ request = request ,
139134 )
140135
141136 except RuntimeError :
@@ -152,8 +147,7 @@ async def _recover_with_archive(
152147 db : Session ,
153148 subtask : Subtask ,
154149 task : TaskResource ,
155- user_id : int ,
156- user_name : str ,
150+ request : ExecutionRequest ,
157151 ) -> bool :
158152 """Recover Pod using workspace archive.
159153
@@ -165,33 +159,29 @@ async def _recover_with_archive(
165159 db: Database session
166160 subtask: Subtask
167161 task: Task
168- user_id: User ID
169- user_name: Username
162+ request: Execution request carrying the normal executor config
170163
171164 Returns:
172165 True if successful, False otherwise
173166 """
174167 task_id = task .id
175168
176169 try :
177- # Create Pod with skip_git_clone=true
178- sandbox , error = await self ._create_sandbox (
179- task = task ,
180- subtask = subtask ,
181- user_id = user_id ,
182- user_name = user_name ,
183- skip_git_clone = True ,
184- )
170+ request .skip_git_clone = True
171+ request .executor_name = None
172+ request .executor_namespace = None
185173
186- if error or not sandbox :
174+ executor , error = await self ._prepare_executor (request , True )
175+
176+ if error or not executor :
187177 logger .error (
188- f"[RecoveryService] Failed to create sandbox for task { task_id } : { error } "
178+ f"[RecoveryService] Failed to prepare executor for task { task_id } : { error } "
189179 )
190180 return False
191181
192- executor_name = sandbox .container_name
182+ executor_name = executor .container_name
193183 executor_namespace = self ._resolve_executor_namespace (
194- sandbox = sandbox ,
184+ sandbox = executor ,
195185 previous_namespace = subtask .executor_namespace ,
196186 )
197187
@@ -213,6 +203,8 @@ async def _recover_with_archive(
213203 subtask .executor_name = executor_name
214204 subtask .executor_namespace = executor_namespace
215205 subtask .executor_deleted_at = False
206+ request .executor_name = executor_name
207+ request .executor_namespace = executor_namespace
216208 db .add (subtask )
217209 db .commit ()
218210
@@ -235,8 +227,7 @@ async def _recover_without_archive(
235227 db : Session ,
236228 subtask : Subtask ,
237229 task : TaskResource ,
238- user_id : int ,
239- user_name : str ,
230+ request : ExecutionRequest ,
240231 ) -> bool :
241232 """Recover Pod with normal git clone (no archive).
242233
@@ -247,40 +238,38 @@ async def _recover_without_archive(
247238 db: Database session
248239 subtask: Subtask
249240 task: Task
250- user_id: User ID
251- user_name: Username
241+ request: Execution request carrying the normal executor config
252242
253243 Returns:
254244 True if successful, False otherwise
255245 """
256246 task_id = task .id
257247
258248 try :
259- # Create Pod normally
260- sandbox , error = await self ._create_sandbox (
261- task = task ,
262- subtask = subtask ,
263- user_id = user_id ,
264- user_name = user_name ,
265- skip_git_clone = False ,
266- )
249+ request .skip_git_clone = False
250+ request .executor_name = None
251+ request .executor_namespace = None
252+
253+ executor , error = await self ._prepare_executor (request , False )
267254
268- if error or not sandbox :
255+ if error or not executor :
269256 logger .error (
270- f"[RecoveryService] Failed to create sandbox for task { task_id } : { error } "
257+ f"[RecoveryService] Failed to prepare executor for task { task_id } : { error } "
271258 )
272259 return False
273260
274- executor_name = sandbox .container_name
261+ executor_name = executor .container_name
275262 executor_namespace = self ._resolve_executor_namespace (
276- sandbox = sandbox ,
263+ sandbox = executor ,
277264 previous_namespace = subtask .executor_namespace ,
278265 )
279266
280267 # Update subtask with new executor info and reset deleted flag
281268 subtask .executor_name = executor_name
282269 subtask .executor_namespace = executor_namespace
283270 subtask .executor_deleted_at = False
271+ request .executor_name = executor_name
272+ request .executor_namespace = executor_namespace
284273 db .add (subtask )
285274 db .commit ()
286275
@@ -298,62 +287,32 @@ async def _recover_without_archive(
298287 )
299288 return False
300289
301- async def _create_sandbox (
290+ async def _prepare_executor (
302291 self ,
303- task : TaskResource ,
304- subtask : Subtask ,
305- user_id : int ,
306- user_name : str ,
292+ request : ExecutionRequest ,
307293 skip_git_clone : bool ,
308294 ):
309- """Create a new sandbox Pod for the task .
295+ """Prepare a normal executor runtime without initial dispatch .
310296
311297 Args:
312- task: Task resource
313- subtask: Subtask
314- user_id: User ID
315- user_name: Username
298+ request: Execution request carrying the normal executor config
316299 skip_git_clone: Whether to skip git clone
317300
318301 Returns:
319- Tuple of (Sandbox , error_message)
302+ Tuple of (executor runtime , error_message)
320303 """
321- from app .services .execution import get_sandbox_manager
322-
323- task_crd = Task .model_validate (task .json )
324-
325- # Get shell type from subtask or task
326- shell_type = "ClaudeCode" # Default
304+ from app .services .execution import get_executor_runtime_client
327305
328- # Build bot_config from task
329- bot_config = {}
330-
331- # Build metadata
332- metadata = {
333- "task_id" : task .id ,
334- "subtask_id" : subtask .id ,
335- "skip_git_clone" : skip_git_clone ,
336- }
337- if subtask .executor_namespace :
338- metadata ["executor_namespace" ] = subtask .executor_namespace
339-
340- # Get workspace ref if available
341- workspace_ref = (
342- task_crd .spec .workspaceRef .name if task_crd .spec .workspaceRef else None
343- )
306+ runtime_client = get_executor_runtime_client ()
307+ request .skip_git_clone = skip_git_clone
308+ request .executor_name = None
309+ request .executor_namespace = None
344310
345- # Create sandbox
346- sandbox_manager = get_sandbox_manager ()
347- sandbox , error = await sandbox_manager .create_sandbox (
348- shell_type = shell_type ,
349- user_id = user_id ,
350- user_name = user_name ,
351- workspace_ref = workspace_ref ,
352- bot_config = bot_config ,
353- metadata = metadata ,
311+ executor , error = await runtime_client .prepare_executor (
312+ request = request ,
354313 )
355314
356- return sandbox , error
315+ return executor , error
357316
358317
359318# Global service instance
0 commit comments