codex-api-proxy 0.1.5__tar.gz → 0.1.6__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.
Files changed (31) hide show
  1. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/PKG-INFO +143 -39
  2. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/README.md +142 -38
  3. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/pyproject.toml +1 -1
  4. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/__init__.py +1 -1
  5. codex_api_proxy-0.1.6/src/codex_api_proxy/anthropic_messages.py +490 -0
  6. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/cli.py +169 -26
  7. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/config.py +5 -2
  8. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/main.py +62 -30
  9. codex_api_proxy-0.1.6/src/codex_api_proxy/metrics.py +67 -0
  10. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/models.py +24 -0
  11. codex_api_proxy-0.1.6/src/codex_api_proxy/structured_logging.py +52 -0
  12. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/PKG-INFO +143 -39
  13. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/SOURCES.txt +2 -0
  14. codex_api_proxy-0.1.6/tests/test_anthropic_messages.py +375 -0
  15. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_api.py +130 -2
  16. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_cli.py +83 -7
  17. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_config.py +3 -3
  18. codex_api_proxy-0.1.5/src/codex_api_proxy/anthropic_messages.py +0 -257
  19. codex_api_proxy-0.1.5/tests/test_anthropic_messages.py +0 -167
  20. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/setup.cfg +0 -0
  21. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/auth.py +0 -0
  22. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/chat_completions.py +0 -0
  23. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/sse_utils.py +0 -0
  24. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/dependency_links.txt +0 -0
  25. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/entry_points.txt +0 -0
  26. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/requires.txt +0 -0
  27. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/top_level.txt +0 -0
  28. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_auth.py +0 -0
  29. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_chat_completions.py +0 -0
  30. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_models.py +0 -0
  31. {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_release_version.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codex-api-proxy
3
- Version: 0.1.5
3
+ Version: 0.1.6
4
4
  Summary: Local OpenAI-compatible HTTP proxy backed by Codex/OpenAI credentials
5
5
  Author: codex-api-proxy contributors
6
6
  License-Expression: MIT
@@ -36,7 +36,8 @@ This package is intentionally narrow:
36
36
  - reuse the user's existing Codex/OpenAI login credentials;
37
37
  - support `/v1/chat/completions`, `/v1/responses`, `/v1/messages`, and `/v1/models`;
38
38
  - convert Chat Completions to Responses API when using ChatGPT Codex credentials;
39
- - convert Anthropic-style Messages API text requests to Responses API for local Anthropic-compatible clients;
39
+ - convert Anthropic-style Messages API requests to Responses API for local Anthropic-compatible clients such as Claude Code;
40
+ - accept image input for vision tasks through Chat Completions `image_url` parts and Anthropic `image` content blocks;
40
41
  - otherwise transparently forward OpenAI API-key requests to OpenAI's native `/chat/completions`.
41
42
 
42
43
  Out of scope:
@@ -95,7 +96,7 @@ Outbound upstream proxy settings are controlled by environment variables:
95
96
  - `HTTPS_PROXY`
96
97
  - `https_proxy`
97
98
 
98
- When none are set, the proxy defaults to `http://127.0.0.1:8118`.
99
+ When none are set, the proxy connects directly to the upstream API without a proxy.
99
100
 
100
101
  You can also set the upstream proxy explicitly at startup:
101
102
 
@@ -137,13 +138,15 @@ Bind to all interfaces with local bearer auth:
137
138
  codex-api-proxy start --host 0.0.0.0 --api-key local-secret
138
139
  ```
139
140
 
141
+ Binding to `0.0.0.0`, `::`, or `[::]` requires `--api-key`; the proxy refuses to start on public interfaces without local bearer auth.
142
+
140
143
  Start with an explicit upstream proxy:
141
144
 
142
145
  ```bash
143
146
  codex-api-proxy start --proxy=http://127.0.0.1:8118
144
147
  ```
145
148
 
146
- Restart using the last saved start settings:
149
+ Restart using the last saved start config:
147
150
 
148
151
  ```bash
149
152
  codex-api-proxy restart
@@ -161,16 +164,24 @@ Status:
161
164
  codex-api-proxy status --verbose
162
165
  ```
163
166
 
167
+ Run diagnostics:
168
+
169
+ ```bash
170
+ codex-api-proxy doctor
171
+ ```
172
+
164
173
  ## CLI Options
165
174
 
166
175
  - `--host`: bind host, default `127.0.0.1`
167
176
  - `--port`: bind port, default `8765`
168
177
  - `--api-key`: require client requests to send `Authorization: Bearer <key>`
169
- - `--proxy`: upstream HTTP(S) proxy URL for OpenAI/Codex API calls
178
+ - `--proxy`: upstream HTTP(S) proxy URL for OpenAI/Codex API calls; omitted means direct upstream connections
170
179
  - `--log-level`: `debug`, `info`, `warning`, or `error`
180
+ - `--log-format`: `text` or `json` for application event logs
181
+ - `--models-cache-ttl`: seconds to cache `/v1/models`, default `300`; use `0` to disable
171
182
  - `--pid-file`: daemon pid file, default `~/.codex-api-proxy/codex-api-proxy.pid`
172
183
  - `--log-file`: daemon log file, default `~/.codex-api-proxy/codex-api-proxy.log`
173
- - `--state-file`: daemon state file, default `~/.codex-api-proxy/codex-api-proxy.state.json`
184
+ - `--state-file`: daemon config file, default `~/.codex-api-proxy/config.toml`
174
185
  - `--foreground`: run without daemonizing
175
186
 
176
187
  Environment variables for the local server:
@@ -201,6 +212,8 @@ Models:
201
212
  curl -sS http://127.0.0.1:8765/v1/models
202
213
  ```
203
214
 
215
+ `/v1/models` responses are cached locally for `--models-cache-ttl` seconds. Use `?refresh=true` to bypass and refresh the cache.
216
+
204
217
  Chat completion:
205
218
 
206
219
  ```bash
@@ -225,7 +238,60 @@ curl -sS http://127.0.0.1:8765/v1/responses \
225
238
  -d '{"model":"gpt-5.5","input":"Reply with exactly: pong"}'
226
239
  ```
227
240
 
228
- Image input through Chat Completions:
241
+ Anthropic-style Messages API:
242
+
243
+ ```bash
244
+ curl -sS http://127.0.0.1:8765/v1/messages \
245
+ -H 'Content-Type: application/json' \
246
+ -H 'anthropic-version: 2023-06-01' \
247
+ -d '{
248
+ "model": "gpt-5.5",
249
+ "max_tokens": 128,
250
+ "system": "Be brief.",
251
+ "messages": [{"role":"user","content":"Reply with exactly: pong"}]
252
+ }'
253
+ ```
254
+
255
+ Streaming Anthropic-style Messages API:
256
+
257
+ ```bash
258
+ curl -N http://127.0.0.1:8765/v1/messages \
259
+ -H 'Content-Type: application/json' \
260
+ -H 'anthropic-version: 2023-06-01' \
261
+ -d '{
262
+ "model": "gpt-5.5",
263
+ "max_tokens": 128,
264
+ "stream": true,
265
+ "messages": [{"role":"user","content":[{"type":"text","text":"Reply with exactly: pong"}]}]
266
+ }'
267
+ ```
268
+
269
+ When local `--api-key` auth is enabled, `/v1/messages` accepts either `Authorization: Bearer <key>` or `x-api-key: <key>` because Anthropic-compatible clients vary in which header they send.
270
+
271
+ The Anthropic compatibility layer currently covers text messages, system prompts, streaming text deltas, and image content blocks. Full Anthropic `tool_use` / `tool_result` round-tripping is not yet implemented.
272
+
273
+ When `--api-key` is configured:
274
+
275
+ ```bash
276
+ curl -sS http://127.0.0.1:8765/v1/chat/completions \
277
+ -H 'Authorization: Bearer local-secret' \
278
+ -H 'Content-Type: application/json' \
279
+ -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Reply with exactly: pong"}]}'
280
+ ```
281
+
282
+ ## Image Recognition
283
+
284
+ The proxy forwards image input to the upstream Codex/OpenAI Responses API for vision tasks.
285
+
286
+ Supported input shapes:
287
+
288
+ - Chat Completions: `image_url` parts with a `data:` URL or remote `https://` URL, plus optional `detail`
289
+ - Chat Completions: Responses-style `input_image` parts (passed through as-is)
290
+ - Anthropic Messages: `image` content blocks with `source.type` of `base64` or `url`
291
+
292
+ When using ChatGPT Codex credentials, image parts are converted to Responses API `input_image` parts before the upstream call. `/v1/responses` requests with `input_image` are passed through unchanged.
293
+
294
+ Chat Completions example:
229
295
 
230
296
  ```bash
231
297
  BASE64_IMAGE=$(base64 < image.jpg)
@@ -249,62 +315,100 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
249
315
  }'
250
316
  ```
251
317
 
252
- When using ChatGPT Codex credentials, Chat Completions image parts are converted to Responses API `input_image` parts. `/v1/responses` requests are passed through unchanged.
253
-
254
- Anthropic-style Messages API:
318
+ Anthropic Messages example:
255
319
 
256
320
  ```bash
321
+ BASE64_IMAGE=$(base64 < image.jpg)
257
322
  curl -sS http://127.0.0.1:8765/v1/messages \
258
323
  -H 'Content-Type: application/json' \
259
324
  -H 'anthropic-version: 2023-06-01' \
260
325
  -d '{
261
326
  "model": "gpt-5.5",
262
- "max_tokens": 128,
263
- "system": "Be brief.",
264
- "messages": [{"role":"user","content":"Reply with exactly: pong"}]
327
+ "max_tokens": 256,
328
+ "messages": [{
329
+ "role": "user",
330
+ "content": [
331
+ {"type": "text", "text": "What is in this image?"},
332
+ {
333
+ "type": "image",
334
+ "source": {
335
+ "type": "base64",
336
+ "media_type": "image/jpeg",
337
+ "data": "'"$BASE64_IMAGE"'"
338
+ }
339
+ }
340
+ ]
341
+ }]
265
342
  }'
266
343
  ```
267
344
 
268
- Streaming Anthropic-style Messages API:
345
+ ## Claude Code
269
346
 
270
- ```bash
271
- curl -N http://127.0.0.1:8765/v1/messages \
272
- -H 'Content-Type: application/json' \
273
- -H 'anthropic-version: 2023-06-01' \
274
- -d '{
275
- "model": "gpt-5.5",
276
- "max_tokens": 128,
277
- "stream": true,
278
- "messages": [{"role":"user","content":[{"type":"text","text":"Reply with exactly: pong"}]}]
279
- }'
280
- ```
347
+ Claude Code speaks the Anthropic Messages API. Point it at this proxy so requests are converted to the upstream Codex/OpenAI Responses API using your existing `~/.codex/auth.json` credentials.
348
+
349
+ ### 1. Start the proxy
281
350
 
282
- For Anthropic-compatible clients such as Claude Code, point the Anthropic base URL at this proxy and use the local API key configured with `--api-key`, if any:
351
+ Start the proxy with a local API key if you want to protect the local endpoint:
283
352
 
284
353
  ```bash
285
- ANTHROPIC_BASE_URL=http://127.0.0.1:8765 \
286
- ANTHROPIC_AUTH_TOKEN=local-secret \
287
- claude
354
+ codex-api-proxy start --api-key sk-tmp
288
355
  ```
289
356
 
290
- When local `--api-key` auth is enabled, `/v1/messages` accepts either `Authorization: Bearer <key>` or `x-api-key: <key>` because Anthropic-compatible clients vary in which header they send.
357
+ `ANTHROPIC_AUTH_TOKEN` in Claude Code must match the value passed to `--api-key`. If you start the proxy without `--api-key`, local bearer auth is disabled and `ANTHROPIC_AUTH_TOKEN` is not required.
358
+
359
+ ### 2. Configure Claude Code
360
+
361
+ Edit `~/.claude/settings.json` and set the Anthropic base URL to this proxy:
362
+
363
+ ```json
364
+ {
365
+ "env": {
366
+ "ANTHROPIC_BASE_URL": "http://127.0.0.1:8765",
367
+ "ANTHROPIC_AUTH_TOKEN": "sk-tmp",
368
+ "ANTHROPIC_MODEL": "gpt-5.5",
369
+ "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
370
+ "CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING": "1"
371
+ },
372
+ "enabledPlugins": {
373
+ "superpowers@claude-plugins-official": true
374
+ },
375
+ "skipDangerousModePermissionPrompt": true,
376
+ "theme": "dark"
377
+ }
378
+ ```
291
379
 
292
- The Anthropic compatibility layer currently covers text messages, system prompts, streaming text deltas, and image content blocks. Full Anthropic `tool_use` / `tool_result` round-tripping is not yet implemented.
380
+ Key fields:
293
381
 
294
- When `--api-key` is configured:
382
+ - `ANTHROPIC_BASE_URL`: local proxy URL, default `http://127.0.0.1:8765`
383
+ - `ANTHROPIC_AUTH_TOKEN`: must match `codex-api-proxy start --api-key ...` when local auth is enabled
384
+ - `ANTHROPIC_MODEL`: upstream model id exposed by `/v1/models`, for example `gpt-5.5`
385
+
386
+ Restart Claude Code after changing `settings.json`.
387
+
388
+ ### 3. Verify
295
389
 
296
390
  ```bash
297
- curl -sS http://127.0.0.1:8765/v1/chat/completions \
298
- -H 'Authorization: Bearer local-secret' \
299
- -H 'Content-Type: application/json' \
300
- -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Reply with exactly: pong"}]}'
391
+ codex-api-proxy status --verbose
392
+ curl -sS http://127.0.0.1:8765/health
393
+ ```
394
+
395
+ Then launch Claude Code from a terminal:
396
+
397
+ ```bash
398
+ claude
301
399
  ```
302
400
 
401
+ Image attachments in Claude Code are sent as Anthropic `image` blocks and are converted by the proxy before the upstream request. Tool calling in Claude Code depends on Anthropic `tool_use` / `tool_result` support, which is not fully implemented in this proxy yet.
402
+
303
403
  ## Operations
304
404
 
305
- `/health` checks that credentials can be loaded and shows the upstream mode without exposing secrets.
405
+ `/health` is a process liveness check. It returns the proxy version and uptime without loading credentials, refreshing tokens, writing `auth.json`, or contacting upstream services.
406
+
407
+ `/ready` checks that credentials can be loaded and shows the upstream mode without exposing secrets. It may refresh Codex/ChatGPT tokens when refresh criteria are met.
408
+
409
+ `/metrics` returns local request counters as JSON. `/metrics/prometheus` returns Prometheus text format metrics.
306
410
 
307
- `/ready` is an alias of `/health`.
411
+ Successful proxied responses include `x-request-id`. The proxy uses incoming `x-request-id` or `x-correlation-id` when present, otherwise it generates one.
308
412
 
309
413
  `/metrics` returns local request counters:
310
414
 
@@ -316,4 +420,4 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
316
420
 
317
421
  When `--log-level debug` is set, chat completions log input messages and output messages through `codex_api_proxy.messages` and the daemon's `uvicorn.error` log stream. Streaming output is logged after the stream finishes. These logs can contain prompt and response data; use debug logging only in trusted environments.
318
422
 
319
- Latency summaries are logged through `codex_api_proxy.latency`.
423
+ Latency summaries are logged through `codex_api_proxy.latency`. Set `--log-format json` for structured JSON event logs.
@@ -12,7 +12,8 @@ This package is intentionally narrow:
12
12
  - reuse the user's existing Codex/OpenAI login credentials;
13
13
  - support `/v1/chat/completions`, `/v1/responses`, `/v1/messages`, and `/v1/models`;
14
14
  - convert Chat Completions to Responses API when using ChatGPT Codex credentials;
15
- - convert Anthropic-style Messages API text requests to Responses API for local Anthropic-compatible clients;
15
+ - convert Anthropic-style Messages API requests to Responses API for local Anthropic-compatible clients such as Claude Code;
16
+ - accept image input for vision tasks through Chat Completions `image_url` parts and Anthropic `image` content blocks;
16
17
  - otherwise transparently forward OpenAI API-key requests to OpenAI's native `/chat/completions`.
17
18
 
18
19
  Out of scope:
@@ -71,7 +72,7 @@ Outbound upstream proxy settings are controlled by environment variables:
71
72
  - `HTTPS_PROXY`
72
73
  - `https_proxy`
73
74
 
74
- When none are set, the proxy defaults to `http://127.0.0.1:8118`.
75
+ When none are set, the proxy connects directly to the upstream API without a proxy.
75
76
 
76
77
  You can also set the upstream proxy explicitly at startup:
77
78
 
@@ -113,13 +114,15 @@ Bind to all interfaces with local bearer auth:
113
114
  codex-api-proxy start --host 0.0.0.0 --api-key local-secret
114
115
  ```
115
116
 
117
+ Binding to `0.0.0.0`, `::`, or `[::]` requires `--api-key`; the proxy refuses to start on public interfaces without local bearer auth.
118
+
116
119
  Start with an explicit upstream proxy:
117
120
 
118
121
  ```bash
119
122
  codex-api-proxy start --proxy=http://127.0.0.1:8118
120
123
  ```
121
124
 
122
- Restart using the last saved start settings:
125
+ Restart using the last saved start config:
123
126
 
124
127
  ```bash
125
128
  codex-api-proxy restart
@@ -137,16 +140,24 @@ Status:
137
140
  codex-api-proxy status --verbose
138
141
  ```
139
142
 
143
+ Run diagnostics:
144
+
145
+ ```bash
146
+ codex-api-proxy doctor
147
+ ```
148
+
140
149
  ## CLI Options
141
150
 
142
151
  - `--host`: bind host, default `127.0.0.1`
143
152
  - `--port`: bind port, default `8765`
144
153
  - `--api-key`: require client requests to send `Authorization: Bearer <key>`
145
- - `--proxy`: upstream HTTP(S) proxy URL for OpenAI/Codex API calls
154
+ - `--proxy`: upstream HTTP(S) proxy URL for OpenAI/Codex API calls; omitted means direct upstream connections
146
155
  - `--log-level`: `debug`, `info`, `warning`, or `error`
156
+ - `--log-format`: `text` or `json` for application event logs
157
+ - `--models-cache-ttl`: seconds to cache `/v1/models`, default `300`; use `0` to disable
147
158
  - `--pid-file`: daemon pid file, default `~/.codex-api-proxy/codex-api-proxy.pid`
148
159
  - `--log-file`: daemon log file, default `~/.codex-api-proxy/codex-api-proxy.log`
149
- - `--state-file`: daemon state file, default `~/.codex-api-proxy/codex-api-proxy.state.json`
160
+ - `--state-file`: daemon config file, default `~/.codex-api-proxy/config.toml`
150
161
  - `--foreground`: run without daemonizing
151
162
 
152
163
  Environment variables for the local server:
@@ -177,6 +188,8 @@ Models:
177
188
  curl -sS http://127.0.0.1:8765/v1/models
178
189
  ```
179
190
 
191
+ `/v1/models` responses are cached locally for `--models-cache-ttl` seconds. Use `?refresh=true` to bypass and refresh the cache.
192
+
180
193
  Chat completion:
181
194
 
182
195
  ```bash
@@ -201,7 +214,60 @@ curl -sS http://127.0.0.1:8765/v1/responses \
201
214
  -d '{"model":"gpt-5.5","input":"Reply with exactly: pong"}'
202
215
  ```
203
216
 
204
- Image input through Chat Completions:
217
+ Anthropic-style Messages API:
218
+
219
+ ```bash
220
+ curl -sS http://127.0.0.1:8765/v1/messages \
221
+ -H 'Content-Type: application/json' \
222
+ -H 'anthropic-version: 2023-06-01' \
223
+ -d '{
224
+ "model": "gpt-5.5",
225
+ "max_tokens": 128,
226
+ "system": "Be brief.",
227
+ "messages": [{"role":"user","content":"Reply with exactly: pong"}]
228
+ }'
229
+ ```
230
+
231
+ Streaming Anthropic-style Messages API:
232
+
233
+ ```bash
234
+ curl -N http://127.0.0.1:8765/v1/messages \
235
+ -H 'Content-Type: application/json' \
236
+ -H 'anthropic-version: 2023-06-01' \
237
+ -d '{
238
+ "model": "gpt-5.5",
239
+ "max_tokens": 128,
240
+ "stream": true,
241
+ "messages": [{"role":"user","content":[{"type":"text","text":"Reply with exactly: pong"}]}]
242
+ }'
243
+ ```
244
+
245
+ When local `--api-key` auth is enabled, `/v1/messages` accepts either `Authorization: Bearer <key>` or `x-api-key: <key>` because Anthropic-compatible clients vary in which header they send.
246
+
247
+ The Anthropic compatibility layer currently covers text messages, system prompts, streaming text deltas, and image content blocks. Full Anthropic `tool_use` / `tool_result` round-tripping is not yet implemented.
248
+
249
+ When `--api-key` is configured:
250
+
251
+ ```bash
252
+ curl -sS http://127.0.0.1:8765/v1/chat/completions \
253
+ -H 'Authorization: Bearer local-secret' \
254
+ -H 'Content-Type: application/json' \
255
+ -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Reply with exactly: pong"}]}'
256
+ ```
257
+
258
+ ## Image Recognition
259
+
260
+ The proxy forwards image input to the upstream Codex/OpenAI Responses API for vision tasks.
261
+
262
+ Supported input shapes:
263
+
264
+ - Chat Completions: `image_url` parts with a `data:` URL or remote `https://` URL, plus optional `detail`
265
+ - Chat Completions: Responses-style `input_image` parts (passed through as-is)
266
+ - Anthropic Messages: `image` content blocks with `source.type` of `base64` or `url`
267
+
268
+ When using ChatGPT Codex credentials, image parts are converted to Responses API `input_image` parts before the upstream call. `/v1/responses` requests with `input_image` are passed through unchanged.
269
+
270
+ Chat Completions example:
205
271
 
206
272
  ```bash
207
273
  BASE64_IMAGE=$(base64 < image.jpg)
@@ -225,62 +291,100 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
225
291
  }'
226
292
  ```
227
293
 
228
- When using ChatGPT Codex credentials, Chat Completions image parts are converted to Responses API `input_image` parts. `/v1/responses` requests are passed through unchanged.
229
-
230
- Anthropic-style Messages API:
294
+ Anthropic Messages example:
231
295
 
232
296
  ```bash
297
+ BASE64_IMAGE=$(base64 < image.jpg)
233
298
  curl -sS http://127.0.0.1:8765/v1/messages \
234
299
  -H 'Content-Type: application/json' \
235
300
  -H 'anthropic-version: 2023-06-01' \
236
301
  -d '{
237
302
  "model": "gpt-5.5",
238
- "max_tokens": 128,
239
- "system": "Be brief.",
240
- "messages": [{"role":"user","content":"Reply with exactly: pong"}]
303
+ "max_tokens": 256,
304
+ "messages": [{
305
+ "role": "user",
306
+ "content": [
307
+ {"type": "text", "text": "What is in this image?"},
308
+ {
309
+ "type": "image",
310
+ "source": {
311
+ "type": "base64",
312
+ "media_type": "image/jpeg",
313
+ "data": "'"$BASE64_IMAGE"'"
314
+ }
315
+ }
316
+ ]
317
+ }]
241
318
  }'
242
319
  ```
243
320
 
244
- Streaming Anthropic-style Messages API:
321
+ ## Claude Code
245
322
 
246
- ```bash
247
- curl -N http://127.0.0.1:8765/v1/messages \
248
- -H 'Content-Type: application/json' \
249
- -H 'anthropic-version: 2023-06-01' \
250
- -d '{
251
- "model": "gpt-5.5",
252
- "max_tokens": 128,
253
- "stream": true,
254
- "messages": [{"role":"user","content":[{"type":"text","text":"Reply with exactly: pong"}]}]
255
- }'
256
- ```
323
+ Claude Code speaks the Anthropic Messages API. Point it at this proxy so requests are converted to the upstream Codex/OpenAI Responses API using your existing `~/.codex/auth.json` credentials.
324
+
325
+ ### 1. Start the proxy
257
326
 
258
- For Anthropic-compatible clients such as Claude Code, point the Anthropic base URL at this proxy and use the local API key configured with `--api-key`, if any:
327
+ Start the proxy with a local API key if you want to protect the local endpoint:
259
328
 
260
329
  ```bash
261
- ANTHROPIC_BASE_URL=http://127.0.0.1:8765 \
262
- ANTHROPIC_AUTH_TOKEN=local-secret \
263
- claude
330
+ codex-api-proxy start --api-key sk-tmp
264
331
  ```
265
332
 
266
- When local `--api-key` auth is enabled, `/v1/messages` accepts either `Authorization: Bearer <key>` or `x-api-key: <key>` because Anthropic-compatible clients vary in which header they send.
333
+ `ANTHROPIC_AUTH_TOKEN` in Claude Code must match the value passed to `--api-key`. If you start the proxy without `--api-key`, local bearer auth is disabled and `ANTHROPIC_AUTH_TOKEN` is not required.
334
+
335
+ ### 2. Configure Claude Code
336
+
337
+ Edit `~/.claude/settings.json` and set the Anthropic base URL to this proxy:
338
+
339
+ ```json
340
+ {
341
+ "env": {
342
+ "ANTHROPIC_BASE_URL": "http://127.0.0.1:8765",
343
+ "ANTHROPIC_AUTH_TOKEN": "sk-tmp",
344
+ "ANTHROPIC_MODEL": "gpt-5.5",
345
+ "CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
346
+ "CLAUDE_CODE_DISABLE_ADAPTIVE_THINKING": "1"
347
+ },
348
+ "enabledPlugins": {
349
+ "superpowers@claude-plugins-official": true
350
+ },
351
+ "skipDangerousModePermissionPrompt": true,
352
+ "theme": "dark"
353
+ }
354
+ ```
267
355
 
268
- The Anthropic compatibility layer currently covers text messages, system prompts, streaming text deltas, and image content blocks. Full Anthropic `tool_use` / `tool_result` round-tripping is not yet implemented.
356
+ Key fields:
269
357
 
270
- When `--api-key` is configured:
358
+ - `ANTHROPIC_BASE_URL`: local proxy URL, default `http://127.0.0.1:8765`
359
+ - `ANTHROPIC_AUTH_TOKEN`: must match `codex-api-proxy start --api-key ...` when local auth is enabled
360
+ - `ANTHROPIC_MODEL`: upstream model id exposed by `/v1/models`, for example `gpt-5.5`
361
+
362
+ Restart Claude Code after changing `settings.json`.
363
+
364
+ ### 3. Verify
271
365
 
272
366
  ```bash
273
- curl -sS http://127.0.0.1:8765/v1/chat/completions \
274
- -H 'Authorization: Bearer local-secret' \
275
- -H 'Content-Type: application/json' \
276
- -d '{"model":"gpt-5.5","messages":[{"role":"user","content":"Reply with exactly: pong"}]}'
367
+ codex-api-proxy status --verbose
368
+ curl -sS http://127.0.0.1:8765/health
369
+ ```
370
+
371
+ Then launch Claude Code from a terminal:
372
+
373
+ ```bash
374
+ claude
277
375
  ```
278
376
 
377
+ Image attachments in Claude Code are sent as Anthropic `image` blocks and are converted by the proxy before the upstream request. Tool calling in Claude Code depends on Anthropic `tool_use` / `tool_result` support, which is not fully implemented in this proxy yet.
378
+
279
379
  ## Operations
280
380
 
281
- `/health` checks that credentials can be loaded and shows the upstream mode without exposing secrets.
381
+ `/health` is a process liveness check. It returns the proxy version and uptime without loading credentials, refreshing tokens, writing `auth.json`, or contacting upstream services.
382
+
383
+ `/ready` checks that credentials can be loaded and shows the upstream mode without exposing secrets. It may refresh Codex/ChatGPT tokens when refresh criteria are met.
384
+
385
+ `/metrics` returns local request counters as JSON. `/metrics/prometheus` returns Prometheus text format metrics.
282
386
 
283
- `/ready` is an alias of `/health`.
387
+ Successful proxied responses include `x-request-id`. The proxy uses incoming `x-request-id` or `x-correlation-id` when present, otherwise it generates one.
284
388
 
285
389
  `/metrics` returns local request counters:
286
390
 
@@ -292,4 +396,4 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
292
396
 
293
397
  When `--log-level debug` is set, chat completions log input messages and output messages through `codex_api_proxy.messages` and the daemon's `uvicorn.error` log stream. Streaming output is logged after the stream finishes. These logs can contain prompt and response data; use debug logging only in trusted environments.
294
398
 
295
- Latency summaries are logged through `codex_api_proxy.latency`.
399
+ Latency summaries are logged through `codex_api_proxy.latency`. Set `--log-format json` for structured JSON event logs.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "codex-api-proxy"
3
- version = "0.1.5"
3
+ version = "0.1.6"
4
4
  description = "Local OpenAI-compatible HTTP proxy backed by Codex/OpenAI credentials"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,3 +1,3 @@
1
1
  """OpenAI-compatible HTTP proxy backed by Codex/OpenAI credentials."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.6"