Repository navigation
feat(agents): cdp-config/v1 hands an agent the CDP endpoints it drives - #440
Merged
earakely-scale merged 3 commits intoNov 2, 2026
Merged
earakely-scale merged 3 commits into
earakely-scale merged 3 commits into
Conversation
An agent that drives a browser itself lists CDP_CONFIG_V1. The SDK serves add (adding a name again replaces it), list (header values hidden) and remove at /ext/cdp-config, and passes the endpoints to every turn as TaskRequest.cdp_endpoints. request.cdp_endpoint(name=None) returns the named or only endpoint and otherwise fails the turn as an infra_error (cdp.no_endpoint, cdp.ambiguous), so an agent never falls back to a browser of its own. TaskFailed is the exception behind it: raised in run(), it ends the turn as TaskResult.failure would. agent-env knows the extension as A2AAgent.EXT_CDP_CONFIG. Nothing adds endpoints yet; browser_connect_cdp does that next. FD-4948 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…with a bad port urlsplit accepts http://:8080/ and ws://browser.test:abc/ with a netloc, so add stored addresses no client could connect to. FD-4948 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ure stays private - list returns each endpoint's has_headers and metadata only. An agentenv address carries its credential in the URL, so hiding headers alone hid nothing that matters. - TaskFailed becomes the private _TaskFailed: only cdp_endpoint raises it, so the protocol gains no public way to fail a turn yet. The docs say to call cdp_endpoint before an exception handler that catches everything. - AGENTS.md no longer says agent-env sends endpoints: nothing does until the browser_connect_cdp task step. FD-4948 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
deleted the
edgararakelyan/fd-4948-m81-cdp-configv1-in-the-agent-sdk
branch
November 2, 2026 17:33
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.
What and why
An agent that drives a browser itself, such as Browser Use (#378) or Stagehand, needs a CDP address from the task, and should fail if the task gives none rather than reaching for a browser of its own. This adds the agent side of that:
cdp-config/v1, built the waymcp-config/v1is. It is M8.1 of the website browser design (FD-4948).CDP_CONFIG_V1at/ext/cdp-config, with no card params. The SDK implements all three operations:add{name, http_url, ws_url, headers?, metadata?}list{"cdp_endpoints": {name: {has_headers, metadata}}}. It shows neither the URLs nor the header values: an agentenv address carries its credential in the URL.remove{name}absent, not an error.chromiumandchromium-buyerboth work.http_urlmust be an absolutehttp(s)URL andws_urlan absolutews(s)URL, each with a host and, if it gives one, a valid port.Every turn gets the endpoints as
TaskRequest.cdp_endpoints, headers included, as a detached copy.request.cdp_endpoint(name=None)returns the named endpoint, or the only one. Anything else fails the turn as aninfra_error:cdp.no_endpointwhen there is none, or none by that name;cdp.ambiguouswhen there are several and no name.It fails the turn by raising a private exception, which the executor turns into
TaskResult.failure, streaming or not. The protocol gains no public way to fail a turn. The docs say to callcdp_endpoint()before any handler of the agent's own that catches every exception. Any other exception still becomes the opaqueframework.unhandled_exception.agent-env knows the extension as
A2AAgent.EXT_CDP_CONFIG, and the card check logs whether an agent advertises it.Docs: a
cdp-config/v1section inagents/AGENTS.md, which says nothing in agent-env sends endpoints yet, and the wire contract in the protocol README.Nothing adds endpoints yet.
browser_connect_cdp(M8.17) does that, and the Browser Use change is M8.18. No shipped agent lists the extension in this PR.Choices to confirm in review:
infra_error, not anagent_error. The run couldn't happen, and it isn't the agent's fault. Benchmark results shouldn't count it as the agent scoring 0.removeis a DELETE with a JSON body, as the design's sketch has it. The route reads a body for any method but GET.How it was tested
make lint: clean.pytest tst/unit packages/agentenv-protocol/tests -n auto): 12,471 passed, 66 skipped.test_a2a_cdp_config.py:listbut passed to the turn;add,listandremoveto their methods and path.CDP_CONFIG_V1and drives the turn's endpoint with Playwright 1.52connect_over_cdp.DockerImageArtifact.put,A2AAgent.put,deploy.send_a2a_message,poll_a2a_taskandTerminalResponse, the pathprompt_agentuses./ext/cdp-config.infra_error,cdp.no_endpoint.add, the turn opens the page in Chromium and reads its title: once byhttp_url, once byws_url.chromiumagain with another address replaces it, and the next turn uses the new one.cdp.ambiguous, and an unknown name failscdp.no_endpoint. A named turn reaches its endpoint with its headers, whilelistshows neither URLs nor header values.httpws_url, a bad name,http://:8080/and a non-numeric port get 400s.remove, removing again (absent), an emptylist, and the turn fails closed again.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no new actionable issues were found.Summary
Adds
cdp-config/v1so agents can use registered browser endpoints.Since the previous review, listing hides URLs and the failure exception is private. The earlier URL-validation finding is fixed: addresses need a host and a valid port.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A["POST /ext/cdp-config"] --> B["Registered endpoints"] B --> C["GET: names, metadata, has_headers"] B --> D["TaskRequest: full detached copy"] D --> E{"cdp_endpoint(name)"} E --> F["Selected browser endpoint"] E --> G["Missing or ambiguous: infra_error"]Reviews (3) · Last reviewed commit: "refactor(agents): cdp-config/v1 list sho..." · Reviewed by Greptile