Skip to main content
This page documents the praisonai-browser Python package and the unpacked developer extension that connects to its bridge server.It does not describe the PraisonAI Browser Agent published on the Chrome Web Store. That is a separate, standalone build: it runs entirely locally, makes no network requests, connects to no bridge or model, and requests six permissions with no host permissions. See chrome.praison.ai.
Control browser automation for AI agents directly from the CLI. Launch Chrome, navigate pages, take screenshots, run browser agents, and more.
This command group ships in the praisonai-browser package. Running it inside praisonai triggers auto-install via the ensure_praisonai_browser() bootstrap helper. You can also invoke the standalone entry point directly with praisonai-browser ….

Standalone Entry Point

The praisonai-browser console script mirrors every praisonai browser subcommand.
Inside the full wrapper the same commands work unchanged:

Commands


Doctor

Check browser health and configuration:

Doctor Extension

Check whether the Chrome extension is working. This command reports two independent signals — the bridge connection is ground truth, the CDP check is optional.
Two signals:
  1. Bridge connection (ground truth) — queries http://localhost:<server-port>/health and reads the extension_connections count. ✅ Extension connected to bridge (N connection(s)) means the extension is working, regardless of which Chrome profile it runs in.
  2. CDP :9222 (optional) — a service-worker check on the debug port. Shown as ℹ️ Extension not in CDP Chrome on port 9222 (normal for daily 'Work' Chrome). — this is info only and is not a failure on its own.
Exit codes: doctor extension exits 0 when the bridge shows at least one extension connection (regardless of the CDP result), and exits 1 only when the bridge shows zero extension connections.
extension_connections counts only clients whose WebSocket Origin starts with chrome-extension://. Servers older than PraisonAI #3115 don’t return this field; the CLI falls back to the total connections count in that case (slightly noisier, but still works).
Run praisonai browser doctor server before a session to confirm the bridge is up — this avoids the bridge-unreachable message on run.

Launch

Launch Chrome with the PraisonAI extension:
With a goal to execute:

Manual Load Fallback

Auto-load can fail silently on Chrome 137+ / Windows, which now blocks automated --load-extension. When the extension doesn’t connect, launch prints a manual “Load unpacked” recovery flow. The instructions differ by flag:
  • Default — the bridge is running, so it points you to curl http://127.0.0.1:<server-port>/health (expect extension_connections >= 1).
  • --no-server — no bridge was started, so it tells you to run praisonai browser start first, then verify with praisonai browser doctor extension.
With --no-server there is no bridge listening on port 8765, so a /health check will fail until you start the server. Start it first, then load the extension into your daily “Work” Chrome.

Run

Run a browser agent with a specific goal:
run fails fast: it checks the bridge, honours typed exit codes, and aborts a stalled session in 30 seconds instead of hanging silently.

Pre-flight check

run hits GET http://127.0.0.1:8765/health with a 3-second timeout before opening the WebSocket, so a missing bridge or extension fails in seconds instead of hanging on the full --timeout. Three failures land here: The “no extension” message lists four recovery steps: open Chrome with the PraisonAI extension and side panel, verify with curl http://127.0.0.1:8765/health (expect extension_connections >= 1), use the side panel or the CLI (not both), and — as a tip — use --engine cdp for extension-free automation.

Exit codes

run returns a stable exit code you can script against in CI, cron, or make targets. These codes apply to both normal and --debug runs, so 2 always means “fix the environment” and 1 always means “the prompt or page didn’t work out.”

First-step watchdog

When the server can’t confirm the task reached an extension, run aborts after 30 seconds if no automation step has appeared:
This maps to exit code 2. The watchdog applies only when delivery is unconfirmed — a confirmed run honours --timeout fully, so a slow first step from a cold browser or slow initial model call is legitimate. Steps that arrive right at the deadline are shown before the watchdog fires.

Verbose delivery indicator

Add -v to see whether the task reached an extension once the session starts:
If the server reports delivery as False, run fails fast with Extension automation did not start. (exit 2) instead of polling an empty session until timeout.

Retry & selector fallback (CDP / hybrid engines)

When a step fails, --max-retries N re-runs it up to N times, and the CDP agent tries three alternative-selector strategies before giving up on a step:
  1. Text-match — replaces the failing selector with one that matches the same visible text.
  2. Fallback-selector — swaps in a semantically equivalent selector (#login, [data-testid="login"], button[type="submit"], …).
  3. Click → navigate — if the target was a link, navigate to its href directly.
A step is considered failed when the injected JS reports the selector matched no element — for example:
Reachability: --engine cdp and --engine hybrid. Extension mode uses its own retry path.

Common failures

The bridge server is not running. Start it in a separate terminal, then verify:
The failing layer is the local bridge server on port 8765, not the site named in --url. This message replaces the raw WinError 1225 (Windows), errno 111 (Linux), and errno 61 (macOS) connection-refused errors, so those still land here when searched.
The bridge is up but no extension is attached. Open Chrome with the PraisonAI extension and side panel, then confirm the count:
For extension-free automation, use --engine cdp instead.
The side panel agent and the CLI can’t drive the same extension at once. run surfaces server errors with a friendly message and exits 2:
Stop the side panel run, then retry from the CLI. You can confirm the bridge is idle with:

Options

praisonai browser run accepts 14 options. Most only take effect on the CDP engine — see the Engine × Option matrix below for exactly which flag reaches the wire on each engine.

Engine × Option matrix

This is the crux of the #4313 fix. On the default extension engine only goal, model and max-steps reach the wire — the extension drives the tab you already have open in Chrome. Engine-only flags are now warned about (see Engine-only options warning) instead of silently discarded.

Which engine should I use?

Engine-only options warning

Starting with #4313, setting a CDP-only flag on the default extension engine is no longer a silent no-op. The CLI prints a yellow notice to the console listing exactly which flags were dropped, so you can catch a mistyped --engine immediately. On the extension engine, any of --vision, --screenshots, --record-video, --max-retries (when ≠ 3), --headless, --extension, --no-record triggers:
On the playwright or hybrid engines, any of --vision, --screenshots, --record-video, --max-retries (when ≠ 3), --no-record triggers:
Only the flags you actually set appear in the list, so the exact string depends on your invocation. Grep your terminal for Ignored on the to confirm whether a flag took effect.

Sample “Starting browser agent” output

On the extension path, run echoes the forwarded values before starting. As of #4313 this includes the per-session Max steps line and the context-only --url label:
--max-steps is now forwarded on the wire and honoured per-session by the bridge server. Previously the value you typed on run was silently replaced by the server default set at praisonai-browser start --max-steps; the server now reads message.get("max_steps", self.max_steps) and applies it for that session.

Video recording (CDP only)

--record-video captures the run to recording.webm. Reachable only on --engine cdp — on extension, playwright, and hybrid it is ignored with the warning above.
  • Output location. The file lands under the auto-created ~/.praisonai/browser_screenshots/<timestamp>/ directory, or under --screenshots <dir> if you pass one. The 📹 Recording to: … line only appears on the CDP engine.
  • Implicit vision → gpt-4o. --record-video currently implies enable_vision=True, so the model is upgraded to gpt-4o for the run. Billing note: expect gpt-4o pricing for a recorded run even if you passed a cheaper --model.

Examples


Two ways to start a session

praisonai browser run isn’t the only entry point — you can also start automation from the side panel inside Chrome. Only one at a time can drive the extension. The side panel opens its own extension-origin WebSocket to the bridge and sends start_session on it. The bridge treats that connection as the extension itself (rather than self-excluding it as “no extension available”), so a side-panel task no longer fails with NO_EXTENSION on a single-extension setup. While a side-panel session is running, /health reports extension_busy: true and active_session_id: <session_id>. A concurrent praisonai browser run in that state is rejected at the pre-flight check with:
Exit code 2. The reverse also holds: starting a side-panel run while run is active is rejected the same way.
Navigate a browser tab to a URL:

Screenshot

Capture a screenshot of the current page:
With options:
The single-action praisonai browser-tool screenshot (a separate command group, below) is the surface hardened by PR #4943 — it now guarantees bytes on disk when you pass --output and fails loudly if the tool returned no image data. See Single-action browser-tool commands.

Pages

List all open browser pages/tabs:

DOM

Get the DOM tree from a browser page:

Content

Read page content as text:

JS / Execute

Execute JavaScript in a browser page:

Sessions

List browser automation sessions:
Sessions end in one of completed, failed, stopped, or cancelled. cancelled covers mid-run disconnects (extension quit, CLI Ctrl-C, tab closed) — all four now stamp ended_at in the SQLite store, so sessions and history show accurate durations for interrupted runs.

History

Show step-by-step history for a session:

Examples

Web Scraping Workflow

Using Browser Agent

Browser Health Check


Chrome Management

Start Server

Chrome Subcommands

Extension Subcommands


Single-action browser-tool commands

praisonai browser-tool <action> is a lightweight command group that drives praisonai_tools.BrowserBaseTool for one-shot actions — status, open, navigate, snapshot, screenshot, click, type, and profiles. It is distinct from the agent-driven praisonai browser run above. As of PR #4943, these commands report success only when the action actually succeeded. BrowserBaseTool.run signals failure by returning a value (for example {"error": "Unknown action: click"}) rather than raising, so six of the eight subcommands used to print that value as Result: and exit 0 for work that never happened — screenshot --output even printed “saved” without ever opening the file. Every result now flows through a _require_success check and non-zero exit on failure.

Exit codes

As of PR #4943, every browser-tool subcommand exits non-zero on tool-level failure. Previously most exited 0 with an error string printed as the result. A 0 exit now means the action reported success.

Screenshot

Capture the current page. Without --output the result is printed; with --output <path> the image bytes are written to disk.
1

Minimal use

2

Guarantee bytes on disk with --output

The tool’s image data is extracted (raw bytes, base64, data: URI, or a file path it wrote) and written to <path>. If no image data comes back, the command fails loudly instead of printing a false “saved” line.
3

Pick an image format with --format

--format defaults to png; a non-default value is forwarded to the tool.
Failure mode before vs. after the fix:

Snapshot

Capture the page as text (--format aria default, or ai). With --output the text is written to a file.
When the underlying action fails, the command exits non-zero and does not write the error dict into the file as page text — the old behaviour that produced a “snapshot” file full of {'error': ...}.

Click, Type, and Navigate

An unknown action (for example a click an older tool build cannot honour) now exits non-zero with the tool’s error message, instead of printing {'error': 'Unknown action: click'} and exiting 0.

Status and Open

status --json emits a machine-readable object:
open --headless requests a headless browser; the flag reaches the tool (or is reported as unsupported).
Compatibility guarantee. Flags left at their defaults are not forwarded to BrowserBaseTool.run, so a praisonai-tools build with a narrower run() signature keeps working unchanged. Only a flag you actually set is forwarded — and if the installed tool cannot accept it, the command reports it as unsupported rather than silently dropping it.

Environment Variables


Bot CLI

Deploy messaging bots

Sandbox CLI

Sandbox container management