@askalf/dario 6.2.0 → 6.3.0
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.
- package/README.md +23 -3
- package/dist/codex-backend.d.ts +14 -0
- package/dist/codex-backend.js +142 -0
- package/dist/doctor-core.d.ts +15 -0
- package/dist/doctor-core.js +26 -0
- package/dist/midstream.d.ts +28 -0
- package/dist/midstream.js +56 -0
- package/dist/proxy.js +103 -16
- package/dist/responses-inbound.d.ts +108 -0
- package/dist/responses-inbound.js +616 -0
- package/docs/drift-monitor.md +6 -0
- package/docs/integrations/codex-cli.md +94 -0
- package/docs/midstream-continuation.md +26 -0
- package/package.json +1 -1
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Codex CLI on your Claude plan
|
|
2
|
+
|
|
3
|
+
OpenAI's Codex CLI runs on a Claude subscription through dario, with its
|
|
4
|
+
tools, since 6.3. The other way round — Claude Code on a ChatGPT plan — has
|
|
5
|
+
worked since 5.5.89. Both on one machine, one `dario proxy`, is the whole
|
|
6
|
+
point of the project in two panes.
|
|
7
|
+
|
|
8
|
+
## Why this needed a new endpoint
|
|
9
|
+
|
|
10
|
+
Codex CLI 0.154 removed `wire_api = "chat"` for custom providers
|
|
11
|
+
([openai/codex discussion 7782](https://github.com/openai/codex/discussions/7782)):
|
|
12
|
+
a provider has to speak the **Responses API** or it cannot be used at all. So
|
|
13
|
+
dario now has `POST /v1/responses`. The request is translated once at the front
|
|
14
|
+
door into the Messages shape every other dario path already serves — pool,
|
|
15
|
+
template, failover, mid-stream continuation — and everything written back is
|
|
16
|
+
translated at the write boundary. For a ChatGPT-subscription model the body
|
|
17
|
+
goes through to the codex backend untouched instead (it speaks Responses
|
|
18
|
+
natively), which is what keeps Codex's newest request features working there:
|
|
19
|
+
`additional_tools` input items, `custom` tools, `reasoning.context`,
|
|
20
|
+
`include`.
|
|
21
|
+
|
|
22
|
+
The OpenAI Agents SDK and anything else that speaks Responses gets the same
|
|
23
|
+
endpoint.
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
dario proxy # your Claude plan, port 3456
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`~/.codex/config.toml`:
|
|
32
|
+
|
|
33
|
+
```toml
|
|
34
|
+
model = "claude-opus-5"
|
|
35
|
+
model_provider = "dario"
|
|
36
|
+
|
|
37
|
+
[model_providers.dario]
|
|
38
|
+
name = "dario"
|
|
39
|
+
base_url = "http://127.0.0.1:3456/v1"
|
|
40
|
+
env_key = "DARIO_API_KEY"
|
|
41
|
+
wire_api = "responses"
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`export DARIO_API_KEY=dario` (any value until you set one on the proxy; then it
|
|
45
|
+
has to match), and `codex` runs on the Claude pool. `-m claude-sonnet-5` /
|
|
46
|
+
`-m claude-opus-5` / any `claude-*` id; `codex exec` works the same way.
|
|
47
|
+
|
|
48
|
+
With a ChatGPT account attached as well (`dario add altman`),
|
|
49
|
+
`-m gpt-5.6-sol` on the same provider block goes to that plan through dario —
|
|
50
|
+
pooling, failover and `x-dario-*` headers included.
|
|
51
|
+
|
|
52
|
+
Codex prints `Model metadata for claude-opus-5 not found. Defaulting to fallback
|
|
53
|
+
metadata` for any model it does not ship metadata for. Harmless: it falls back
|
|
54
|
+
to its classic request profile (top-level `tools` and `instructions`), which is
|
|
55
|
+
exactly the one the translation reads.
|
|
56
|
+
|
|
57
|
+
## What runs, and what does not
|
|
58
|
+
|
|
59
|
+
Verified on 2026-09-12 with Codex CLI 0.154.0 on a Claude Max plan:
|
|
60
|
+
|
|
61
|
+
- a plain turn;
|
|
62
|
+
- the full agent loop — `exec_command` called by Claude, executed by Codex,
|
|
63
|
+
the `function_call_output` returned, Claude answering from it — with the
|
|
64
|
+
17 KB Codex system prompt cached on the Claude side (98–99% cache reads
|
|
65
|
+
from the second turn);
|
|
66
|
+
- the same loop on a ChatGPT plan through the passthrough.
|
|
67
|
+
|
|
68
|
+
Translated on the Claude pool: `instructions` and `developer` messages
|
|
69
|
+
(hoisted to the system prompt, in order), `message` items with `input_text`,
|
|
70
|
+
`output_text` and `input_image` parts (data-URL and https images),
|
|
71
|
+
`function_call` / `function_call_output` (tool_use / tool_result, call ids
|
|
72
|
+
preserved), `function` tools (and `namespace` groups, flattened),
|
|
73
|
+
`tool_choice` including `required` and a named function,
|
|
74
|
+
`parallel_tool_calls: false`, `max_output_tokens`, `temperature`, `top_p`,
|
|
75
|
+
`reasoning.effort` (as dario's own `model:high` effort spelling). Back out:
|
|
76
|
+
`message`, `function_call` and `reasoning` items, the full Responses event
|
|
77
|
+
sequence with sequence numbers, usage in OpenAI terms (cached prefix inside
|
|
78
|
+
`input_tokens`, reported again under `cached_tokens`), `incomplete` on
|
|
79
|
+
`max_tokens`, `response.failed` on an upstream error.
|
|
80
|
+
|
|
81
|
+
Dropped, with a line at `--verbose`: hosted tool types the pool cannot run
|
|
82
|
+
(`web_search`, `file_search`, `mcp`, …), `custom` freeform tools,
|
|
83
|
+
`reasoning` items on the way in (OpenAI's encrypted content — the pool does
|
|
84
|
+
not need it back), `text.format`. `previous_response_id` on the Claude pool is a 400 naming the
|
|
85
|
+
field (dario is stateless there; send the full input each turn, which Codex
|
|
86
|
+
does); on a ChatGPT-subscription model it is forwarded untouched to a backend
|
|
87
|
+
that keeps state, `store` as you sent it or omitted for the backend's default.
|
|
88
|
+
|
|
89
|
+
Not built: a buffered (non-streaming) response from a ChatGPT-subscription
|
|
90
|
+
model on this route — the backend streams, and folding a Responses stream into
|
|
91
|
+
a response object is not written yet; the answer is a 400 naming `stream`.
|
|
92
|
+
Mid-stream continuation runs under this route on the Claude pool (the
|
|
93
|
+
translated request is an ordinary Anthropic-shape request) and not on the
|
|
94
|
+
passthrough.
|
|
@@ -134,6 +134,32 @@ is never closed with a synthetic `end_turn`; only the resume's own
|
|
|
134
134
|
| `--pool-fallback=…` | where the second hop goes; without an entry for the other provider a stream gets the same-model resume only |
|
|
135
135
|
|
|
136
136
|
On by default: it only ever acts where the alternative is a broken stream.
|
|
137
|
+
`dario doctor` reports which hops this host can take:
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
[ OK ] Continuation on: a dying stream resumes on the same model, then on gpt-5.6-sol → claude-sonnet-5 (two hops)
|
|
141
|
+
[ OK ] Continuation on: a dying stream resumes on the same model only — add --pool-fallback for a second hop on the other subscription
|
|
142
|
+
[INFO] Continuation off — a stream that dies mid-answer ends truncated (unset DARIO_MIDSTREAM_CONTINUE / drop --no-midstream-continue)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Seeing it happen
|
|
146
|
+
|
|
147
|
+
Nothing about a healthy stream shows the feature, so there is a tap that
|
|
148
|
+
kills one on purpose:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
DARIO_CHAOS_CUT_AFTER=300 dario proxy
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
The first streamed answer dies after 300 characters — the upstream socket is
|
|
155
|
+
cut from dario's side, exactly the failure a real reset produces — and the
|
|
156
|
+
continuation finishes it. Point any client at the proxy, ask for something
|
|
157
|
+
long, and watch the answer keep going past the cut; a raw `curl -N` shows the
|
|
158
|
+
seam comment. `DARIO_CHAOS_CUT_STREAMS=3` cuts the first three instead of one.
|
|
159
|
+
The tap spares resumes, so it shows the first hop — the same model finishing
|
|
160
|
+
its own answer; the other subscription takes over only when that model cannot
|
|
161
|
+
serve the resume. dario warns loudly at startup while the tap is set; it is a
|
|
162
|
+
demo and test affordance, never a default.
|
|
137
163
|
|
|
138
164
|
## How it was proven
|
|
139
165
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askalf/dario",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"description": "Use your Claude and ChatGPT subscriptions in Cursor, Cline, Aider, Claude Code and the Agent SDK — at subscription pricing, not per-token API bills. One local Anthropic + OpenAI-compatible endpoint: either plan answers either wire shape, with automatic failover when one hits its limit.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|