@@ -90,11 +90,6 @@ async def execute(
9090 """Run a computer action, capturing a screenshot and notifying hooks."""
9191 computer = await resolve_computer (tool = action .computer_tool , run_context = context_wrapper )
9292 agent_hooks = agent .hooks
93- output_func = (
94- cls ._get_screenshot_async (computer , action .tool_call )
95- if hasattr (computer , "screenshot_async" )
96- else cls ._get_screenshot_sync (computer , action .tool_call )
97- )
9893 await asyncio .gather (
9994 hooks .on_tool_start (context_wrapper , agent , action .computer_tool ),
10095 (
@@ -104,7 +99,7 @@ async def execute(
10499 ),
105100 )
106101
107- output = await output_func
102+ output = await cls . _execute_action_and_capture ( computer , action . tool_call )
108103
109104 await asyncio .gather (
110105 hooks .on_tool_end (context_wrapper , agent , action .computer_tool , output ),
@@ -131,62 +126,40 @@ async def execute(
131126 )
132127
133128 @classmethod
134- async def _get_screenshot_sync (
135- cls ,
136- computer : Any ,
137- tool_call : ResponseComputerToolCall ,
129+ async def _execute_action_and_capture (
130+ cls , computer : Any , tool_call : ResponseComputerToolCall
138131 ) -> str :
139- """Execute the computer action for sync drivers and return the screenshot."""
140- action = tool_call .action
141- if isinstance (action , ActionClick ):
142- computer .click (action .x , action .y , action .button )
143- elif isinstance (action , ActionDoubleClick ):
144- computer .double_click (action .x , action .y )
145- elif isinstance (action , ActionDrag ):
146- computer .drag ([(p .x , p .y ) for p in action .path ])
147- elif isinstance (action , ActionKeypress ):
148- computer .keypress (action .keys )
149- elif isinstance (action , ActionMove ):
150- computer .move (action .x , action .y )
151- elif isinstance (action , ActionScreenshot ):
152- computer .screenshot ()
153- elif isinstance (action , ActionScroll ):
154- computer .scroll (action .x , action .y , action .scroll_x , action .scroll_y )
155- elif isinstance (action , ActionType ):
156- computer .type (action .text )
157- elif isinstance (action , ActionWait ):
158- computer .wait ()
132+ """Execute the computer action (sync or async drivers) and return the screenshot."""
159133
160- return cast (str , computer .screenshot ())
134+ async def maybe_call (method_name : str , * args : Any ) -> Any :
135+ method = getattr (computer , method_name , None )
136+ if method is None or not callable (method ):
137+ raise ModelBehaviorError (f"Computer driver missing method { method_name } " )
138+ result = method (* args )
139+ return await result if inspect .isawaitable (result ) else result
161140
162- @classmethod
163- async def _get_screenshot_async (
164- cls ,
165- computer : Any ,
166- tool_call : ResponseComputerToolCall ,
167- ) -> str :
168- """Execute the computer action for async drivers and return the screenshot."""
169141 action = tool_call .action
170142 if isinstance (action , ActionClick ):
171- await computer . click ( action .x , action .y , action .button )
143+ await maybe_call ( "click" , action .x , action .y , action .button )
172144 elif isinstance (action , ActionDoubleClick ):
173- await computer . double_click ( action .x , action .y )
145+ await maybe_call ( "double_click" , action .x , action .y )
174146 elif isinstance (action , ActionDrag ):
175- await computer . drag ( [(p .x , p .y ) for p in action .path ])
147+ await maybe_call ( "drag" , [(p .x , p .y ) for p in action .path ])
176148 elif isinstance (action , ActionKeypress ):
177- await computer . keypress ( action .keys )
149+ await maybe_call ( "keypress" , action .keys )
178150 elif isinstance (action , ActionMove ):
179- await computer . move ( action .x , action .y )
151+ await maybe_call ( "move" , action .x , action .y )
180152 elif isinstance (action , ActionScreenshot ):
181- await computer . screenshot ( )
153+ await maybe_call ( "screenshot" )
182154 elif isinstance (action , ActionScroll ):
183- await computer . scroll ( action .x , action .y , action .scroll_x , action .scroll_y )
155+ await maybe_call ( "scroll" , action .x , action .y , action .scroll_x , action .scroll_y )
184156 elif isinstance (action , ActionType ):
185- await computer . type ( action .text )
157+ await maybe_call ( "type" , action .text )
186158 elif isinstance (action , ActionWait ):
187- await computer . wait ( )
159+ await maybe_call ( "wait" )
188160
189- return cast (str , await computer .screenshot ())
161+ screenshot_result = await maybe_call ("screenshot" )
162+ return cast (str , screenshot_result )
190163
191164
192165class LocalShellAction :
0 commit comments