Skip to content

Toggle individual CLIs on/off (extend ENABLE_HERMES pattern to Codex/OpenCode/Gemini) #29

@dgokeeffe

Description

@dgokeeffe

Motivation

setup_hermes.py already supports ENABLE_HERMES=false to skip its install. The other three secondary CLIs (Codex, OpenCode, Gemini) don't have an equivalent, so an operator who knows their workspace can't actually run a particular agent has to either:

  • live with the broken install + dead UI, or
  • fork and gut the setup script.

Real triggering case: workspace adb-7405613340366915.15.azuredatabricks.net serves only databricks-gpt-oss-* models. Codex is configured with wire_api = "responses", but:

$ curl -X POST .../serving-endpoints/responses -d '{"model":"databricks-gpt-oss-120b",...}'
{"error_code":"BAD_REQUEST","message":"Responses API passthrough is not supported for model databricks-gpt-oss-120b."}
HTTP 400

So Codex on this workspace won't function regardless of which model it picks. An operator needs ENABLE_CODEX=false to cleanly skip the install rather than ship a broken agent into the terminal UI.

Fix shape (PR coming)

Replicate the Hermes pattern. 4-line gate at the top of each of setup_codex.py, setup_opencode.py, setup_gemini.py:

if os.environ.get("ENABLE_<CLI>", "true").strip().lower() in ("false", "0", "no"):
    print("ENABLE_<CLI>=false — skipping <CLI> setup")
    raise SystemExit(0)

app.yaml documents all four toggles together. Defaults to "true" for all → existing deployments are unchanged.

Out of scope

  • Claude Code stays always-on. setup_claude.py also creates ~/projects, writes ~/.claude.json with MCP servers (used app-wide), and copies subagent definitions. Some of that is non-Claude-specific. Adding ENABLE_CLAUDE=false would require disentangling those side effects first. Can be a follow-up if there's demand for a "no-Claude" deploy.
  • No UI surfacing. A skipped agent's setup-status step still shows complete (because raise SystemExit(0) is a clean exit). The print line is in the step's stdout buffer; users who care can read it. Adding a "skipped" state to the UI is more invasive — keep this PR small.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions