# AI Fleet — Local LLM Upgrade Install Plan *Built from Gemini Deep Research output, 2026-05-15* *Audience: Jonathan (human) + Gemini CLI follow-up* --- ## Executive Summary Based on Gemini's May 2026 LLM evaluation, the AI Fleet bake-off failures (qwen3:32b, deepseek-r1:32b) are caused by **server-side Ollama bugs**, not the models themselves. The fix is a combination of: 1. **Modelfile patches** for Qwen3 family (Ollama issue #14601) 2. **Harness changes** to `local-agent.py` (prefix cache normalization, context window, temperature) 3. **New model evaluation** of Gemma 4 26B MoE and Mistral Small 4 (with caveats below) 4. **Tier 1B (EVO-T1)** unblocked via IPEX-LLM `[cpp]` pip path once drivers resolve **Keep `qwen2.5-coder:32b` as Tier 1A baseline.** Don't replace it until alternatives prove out. --- ## ⚠️ Claims to Verify Before Acting Gemini's report has a few claims I couldn't independently verify. Treat them as hypotheses, not facts: | Claim | Why suspect | How to verify | |---|---|---| | Mistral Small 4 is "119B MoE, fits comfortably in 24GB VRAM at 4-bit" | Math doesn't work: 119B × 4 bits = ~60GB weights alone. MoE doesn't free VRAM by default | Check `huggingface.co/mistralai` and `ollama.com/library/mistral-small` for actual size + memory footprint | | Tau2-bench 86.4% (Gemma 4 31B) vs 6.6% (Gemma 3) | Specific benchmarks unverified | Cross-check Gemma 4 model card on ai.google.dev | | `ipex-llm[cpp]==2.3.0b20251029` + Ollama v0.9.3 | Very specific version pin | Check Intel's IPEX-LLM GitHub for current stable | | Mass 403 ToS bans on OAuth Gemini CLI in Feb/Apr 2026 | Policy claim, needs confirmation | Check google AI dev forum + your own Gemini Pro account status before changing auth | | `geminicli.com` malicious | ✅ Already confirmed from prior analysis + multiple security citations | No action — block at firewall | **Action: Spot-check the Mistral Small 4 sizing before pulling it (it's a ~60GB download otherwise).** --- ## Phase 0 — Pre-flight (do these first, ~10 min) All commands run from EVO-T1 (`claude-server-evo`, 10.0.0.56) unless noted. ### 0.1 Verify Ollama version on JONATHAN-PC ```bash ssh administrator@10.0.0.199 'powershell -c "(Invoke-WebRequest http://localhost:11436/api/version -UseBasicParsing).Content"' ``` **Acceptance:** Ollama version ≥ 0.5.0 (needed for the Modelfile template fix). Upgrade if older. ### 0.2 Check disk space for new models ```bash ssh administrator@10.0.0.199 'powershell -c "Get-PSDrive C | Select-Object Used,Free"' ``` **Acceptance:** ≥ 100 GB free. Mistral Small 4 (if claim is right) is ~60 GB; Gemma 4 26B MoE is ~16 GB. ### 0.3 Confirm current baseline still works ```bash cd /home/claude/ai-fleet ./tests/runners/run-routing.sh # must pass 50/50 python3 scripts/local-agent.py \ --task "Add a comment to scripts/dispatch.sh explaining tier 0" \ --repo /home/claude/ai-fleet \ --model qwen2.5-coder:32b \ --backend http://10.0.0.199:11436 \ --dry-run --max-turns 10 ``` **Acceptance:** Status=success, valid commit. This is the regression baseline. ### 0.4 Pull research citation evidence (for sanity) Before pulling a 60GB model, verify the size: ```bash # Check Ollama library page curl -s https://ollama.com/library/mistral-small | grep -iE "size|param" # Or check HF curl -s https://huggingface.co/api/models/mistralai/Mistral-Small-4 | jq . ``` --- ## Phase 1 — Fix Qwen3 family (high-value, low-risk) Per Gemini's report (cross-referenced with Ollama issue #14601), the Qwen3 Go-struct bug has a known Modelfile fix. ### 1.1 SSH to JONATHAN-PC and inspect the qwen3 Modelfile ```bash ssh administrator@10.0.0.199 'powershell -c "ollama show qwen3:32b --modelfile"' > /tmp/qwen3-modelfile.txt grep -n "Function" /tmp/qwen3-modelfile.txt ``` ### 1.2 Apply the template fix The fix is replacing `{{.Function }}` with `{{.Function | json }}` in the template. Then create a custom model: ```bash # Save patched Modelfile to JONATHAN-PC # Then on JONATHAN-PC: ollama create qwen3-fixed:32b -f C:\Tools\qwen3-fixed.Modelfile ``` ### 1.3 Re-run bake-off with patched model ```bash python3 scripts/local-agent.py \ --task "Add --help flag to scripts/dispatch.sh (include tier descriptions)" \ --repo /home/claude/ai-fleet \ --model qwen3-fixed:32b \ --backend http://10.0.0.199:11436 \ --max-turns 20 ``` **Acceptance:** Task completes in ≤ 12 turns. If it stalls, revert to qwen2.5-coder. --- ## Phase 2 — Test Gemma 4 26B MoE (the safer new model) Gemma 4 26B MoE math checks out (~15.6 GB Q4_K_M, fits 24 GB with headroom). This is the lower-risk model to add. ### 2.1 Pull Gemma 4 26B MoE on JONATHAN-PC ```bash ssh administrator@10.0.0.199 'powershell -c "ollama pull gemma4:26b"' # Verify the tag exists first by browsing ollama.com/library/gemma4 # If the tag differs (e.g. gemma4:26b-instruct-q4_K_M), adjust ``` ### 2.2 Critical: enable Jinja template parsing Per Gemini's report, Gemma 4 needs `--jinja` flag set or it enters infinite tool-call loops. Ollama uses Jinja by default in recent versions, but verify: ```bash ssh administrator@10.0.0.199 'powershell -c "ollama show gemma4:26b --template"' ``` Confirm the template uses `tool_response` blocks (not plain text injection). ### 2.3 Bake-off test ```bash python3 scripts/local-agent.py \ --task "Add --help flag to scripts/dispatch.sh (include tier descriptions)" \ --repo /home/claude/ai-fleet \ --model gemma4:26b \ --backend http://10.0.0.199:11436 \ --max-turns 20 ``` ### 2.4 If infinite-loop bug appears Symptom: model calls same tool repeatedly because it can't "see" prior tool results. Fix: ensure `local-agent.py` injects tool results in the format Gemma's template expects (structured `tool_response`, not plain content text). --- ## Phase 3 — Test Mistral Small 4 (CONDITIONAL — verify sizing first) **DO NOT pull until you've confirmed it actually fits in 24 GB.** Gemini's report says 119B MoE Q4 fits in 24GB which is mathematically impossible without expert offloading. Either: - The model is smaller than claimed (some Mistral variants are 22B/24B "Small"), or - The fit requires CPU offloading with major speed cost ### 3.1 Verify model size ```bash curl -s https://huggingface.co/api/models/mistralai/Mistral-Small-4-Instruct-2503 | jq '.safetensors.total' # Or check the unsloth GGUF page Gemini cited: huggingface.co/unsloth/Mistral-Small-4-119B-2603-GGUF ``` ### 3.2 If actually ≤ 25 GB at Q4_K_M Proceed to pull and bake-off: ```bash ssh administrator@10.0.0.199 'powershell -c "ollama pull mistral-small:4-q4_K_M"' python3 scripts/local-agent.py \ --task "Add --help flag to scripts/dispatch.sh (include tier descriptions)" \ --repo /home/claude/ai-fleet \ --model mistral-small:4-q4_K_M \ --backend http://10.0.0.199:11436 \ --max-turns 20 ``` ### 3.3 If actually 60GB+ Skip Mistral Small 4 for Tier 1A. Either: - Use a smaller Mistral variant (Mistral Nemo 12B — fits anywhere) - Wait until EXL2/AWQ deployment for 4090 (TabbyAPI plan) - Test on EVO-T1 with offload only if it has serving infra --- ## Phase 4 — Harness changes to `local-agent.py` Pure code changes, no model pulls. Test against qwen2.5-coder:32b baseline. ### 4.1 Prefix-cache normalization (strip empty think blocks) In the message-trimming logic around line 431-432 of `local-agent.py`, before sending messages to Ollama: ```python def _strip_empty_think_blocks(messages): cleaned = [] for m in messages: content = m.get("content") or "" # Strip empty blocks that break prefix cache content = re.sub(r"\s*", "", content) cleaned.append({**m, "content": content}) return cleaned ``` Call this before every `call_llm()`. Expected impact: 30-50% latency reduction on thinking models per Gemini's report. ### 4.2 Context window enforcement Line 592 — change default `--num-ctx` from `8192` to `32768`: ```python parser.add_argument("--num-ctx", type=int, default=32768, ...) ``` **Why:** 8K is too small for repository-level work. Ollama silently crops longer inputs. ### 4.3 Temperature per model class In `call_llm()` around line 346, currently `temperature: 0.1`. Add model-class branching: ```python THINKING_MODELS = ("qwen3", "deepseek-r1", "gemma4") # raise temp for these temperature = 1.0 if any(m in model for m in THINKING_MODELS) else 0.1 top_k = 40 if any(m in model for m in THINKING_MODELS) else None ``` **Why:** Low temp causes thinking-model loops. Gemini's report claims raising to 1.0 stabilizes reasoning. ### 4.4 Acceptance test for harness changes ```bash # Regress against baseline first python3 scripts/local-agent.py --model qwen2.5-coder:32b ... --dry-run # Must still pass — these changes shouldn't break the working model # Then re-test the previously-failing models python3 scripts/local-agent.py --model qwen3:32b ... --max-turns 20 python3 scripts/local-agent.py --model deepseek-r1:32b ... --max-turns 20 ``` --- ## Phase 5 — Tier 1B (EVO-T1) — wait until drivers resolved Currently blocked on Intel GPU PPA (kobuk-team) per `plans/SESSION-RESUME.md`. Once that's fixed: ### 5.1 Install IPEX-LLM via pip path (NOT the portable zip) Per Gemini's recommendation (cite #6, #7 — Reddit IPEX-LLM solutions): ```bash ssh claude@10.0.0.56 'pip install --pre --upgrade ipex-llm[cpp]' # Verify the version Gemini cited (2.3.0b20251029) — but use whatever's current stable ``` ### 5.2 Run Ollama via IPEX-LLM init script ```bash ssh claude@10.0.0.56 ' source /opt/intel/oneapi/setvars.sh init-ollama # creates symlinks to IPEX-LLM accelerated binary OLLAMA_HOST=0.0.0.0:11434 ollama serve & ' ``` ### 5.3 Pull 12-14B model Three candidates, in order of preference: 1. **Mistral Nemo 12B** — Quantization-aware trained, 128K context, fits 8GB Arc 2. **Qwen 3 Coder 14B** — Best SWE-bench at this size, may need offload for >8K context 3. **Gemma 4 E4B** — Fastest option, multimodal support ```bash ssh claude@10.0.0.56 'ollama pull mistral-nemo:12b-instruct-q4_K_M' ``` ### 5.4 Acceptance - Inference at ≥ 12 tps for sustained generation - Tool calling works end-to-end on same `--help` benchmark task --- ## Phase 6 — Security cleanup (do alongside Phase 4) ### 6.1 Confirm geminicli.com isn't reachable ```bash # Block at UniFi firewall as belt-and-suspenders # Add DNS sinkhole or firewall rule for geminicli.com → 0.0.0.0 ``` ### 6.2 Audit Gemini CLI installation ```bash which gemini npm ls -g @google/gemini-cli # If any non-@google namespace gemini package is installed, uninstall ``` ### 6.3 Verify Gemini CLI version ≥ 0.39.1 (CVSS 10.0 patch) ```bash gemini --version # if installed ``` ### 6.4 Authentication review (low priority, verify claim first) Gemini's report claims OAuth-based CLI users got mass-banned in Feb/Apr 2026. Before changing anything: 1. Check current `/delegate` flow auth method 2. Verify with current Google AI dev forum status 3. If true, migrate to API-key auth via Google AI Studio 4. If false, no change needed --- ## Phase 7 — Acceptance & Rollback ### 7.1 Definition of done - Baseline `qwen2.5-coder:32b` still completes the bake-off task (no regression) - At least one previously-failing model (qwen3 or deepseek-r1) now completes the task with the Modelfile fix + harness changes - Gemma 4 26B MoE either completes the task OR is documented as "needs Jinja work" - Mistral Small 4 either tested or explicitly ruled out (sizing claim verified) - All harness changes regression-tested against baseline - Tier 1B unblocked (EVO-T1 drivers + 12B model serving) ### 7.2 Rollback if something breaks ```bash cd /home/claude/ai-fleet git status # see what changed git stash # stash harness changes # qwen2.5-coder:32b on baseline harness is always the fallback ``` ### 7.3 Commit changes only after acceptance ```bash git add scripts/local-agent.py git commit -m "feat(local-agent): prefix cache norm, num_ctx 32K, temp per model class" ``` --- ## Open Questions for Gemini Follow-up Research If you want to ping Gemini again, these are the still-unresolved questions: 1. **Mistral Small 4 actual VRAM footprint at Q4_K_M** — is it really 119B? Is there a way to fit it in 24GB without major offload penalty? 2. **Exact Ollama Modelfile template diff** for qwen3 fix — Gemini said `{{.Function}}` → `{{.Function | json}}` but didn't show the full template 3. **Current stable IPEX-LLM version** as of May 15, 2026 — the report cited a beta build, want current stable 4. **OAuth ban status** — is this actually affecting `/delegate` or only `gemini-cli` direct OAuth users? 5. **TabbyAPI EXL2 path for the 4090** — when EXL2 is deployed (post-Phase 5), does Gemma 4 or Qwen 3 Coder have EXL2 quants available? --- ## Order of Operations (TL;DR for execution) 1. **Phase 0** — Pre-flight, 10 min 2. **Phase 1** — Fix Qwen3 Modelfile, 30 min 3. **Phase 4** — Harness changes (parallel with Phase 1), 1 hr 4. **Phase 2** — Test Gemma 4 26B MoE, 1 hr (includes ~16GB pull) 5. **Phase 6** — Security cleanup, 15 min 6. **Phase 3** — Mistral Small 4 (CONDITIONAL on sizing verification) 7. **Phase 5** — EVO-T1 Tier 1B (BLOCKED until drivers resolve, do separately) 8. **Phase 7** — Acceptance + commit Total active work: ~3-4 hours, plus EVO-T1 work when unblocked.