feat: add dialog detection and document dialog commands (#999)
Fixes #992 When a JavaScript dialog (alert/confirm/prompt) blocks the page, agents had no way to detect it — all commands just timed out with generic errors. - Add `dialog status` command to check for pending dialogs - Track dialog state via CDP Page.javascriptDialogOpening/Closed events - Auto-inject `warning` field into all command responses when a dialog is pending, so agents can distinguish dialog-blocked timeouts from other issues - Document dialog commands in SKILL.md (was missing entirely), README.md, docs site, and --help output Co-authored-by: ctate <366502+ctate@users.noreply.github.com>
This commit is contained in:
+45
-2
@@ -122,6 +122,7 @@ pub fn print_response_with_opts(resp: &Response, action: Option<&str>, opts: &Ou
|
||||
} else {
|
||||
println!("{}", serde_json::to_string(resp).unwrap_or_default());
|
||||
}
|
||||
// JSON mode includes the warning field in the JSON payload already
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,10 +132,42 @@ pub fn print_response_with_opts(resp: &Response, action: Option<&str>, opts: &Ou
|
||||
color::error_indicator(),
|
||||
resp.error.as_deref().unwrap_or("Unknown error")
|
||||
);
|
||||
// Still print dialog warning after errors, since a pending dialog
|
||||
// is the most common cause of commands timing out
|
||||
if let Some(ref warning) = resp.warning {
|
||||
eprintln!("{} {}", color::warning_indicator(), warning);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(data) = &resp.data {
|
||||
// Dialog status response
|
||||
if action == Some("dialog") {
|
||||
if let Some(has_dialog) = data.get("hasDialog").and_then(|v| v.as_bool()) {
|
||||
if has_dialog {
|
||||
let dtype = data
|
||||
.get("type")
|
||||
.and_then(|v| v.as_str())
|
||||
.unwrap_or("unknown");
|
||||
let message = data.get("message").and_then(|v| v.as_str()).unwrap_or("");
|
||||
println!(
|
||||
"{} JavaScript {} dialog is open: \"{}\"",
|
||||
color::warning_indicator(),
|
||||
dtype,
|
||||
message
|
||||
);
|
||||
if let Some(default_prompt) = data.get("defaultPrompt").and_then(|v| v.as_str())
|
||||
{
|
||||
println!(" Default prompt text: \"{}\"", default_prompt);
|
||||
}
|
||||
println!(" Use `dialog accept [text]` or `dialog dismiss` to resolve it");
|
||||
} else {
|
||||
println!("{} No dialog is currently open", color::success_indicator());
|
||||
}
|
||||
print_warning(resp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if action == Some("storage_get") {
|
||||
if let Some(output) = format_storage_text(data) {
|
||||
println!("{}", output);
|
||||
@@ -888,6 +921,14 @@ pub fn print_response_with_opts(resp: &Response, action: Option<&str>, opts: &Ou
|
||||
// Default success
|
||||
println!("{} Done", color::success_indicator());
|
||||
}
|
||||
|
||||
print_warning(resp);
|
||||
}
|
||||
|
||||
fn print_warning(resp: &Response) {
|
||||
if let Some(ref warning) = resp.warning {
|
||||
eprintln!("{} {}", color::warning_indicator(), warning);
|
||||
}
|
||||
}
|
||||
|
||||
/// Print command-specific help. Returns true if help was printed, false if command unknown.
|
||||
@@ -1995,13 +2036,14 @@ Examples:
|
||||
r##"
|
||||
agent-browser dialog - Handle browser dialogs
|
||||
|
||||
Usage: agent-browser dialog <response> [text]
|
||||
Usage: agent-browser dialog <accept|dismiss|status> [text]
|
||||
|
||||
Respond to browser dialogs (alert, confirm, prompt).
|
||||
Respond to or check for browser dialogs (alert, confirm, prompt).
|
||||
|
||||
Operations:
|
||||
accept [text] Accept dialog, optionally with prompt text
|
||||
dismiss Dismiss/cancel dialog
|
||||
status Check if a dialog is currently open
|
||||
|
||||
Global Options:
|
||||
--json Output as JSON
|
||||
@@ -2011,6 +2053,7 @@ Examples:
|
||||
agent-browser dialog accept
|
||||
agent-browser dialog accept "my input"
|
||||
agent-browser dialog dismiss
|
||||
agent-browser dialog status
|
||||
"##
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user