11from __future__ import annotations
22
33import logging
4- import uuid
54from typing import TYPE_CHECKING
65
76from django .conf import settings as django_settings
87from django .utils import timezone
98
109from langchain .agents import create_agent
1110from langchain .agents .middleware import ModelRequest , dynamic_prompt
12- from langchain .tools import ToolRuntime
1311from langchain_anthropic .middleware .prompt_caching import AnthropicPromptCachingMiddleware
1412from langchain_core .prompts import ChatPromptTemplate , MessagesPlaceholder
15- from langchain_core .runnables import Runnable , RunnableConfig
13+ from langchain_core .runnables import Runnable
1614from langgraph .checkpoint .postgres .aio import AsyncPostgresSaver
1715from langgraph .config import get_stream_writer
1816from langgraph .constants import START
2321from automation .agents import BaseAgent
2422from automation .agents .middleware import InjectImagesMiddleware
2523from automation .agents .plan_and_execute import PlanAndExecuteAgent
26- from automation .agents .tools .sandbox import bash_tool
24+ from automation .agents .tools .sandbox import _run_bash_commands
2725from automation .agents .tools .toolkits import FileNavigationToolkit , MergeRequestToolkit , WebSearchToolkit
2826from automation .utils import has_file_changes
2927from codebase .context import RuntimeCtx
3028from core .constants import BOT_NAME
29+ from core .sandbox .client import DAIVSandboxClient
30+ from core .sandbox .schemas import StartSessionRequest
3131
3232from .conf import settings
3333from .prompts import respond_reviewer_system , review_comment_system , review_human
@@ -110,7 +110,7 @@ async def compile(self) -> CompiledStateGraph:
110110 Compile the workflow for the agent.
111111
112112 Returns:
113- CompiledStateGraph: The compiled workflow .
113+ CompiledStateGraph: The compiled state graph .
114114 """
115115 workflow = StateGraph (OverallState , input_schema = ReviewInState , context_schema = RuntimeCtx )
116116
@@ -165,7 +165,7 @@ async def evaluate_review_comments(self, state: ReplyReviewerState) -> dict:
165165 state (ReviewState): The state of the agent.
166166
167167 Returns:
168- dict: The next step in the workflow .
168+ dict: The result of the evaluate review comments .
169169 """
170170 review_comment_evaluator = await ReviewCommentEvaluator .get_runnable ()
171171 response = await review_comment_evaluator .ainvoke ({"messages" : state ["review_context" ].notes })
@@ -181,6 +181,12 @@ async def collect_evaluations(self, state: OverallState) -> dict:
181181
182182 This deferred node waits for all parallel assessment tasks to complete
183183 and collects the classified reviews into to_reply and to_plan_and_execute lists.
184+
185+ Args:
186+ state (OverallState): The state of the agent.
187+
188+ Returns:
189+ dict: The result of the collect evaluations.
184190 """
185191 # Just pass through - the state reducers will have collected everything
186192 return {}
@@ -191,6 +197,12 @@ async def route_to_processors(self, state: OverallState) -> list[Send]:
191197
192198 - to_reply reviews are sent to reply_reviewer in parallel (one Send per review)
193199 - to_plan_and_execute reviews are sent as a batch to sequential_processor
200+
201+ Args:
202+ state (OverallState): The state of the agent.
203+
204+ Returns:
205+ list[Send]: The sends to the processors.
194206 """
195207 sends = []
196208
@@ -210,6 +222,13 @@ async def plan_and_execute_processor(self, state: OverallState, runtime: Runtime
210222
211223 Each review that requires code changes is processed one at a time,
212224 ensuring that file modifications don't conflict with each other.
225+
226+ Args:
227+ state (OverallState): The state of the agent.
228+ runtime (Runtime[RuntimeCtx]): The runtime context.
229+
230+ Returns:
231+ dict: The result of the plan and execute processor.
213232 """
214233 stream_writer = get_stream_writer ()
215234
@@ -238,6 +257,12 @@ async def final_aggregate(self, state: OverallState) -> dict:
238257
239258 This deferred node waits for both reply_reviewer and sequential_processor
240259 to complete and collects all replies.
260+
261+ Args:
262+ state (OverallState): The state of the agent.
263+
264+ Returns:
265+ dict: The result of the final aggregation.
241266 """
242267 # All replies have been collected via the state reducers
243268 return {}
@@ -291,31 +316,26 @@ async def reply_reviewer(self, state: ReplyReviewerState, runtime: Runtime[Runti
291316
292317 return {}
293318
294- async def apply_format_code (
295- self , state : OverallState , config : RunnableConfig , runtime : Runtime [RuntimeCtx ]
296- ) -> dict :
319+ async def apply_format_code (self , state : OverallState , runtime : Runtime [RuntimeCtx ]) -> dict :
297320 """
298321 Apply format code to the file changes.
322+
323+ Args:
324+ state (OverallState): The state of the agent.
325+ runtime (Runtime[RuntimeCtx]): The runtime context.
326+
327+ Returns:
328+ dict: The result of the format code application.
299329 """
300330 if not await has_file_changes (runtime .store ):
301331 return {}
302332
303- tool_call_id = uuid .uuid4 ()
304- await bash_tool .ainvoke ({
305- "type" : "tool_call" ,
306- "name" : bash_tool .name ,
307- "id" : tool_call_id ,
308- "args" : {
309- "commands" : runtime .context .config .sandbox .format_code ,
310- "runtime" : ToolRuntime [RuntimeCtx ](
311- state = state ,
312- tool_call_id = tool_call_id ,
313- config = config ,
314- context = runtime .context ,
315- store = runtime .store ,
316- stream_writer = runtime .stream_writer ,
317- ),
318- },
319- })
333+ daiv_sandbox_client = DAIVSandboxClient ()
334+
335+ session_id = await daiv_sandbox_client .start_session (
336+ StartSessionRequest (base_image = runtime .context .config .sandbox .base_image )
337+ )
338+ await _run_bash_commands (runtime .context .config .sandbox .format_code , runtime .context .repo_dir , session_id )
339+ await daiv_sandbox_client .close_session (session_id )
320340
321341 return {}
0 commit comments