Skip to content

Commit ddae14f

Browse files
committed
remove warning level, consolidate with api
1 parent 7165054 commit ddae14f

File tree

13 files changed

+69
-73
lines changed

13 files changed

+69
-73
lines changed

stagehand/a11y/utils.py

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,16 +81,16 @@ async def _clean_structural_nodes(
8181
node["role"] = result_value
8282
node_role = result_value
8383
except Exception as tag_name_error:
84-
# Use logger.warning (level 2)
85-
logger.warning(
84+
# Use logger.debug (level 2)
85+
logger.debug(
8686
message=f"Could not fetch tagName for node {backend_node_id}",
8787
auxiliary={
8888
"error": {"value": str(tag_name_error), "type": "string"}
8989
},
9090
)
9191
except Exception as resolve_error:
92-
# Use logger.warning (level 2)
93-
logger.warning(
92+
# Use logger.debug (level 2)
93+
logger.debug(
9494
message=f"Could not resolve DOM node ID {backend_node_id}",
9595
auxiliary={"error": {"value": str(resolve_error), "type": "string"}},
9696
)
@@ -278,9 +278,8 @@ async def get_accessibility_tree(
278278
try:
279279
await page.disable_cdp_domain("Accessibility")
280280
except Exception:
281-
# Log if disabling fails, but don't raise further
282-
if logger:
283-
logger.warning("Failed to disable Accessibility domain on cleanup.")
281+
# Use logger.debug (level 2)
282+
logger.debug("Failed to disable Accessibility domain on cleanup.")
284283

285284

286285
# JavaScript function to get XPath (remains JavaScript)

stagehand/agent.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,20 @@ def __init__(self, stagehand_client, agent_config: AgentConfig):
3131
self._stagehand = stagehand_client
3232
self._config = agent_config # Store the required config
3333

34+
if not self._stagehand._initialized:
35+
self._stagehand.logger.error(
36+
"Stagehand must be initialized before creating an agent. Call await stagehand.init() first."
37+
)
38+
raise RuntimeError(
39+
"Stagehand must be initialized before creating an agent. Call await stagehand.init() first."
40+
)
41+
3442
# Perform provider inference and validation
3543
if self._config.model and not self._config.provider:
3644
if self._config.model in MODEL_TO_PROVIDER_MAP:
3745
self._config.provider = MODEL_TO_PROVIDER_MAP[self._config.model]
3846
else:
39-
self._stagehand.logger.warning(
47+
self._stagehand.logger.error(
4048
f"Could not infer provider for model: {self._config.model}"
4149
)
4250

stagehand/agent/anthropic_cua.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ async def run_task(
243243
break
244244

245245
if not agent_action and not task_completed:
246-
self.logger.warning(
246+
self.logger.debug(
247247
"Model did not request an action and task not marked complete. Ending task to prevent loop.",
248248
category=StagehandFunctionName.AGENT,
249249
)
@@ -290,7 +290,7 @@ def _process_provider_response(
290290
block.model_dump() for block in response.content
291291
]
292292
except Exception as e:
293-
self.logger.warning(
293+
self.logger.debug(
294294
f"Could not model_dump response.content blocks: {e}",
295295
category=StagehandFunctionName.AGENT,
296296
)
@@ -337,7 +337,7 @@ def _convert_tool_use_to_agent_action(
337337
and tool_name != "goto"
338338
and tool_name != "navigate_back"
339339
):
340-
self.logger.warning(
340+
self.logger.debug(
341341
f"Unsupported tool name from Anthropic: {tool_name}",
342342
category=StagehandFunctionName.AGENT,
343343
)
@@ -501,7 +501,7 @@ def _convert_tool_use_to_agent_action(
501501
)
502502
action_type_str = "drag" # Normalize
503503
else:
504-
self.logger.warning(
504+
self.logger.debug(
505505
"Drag action missing valid start or end coordinates.",
506506
category=StagehandFunctionName.AGENT,
507507
)
@@ -559,7 +559,7 @@ def _convert_tool_use_to_agent_action(
559559
)
560560
action_type_str = "function"
561561
else:
562-
self.logger.warning(
562+
self.logger.debug(
563563
"Goto action from Anthropic missing URL",
564564
category=StagehandFunctionName.AGENT,
565565
)
@@ -572,7 +572,7 @@ def _convert_tool_use_to_agent_action(
572572
)
573573
action_type_str = "function"
574574
else:
575-
self.logger.warning(
575+
self.logger.debug(
576576
f"Unsupported action type '{action_type_str}' from Anthropic computer tool.",
577577
category=StagehandFunctionName.AGENT,
578578
)
@@ -613,7 +613,7 @@ def _format_action_feedback(
613613
self.format_screenshot(new_screenshot_base64)
614614
)
615615
else:
616-
self.logger.warning(
616+
self.logger.debug(
617617
"Missing screenshot for computer tool feedback (empty string passed).",
618618
category=StagehandFunctionName.AGENT,
619619
)

stagehand/agent/google_cua.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ async def _process_provider_response(
150150
and candidate.safety_ratings
151151
):
152152
error_message += f" - Safety Ratings: {candidate.safety_ratings}"
153-
self.logger.warning(error_message, category="agent")
153+
self.logger.info(error_message, category="agent")
154154
return None, reasoning_text, True, error_message, None
155155

156156
agent_action: Optional[AgentAction] = None
@@ -218,7 +218,7 @@ async def _process_provider_response(
218218
"keys": [self.key_to_playwright("PageDown")],
219219
}
220220
else:
221-
self.logger.warning(
221+
self.logger.error(
222222
f"Unsupported scroll direction: {direction}", category="agent"
223223
)
224224
return (
@@ -264,7 +264,7 @@ async def _process_provider_response(
264264
"arguments": {"url": "https://www.google.com"},
265265
}
266266
else:
267-
self.logger.warning(
267+
self.logger.error(
268268
f"Unsupported Google CUA function: {action_name}", category="agent"
269269
)
270270
return (
@@ -524,7 +524,7 @@ async def run_task(
524524
)
525525

526526
if not agent_action and not task_completed:
527-
self.logger.warning(
527+
self.logger.error(
528528
"Model did not request an action and task not marked complete. Ending task.",
529529
category="agent",
530530
)
@@ -540,7 +540,7 @@ async def run_task(
540540
usage=usage_obj,
541541
)
542542

543-
self.logger.warning("Max steps reached for Google CUA task.", category="agent")
543+
self.logger.error("Max steps reached for Google CUA task.", category="agent")
544544
usage_obj = {
545545
"input_tokens": total_input_tokens,
546546
"output_tokens": total_output_tokens,

stagehand/agent/openai_cua.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def _process_provider_response(
214214
)
215215
# Ensure arguments is a dict, even if empty
216216
if not isinstance(arguments, dict):
217-
self.logger.warning(
217+
self.logger.debug(
218218
f"Function call arguments are not a dict: {arguments}. Using empty dict.",
219219
category="agent",
220220
)
@@ -464,7 +464,7 @@ async def run_task(
464464
)
465465

466466
if not agent_action and not task_completed:
467-
self.logger.warning(
467+
self.logger.info(
468468
"Model did not request an action and task not marked complete. Ending task to prevent loop.",
469469
category="agent",
470470
)
@@ -480,7 +480,7 @@ async def run_task(
480480
usage=usage_obj,
481481
)
482482

483-
self.logger.warning("Max steps reached for OpenAI CUA task.", category="agent")
483+
self.logger.info("Max steps reached for OpenAI CUA task.", category="agent")
484484
usage_obj = {
485485
"input_tokens": total_input_tokens,
486486
"output_tokens": total_output_tokens,

stagehand/client.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ def __init__(
179179
)
180180
if not self.model_api_key:
181181
# Model API key needed if Stagehand server creates the session
182-
self.logger.warning(
182+
self.logger.info(
183183
"model_api_key is recommended when creating a new BROWSERBASE session to configure the Stagehand server's LLM."
184184
)
185185
elif self.session_id:
@@ -477,7 +477,7 @@ async def init(self):
477477
self._context = existing_contexts[0]
478478
else:
479479
# This case might be less common with Browserbase but handle it
480-
self.logger.warning(
480+
self.logger.debug(
481481
"No existing context found in remote browser, creating a new one."
482482
)
483483
self._context = (
@@ -705,7 +705,7 @@ async def close(self):
705705
f"Error ending server session {self.session_id}: {str(e)}"
706706
)
707707
elif self.session_id:
708-
self.logger.warning(
708+
self.logger.debug(
709709
"Cannot end server session: HTTP client not available."
710710
)
711711

@@ -769,7 +769,7 @@ async def _create_session(self):
769769

770770
payload = {
771771
"modelName": self.model_name,
772-
"verbose": 2 if self.verbose == 3 else self.verbose,
772+
"verbose": self.verbose,
773773
"domSettleTimeoutMs": self.dom_settle_timeout_ms,
774774
"browserbaseSessionCreateParams": (
775775
browserbase_session_create_params
@@ -913,7 +913,7 @@ async def _execute(self, method: str, payload: dict[str, Any]) -> Any:
913913
# Log any other message types
914914
self.logger.debug(f"[UNKNOWN] Message type: {msg_type}")
915915
except json.JSONDecodeError:
916-
self.logger.warning(f"Could not parse line as JSON: {line}")
916+
self.logger.debug(f"Could not parse line as JSON: {line}")
917917

918918
# Return the final result
919919
return result
@@ -942,17 +942,16 @@ async def _handle_log(self, msg: dict[str, Any]):
942942

943943
# Map level strings to internal levels
944944
level_map = {
945-
"debug": 3,
945+
"debug": 2,
946946
"info": 1,
947-
"warning": 2,
948947
"error": 0,
949948
}
950949

951950
# Convert string level to int if needed
952951
if isinstance(level_str, str):
953952
internal_level = level_map.get(level_str.lower(), 1)
954953
else:
955-
internal_level = min(level_str, 3) # Ensure level is between 0-3
954+
internal_level = min(level_str, 2) # Ensure level is between 0-2
956955

957956
# Handle the case where message itself might be a JSON-like object
958957
if isinstance(message, dict):
@@ -986,7 +985,7 @@ def _log(
986985
987986
Args:
988987
message: The message to log
989-
level: Verbosity level (0=error, 1=info, 2=detailed, 3=debug)
988+
level: Verbosity level (0=error, 1=info, 2=debug)
990989
category: Optional category for the message
991990
auxiliary: Optional auxiliary data to include
992991
"""

stagehand/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class StagehandConfig(BaseModel):
2525
wait_for_captcha_solves (Optional[bool]): Whether to wait for CAPTCHA to be solved.
2626
act_timeout_ms (Optional[int]): Timeout for act commands (in milliseconds).
2727
system_prompt (Optional[str]): System prompt to use for LLM interactions.
28-
verbose (Optional[int]): Verbosity level for logs (1=minimal, 2=medium, 3=detailed).
28+
verbose (Optional[int]): Verbosity level for logs (0=errors, 1=info, 2=debug).
2929
local_browser_launch_options (Optional[dict[str, Any]]): Local browser launch options.
3030
"""
3131

@@ -38,7 +38,7 @@ class StagehandConfig(BaseModel):
3838
)
3939
verbose: Optional[int] = Field(
4040
1,
41-
description="Verbosity level for logs: 1=minimal (INFO), 2=medium (WARNING), 3=detailed (DEBUG)",
41+
description="Verbosity level for logs: 0=errors only, 1=info, 2=debug",
4242
)
4343
logger: Optional[Callable[[Any], None]] = Field(
4444
None, description="Custom logging function"

stagehand/handlers/act_handler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ async def _act_from_observe_result(
156156
)
157157

158158
if observe_result.method == "not-supported":
159-
self.logger.warning(
159+
self.logger.error(
160160
message="Cannot execute ObserveResult with unsupported method",
161161
category="act",
162162
auxiliary={
@@ -229,7 +229,7 @@ async def _act_from_observe_result(
229229
if (
230230
not act_command
231231
): # If both method and description were empty or resulted in an empty command
232-
self.logger.warning(
232+
self.logger.error(
233233
"Self-heal attempt aborted: could not construct a valid command from ObserveResult.",
234234
category="act",
235235
auxiliary={
@@ -307,7 +307,7 @@ async def _perform_playwright_method(
307307
elif hasattr(locator, method) and callable(getattr(locator, method)):
308308
await fallback_locator_method(context)
309309
else:
310-
self.logger.warning(
310+
self.logger.error(
311311
message="chosen method is invalid",
312312
category="act",
313313
auxiliary={"method": {"value": method, "type": "string"}},

stagehand/handlers/act_handler_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ async def handle_possible_page_navigation(
458458
try:
459459
await stagehand_page._wait_for_settled_dom(dom_settle_timeout_ms)
460460
except Exception as e:
461-
logger.warning(
461+
logger.debug(
462462
message="wait for settled DOM timeout hit",
463463
category="action",
464464
auxiliary={

stagehand/handlers/cua_handler.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ async def perform_action(self, action: AgentAction) -> ActionExecutionResult:
149149
await self.page.go_back()
150150
return {"success": True}
151151
# Add other function calls like back, forward, reload if needed, similar to TS version
152-
self.logger.warning(
152+
self.logger.error(
153153
f"Unsupported function call: {name}",
154154
category=StagehandFunctionName.AGENT,
155155
)
@@ -195,7 +195,7 @@ async def perform_action(self, action: AgentAction) -> ActionExecutionResult:
195195
return {"success": True}
196196

197197
else:
198-
self.logger.warning(
198+
self.logger.error(
199199
f"Unsupported action type: {action_type}",
200200
category=StagehandFunctionName.AGENT,
201201
)
@@ -236,7 +236,7 @@ async def _update_cursor_position(self, x: int, y: int) -> None:
236236
f"window.__stagehandUpdateCursorPosition({x}, {y})"
237237
)
238238
except Exception as e:
239-
self.logger.warning(
239+
self.logger.debug(
240240
f"Failed to call window.__stagehandUpdateCursorPosition: {e}",
241241
category=StagehandFunctionName.AGENT,
242242
)
@@ -246,7 +246,7 @@ async def _animate_click(self, x: int, y: int) -> None:
246246
try:
247247
await self.page.evaluate(f"window.__stagehandAnimateClick({x}, {y})")
248248
except Exception as e:
249-
self.logger.warning(
249+
self.logger.debug(
250250
f"Failed to call window.__stagehandAnimateClick: {e}",
251251
category=StagehandFunctionName.AGENT,
252252
)

0 commit comments

Comments
 (0)