1use serde_json::Value;
2
3use crate::methods::{browser, page};
4use crate::protocol::ServerError;
5use crate::state::AppState;
6
7pub async fn dispatch(
8 state: &mut AppState,
9 method: &str,
10 params: Value,
11) -> Result<Value, ServerError> {
12 if matches!(method, "agent.observe" | "agent.step") {
13 let browser = state.browser()?.clone();
14 let page = state
15 .page(
16 params["pageId"]
17 .as_str()
18 .ok_or_else(|| ServerError::invalid_params("pageId required"))?,
19 )?
20 .clone();
21 let mut args = params;
22 if let Some(object) = args.as_object_mut() {
23 object.remove("pageId");
24 }
25 let result = if method == "agent.observe" {
26 serde_json::to_value(
27 state
28 .agent
29 .observe(
30 &browser,
31 &page,
32 serde_json::from_value(args)
33 .map_err(|e| ServerError::invalid_params(e.to_string()))?,
34 )
35 .await
36 .map_err(|e| ServerError::internal(format!("{e:#}")))?,
37 )
38 } else {
39 serde_json::to_value(
40 state
41 .agent
42 .step(
43 &browser,
44 &page,
45 &state.operations,
46 serde_json::from_value(args)
47 .map_err(|e| ServerError::invalid_params(e.to_string()))?,
48 )
49 .await
50 .map_err(|e| ServerError::internal(format!("{e:#}")))?,
51 )
52 };
53 return result.map_err(|e| ServerError::internal(e.to_string()));
54 }
55 if let Some(result) = crate::operations::sidecar::dispatch(state, method, ¶ms).await {
56 return result;
57 }
58 if matches!(method, "browser.close" | "browser.close_tab" | "page.close") {
59 state.operations.stop().await;
60 }
61 match method {
62 "browser.launch" => browser::launch(state, params).await,
63 "browser.new_page" => browser::new_page(state, params).await,
64 "browser.tabs" => browser::tabs(state, params).await,
65 "browser.close_tab" => browser::close_tab(state, params).await,
66 "browser.close" => browser::close(state, params).await,
67
68 "page.goto" => page::goto(state, params).await,
69 "page.click" => page::click(state, params).await,
70 "page.click_text" => page::click_text(state, params).await,
71 "page.human_click" => page::human_click(state, params).await,
72 "page.human_click_text" => page::human_click_text(state, params).await,
73 "page.fill" => page::fill(state, params).await,
74 "page.human_fill" => page::human_fill(state, params).await,
75 "page.type_into" => page::type_into(state, params).await,
76 "page.text" => page::text(state, params).await,
77 "page.content" => page::content(state, params).await,
78 "page.title" => page::title(state, params).await,
79 "page.url" => page::url(state, params).await,
80 "page.get_text" => page::get_text(state, params).await,
81 "page.get_attribute" => page::get_attribute(state, params).await,
82 "page.exists" => page::exists(state, params).await,
83 "page.wait_for" => page::wait_for(state, params).await,
84 "page.wait_for_visible" => page::wait_for_visible(state, params).await,
85 "page.wait_for_text" => page::wait_for_text(state, params).await,
86 "page.evaluate" => page::evaluate(state, params).await,
87 "page.execute" => page::execute(state, params).await,
88 "page.fetch" => page::fetch(state, params).await,
89 "page.capture_state" => page::capture_state(state, params).await,
90 "page.restore_state" => page::restore_state(state, params).await,
91 "page.screenshot" => page::screenshot(state, params).await,
92 "page.select" => page::select(state, params).await,
93 "page.hover" => page::hover(state, params).await,
94 "page.press_key" => page::press_key(state, params).await,
95 "page.mouse_down" => page::mouse_down(state, params).await,
96 "page.mouse_move" => page::mouse_move(state, params).await,
97 "page.mouse_up" => page::mouse_up(state, params).await,
98 "page.key_down" => page::key_down(state, params).await,
99 "page.key_up" => page::key_up(state, params).await,
100 "page.release_all_inputs" => page::release_all_inputs(state, params).await,
101 "page.solve_captcha" => page::solve_captcha(state, params).await,
102 "page.close" => page::close(state, params).await,
103
104 _ => Err(ServerError::unknown_method(method)),
105 }
106}