Claude Code on GPT, via LiteLLM on camden

Log
Published
Session
10 Oct 2026, 08:27 to 16:50 UTC
Project
.agents
Agent
Claude Code
Model
claude-opus-5-5
Tags

Value

3.7

■■■■ of 4

Time

3h 07m

active

Elapsed

8h 23m

wall-clock span

Commits

12

from this session

Cost

$55.22

model spend

Tokens

396k

uncached in, plus out

Tool calls

558

by the agent

Outcomes

15

10 left open

Summary

Written by the summariser

Explore whether Claude Code can run on GPT models behind codex-lb, then build a dedicated claude-openai home on a LiteLLM gateway and align GPT routing across the GPT harnesses.

Rob asked whether Claude Code could use GPT models through codex-lb, and chose LiteLLM on camden as the bridge after comparing it with CCR. The agent deployed LiteLLM with its own database, per-Mac keys, telemetry to the m7kni stack, and smoke tests that passed. It then built a claude-openai home on MBP16 that maps Claude Code's lanes to GPT models, and a live run confirmed the routing. Follow-ups added Entra SSO for the LiteLLM admin UI, an 872k context window with compaction at 85% across the GPT harnesses, caching and queue fixes, one routing map shared by claude-openai, Codex and pi, and classifier allowances after auto mode blocked two actions. A LiteLLM restart then briefly stopped loop lanes, so a Traefik fallback now returns 502 instead of 404. Most changes are pushed and rolled out to both Macs, but several checks remain open.

What came out of it

  • LiteLLM v1.104.2 deployed on camden at a private admin address with its own Postgres, a nightly dump at 02:50, and per-Mac virtual keys; eight compatibility smoke tests passed.
  • Entra SSO on the LiteLLM admin UI via a new homelab-litellm app; a browser test landed on the keys page as an admin user.
  • LAB-0023 closed: Prometheus metrics reach Mimir through a Fleet Management pipeline, Pyroscope profiles are flowing, and OTel V2 traces reach m7kni.
  • claude-openai home built and live on MBP16 (HRN-0327): commits [commit] and [commit] pushed, [commit] committed but not pushed; plugins installed, transcripts in a claude-openai namespace, config backed up to a new private repo rob/claude-openai-mbp16.
  • Live acceptance run through the claude-openai launcher: main session on gpt-6.1-sol at medium, mapper and sonnet dispatch at low, file write and Firecrawl search worked.
  • HRN-0328: retry watchdog and fail-closed guard hooks published to every Claude home; commits [commit] and [commit] pushed, [commit] committed but not pushed.
  • codex-lb advertises 872k on the four GPT-6 models; LiteLLM serves only gpt-6.1-sol, gpt-6-astra and gpt-6-luna. Codex, loop-pi and claude-openai compact at 741,200 (commits [commit] and [commit] pushed).
  • claude-openai auto mode runs on Claude Code's own classifier (CLAUDE_CODE_AUTO_MODE_SERVER=0, commit [commit]). A CLAUDE_CODE_MODEL_CAPABILITIES setting moved reminders out of system messages; warm main-session turns then cached about 99.5–99.8% (commit [commit]).
  • A LiteLLM pre-call hook gives each subagent and side call its own cache key. In a test with three parallel subagents, overall caching rose to 84% and the worst queue wait fell to 0.66 s, down from 9.5 s.
  • Routing map aligned across claude-openai, Codex and pi (HRN-0330): loop-pi [commit], agent-docs [commit] with new harness-claude-openai.md, agent-skills [commit] (agent-workflows 1.21.0), rob/agents [commit] and [commit], site [commit], public protocol repo [commit]. Pointer published to 44 consumer repos; codex-update-all ran cleanly on both Macs.
  • Pi rescue-sol renamed rescue-astra-medium; Codex poller-high dropped; retired rescue-sol.md files moved to backups on both Macs.
  • Classifier policy (commit [commit], pushed): m7kni.com trusted, wave-notify allowed, CodeRabbit reviews allowed on owned repos but not backup or customer repos. Published to Personal, Work and claude-openai.
  • LiteLLM prompt storage enabled with 90-day retention; the stale STORE_MODEL_IN_DB line was removed and the container recreated. During the recreate, clients got 502 for about 22 s and the loop lanes kept running.
  • Traefik fallback route added on camden so LiteLLM restarts return 502, which Claude Code retries, instead of 404.
  • Backlog items logged: RKB-0028 (full-detail article brief for the rob-knight-com-site backlog), HRN-0329, HRN-0331 and HRN-0332.

I wanted to see whether Claude Code could stay my harness while GPT models did the work underneath. I already had codex-lb serving GPT models, but Claude Code speaks an Anthropic-style API, so it needed a translator in between. I compared claude-code-router with LiteLLM and chose LiteLLM, running on camden, because it is a mature, auditable service that fits how I already run things in the homelab.

I deployed LiteLLM with its own database, a separate key for each Mac, and a set of compatibility smoke tests that all passed. I then built a dedicated claude-openai home on my laptop that maps Claude Code's model tiers to GPT models. A live run worked end to end: the main session ran on gpt-6.1-sol, the dispatch work ran at low effort, and file writes and web search both worked.

After that I tuned the GPT harnesses. Each one now uses an 872k context window and compacts at 85 percent. Every subagent and side call also gets its own cache key. In a test with three parallel subagents, overall cache use rose to 84 percent and the worst queue wait fell from 9.5 seconds to 0.66 seconds. Warm main-session turns were served from cache at roughly 99.5 to 99.8 percent. I also put the LiteLLM admin screen behind single sign-on.

The restart problem was the most instructive part. When I restarted LiteLLM, the proxy in front of it answered 404 for a moment. Claude Code reads a 404 as "this model doesn't exist", so it switched to its fallback model, which also returned 404, and both of my loop lanes failed. I added a low-priority fallback route so restarts return 502 instead, which Claude Code retries. I tested that during a live container recreate. For about 22 seconds requests got 502, never 404, and the lanes kept running.

Still open: the classifier allowances that let some actions through automatic mode are not yet proven, because the running session has to retry them first. Prompt bodies are stored for 90 days now, but the messages field stays empty because of an upstream bug. Some of this depends on undocumented Claude Code and LiteLLM internals, so I'll need to recheck it on upgrade. The Codex hook trust after the plugin refresh is also unverified.

Left open

  • The classifier allowances are unproven: the loop176 root still needs to retry the CodeRabbit steps and wave-notify. The agent suggested paste text for Rob to send to that session.
  • RKB-0029 (revise published articles for the route changes) needs Rob's approval before the prose changes.
  • The Codex Stop-hook trust after the plugin refresh is unverified; the README says to re-trust it in each Codex home.
  • The messages field in LiteLLM spend logs stays empty because of an upstream bug, and the UI request view was not checked.
  • The 502 fallback was exercised by one recreate during a live loop, not a full real restart test.
  • Work Codex homes going straight to OpenAI have not been tried at 872k.
  • The cache fix depends on an undocumented Claude Code setting and on LiteLLM's current adapter internals, so both need re-checking on upgrade.
  • HRN-0329: the Work preference sync on MBP16 and both GFMBP sync workers are stuck on a Claude plugin conflict; GFMBP's Codex homes were edited by hand.
  • HRN-0331 (per-spawn effort for pi) and HRN-0332 (flaky codex-update-all test under load) are logged but not started.
  • Some checkouts on both Macs with local work or diverged branches were left alone, and two GFMBP repos need a manual pull from a terminal.