You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(llc/docker): LLC subprocess agents unrunnable under compose — claude/gh CLI absent from backend image + localhost API base #9793
Gap: LLC subprocess agents can't run under docker-compose
The LLC subprocess adapters (ClaudeCodeAdapter, CopilotLocalAdapter, and their subscription variants) spawn the claude / gh CLI as a child of the backend process (asyncio.create_subprocess_exec). Under compose that runs inside the autobot-backend container.
Blocker 1 — agent CLIs absent from the backend image
docker/backend/Dockerfile installs neither claude nor gh. So _resolve_claude_cli() / _resolve_gh_cli() raise RuntimeError in-container, and every claude_code / copilot heartbeat fails fast. The LLC heartbeat scheduler does start under compose (initialization/lifespan.py_init_heartbeat_scheduler, not gated), so such agents are dispatched and immediately fail.
Blocker 2 — LLC_AGENT_API_BASE_URL unset in compose
Falls back to http://localhost:8001/api. That is correct for a co-located agent (the CLI runs in the backend container, so loopback reaches the LLC API + auth middleware), but it's the same localhost-vs-service-name fragility tracked in #9715 — if the backend's in-container bind port differs from 8001 the agent can't reach the API.
Required (for compose runnability)
Add claude (@anthropic-ai/claude-code) and/or gh CLI to the backend image — or ship a dedicated agent-runner image / sidecar so the heavy CLIs aren't forced into the API image.
Set LLC_AGENT_API_BASE_URL explicitly in docker-compose.yml (co-located → http://localhost:<backend-port>/api, or the backend service name if agents ever run out-of-container).
Consider gating heartbeat dispatch for subprocess adapter types when the required CLI is absent, so runs are skipped (logged) rather than FAILED-spamming.
Notes
The adapter code is correct (run-scoped key forwarding/redaction/prompt fixed in #9760, #9772, #9789/PR-A); this issue is purely the deployment/image/networking layer. Related: #9715 (compose localhost vs service names), #9008 (Copilot adapter), #9789 (adapter key handling).
Bug sweep 2026-06-10 → TOO-BIG (deployment/image). The adapter code is correct; the gap is infrastructure: the backend image ships neither claude nor gh, and LLC_AGENT_API_BASE_URL is unset under compose. Fixing it means a Dockerfile change (add the CLIs or a dedicated agent-runner sidecar) + compose env + optional heartbeat-gating when the CLI is absent — a cross-cutting deployment change, not a code edit.
2026-06-11 assessment (umbrella #9919 sweep): implement-now, sidecar ruled out (adapters spawn the CLI as a child of the backend process — llc/adapters/claude_code_adapter.pyshutil.which('claude') + asyncio.create_subprocess_exec; a sidecar needs a dispatch RPC = re-architecture). Plan: (1) minimal increment (S, ship first): heartbeat dispatch gate in llc/scheduler/heartbeat_scheduler.py (~line 678) — skip-with-log when the adapter's required CLI is absent (mirrors the existing 'no LLC adapter registered' pattern); converts every-heartbeat FAILED runs into a clean degraded state. (2) bake-in (M):docker/backend/Dockerfile production stage — gh via apt repo + claude native installer to /usr/local/bin; (3) compose env: explicit LLC_AGENT_API_BASE_URL + ANTHROPIC_API_KEY/GH_TOKEN passthrough (currently NO credential reaches the container — unstated 4th blocker). Remaining human decision (narrow): subscription-variant OAuth (mount host ~/.claude/gh auth state into the container vs document host-only).
Activity
mrveiss commentedon Jun 10, 2026
Bug sweep 2026-06-10 → TOO-BIG (deployment/image). The adapter code is correct; the gap is infrastructure: the backend image ships neither
claudenorgh, andLLC_AGENT_API_BASE_URLis unset under compose. Fixing it means a Dockerfile change (add the CLIs or a dedicated agent-runner sidecar) + compose env + optional heartbeat-gating when the CLI is absent — a cross-cutting deployment change, not a code edit.mrveiss commentedon Jun 11, 2026
2026-06-11 assessment (umbrella #9919 sweep): implement-now, sidecar ruled out (adapters spawn the CLI as a child of the backend process —
llc/adapters/claude_code_adapter.pyshutil.which('claude')+asyncio.create_subprocess_exec; a sidecar needs a dispatch RPC = re-architecture). Plan: (1) minimal increment (S, ship first): heartbeat dispatch gate inllc/scheduler/heartbeat_scheduler.py(~line 678) — skip-with-log when the adapter's required CLI is absent (mirrors the existing 'no LLC adapter registered' pattern); converts every-heartbeat FAILED runs into a clean degraded state. (2) bake-in (M):docker/backend/Dockerfileproduction stage —ghvia apt repo +claudenative installer to /usr/local/bin; (3) compose env: explicitLLC_AGENT_API_BASE_URL+ANTHROPIC_API_KEY/GH_TOKENpassthrough (currently NO credential reaches the container — unstated 4th blocker). Remaining human decision (narrow): subscription-variant OAuth (mount host~/.claude/gh auth state into the container vs document host-only).fix(llc): build-time CLI proof, drop unused gnupg, document env vars (#…
fix(docker): claude installer ignores CLAUDE_INSTALL_DIR — HOME-redir…
feat(llc): compose-runnable subprocess agents — CLI gate, image bake-…
github-actions commentedon Jun 11, 2026
PR #9948 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Jun 11, 2026
Solved by commit
857cfaedce1142b5c5125bfd08612bc114062750(squash merge of PR #9948 intoDev_new_gui). Criteria: (1) heartbeat CLI-availability gate — subprocess adapters declare_required_cli(claude/gh),_dispatch_adapterskips-with-INFO instead of FAILED runs (29/29 tests, 4 new); (2) backend image bakes ingh(signed apt repo) +claude(official installer, HOME-redirect to/opt/claude-cli+/usr/local/binsymlink,stablechannel — the--versionbuild gate caught the installer ignoringCLAUDE_INSTALL_DIR); (3) compose passesLLC_AGENT_API_BASE_URL+ANTHROPIC_API_KEY/GH_TOKENthrough. Open sub-question stays tracked here: subscription-variant OAuth (mount host~/.claude/gh auth state vs document host-only) — needs a product decision. Follow-ups filed: #9950 (installer hardening), #9951 (SKIPPED heartbeat status).