mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-09-29 17:19:17 +08:00
* fix(examples): inherit acp-docker image from config/defaults.json
examples/acp-docker/docker-compose.yml hardcoded the agent-server image at
`1.25.0-python`. Canvas enforces `compatibility.minimumAgentServer` (1.28.0)
from the repo's single source of truth, so the example default fell below the
floor and rendered "Disconnected — requires 1.28.0 or newer" — a reviewer
following the quickstart as written never reached the feature.
examples/acp-docker was the lone in-repo file hardcoding a version instead of
inheriting from config/defaults.json (14 other files read it; check-sdk-version
-sync only validates the released PyPI package, not in-repo files).
- scripts/gen-acp-docker-env.mjs: read defaults.json, pin AGENT_SERVER_IMAGE to
`${images.agentServer}:${versions.agentServer}-python` in examples/acp-docker
/.env (idempotent upsert; mirrors scripts/docker-build.mjs).
- package.json: `npm run example:acp-docker:env`.
- docker-compose.yml: no-config fallback `1.25.0-python` -> `latest-python`,
always >= the compatibility floor, so zero-config `docker compose up` never
shows "Disconnected"; the generated .env overrides with the pinned SoT
version for the reproducible path.
- .env.example / README.md: document both paths; correct the version narrative
(floor is the defaults.json compatibility pin; #3510 is the deeper functional
floor at/below it).
- __tests__/scripts/acp-docker-env-sync.test.ts: assert the generator's tag
matches defaults.json, the pin satisfies the floor, and the compose fallback
stays `latest-python`. Mirrors docs-version-sync.test.ts — the guard that
makes "can't silently drift" true.
* test(examples): harden acp-docker env-sync per review
Addresses the cli-review-panel findings worth acting on (the rest were
cosmetic or matched the no-validation idiom of scripts/docker-build.mjs):
- gte() in the test guarded with parseSemver — a non-numeric pin (sha /
pre-release) now fails the floor check loudly instead of silently
comparing NaN. The floor check is a CI gate; its one piece of logic
shouldn't mis-compare in silence.
- compose-fallback assertion derives the registry from config.images
.agentServer instead of hardcoding ghcr.io/openhands/... — a registry
change no longer false-fails a test that only cares about the latest-python
tag.
- upsertEnvLine now has unit tests (append / replace-in-place+preserve /
idempotent / commented-template-line / keyless-line guard), making the
"idempotent upsert" claim defensible. It was the one untested piece of real
logic.
- upsertEnvLine guards a keyless line (no "=") with a clear throw, instead of
an empty key matching every line and rewriting the whole file.
* fix(examples): guard acp-docker env-sync entrypoint against undefined argv[1]
The CLI entrypoint guard called pathToFileURL(process.argv[1]) unconditionally.
process.argv[1] is undefined in some ESM contexts (e.g. importing the module for
its exports via `node --input-type=module -e "import(...)"`), so the guard threw
ERR_INVALID_ARG_TYPE at import, before any exported helper was reachable.
Short-circuit on process.argv[1] before pathToFileURL so importing the module is
side-effect-free while the CLI path is unchanged. Add a regression test that
reproduces the bare-import context and asserts a clean exit.
Addresses the review finding on #1434.
* docs(acp-docker): trim verbose comments per review
Address all-hands-bot's review suggestions on #1434:
- test header describes the current invariant, not the prior-state history
(that narration belonged in the PR description)
- docker-compose.yml: condense the image-pin comment to the how-to-override;
the compatibility-floor / #3510 rationale already lives in README §1 + the test
- .env.example: 7-line pin explainer down to 2
Comment-only; env-sync test still 10/10 green, prettier clean.
* Clarify ACP Docker image version guidance
Co-authored-by: openhands <openhands@all-hands.dev>
---------
Co-authored-by: enyst <engel.nyst@gmail.com>
Co-authored-by: openhands <openhands@all-hands.dev>
35 lines
1.4 KiB
Bash
35 lines
1.4 KiB
Bash
# Example environment for examples/acp-docker/docker-compose.yml.
|
|
# Copy to `.env` in this directory. Everything here is OPTIONAL — the
|
|
# recommended path is to enter credentials in Canvas's onboarding "Set up
|
|
# credentials" step (they ride the conversation start request as secrets).
|
|
# Set values here only if you want them baked into the container instead.
|
|
|
|
# Pin the agent-server image. The compose default is `latest-python`.
|
|
# For a reproducible pin (driven by config/defaults.json): npm run example:acp-docker:env
|
|
# AGENT_SERVER_IMAGE=ghcr.io/openhands/agent-server:latest-python
|
|
|
|
# --- Claude Code ---
|
|
# A Pro/Max OAuth token, OR an API key. Do NOT set ANTHROPIC_BASE_URL with the
|
|
# OAuth token — an inherited base URL breaks bearer auth (see docs/ACP_AGENTS.md).
|
|
# CLAUDE_CODE_OAUTH_TOKEN=
|
|
# ANTHROPIC_API_KEY=
|
|
|
|
# --- Codex ---
|
|
# Subscription auth.json is supplied via Canvas (CODEX_AUTH_JSON); for an API
|
|
# key instead:
|
|
# OPENAI_API_KEY=
|
|
|
|
# --- Gemini CLI (Vertex AI) ---
|
|
# The service-account / ADC JSON is supplied via Canvas
|
|
# (GOOGLE_APPLICATION_CREDENTIALS_JSON). These scalars can live here or in Canvas:
|
|
# GOOGLE_CLOUD_PROJECT=
|
|
# GOOGLE_CLOUD_LOCATION=us-central1
|
|
# GOOGLE_GENAI_USE_VERTEXAI=true
|
|
# Or the API-key path:
|
|
# GEMINI_API_KEY=
|
|
|
|
# --- Auth (optional) ---
|
|
# Require a session key on the backend; mirror it into Canvas as
|
|
# VITE_SESSION_API_KEY. Leave unset for an open local backend.
|
|
# SESSION_API_KEY=
|