codexcomp
Codex + Complete — a lightweight local proxy that folds gpt-5.5's "516" reasoning truncation into complete, untruncated answers for the OpenAI Codex CLI.
English · 简体中文
uv tool install codexcomp # install
codexcomp # run (127.0.0.1:8787)
# then append to ~/.codex/config.toml: openai_base_url = "http://127.0.0.1:8787/v1"
It overrides the built-in provider's base URL in place — model_provider is unchanged,
so session grouping, remote compaction, and remote-control keep working.
Credits. The detect-and-continue mechanism originates from neteroster/CodexCont (MIT); this is an independent, from-scratch implementation that keeps the built-in provider intact.
The problem
gpt-5.5's reasoning is intermittently truncated at reasoning_tokens == 518·n − 2
(516, 1034, 1552, …): the turn stops mid-reasoning and answers from an incomplete
thought, degrading quality sharply. Aggregate telemetry in the upstream report shows ~44 %
of gpt-5.5 responses that reach 516 reasoning tokens end at exactly that boundary — an
upstream defect with no official fix
(openai/codex#30364).
codexcomp sits on 127.0.0.1 between Codex and the upstream Responses API. On a 518n−2
truncation it drives the model to keep reasoning and folds the extra rounds into a single
downstream response — Codex sees one complete, untruncated answer.
Features
- Detect → continue → fold — spots the
518n−2fingerprint, replays the round's reasoning with a continue nudge, and folds all rounds into one response. - Zero-footprint wiring — one official top-level
openai_base_urlkey; no[model_providers]entry, no provider id change, no session re-bucketing. - WebSocket-first transport — native
responses_websocketsprotocol (envelope frames, serial connection reuse, prewarm); no "Falling back" noise in Codex logs. - Resilient SSE fallback — the POST path transparently decompresses zstd/gzip upstream responses.
- Full
/v1/*passthrough — includingGET /v1/models(model catalog refresh). - Protocol-faithful headers & compaction — upstream response headers reach Codex on the
POST path (
x-codex-*rate-limit snapshots,x-models-etag, request ids), thex-codex-turn-statesticky-routing token is replayed across fold rounds when the upstream issues one, and remote-compaction requests are never folded. - Live streaming — reasoning streams in real time even mid-fold; only the final clean round's output is released downstream.
- Honest accounting — the true cumulative cost of folded rounds is reported under
metadata.proxy_billed_usage. - Loopback-only, auth passthrough — forwards Codex's
Authorizationheader; never reads, persists, or logs a credential. - Opt-in autostart — installation registers nothing; one command sets up a systemd user unit (Linux/WSL) or LaunchAgent (macOS).
Quick start
Requires uv and the Codex CLI (ChatGPT OAuth; tested on 0.142.x).
uv tool install codexcomp # from PyPI
# uv tool install git+https://github.com/dzshzx/codexcomp # or from source
codexcomp # foreground, 127.0.0.1:8787
Point Codex at the proxy with one top-level config key:
# ~/.codex/config.toml (top level, before the first [table])
openai_base_url = "http://127.0.0.1:8787/v1"
That's it. Disable by removing that line and stopping the proxy; upgrade / uninstall with
uv tool upgrade codexcomp / uv tool uninstall codexcomp.
How it works
A state machine (codexcomp/fold.py) runs per round:
- Detect —
reasoning_tokens == 518n − 2(any tier by default; cuts up to n=21 observed — see--max-n/--max-continue) marks the round as truncated. - Continue — discard the tentative output and replay the round's reasoning items (incl.
encrypted_content) plus onephase:"commentary""Continue thinking..."message as the next input. - Fold — stream reasoning live, flush only the final clean round, and rebuild the terminal
event as one response (reasoning summed, true cost under
metadata.proxy_billed_usage).
CLI reference
| Command | Description |
|---|---|
codexcomp / codexcomp run |
Start the proxy in the foreground. |
codexcomp install-service |
Opt-in autostart registration for the current platform. |
codexcomp uninstall-service |
Remove the autostart entry. |
codexcompw |
Windowless entry (Windows); logs to %LOCALAPPDATA%\codexcomp\codexcompw.log. |
| Flag | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Bind address — keep it loopback. |
--port |
8787 |
Must match openai_base_url; if busy the proxy exits. |
--upstream |
https://chatgpt.com/backend-api/codex |
Upstream base URL. |
--log-level |
info |
One of critical / error / warning / info / debug. |
--max-n |
0 |
Highest 518n−2 tier to auto-continue; 0 = no cap (cuts up to n=21 observed). |
--max-continue |
3 |
Max continuation rounds per request (runaway guard). |
Autostart (optional, off by default)
codexcomp install-service # register + start (current platform)
codexcomp uninstall-service # remove
- Linux / WSL — systemd user unit;
loginctl enable-lingerstarts it at boot without login. - macOS — launchd LaunchAgent in
~/Library/LaunchAgents/. - Windows — prints manual steps only: point a Startup shortcut (
Win+R→shell:startup) at the windowlesscodexcompw(where.exe codexcompw). Delete it to disable.
With WSL2 networkingMode=mirrored, Windows and WSL share 127.0.0.1: run one proxy in WSL
and just add the openai_base_url line on the Windows side — no second proxy needed.
Verify
curl -sS http://127.0.0.1:8787/healthz # {"ok":true,...}
journalctl --user -u codexcomp -f | grep -E 'round|done' # Linux/WSL
A live fold — two consecutive 516s folded, answer correct:
round 1: in=21550 out=664 reason=516 total=22214 | n=1 buffered=['function_call'] -> continue
round 2: in=22078 out=652 reason=516 total=22730 | n=1 buffered=['function_call'] -> continue
round 3: in=22606 out=566 reason=291 total=23172 | n=None buffered=[...] -> clean
done: 3 round(s) | ... | status=completed stop=natural
Round verdicts: continue (cut detected → will continue), clean (natural end),
tier_out_of_window / max_continue / no_encrypted_content (cut detected but released
as-is), compaction_request (remote-compaction request — never folded),
upstream_eof (stream ended without a terminal event). done: lines end with
stop=natural or the release reason. A fold torn down by a client disconnect logs
fold aborted downstream after N round(s) instead of a done: line.
Evals
evals/candy_eval.py measures the fix end-to-end: it runs a model × effort ×
proxy-on/off grid of codex exec calls on the candy pigeonhole puzzle from
haowang02/codex-candy-eval
(answer: 21, independently re-verified by brute force) and reports boundary-cut
rate, reasoning tokens and accuracy per condition. Both modes wire
openai_base_url explicitly, so the ambient config doesn't matter; interrupted
grids resume by re-running the same command.
codexcomp & # proxy must be running for `on`
python evals/candy_eval.py -m gpt-5.5 -r xhigh -n 5 # small grid
python evals/candy_eval.py # full 80-run grid
An 80-run grid of this eval (2026-07-06) found every unmitigated gpt-5.5 run
cut exactly on a 518n−2 boundary, 15% vs 90% accuracy off/on — details in
openai/codex#30364.
FAQ
Does it touch normal turns?
No. Clean rounds pass through byte-for-byte; the fold path only engages on a detected
518n−2 truncation.
What does a fold cost?
Continuation rounds spend extra real tokens, bounded by the continuation cap
(--max-continue, default 3). The true cumulative usage is reported under
metadata.proxy_billed_usage.
What happens when OpenAI fixes this upstream?
Nothing breaks — the detector simply stops firing and the proxy becomes a transparent
passthrough. Unwire it by deleting the openai_base_url line whenever you like.
Why not a separate [model_providers] entry?
That changes the provider id, which re-buckets session history and drops remote compaction
and remote-control. openai_base_url is the official in-place override of the built-in
openai provider.
Is my credential safe?
The proxy forwards the Authorization header untouched and binds to loopback only; it never
reads, persists, or logs a credential.
Security & disclaimer
- Auth passthrough only — forwards Codex's
Authorizationheader; never reads, persists, or logs a credential. - Loopback only — do not expose it on a non-loopback interface.
- Unofficial — it relies on non-contract upstream behavior; an OpenAI-side change may break it. Use at your own risk.
- Continuation spends extra real tokens (
metadata.proxy_billed_usage), bounded by the--max-continuecap (default 3 rounds).
Development
git clone https://github.com/dzshzx/codexcomp && cd codexcomp
uv sync
uv run python test_fold.py # fold state-machine self-test → ALL PASS
uv run python test_ws.py # transport self-test (WS protocol, headers) → ALL PASS
uv run codexcomp # run locally
Releases go out via PyPI Trusted Publishing (OIDC, no stored token): push a v* tag to build
and publish. Version history: CHANGELOG.md.
Contributing
Bug reports, fold-log excerpts, and reproduction details are the most valuable
contributions — please file them on
GitHub Issues. For code changes, run
uv run python test_fold.py and uv run python test_ws.py before opening a PR and keep
changes focused.
Community
Built for and shared with the LINUX DO community, where the gpt-5.5 "516" degradation was diagnosed. Feedback and issues welcome there and on GitHub Issues.
License
MIT — mechanism credit to neteroster/CodexCont (MIT), whose 518n−2 detect-and-continue idea this reuses with an independent, from-scratch implementation.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codexcomp-0.3.4.tar.gz.
File metadata
- Download URL: codexcomp-0.3.4.tar.gz
- Upload date:
- Size: 71.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
98d7ddf78fda6cb327a3317eed2719384be5f7b1553899aed524e4f7e565b6e1
|
|
| MD5 |
0c03b58e402daee4163af24d0b61b163
|
|
| BLAKE2b-256 |
5952468300d6b1b43dbc1cd4825bfefd3485ea73f678ea90a9f98a7aae9e7d75
|
Provenance
The following attestation bundles were made for codexcomp-0.3.4.tar.gz:
Publisher:
release.yml on dzshzx/codexcomp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codexcomp-0.3.4.tar.gz -
Subject digest:
98d7ddf78fda6cb327a3317eed2719384be5f7b1553899aed524e4f7e565b6e1 - Sigstore transparency entry: 2101661218
- Sigstore integration time:
-
Permalink:
dzshzx/codexcomp@9d9b11638db9f510e481f6dbe85ae5382b7a9f64 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/dzshzx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9d9b11638db9f510e481f6dbe85ae5382b7a9f64 -
Trigger Event:
push
-
Statement type:
File details
Details for the file codexcomp-0.3.4-py3-none-any.whl.
File metadata
- Download URL: codexcomp-0.3.4-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
10a549f80ef06da269547d062fffb55b543242ca770c17a47ddc02131f792081
|
|
| MD5 |
d5909bd06cb01a008742d954725fb249
|
|
| BLAKE2b-256 |
743bf44a751f110ff9796f2b7fbd08435bd76cb69bfeabe754245bb5b6f93a1c
|
Provenance
The following attestation bundles were made for codexcomp-0.3.4-py3-none-any.whl:
Publisher:
release.yml on dzshzx/codexcomp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
codexcomp-0.3.4-py3-none-any.whl -
Subject digest:
10a549f80ef06da269547d062fffb55b543242ca770c17a47ddc02131f792081 - Sigstore transparency entry: 2101661729
- Sigstore integration time:
-
Permalink:
dzshzx/codexcomp@9d9b11638db9f510e481f6dbe85ae5382b7a9f64 -
Branch / Tag:
refs/tags/v0.3.4 - Owner: https://github.com/dzshzx
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@9d9b11638db9f510e481f6dbe85ae5382b7a9f64 -
Trigger Event:
push
-
Statement type: