aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-07-13 23:05:00 -0500
committerCraig Jennings <c@cjennings.net>2026-07-13 23:05:00 -0500
commit1b98a9ed2acff1605895700302ff276ba88baa5b (patch)
tree77a25a0c4b2ce2f6b318de914a34de0f3b4fad8f
parent21d14e0752fa8438a7ea299402e6680c3bc25062 (diff)
downloadrulesets-1b98a9ed2acff1605895700302ff276ba88baa5b.tar.gz
rulesets-1b98a9ed2acff1605895700302ff276ba88baa5b.zip
feat(launcher): wire the local runtime — codex --oss over ollama
ai --runtime local now launches codex against the machine's ollama (explicit --local-provider=ollama, model from AI_LOCAL_MODEL, default gpt-oss:120b). Verified end to end with a codex exec completion through the local model. The dependency check probes AGENT_BIN now that AGENT_CMD carries flags. This makes codex-over-ollama the de-facto answer to the runtime spec's first-supported-local-CLI blocker.
-rwxr-xr-xclaude-templates/bin/ai32
-rw-r--r--scripts/tests/ai-launcher-runtime.bats13
-rw-r--r--todo.org3
3 files changed, 30 insertions, 18 deletions
diff --git a/claude-templates/bin/ai b/claude-templates/bin/ai
index c09faab..c805e8b 100755
--- a/claude-templates/bin/ai
+++ b/claude-templates/bin/ai
@@ -11,9 +11,10 @@
# in the 'ai' session (new window or switch to existing).
# Use '.' for current directory. Git prep per dir.
#
-# ai --runtime <rt> Launch with a different agent CLI: claude (default) or
-# codex. 'local' is reserved for a local-LLM CLI, pending
-# the model evaluation. Also settable via AI_RUNTIME.
+# ai --runtime <rt> Launch with a different agent CLI: claude (default),
+# codex, or local (codex --oss against this machine's
+# ollama; model per AI_LOCAL_MODEL, default gpt-oss:120b).
+# Also settable via AI_RUNTIME.
#
# ai --attach Attach to the existing 'ai' session without changes.
#
@@ -30,20 +31,21 @@
SESSION="ai"
RUNTIME="${AI_RUNTIME:-claude}"
-
-# Map the runtime name to the agent CLI a pane launches. Both current CLIs
-# take the opening instructions as a positional prompt, so only the command
-# name varies; a runtime whose CLI needs different plumbing gets its own case.
+LOCAL_MODEL="${AI_LOCAL_MODEL:-gpt-oss:120b}"
+
+# Map the runtime name to the agent CLI a pane launches. All three take the
+# opening instructions as a positional prompt. AGENT_BIN is the binary the
+# dependency check probes; AGENT_CMD is the full launch command (the local
+# runtime rides codex's open-source provider against the machine's ollama —
+# model per AI_LOCAL_MODEL, default gpt-oss:120b, verified on ratio's
+# Strix Halo 2026-07-13).
resolve_agent_cmd() {
case "$RUNTIME" in
- claude) AGENT_CMD="claude" ;;
- codex) AGENT_CMD="codex" ;;
- local)
- echo "ai: the 'local' runtime is reserved but not wired yet (pending the local-model evaluation) — valid runtimes: claude, codex" >&2
- exit 2
- ;;
+ claude) AGENT_BIN="claude"; AGENT_CMD="claude" ;;
+ codex) AGENT_BIN="codex"; AGENT_CMD="codex" ;;
+ local) AGENT_BIN="codex"; AGENT_CMD="codex --oss --local-provider=ollama -m $LOCAL_MODEL" ;;
*)
- echo "ai: unknown runtime '$RUNTIME' — valid runtimes: claude, codex" >&2
+ echo "ai: unknown runtime '$RUNTIME' — valid runtimes: claude, codex, local" >&2
exit 2
;;
esac
@@ -73,7 +75,7 @@ usage() {
}
check_deps() {
- for cmd in fzf tmux "$AGENT_CMD"; do
+ for cmd in fzf tmux "$AGENT_BIN"; do
if ! command -v "$cmd" &>/dev/null; then
echo "ai: $cmd is not installed" >&2
exit 1
diff --git a/scripts/tests/ai-launcher-runtime.bats b/scripts/tests/ai-launcher-runtime.bats
index 4ec24bf..b93f778 100644
--- a/scripts/tests/ai-launcher-runtime.bats
+++ b/scripts/tests/ai-launcher-runtime.bats
@@ -38,10 +38,17 @@ teardown() {
[[ "$output" == codex\ * ]]
}
-@test "--runtime local is reserved and says why it is not wired" {
+@test "--runtime local launches codex --oss over ollama with the default local model" {
run bash "$AI" --runtime local --print-launch "$PROJ"
- [ "$status" -eq 2 ]
- [[ "$output" == *"not wired"* ]]
+ [ "$status" -eq 0 ]
+ [[ "$output" == "codex --oss --local-provider=ollama -m gpt-oss:120b "* ]]
+ [[ "$output" == *"protocols.org"* ]]
+}
+
+@test "AI_LOCAL_MODEL overrides the local runtime's model" {
+ AI_LOCAL_MODEL=qwen3-coder:30b run bash "$AI" --runtime local --print-launch "$PROJ"
+ [ "$status" -eq 0 ]
+ [[ "$output" == "codex --oss --local-provider=ollama -m qwen3-coder:30b "* ]]
}
@test "an unknown runtime errors and names the valid ones" {
diff --git a/todo.org b/todo.org
index 8f85e44..42dd8f0 100644
--- a/todo.org
+++ b/todo.org
@@ -293,6 +293,9 @@ Analysis in [[file:docs/design/2026-07-13-runtime-portability-inventories.org]]
*** 2026-07-13 Mon @ 13:34:17 -0500 Hook parity inventoried — only two hooks carry real porting work
Full mapping in [[file:docs/design/2026-07-13-runtime-portability-inventories.org]]. AskUserQuestion deny is moot off Claude (no popup tool to deny); PostToolUse validators survive via the bundles' git pre-commit hooks; clear-resume folds into the session-plumbing child; session-title is cosmetic. Real gaps: PreCompact priority-save (prose downgrade) and Stop wrap-teardown (Codex notify / manual elsewhere) — decisions in the VERIFY below.
+*** 2026-07-13 Mon @ 23:04:21 -0500 Local runtime wired — ai --runtime local runs codex --oss over ollama
+The reserved lane went live the same day: =local= maps to =codex --oss --local-provider=ollama -m $AI_LOCAL_MODEL= (default gpt-oss:120b; qwen3-coder:30b via the env var). Verified end to end: =codex exec --oss --local-provider=ollama -m gpt-oss:120b= returned a correct completion through the local model (~7K tokens). The explicit provider flag avoids config.toml dependence (a root-level =oss_provider= key would also work; appending to the file lands in the last TOML table and silently does nothing — learned live). Dependency check keys on AGENT_BIN (codex) now that AGENT_CMD carries flags. This partially answers the spec's "first supported local editing CLI" blocker: codex-over-ollama is the de-facto v1. The model-floor child's live trial (a takuzu session under =ai --runtime local=) is the next step.
+
*** 2026-07-13 Mon @ 16:39:41 -0500 Launcher runtime flag built — ai --runtime claude|codex
Shipped TDD (new =scripts/tests/ai-launcher-runtime.bats=, 6 tests red→green): =--runtime= flag + =AI_RUNTIME= env on =bin/ai=, runtime→CLI mapping (claude default, codex 1:1 — both take the opening line as a positional prompt), runtime-aware dependency check, =local= reserved with a clear not-wired-yet error (pending the model-floor evaluation), and a =--print-launch= mode as the test seam (prints the pane launch command, no tmux/fzf). Kept small per the 2026-06-24 helper-task caveat — dispatch pre-parse only, no launcher restructure. The Emacs-side equivalent (ai-term multi-LLM) remains .emacs.d's June handoff. Live smoke: correct commands for both runtimes against real projects.