Repository navigation
feat: opencode, gemini cli and cursor agent run structured too, through the agent client protocol - #80
Merged
Conversation
…gh the agent client protocol A generic ACP driver (internal/box/acpdriver.go) runs any agent whose preset says how it speaks the Agent Client Protocol (AgentPreset.ACP: opencode "acp", gemini "--acp", cursor-agent "acp"; a repository's own agent can have one) under `berthd agent-host`: - it opens the session: initialize, then session/resume or session/load with the conversation's id when it is carried on, else session/new, calling authenticate first when the agent asks for it (Cursor Agent) - prompts are session/prompt, whose answer is the turn's end; Stop is session/cancel - the agent's own modes (its mode config option, or session/set_mode) are offered with bypass beside them - permission requests come to the chat as Allow / Always allow / Deny, picked by option kind since each agent names them its own way; bypass has berthd allow them, and opencode is started asking so that it does - what else it asks of its client gets an error; streamed chunks make the draft and, gathered, the reply in the conversation (internal/transcript/acphost.go), with a tool's label updated once the agent says what it runs Boxes list driver.acp; sessions and tasks take driver: "acp". The Labs switch starts these agents structured too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully 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.
Stacked on #79 (base
codex-driver), which is stacked on #78. Merge in order: #78, #79, then this one. GitHub retargets each tomainas the one below merges.Phase 6 of
design/structured-agents/plan.md: a generic ACP driver, behind the same Labs switch (Structured agents).Driver (
internal/box/acpdriver.go, capabilitydriver.acp)Which agents: any agent whose preset has the new
acpfield, meaning what follows its command to start its ACP server. Built-ins:opencode acpgemini --acp(--experimental-acpis deprecated)cursor-agent acp(works, but isn't in its--help)A repo's
.berth/config.jsoncan give its own agent one, or add one to a built-in by id. That makes the driver config-driven.Opening a session:
initialize, thensession/resumewhen the agent advertises it,session/loadwhen it can load, elsesession/newauthenticatewith the advertised method when the agent says auth is required (Cursor Agent, which uses its existing login)session/set_config_option, and a non-bypass mode is set the same wayTurns:
session/promptis written without waiting, because its answer is the turn's end (stopReason:end_turn, orcancelled→ interrupted, or an error → error). Stop issession/cancel.Modes: the agent's own (its
modeconfig option, ormodeswithsession/set_mode), plusbypassPermissions, where berthd answers.Permissions:
session/request_permissiongivesask.choices, picked by option kind (allow_once,allow_always,reject_once), because ids differ per agent (opencodeonce, Cursorallow-once). opencode allows everything unless told otherwise, so it starts withOPENCODE_CONFIG_CONTENTasking for bash, edit and webfetch, and bypass is berthd answering.Anything else the agent asks (
fs/*,terminal/*,cursor/create_plan) gets a JSON-RPC error. berthd advertises neither fs nor terminal, so agents use their own tools.Conversation (
internal/transcript/acphost.go):session/promptconv.retitle)session/loadare skipped, because they're already in the logResume and the conversation list (feat: a structured claude agent's conversation can be resumed, after its agent ends or its session is gone #78) work for ACP conversations:
relaunchpicks the preset frommeta.json.App
startWorkpassesdriver: "acp"for a pick whose preset hasacp, on boxes listingdriver.acp. With Ask it starts in the agent's own default mode. These sessions open as conversations. The Labs text names the agents. Also covered: config reference (acp), Labs guide, app API and changelog.Tests
TestAStructuredACPSessionIsDrivenThroughItsProtocol, with a stand-in agent (python3) following the recorded opencode and Cursor messages:session/resume-race.TestAStructuredACPSessionsLogReadsAsItsConversationuses a recorded, anonymised opencode log.TestALiveACPSessionWorks(opt-inBERTH_LIVE_ACP=<preset>,BERTH_LIVE_ACP_MODEL) passed locally against real opencode (opencode/big-pickle, 5.5s) and real Cursor Agent (13.6s, through its authenticate step). Gemini wasn't run because it isn't logged in here.go test -race ./...,go vet ./..., app checks and build,tsc -p e2eand the docs build all pass.That completes phases 0–6. What's left is phase 7 (flows and headless runs onto the drivers) and phase 8 (turning it on by default).
🤖 Generated with Claude Code