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.
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/PKG-INFO +143 -39
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/README.md +142 -38
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/pyproject.toml +1 -1
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/__init__.py +1 -1
- codex_api_proxy-0.1.6/src/codex_api_proxy/anthropic_messages.py +490 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/cli.py +169 -26
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/config.py +5 -2
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/main.py +62 -30
- codex_api_proxy-0.1.6/src/codex_api_proxy/metrics.py +67 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/models.py +24 -0
- codex_api_proxy-0.1.6/src/codex_api_proxy/structured_logging.py +52 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/PKG-INFO +143 -39
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/SOURCES.txt +2 -0
- codex_api_proxy-0.1.6/tests/test_anthropic_messages.py +375 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_api.py +130 -2
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_cli.py +83 -7
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_config.py +3 -3
- codex_api_proxy-0.1.5/src/codex_api_proxy/anthropic_messages.py +0 -257
- codex_api_proxy-0.1.5/tests/test_anthropic_messages.py +0 -167
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/setup.cfg +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/auth.py +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/chat_completions.py +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy/sse_utils.py +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/dependency_links.txt +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/entry_points.txt +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/requires.txt +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/top_level.txt +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_auth.py +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_chat_completions.py +0 -0
- {codex_api_proxy-0.1.5 → codex_api_proxy-0.1.6}/tests/test_models.py +0 -0
- {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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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":
|
|
263
|
-
"
|
|
264
|
-
|
|
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
|
-
|
|
345
|
+
## Claude Code
|
|
269
346
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
|
|
351
|
+
Start the proxy with a local API key if you want to protect the local endpoint:
|
|
283
352
|
|
|
284
353
|
```bash
|
|
285
|
-
|
|
286
|
-
ANTHROPIC_AUTH_TOKEN=local-secret \
|
|
287
|
-
claude
|
|
354
|
+
codex-api-proxy start --api-key sk-tmp
|
|
288
355
|
```
|
|
289
356
|
|
|
290
|
-
|
|
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
|
-
|
|
380
|
+
Key fields:
|
|
293
381
|
|
|
294
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
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`
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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":
|
|
239
|
-
"
|
|
240
|
-
|
|
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
|
-
|
|
321
|
+
## Claude Code
|
|
245
322
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
|
|
327
|
+
Start the proxy with a local API key if you want to protect the local endpoint:
|
|
259
328
|
|
|
260
329
|
```bash
|
|
261
|
-
|
|
262
|
-
ANTHROPIC_AUTH_TOKEN=local-secret \
|
|
263
|
-
claude
|
|
330
|
+
codex-api-proxy start --api-key sk-tmp
|
|
264
331
|
```
|
|
265
332
|
|
|
266
|
-
|
|
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
|
-
|
|
356
|
+
Key fields:
|
|
269
357
|
|
|
270
|
-
|
|
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
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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`
|
|
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
|
-
|
|
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.
|