codex-api-proxy 0.1.4__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.4 → codex_api_proxy-0.1.6}/PKG-INFO +161 -16
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/README.md +160 -15
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/pyproject.toml +1 -1
- {codex_api_proxy-0.1.4 → 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.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/cli.py +169 -26
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/config.py +5 -2
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/main.py +276 -26
- codex_api_proxy-0.1.6/src/codex_api_proxy/metrics.py +67 -0
- {codex_api_proxy-0.1.4 → 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.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/PKG-INFO +161 -16
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/SOURCES.txt +4 -0
- codex_api_proxy-0.1.6/tests/test_anthropic_messages.py +375 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_api.py +130 -2
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_cli.py +83 -7
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_config.py +3 -3
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/setup.cfg +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/auth.py +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/chat_completions.py +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy/sse_utils.py +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/dependency_links.txt +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/entry_points.txt +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/requires.txt +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/src/codex_api_proxy.egg-info/top_level.txt +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_auth.py +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_chat_completions.py +0 -0
- {codex_api_proxy-0.1.4 → codex_api_proxy-0.1.6}/tests/test_models.py +0 -0
- {codex_api_proxy-0.1.4 → 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
|
|
@@ -34,8 +34,10 @@ This package is intentionally narrow:
|
|
|
34
34
|
|
|
35
35
|
- expose OpenAI-compatible local endpoints for clients such as OpenClaw;
|
|
36
36
|
- reuse the user's existing Codex/OpenAI login credentials;
|
|
37
|
-
- support `/v1/chat/completions`, `/v1/responses`, and `/v1/models`;
|
|
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 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;
|
|
39
41
|
- otherwise transparently forward OpenAI API-key requests to OpenAI's native `/chat/completions`.
|
|
40
42
|
|
|
41
43
|
Out of scope:
|
|
@@ -94,7 +96,7 @@ Outbound upstream proxy settings are controlled by environment variables:
|
|
|
94
96
|
- `HTTPS_PROXY`
|
|
95
97
|
- `https_proxy`
|
|
96
98
|
|
|
97
|
-
When none are set, the proxy
|
|
99
|
+
When none are set, the proxy connects directly to the upstream API without a proxy.
|
|
98
100
|
|
|
99
101
|
You can also set the upstream proxy explicitly at startup:
|
|
100
102
|
|
|
@@ -136,13 +138,15 @@ Bind to all interfaces with local bearer auth:
|
|
|
136
138
|
codex-api-proxy start --host 0.0.0.0 --api-key local-secret
|
|
137
139
|
```
|
|
138
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
|
+
|
|
139
143
|
Start with an explicit upstream proxy:
|
|
140
144
|
|
|
141
145
|
```bash
|
|
142
146
|
codex-api-proxy start --proxy=http://127.0.0.1:8118
|
|
143
147
|
```
|
|
144
148
|
|
|
145
|
-
Restart using the last saved start
|
|
149
|
+
Restart using the last saved start config:
|
|
146
150
|
|
|
147
151
|
```bash
|
|
148
152
|
codex-api-proxy restart
|
|
@@ -160,16 +164,24 @@ Status:
|
|
|
160
164
|
codex-api-proxy status --verbose
|
|
161
165
|
```
|
|
162
166
|
|
|
167
|
+
Run diagnostics:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
codex-api-proxy doctor
|
|
171
|
+
```
|
|
172
|
+
|
|
163
173
|
## CLI Options
|
|
164
174
|
|
|
165
175
|
- `--host`: bind host, default `127.0.0.1`
|
|
166
176
|
- `--port`: bind port, default `8765`
|
|
167
177
|
- `--api-key`: require client requests to send `Authorization: Bearer <key>`
|
|
168
|
-
- `--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
|
|
169
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
|
|
170
182
|
- `--pid-file`: daemon pid file, default `~/.codex-api-proxy/codex-api-proxy.pid`
|
|
171
183
|
- `--log-file`: daemon log file, default `~/.codex-api-proxy/codex-api-proxy.log`
|
|
172
|
-
- `--state-file`: daemon
|
|
184
|
+
- `--state-file`: daemon config file, default `~/.codex-api-proxy/config.toml`
|
|
173
185
|
- `--foreground`: run without daemonizing
|
|
174
186
|
|
|
175
187
|
Environment variables for the local server:
|
|
@@ -200,6 +212,8 @@ Models:
|
|
|
200
212
|
curl -sS http://127.0.0.1:8765/v1/models
|
|
201
213
|
```
|
|
202
214
|
|
|
215
|
+
`/v1/models` responses are cached locally for `--models-cache-ttl` seconds. Use `?refresh=true` to bypass and refresh the cache.
|
|
216
|
+
|
|
203
217
|
Chat completion:
|
|
204
218
|
|
|
205
219
|
```bash
|
|
@@ -224,7 +238,60 @@ curl -sS http://127.0.0.1:8765/v1/responses \
|
|
|
224
238
|
-d '{"model":"gpt-5.5","input":"Reply with exactly: pong"}'
|
|
225
239
|
```
|
|
226
240
|
|
|
227
|
-
|
|
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:
|
|
228
295
|
|
|
229
296
|
```bash
|
|
230
297
|
BASE64_IMAGE=$(base64 < image.jpg)
|
|
@@ -248,22 +315,100 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
|
|
|
248
315
|
}'
|
|
249
316
|
```
|
|
250
317
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
When `--api-key` is configured:
|
|
318
|
+
Anthropic Messages example:
|
|
254
319
|
|
|
255
320
|
```bash
|
|
256
|
-
|
|
257
|
-
|
|
321
|
+
BASE64_IMAGE=$(base64 < image.jpg)
|
|
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' \
|
|
325
|
+
-d '{
|
|
326
|
+
"model": "gpt-5.5",
|
|
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
|
+
}]
|
|
342
|
+
}'
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Claude Code
|
|
346
|
+
|
|
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
|
|
350
|
+
|
|
351
|
+
Start the proxy with a local API key if you want to protect the local endpoint:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
codex-api-proxy start --api-key sk-tmp
|
|
355
|
+
```
|
|
356
|
+
|
|
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
|
+
```
|
|
379
|
+
|
|
380
|
+
Key fields:
|
|
381
|
+
|
|
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
|
|
389
|
+
|
|
390
|
+
```bash
|
|
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
|
|
260
399
|
```
|
|
261
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
|
+
|
|
262
403
|
## Operations
|
|
263
404
|
|
|
264
|
-
`/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.
|
|
265
410
|
|
|
266
|
-
|
|
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.
|
|
267
412
|
|
|
268
413
|
`/metrics` returns local request counters:
|
|
269
414
|
|
|
@@ -275,4 +420,4 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
|
|
|
275
420
|
|
|
276
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.
|
|
277
422
|
|
|
278
|
-
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.
|
|
@@ -10,8 +10,10 @@ This package is intentionally narrow:
|
|
|
10
10
|
|
|
11
11
|
- expose OpenAI-compatible local endpoints for clients such as OpenClaw;
|
|
12
12
|
- reuse the user's existing Codex/OpenAI login credentials;
|
|
13
|
-
- support `/v1/chat/completions`, `/v1/responses`, and `/v1/models`;
|
|
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 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;
|
|
15
17
|
- otherwise transparently forward OpenAI API-key requests to OpenAI's native `/chat/completions`.
|
|
16
18
|
|
|
17
19
|
Out of scope:
|
|
@@ -70,7 +72,7 @@ Outbound upstream proxy settings are controlled by environment variables:
|
|
|
70
72
|
- `HTTPS_PROXY`
|
|
71
73
|
- `https_proxy`
|
|
72
74
|
|
|
73
|
-
When none are set, the proxy
|
|
75
|
+
When none are set, the proxy connects directly to the upstream API without a proxy.
|
|
74
76
|
|
|
75
77
|
You can also set the upstream proxy explicitly at startup:
|
|
76
78
|
|
|
@@ -112,13 +114,15 @@ Bind to all interfaces with local bearer auth:
|
|
|
112
114
|
codex-api-proxy start --host 0.0.0.0 --api-key local-secret
|
|
113
115
|
```
|
|
114
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
|
+
|
|
115
119
|
Start with an explicit upstream proxy:
|
|
116
120
|
|
|
117
121
|
```bash
|
|
118
122
|
codex-api-proxy start --proxy=http://127.0.0.1:8118
|
|
119
123
|
```
|
|
120
124
|
|
|
121
|
-
Restart using the last saved start
|
|
125
|
+
Restart using the last saved start config:
|
|
122
126
|
|
|
123
127
|
```bash
|
|
124
128
|
codex-api-proxy restart
|
|
@@ -136,16 +140,24 @@ Status:
|
|
|
136
140
|
codex-api-proxy status --verbose
|
|
137
141
|
```
|
|
138
142
|
|
|
143
|
+
Run diagnostics:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
codex-api-proxy doctor
|
|
147
|
+
```
|
|
148
|
+
|
|
139
149
|
## CLI Options
|
|
140
150
|
|
|
141
151
|
- `--host`: bind host, default `127.0.0.1`
|
|
142
152
|
- `--port`: bind port, default `8765`
|
|
143
153
|
- `--api-key`: require client requests to send `Authorization: Bearer <key>`
|
|
144
|
-
- `--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
|
|
145
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
|
|
146
158
|
- `--pid-file`: daemon pid file, default `~/.codex-api-proxy/codex-api-proxy.pid`
|
|
147
159
|
- `--log-file`: daemon log file, default `~/.codex-api-proxy/codex-api-proxy.log`
|
|
148
|
-
- `--state-file`: daemon
|
|
160
|
+
- `--state-file`: daemon config file, default `~/.codex-api-proxy/config.toml`
|
|
149
161
|
- `--foreground`: run without daemonizing
|
|
150
162
|
|
|
151
163
|
Environment variables for the local server:
|
|
@@ -176,6 +188,8 @@ Models:
|
|
|
176
188
|
curl -sS http://127.0.0.1:8765/v1/models
|
|
177
189
|
```
|
|
178
190
|
|
|
191
|
+
`/v1/models` responses are cached locally for `--models-cache-ttl` seconds. Use `?refresh=true` to bypass and refresh the cache.
|
|
192
|
+
|
|
179
193
|
Chat completion:
|
|
180
194
|
|
|
181
195
|
```bash
|
|
@@ -200,7 +214,60 @@ curl -sS http://127.0.0.1:8765/v1/responses \
|
|
|
200
214
|
-d '{"model":"gpt-5.5","input":"Reply with exactly: pong"}'
|
|
201
215
|
```
|
|
202
216
|
|
|
203
|
-
|
|
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:
|
|
204
271
|
|
|
205
272
|
```bash
|
|
206
273
|
BASE64_IMAGE=$(base64 < image.jpg)
|
|
@@ -224,22 +291,100 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
|
|
|
224
291
|
}'
|
|
225
292
|
```
|
|
226
293
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
When `--api-key` is configured:
|
|
294
|
+
Anthropic Messages example:
|
|
230
295
|
|
|
231
296
|
```bash
|
|
232
|
-
|
|
233
|
-
|
|
297
|
+
BASE64_IMAGE=$(base64 < image.jpg)
|
|
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' \
|
|
301
|
+
-d '{
|
|
302
|
+
"model": "gpt-5.5",
|
|
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
|
+
}]
|
|
318
|
+
}'
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Claude Code
|
|
322
|
+
|
|
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
|
|
326
|
+
|
|
327
|
+
Start the proxy with a local API key if you want to protect the local endpoint:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
codex-api-proxy start --api-key sk-tmp
|
|
331
|
+
```
|
|
332
|
+
|
|
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
|
+
```
|
|
355
|
+
|
|
356
|
+
Key fields:
|
|
357
|
+
|
|
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
|
|
365
|
+
|
|
366
|
+
```bash
|
|
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
|
|
236
375
|
```
|
|
237
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
|
+
|
|
238
379
|
## Operations
|
|
239
380
|
|
|
240
|
-
`/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.
|
|
241
386
|
|
|
242
|
-
|
|
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.
|
|
243
388
|
|
|
244
389
|
`/metrics` returns local request counters:
|
|
245
390
|
|
|
@@ -251,4 +396,4 @@ curl -sS http://127.0.0.1:8765/v1/chat/completions \
|
|
|
251
396
|
|
|
252
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.
|
|
253
398
|
|
|
254
|
-
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.
|