elizaos_browser/
plugin.rs1use crate::actions::{
2 browser_click, browser_extract, browser_navigate, browser_screenshot, browser_select,
3 browser_type,
4};
5use crate::providers::get_browser_state;
6use crate::services::BrowserService;
7use crate::types::{ActionResult, BrowserConfig};
8use std::env;
9use std::sync::Arc;
10use tracing::info;
11
12pub struct BrowserPlugin {
13 pub name: String,
14 pub description: String,
15 pub config: BrowserConfig,
16 pub service: Option<Arc<BrowserService>>,
17}
18
19impl BrowserPlugin {
20 pub fn new(config: BrowserConfig) -> Self {
21 Self {
22 name: "plugin-browser".to_string(),
23 description: "Browser automation plugin".to_string(),
24 config,
25 service: None,
26 }
27 }
28
29 pub async fn init(&mut self) -> Result<(), String> {
30 info!("Initializing browser automation plugin");
31
32 self.config = BrowserConfig {
33 headless: env::var("BROWSER_HEADLESS")
34 .map(|v| v.to_lowercase() == "true")
35 .unwrap_or(true),
36 browserbase_api_key: env::var("BROWSERBASE_API_KEY").ok(),
37 browserbase_project_id: env::var("BROWSERBASE_PROJECT_ID").ok(),
38 openai_api_key: env::var("OPENAI_API_KEY").ok(),
39 anthropic_api_key: env::var("ANTHROPIC_API_KEY").ok(),
40 ollama_base_url: env::var("OLLAMA_BASE_URL").ok(),
41 ollama_model: env::var("OLLAMA_MODEL").ok(),
42 capsolver_api_key: env::var("CAPSOLVER_API_KEY").ok(),
43 server_port: env::var("BROWSER_SERVER_PORT")
44 .ok()
45 .and_then(|v| v.parse().ok())
46 .unwrap_or(3456),
47 };
48
49 let service = BrowserService::new(self.config.clone());
50 service.start().await?;
51 self.service = Some(Arc::new(service));
52
53 info!("Browser plugin initialized successfully");
54 Ok(())
55 }
56
57 pub async fn stop(&mut self) {
58 info!("Stopping browser automation plugin");
59 if let Some(service) = &self.service {
60 service.stop().await;
61 }
62 self.service = None;
63 }
64
65 pub async fn handle_action(
66 &self,
67 action_name: &str,
68 message: &str,
69 ) -> Result<ActionResult, String> {
70 let service = self
71 .service
72 .as_ref()
73 .ok_or("Browser service not initialized")?;
74
75 match action_name {
76 "BROWSER_NAVIGATE" => Ok(browser_navigate(Arc::clone(service), message).await),
77 "BROWSER_CLICK" => Ok(browser_click(Arc::clone(service), message).await),
78 "BROWSER_TYPE" => Ok(browser_type(Arc::clone(service), message).await),
79 "BROWSER_SELECT" => Ok(browser_select(Arc::clone(service), message).await),
80 "BROWSER_EXTRACT" => Ok(browser_extract(Arc::clone(service), message).await),
81 "BROWSER_SCREENSHOT" => Ok(browser_screenshot(Arc::clone(service), message).await),
82 _ => Err(format!("Unknown action: {}", action_name)),
83 }
84 }
85
86 pub async fn get_provider(&self, provider_name: &str) -> Result<serde_json::Value, String> {
87 let service = self
88 .service
89 .as_ref()
90 .ok_or("Browser service not initialized")?;
91
92 match provider_name {
93 "BROWSER_STATE" => {
94 let result = get_browser_state(Arc::clone(service)).await;
95 Ok(serde_json::json!({
96 "text": result.text,
97 "values": result.values,
98 "data": result.data,
99 }))
100 }
101 _ => Err(format!("Unknown provider: {}", provider_name)),
102 }
103 }
104}
105
106pub fn create_browser_plugin(config: Option<BrowserConfig>) -> BrowserPlugin {
107 BrowserPlugin::new(config.unwrap_or_default())
108}