---
layout: ../layouts/Base.astro
title: Projects · Jesse Anderson
description: OpenClaw bridges, Local models, Modified Codex
slug: projects
navLabel: Projects
navOrder: 2
summary: the rig, the forks, codex-local on a 9B model, operating doctrine
---

<main class="projects">
  <header class="page-header">
    <p class="eyebrow">My Projects</p>
    <h1>
        OpenClaw bridges,<br />
        <span class="accent">Modified Codex</span>, Local models<br />
    </h1>
  </header>
  <Project eyebrow="OpenClaw bridges" title="3D scenes by voice.">
    I built this so my 8-year-old could direct his <span class="accent">Roblox, Blender, and Daz</span> scenes through natural language. 
    He says "make Torus.1 50% thinner on the Z-axis," and the <span class="accent">live environment</span> updates. 
    Under the hood: an <span class="accent">AI helper bridge</span> through OpenClaw driving live scene state. 
    Three things crossed here that I cared about. 
    <span class="accent">AI</span> work. My long-running 
    <span class="accent">3DCG</span> interest. 
    <span class="accent">A kid</span> who'd already started building in Blender, Roblox Studio, and Suno.
    <ImagePlaceholder 
      src='/images/openclaw_3d_creator_bridge.png'
      alt='OpenClaw bridge: a creator-AI-3D scene editing demo'
      note='OpenClaw, Blender / Roblox / Daz via natural language'
    />
  </Project>

  <Project eyebrow="codex-local" title="What 9B can actually do." featured={true}>
    codex-local is my Codex CLI fork. I tuned it to babysit a local model through a structured task list. 
    It runs multi-turn agentic coding sessions, edits multiple files, completes the work, and does it with just Qwopus-3.5:9B underneath.

    <ProjectStats stats={[
        ['9B', 'parameters (Qwopus-3.5:9B)'],
        ['20+', 'turns of sustained coherence'],
        ['10+', 'files edited per prompt'],
        ['20', 'Model steering nudges']
    ]} />

    What makes this work isn't the model. It's everything I built around it:

    1. **Trim the tool menu** — Codex has ~120 tools. <span class="accent">Small models get confused by big menus</span>; we show them ~10.
    1. **Plain-English tool cheat sheet** — We paste simple "<span class="accent">here's how each tool works</span>, with an example" text into the system prompt.
    1. **Rewrite shell-ish tool names** — <span class="accent">Models call `ls`, `cat`, `grep` like tools</span>. We catch that and convert to a proper `shell` call.
    1. **Browser user-agent for curl** — Sites block `curl/8.0`. <span class="accent">We auto-add a real browser UA</span> to any curl command.
    1. **Web search + web fetch** — No <span class="accent">built-in web search in local mode</span>, so we added two tools for looking up real API docs.
    1. **Fix broken patches** — <span class="accent">Small models mangle patches</span>: (a) write git-diff format, (b) leave `@@ -1,6 +1,6 @@` line numbers, (c) forget `+` prefixes and closing markers. We fix all three automatically.
    1. **<span class="accent">Better patch error messages</span>** — Default errors are cryptic. We rewrote the common ones to explain what to try next.
    1. **Better network errors** — Instead of "error sending request", <span class="accent">we show the real cause</span> (DNS, TLS, connection refused, etc.).
    1. **<span class="accent">Catch announce-without-act</span>** — When the model says "Now I'll do X" and stops, a judge model spots it and we re-prompt "take the action." Up to 3 retries.
    1. **<span class="accent">Stop repetition</span>** — (a) Same tool + same args 3× → STOP block in next prompt. (b) Same file failing 3× with different commands → same STOP block.
    1. **<span class="accent">Trim old conversation</span>** — Keep the most recent turn intact, summarize older turns, drop stale file reads, pin errors so the model can't forget them.
    1. **Log the model's thinking** — <span class="accent">Reasoning text goes to debug</span> logs so we can explain weird behavior later.
    1. **Reroute wrong picks** — If the router picked "text-only model" but the conversation has tool calls, <span class="accent">we upgrade to the tool-capable Coder</span>.
    1. **<span class="accent">Diagnostic logs</span>** — Extra logging for "which tools did we pass?", "did the STOP fire?", "what did the bail judge decide?"
    1. **LM Studio / OpenAI-compat support** — Ollama and OpenAI-style servers disagree on URLs, payload shape, tool-call encoding, etc. <span class="accent">A "flavor" switch</span> lets one codebase talk to both.
    1. **Token + time budget knobs** — New per-role <span class="accent">`max_tokens` and `timeout_seconds`</span> in `config.toml`. Set either to `0` for unlimited (reasoning models need this).
    1. **Pin current file contents** — Models forget a file changed and generate patches based on the old version. <span class="accent">We pin live on-disk contents</span> at the top of the prompt.
    1. **Catch thinking loops** — <span class="accent">Some models spiral</span>: "Actually, wait. Hmm. Let me reconsider." We watch the stream for 6+ self-doubt phrases after half the token budget is burned, abort mid-generation, and re-prompt "stop second-guessing."
    1. **Stream the coder's output** — To make the anti-spiral work, we switched from "send, wait, parse" to "<span class="accent">open stream, watch tokens, abort if needed</span>." Also lets us log reasoning in real time.
    1. **<span class="accent">Skip extras in local-only mode</span>** — Normally a router, reasoner, and compactor help the main model. Locally we can't afford extras, so the Coder handles everything.

    Most local-model coding agents stall the moment a task goes past trivial. With these nudges in place, 9B parameters really work. 
  </Project>

  <Project>
    <ImagePlaceholder
        src='/images/local_models_potato.png'
        alt='Running local models effectively on a potato'
        note='Running local models effectively on a potato'
    />
    - **Main workstation:**<br />
      &nbsp;&nbsp;• <span class="accent">3080 10GB</span> + <span class="accent">1080 8GB</span> (Monitor hooked up to Intel iGPU)<br />
      &nbsp;&nbsp;• 13th Gen i9 + 64GB DDR5 6800<br />
    - **Laptop:**<br />
      &nbsp;&nbsp;• <span class="accent">3080 8GB</span> (Screen running from Intel iGPU)<br />
      &nbsp;&nbsp;• 11th Gen i7 + 32GB DDR4 3200<br />
    - **LLM Servers:**<br />
      &nbsp;&nbsp;• Ollama - main install (Using <span class="accent">`OLLAMA_FLASH_ATTENTION=1`</span> and <span class="accent">`OLLAMA_KV_CACHE_TYPE=q8_0</span>)<br />
      &nbsp;&nbsp;• llama.cpp - used to try MoE models across both GPUs and CPU offloading<br />
      &nbsp;&nbsp;• LM Studio - used for qwopus (doesn't run in Ollama)<br />
    - **Tested Models (3080 10GB):**<br />
      &nbsp;&nbsp;• gemma4:e4b<br />
      &nbsp;&nbsp;• gemma4:e4b-q6_k (<span class="accent">Impressive runner-up</span>) <br />
      &nbsp;&nbsp;• qwen3.5:9b-opus-openclaw-distilled-iq4_xs<br />
      &nbsp;&nbsp;• qwen3.5:9b-opus-openclaw-distilled-q4_k_m<br />
      &nbsp;&nbsp;• qwen3.5:9b-opus-openclaw-distilled-q6_k<br />
      &nbsp;&nbsp;• qwen3:14b-iq4_xs<br />
      &nbsp;&nbsp;• qwopus3.5:9b-v3-q6_k (<span class="accent">WINNER!</span>)
    - **Tested Models (3080 8GB):**<br />
      &nbsp;&nbsp;• deepseek-r1:8b<br />
      &nbsp;&nbsp;• qwen3.5:9b-uncensored-aggressive-q4_k_m<br />
    - **Tested Models (1080 8GB):**<br />
      &nbsp;&nbsp;• qwen3:4b<br />
      &nbsp;&nbsp;• qwen3:8b<br />
      &nbsp;&nbsp;• qwen3.5:9b-iq4_nl<br />
      &nbsp;&nbsp;• qwen3.5:9b-q4_k_m (<span class="accent">works great as a classifier!</span>)<br />
    - **Tested Models (3080 + 1080 18GB):**<br />
      &nbsp;&nbsp;• devstral-small-2:Q4_K_M (<span class="accent">CPU offload</span>)<br />
      &nbsp;&nbsp;• gemma-4-26b-a4b-it:Q4_K_M (<span class="accent">CPU offload</span>)<br />
      &nbsp;&nbsp;• qwen3.5:35b-a3b (<span class="accent">CPU offload</span>)<br />

  </Project>

  {/*
  <Project eyebrow="coding-agent-router" title="Multi-agent CLI routing.">
    A multi-agent CLI router with the same docs-first discipline. It routes prompts across specialized workers that share context. 
    The starting assumption: no single model is the right choice for every step in a long task. 
    It pairs with codex-local on the local side and with cloud providers when something needs the bigger model.
  </Project>
  */}

  <Project eyebrow="Operating doctrine" title="How I actually work with AI.">
    - **<span class="accent">Find the upstream fix.</span>** Mitigations, fallbacks, band-aids are the worst. If we don't own upstream, then mitigate.
    - **Docs-first.** Then architecture. Docs are <span class="accent">load-bearing artifacts</span> the agent reads on every turn.
    - **Long autonomous runs are normal.** I let <span class="accent">agents work overnight regularly</span>.
    - **State in files, not in-context.** Long runs <span class="accent">survive</span> crashes, context exhaustion, model swaps, and OAuth expirations. The agent rehydrates from disk.
    - **No green-by-inference.** <span class="accent">Verify before declaring done.</span> Check the deployed version, inspect the running process, read the Discord channel.
    - **<span class="accent">AI is infrastructure</span>, the same as a database.** I instrument it, test it in tiers (hermetic, e2e, live-canary), 
      and put silent failures on a heartbeat (OAuth expiry, model health) the same way I'd put a dead database on one.
    - **<span class="accent">Platform-engineering reflexes</span> don't go away just because it's AI.** 
      I want redundancy, failover, quick recovery, auto-scaling, and reproducible deployment, with low operational overhead.
  </Project>

</main>
