codex-as-api 0.6.3__tar.gz → 0.6.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/PKG-INFO +97 -26
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/README.md +96 -25
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/RELEASES.md +78 -0
- codex_as_api-0.6.5/config/codex-upstream-contract.json +86 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/config/model-capabilities.json +12 -12
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/pyproject.toml +3 -1
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/__init__.py +1 -1
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/anthropic_adapter.py +5 -4
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/auth.py +133 -21
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/messages.py +1 -1
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/model_capabilities.py +13 -6
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/protocol.py +2 -1
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/provider.py +78 -66
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/server.py +96 -5
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/conftest.py +1 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_anthropic_adapter.py +1 -4
- codex_as_api-0.6.5/tests/test_auth.py +730 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_codex_config.py +4 -4
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_messages.py +0 -1
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_model_capabilities.py +34 -3
- codex_as_api-0.6.5/tests/test_package_versions.py +94 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_protocol.py +0 -3
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_provider.py +87 -7
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_server.py +317 -6
- codex_as_api-0.6.3/tests/test_auth.py +0 -326
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/.gitignore +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/LICENSE +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/THIRD_PARTY_NOTICES.md +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/config/o200k_base.tiktoken +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/requirements-server.txt +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/requirements.txt +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/codex_config.py +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/src/codex_as_api/o200k_tokenizer.py +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/__init__.py +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/fixtures/o200k_base_encode_ordinary.json +0 -0
- {codex_as_api-0.6.3 → codex_as_api-0.6.5}/tests/test_o200k_tokenizer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codex-as-api
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.5
|
|
4
4
|
Summary: Use ChatGPT/Codex OAuth as a local OpenAI-compatible API server.
|
|
5
5
|
Project-URL: Homepage, https://github.com/Eunho-J/codex-as-api
|
|
6
6
|
Project-URL: Repository, https://github.com/Eunho-J/codex-as-api
|
|
@@ -49,7 +49,7 @@ Use ChatGPT / Codex OAuth as a local OpenAI-compatible API server.
|
|
|
49
49
|
- **Tool calling** — function calls, tool results, and parallel tool calls
|
|
50
50
|
- **Image support** — generation, inspection, multimodal Chat input, and capability-gated `original` image detail in classic Responses
|
|
51
51
|
- **Reasoning** — configurable effort/context, `standard` mode compatibility, persisted reasoning, and streaming thinking content
|
|
52
|
-
- **Codex features** — `prompt_cache_key`, process-local `response_id` continuation, subagent headers, and remote compaction
|
|
52
|
+
- **Codex features** — session-aware `prompt_cache_key`, process-local Chat `response_id` continuation, subagent headers, and remote compaction
|
|
53
53
|
- **Codex config aware** — reads `CODEX_HOME` / `~/.codex/config.toml` for model, reasoning-effort, and context-window settings
|
|
54
54
|
- **Token estimate & compaction helpers** — Anthropic-compatible `/v1/messages/count_tokens` and `/v1/messages/compact`
|
|
55
55
|
- **Auto auth** — reads `~/.codex/auth.json` and auto-refreshes OAuth tokens
|
|
@@ -165,7 +165,7 @@ Environment variables (Python, Rust, and TypeScript):
|
|
|
165
165
|
| `CODEX_AS_API_PORT` | `18080` | Listen port |
|
|
166
166
|
| `CODEX_AS_API_MODEL` | `~/.codex/config.toml` `model`, else `gpt-5.5` | Model identifier passed to Codex backend |
|
|
167
167
|
| `CODEX_AS_API_AUTH_PATH` | `~/.codex/auth.json` | Path to OAuth credentials file |
|
|
168
|
-
| `CODEX_AS_API_CODEX_CLI_VERSION` |
|
|
168
|
+
| `CODEX_AS_API_CODEX_CLI_VERSION` | `0.147.0` | Override the validated Codex compatibility baseline identified in backend request `User-Agent` headers |
|
|
169
169
|
| `CODEX_AS_API_RESPONSES_LITE` | `auto` | Responses Lite mode: `auto`, `on`, or `off` |
|
|
170
170
|
| `CODEX_AS_API_CODEX_METADATA` | `off` | Add Codex-style per-turn `client_metadata` and related backend headers |
|
|
171
171
|
| `CODEX_HOME` | `~/.codex` | Codex home directory used for `auth.json` and `config.toml` discovery |
|
|
@@ -177,8 +177,8 @@ model = "gpt-5.6-sol"
|
|
|
177
177
|
model_reasoning_effort = "high"
|
|
178
178
|
|
|
179
179
|
# Optional overrides. Without them, known models use the bundled Codex catalog values.
|
|
180
|
-
model_context_window =
|
|
181
|
-
model_auto_compact_token_limit =
|
|
180
|
+
model_context_window = 272000
|
|
181
|
+
model_auto_compact_token_limit = 244800
|
|
182
182
|
```
|
|
183
183
|
|
|
184
184
|
`CODEX_AS_API_MODEL` overrides the Codex config model. A request-level `reasoning_effort` overrides `model_reasoning_effort`; when both are omitted, known models use the Codex catalog default. The effective model, reasoning setting, and context settings are exposed from `/health`; context settings are also returned by Anthropic token-count responses.
|
|
@@ -198,7 +198,7 @@ model_auto_compact_token_limit = 334800
|
|
|
198
198
|
| `gpt-5.3-codex-spark` | Ultra-fast coding model |
|
|
199
199
|
| `gpt-5.2` | Previous generation model |
|
|
200
200
|
|
|
201
|
-
Model capability behavior is driven by `config/model-capabilities.json` across Python, TypeScript, and Rust. The public `gpt-5.6` alias uses Sol's private Codex capability entry. The GPT-5.6 entries use the official Codex Responses Lite contract and a
|
|
201
|
+
Model capability behavior is driven by `config/model-capabilities.json` across Python, TypeScript, and Rust. The public `gpt-5.6` alias uses Sol's private Codex capability entry. The GPT-5.6 entries use the official Codex Responses Lite contract and a 272,000-token **Codex OAuth** context-window maximum; do not substitute the larger public API context figures for this backend. Larger config overrides are clamped to 272,000. Unknown models use conservative behavior: classic Responses payloads, no assumed parallel tool support, no automatic verbosity, reasoning-effort, or service-tier fields, and, without config overrides, the legacy 200,000-token context / 160,000-token compact thresholds.
|
|
202
202
|
|
|
203
203
|
To use a different port:
|
|
204
204
|
|
|
@@ -310,13 +310,36 @@ curl -N http://localhost:18080/v1/messages \
|
|
|
310
310
|
}'
|
|
311
311
|
```
|
|
312
312
|
|
|
313
|
+
### Identifier and cache behavior
|
|
314
|
+
|
|
315
|
+
The two compatibility facades intentionally use the similarly named fields for
|
|
316
|
+
different jobs:
|
|
317
|
+
|
|
318
|
+
| Input or output | `/v1/chat/completions` | `/v1/messages` |
|
|
319
|
+
|---|---|---|
|
|
320
|
+
| `client_metadata.session_id` | Forwarded to Codex, used as the default `prompt_cache_key`, and required when Codex metadata mode is enabled | Not used or forwarded |
|
|
321
|
+
| `client_metadata.thread_id` | Codex metadata thread identity; defaults to `session_id` for a root request and preserves an explicit child thread | Not used or synthesized |
|
|
322
|
+
| `prompt_cache_key` | Explicit value wins; otherwise a non-empty `client_metadata.session_id` is used; otherwise omitted | Optional proxy extension; explicit value wins, otherwise the Claude Code session header is hashed |
|
|
323
|
+
| `x-claude-code-session-id` | Not used | SHA-256 of `codex-as-api:claude-code-session:<exact header value>` supplies cache affinity only |
|
|
324
|
+
| `previous_response_id` | Resolves a known entry from the 256-chain process-local history and replays full input/output over HTTP; never forwarded | Non-null values return Anthropic-style HTTP 400 because normal Messages is stateless |
|
|
325
|
+
| `cache_control` | Not an OpenAI Chat control | Validated as an Anthropic compatibility hint, then stripped before Codex transport |
|
|
326
|
+
|
|
327
|
+
Anthropic `cache_control` is a cache-boundary annotation, not an identifier.
|
|
328
|
+
This proxy accepts only `{"type":"ephemeral"}` with optional `ttl: "5m"` or
|
|
329
|
+
`"1h"` at request, system, message, content-block, and tool locations. The
|
|
330
|
+
private Codex request has no Anthropic breakpoint or TTL fields, so accepted
|
|
331
|
+
hints do not reproduce Anthropic caching semantics. Normal `/v1/messages`
|
|
332
|
+
responses do not expose the Chat-only `response_id`. The custom
|
|
333
|
+
`/v1/messages/compact` endpoint retains its documented local
|
|
334
|
+
`previous_response_id` support.
|
|
335
|
+
|
|
313
336
|
### `POST /v1/messages/count_tokens`
|
|
314
337
|
|
|
315
338
|
Anthropic-compatible token counting helper. Codex OAuth does not expose a count-only endpoint equivalent to Anthropic's native API, so this route counts text locally and returns context-window metadata for the effective backend model. Normalized model-visible messages, tool calls, tool-result metadata, reasoning, and tool schemas are counted once. Request-envelope and generation-control fields are excluded, and image inputs use a separate fixed estimate so inline base64 data is not counted as text.
|
|
316
339
|
|
|
317
340
|
GPT-5-family text uses a bundled port of official `tiktoken` `o200k_base` `encode_ordinary`: the same Unicode pre-tokenization regex, byte-pair merge algorithm, and merge-rank data are implemented in Python, TypeScript, and Rust. Official `tiktoken` maps `gpt-5` and its `gpt-5-`-prefixed variants to [`o200k_base`](https://github.com/openai/tiktoken/blob/08a5f3b2c987ada4fc5aa1f16c643c203fa8acaa/tiktoken/model.py#L7-L20); this project applies that GPT-5-family encoding to the bundled `gpt-5.*` Codex model IDs. The project does not depend on a `tiktoken` package or download encoding data at runtime. The last upstream synchronization check was **2026-07-14**, against [`tiktoken` 0.13.0 at `08a5f3b`](https://github.com/openai/tiktoken/tree/08a5f3b2c987ada4fc5aa1f16c643c203fa8acaa); the bundled rank file SHA-256 is `446a9538cb6c348e3516120d7c08b09f57c36495e2acfffe59a5bf8b0cfb1a2d`.
|
|
318
341
|
|
|
319
|
-
Official Codex also has a [`ceil(UTF-8 bytes / 4)` truncation helper](https://github.com/openai/codex/blob/
|
|
342
|
+
Official Codex also has a [`ceil(UTF-8 bytes / 4)` truncation helper](https://github.com/openai/codex/blob/bd2de422aa287b97b06ca6425a10935bcf1b3731/codex-rs/utils/string/src/truncate.rs#L4-L84), but Codex documents the history estimate using that helper as [a coarse lower bound rather than a tokenizer-accurate count](https://github.com/openai/codex/blob/bd2de422aa287b97b06ca6425a10935bcf1b3731/codex-rs/core/src/context_manager/history.rs#L162-L186). This endpoint therefore uses exact `o200k_base` ordinary text tokenization instead. The complete request count remains an estimate because protocol-wrapper overhead and image cost are local constants, but the former byte-as-token and raw-payload double count that could overstate ordinary Claude Code requests by about 8x is removed.
|
|
320
343
|
|
|
321
344
|
```bash
|
|
322
345
|
curl http://localhost:18080/v1/messages/count_tokens \
|
|
@@ -388,7 +411,7 @@ Health check. Returns auth availability, configured model and reasoning effort,
|
|
|
388
411
|
|
|
389
412
|
```bash
|
|
390
413
|
curl http://localhost:18080/health
|
|
391
|
-
# {"status":"ok","auth_available":true,"model":"gpt-5.6-sol","reasoning_effort":"high","codex_config_path":"/Users/me/.codex/config.toml","context_window":
|
|
414
|
+
# {"status":"ok","auth_available":true,"model":"gpt-5.6-sol","reasoning_effort":"high","codex_config_path":"/Users/me/.codex/config.toml","context_window":272000,"auto_compact_token_limit":244800}
|
|
392
415
|
```
|
|
393
416
|
|
|
394
417
|
## Codex-Specific Features
|
|
@@ -399,7 +422,7 @@ These features are extensions beyond the standard OpenAI API, designed for Codex
|
|
|
399
422
|
|
|
400
423
|
`prompt_cache_key` keeps related prefixes in the same backend cache family. Use one stable, privacy-safe key per conversation or application prefix.
|
|
401
424
|
|
|
402
|
-
Official Codex [defaults this field to its
|
|
425
|
+
Official Codex 0.147.0 [defaults this field to its Responses metadata session ID](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/core/src/client.rs#L475-L487), and [projects the same value into `client_metadata.session_id`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/core/src/responses_metadata.rs#L219-L228), unless an explicit override is present. This proxy follows the same precedence on Chat requests: explicit `prompt_cache_key`, then a non-empty `client_metadata.session_id`, then omission. It does not generate a process-wide session or reuse `thread_id` as the cache key.
|
|
403
426
|
|
|
404
427
|
The private Codex OAuth HTTP and WebSocket request structures do not contain public GPT-5.6 `prompt_cache_options` or content-block `prompt_cache_breakpoint` fields. This proxy treats explicit `null` as omitted and rejects non-null controls with HTTP 400 instead of forwarding a request that the private route rejects or silently pretending the requested cache policy was applied. Use a public Responses API client when explicit cache policy or breakpoints are required. See OpenAI's [public prompt caching guide](https://developers.openai.com/api/docs/guides/prompt-caching#prompt-cache-breakpoints).
|
|
405
428
|
|
|
@@ -454,7 +477,7 @@ The mapping is intentionally transport-aware:
|
|
|
454
477
|
|---|---|
|
|
455
478
|
| `reasoning.mode: "standard"` | Omit mode; send the resolved effort/context |
|
|
456
479
|
| `reasoning.mode: "pro"` | HTTP 400; no official Codex alias |
|
|
457
|
-
| `prompt_cache_key` | Forward
|
|
480
|
+
| `prompt_cache_key` | Forward an explicit value; otherwise use non-empty `client_metadata.session_id` |
|
|
458
481
|
| Non-null `prompt_cache_options` / breakpoint | HTTP 400; `null` is omitted and there is no private field |
|
|
459
482
|
| Non-null `safety_identifier` | HTTP 400; `null` is omitted and OAuth account/thread IDs are not semantic aliases |
|
|
460
483
|
| Non-empty `stop` / `stop_sequences` | HTTP 400; no private field |
|
|
@@ -462,7 +485,7 @@ The mapping is intentionally transport-aware:
|
|
|
462
485
|
| `service_tier: "fast"` | Send `service_tier: "priority"` |
|
|
463
486
|
| `service_tier: "default"` | Omit the field |
|
|
464
487
|
|
|
465
|
-
Authenticated tests on July 10, 2026 verified both official continuation paths with `gpt-5.6-sol`: a direct private Responses WebSocket completed a second delta request using the exact prior `response.id`, and the private HTTP endpoint completed the same continuation when the full prior input/output history was replayed. The proxy implements the HTTP replay strategy. Direct HTTP forwarding of `previous_response_id`, Pro, public cache controls, and `safety_identifier` was rejected and is not used. See OpenAI's [reasoning mode documentation](https://developers.openai.com/api/docs/guides/reasoning#reasoning-mode) and the
|
|
488
|
+
Authenticated tests on July 10, 2026 verified both official continuation paths with `gpt-5.6-sol`: a direct private Responses WebSocket completed a second delta request using the exact prior `response.id`, and the private HTTP endpoint completed the same continuation when the full prior input/output history was replayed. The proxy implements the HTTP replay strategy. Direct HTTP forwarding of `previous_response_id`, Pro, public cache controls, and `safety_identifier` was rejected and is not used. See OpenAI's [reasoning mode documentation](https://developers.openai.com/api/docs/guides/reasoning#reasoning-mode) and the Codex 0.147.0 [HTTP/WebSocket request structures](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/common.rs#L251-L307).
|
|
466
489
|
|
|
467
490
|
### `responses_lite`
|
|
468
491
|
|
|
@@ -508,15 +531,15 @@ Set `parallel_tool_calls: true` to request parallel tool calls when the selected
|
|
|
508
531
|
|
|
509
532
|
### `client_metadata` and `codex_metadata`
|
|
510
533
|
|
|
511
|
-
`client_metadata` is forwarded to the Codex backend. Set `codex_metadata: true` or `CODEX_AS_API_CODEX_METADATA=on` to
|
|
534
|
+
`client_metadata` is forwarded to the Codex backend. Set `codex_metadata: true` or `CODEX_AS_API_CODEX_METADATA=on` to add Codex-style turn metadata. Metadata mode requires a non-empty caller-supplied `client_metadata.session_id`; it preserves that session, defaults a missing root `thread_id` to the session, and preserves an explicit child `thread_id`.
|
|
512
535
|
|
|
513
|
-
|
|
536
|
+
The installation ID and process window ID remain stable, while `turn_id` and `x-codex-turn-metadata` are regenerated for each request. Metadata `thread_id` is neither a `previous_response_id` alias nor a cache key. An explicit `prompt_cache_key` wins; otherwise the non-empty session ID supplies cache affinity.
|
|
514
537
|
|
|
515
538
|
### `previous_response_id`
|
|
516
539
|
|
|
517
540
|
Non-streaming responses and the final streaming finish chunk expose the real upstream Responses ID as `response_id`. The provider keeps up to 256 completed chains in a process-local LRU store. Passing a known ID as `previous_response_id` prepends the saved semantic input and exact prior `response.output_item.done` items—including encrypted reasoning and tool items—to the new input, then sends one full private HTTP request. The ID itself is never forwarded and is never converted to `thread_id`.
|
|
518
541
|
|
|
519
|
-
That event source is intentional: the
|
|
542
|
+
That event source is intentional: the Codex 0.147.0 SSE parser [takes semantic items from `response.output_item.done`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/sse/responses.rs#L330-L341), while its [`response.completed` shape contains the response ID, usage, and `end_turn`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/sse/responses.rs#L112-L160), not replay history. The authenticated private HTTP rollout likewise returned an empty `response.completed.output`; the proxy therefore commits the completed output-item events instead of treating that extra field as conversation state.
|
|
520
543
|
|
|
521
544
|
Only a real `response.completed` event commits a chain. Branches from an older retained ID are supported. Restarting the server or evicting an old entry removes that local state; an unknown ID returns HTTP 400 before any upstream request.
|
|
522
545
|
|
|
@@ -642,7 +665,7 @@ curl -N http://localhost:18080/v1/chat/completions \
|
|
|
642
665
|
|
|
643
666
|
## Using with Claude Code
|
|
644
667
|
|
|
645
|
-
The `/v1/messages` endpoint implements the Anthropic Messages gateway shape used by Claude Code.
|
|
668
|
+
The `/v1/messages` endpoint implements the Anthropic Messages gateway shape used by Claude Code. The current request shape was reproduced with Claude Code `2.1.220`; streaming, real Codex OAuth chat, request-level GPT model routing, adaptive thinking, `--effort max`, and Fast Mode remain covered.
|
|
646
669
|
|
|
647
670
|
Start the proxy first. `CODEX_AS_API_MODEL` is the fallback used when Claude Code sends a built-in Anthropic model name:
|
|
648
671
|
|
|
@@ -666,7 +689,14 @@ CLAUDE_CODE_ATTRIBUTION_HEADER=0 \
|
|
|
666
689
|
claude
|
|
667
690
|
```
|
|
668
691
|
|
|
669
|
-
Run `/model` and select **GPT-5.6 Sol**. The custom entry is appended to the built-in rows rather than replacing them. Claude Code `2.1.
|
|
692
|
+
Run `/model` and select **GPT-5.6 Sol**. The custom entry is appended to the built-in rows rather than replacing them. Claude Code `2.1.220` recognizes this GPT model ID without a custom capability declaration: `/effort low|medium|high|xhigh|max`, the picker effort control, and `claude --effort ...` are translated from Claude Code's `output_config.effort` to the Codex reasoning effort. Claude Code Fast Mode's `speed: "fast"` is translated to the Codex `priority` service tier.
|
|
693
|
+
|
|
694
|
+
Claude Code sends `x-claude-code-session-id` for gateway request grouping. This
|
|
695
|
+
proxy hashes the exact header value into a stable `prompt_cache_key`; it does
|
|
696
|
+
not turn the header into Codex `session_id` or `thread_id` metadata. A
|
|
697
|
+
top-level `prompt_cache_key` is supported as a proxy extension and takes
|
|
698
|
+
precedence. Normal Messages requests remain stateless, so callers must send
|
|
699
|
+
full message history.
|
|
670
700
|
|
|
671
701
|
If managed settings define an `availableModels` allowlist, that list must include the exact `ANTHROPIC_CUSTOM_MODEL_OPTION` value, such as `gpt-5.6-sol`; otherwise Claude Code hides or rejects the custom row.
|
|
672
702
|
|
|
@@ -710,7 +740,7 @@ HTTP Server (FastAPI / Axum / Express)
|
|
|
710
740
|
```
|
|
711
741
|
|
|
712
742
|
The provider handles:
|
|
713
|
-
- Token loading and
|
|
743
|
+
- Token loading, proactive refresh five minutes before expiry, and refresh on 401
|
|
714
744
|
- OpenAI Responses API over SSE
|
|
715
745
|
- `prompt_cache_key` and cache read/write accounting
|
|
716
746
|
- GPT-5.6 reasoning effort/context plus `standard` mode compatibility
|
|
@@ -723,20 +753,32 @@ The provider handles:
|
|
|
723
753
|
|
|
724
754
|
## Release & package publishing
|
|
725
755
|
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
756
|
+
The `Release` GitHub Actions workflow runs on a pushed `v*` tag. It rejects a
|
|
757
|
+
tag that does not exactly match every Python, npm, and Rust version surface,
|
|
758
|
+
runs the complete cross-runtime gate, and then publishes PyPI, npmjs, the
|
|
759
|
+
scoped GitHub npm package, platform Rust binaries, and one GitHub Release.
|
|
729
760
|
|
|
730
|
-
|
|
761
|
+
The workflow uses registry-supported OIDC for PyPI and npmjs. No `PYPI_TOKEN`,
|
|
762
|
+
`NPM_TOKEN`, personal access token, or repository secret is required. One-time
|
|
763
|
+
registry setup is still required:
|
|
731
764
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
765
|
+
- Create GitHub environments named `pypi` and `npm`; add deployment protection
|
|
766
|
+
rules if desired.
|
|
767
|
+
- On PyPI, add a trusted publisher for project `codex-as-api`, owner `Eunho-J`,
|
|
768
|
+
repository `codex-as-api`, workflow `release.yml`, environment `pypi`.
|
|
769
|
+
- On npmjs, add a GitHub Actions trusted publisher for package `codex-as-api`,
|
|
770
|
+
owner `Eunho-J`, repository `codex-as-api`, workflow `release.yml`,
|
|
771
|
+
environment `npm`, with `npm publish` allowed.
|
|
772
|
+
- GitHub Packages and GitHub Releases use the job-scoped automatic
|
|
773
|
+
`GITHUB_TOKEN`; repository policy must allow the workflow's declared
|
|
774
|
+
`packages: write` and `contents: write` permissions.
|
|
735
775
|
|
|
736
|
-
|
|
776
|
+
After bumping every version and passing the local gate, push the matching tag:
|
|
737
777
|
|
|
738
778
|
```bash
|
|
739
|
-
|
|
779
|
+
python scripts/check_package_versions.py --tag v0.6.5
|
|
780
|
+
git tag v0.6.5
|
|
781
|
+
git push origin v0.6.5
|
|
740
782
|
```
|
|
741
783
|
|
|
742
784
|
## Tests
|
|
@@ -767,6 +809,35 @@ npm test
|
|
|
767
809
|
|
|
768
810
|
## Release Notes
|
|
769
811
|
|
|
812
|
+
### v0.6.5
|
|
813
|
+
|
|
814
|
+
- Align GPT-5.6 alias, Sol, Terra, and Luna context limits with Codex `0.147.0`
|
|
815
|
+
at 272,000 tokens and derive the 244,800-token automatic compact threshold.
|
|
816
|
+
- Pin the verified upstream request, Responses Lite, header, and model contract
|
|
817
|
+
to `openai/codex` commit
|
|
818
|
+
`be6e8eac029b183056b7e4402879f15d2c85f61b`; track its new fractional SSE
|
|
819
|
+
rollout-budget field without claiming an unapproved facade mapping.
|
|
820
|
+
- Refresh OAuth credentials five minutes before expiry, coalesce concurrent
|
|
821
|
+
refreshes, reload changed credentials after 401, and preserve upstream HTTP
|
|
822
|
+
status codes across all three servers.
|
|
823
|
+
- Replace startup npm version discovery with deterministic compatibility and
|
|
824
|
+
package-version identity in the Codex-style `User-Agent`.
|
|
825
|
+
- Add full cross-runtime CI plus tag-gated OIDC publishing to PyPI and npmjs,
|
|
826
|
+
`GITHUB_TOKEN` publishing to GitHub Packages, and GitHub Release assets.
|
|
827
|
+
|
|
828
|
+
### v0.6.4
|
|
829
|
+
|
|
830
|
+
- Remove process-global generated Codex session/thread identities and require
|
|
831
|
+
explicit session identity when Codex metadata mode is enabled.
|
|
832
|
+
- Resolve Chat cache affinity as explicit `prompt_cache_key`, then
|
|
833
|
+
`client_metadata.session_id`, then omission.
|
|
834
|
+
- Derive Claude Code cache affinity from `x-claude-code-session-id` without
|
|
835
|
+
fabricating Codex metadata; keep normal Anthropic Messages stateless.
|
|
836
|
+
- Validate and strip Anthropic `cache_control` compatibility hints without
|
|
837
|
+
claiming unavailable breakpoint or TTL semantics.
|
|
838
|
+
- Update current compatibility evidence to Codex `0.145.0`, Codex `main` at
|
|
839
|
+
`bd2de422aa287b97b06ca6425a10935bcf1b3731`, and Claude Code `2.1.220`.
|
|
840
|
+
|
|
770
841
|
### v0.6.3
|
|
771
842
|
|
|
772
843
|
- Accept Claude Code auxiliary requests that combine ambient `output_config.effort` with call-level `thinking.disabled`.
|
|
@@ -15,7 +15,7 @@ Use ChatGPT / Codex OAuth as a local OpenAI-compatible API server.
|
|
|
15
15
|
- **Tool calling** — function calls, tool results, and parallel tool calls
|
|
16
16
|
- **Image support** — generation, inspection, multimodal Chat input, and capability-gated `original` image detail in classic Responses
|
|
17
17
|
- **Reasoning** — configurable effort/context, `standard` mode compatibility, persisted reasoning, and streaming thinking content
|
|
18
|
-
- **Codex features** — `prompt_cache_key`, process-local `response_id` continuation, subagent headers, and remote compaction
|
|
18
|
+
- **Codex features** — session-aware `prompt_cache_key`, process-local Chat `response_id` continuation, subagent headers, and remote compaction
|
|
19
19
|
- **Codex config aware** — reads `CODEX_HOME` / `~/.codex/config.toml` for model, reasoning-effort, and context-window settings
|
|
20
20
|
- **Token estimate & compaction helpers** — Anthropic-compatible `/v1/messages/count_tokens` and `/v1/messages/compact`
|
|
21
21
|
- **Auto auth** — reads `~/.codex/auth.json` and auto-refreshes OAuth tokens
|
|
@@ -131,7 +131,7 @@ Environment variables (Python, Rust, and TypeScript):
|
|
|
131
131
|
| `CODEX_AS_API_PORT` | `18080` | Listen port |
|
|
132
132
|
| `CODEX_AS_API_MODEL` | `~/.codex/config.toml` `model`, else `gpt-5.5` | Model identifier passed to Codex backend |
|
|
133
133
|
| `CODEX_AS_API_AUTH_PATH` | `~/.codex/auth.json` | Path to OAuth credentials file |
|
|
134
|
-
| `CODEX_AS_API_CODEX_CLI_VERSION` |
|
|
134
|
+
| `CODEX_AS_API_CODEX_CLI_VERSION` | `0.147.0` | Override the validated Codex compatibility baseline identified in backend request `User-Agent` headers |
|
|
135
135
|
| `CODEX_AS_API_RESPONSES_LITE` | `auto` | Responses Lite mode: `auto`, `on`, or `off` |
|
|
136
136
|
| `CODEX_AS_API_CODEX_METADATA` | `off` | Add Codex-style per-turn `client_metadata` and related backend headers |
|
|
137
137
|
| `CODEX_HOME` | `~/.codex` | Codex home directory used for `auth.json` and `config.toml` discovery |
|
|
@@ -143,8 +143,8 @@ model = "gpt-5.6-sol"
|
|
|
143
143
|
model_reasoning_effort = "high"
|
|
144
144
|
|
|
145
145
|
# Optional overrides. Without them, known models use the bundled Codex catalog values.
|
|
146
|
-
model_context_window =
|
|
147
|
-
model_auto_compact_token_limit =
|
|
146
|
+
model_context_window = 272000
|
|
147
|
+
model_auto_compact_token_limit = 244800
|
|
148
148
|
```
|
|
149
149
|
|
|
150
150
|
`CODEX_AS_API_MODEL` overrides the Codex config model. A request-level `reasoning_effort` overrides `model_reasoning_effort`; when both are omitted, known models use the Codex catalog default. The effective model, reasoning setting, and context settings are exposed from `/health`; context settings are also returned by Anthropic token-count responses.
|
|
@@ -164,7 +164,7 @@ model_auto_compact_token_limit = 334800
|
|
|
164
164
|
| `gpt-5.3-codex-spark` | Ultra-fast coding model |
|
|
165
165
|
| `gpt-5.2` | Previous generation model |
|
|
166
166
|
|
|
167
|
-
Model capability behavior is driven by `config/model-capabilities.json` across Python, TypeScript, and Rust. The public `gpt-5.6` alias uses Sol's private Codex capability entry. The GPT-5.6 entries use the official Codex Responses Lite contract and a
|
|
167
|
+
Model capability behavior is driven by `config/model-capabilities.json` across Python, TypeScript, and Rust. The public `gpt-5.6` alias uses Sol's private Codex capability entry. The GPT-5.6 entries use the official Codex Responses Lite contract and a 272,000-token **Codex OAuth** context-window maximum; do not substitute the larger public API context figures for this backend. Larger config overrides are clamped to 272,000. Unknown models use conservative behavior: classic Responses payloads, no assumed parallel tool support, no automatic verbosity, reasoning-effort, or service-tier fields, and, without config overrides, the legacy 200,000-token context / 160,000-token compact thresholds.
|
|
168
168
|
|
|
169
169
|
To use a different port:
|
|
170
170
|
|
|
@@ -276,13 +276,36 @@ curl -N http://localhost:18080/v1/messages \
|
|
|
276
276
|
}'
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
+
### Identifier and cache behavior
|
|
280
|
+
|
|
281
|
+
The two compatibility facades intentionally use the similarly named fields for
|
|
282
|
+
different jobs:
|
|
283
|
+
|
|
284
|
+
| Input or output | `/v1/chat/completions` | `/v1/messages` |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| `client_metadata.session_id` | Forwarded to Codex, used as the default `prompt_cache_key`, and required when Codex metadata mode is enabled | Not used or forwarded |
|
|
287
|
+
| `client_metadata.thread_id` | Codex metadata thread identity; defaults to `session_id` for a root request and preserves an explicit child thread | Not used or synthesized |
|
|
288
|
+
| `prompt_cache_key` | Explicit value wins; otherwise a non-empty `client_metadata.session_id` is used; otherwise omitted | Optional proxy extension; explicit value wins, otherwise the Claude Code session header is hashed |
|
|
289
|
+
| `x-claude-code-session-id` | Not used | SHA-256 of `codex-as-api:claude-code-session:<exact header value>` supplies cache affinity only |
|
|
290
|
+
| `previous_response_id` | Resolves a known entry from the 256-chain process-local history and replays full input/output over HTTP; never forwarded | Non-null values return Anthropic-style HTTP 400 because normal Messages is stateless |
|
|
291
|
+
| `cache_control` | Not an OpenAI Chat control | Validated as an Anthropic compatibility hint, then stripped before Codex transport |
|
|
292
|
+
|
|
293
|
+
Anthropic `cache_control` is a cache-boundary annotation, not an identifier.
|
|
294
|
+
This proxy accepts only `{"type":"ephemeral"}` with optional `ttl: "5m"` or
|
|
295
|
+
`"1h"` at request, system, message, content-block, and tool locations. The
|
|
296
|
+
private Codex request has no Anthropic breakpoint or TTL fields, so accepted
|
|
297
|
+
hints do not reproduce Anthropic caching semantics. Normal `/v1/messages`
|
|
298
|
+
responses do not expose the Chat-only `response_id`. The custom
|
|
299
|
+
`/v1/messages/compact` endpoint retains its documented local
|
|
300
|
+
`previous_response_id` support.
|
|
301
|
+
|
|
279
302
|
### `POST /v1/messages/count_tokens`
|
|
280
303
|
|
|
281
304
|
Anthropic-compatible token counting helper. Codex OAuth does not expose a count-only endpoint equivalent to Anthropic's native API, so this route counts text locally and returns context-window metadata for the effective backend model. Normalized model-visible messages, tool calls, tool-result metadata, reasoning, and tool schemas are counted once. Request-envelope and generation-control fields are excluded, and image inputs use a separate fixed estimate so inline base64 data is not counted as text.
|
|
282
305
|
|
|
283
306
|
GPT-5-family text uses a bundled port of official `tiktoken` `o200k_base` `encode_ordinary`: the same Unicode pre-tokenization regex, byte-pair merge algorithm, and merge-rank data are implemented in Python, TypeScript, and Rust. Official `tiktoken` maps `gpt-5` and its `gpt-5-`-prefixed variants to [`o200k_base`](https://github.com/openai/tiktoken/blob/08a5f3b2c987ada4fc5aa1f16c643c203fa8acaa/tiktoken/model.py#L7-L20); this project applies that GPT-5-family encoding to the bundled `gpt-5.*` Codex model IDs. The project does not depend on a `tiktoken` package or download encoding data at runtime. The last upstream synchronization check was **2026-07-14**, against [`tiktoken` 0.13.0 at `08a5f3b`](https://github.com/openai/tiktoken/tree/08a5f3b2c987ada4fc5aa1f16c643c203fa8acaa); the bundled rank file SHA-256 is `446a9538cb6c348e3516120d7c08b09f57c36495e2acfffe59a5bf8b0cfb1a2d`.
|
|
284
307
|
|
|
285
|
-
Official Codex also has a [`ceil(UTF-8 bytes / 4)` truncation helper](https://github.com/openai/codex/blob/
|
|
308
|
+
Official Codex also has a [`ceil(UTF-8 bytes / 4)` truncation helper](https://github.com/openai/codex/blob/bd2de422aa287b97b06ca6425a10935bcf1b3731/codex-rs/utils/string/src/truncate.rs#L4-L84), but Codex documents the history estimate using that helper as [a coarse lower bound rather than a tokenizer-accurate count](https://github.com/openai/codex/blob/bd2de422aa287b97b06ca6425a10935bcf1b3731/codex-rs/core/src/context_manager/history.rs#L162-L186). This endpoint therefore uses exact `o200k_base` ordinary text tokenization instead. The complete request count remains an estimate because protocol-wrapper overhead and image cost are local constants, but the former byte-as-token and raw-payload double count that could overstate ordinary Claude Code requests by about 8x is removed.
|
|
286
309
|
|
|
287
310
|
```bash
|
|
288
311
|
curl http://localhost:18080/v1/messages/count_tokens \
|
|
@@ -354,7 +377,7 @@ Health check. Returns auth availability, configured model and reasoning effort,
|
|
|
354
377
|
|
|
355
378
|
```bash
|
|
356
379
|
curl http://localhost:18080/health
|
|
357
|
-
# {"status":"ok","auth_available":true,"model":"gpt-5.6-sol","reasoning_effort":"high","codex_config_path":"/Users/me/.codex/config.toml","context_window":
|
|
380
|
+
# {"status":"ok","auth_available":true,"model":"gpt-5.6-sol","reasoning_effort":"high","codex_config_path":"/Users/me/.codex/config.toml","context_window":272000,"auto_compact_token_limit":244800}
|
|
358
381
|
```
|
|
359
382
|
|
|
360
383
|
## Codex-Specific Features
|
|
@@ -365,7 +388,7 @@ These features are extensions beyond the standard OpenAI API, designed for Codex
|
|
|
365
388
|
|
|
366
389
|
`prompt_cache_key` keeps related prefixes in the same backend cache family. Use one stable, privacy-safe key per conversation or application prefix.
|
|
367
390
|
|
|
368
|
-
Official Codex [defaults this field to its
|
|
391
|
+
Official Codex 0.147.0 [defaults this field to its Responses metadata session ID](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/core/src/client.rs#L475-L487), and [projects the same value into `client_metadata.session_id`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/core/src/responses_metadata.rs#L219-L228), unless an explicit override is present. This proxy follows the same precedence on Chat requests: explicit `prompt_cache_key`, then a non-empty `client_metadata.session_id`, then omission. It does not generate a process-wide session or reuse `thread_id` as the cache key.
|
|
369
392
|
|
|
370
393
|
The private Codex OAuth HTTP and WebSocket request structures do not contain public GPT-5.6 `prompt_cache_options` or content-block `prompt_cache_breakpoint` fields. This proxy treats explicit `null` as omitted and rejects non-null controls with HTTP 400 instead of forwarding a request that the private route rejects or silently pretending the requested cache policy was applied. Use a public Responses API client when explicit cache policy or breakpoints are required. See OpenAI's [public prompt caching guide](https://developers.openai.com/api/docs/guides/prompt-caching#prompt-cache-breakpoints).
|
|
371
394
|
|
|
@@ -420,7 +443,7 @@ The mapping is intentionally transport-aware:
|
|
|
420
443
|
|---|---|
|
|
421
444
|
| `reasoning.mode: "standard"` | Omit mode; send the resolved effort/context |
|
|
422
445
|
| `reasoning.mode: "pro"` | HTTP 400; no official Codex alias |
|
|
423
|
-
| `prompt_cache_key` | Forward
|
|
446
|
+
| `prompt_cache_key` | Forward an explicit value; otherwise use non-empty `client_metadata.session_id` |
|
|
424
447
|
| Non-null `prompt_cache_options` / breakpoint | HTTP 400; `null` is omitted and there is no private field |
|
|
425
448
|
| Non-null `safety_identifier` | HTTP 400; `null` is omitted and OAuth account/thread IDs are not semantic aliases |
|
|
426
449
|
| Non-empty `stop` / `stop_sequences` | HTTP 400; no private field |
|
|
@@ -428,7 +451,7 @@ The mapping is intentionally transport-aware:
|
|
|
428
451
|
| `service_tier: "fast"` | Send `service_tier: "priority"` |
|
|
429
452
|
| `service_tier: "default"` | Omit the field |
|
|
430
453
|
|
|
431
|
-
Authenticated tests on July 10, 2026 verified both official continuation paths with `gpt-5.6-sol`: a direct private Responses WebSocket completed a second delta request using the exact prior `response.id`, and the private HTTP endpoint completed the same continuation when the full prior input/output history was replayed. The proxy implements the HTTP replay strategy. Direct HTTP forwarding of `previous_response_id`, Pro, public cache controls, and `safety_identifier` was rejected and is not used. See OpenAI's [reasoning mode documentation](https://developers.openai.com/api/docs/guides/reasoning#reasoning-mode) and the
|
|
454
|
+
Authenticated tests on July 10, 2026 verified both official continuation paths with `gpt-5.6-sol`: a direct private Responses WebSocket completed a second delta request using the exact prior `response.id`, and the private HTTP endpoint completed the same continuation when the full prior input/output history was replayed. The proxy implements the HTTP replay strategy. Direct HTTP forwarding of `previous_response_id`, Pro, public cache controls, and `safety_identifier` was rejected and is not used. See OpenAI's [reasoning mode documentation](https://developers.openai.com/api/docs/guides/reasoning#reasoning-mode) and the Codex 0.147.0 [HTTP/WebSocket request structures](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/common.rs#L251-L307).
|
|
432
455
|
|
|
433
456
|
### `responses_lite`
|
|
434
457
|
|
|
@@ -474,15 +497,15 @@ Set `parallel_tool_calls: true` to request parallel tool calls when the selected
|
|
|
474
497
|
|
|
475
498
|
### `client_metadata` and `codex_metadata`
|
|
476
499
|
|
|
477
|
-
`client_metadata` is forwarded to the Codex backend. Set `codex_metadata: true` or `CODEX_AS_API_CODEX_METADATA=on` to
|
|
500
|
+
`client_metadata` is forwarded to the Codex backend. Set `codex_metadata: true` or `CODEX_AS_API_CODEX_METADATA=on` to add Codex-style turn metadata. Metadata mode requires a non-empty caller-supplied `client_metadata.session_id`; it preserves that session, defaults a missing root `thread_id` to the session, and preserves an explicit child `thread_id`.
|
|
478
501
|
|
|
479
|
-
|
|
502
|
+
The installation ID and process window ID remain stable, while `turn_id` and `x-codex-turn-metadata` are regenerated for each request. Metadata `thread_id` is neither a `previous_response_id` alias nor a cache key. An explicit `prompt_cache_key` wins; otherwise the non-empty session ID supplies cache affinity.
|
|
480
503
|
|
|
481
504
|
### `previous_response_id`
|
|
482
505
|
|
|
483
506
|
Non-streaming responses and the final streaming finish chunk expose the real upstream Responses ID as `response_id`. The provider keeps up to 256 completed chains in a process-local LRU store. Passing a known ID as `previous_response_id` prepends the saved semantic input and exact prior `response.output_item.done` items—including encrypted reasoning and tool items—to the new input, then sends one full private HTTP request. The ID itself is never forwarded and is never converted to `thread_id`.
|
|
484
507
|
|
|
485
|
-
That event source is intentional: the
|
|
508
|
+
That event source is intentional: the Codex 0.147.0 SSE parser [takes semantic items from `response.output_item.done`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/sse/responses.rs#L330-L341), while its [`response.completed` shape contains the response ID, usage, and `end_turn`](https://github.com/openai/codex/blob/be6e8eac029b183056b7e4402879f15d2c85f61b/codex-rs/codex-api/src/sse/responses.rs#L112-L160), not replay history. The authenticated private HTTP rollout likewise returned an empty `response.completed.output`; the proxy therefore commits the completed output-item events instead of treating that extra field as conversation state.
|
|
486
509
|
|
|
487
510
|
Only a real `response.completed` event commits a chain. Branches from an older retained ID are supported. Restarting the server or evicting an old entry removes that local state; an unknown ID returns HTTP 400 before any upstream request.
|
|
488
511
|
|
|
@@ -608,7 +631,7 @@ curl -N http://localhost:18080/v1/chat/completions \
|
|
|
608
631
|
|
|
609
632
|
## Using with Claude Code
|
|
610
633
|
|
|
611
|
-
The `/v1/messages` endpoint implements the Anthropic Messages gateway shape used by Claude Code.
|
|
634
|
+
The `/v1/messages` endpoint implements the Anthropic Messages gateway shape used by Claude Code. The current request shape was reproduced with Claude Code `2.1.220`; streaming, real Codex OAuth chat, request-level GPT model routing, adaptive thinking, `--effort max`, and Fast Mode remain covered.
|
|
612
635
|
|
|
613
636
|
Start the proxy first. `CODEX_AS_API_MODEL` is the fallback used when Claude Code sends a built-in Anthropic model name:
|
|
614
637
|
|
|
@@ -632,7 +655,14 @@ CLAUDE_CODE_ATTRIBUTION_HEADER=0 \
|
|
|
632
655
|
claude
|
|
633
656
|
```
|
|
634
657
|
|
|
635
|
-
Run `/model` and select **GPT-5.6 Sol**. The custom entry is appended to the built-in rows rather than replacing them. Claude Code `2.1.
|
|
658
|
+
Run `/model` and select **GPT-5.6 Sol**. The custom entry is appended to the built-in rows rather than replacing them. Claude Code `2.1.220` recognizes this GPT model ID without a custom capability declaration: `/effort low|medium|high|xhigh|max`, the picker effort control, and `claude --effort ...` are translated from Claude Code's `output_config.effort` to the Codex reasoning effort. Claude Code Fast Mode's `speed: "fast"` is translated to the Codex `priority` service tier.
|
|
659
|
+
|
|
660
|
+
Claude Code sends `x-claude-code-session-id` for gateway request grouping. This
|
|
661
|
+
proxy hashes the exact header value into a stable `prompt_cache_key`; it does
|
|
662
|
+
not turn the header into Codex `session_id` or `thread_id` metadata. A
|
|
663
|
+
top-level `prompt_cache_key` is supported as a proxy extension and takes
|
|
664
|
+
precedence. Normal Messages requests remain stateless, so callers must send
|
|
665
|
+
full message history.
|
|
636
666
|
|
|
637
667
|
If managed settings define an `availableModels` allowlist, that list must include the exact `ANTHROPIC_CUSTOM_MODEL_OPTION` value, such as `gpt-5.6-sol`; otherwise Claude Code hides or rejects the custom row.
|
|
638
668
|
|
|
@@ -676,7 +706,7 @@ HTTP Server (FastAPI / Axum / Express)
|
|
|
676
706
|
```
|
|
677
707
|
|
|
678
708
|
The provider handles:
|
|
679
|
-
- Token loading and
|
|
709
|
+
- Token loading, proactive refresh five minutes before expiry, and refresh on 401
|
|
680
710
|
- OpenAI Responses API over SSE
|
|
681
711
|
- `prompt_cache_key` and cache read/write accounting
|
|
682
712
|
- GPT-5.6 reasoning effort/context plus `standard` mode compatibility
|
|
@@ -689,20 +719,32 @@ The provider handles:
|
|
|
689
719
|
|
|
690
720
|
## Release & package publishing
|
|
691
721
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
722
|
+
The `Release` GitHub Actions workflow runs on a pushed `v*` tag. It rejects a
|
|
723
|
+
tag that does not exactly match every Python, npm, and Rust version surface,
|
|
724
|
+
runs the complete cross-runtime gate, and then publishes PyPI, npmjs, the
|
|
725
|
+
scoped GitHub npm package, platform Rust binaries, and one GitHub Release.
|
|
695
726
|
|
|
696
|
-
|
|
727
|
+
The workflow uses registry-supported OIDC for PyPI and npmjs. No `PYPI_TOKEN`,
|
|
728
|
+
`NPM_TOKEN`, personal access token, or repository secret is required. One-time
|
|
729
|
+
registry setup is still required:
|
|
697
730
|
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
731
|
+
- Create GitHub environments named `pypi` and `npm`; add deployment protection
|
|
732
|
+
rules if desired.
|
|
733
|
+
- On PyPI, add a trusted publisher for project `codex-as-api`, owner `Eunho-J`,
|
|
734
|
+
repository `codex-as-api`, workflow `release.yml`, environment `pypi`.
|
|
735
|
+
- On npmjs, add a GitHub Actions trusted publisher for package `codex-as-api`,
|
|
736
|
+
owner `Eunho-J`, repository `codex-as-api`, workflow `release.yml`,
|
|
737
|
+
environment `npm`, with `npm publish` allowed.
|
|
738
|
+
- GitHub Packages and GitHub Releases use the job-scoped automatic
|
|
739
|
+
`GITHUB_TOKEN`; repository policy must allow the workflow's declared
|
|
740
|
+
`packages: write` and `contents: write` permissions.
|
|
701
741
|
|
|
702
|
-
|
|
742
|
+
After bumping every version and passing the local gate, push the matching tag:
|
|
703
743
|
|
|
704
744
|
```bash
|
|
705
|
-
|
|
745
|
+
python scripts/check_package_versions.py --tag v0.6.5
|
|
746
|
+
git tag v0.6.5
|
|
747
|
+
git push origin v0.6.5
|
|
706
748
|
```
|
|
707
749
|
|
|
708
750
|
## Tests
|
|
@@ -733,6 +775,35 @@ npm test
|
|
|
733
775
|
|
|
734
776
|
## Release Notes
|
|
735
777
|
|
|
778
|
+
### v0.6.5
|
|
779
|
+
|
|
780
|
+
- Align GPT-5.6 alias, Sol, Terra, and Luna context limits with Codex `0.147.0`
|
|
781
|
+
at 272,000 tokens and derive the 244,800-token automatic compact threshold.
|
|
782
|
+
- Pin the verified upstream request, Responses Lite, header, and model contract
|
|
783
|
+
to `openai/codex` commit
|
|
784
|
+
`be6e8eac029b183056b7e4402879f15d2c85f61b`; track its new fractional SSE
|
|
785
|
+
rollout-budget field without claiming an unapproved facade mapping.
|
|
786
|
+
- Refresh OAuth credentials five minutes before expiry, coalesce concurrent
|
|
787
|
+
refreshes, reload changed credentials after 401, and preserve upstream HTTP
|
|
788
|
+
status codes across all three servers.
|
|
789
|
+
- Replace startup npm version discovery with deterministic compatibility and
|
|
790
|
+
package-version identity in the Codex-style `User-Agent`.
|
|
791
|
+
- Add full cross-runtime CI plus tag-gated OIDC publishing to PyPI and npmjs,
|
|
792
|
+
`GITHUB_TOKEN` publishing to GitHub Packages, and GitHub Release assets.
|
|
793
|
+
|
|
794
|
+
### v0.6.4
|
|
795
|
+
|
|
796
|
+
- Remove process-global generated Codex session/thread identities and require
|
|
797
|
+
explicit session identity when Codex metadata mode is enabled.
|
|
798
|
+
- Resolve Chat cache affinity as explicit `prompt_cache_key`, then
|
|
799
|
+
`client_metadata.session_id`, then omission.
|
|
800
|
+
- Derive Claude Code cache affinity from `x-claude-code-session-id` without
|
|
801
|
+
fabricating Codex metadata; keep normal Anthropic Messages stateless.
|
|
802
|
+
- Validate and strip Anthropic `cache_control` compatibility hints without
|
|
803
|
+
claiming unavailable breakpoint or TTL semantics.
|
|
804
|
+
- Update current compatibility evidence to Codex `0.145.0`, Codex `main` at
|
|
805
|
+
`bd2de422aa287b97b06ca6425a10935bcf1b3731`, and Claude Code `2.1.220`.
|
|
806
|
+
|
|
736
807
|
### v0.6.3
|
|
737
808
|
|
|
738
809
|
- Accept Claude Code auxiliary requests that combine ambient `output_config.effort` with call-level `thinking.disabled`.
|
|
@@ -1,5 +1,83 @@
|
|
|
1
1
|
# Release Notes
|
|
2
2
|
|
|
3
|
+
## v0.6.5
|
|
4
|
+
|
|
5
|
+
### Codex 0.147 compatibility
|
|
6
|
+
|
|
7
|
+
- Align GPT-5.6 alias, Sol, Terra, and Luna context limits with the stable
|
|
8
|
+
Codex 0.147 catalog at 272,000 tokens. Automatic compact defaults now derive
|
|
9
|
+
to 244,800 tokens.
|
|
10
|
+
- Pin a structured compatibility fixture to `openai/codex` 0.147.0 commit
|
|
11
|
+
`be6e8eac029b183056b7e4402879f15d2c85f61b`, covering the model fields,
|
|
12
|
+
Responses request path, Lite behavior, and originator header. The fractional
|
|
13
|
+
`codex_rollout_budget_units` usage field is tracked as upstream-only because
|
|
14
|
+
this facade has no approved public mapping for it.
|
|
15
|
+
- Replace the moving startup `npm view @openai/codex version` lookup with a
|
|
16
|
+
deterministic Codex compatibility baseline and `codex-as-api` package
|
|
17
|
+
version in the request `User-Agent`.
|
|
18
|
+
|
|
19
|
+
### Authentication and errors
|
|
20
|
+
|
|
21
|
+
- Refresh OAuth access tokens five minutes before expiry, coalesce concurrent
|
|
22
|
+
refresh work, and reload credentials changed by another request before
|
|
23
|
+
rotating a refresh token after HTTP 401.
|
|
24
|
+
- Preserve the existing root or nested auth-file layout, reject account
|
|
25
|
+
switches and conflicting token claims, and compare the credential snapshot
|
|
26
|
+
again before persisting a refresh response.
|
|
27
|
+
- Preserve upstream HTTP statuses, including rate-limit and overload responses,
|
|
28
|
+
in Python and TypeScript to match Rust.
|
|
29
|
+
|
|
30
|
+
### CI and publishing
|
|
31
|
+
|
|
32
|
+
- Add pull-request and push CI for Python tests, Ruff, mypy, package builds,
|
|
33
|
+
TypeScript tests/build/package checks, and Rust format, Clippy, tests, and
|
|
34
|
+
release builds.
|
|
35
|
+
- Add a tag-triggered release workflow that requires exact tag/package version
|
|
36
|
+
agreement and the full cross-runtime gate before publishing.
|
|
37
|
+
- Publish PyPI and npmjs through trusted-publisher OIDC, GitHub Packages and
|
|
38
|
+
GitHub Releases through the automatic repository `GITHUB_TOKEN`, and attach
|
|
39
|
+
Python/npm distributions plus Linux, macOS, and Windows Rust binaries.
|
|
40
|
+
- Remove the manual npm workflow that could report success after silently
|
|
41
|
+
skipping npmjs publication when `NPM_TOKEN` was absent.
|
|
42
|
+
|
|
43
|
+
## v0.6.4
|
|
44
|
+
|
|
45
|
+
### Codex identity and cache affinity
|
|
46
|
+
|
|
47
|
+
- Remove process-global generated `session_id` and `thread_id` values from
|
|
48
|
+
Python, TypeScript, and Rust. Codex metadata mode now requires an explicit
|
|
49
|
+
non-empty `client_metadata.session_id`, defaults a root `thread_id` to that
|
|
50
|
+
session, preserves an explicit child thread, and refreshes only turn-scoped
|
|
51
|
+
identity on each request.
|
|
52
|
+
- Resolve Chat `prompt_cache_key` as explicit value, then non-empty
|
|
53
|
+
`client_metadata.session_id`, then omission. This matches Codex 0.145.0 and
|
|
54
|
+
current `main`, where the official default is Responses metadata
|
|
55
|
+
`session_id`, not `thread_id`.
|
|
56
|
+
- Retain bounded process-local Chat `previous_response_id` history replay over
|
|
57
|
+
private HTTP. The ID remains local and is never forwarded upstream.
|
|
58
|
+
|
|
59
|
+
### Claude Code session and cache compatibility
|
|
60
|
+
|
|
61
|
+
- Read `x-claude-code-session-id` on `/v1/messages` and derive a stable,
|
|
62
|
+
privacy-safe SHA-256 `prompt_cache_key`; an explicit proxy extension
|
|
63
|
+
`prompt_cache_key` takes precedence.
|
|
64
|
+
- Keep normal Anthropic Messages stateless: reject non-null
|
|
65
|
+
`previous_response_id`, disable ambient Codex metadata, avoid fabricated
|
|
66
|
+
Claude thread IDs, and remove Python's nonstandard Anthropic `response_id`.
|
|
67
|
+
- Validate Anthropic `cache_control` hints at request, system, message, content,
|
|
68
|
+
and tool locations. Accept only `type: "ephemeral"` with optional TTL `5m` or
|
|
69
|
+
`1h`, then strip the hint because the private Codex transport cannot preserve
|
|
70
|
+
Anthropic cache breakpoints or TTL behavior.
|
|
71
|
+
|
|
72
|
+
### Validation
|
|
73
|
+
|
|
74
|
+
- Python: 515 tests, mypy, and changed-file Ruff checks.
|
|
75
|
+
- TypeScript: 261 tests and production build.
|
|
76
|
+
- Rust: 253 tests and rustfmt.
|
|
77
|
+
- Re-audited `@openai/codex` 0.145.0 plus `main` at
|
|
78
|
+
`bd2de422aa287b97b06ca6425a10935bcf1b3731`, and reproduced the Claude Code
|
|
79
|
+
2.1.220 request shape.
|
|
80
|
+
|
|
3
81
|
## v0.6.3
|
|
4
82
|
|
|
5
83
|
### Claude Code WebSearch/WebFetch auxiliary calls
|