9.6 KiB
Gemini ACP Adapter
This document records the verified local behavior of gemini --experimental-acp and the recommended adapter design for integrating Gemini into xworkmate-bridge as a single-agent ACP backend.
Goal
Keep the bridge semantics unchanged:
openclaw gatewaystays on gateway runtime forwardingcodex ACPstays a single-agent ACP backendopencode ACPstays a single-agent ACP backendgemini ACPis added as another single-agent ACP backend
Gemini should therefore be integrated through an adapter layer, not through the gateway runtime path.
Verified Local Findings
The local Gemini CLI binary supports an experimental ACP stdio mode:
gemini --experimental-acp
The bridge's current ACP RPC surface is not directly compatible with Gemini's ACP mode.
The following bridge-style methods were verified to be unsupported by Gemini ACP:
acp.capabilitiessession.starttools/list
Example response:
{"jsonrpc":"2.0","id":1,"error":{"code":-32601,"message":"\"Method not found\": acp.capabilities","data":{"method":"acp.capabilities"}}}
Gemini ACP does respond to initialize, and protocolVersion is required:
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1}}' \
| gemini --experimental-acp
Observed result:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": 1,
"authMethods": [
{
"id": "oauth-personal",
"name": "Log in with Google",
"description": null
},
{
"id": "gemini-api-key",
"name": "Use Gemini API key",
"description": "Requires setting the `GEMINI_API_KEY` environment variable"
},
{
"id": "vertex-ai",
"name": "Vertex AI",
"description": null
}
],
"agentCapabilities": {
"loadSession": false,
"promptCapabilities": {
"image": true,
"audio": true,
"embeddedContext": true
},
"mcpCapabilities": {
"http": true,
"sse": true
}
}
}
}
Conclusion
Gemini ACP is reachable over stdio JSON-RPC, but it does not expose the same RPC methods expected by xworkmate-bridge today.
This means Gemini should be connected behind a small ACP adapter that:
- speaks the bridge-facing ACP surface already used by
xworkmate-bridge - speaks Gemini's experimental ACP surface on stdio
Recommended Topology
xworkmate app / agent manager
-> xworkmate-bridge
-> external provider: gemini
-> gemini ACP adapter
-> stdio child process: gemini --experimental-acp
The adapter should be registered in bridge provider sync as an external ACP provider:
providerId: "gemini"label: "Gemini"endpoint: http://127.0.0.1:<port>/acp/rpcorws://127.0.0.1:<port>/acpenabled: true
xworkmate-bridge already supports this provider shape through xworkmate.providers.sync.
Adapter Responsibilities
The Gemini ACP adapter should own all protocol translation.
Bridge-facing side
Expose the same single-agent ACP methods the bridge already forwards:
acp.capabilitiessession.startsession.messagesession.cancelsession.close
Gemini-facing side
Launch one Gemini ACP stdio child process:
gemini --experimental-acp
Then initialize it first:
{
"jsonrpc": "2.0",
"id": "init-1",
"method": "initialize",
"params": {
"protocolVersion": 1,
"clientInfo": {
"name": "xworkmate-gemini-adapter",
"version": "0.1.0"
}
}
}
The adapter should cache the initialization result and derive bridge-side capability information from it.
Bridge-to-Gemini Mapping
The exact post-initialize Gemini method surface still needs to be enumerated. Until that discovery is finished, the adapter contract should be structured as follows.
acp.capabilities
Return a bridge-compatible synthesized response. Suggested response:
{
"singleAgent": true,
"multiAgent": false,
"providers": ["gemini"],
"capabilities": {
"single_agent": true,
"multi_agent": false,
"providers": ["gemini"]
},
"upstream": {
"protocolVersion": 1,
"promptCapabilities": {
"image": true,
"audio": true,
"embeddedContext": true
},
"mcpCapabilities": {
"http": true,
"sse": true
},
"authMethods": [
"oauth-personal",
"gemini-api-key",
"vertex-ai"
]
}
}
session.start
Suggested adapter behavior:
- Ensure Gemini stdio process is started
- Ensure
initializehas succeeded - Create adapter-local session state keyed by
sessionId - Translate the bridge prompt and metadata into the Gemini request format
- Return a bridge-compatible response envelope
If Gemini requires a different request method than bridge session.start, the translation should remain fully internal to the adapter.
session.message
Suggested adapter behavior:
- Reuse adapter-local session state
- Translate
taskPrompt, attachments, and working directory metadata as supported - Stream or collect Gemini output
- Repackage into the bridge's current single-agent result shape
session.cancel and session.close
Because Gemini reported loadSession: false, the first adapter version should assume sessions are adapter-local, not durable upstream sessions.
Recommended behavior:
session.cancel: cancel the current in-flight Gemini request or kill and restart the child process if fine-grained cancellation is unavailablesession.close: drop adapter-local state and optionally recycle the child process
Startup Configuration
Environment
At minimum, support these startup modes:
API key mode
export GEMINI_API_KEY=your_api_key
gemini --experimental-acp
OAuth mode
Use the Gemini CLI's own authenticated environment, then run:
gemini --experimental-acp
Vertex AI mode
Run Gemini CLI in an environment already configured for Vertex AI auth, then launch:
gemini --experimental-acp
Recommended adapter process contract
Example adapter startup:
./build/bin/xworkmate-go-core gemini-acp-adapter \
--listen 127.0.0.1:8791 \
--gemini-bin /opt/homebrew/bin/gemini \
--gemini-args="--experimental-acp"
Recommended adapter environment:
XWORKMATE_GEMINI_BIN=/opt/homebrew/bin/gemini
XWORKMATE_GEMINI_ARGS=--experimental-acp
XWORKMATE_GEMINI_INIT_PROTOCOL_VERSION=1
The implemented adapter exposes:
POST /acp/rpcGET /acpWebSocket ACP
Supported adapter methods:
acp.capabilitiessession.startsession.messagesession.cancelsession.closegemini.initializegemini.raw
session.start and session.message now use a compatibility layer by default:
- the adapter still initializes Gemini ACP first so
acp.capabilitiesremains grounded in the real upstream ACP surface - if
GEMINI_ADAPTER_UPSTREAM_METHODis unset, session traffic runs through adapter-local prompt mode - the adapter keeps session-local history keyed by
sessionId session.startresets adapter-local history for that sessionsession.messagereplays prior user turns plus the new turn as one prompt to the Gemini CLI- the adapter returns a bridge-compatible single-agent payload with
output,provider,mode, andupstreamMethod: "prompt" session.closedrops adapter-local state
This default exists because the verified Gemini ACP upstream did not expose bridge-compatible session.start / session.message methods during testing.
If Gemini ACP later gains a compatible conversation method, you can override the forwarded method name with:
export GEMINI_ADAPTER_UPSTREAM_METHOD=your-discovered-gemini-method
Bridge Provider Sync Example
Once the adapter is running, register it as a normal external provider:
{
"jsonrpc": "2.0",
"id": "providers-sync-1",
"method": "xworkmate.providers.sync",
"params": {
"providers": [
{
"providerId": "gemini",
"label": "Gemini",
"endpoint": "http://127.0.0.1:8791/acp/rpc",
"enabled": true
}
]
}
}
Example local startup and sync flow:
./build/bin/xworkmate-go-core gemini-acp-adapter \
--listen 127.0.0.1:8791 \
--gemini-bin /opt/homebrew/bin/gemini \
--gemini-args="--experimental-acp"
Then sync this provider into the bridge:
{
"jsonrpc": "2.0",
"id": "providers-sync-gemini",
"method": "xworkmate.providers.sync",
"params": {
"providers": [
{
"providerId": "gemini",
"label": "Gemini",
"endpoint": "http://127.0.0.1:8791",
"enabled": true
}
]
}
}
Recommended First Implementation Scope
The first adapter milestone should stay intentionally small:
- Start
gemini --experimental-acp - Send
initialize - Expose bridge-compatible
acp.capabilities - Translate one synchronous prompt path for
session.startandsession.message - Return bridge-compatible
output,provider,mode, andturnId
Do not block the first version on:
- durable upstream session restore
- multimodal attachment parity
- complex streaming semantics
- full cancellation fidelity
Next Validation Tasks
Before implementing the adapter, enumerate Gemini's post-initialize callable methods and request schema.
Recommended next probes:
- inspect whether Gemini sends notifications after
initialize - test likely conversation methods after
initialize - determine whether the protocol requires explicit auth selection or out-of-band auth only
- verify whether one process supports multiple sequential requests safely
- verify whether one process supports concurrent requests or must be serialized