eoka-cli 0.10.1

Browser automation CLI for AI agents and pentesting
use super::*;

impl Handler {
    pub(super) async fn handle_agent(&mut self, cmd: &str, args: &Value) -> Response {
        let mut result: anyhow::Result<Response> = async {
            let state = self
                .state
                .as_ref()
                .ok_or_else(|| anyhow::anyhow!("Open a browser page first"))?;
            let page = state
                .current_tab()
                .ok_or_else(|| anyhow::anyhow!("Open a tab first"))?
                .page
                .clone();
            match cmd {
                "agent_observe" => Ok(Response::ok(serde_json::to_value(
                    self.agent
                        .observe(&state.browser, &page, serde_json::from_value(args.clone())?)
                        .await?,
                )?)),
                "agent_step" => Ok(Response::agent_result(
                    self.agent
                        .step_selected(
                            &state.browser,
                            &page,
                            &self.operations,
                            serde_json::from_value(args.clone())?,
                        )
                        .await?,
                )),
                _ => anyhow::bail!("Unknown agent tool"),
            }
        }
        .await;
        if let Ok(response) = &mut result {
            if let Some(id) = response
                .data
                .as_ref()
                .and_then(|v| v["observation"]["tab_id"].as_str())
                .map(str::to_owned)
            {
                if let Some(state) = self.state.as_mut() {
                    if state.current_tab_id.as_deref() != Some(id.as_str()) {
                        if let Err(error) = state.attach_existing_tab(&id).await {
                            if let Some(data) = response.data.as_mut() {
                                data["observation_error"] =
                                    json!(format!("Destination selection failed: {error}"));
                            }
                        }
                    }
                }
            }
        }
        match result {
            Ok(response) => response,
            Err(error) => Response::err_detail(
                eoka_protocol::ErrorDetail::new("agent_error", format!("{error:#}"))
                    .retryable(false),
            ),
        }
    }
}