fix: per-invocation env (CLICK_MODE / HUMANIZE) reaches a running daemon
Root cause behind Hermes #1 (CLICK_MODE=dom "does nothing") and #2 (--humanize "does nothing"): both are env vars the daemon reads, but the daemon's env is frozen at spawn — set them on a command to an already-running daemon and they were silently ignored. (Confirmed: setting CLICK_MODE=dom at daemon spawn made dom_click fire; setting it later did not.) Fix: the client forwards AGENT_BROWSER_CLICK_MODE / AGENT_BROWSER_HUMANIZE in the command envelope (_clickMode/_humanize); execute_command applies them per command — mirrors CLICK_MODE into the process env (interaction::click reads it fresh) and sets the humanize session level. Each command is authoritative. Verified on an already-running daemon: CLICK_MODE=dom now fires dom_click (hits 0→1); --humanize human typing applies.
This commit is contained in:
+15
-1
@@ -821,7 +821,21 @@ fn connect(session: &str) -> Result<Connection, String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_command(cmd: Value, session: &str) -> Result<Response, String> {
|
pub fn send_command(mut cmd: Value, session: &str) -> Result<Response, String> {
|
||||||
|
// Forward per-invocation env to the daemon. The daemon's environment is
|
||||||
|
// frozen at spawn, so settings like AGENT_BROWSER_CLICK_MODE /
|
||||||
|
// AGENT_BROWSER_HUMANIZE (incl. the --humanize flag, which sets the latter)
|
||||||
|
// are otherwise silently ignored on an already-running daemon. Carry them in
|
||||||
|
// the envelope so they apply to THIS command.
|
||||||
|
if let Some(obj) = cmd.as_object_mut() {
|
||||||
|
if let Ok(m) = std::env::var("AGENT_BROWSER_CLICK_MODE") {
|
||||||
|
obj.insert("_clickMode".to_string(), Value::String(m));
|
||||||
|
}
|
||||||
|
if let Ok(h) = std::env::var("AGENT_BROWSER_HUMANIZE") {
|
||||||
|
obj.insert("_humanize".to_string(), Value::String(h));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Retry logic for transient errors (EAGAIN/EWOULDBLOCK/connection issues)
|
// Retry logic for transient errors (EAGAIN/EWOULDBLOCK/connection issues)
|
||||||
const MAX_RETRIES: u32 = 5;
|
const MAX_RETRIES: u32 = 5;
|
||||||
const RETRY_DELAY_MS: u64 = 200;
|
const RETRY_DELAY_MS: u64 = 200;
|
||||||
|
|||||||
@@ -1160,6 +1160,23 @@ impl Drop for DaemonState {
|
|||||||
|
|
||||||
pub async fn execute_command(cmd: &Value, state: &mut DaemonState) -> Value {
|
pub async fn execute_command(cmd: &Value, state: &mut DaemonState) -> Value {
|
||||||
let action = cmd.get("action").and_then(|v| v.as_str()).unwrap_or("");
|
let action = cmd.get("action").and_then(|v| v.as_str()).unwrap_or("");
|
||||||
|
|
||||||
|
// Apply per-invocation overrides the client forwarded (the daemon's own env
|
||||||
|
// is frozen at spawn). CLICK_MODE is read fresh from the process env by
|
||||||
|
// interaction::click, so mirror it here — set when this command provided it,
|
||||||
|
// clear otherwise, so a value from an earlier command never leaks forward.
|
||||||
|
match cmd.get("_clickMode").and_then(|v| v.as_str()) {
|
||||||
|
Some(m) if !m.is_empty() => std::env::set_var("AGENT_BROWSER_CLICK_MODE", m),
|
||||||
|
_ => std::env::remove_var("AGENT_BROWSER_CLICK_MODE"),
|
||||||
|
}
|
||||||
|
// Humanize: set the session level from the client's --humanize / env. Only
|
||||||
|
// set when provided (don't clear — the adaptive per-navigation detector also
|
||||||
|
// owns this level between explicit overrides).
|
||||||
|
if let Some(h) = cmd.get("_humanize").and_then(|v| v.as_str()) {
|
||||||
|
if let Some(level) = super::humanize::HumanizeLevel::parse(h) {
|
||||||
|
super::humanize::set_detected_level(level);
|
||||||
|
}
|
||||||
|
}
|
||||||
let id = cmd
|
let id = cmd
|
||||||
.get("id")
|
.get("id")
|
||||||
.and_then(|v| v.as_str())
|
.and_then(|v| v.as_str())
|
||||||
|
|||||||
Reference in New Issue
Block a user