Skip to content

Commit b762c23

Browse files
committed
refactor: Clean up browser action handling and fix f-string bug
- Refactored browser actions into dictionary-based mapping for better organization - Modularized action handling functions for improved maintainability - Fixed f-string where safety['decision'] variable wasn't inside curly braces
1 parent b18bcfb commit b762c23

1 file changed

Lines changed: 107 additions & 75 deletions

File tree

agent.py

Lines changed: 107 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -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"\nArgs:"
327+
function_call_str += "\nArgs:"
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

Comments
 (0)