Repository navigation
Conversation
A `browser` tool drives the user's MindsHub browser instance (br-<hash>), a real Chromium the user watches and takes over beside the chat. It reads pages as numbered elements and acts on them by number. - run: the model states a goal plus values to type; Jev (/v1/decisions) picks each click, scroll and select. Anything below its confidence bar, a sign-in wall, or a step that would commit something goes back to the model or the user. browser_jev=shadow (default) only records Jev's picks against the model's; on lets it act; off never asks. - act/page/screenshot: single steps for the model. - hand_to_user: the user signs in or solves a CAPTCHA in the browser, then Jev checks they're signed in and the login is noted. - note_login: records the site in the browser profile and as a global profile memory. Never a credential. - open emits StreamBrowserSession with a viewer embed URL, so hosts can split the screen. Registered when the host passes ChatSessionConfig.browser (or the CLI sets ANTON_BROWSER_URL). The cloud pod reads TurnRequestV1.browser and allows the tool only then; the pod reaches the instance with its turn key. A built-in `browser` skill covers when to act, hand over and confirm. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he user Standalone services - BrowserConfig takes an optional `token` (a standalone service's BROWSER_SERVICE_TOKEN), kept out of repr. With a token the tool sends it instead of the MindsHub credential and needs no MindsHub connection. - Plain http is accepted only for localhost/127.0.0.1/[::1]. - CLI: ANTON_BROWSER_URL + ANTON_BROWSER_TOKEN. TurnRequestV1.browser may carry the token, the way `llm.api_key` already travels. - A refused standalone token points at the API key, not "reconnect MindsHub"; model-facing text no longer says "MindsHub browser". Human checks - page.human_check spots Cloudflare / reCAPTCHA / hCaptcha verification pages. open, page, act and run hand such a page to the user at once instead of returning it to the model to click. - Hand-overs switch the service to "your turn" (POST /sessions/:id/control) and back; Done in the browser viewer ends the hand-over too and retires the chat card. Best effort against services without the endpoint. - A 409 human_in_control from the service becomes a "wait for the user" outcome (browser_human_in_control, classified in root_cause). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
lucas-koontz
pushed a commit
to mindsdb/cowork-server
that referenced
this pull request
Oct 18, 2026
…nton (ENG-3298) The shared browser is a per-user MindsHub instance (br-<hash>) the agent drives while the user watches beside the chat. This is the server's half: - /browse/status, /browse/provision, /browse/embed replace the compat stub. Each calls MindsHub as the caller (hub_credential): the /instance lambda for status and provisioning, the instance worker's /_embed for a fresh one-hour viewer URL. Provisioning remembers the instance in browser_url. - browser_enabled (per user) turns it on. Then the desktop harness passes anton a BrowserConfig and web turns carry params.browser, so anton registers its browser tool. Neither carries a credential. - StreamBrowserSession becomes response.browser_session_opened on both paths (a pod's "browser" turn_step maps to the same event), so the renderer can split the chat and show the live viewer. anton-agent temporarily tracks mindsdb/anton#540's branch so this PR's environment runs the browser tool; it goes back to main before merge. Refs: ENG-3298 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A failed or no-op step usually means a modal, cookie banner or overlay is in the way, which the page list doesn't make obvious. Still on request only, never after every step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y for secrets - act takes drag, and x/y clicks (right, double) for canvas apps; x/y are pixels on the latest screenshot, which now says its size. - hand_to_user is for sign-ins, CAPTCHAs and payments only: when stuck, say so in the chat instead of giving the user the work. - Skill: for pictures in canvas apps, make the image and insert it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This adds the anton side of the shared browser (ENG-3188, ENG-3296).
The user's MindsHub browser instance (
br-<hash>, mindshub_services#239) is a real Chromium they watch beside the chat and can take over at any time. This PR gives anton abrowsertool to work in it with them.What the model gets
The tool is
browser, with these actions:openruninputsholds values to type, e.g.{"search": "MacBook Air"}.page,act,screenshot[17] button "Add to Cart"lines, takes one step, or returns an annotated image.hand_to_usernote_logincloseThe tool prompt and a new built-in
browserskill cover:Jev drives
runEach step is one
/v1/decisionscall. The newjev.decideis a generic sibling ofclassify, and it never raises. It asks four questions:next_action: one of 9 optionstarget: which element, from a shortlist of about 40, ranked by overlap with the goal and whether it's on screenneeds_userriskyAn
input_keyquestion is added wheninputsare given.What happens with each answer:
typeandselectonly use a value frominputs.browser_jev_min_p(default 0.8);risky≥ 0.5.browser_jevcontrols the rollout and defaults toshadow. In shadow,runonly reads the page and records Jev's pick. The model's nextactis compared against it and logged as thebrowser_jev_shadowevent (agree on action and target, plus both probabilities).onlets Jev act, andoffnever calls it.Wiring
ChatSessionConfig.browseris aBrowserConfig(base_url, profile="main"). When it's set, the tool is registered. Hosts set it; the CLI falls back toANTON_BROWSER_URL.minds_api_key. The worker accepts either for the instance's owner (mindshub_services#241).TurnRequestV1.browsercarries{base_url, profile}.browseronly when that field parses.StreamBrowserSessiongoes out on the wire as{"kind": "browser", ...}.StreamBrowserSession(session_id, view_url, expires_at)is emitted when the tool first opens the browser.view_urlis a one-hour embed URL from the worker's/_embed, so hosts can split the screen.browser_bad_input,browser_stale_element,browser_unauthorized,browser_unreachable,browser_error.Related PRs
browserthrough to the pod)response.browser_session_opened, and the split paneTesting
tests/test_browser_tool.py: 26 tests, run against a fake instance served throughhttpx.MockTransport, with a fake Jev and a fake elicitor. They cover:note_loginand the memory write;jev.decide, and the config and contract wiring.test_cloud_turn_processtests fail in my local environment, and the same five fail on a cleanstagingcheckout too.ruff checkpasses, anduv lock --checkis clean.🤖 Generated with Claude Code