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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions