Goal
Make amux completely standalone — runnable with no cloud LLM dependency — by adding Ollama (local models) as a first-class, fully-swappable provider alongside Claude Code, Codex, and Gemini. When a user selects Ollama, every amux feature must work identically to the cloud providers, driven by a locally-hosted model.
Definition of done: a user with only Ollama installed (no ANTHROPIC_API_KEY, no Gemini/OpenAI keys, no network) can create sessions, run the full agentic loop, and use every dashboard feature end-to-end. Validated against GLM‑5.2 and Qwen3.5 as the reference local models.
Two integration surfaces
Ollama is a local model server (http://localhost:11434, OpenAI‑compatible at /v1), not an interactive agentic coding CLI like claude/codex/gemini. So "integrate Ollama" spans two distinct surfaces, both required for standalone:
A. Session-driving agent (the terminal a peek renders)
amux drives an interactive agent CLI inside tmux. Ollama has no agentic CLI of its own (ollama run is a bare REPL — no tool use / file edits). Design decision needed (see Open Questions): wrap an open agentic CLI that speaks to an OpenAI‑compatible endpoint and point it at Ollama. Candidates: Codex CLI configured with a custom provider base‑url, aider --model ollama/<m>, opencode, crush. Whatever we pick becomes the "ollama" provider's launch command.
B. amux's own internal LLM calls (features that call an LLM directly)
Several features call Anthropic directly and must become provider-routable (or fall back to the local model):
- Browser "Computer Use" agent —
_run_browser_agent() uses anthropic.Anthropic() + client.beta.messages.create(model="claude-sonnet-4-5") (~line 1024–1144). Ollama has no Computer‑Use API — needs an OpenAI‑compatible tool-calling loop or a documented degradation.
- YOLO auto-answers / feedback-survey auto-answers, any summarization/title generation,
/api/agent.
- Anywhere
ANTHROPIC_API_KEY / api.anthropic.com is assumed.
Current provider abstraction (what already exists to build on)
CC_PROVIDER per-session env var; _SESSION_PROVIDERS = ("claude", "codex", "gemini", "iterm2"). Touch points:
_default_model_for_provider() (~9609), _provider_label() (~9617), _provider_yolo_flag() (~9626), _strip_provider_yolo_flags() (~9634), _is_yolo_enabled() (~9664)
- Launch:
start_session() (~9944) — per-provider command build (codex ~10053, gemini ~10104)
- Restart:
_stop_session_for_restart(name, provider) (~9771)
- Status detection:
_detect_claude_status() — codex patterns (~4120–4160), gemini (~4154). Peek parity parsers _pending_input(), _agent_panel(), _live_limit_region() (contract in docs/peek-parity.md + tests/test_peek_parity.py)
- Session payload provider fields (~8710–8784); model extraction
_extract_model_from_flags() for providers without Claude JSONL
- Codex trust helper
_auto_trust_codex_dir() (~5690)
Adding a provider = implementing this whole surface for "ollama", not just a launch string.
Task checklist
Provider plumbing
Launch & lifecycle
Status detection & peek parity (docs/peek-parity.md is the contract)
Internal LLM features → provider-routable
Config / UI
Docs & cloud
Feature-parity test matrix
Every feature must pass with provider = ollama (model = GLM‑5.2, then Qwen3.5), matching Claude/Codex/Gemini behavior:
| Area |
Feature |
claude |
codex |
gemini |
ollama |
| Session |
create / start / stop / restart / resume |
✅ |
✅ |
✅ |
⬜ |
| Session |
rename (queue+history follow), archive, delete |
✅ |
✅ |
✅ |
⬜ |
| Peek |
content parity, scrollback, freshness (P1–P3) |
✅ |
✅ |
✅ |
⬜ |
| Peek |
status honesty: active/idle/waiting (P4) |
✅ |
✅ |
✅ |
⬜ |
| Send |
exactly-once + settle delay + subagent hold (P5) |
✅ |
✅ |
✅ |
⬜ |
| Steering |
queue, settle delivery, sent-history, standing instructions |
✅ |
✅ |
✅ |
⬜ |
| Auto |
auto-continue, auto-restart, YOLO auto-answers |
✅ |
✅ |
✅ |
⬜ |
| Context |
auto-compact / context tracking (or documented N/A) |
✅ |
✅ |
✅ |
⬜ |
| Board/CRM/Notes/Calendar/Scheduler |
run against a local-model session |
✅ |
✅ |
✅ |
⬜ |
| Browser agent |
/api/browser/agent drives a task |
✅ |
— |
— |
⬜ |
| Standalone |
no api.anthropic.com calls; works network-off |
— |
— |
— |
⬜ |
Success criteria
Open questions / decisions
- Which agentic CLI backs the ollama provider? Reuse Codex CLI with a custom OpenAI‑compatible provider (
base_url=http://localhost:11434/v1), or adopt aider/opencode/crush? Trade-off: parity of tool-use/agentic quality on local models vs. new status-detection surface to write.
- Browser Computer‑Use agent has no Ollama equivalent — implement an OpenAI‑tool‑calling agent loop, or mark it unsupported when standalone?
- Model naming — track the Ollama model tag (
glm-5.2, qwen3.5) in CC_FLAGS/meta the way codex/gemini models are surfaced.
- Compaction/context semantics differ per CLI — define expected behavior (native compaction vs. N/A) for the ollama path.
Note: keep the single-file rule — no env-branched cloud/OSS code paths; provider behavior is driven by CC_PROVIDER + config, not build flags.
Goal
Make amux completely standalone — runnable with no cloud LLM dependency — by adding Ollama (local models) as a first-class, fully-swappable provider alongside Claude Code, Codex, and Gemini. When a user selects Ollama, every amux feature must work identically to the cloud providers, driven by a locally-hosted model.
Definition of done: a user with only Ollama installed (no
ANTHROPIC_API_KEY, no Gemini/OpenAI keys, no network) can create sessions, run the full agentic loop, and use every dashboard feature end-to-end. Validated against GLM‑5.2 and Qwen3.5 as the reference local models.Two integration surfaces
Ollama is a local model server (
http://localhost:11434, OpenAI‑compatible at/v1), not an interactive agentic coding CLI likeclaude/codex/gemini. So "integrate Ollama" spans two distinct surfaces, both required for standalone:A. Session-driving agent (the terminal a peek renders)
amux drives an interactive agent CLI inside tmux. Ollama has no agentic CLI of its own (
ollama runis a bare REPL — no tool use / file edits). Design decision needed (see Open Questions): wrap an open agentic CLI that speaks to an OpenAI‑compatible endpoint and point it at Ollama. Candidates: Codex CLI configured with a custom provider base‑url,aider --model ollama/<m>,opencode,crush. Whatever we pick becomes the"ollama"provider's launch command.B. amux's own internal LLM calls (features that call an LLM directly)
Several features call Anthropic directly and must become provider-routable (or fall back to the local model):
_run_browser_agent()usesanthropic.Anthropic()+client.beta.messages.create(model="claude-sonnet-4-5")(~line 1024–1144). Ollama has no Computer‑Use API — needs an OpenAI‑compatible tool-calling loop or a documented degradation./api/agent.ANTHROPIC_API_KEY/api.anthropic.comis assumed.Current provider abstraction (what already exists to build on)
CC_PROVIDERper-session env var;_SESSION_PROVIDERS = ("claude", "codex", "gemini", "iterm2"). Touch points:_default_model_for_provider()(~9609),_provider_label()(~9617),_provider_yolo_flag()(~9626),_strip_provider_yolo_flags()(~9634),_is_yolo_enabled()(~9664)start_session()(~9944) — per-provider command build (codex~10053,gemini~10104)_stop_session_for_restart(name, provider)(~9771)_detect_claude_status()— codex patterns (~4120–4160), gemini (~4154). Peek parity parsers_pending_input(),_agent_panel(),_live_limit_region()(contract indocs/peek-parity.md+tests/test_peek_parity.py)_extract_model_from_flags()for providers without Claude JSONL_auto_trust_codex_dir()(~5690)Adding a provider = implementing this whole surface for
"ollama", not just a launch string.Task checklist
Provider plumbing
"ollama"to_SESSION_PROVIDERS_default_model_for_provider("ollama")→ default local model (e.g.qwen3.5)_provider_label,_provider_yolo_flag,_strip_provider_yolo_flags,_is_yolo_enabledfor ollama's autonomy flagOLLAMA_HOST), preflight check that Ollama is reachable + model pulledLaunch & lifecycle
start_session()ollama branch — build the agentic-CLI command pointed at Ollama; fresh + resume pathscodex_session_id/gemini_session_id) if the chosen CLI supports it_stop_session_for_restart()ollama handling; auto-trust/noninteractive equivalentStatus detection & peek parity (
docs/peek-parity.mdis the contract)_detect_claude_status()patterns for the ollama CLI: active spinner, idle prompt, waiting/approval, limit/error states_pending_input()+_agent_panel()parse the ollama CLI's prompt/agent UI (P5/P6)tests/test_peek_parity.py; steering exactly-once + settle behavior verifiedInternal LLM features → provider-routable
_llm_complete(...)) that targets Ollama's OpenAI‑compatible/v1when standaloneANTHROPIC_API_KEYConfig / UI
PATCHsession provider) handles ollama (see ~47556–47710)Docs & cloud
if IS_CLOUDbranches)api.anthropic.comwhen provider=ollama and no keys are set (network-off test)Feature-parity test matrix
Every feature must pass with provider = ollama (model = GLM‑5.2, then Qwen3.5), matching Claude/Codex/Gemini behavior:
/api/browser/agentdrives a taskapi.anthropic.comcalls; works network-offSuccess criteria
ANTHROPIC_API_KEY/Gemini/OpenAI keys unset and networking to cloud LLM APIs blocked, amux still: creates sessions, runs the agentic loop, and serves every dashboard feature (internal LLM features either work via Ollama or degrade with a clear message — never crash).tests/test_peek_parity.pyincludes ollama fixtures and passes.Open questions / decisions
base_url=http://localhost:11434/v1), or adoptaider/opencode/crush? Trade-off: parity of tool-use/agentic quality on local models vs. new status-detection surface to write.glm-5.2,qwen3.5) inCC_FLAGS/meta the way codex/gemini models are surfaced.Note: keep the single-file rule — no env-branched cloud/OSS code paths; provider behavior is driven by
CC_PROVIDER+ config, not build flags.