Add camofox-browser integration: gyandoot-browser crate + agent tools

New crate: crates/gyandoot-browser/
  - client.rs: Full REST client for camofox-browser API (health, tabs,
    navigation, snapshots, click/type/scroll, search macros)
  - macros.rs: 14 SearchMacro enum (Google, YouTube, Amazon, Reddit,
    Wikipedia, Twitter, Yelp, Spotify, Netflix, LinkedIn, Instagram,
    TikTok, Twitch) with parse/display
  - snapshot.rs: PageSnapshot, PageLinks, NavigationResult, HealthResponse
  - session.rs: BrowserSession, SessionManager with idle cleanup

New module: crates/gyandoot-agent/src/browser_tools.rs
  - WebSearchTool: Search the web using anti-detection browser
  - WebBrowseTool: Browse URLs, click, type, scroll with element refs
  - register_browser_tools(): Wire both tools into ToolExecutor

CLI: Added
                                 o
                                 |
               - - - - - -     .---.     - - - - - -
          - - - - - - - - -  [ ^   ^ ]  - - - - - - - - -
             - - - - - - -   |  ___  |   - - - - - - -
                              `-----'
           ____ __   __  ___   _   _  ____   ___   ___  _____
          / ___|\ \ / / / _ \ | \ | ||  _ \ / _ \ / _ \|_   _|
         | |  _  \ V / / /_\ \|  \| || | | | | | | | | | | |
         | |_| |  | |  |  _  || |\  || |_| | |_| | |_| | | |
          \____/  |_|  |_| |_||_| \_||____/ \___/ \___/  |_|

        o - - - - - - -  knowledge. delivered. - - - - - - - o

Unknown command: browser
Run 'gyandoot help' for usage. subcommand with health/search/browse actions

Installer: Updated install.sh with camofox-browser cloning, Node.js
detection, npm dependency install, and systemd service setup

Camofox-browser running at http://localhost:9377 (Docker, verified working)

Workspace: 12 crates + CLI binary — cargo check passes with 0 errors.
This commit is contained in:
2026-06-11 20:23:35 +05:30
parent 851c838ca5
commit 605747023b
13 changed files with 1578 additions and 5 deletions

View File

@@ -63,6 +63,12 @@ enum Commands {
#[command(subcommand)]
action: MemoryAction,
},
/// Browser commands (camofox anti-detection browser)
#[command(name = "browser")]
Browser {
#[command(subcommand)]
action: BrowserAction,
},
}
#[derive(Subcommand, Debug)]
@@ -85,6 +91,25 @@ enum MemoryAction {
Export { path: PathBuf },
}
#[derive(Subcommand, Debug)]
enum BrowserAction {
/// Check camofox-browser health
Health,
/// Search the web using anti-detection browser
Search {
/// Search query
query: String,
/// Site to search (google, youtube, reddit, wikipedia, etc.)
#[arg(short = 's', long = "site", default_value = "google")]
site: String,
},
/// Browse a URL using anti-detection browser
Browse {
/// URL to visit
url: String,
},
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli = Cli::parse();
@@ -121,6 +146,9 @@ async fn main() -> anyhow::Result<()> {
Some(Commands::Memory { action }) => {
cmd_memory(action).await?;
}
Some(Commands::Browser { action }) => {
cmd_browser(action).await?;
}
None => {
// Default: run interactive CLI mode
cmd_run(&cli.profile, "cli", None).await?;
@@ -285,4 +313,48 @@ async fn cmd_memory(action: MemoryAction) -> anyhow::Result<()> {
}
}
Ok(())
}
/// Handle browser commands (camofox anti-detection browser)
async fn cmd_browser(action: BrowserAction) -> anyhow::Result<()> {
use gyandoot_browser::BrowserClient;
use gyandoot_agent::browser_tools::{WebSearchTool, WebBrowseTool};
use gyandoot_agent::tools::Tool;
let client = BrowserClient::new();
match action {
BrowserAction::Health => {
match client.health().await {
Ok(health) => {
println!("✅ Camofox Browser — Health OK");
println!(" Engine: {}", health.engine);
println!(" Browser connected: {}", health.browser_connected);
println!(" Active tabs: {}", health.active_tabs);
println!(" Active sessions: {}", health.active_sessions);
}
Err(e) => {
eprintln!("❌ Camofox not reachable: {}", e);
eprintln!(" Start with: cd ~/camofox-browser && npm start");
}
}
}
BrowserAction::Search { query, site } => {
let tool = WebSearchTool::new(client);
let args = serde_json::json!({"query": query, "site": site});
match tool.execute(args).await {
Ok(result) => println!("{}", result),
Err(e) => eprintln!("Search failed: {}", e),
}
}
BrowserAction::Browse { url } => {
let tool = WebBrowseTool::new(client);
let args = serde_json::json!({"url": url});
match tool.execute(args).await {
Ok(result) => println!("{}", result),
Err(e) => eprintln!("Browse failed: {}", e),
}
}
}
Ok(())
}