@@ -115,84 +115,114 @@ def __init__(
115115 ],
116116 )
117117
118+ self ._action_handlers = {
119+ "open_web_browser" : self ._handle_open_web_browser ,
120+ "click_at" : self ._handle_click_at ,
121+ "hover_at" : self ._handle_hover_at ,
122+ "type_text_at" : self ._handle_type_text_at ,
123+ "scroll_document" : self ._handle_scroll_document ,
124+ "scroll_at" : self ._handle_scroll_at ,
125+ "wait_5_seconds" : self ._handle_wait_5_seconds ,
126+ "go_back" : self ._handle_go_back ,
127+ "go_forward" : self ._handle_go_forward ,
128+ "search" : self ._handle_search ,
129+ "navigate" : self ._handle_navigate ,
130+ "key_combination" : self ._handle_key_combination ,
131+ "drag_and_drop" : self ._handle_drag_and_drop ,
132+ multiply_numbers .__name__ : self ._handle_multiply_numbers ,
133+ }
134+
118135 def handle_action (self , action : types .FunctionCall ) -> FunctionResponseT :
119136 """Handles the action and returns the environment state."""
120- if action .name == "open_web_browser" :
121- return self ._browser_computer .open_web_browser ()
122- elif action .name == "click_at" :
123- x = self .denormalize_x (action .args ["x" ])
124- y = self .denormalize_y (action .args ["y" ])
125- return self ._browser_computer .click_at (
126- x = x ,
127- y = y ,
128- )
129- elif action .name == "hover_at" :
130- x = self .denormalize_x (action .args ["x" ])
131- y = self .denormalize_y (action .args ["y" ])
132- return self ._browser_computer .hover_at (
133- x = x ,
134- y = y ,
135- )
136- elif action .name == "type_text_at" :
137- x = self .denormalize_x (action .args ["x" ])
138- y = self .denormalize_y (action .args ["y" ])
139- press_enter = action .args .get ("press_enter" , False )
140- clear_before_typing = action .args .get ("clear_before_typing" , True )
141- return self ._browser_computer .type_text_at (
142- x = x ,
143- y = y ,
144- text = action .args ["text" ],
145- press_enter = press_enter ,
146- clear_before_typing = clear_before_typing ,
147- )
148- elif action .name == "scroll_document" :
149- return self ._browser_computer .scroll_document (action .args ["direction" ])
150- elif action .name == "scroll_at" :
151- x = self .denormalize_x (action .args ["x" ])
152- y = self .denormalize_y (action .args ["y" ])
153- magnitude = action .args .get ("magnitude" , 800 )
154- direction = action .args ["direction" ]
155-
156- if direction in ("up" , "down" ):
157- magnitude = self .denormalize_y (magnitude )
158- elif direction in ("left" , "right" ):
159- magnitude = self .denormalize_x (magnitude )
160- else :
161- raise ValueError ("Unknown direction: " , direction )
162- return self ._browser_computer .scroll_at (
163- x = x , y = y , direction = direction , magnitude = magnitude
164- )
165- elif action .name == "wait_5_seconds" :
166- return self ._browser_computer .wait_5_seconds ()
167- elif action .name == "go_back" :
168- return self ._browser_computer .go_back ()
169- elif action .name == "go_forward" :
170- return self ._browser_computer .go_forward ()
171- elif action .name == "search" :
172- return self ._browser_computer .search ()
173- elif action .name == "navigate" :
174- return self ._browser_computer .navigate (action .args ["url" ])
175- elif action .name == "key_combination" :
176- return self ._browser_computer .key_combination (
177- action .args ["keys" ].split ("+" )
178- )
179- elif action .name == "drag_and_drop" :
180- x = self .denormalize_x (action .args ["x" ])
181- y = self .denormalize_y (action .args ["y" ])
182- destination_x = self .denormalize_x (action .args ["destination_x" ])
183- destination_y = self .denormalize_y (action .args ["destination_y" ])
184- return self ._browser_computer .drag_and_drop (
185- x = x ,
186- y = y ,
187- destination_x = destination_x ,
188- destination_y = destination_y ,
189- )
190- # Handle the custom function declarations here.
191- elif action .name == multiply_numbers .__name__ :
192- return multiply_numbers (x = action .args ["x" ], y = action .args ["y" ])
137+ if handler := self ._action_handlers .get (action .name ):
138+ return handler (action )
193139 else :
194140 raise ValueError (f"Unsupported function: { action } " )
195141
142+ def _handle_open_web_browser (self , action : types .FunctionCall ) -> FunctionResponseT :
143+ return self ._browser_computer .open_web_browser ()
144+
145+ def _handle_click_at (self , action : types .FunctionCall ) -> FunctionResponseT :
146+ x = self .denormalize_x (action .args ["x" ])
147+ y = self .denormalize_y (action .args ["y" ])
148+ return self ._browser_computer .click_at (x = x , y = y )
149+
150+ def _handle_hover_at (self , action : types .FunctionCall ) -> FunctionResponseT :
151+ x = self .denormalize_x (action .args ["x" ])
152+ y = self .denormalize_y (action .args ["y" ])
153+ return self ._browser_computer .hover_at (x = x , y = y )
154+
155+ def _handle_type_text_at (self , action : types .FunctionCall ) -> FunctionResponseT :
156+ x = self .denormalize_x (action .args ["x" ])
157+ y = self .denormalize_y (action .args ["y" ])
158+ press_enter = action .args .get ("press_enter" , False )
159+ clear_before_typing = action .args .get ("clear_before_typing" , True )
160+ return self ._browser_computer .type_text_at (
161+ x = x ,
162+ y = y ,
163+ text = action .args ["text" ],
164+ press_enter = press_enter ,
165+ clear_before_typing = clear_before_typing ,
166+ )
167+
168+ def _handle_scroll_document (self , action : types .FunctionCall ) -> FunctionResponseT :
169+ return self ._browser_computer .scroll_document (action .args ["direction" ])
170+
171+ def _handle_scroll_at (self , action : types .FunctionCall ) -> FunctionResponseT :
172+ x = self .denormalize_x (action .args ["x" ])
173+ y = self .denormalize_y (action .args ["y" ])
174+ magnitude = action .args .get ("magnitude" , 800 )
175+ direction = action .args ["direction" ]
176+
177+ if direction in ("up" , "down" ):
178+ magnitude = self .denormalize_y (magnitude )
179+ elif direction in ("left" , "right" ):
180+ magnitude = self .denormalize_x (magnitude )
181+ else :
182+ raise ValueError (f"Unknown direction: { direction } " )
183+ return self ._browser_computer .scroll_at (
184+ x = x , y = y , direction = direction , magnitude = magnitude
185+ )
186+
187+ def _handle_wait_5_seconds (
188+ self , action : types .FunctionCall
189+ ) -> FunctionResponseT :
190+ return self ._browser_computer .wait_5_seconds ()
191+
192+ def _handle_go_back (self , action : types .FunctionCall ) -> FunctionResponseT :
193+ return self ._browser_computer .go_back ()
194+
195+ def _handle_go_forward (self , action : types .FunctionCall ) -> FunctionResponseT :
196+ return self ._browser_computer .go_forward ()
197+
198+ def _handle_search (self , action : types .FunctionCall ) -> FunctionResponseT :
199+ return self ._browser_computer .search ()
200+
201+ def _handle_navigate (self , action : types .FunctionCall ) -> FunctionResponseT :
202+ return self ._browser_computer .navigate (action .args ["url" ])
203+
204+ def _handle_key_combination (
205+ self , action : types .FunctionCall
206+ ) -> FunctionResponseT :
207+ return self ._browser_computer .key_combination (action .args ["keys" ].split ("+" ))
208+
209+ def _handle_drag_and_drop (self , action : types .FunctionCall ) -> FunctionResponseT :
210+ x = self .denormalize_x (action .args ["x" ])
211+ y = self .denormalize_y (action .args ["y" ])
212+ destination_x = self .denormalize_x (action .args ["destination_x" ])
213+ destination_y = self .denormalize_y (action .args ["destination_y" ])
214+ return self ._browser_computer .drag_and_drop (
215+ x = x ,
216+ y = y ,
217+ destination_x = destination_x ,
218+ destination_y = destination_y ,
219+ )
220+
221+ def _handle_multiply_numbers (
222+ self , action : types .FunctionCall
223+ ) -> FunctionResponseT :
224+ return multiply_numbers (x = action .args ["x" ], y = action .args ["y" ])
225+
196226 def get_model_response (
197227 self , max_retries = 5 , base_delay_s = 1
198228 ) -> types .GenerateContentResponse :
@@ -253,11 +283,13 @@ def run_one_iteration(self) -> Literal["COMPLETE", "CONTINUE"]:
253283 try :
254284 response = self .get_model_response ()
255285 except Exception as e :
286+ print (e )
256287 return "COMPLETE"
257288 else :
258289 try :
259290 response = self .get_model_response ()
260291 except Exception as e :
292+ print (e )
261293 return "COMPLETE"
262294
263295 if not response .candidates :
@@ -292,7 +324,7 @@ def run_one_iteration(self) -> Literal["COMPLETE", "CONTINUE"]:
292324 # Print the function call and any reasoning.
293325 function_call_str = f"Name: { function_call .name } "
294326 if function_call .args :
295- function_call_str += f "\n Args:"
327+ function_call_str += "\n Args:"
296328 for key , value in function_call .args .items ():
297329 function_call_str += f"\n { key } : { value } "
298330 function_call_strs .append (function_call_str )
@@ -390,7 +422,7 @@ def _get_safety_confirmation(
390422 self , safety : dict [str , Any ]
391423 ) -> Literal ["CONTINUE" , "TERMINATE" ]:
392424 if safety ["decision" ] != "require_confirmation" :
393- raise ValueError (f"Unknown safety decision: safety['decision']" )
425+ raise ValueError (f"Unknown safety decision: { safety ['decision' ]} " )
394426 termcolor .cprint (
395427 "Safety service requires explicit confirmation!" ,
396428 color = "yellow" ,
0 commit comments