mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 18:00:54 +00:00
test: add Droid ACP bind Docker lane
This commit is contained in:
@@ -56,6 +56,9 @@ Docs: https://docs.openclaw.ai
|
|||||||
- Providers/LiteLLM: register `litellm` as an image-generation provider so `image_generate model=litellm/...` calls and `agents.defaults.imageGenerationModel.fallbacks` entries resolve through the LiteLLM proxy. Thanks @zqchris.
|
- Providers/LiteLLM: register `litellm` as an image-generation provider so `image_generate model=litellm/...` calls and `agents.defaults.imageGenerationModel.fallbacks` entries resolve through the LiteLLM proxy. Thanks @zqchris.
|
||||||
- Codex harness: require Codex app-server `0.125.0` or newer and cover native MCP `PreToolUse`, `PostToolUse`, and `PermissionRequest` payloads through the OpenClaw hook relay.
|
- Codex harness: require Codex app-server `0.125.0` or newer and cover native MCP `PreToolUse`, `PostToolUse`, and `PermissionRequest` payloads through the OpenClaw hook relay.
|
||||||
- Agents/Codex: teach prompts and `agents_list` to surface native Codex app-server availability so agents prefer `/codex ...` over Codex ACP unless ACP/acpx is explicit. Thanks @vincentkoc.
|
- Agents/Codex: teach prompts and `agents_list` to surface native Codex app-server availability so agents prefer `/codex ...` over Codex ACP unless ACP/acpx is explicit. Thanks @vincentkoc.
|
||||||
|
- ACPX/Droid: add Factory Droid to the live ACP bind Docker matrix, including
|
||||||
|
`.factory` settings staging, `FACTORY_API_KEY` forwarding, and the single-agent
|
||||||
|
`test:docker:live-acp-bind:droid` recipe.
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
|
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ Notes:
|
|||||||
- Overrides:
|
- Overrides:
|
||||||
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
|
- `OPENCLAW_LIVE_ACP_BIND_AGENT=claude`
|
||||||
- `OPENCLAW_LIVE_ACP_BIND_AGENT=codex`
|
- `OPENCLAW_LIVE_ACP_BIND_AGENT=codex`
|
||||||
|
- `OPENCLAW_LIVE_ACP_BIND_AGENT=droid`
|
||||||
- `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini`
|
- `OPENCLAW_LIVE_ACP_BIND_AGENT=gemini`
|
||||||
- `OPENCLAW_LIVE_ACP_BIND_AGENT=opencode`
|
- `OPENCLAW_LIVE_ACP_BIND_AGENT=opencode`
|
||||||
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
|
- `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini`
|
||||||
@@ -250,6 +251,7 @@ Single-agent Docker recipes:
|
|||||||
```bash
|
```bash
|
||||||
pnpm test:docker:live-acp-bind:claude
|
pnpm test:docker:live-acp-bind:claude
|
||||||
pnpm test:docker:live-acp-bind:codex
|
pnpm test:docker:live-acp-bind:codex
|
||||||
|
pnpm test:docker:live-acp-bind:droid
|
||||||
pnpm test:docker:live-acp-bind:gemini
|
pnpm test:docker:live-acp-bind:gemini
|
||||||
pnpm test:docker:live-acp-bind:opencode
|
pnpm test:docker:live-acp-bind:opencode
|
||||||
```
|
```
|
||||||
@@ -258,8 +260,9 @@ Docker notes:
|
|||||||
|
|
||||||
- The Docker runner lives at `scripts/test-live-acp-bind-docker.sh`.
|
- The Docker runner lives at `scripts/test-live-acp-bind-docker.sh`.
|
||||||
- By default, it runs the ACP bind smoke against the aggregate live CLI agents in sequence: `claude`, `codex`, then `gemini`.
|
- By default, it runs the ACP bind smoke against the aggregate live CLI agents in sequence: `claude`, `codex`, then `gemini`.
|
||||||
- Use `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini`, or `OPENCLAW_LIVE_ACP_BIND_AGENTS=opencode` to narrow the matrix.
|
- Use `OPENCLAW_LIVE_ACP_BIND_AGENTS=claude`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=codex`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=droid`, `OPENCLAW_LIVE_ACP_BIND_AGENTS=gemini`, or `OPENCLAW_LIVE_ACP_BIND_AGENTS=opencode` to narrow the matrix.
|
||||||
- It sources `~/.profile`, stages the matching CLI auth material into the container, then installs the requested live CLI (`@anthropic-ai/claude-code`, `@openai/codex`, `@google/gemini-cli`, or `opencode-ai`) if missing. The ACP backend itself is the bundled embedded `acpx/runtime` package from the `acpx` plugin.
|
- It sources `~/.profile`, stages the matching CLI auth material into the container, then installs the requested live CLI (`@anthropic-ai/claude-code`, `@openai/codex`, Factory Droid via `https://app.factory.ai/cli`, `@google/gemini-cli`, or `opencode-ai`) if missing. The ACP backend itself is the bundled embedded `acpx/runtime` package from the `acpx` plugin.
|
||||||
|
- The Droid Docker variant stages `~/.factory` for settings, forwards `FACTORY_API_KEY`, and requires that API key because local Factory OAuth/keyring auth is not portable into the container. It uses ACPX's built-in `droid exec --output-format acp` registry entry.
|
||||||
- The OpenCode Docker variant is a strict single-agent regression lane. It writes a temporary `OPENCODE_CONFIG_CONTENT` default model from `OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL` (default `opencode/kimi-k2.6`) after sourcing `~/.profile`, and `pnpm test:docker:live-acp-bind:opencode` requires a bound assistant transcript instead of accepting the generic post-bind skip.
|
- The OpenCode Docker variant is a strict single-agent regression lane. It writes a temporary `OPENCODE_CONFIG_CONTENT` default model from `OPENCLAW_LIVE_ACP_BIND_OPENCODE_MODEL` (default `opencode/kimi-k2.6`) after sourcing `~/.profile`, and `pnpm test:docker:live-acp-bind:opencode` requires a bound assistant transcript instead of accepting the generic post-bind skip.
|
||||||
- Direct `acpx` CLI calls are only a manual/workaround path for comparing behavior outside the Gateway. The Docker ACP bind smoke exercises OpenClaw's embedded `acpx` runtime backend.
|
- Direct `acpx` CLI calls are only a manual/workaround path for comparing behavior outside the Gateway. The Docker ACP bind smoke exercises OpenClaw's embedded `acpx` runtime backend.
|
||||||
|
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ These Docker runners split into two buckets:
|
|||||||
The live-model Docker runners also bind-mount only the needed CLI auth homes (or all supported ones when the run is not narrowed), then copy them into the container home before the run so external-CLI OAuth can refresh tokens without mutating the host auth store:
|
The live-model Docker runners also bind-mount only the needed CLI auth homes (or all supported ones when the run is not narrowed), then copy them into the container home before the run so external-CLI OAuth can refresh tokens without mutating the host auth store:
|
||||||
|
|
||||||
- Direct models: `pnpm test:docker:live-models` (script: `scripts/test-live-models-docker.sh`)
|
- Direct models: `pnpm test:docker:live-models` (script: `scripts/test-live-models-docker.sh`)
|
||||||
- ACP bind smoke: `pnpm test:docker:live-acp-bind` (script: `scripts/test-live-acp-bind-docker.sh`; covers Claude, Codex, and Gemini by default, with strict OpenCode coverage via `pnpm test:docker:live-acp-bind:opencode`)
|
- ACP bind smoke: `pnpm test:docker:live-acp-bind` (script: `scripts/test-live-acp-bind-docker.sh`; covers Claude, Codex, and Gemini by default, with strict Droid/OpenCode coverage via `pnpm test:docker:live-acp-bind:droid` and `pnpm test:docker:live-acp-bind:opencode`)
|
||||||
- CLI backend smoke: `pnpm test:docker:live-cli-backend` (script: `scripts/test-live-cli-backend-docker.sh`)
|
- CLI backend smoke: `pnpm test:docker:live-cli-backend` (script: `scripts/test-live-cli-backend-docker.sh`)
|
||||||
- Codex app-server harness smoke: `pnpm test:docker:live-codex-harness` (script: `scripts/test-live-codex-harness-docker.sh`)
|
- Codex app-server harness smoke: `pnpm test:docker:live-codex-harness` (script: `scripts/test-live-codex-harness-docker.sh`)
|
||||||
- Gateway + dev agent: `pnpm test:docker:live-gateway` (script: `scripts/test-live-gateway-models-docker.sh`)
|
- Gateway + dev agent: `pnpm test:docker:live-gateway` (script: `scripts/test-live-gateway-models-docker.sh`)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ read_when:
|
|||||||
title: "ACP agents"
|
title: "ACP agents"
|
||||||
---
|
---
|
||||||
|
|
||||||
[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) sessions let OpenClaw run external coding harnesses (for example Pi, Claude Code, Cursor, Copilot, OpenClaw ACP, OpenCode, Gemini CLI, and other supported ACPX harnesses) through an ACP backend plugin.
|
[Agent Client Protocol (ACP)](https://agentclientprotocol.com/) sessions let OpenClaw run external coding harnesses (for example Pi, Claude Code, Cursor, Copilot, Droid, OpenClaw ACP, OpenCode, Gemini CLI, and other supported ACPX harnesses) through an ACP backend plugin.
|
||||||
|
|
||||||
If you ask OpenClaw in plain language to bind or control Codex in the current conversation and the bundled `codex` plugin is enabled, OpenClaw should use the native Codex app-server plugin (`/codex bind`, `/codex threads`, `/codex resume`, `/codex steer`, `/codex stop`) instead of ACP. If you ask for `/acp`, ACP, acpx, or an ACP adapter test explicitly, OpenClaw can still route Codex through ACP. Each ACP session spawn is tracked as a [background task](/automation/tasks).
|
If you ask OpenClaw in plain language to bind or control Codex in the current conversation and the bundled `codex` plugin is enabled, OpenClaw should use the native Codex app-server plugin (`/codex bind`, `/codex threads`, `/codex resume`, `/codex steer`, `/codex stop`) instead of ACP. If you ask for `/acp`, ACP, acpx, or an ACP adapter test explicitly, OpenClaw can still route Codex through ACP. Each ACP session spawn is tracked as a [background task](/automation/tasks).
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ OpenClaw picks `runtime: "acp"`, resolves the harness `agentId`, binds to the cu
|
|||||||
|
|
||||||
For `sessions_spawn`, `runtime: "acp"` is advertised only when ACP is enabled,
|
For `sessions_spawn`, `runtime: "acp"` is advertised only when ACP is enabled,
|
||||||
the requester is not sandboxed, and an ACP runtime backend is loaded. It targets
|
the requester is not sandboxed, and an ACP runtime backend is loaded. It targets
|
||||||
ACP harness ids such as `codex`, `claude`, `gemini`, or `opencode`. Do not pass
|
ACP harness ids such as `codex`, `claude`, `droid`, `gemini`, or `opencode`. Do not pass
|
||||||
a normal OpenClaw config agent id from `agents_list` unless that entry is
|
a normal OpenClaw config agent id from `agents_list` unless that entry is
|
||||||
explicitly configured with `agents.list[].runtime.type="acp"`; otherwise use
|
explicitly configured with `agents.list[].runtime.type="acp"`; otherwise use
|
||||||
the default sub-agent runtime. When an OpenClaw agent is configured with
|
the default sub-agent runtime. When an OpenClaw agent is configured with
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ Tool params:
|
|||||||
- `task` (required)
|
- `task` (required)
|
||||||
- `label?` (optional)
|
- `label?` (optional)
|
||||||
- `agentId?` (optional; spawn under another agent id if allowed)
|
- `agentId?` (optional; spawn under another agent id if allowed)
|
||||||
- `runtime?` (`subagent|acp`, default `subagent`; `acp` is only for external ACP harnesses such as `claude`, `gemini`, `opencode`, or explicitly requested Codex ACP/acpx, or for `agents.list[]` entries whose `runtime.type` is `acp`)
|
- `runtime?` (`subagent|acp`, default `subagent`; `acp` is only for external ACP harnesses such as `claude`, `droid`, `gemini`, `opencode`, or explicitly requested Codex ACP/acpx, or for `agents.list[]` entries whose `runtime.type` is `acp`)
|
||||||
- `model?` (optional; overrides the sub-agent model; invalid values are skipped and the sub-agent runs on the default model with a warning in the tool result)
|
- `model?` (optional; overrides the sub-agent model; invalid values are skipped and the sub-agent runs on the default model with a warning in the tool result)
|
||||||
- `thinking?` (optional; overrides thinking level for the sub-agent run)
|
- `thinking?` (optional; overrides thinking level for the sub-agent run)
|
||||||
- `runTimeoutSeconds?` (defaults to `agents.defaults.subagents.runTimeoutSeconds` when set, otherwise `0`; when set, the sub-agent run is aborted after N seconds)
|
- `runTimeoutSeconds?` (defaults to `agents.defaults.subagents.runTimeoutSeconds` when set, otherwise `0`; when set, the sub-agent run is aborted after N seconds)
|
||||||
|
|||||||
@@ -1494,6 +1494,7 @@
|
|||||||
"test:docker:live-acp-bind": "bash scripts/test-live-acp-bind-docker.sh",
|
"test:docker:live-acp-bind": "bash scripts/test-live-acp-bind-docker.sh",
|
||||||
"test:docker:live-acp-bind:claude": "OPENCLAW_LIVE_ACP_BIND_AGENT=claude bash scripts/test-live-acp-bind-docker.sh",
|
"test:docker:live-acp-bind:claude": "OPENCLAW_LIVE_ACP_BIND_AGENT=claude bash scripts/test-live-acp-bind-docker.sh",
|
||||||
"test:docker:live-acp-bind:codex": "OPENCLAW_LIVE_ACP_BIND_AGENT=codex bash scripts/test-live-acp-bind-docker.sh",
|
"test:docker:live-acp-bind:codex": "OPENCLAW_LIVE_ACP_BIND_AGENT=codex bash scripts/test-live-acp-bind-docker.sh",
|
||||||
|
"test:docker:live-acp-bind:droid": "OPENCLAW_LIVE_ACP_BIND_AGENT=droid OPENCLAW_LIVE_ACP_BIND_REQUIRE_TRANSCRIPT=1 bash scripts/test-live-acp-bind-docker.sh",
|
||||||
"test:docker:live-acp-bind:gemini": "OPENCLAW_LIVE_ACP_BIND_AGENT=gemini bash scripts/test-live-acp-bind-docker.sh",
|
"test:docker:live-acp-bind:gemini": "OPENCLAW_LIVE_ACP_BIND_AGENT=gemini bash scripts/test-live-acp-bind-docker.sh",
|
||||||
"test:docker:live-acp-bind:opencode": "OPENCLAW_LIVE_ACP_BIND_AGENT=opencode OPENCLAW_LIVE_ACP_BIND_REQUIRE_TRANSCRIPT=1 bash scripts/test-live-acp-bind-docker.sh",
|
"test:docker:live-acp-bind:opencode": "OPENCLAW_LIVE_ACP_BIND_AGENT=opencode OPENCLAW_LIVE_ACP_BIND_REQUIRE_TRANSCRIPT=1 bash scripts/test-live-acp-bind-docker.sh",
|
||||||
"test:docker:live-build": "bash scripts/test-live-build-docker.sh",
|
"test:docker:live-build": "bash scripts/test-live-build-docker.sh",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
OPENCLAW_DOCKER_LIVE_AUTH_ALL=(.gemini .minimax)
|
OPENCLAW_DOCKER_LIVE_AUTH_ALL=(.factory .gemini .minimax)
|
||||||
OPENCLAW_DOCKER_LIVE_AUTH_FILES_ALL=(
|
OPENCLAW_DOCKER_LIVE_AUTH_FILES_ALL=(
|
||||||
.codex/auth.json
|
.codex/auth.json
|
||||||
.codex/config.toml
|
.codex/config.toml
|
||||||
@@ -49,6 +49,9 @@ openclaw_live_should_include_auth_dir_for_provider() {
|
|||||||
local provider
|
local provider
|
||||||
provider="$(openclaw_live_trim "${1:-}")"
|
provider="$(openclaw_live_trim "${1:-}")"
|
||||||
case "$provider" in
|
case "$provider" in
|
||||||
|
droid | factory | factory-droid)
|
||||||
|
printf '%s\n' ".factory"
|
||||||
|
;;
|
||||||
gemini | gemini-cli | google-gemini-cli)
|
gemini | gemini-cli | google-gemini-cli)
|
||||||
printf '%s\n' ".gemini"
|
printf '%s\n' ".gemini"
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ const DEFAULT_RESOURCE_LIMITS = {
|
|||||||
live: 9,
|
live: 9,
|
||||||
"live:claude": 4,
|
"live:claude": 4,
|
||||||
"live:codex": 4,
|
"live:codex": 4,
|
||||||
|
"live:droid": 4,
|
||||||
"live:gemini": 4,
|
"live:gemini": 4,
|
||||||
"live:opencode": 4,
|
"live:opencode": 4,
|
||||||
npm: 10,
|
npm: 10,
|
||||||
@@ -67,6 +68,9 @@ function liveProviderResource(provider) {
|
|||||||
if (provider === "codex-cli" || provider === "codex") {
|
if (provider === "codex-cli" || provider === "codex") {
|
||||||
return "live:codex";
|
return "live:codex";
|
||||||
}
|
}
|
||||||
|
if (provider === "droid") {
|
||||||
|
return "live:droid";
|
||||||
|
}
|
||||||
if (provider === "google-gemini-cli" || provider === "gemini") {
|
if (provider === "google-gemini-cli" || provider === "gemini") {
|
||||||
return "live:gemini";
|
return "live:gemini";
|
||||||
}
|
}
|
||||||
@@ -318,6 +322,17 @@ const exclusiveLanes = [
|
|||||||
weight: 3,
|
weight: 3,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
liveLane(
|
||||||
|
"live-acp-bind-droid",
|
||||||
|
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:live-acp-bind:droid",
|
||||||
|
{
|
||||||
|
cacheKey: "acp-bind-droid",
|
||||||
|
provider: "droid",
|
||||||
|
resources: ["npm"],
|
||||||
|
timeoutMs: LIVE_ACP_TIMEOUT_MS,
|
||||||
|
weight: 3,
|
||||||
|
},
|
||||||
|
),
|
||||||
liveLane(
|
liveLane(
|
||||||
"live-acp-bind-gemini",
|
"live-acp-bind-gemini",
|
||||||
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:live-acp-bind:gemini",
|
"OPENCLAW_SKIP_DOCKER_BUILD=1 pnpm test:docker:live-acp-bind:gemini",
|
||||||
|
|||||||
@@ -30,10 +30,11 @@ openclaw_live_acp_bind_resolve_auth_provider() {
|
|||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
claude) printf '%s\n' "claude-cli" ;;
|
claude) printf '%s\n' "claude-cli" ;;
|
||||||
codex) printf '%s\n' "codex-cli" ;;
|
codex) printf '%s\n' "codex-cli" ;;
|
||||||
|
droid) printf '%s\n' "droid" ;;
|
||||||
gemini) printf '%s\n' "google-gemini-cli" ;;
|
gemini) printf '%s\n' "google-gemini-cli" ;;
|
||||||
opencode) printf '%s\n' "opencode" ;;
|
opencode) printf '%s\n' "opencode" ;;
|
||||||
*)
|
*)
|
||||||
echo "Unsupported OPENCLAW_LIVE_ACP_BIND agent: ${1:-} (expected claude, codex, gemini, or opencode)" >&2
|
echo "Unsupported OPENCLAW_LIVE_ACP_BIND agent: ${1:-} (expected claude, codex, droid, gemini, or opencode)" >&2
|
||||||
return 1
|
return 1
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
@@ -43,6 +44,7 @@ openclaw_live_acp_bind_resolve_agent_command() {
|
|||||||
case "${1:-}" in
|
case "${1:-}" in
|
||||||
claude) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_CLAUDE:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
claude) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_CLAUDE:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
||||||
codex) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_CODEX:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
codex) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_CODEX:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
||||||
|
droid) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_DROID:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
||||||
gemini) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_GEMINI:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
gemini) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_GEMINI:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
||||||
opencode) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_OPENCODE:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
opencode) printf '%s' "${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND_OPENCODE:-${OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND:-}}" ;;
|
||||||
*) return 1 ;;
|
*) return 1 ;;
|
||||||
@@ -95,9 +97,9 @@ export XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}"
|
|||||||
export COREPACK_HOME="${COREPACK_HOME:-$XDG_CACHE_HOME/node/corepack}"
|
export COREPACK_HOME="${COREPACK_HOME:-$XDG_CACHE_HOME/node/corepack}"
|
||||||
export NPM_CONFIG_CACHE="${NPM_CONFIG_CACHE:-$XDG_CACHE_HOME/npm}"
|
export NPM_CONFIG_CACHE="${NPM_CONFIG_CACHE:-$XDG_CACHE_HOME/npm}"
|
||||||
export npm_config_cache="$NPM_CONFIG_CACHE"
|
export npm_config_cache="$NPM_CONFIG_CACHE"
|
||||||
mkdir -p "$NPM_CONFIG_PREFIX" "$XDG_CACHE_HOME" "$COREPACK_HOME" "$NPM_CONFIG_CACHE"
|
mkdir -p "$NPM_CONFIG_PREFIX" "$HOME/.local/bin" "$XDG_CACHE_HOME" "$COREPACK_HOME" "$NPM_CONFIG_CACHE"
|
||||||
chmod 700 "$XDG_CACHE_HOME" "$COREPACK_HOME" "$NPM_CONFIG_CACHE" || true
|
chmod 700 "$XDG_CACHE_HOME" "$COREPACK_HOME" "$NPM_CONFIG_CACHE" || true
|
||||||
export PATH="$NPM_CONFIG_PREFIX/bin:$PATH"
|
export PATH="$HOME/.local/bin:$NPM_CONFIG_PREFIX/bin:$PATH"
|
||||||
if [ "${OPENCLAW_DOCKER_AUTH_PRESTAGED:-0}" != "1" ]; then
|
if [ "${OPENCLAW_DOCKER_AUTH_PRESTAGED:-0}" != "1" ]; then
|
||||||
IFS=',' read -r -a auth_dirs <<<"${OPENCLAW_DOCKER_AUTH_DIRS_RESOLVED:-}"
|
IFS=',' read -r -a auth_dirs <<<"${OPENCLAW_DOCKER_AUTH_DIRS_RESOLVED:-}"
|
||||||
IFS=',' read -r -a auth_files <<<"${OPENCLAW_DOCKER_AUTH_FILES_RESOLVED:-}"
|
IFS=',' read -r -a auth_files <<<"${OPENCLAW_DOCKER_AUTH_FILES_RESOLVED:-}"
|
||||||
@@ -153,6 +155,17 @@ WRAP
|
|||||||
npm install -g @openai/codex
|
npm install -g @openai/codex
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
|
droid)
|
||||||
|
if ! command -v droid >/dev/null 2>&1; then
|
||||||
|
curl -fsSL https://app.factory.ai/cli | sh
|
||||||
|
export PATH="$HOME/.local/bin:$PATH"
|
||||||
|
fi
|
||||||
|
droid --version
|
||||||
|
if [ -z "${FACTORY_API_KEY:-}" ]; then
|
||||||
|
echo "Droid Docker ACP bind requires FACTORY_API_KEY; Factory OAuth/keyring auth in ~/.factory is not portable into the container." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
gemini)
|
gemini)
|
||||||
mkdir -p "$HOME/.gemini"
|
mkdir -p "$HOME/.gemini"
|
||||||
if [ ! -x "$NPM_CONFIG_PREFIX/bin/gemini" ]; then
|
if [ ! -x "$NPM_CONFIG_PREFIX/bin/gemini" ]; then
|
||||||
@@ -197,7 +210,7 @@ for token in "${ACP_AGENT_TOKENS[@]}"; do
|
|||||||
done
|
done
|
||||||
|
|
||||||
if ((${#ACP_AGENTS[@]} == 0)); then
|
if ((${#ACP_AGENTS[@]} == 0)); then
|
||||||
echo "No ACP bind agents selected. Use OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini,opencode." >&2
|
echo "No ACP bind agents selected. Use OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,droid,gemini,opencode." >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -283,6 +296,7 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
|||||||
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD="${ANTHROPIC_API_KEY_OLD:-}" \
|
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD="${ANTHROPIC_API_KEY_OLD:-}" \
|
||||||
-e GEMINI_API_KEY \
|
-e GEMINI_API_KEY \
|
||||||
-e GOOGLE_API_KEY \
|
-e GOOGLE_API_KEY \
|
||||||
|
-e FACTORY_API_KEY \
|
||||||
-e OPENAI_API_KEY \
|
-e OPENAI_API_KEY \
|
||||||
-e OPENCODE_API_KEY \
|
-e OPENCODE_API_KEY \
|
||||||
-e OPENCODE_ZEN_API_KEY \
|
-e OPENCODE_ZEN_API_KEY \
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ function resolveTargetAcpAgentId(params: {
|
|||||||
error:
|
error:
|
||||||
`agentId "${requested}" is an OpenClaw config agent, not an ACP harness. ` +
|
`agentId "${requested}" is an OpenClaw config agent, not an ACP harness. ` +
|
||||||
'Use runtime="subagent" or omit runtime for OpenClaw config agents. ' +
|
'Use runtime="subagent" or omit runtime for OpenClaw config agents. ' +
|
||||||
'Use runtime="acp" only with external ACP harness ids such as codex, claude, gemini, or opencode, or configure agents.list[].runtime.type="acp" with runtime.acp.agent.',
|
'Use runtime="acp" only with external ACP harness ids such as codex, claude, droid, gemini, or opencode, or configure agents.list[].runtime.type="acp" with runtime.acp.agent.',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return { ok: true, agentId: requested };
|
return { ok: true, agentId: requested };
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ const CONNECT_TIMEOUT_MS = 90_000;
|
|||||||
const LIVE_TIMEOUT_MS = 240_000;
|
const LIVE_TIMEOUT_MS = 240_000;
|
||||||
const DEFAULT_LIVE_CODEX_MODEL = "gpt-5.5";
|
const DEFAULT_LIVE_CODEX_MODEL = "gpt-5.5";
|
||||||
const DEFAULT_LIVE_PARENT_MODEL = "openai/gpt-5.4";
|
const DEFAULT_LIVE_PARENT_MODEL = "openai/gpt-5.4";
|
||||||
type LiveAcpAgent = "claude" | "codex" | "gemini" | "opencode";
|
type LiveAcpAgent = "claude" | "codex" | "droid" | "gemini" | "opencode";
|
||||||
|
|
||||||
function createSlackCurrentConversationBindingRegistry() {
|
function createSlackCurrentConversationBindingRegistry() {
|
||||||
return createTestRegistry([
|
return createTestRegistry([
|
||||||
@@ -76,6 +76,9 @@ function normalizeAcpAgent(raw: string | undefined): LiveAcpAgent {
|
|||||||
if (normalized === "codex") {
|
if (normalized === "codex") {
|
||||||
return "codex";
|
return "codex";
|
||||||
}
|
}
|
||||||
|
if (normalized === "droid") {
|
||||||
|
return "droid";
|
||||||
|
}
|
||||||
if (normalized === "opencode") {
|
if (normalized === "opencode") {
|
||||||
return "opencode";
|
return "opencode";
|
||||||
}
|
}
|
||||||
@@ -141,6 +144,7 @@ function logLiveStep(message: string): void {
|
|||||||
|
|
||||||
function shouldRequireBoundAssistantTranscript(liveAgent: LiveAcpAgent): boolean {
|
function shouldRequireBoundAssistantTranscript(liveAgent: LiveAcpAgent): boolean {
|
||||||
return (
|
return (
|
||||||
|
liveAgent === "droid" ||
|
||||||
liveAgent === "opencode" ||
|
liveAgent === "opencode" ||
|
||||||
isTruthyEnvValue(process.env.OPENCLAW_LIVE_ACP_BIND_REQUIRE_TRANSCRIPT)
|
isTruthyEnvValue(process.env.OPENCLAW_LIVE_ACP_BIND_REQUIRE_TRANSCRIPT)
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user