Skip to content

bug(llc/docker): LLC subprocess agents unrunnable under compose — claude/gh CLI absent from backend image + localhost API base #9793

Closed

Description

@mrveiss

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)

  1. 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.
  2. 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).
  3. 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).

Labels: bug · backend · agents · priority: medium

Activity

  1. mrveiss commented on Jun 10, 2026

    @mrveiss
    OwnerAuthor

    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.

  2. mrveiss commented on Jun 11, 2026

    @mrveiss
    OwnerAuthor

    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.py shutil.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).

  3. github-actions commented on Jun 11, 2026

    @github-actions
    Contributor

    PR #9948 (merged to Dev_new_gui) references this issue with a close keyword.

    feat(llc): compose-runnable subprocess agents — CLI gate, image bake-in, env passthrough (#9793)

    If this issue is fully resolved, close it manually. If work remains, no action is needed.

  4. mrveiss commented on Jun 11, 2026

    @mrveiss
    OwnerAuthor

    Solved by commit 857cfaedce1142b5c5125bfd08612bc114062750 (squash merge of PR #9948 into Dev_new_gui). Criteria: (1) heartbeat CLI-availability gate — subprocess adapters declare _required_cli (claude/gh), _dispatch_adapter skips-with-INFO instead of FAILED runs (29/29 tests, 4 new); (2) backend image bakes in gh (signed apt repo) + claude (official installer, HOME-redirect to /opt/claude-cli + /usr/local/bin symlink, stable channel — the --version build gate caught the installer ignoring CLAUDE_INSTALL_DIR); (3) compose passes LLC_AGENT_API_BASE_URL + ANTHROPIC_API_KEY/GH_TOKEN through. 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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions