Skip to content

v0.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 22:07
8821644

A codex subscription can now be a rung in the waterfall. It is a full
participant -- tool calls work -- so it can sit anywhere in the chain rather
than only at the bottom.

Codex subscription as a waterfall rung (#35)

Every other rung is an api_key HTTP row that LiteLLM dials from config alone.
A codex subscription is not: it authenticates with the ChatGPT OAuth tokens
the codex CLI keeps in ~/.codex/auth.json, and it speaks the Responses API
rather than chat/completions. shmobster/codex_llm.py bridges that as an
in-process litellm.CustomLLM -- there is no second process to run under
launchd.

One keyless row enables it:

{"name": "codex", "model": "codex/chatgpt/gpt-5.5"}

The chatgpt/ segment is load-bearing, not decoration. LiteLLM dispatches on
the model name before it dispatches on the custom provider, so a row of
codex/gpt-5.5 leaves it holding the bare gpt-5.5, recognising that as an
OpenAI model, and quietly billing a platform API key -- the bridge is never
reached, and if OPENAI_API_KEY happens to be valid there is no error at all.
The segment is stripped back off before the request goes out. Written up
generically as
skillz#181.

Two more things the live endpoint dictates, neither of them documented:

  • stream: true is mandatory. A non-streaming request is refused outright
    with 400 Stream must be set to true, so the SSE body is read whole and parsed
    even though nothing downstream streams.
  • The model must be one your ChatGPT plan allows. gpt-5.5 works;
    gpt-5.1-codex is refused with "not supported when using Codex with a ChatGPT
    account"
    .

Why read codex's token instead of driving the binary. The alternatives were
codex exec or the codex app-server JSON-RPC that OpenClaw's codex extension
speaks. Both keep the token out of our hands, but both hand us an agent: codex
brings its own tool set, sandbox and approval policy, and shmobster already owns
that loop (handler + YOLT gate + channel policy). Nesting a second agent inside
one waterfall rung buys nothing here, and codex exec additionally returns final
text only -- no tool calls.

Token rotation stays yours. auth.json is re-read on every call, so any
rotation the codex CLI performs is picked up without a restart. shmobster
deliberately does not refresh it: that would mean writing back to auth.json
and racing the CLI over a refresh token that may be single-use, and breaking your
actual codex login is worse than one dead rung. Instead the token's own exp is
read per call:

codex: the ChatGPT token expires in ~19h; run `codex login` to rotate it

logged at most hourly so a busy channel does not turn it into spam. Once expired
the rung returns 401, LiteLLM cools it, and the chain falls through. Either way
the fix is codex login -- or just using the codex CLI for anything, which
rotates the file as a side effect.

Upgrading

git pull
.venv/bin/pip install -r requirements.txt
.venv/bin/python selfcheck.py
deploy/service.sh restart
  • Nothing is required. No new dependency, and no config change unless you
    want the codex rung.
  • To enable it, add the keyless row above to your waterfall. It needs a
    codex login on that machine (codex login); CODEX_HOME is honoured if you
    set it. Verify with codex login status before restarting.
  • If you add the row, do not shorten the model string. codex/gpt-5.5
    without the chatgpt/ segment silently routes to OpenAI on your platform key
    instead of your subscription -- see above.
  • Keyless rows are now supported generally. A waterfall entry may omit
    api_key entirely; previously an absent key was still passed through as empty.
    Existing rows are unaffected.