Refine host browser routing and settings copy
Some checks are pending
Build And Publish Docker Images / plan (push) Waiting to run
Build And Publish Docker Images / build (push) Blocked by required conditions

Store and surface host-browser preparation and CDP endpoint metadata from A0 CLI.

Let Browser runtime prepare candidate CLIs before the first action, and keep host-required errors more actionable.

Simplify Host Browser settings language and document the Chrome remote-debugging consent flow.
This commit is contained in:
Alessandro 2026-05-08 06:37:32 +02:00
parent 4b3e2eb327
commit d47207dfd7
7 changed files with 155 additions and 37 deletions

View file

@ -328,7 +328,8 @@ class ConnectorBrowserRuntime:
for status in statuses:
parts.append(
f"sid={status.get('sid')} status={status.get('status')} "
f"supported={status.get('supported')} enabled={status.get('enabled')} "
f"supported={status.get('supported')} can_prepare={status.get('can_prepare')} "
f"enabled={status.get('enabled')} "
f"reason={status.get('support_reason') or 'none'}"
)
return "; ".join(parts)

View file

@ -59,7 +59,8 @@ def _host_browser_status_detail(context_id: str) -> str:
for status in statuses:
parts.append(
f"sid={status.get('sid')} supported={status.get('supported')} "
f"enabled={status.get('enabled')} status={status.get('status') or 'unknown'} "
f"can_prepare={status.get('can_prepare')} enabled={status.get('enabled')} "
f"status={status.get('status') or 'unknown'} "
f"reason={status.get('support_reason') or 'none'}"
)
return "; ".join(parts)

View file

@ -52,6 +52,32 @@ function normalizeBoolean(value, fallback = true) {
return fallback;
}
function hostBrowserFamilyLabel(value) {
const family = String(value || "").trim().toLowerCase();
const a0Profile = family.endsWith("-a0");
const remoteDebugging = family.endsWith("-cdp");
const base = a0Profile ? family.slice(0, -3) : remoteDebugging ? family.slice(0, -4) : family;
const labels = {
chrome: "Chrome",
chromium: "Chromium",
edge: "Edge",
"edge-dev": "Edge Dev",
};
const label = labels[base] || "Host browser";
if (remoteDebugging) return `${label} (allowed)`;
return a0Profile ? `${label} (A0 profile)` : label;
}
function hostBrowserStatusLabel(value) {
const status = String(value || "").trim().toLowerCase();
if (status === "active") return "open";
if (status === "ready") return "ready";
if (status === "disabled") return "will open on first use";
if (status === "relaunch_required") return "close browser and retry";
if (status === "unsupported") return "unavailable";
return status || "ready";
}
export const store = createStore("browserConfig", {
config: null,
extensionsList: [],
@ -96,16 +122,16 @@ export const store = createStore("browserConfig", {
runtimeBackendLabel() {
const value = this.config?.runtime_backend || "container";
if (value === "host_when_available") return "Host When Available";
if (value === "host_required") return "Host Required";
return "Container";
if (value === "host_when_available") return "Use Host When Ready";
if (value === "host_required") return "Require Host Browser";
return "Docker Browser";
},
privacyPolicyLabel() {
const value = this.config?.host_browser_privacy_policy || "enforce_local";
if (value === "warn") return "Warn";
if (value === "warn") return "Warn When Using Cloud";
if (value === "allow") return "Allow";
return "Enforce Local";
return "Local Models Only";
},
async loadHostBrowserStatus() {
@ -127,12 +153,13 @@ export const store = createStore("browserConfig", {
: [];
const active = connectors.find((item) => item?.supported && item?.enabled);
if (active) {
const family = active.browser_family || "browser";
const profile = active.profile_label ? ` / ${active.profile_label}` : "";
return `${family}${profile}: ${active.status || "ready"}`;
const profile = active.profile_label ? ` - ${active.profile_label}` : "";
return `${hostBrowserFamilyLabel(active.browser_family)}${profile}: ${hostBrowserStatusLabel(active.status)}`;
}
if (connectors.length) return "A0 CLI connected, host browser disabled or unavailable";
return "Waiting for A0 CLI";
const preparable = connectors.find((item) => item?.can_prepare || item?.supported);
if (preparable) return "A0 CLI connected - browser will open on first use";
if (connectors.length) return "A0 CLI connected - host browser unavailable";
return "Connect A0 CLI to use a host browser";
},
hasPaths() {

View file

@ -53,27 +53,27 @@
<div class="browser-config-card">
<div class="section-title">Host Browser</div>
<div class="section-description">
Route the existing Browser tool through A0 CLI. When host mode is selected, the first browser action can prepare the local browser automatically.
Use Chrome, Edge, or Chromium on this computer. Keep A0 CLI connected; the browser opens when the agent first needs it.
</div>
<label class="browser-config-field">
<span class="browser-config-field-label">Backend mode</span>
<span class="browser-config-field-label">Browser location</span>
<select x-model="$store.browserConfig.config.runtime_backend">
<option value="container">Container</option>
<option value="host_when_available">Host when available</option>
<option value="host_required">Host required</option>
<option value="container">Docker browser</option>
<option value="host_when_available">Use host when ready</option>
<option value="host_required">Require host browser</option>
</select>
<span class="browser-config-field-help">The WebUI setting is the routing intent; CLI browser commands are available for diagnostics and manual override.</span>
<span class="browser-config-field-help">Require host browser when pages must stay on this computer.</span>
</label>
<label class="browser-config-field">
<span class="browser-config-field-label">Host content policy</span>
<span class="browser-config-field-label">Page content access</span>
<select x-model="$store.browserConfig.config.host_browser_privacy_policy">
<option value="enforce_local">Enforce local</option>
<option value="warn">Warn</option>
<option value="enforce_local">Local models only</option>
<option value="warn">Warn when using cloud</option>
<option value="allow">Allow</option>
</select>
<span class="browser-config-field-help">Local-model enforcement applies before host page content or screenshots are returned to the agent.</span>
<span class="browser-config-field-help">Controls page text and screenshots from the host browser.</span>
</label>
<div class="browser-config-note">