Skip to content

refactor(host-browser): retire HOST_BROWSER_INTERFACE_PREFERENCE#30201

Merged
noanflaherty merged 2 commits into
mainfrom
credence/host-browser-pref-retire
May 10, 2026
Merged

refactor(host-browser): retire HOST_BROWSER_INTERFACE_PREFERENCE#30201
noanflaherty merged 2 commits into
mainfrom
credence/host-browser-pref-retire

Conversation

@credence-the-bot
Copy link
Copy Markdown
Contributor

@credence-the-bot credence-the-bot Bot commented May 10, 2026

Drops the chrome-extension-first interface preference from HostBrowserProxy and removes the now-unused getPreferredClientByCapability method on the event hub. Auto-resolution now picks the most-recently-active host_browser client (lastActiveAt-desc), matching the rest of the host-tool family.

Why

Pre-#30066, HOST_BROWSER_INTERFACE_PREFERENCE = ["chrome-extension", "macos"] was the only way for the proxy to pick a transport when a user had both connected. After #30066, the LLM can pin a transport via target_client_id. The hardcoded preference is now arbitrary tech debt — every other host-tool capability (host_bash, host_file_*, host_cu, host_app_control) auto-resolves by lastActiveAt-desc and lets target_client_id do the override work.

This was the second of the two "skip unless they bite" items from the cross-client host tool arc. Lands alongside #30200 (target_client_id for app_control_*) which is the first.

Behavior change

When a user has both Chrome Extension and macOS host_browser clients connected:

  • Before. Routed to the Chrome Extension by hardcoded preference.
  • After. Routes to whichever client was active most recently.

The LLM-facing target_client_id override (#30066) is the supported way to pin a specific transport — that's what it's for. Single-client setups (the common case) are unaffected.

What changed

  • assistant/src/daemon/host-browser-proxy.ts — Delete HOST_BROWSER_INTERFACE_PREFERENCE constant. resolveTargetClient simplifies to listClientsByCapability(...)[0] for the no-actor branch and listClientsByCapability(...).find(c => c.actorPrincipalId === sourceActorPrincipalId) for the same-actor branch. isAvailable() switches to getMostRecentClientByCapability("host_browser").
  • assistant/src/runtime/assistant-event-hub.ts — Delete the unused getPreferredClientByCapability method (the only caller was HostBrowserProxy).
  • assistant/src/__tests__/host-browser-proxy.test.ts — Drop the getPreferredClientByCapability mock and mockHasConnection flag; consolidate on mockClients. Rewrite the "prefers chrome-extension" and "regression guard" tests to assert the new lastActiveAt-desc semantics. 27/27 tests pass.

Verification

  • bun test src/__tests__/host-browser-proxy.test.ts → 27/27 pass
  • bun run lint on changed files → clean
  • bun run typecheck → no new errors (pre-existing failures in packages/ces-client and packages/service-contracts are unrelated to this PR)

Open in Devin Review

@credence-the-bot
Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 1 additional finding in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚩 Stale JSDoc on request() still references removed "interface-preference resolution"

The request() method's JSDoc at assistant/src/daemon/host-browser-proxy.ts:138-140 still says "falls back to interface-preference resolution without an actor filter" but the underlying resolveTargetClient now simply returns candidates[0] (most-recently-active). This comment was not updated alongside the implementation change and now describes behavior that no longer exists. The assistant/AGENTS.md rule states: "When writing or updating comments, do not reference code that has been removed." Two other files also have stale references: factory.ts:102 and extension-cdp-client.ts:56 both mention "interface-preference order" in their targetClientId JSDoc comments.

(Refers to lines 138-140)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Drops the chrome-extension-first interface preference from
HostBrowserProxy and removes the now-unused
`getPreferredClientByCapability` method on the event hub.

Auto-resolution now picks the most-recently-active host_browser
client (lastActiveAt-desc), matching the host_bash / host_file_* /
host_cu / host_app_control family. When the LLM needs a specific
transport (e.g. Chrome Extension's `chrome.debugger` over the
macOS CDP bridge), it can pass `target_client_id` explicitly via
the LLM-facing param shipped in #30066.

Behavior change: when a user has both Chrome Extension and macOS
clients connected, host_browser previously routed to the Chrome
Extension by hardcoded preference. It now routes to whichever
client was active most recently. The LLM-facing `target_client_id`
override (#30066) is the supported way to pin a transport.

Closes the last item from the cross-client host tool tech-debt
list. Was deferred per 'skip unless they bite' alongside the
app_control `target_client_id` LLM-param work; lands together with
PR #30200.
Devin caught three JSDoc blocks still referencing 'interface-
preference order/resolution' after the constant was deleted:

- HostBrowserProxy.request() — described the no-actor fallback
  as 'interface-preference resolution'; now matches the resolver
  ('most-recently-active host_browser client').
- extension-cdp-client.ts — targetClientId JSDoc.
- factory.ts — targetClientId JSDoc.

Also dropped a history-style comment in the test ('chrome-
extension preference was retired now that LLMs can pick…') —
code-comments rule is current-state only.

Tests still 27/27. Lint clean.
@credence-the-bot credence-the-bot Bot force-pushed the credence/host-browser-pref-retire branch from 312e13c to 8846582 Compare May 10, 2026 17:17
@credence-the-bot
Copy link
Copy Markdown
Contributor Author

Thanks @devin-ai-integration — fixed in 8846582. Three JSDoc blocks updated (host-browser-proxy.ts:138-140 request(), extension-cdp-client.ts:56, factory.ts:102) plus a history-style comment cleaned up in the test file. Tests still 27/27, lint clean. @devin review

@noanflaherty noanflaherty merged commit 17c227f into main May 10, 2026
13 checks passed
@noanflaherty noanflaherty deleted the credence/host-browser-pref-retire branch May 10, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant