mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(release): isolate Claude ACP subscription auth
This commit is contained in:
@@ -2316,6 +2316,11 @@ jobs:
|
||||
echo "OPENCLAW_TEST_CONSOLE=1" >> "$GITHUB_ENV"
|
||||
;;
|
||||
live-acp-bind-docker)
|
||||
if [[ -n "${OPENCLAW_CLAUDE_CREDENTIALS_JSON:-}" || -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ]]; then
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=subscription" >> "$GITHUB_ENV"
|
||||
else
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=api-key" >> "$GITHUB_ENV"
|
||||
fi
|
||||
if [[ -n "${GEMINI_API_KEY:-}" || -n "${GOOGLE_API_KEY:-}" ]]; then
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini" >> "$GITHUB_ENV"
|
||||
else
|
||||
@@ -2551,6 +2556,11 @@ jobs:
|
||||
echo "OPENCLAW_TEST_CONSOLE=1" >> "$GITHUB_ENV"
|
||||
;;
|
||||
live-acp-bind-docker)
|
||||
if [[ -n "${OPENCLAW_CLAUDE_CREDENTIALS_JSON:-}" || -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ]]; then
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=subscription" >> "$GITHUB_ENV"
|
||||
else
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=api-key" >> "$GITHUB_ENV"
|
||||
fi
|
||||
if [[ -n "${GEMINI_API_KEY:-}" || -n "${GOOGLE_API_KEY:-}" ]]; then
|
||||
echo "OPENCLAW_LIVE_ACP_BIND_AGENTS=claude,codex,gemini" >> "$GITHUB_ENV"
|
||||
else
|
||||
|
||||
@@ -17,6 +17,7 @@ CONFIG_DIR="${OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}"
|
||||
WORKSPACE_DIR="${OPENCLAW_WORKSPACE_DIR:-$HOME/.openclaw/workspace}"
|
||||
PROFILE_FILE="$(openclaw_live_default_profile_file)"
|
||||
ACP_AGENT_LIST_RAW="${OPENCLAW_LIVE_ACP_BIND_AGENTS:-${OPENCLAW_LIVE_ACP_BIND_AGENT:-claude,codex,gemini}}"
|
||||
ACP_CLAUDE_AUTH_MODE="${OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH:-auto}"
|
||||
ACP_SETUP_TIMEOUT_SECONDS="$(openclaw_live_read_positive_int_env OPENCLAW_LIVE_ACP_BIND_SETUP_TIMEOUT_SECONDS 180)"
|
||||
TEMP_DIRS=()
|
||||
DOCKER_USER="${OPENCLAW_DOCKER_USER:-node}"
|
||||
@@ -62,6 +63,15 @@ openclaw_live_acp_bind_resolve_agent_command() {
|
||||
esac
|
||||
}
|
||||
|
||||
case "$ACP_CLAUDE_AUTH_MODE" in
|
||||
auto | api-key | subscription)
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH must be one of: auto, api-key, subscription." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
cleanup_temp_dirs() {
|
||||
if ((${#TEMP_DIRS[@]} > 0)); then
|
||||
rm -rf "${TEMP_DIRS[@]}"
|
||||
@@ -174,6 +184,14 @@ fi
|
||||
agent="${OPENCLAW_LIVE_ACP_BIND_AGENT:-claude}"
|
||||
case "$agent" in
|
||||
claude)
|
||||
claude_auth_mode="${OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH:-auto}"
|
||||
if [ "$claude_auth_mode" = "subscription" ]; then
|
||||
unset ANTHROPIC_API_KEY
|
||||
unset ANTHROPIC_API_KEY_OLD
|
||||
unset ANTHROPIC_API_TOKEN
|
||||
unset ANTHROPIC_AUTH_TOKEN
|
||||
unset ANTHROPIC_OAUTH_TOKEN
|
||||
fi
|
||||
claude_code_version="$(
|
||||
node -e 'const path = require("node:path"); const packagePath = path.join(path.dirname(require.resolve("@anthropic-ai/claude-agent-sdk")), "package.json"); process.stdout.write(require(packagePath).claudeCodeVersion);'
|
||||
)"
|
||||
@@ -197,11 +215,16 @@ case "$agent" in
|
||||
cat > "$NPM_CONFIG_PREFIX/bin/claude" <<WRAP
|
||||
#!/usr/bin/env bash
|
||||
script_dir="\$(CDPATH= cd -- "\$(dirname -- "\$0")" && pwd)"
|
||||
if [ -n "\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY:-}" ]; then
|
||||
export ANTHROPIC_API_KEY="\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY}"
|
||||
fi
|
||||
if [ -n "\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD:-}" ]; then
|
||||
export ANTHROPIC_API_KEY_OLD="\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD}"
|
||||
if [ "\${OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH:-auto}" = "subscription" ]; then
|
||||
unset ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN
|
||||
unset ANTHROPIC_AUTH_TOKEN ANTHROPIC_OAUTH_TOKEN
|
||||
else
|
||||
if [ -n "\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY:-}" ]; then
|
||||
export ANTHROPIC_API_KEY="\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY}"
|
||||
fi
|
||||
if [ -n "\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD:-}" ]; then
|
||||
export ANTHROPIC_API_KEY_OLD="\${OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD}"
|
||||
fi
|
||||
fi
|
||||
exec "\$script_dir/claude-real" "\$@"
|
||||
WRAP
|
||||
@@ -369,6 +392,14 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
echo "ERROR: Droid Docker ACP bind requires FACTORY_API_KEY; Factory OAuth/keyring auth in ~/.factory is not portable into the container." >&2
|
||||
exit 1
|
||||
fi
|
||||
CLAUDE_AUTH_MODE="$ACP_CLAUDE_AUTH_MODE"
|
||||
if [[ "$ACP_AGENT" == "claude" && "$CLAUDE_AUTH_MODE" == "auto" ]]; then
|
||||
if [[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" || -f "$HOME/.claude/.credentials.json" ]]; then
|
||||
CLAUDE_AUTH_MODE="subscription"
|
||||
else
|
||||
CLAUDE_AUTH_MODE="api-key"
|
||||
fi
|
||||
fi
|
||||
|
||||
EXTERNAL_AUTH_MOUNTS=()
|
||||
if ((${#AUTH_DIRS[@]} > 0)); then
|
||||
@@ -396,6 +427,9 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
echo "==> Profile file: $PROFILE_STATUS"
|
||||
echo "==> Auth dirs: ${AUTH_DIRS_CSV:-none}"
|
||||
echo "==> Auth files: ${AUTH_FILES_CSV:-none}"
|
||||
if [[ "$ACP_AGENT" == "claude" ]]; then
|
||||
echo "==> Claude auth mode: $CLAUDE_AUTH_MODE"
|
||||
fi
|
||||
if openclaw_live_uses_managed_bind_dirs; then
|
||||
openclaw_live_chown_bind_dirs_for_container_user \
|
||||
"$LIVE_IMAGE_NAME" \
|
||||
@@ -406,13 +440,24 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
fi
|
||||
DOCKER_RUN_ARGS=()
|
||||
openclaw_live_init_docker_run_args DOCKER_RUN_ARGS "${OPENCLAW_LIVE_ACP_BIND_DOCKER_RUN_TIMEOUT:-2700s}"
|
||||
DOCKER_AUTH_ENV=()
|
||||
if [[ "$ACP_AGENT" == "claude" && "$CLAUDE_AUTH_MODE" == "subscription" ]]; then
|
||||
DOCKER_AUTH_ENV+=(
|
||||
-e CLAUDE_CODE_OAUTH_TOKEN="${CLAUDE_CODE_OAUTH_TOKEN:-}"
|
||||
-e OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH="$CLAUDE_AUTH_MODE"
|
||||
)
|
||||
elif [[ "$ACP_AGENT" == "claude" ]]; then
|
||||
DOCKER_AUTH_ENV+=(
|
||||
-e ANTHROPIC_API_KEY
|
||||
-e ANTHROPIC_API_KEY_OLD
|
||||
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-}"
|
||||
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD="${ANTHROPIC_API_KEY_OLD:-}"
|
||||
-e OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH="$CLAUDE_AUTH_MODE"
|
||||
)
|
||||
fi
|
||||
DOCKER_RUN_ARGS+=(--rm -t \
|
||||
-u "$DOCKER_USER" \
|
||||
--entrypoint bash \
|
||||
-e ANTHROPIC_API_KEY \
|
||||
-e ANTHROPIC_API_KEY_OLD \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY="${ANTHROPIC_API_KEY:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_ANTHROPIC_API_KEY_OLD="${ANTHROPIC_API_KEY_OLD:-}" \
|
||||
-e GEMINI_API_KEY \
|
||||
-e GOOGLE_API_KEY \
|
||||
-e FACTORY_API_KEY \
|
||||
@@ -448,6 +493,7 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_THINKING:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_TIMEOUT_MS="${OPENCLAW_LIVE_ACP_SPAWN_DEFAULTS_TIMEOUT_MS:-}" \
|
||||
-e OPENCLAW_LIVE_ACP_BIND_AGENT_COMMAND="$AGENT_COMMAND")
|
||||
openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_AUTH_ENV
|
||||
openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_HOME_MOUNT
|
||||
openclaw_live_append_array DOCKER_RUN_ARGS DOCKER_TRUSTED_HARNESS_MOUNT
|
||||
DOCKER_RUN_ARGS+=(\
|
||||
|
||||
@@ -1098,6 +1098,20 @@ describe("package artifact reuse", () => {
|
||||
expect(readFileSync("scripts/test-live-acp-bind-docker.sh", "utf8")).toContain(
|
||||
'run_setup_command npm install -g "@anthropic-ai/claude-code@$claude_code_version"',
|
||||
);
|
||||
const acpBindScript = readFileSync("scripts/test-live-acp-bind-docker.sh", "utf8");
|
||||
expect(acpBindScript).toContain(
|
||||
"OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH must be one of: auto, api-key, subscription.",
|
||||
);
|
||||
expect(acpBindScript).toContain(
|
||||
'if [[ "$ACP_AGENT" == "claude" && "$CLAUDE_AUTH_MODE" == "subscription" ]]; then',
|
||||
);
|
||||
expect(acpBindScript).toContain(
|
||||
"unset ANTHROPIC_API_KEY ANTHROPIC_API_KEY_OLD ANTHROPIC_API_TOKEN",
|
||||
);
|
||||
expect(acpBindScript).toContain('-e CLAUDE_CODE_OAUTH_TOKEN="${CLAUDE_CODE_OAUTH_TOKEN:-}"');
|
||||
expect(acpBindScript).not.toContain(" -e ANTHROPIC_API_KEY \\\n");
|
||||
expect(workflow.match(/OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=subscription/g)).toHaveLength(2);
|
||||
expect(workflow.match(/OPENCLAW_LIVE_ACP_BIND_CLAUDE_AUTH=api-key/g)).toHaveLength(2);
|
||||
expect(readFileSync("scripts/test-live-acp-bind-docker.sh", "utf8")).toContain(
|
||||
"run_setup_command bash -lc 'curl -fsSL https://app.factory.ai/cli | sh'",
|
||||
);
|
||||
@@ -1283,7 +1297,7 @@ describe("package artifact reuse", () => {
|
||||
reusableWorkflow.match(
|
||||
/if \[\[ -n "\$\{OPENCLAW_CLAUDE_CREDENTIALS_JSON:-\}" \|\| -n "\$\{CLAUDE_CODE_OAUTH_TOKEN:-\}" \]\]; then/g,
|
||||
),
|
||||
).toHaveLength(2);
|
||||
).toHaveLength(4);
|
||||
});
|
||||
|
||||
it("finalizes Testbox delegation even when setup or the remote command fails", () => {
|
||||
|
||||
Reference in New Issue
Block a user