codex-openai-proxy 0.1.0-rc.1 → 0.1.0-rc.2
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 +95 -116
- package/dist/app-server/auth.js +11 -2
- package/dist/app-server/auth.js.map +1 -1
- package/dist/app-server/json-rpc.js +12 -2
- package/dist/app-server/json-rpc.js.map +1 -1
- package/dist/continuation/state.d.ts +5 -0
- package/dist/continuation/state.js +28 -2
- package/dist/continuation/state.js.map +1 -1
- package/dist/core/canonical.js +1 -1
- package/dist/core/canonical.js.map +1 -1
- package/dist/core/config.js +6 -2
- package/dist/core/config.js.map +1 -1
- package/dist/core/redact.d.ts +1 -1
- package/dist/core/redact.js +4 -3
- package/dist/core/redact.js.map +1 -1
- package/dist/http/chat-execute.js +24 -1
- package/dist/http/chat-execute.js.map +1 -1
- package/dist/http/chat-normalize.js +1 -1
- package/dist/http/chat-normalize.js.map +1 -1
- package/dist/http/chat-sse.js +6 -4
- package/dist/http/chat-sse.js.map +1 -1
- package/dist/http/chat-validate.d.ts +9 -3
- package/dist/http/chat-validate.js +71 -3
- package/dist/http/chat-validate.js.map +1 -1
- package/dist/http/chat.js +3 -0
- package/dist/http/chat.js.map +1 -1
- package/dist/http/server.js +10 -1
- package/dist/http/server.js.map +1 -1
- package/package.json +1 -1
- package/protocol/schemas/response-mapping.schema.json +2 -0
package/README.md
CHANGED
|
@@ -1,42 +1,46 @@
|
|
|
1
1
|
# codex-openai-proxy
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use any OpenAI Chat Completions client with Codex. The proxy runs `codex app-server` locally, authenticates with your ChatGPT login, and serves a loopback-only OpenAI-compatible endpoint.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
> Prerelease. Text completions, streaming, function tools, usage metadata, thread continuation, and per-request Codex policy selection are implemented.
|
|
6
6
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Requires Node.js 20+.
|
|
10
10
|
|
|
11
11
|
```sh
|
|
12
12
|
npx --yes codex-openai-proxy@next serve --root /absolute/path/to/project
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
- `--root` is the narrowest directory tree Codex may work in (defaults to the launch directory).
|
|
16
|
+
- The proxy listens at `http://127.0.0.1:8787` and starts the ChatGPT login flow on first use.
|
|
17
|
+
- Or install globally: `npm install --global codex-openai-proxy@next`, then `codex-openai-proxy serve --root ...`.
|
|
18
|
+
- Run `codex-openai-proxy --help` for all server, timeout, logging, and state options.
|
|
16
19
|
|
|
17
|
-
Check
|
|
20
|
+
Check status:
|
|
18
21
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
| Endpoint | Meaning |
|
|
23
|
+
| ------------- | ---------------------------------------------------------------------------------------------- |
|
|
24
|
+
| `GET /health` | 200 while the proxy process is alive |
|
|
25
|
+
| `GET /ready` | 200 once Codex is initialized and authenticated; 503 while starting, logging in, or recovering |
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
## Authentication
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
The proxy uses Codex's ChatGPT account session — no API key is exchanged. If Codex already has a usable account, startup reuses it silently. Otherwise:
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
codex-openai-proxy serve --root /absolute/path/to/project
|
|
31
|
-
```
|
|
31
|
+
- **Interactive terminal** — the proxy opens the browser authorization page. Complete the login and leave `serve` running. If the browser can't be launched, the URL is printed to the terminal.
|
|
32
|
+
- **Non-interactive (containers, services, CI)** — the proxy prints a verification URL and one-time device code to stderr. Keep stderr visible until login completes.
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
Notes:
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
- Completions return `app_server_not_ready` and `/ready` returns 503 until login finishes.
|
|
37
|
+
- The default login deadline is 5 minutes; raise it with e.g. `--tool-timeout 10m`.
|
|
38
|
+
- Treat printed authorization URLs and device codes as credentials — don't paste them into issues or logs.
|
|
39
|
+
- Uninstalling the proxy or deleting its state does **not** log out your Codex account; Codex owns the session.
|
|
36
40
|
|
|
37
41
|
## Use an OpenAI client
|
|
38
42
|
|
|
39
|
-
Point
|
|
43
|
+
Point any OpenAI-compatible client at `http://127.0.0.1:8787/v1`. No API key is required; use any placeholder if your library demands one.
|
|
40
44
|
|
|
41
45
|
```js
|
|
42
46
|
import OpenAI from "openai";
|
|
@@ -54,7 +58,7 @@ const completion = await client.chat.completions.create({
|
|
|
54
58
|
console.log(completion.choices[0].message.content);
|
|
55
59
|
```
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
Or with `curl`:
|
|
58
62
|
|
|
59
63
|
```sh
|
|
60
64
|
curl http://127.0.0.1:8787/v1/chat/completions \
|
|
@@ -65,61 +69,55 @@ curl http://127.0.0.1:8787/v1/chat/completions \
|
|
|
65
69
|
}'
|
|
66
70
|
```
|
|
67
71
|
|
|
68
|
-
##
|
|
69
|
-
|
|
70
|
-
The proxy intentionally implements a focused subset of Chat Completions rather than every OpenAI API endpoint.
|
|
71
|
-
|
|
72
|
-
Standard behavior includes:
|
|
73
|
-
|
|
74
|
-
- `POST /v1/chat/completions` with text-only `system`, `developer`, `user`, `assistant`, and `tool` messages;
|
|
75
|
-
- streaming and non-streaming responses;
|
|
76
|
-
- Chat Completions SSE framing ending with `data: [DONE]`;
|
|
77
|
-
- assistant text in `choices[].message.content` or `choices[].delta.content`;
|
|
78
|
-
- client-defined function tools, `tool_calls`, and `finish_reason: "tool_calls"`;
|
|
79
|
-
- `stream_options.include_usage`; and
|
|
80
|
-
- OpenAI-shaped JSON errors.
|
|
72
|
+
## What's supported
|
|
81
73
|
|
|
82
|
-
|
|
74
|
+
| Supported | Not supported |
|
|
75
|
+
| -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
76
|
+
| `POST /v1/chat/completions` with text-only messages (`system`, `developer`, `user`, `assistant`, `tool`) | Multimodal message content (images, audio) |
|
|
77
|
+
| Streaming (SSE, ends with `data: [DONE]`) and non-streaming | Responses API, embeddings, images, audio, model management |
|
|
78
|
+
| `reasoning_effort` (`none` … `max`, forwarded to Codex) | `tool_choice` other than `"auto"` / `"none"` |
|
|
79
|
+
| Client-defined function tools, `tool_calls`, `finish_reason: "tool_calls"` | More than one choice per response |
|
|
80
|
+
| `stream_options.include_usage` | Remote (non-loopback) serving |
|
|
81
|
+
| OpenAI-shaped JSON errors | |
|
|
83
82
|
|
|
84
|
-
|
|
83
|
+
Harmless unsupported fields are ignored with one structured warning. Malformed or ambiguous input is rejected rather than approximated.
|
|
85
84
|
|
|
86
85
|
## Streaming
|
|
87
86
|
|
|
88
|
-
Set `stream: true` as
|
|
87
|
+
Set `stream: true` as usual:
|
|
89
88
|
|
|
90
89
|
```sh
|
|
91
90
|
curl -N http://127.0.0.1:8787/v1/chat/completions \
|
|
92
91
|
-H 'Content-Type: application/json' \
|
|
93
92
|
-d '{
|
|
94
93
|
"model": "gpt-5.4-mini",
|
|
94
|
+
"reasoning_effort": "high",
|
|
95
95
|
"messages": [{"role": "user", "content": "Describe this repository."}],
|
|
96
96
|
"stream": true,
|
|
97
97
|
"stream_options": {"include_usage": true}
|
|
98
98
|
}'
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
Standard clients
|
|
101
|
+
Standard clients get assistant text, function calls, the finish reason, and the optional usage chunk. Codex reasoning and internal activity arrive in the nonstandard fields described under [Codex-specific extensions](#codex-specific-extensions).
|
|
102
102
|
|
|
103
103
|
## Function tools
|
|
104
104
|
|
|
105
|
-
Function tools
|
|
105
|
+
Function tools follow the normal multi-request Chat Completions flow:
|
|
106
106
|
|
|
107
|
-
1. Send
|
|
108
|
-
2. Receive an assistant response
|
|
109
|
-
3. Execute the
|
|
110
|
-
4. Send the assistant tool-call message
|
|
107
|
+
1. Send your function definitions in `tools`.
|
|
108
|
+
2. Receive an assistant response with `tool_calls`.
|
|
109
|
+
3. Execute the functions in your client.
|
|
110
|
+
4. Send the assistant tool-call message plus matching `role: "tool"` messages — repeating the same `tools`, `reasoning_effort`, and `x_codex` settings as the original request.
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
Pending tool calls are held in memory for five minutes by default. They cannot survive a proxy restart; completed threads can.
|
|
112
|
+
Changing those settings between the call and its results is rejected (`continuation_reasoning_effort_mismatch` / `continuation_policy_mismatch`); the pending call stays intact so you can retry corrected. Pending tool calls are held in memory for 5 minutes, with the deadline restarted whenever an incoming request selects the pending response by `previous_response_id` or matching tool-call IDs. They do not survive a proxy restart.
|
|
115
113
|
|
|
116
114
|
## Codex-specific extensions
|
|
117
115
|
|
|
118
|
-
|
|
116
|
+
These are additive but nonstandard. Strict Chat Completions clients should ignore or strip them.
|
|
119
117
|
|
|
120
118
|
### Continue a Codex thread
|
|
121
119
|
|
|
122
|
-
|
|
120
|
+
Pass the `id` of the newest completed response as top-level `previous_response_id` to continue its persisted Codex thread:
|
|
123
121
|
|
|
124
122
|
```json
|
|
125
123
|
{
|
|
@@ -129,19 +127,27 @@ Codex-specific behavior is additive but nonstandard. Clients that require strict
|
|
|
129
127
|
}
|
|
130
128
|
```
|
|
131
129
|
|
|
132
|
-
|
|
130
|
+
- Send only the new user message — the persisted thread already has the earlier turns.
|
|
131
|
+
- A continuation must use the same model, `reasoning_effort`, tools, and `x_codex` settings as the original.
|
|
132
|
+
- Only the newest response can be continued; unknown, expired, superseded, or busy IDs are rejected — the proxy never silently starts a new thread.
|
|
133
|
+
- Completed threads survive a proxy restart.
|
|
133
134
|
|
|
134
135
|
### Receive Codex activity
|
|
135
136
|
|
|
136
|
-
|
|
137
|
+
Responses can include two nonstandard fields on the assistant delta/message:
|
|
138
|
+
|
|
139
|
+
| Field | Contents |
|
|
140
|
+
| -------------- | --------------------------------------------------------------------------------------------- |
|
|
141
|
+
| `reasoning` | Codex's reasoning summary (string) |
|
|
142
|
+
| `tool_results` | Status/results of Codex's internal activity (commands, file changes, MCP calls, web searches) |
|
|
137
143
|
|
|
138
|
-
Internal
|
|
144
|
+
Internal activity also appears as function-shaped entries in `tool_calls`. These are **observational** — Codex already executed them. Do not execute them, and do not send tool results for them; they never cause `finish_reason: "tool_calls"`. Only your own client-defined functions suspend the turn and require `role: "tool"` follow-ups.
|
|
139
145
|
|
|
140
|
-
|
|
146
|
+
If your client replays a prior assistant message verbatim in a fresh request, the proxy strips these observational fields automatically.
|
|
141
147
|
|
|
142
148
|
### Select Codex policy
|
|
143
149
|
|
|
144
|
-
|
|
150
|
+
Per-request Codex controls live under a nonstandard top-level `x_codex` object:
|
|
145
151
|
|
|
146
152
|
```json
|
|
147
153
|
{
|
|
@@ -155,65 +161,52 @@ Working-directory, sandbox, and web-search controls are nonstandard request exte
|
|
|
155
161
|
}
|
|
156
162
|
```
|
|
157
163
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
Continuations must repeat the same effective `x_codex` settings. A change is rejected with `continuation_cwd_mismatch` or `continuation_policy_mismatch` before the thread is resumed.
|
|
165
|
-
|
|
166
|
-
The machine-readable request-extension schema is [protocol/schemas/x-codex.schema.json](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/protocol/schemas/x-codex.schema.json), shipped inside the installed package at `protocol/schemas/x-codex.schema.json`.
|
|
167
|
-
|
|
168
|
-
> **Project trust side effect:** Starting a new thread with `workspace-write` and a `cwd` can cause app-server to mark that project as trusted in the user's `config.toml`. Set `--root` to the narrowest appropriate boundary; the proxy will not cause app-server to trust a directory outside it.
|
|
164
|
+
| Field | Values | Default | Notes |
|
|
165
|
+
| ------------ | ---------------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------- |
|
|
166
|
+
| `cwd` | absolute path | the configured `--root` | Must be the root or a descendant; symlink escapes and relative paths are rejected |
|
|
167
|
+
| `sandbox` | `read-only`, `workspace-write`, `danger-full-access` | `read-only` | Full access is never selected implicitly |
|
|
168
|
+
| `web_search` | `disabled`, `cached`, `indexed`, `live` | `disabled` | Applied per Codex thread |
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
The JSON Schema ships with the package at `protocol/schemas/x-codex.schema.json`.
|
|
171
171
|
|
|
172
|
-
|
|
172
|
+
> **Project trust:** starting a new thread with `workspace-write` and a `cwd` can cause Codex to mark that project as trusted in your `config.toml`. Keep `--root` as narrow as possible.
|
|
173
173
|
|
|
174
174
|
## Usage metadata
|
|
175
175
|
|
|
176
|
-
When
|
|
176
|
+
When Codex reports exact usage for the turn, responses include standard `prompt_tokens`, `completion_tokens`, and `total_tokens`, plus cached-input and reasoning-token detail when available. When no complete record exists, `usage` is omitted — never estimated.
|
|
177
177
|
|
|
178
|
-
## Safety and
|
|
178
|
+
## Safety and limits
|
|
179
179
|
|
|
180
|
-
The listener accepts only `127.0.0.1`, `::1`,
|
|
180
|
+
- The listener accepts loopback only (`127.0.0.1`, `::1`, `localhost`); non-loopback `Host` authorities and any request with an `Origin` header are rejected.
|
|
181
|
+
- There is no local bearer-token check, so any process running as your user can call the proxy. See the [security model](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/security.md).
|
|
182
|
+
- Structured JSON logs go to stderr. Default logs omit paths and command details; `--log-level debug` may reveal them, so review debug output before sharing.
|
|
181
183
|
|
|
182
|
-
|
|
184
|
+
Default limits (all configurable via CLI flags):
|
|
183
185
|
|
|
184
|
-
|
|
186
|
+
| Limit | Default |
|
|
187
|
+
| ------------------------------------------- | ------------------------------------------- |
|
|
188
|
+
| JSON body size | 1 MiB |
|
|
189
|
+
| Concurrent HTTP requests | 100 (excess rejected with 429 `overloaded`) |
|
|
190
|
+
| Request deadline | 30 s |
|
|
191
|
+
| Suspended tool-call deadline | 5 min |
|
|
192
|
+
| Login / startup deadline (`--tool-timeout`) | 5 min |
|
|
185
193
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
## Limits and recovery
|
|
189
|
-
|
|
190
|
-
The safe defaults are a 1 MiB JSON body, 100 concurrent HTTP requests, a 30-second request deadline, a five-minute suspended dynamic-tool deadline, and a 10-second graceful-shutdown deadline. Each is configurable through the CLI. A full HTTP request pool rejects new work with HTTP 429 `overloaded`; requests never enter an unbounded queue. A second request for an active Codex thread is rejected with HTTP 409 `thread_busy`.
|
|
191
|
-
|
|
192
|
-
If app-server exits unexpectedly, `/ready` returns 503 while the proxy retries after bounded 1, 3, 5, and 10 second delays. Completed continuation records can survive a restart. Suspended client-defined tool calls cannot: shutdown or transport replacement fails their pending app-server requests and expires their mappings.
|
|
193
|
-
|
|
194
|
-
## Known incompatibilities
|
|
195
|
-
|
|
196
|
-
This proxy implements only the focused Chat Completions subset described above. In particular:
|
|
197
|
-
|
|
198
|
-
- content is text-only; multimodal message parts are unsupported;
|
|
199
|
-
- only one choice is produced, and harmless unsupported sampling/output fields are ignored with one warning;
|
|
200
|
-
- `tool_choice` supports only `auto` and `none`;
|
|
201
|
-
- response `reasoning` and `tool_results` require clients that tolerate nonstandard fields;
|
|
202
|
-
- continuation is linear and bound to the original model, tools, canonical cwd, and effective policy; and
|
|
203
|
-
- no endpoint other than health, readiness, and `POST /v1/chat/completions` is implemented.
|
|
194
|
+
A second request for an active Codex thread returns 409 `thread_busy`. If app-server crashes, the proxy retries with bounded backoff while `/ready` returns 503.
|
|
195
|
+
The request deadline aborts downstream work and closes any response that is still open, including a stream blocked by a client that stopped reading; its concurrency slot is then released.
|
|
204
196
|
|
|
205
197
|
## Troubleshooting
|
|
206
198
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
199
|
+
| Symptom | What to do |
|
|
200
|
+
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
201
|
+
| `/ready` returns 503 | Login or startup hasn't finished — follow [Authentication](#authentication) and check the stderr logs for `app_server_ready` or `startup_failed` |
|
|
202
|
+
| Browser login never appears | Non-terminal stderr selects device-code login; run `serve` in a foreground terminal without redirecting stderr |
|
|
203
|
+
| Address already in use | Choose another loopback `--port` |
|
|
204
|
+
| `--codex-path` override rejected | The override must report exactly `codex-cli 0.144.5` (the version bundled with this package); remove the flag to use the bundled executable |
|
|
205
|
+
| Policy request denied | Managed requirements disallow the value; the proxy never silently weakens policy |
|
|
213
206
|
|
|
214
|
-
|
|
207
|
+
For deeper diagnosis, temporarily add `--log-level debug` — but treat its output as sensitive.
|
|
215
208
|
|
|
216
|
-
|
|
209
|
+
## Uninstall and cleanup
|
|
217
210
|
|
|
218
211
|
```sh
|
|
219
212
|
npm uninstall --global codex-openai-proxy
|
|
@@ -221,26 +214,12 @@ npm uninstall --global codex-openai-proxy
|
|
|
221
214
|
npm uninstall codex-openai-proxy
|
|
222
215
|
```
|
|
223
216
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
The namespace name is the first 16 hexadecimal characters of the SHA-256 digest of the canonical absolute root. This command prints it without deleting anything:
|
|
227
|
-
|
|
228
|
-
```sh
|
|
229
|
-
node -e 'const c=require("node:crypto"),f=require("node:fs");const p=f.realpathSync(process.argv[1]);console.log(c.createHash("sha256").update(p).digest("hex").slice(0,16))' /absolute/path/to/project
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Inspect `~/.codex-openai-proxy/<printed-namespace>` before deleting it.
|
|
233
|
-
|
|
234
|
-
## Verification modes
|
|
235
|
-
|
|
236
|
-
- `npm ci && npm run check` is the deterministic offline gate: it regenerates the pinned protocol in a temporary tree for comparison, type-checks, and runs the bounded offline test suites. Required CI runs the same gate on Node.js 24 on Linux, macOS, and Windows.
|
|
237
|
-
- `npm run test:package` builds one tarball and installs it in npm offline mode with lifecycle scripts disabled, exercising the generated bin shim against a local fake app-server. It performs no registry request, login, or live model call. Release automation publishes the exact tarball this smoke retained (`-- --retain`) rather than rebuilding at publish time.
|
|
238
|
-
- `npm run test:package -- --registry-install` is the separate networked packaging check, dispatched on Linux, macOS, and Windows outside required offline CI.
|
|
239
|
-
- `npm run test:live` is the opt-in live compatibility check: serial, `gpt-5.4-mini` only, normally five model calls with a hard maximum of six, and requires explicit authorization. It is never a pull-request prerequisite.
|
|
217
|
+
- Continuation state lives under `~/.codex-openai-proxy` (one namespace per `--root`), or your custom `--state-dir`. Uninstalling does not delete it.
|
|
218
|
+
- Stop every proxy using a root before deleting its namespace. Deleting state invalidates its `previous_response_id` values but does not touch Codex's own threads or your ChatGPT login.
|
|
240
219
|
|
|
241
|
-
##
|
|
220
|
+
## Documentation
|
|
242
221
|
|
|
243
|
-
- [
|
|
244
|
-
- [Security model](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/security.md)
|
|
245
|
-
- [Implementation plan](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/plans/README.md)
|
|
246
|
-
- [App-server protocol reference](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/codex-app-server.md)
|
|
222
|
+
- [Development guide](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/development.md) — source layout, commands, tests, and verification modes
|
|
223
|
+
- [Security model](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/security.md) — threat model and audit boundary
|
|
224
|
+
- [Implementation plan](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/plans/README.md) — decisions and remaining work
|
|
225
|
+
- [App-server protocol reference](https://github.com/CIVITAS-John/codex-app-server-to-proxy/blob/main/docs/codex-app-server.md)
|
package/dist/app-server/auth.js
CHANGED
|
@@ -3,7 +3,11 @@ import { once } from "node:events";
|
|
|
3
3
|
import { listenForAbort, withDeadline } from "../core/abort.js";
|
|
4
4
|
/** Ensures app-server has an authenticated OpenAI account. */
|
|
5
5
|
export async function ensureAuthenticated(options) {
|
|
6
|
-
|
|
6
|
+
// Bound the probe so a stalled app-server fails startup instead of hanging it.
|
|
7
|
+
const account = (await withDeadline(options.signal, {
|
|
8
|
+
milliseconds: options.timeoutMs,
|
|
9
|
+
timeoutReason: new Error("account/read timed out."),
|
|
10
|
+
}, async (deadlineSignal) => await options.rpc.request("account/read", { refreshToken: false }, deadlineSignal)));
|
|
7
11
|
if (typeof account.requiresOpenaiAuth !== "boolean")
|
|
8
12
|
throw new Error("account/read returned an invalid requiresOpenaiAuth value.");
|
|
9
13
|
if (!account.requiresOpenaiAuth || account.account != null)
|
|
@@ -48,8 +52,12 @@ async function startAndWaitForLogin(options, useDeviceCode) {
|
|
|
48
52
|
const disposeDeadline = listenForAbort(deadlineSignal, (abortedSignal) => settle(abortedSignal.reason instanceof Error
|
|
49
53
|
? abortedSignal.reason
|
|
50
54
|
: new Error("ChatGPT login cancelled.")));
|
|
55
|
+
// A transport that dies mid-login must settle the wait immediately
|
|
56
|
+
// rather than reporting a misleading timeout after the full deadline.
|
|
57
|
+
const onTransportClose = (reason) => settle(reason);
|
|
58
|
+
options.rpc.once("close", onTransportClose);
|
|
51
59
|
try {
|
|
52
|
-
const login = (await options.rpc.request("account/login/start", { type: useDeviceCode ? "chatgptDeviceCode" : "chatgpt" },
|
|
60
|
+
const login = (await options.rpc.request("account/login/start", { type: useDeviceCode ? "chatgptDeviceCode" : "chatgpt" }, deadlineSignal));
|
|
53
61
|
loginId = login.loginId;
|
|
54
62
|
if (earlyCompletion !== undefined)
|
|
55
63
|
notification("account/login/completed", earlyCompletion);
|
|
@@ -74,6 +82,7 @@ async function startAndWaitForLogin(options, useDeviceCode) {
|
|
|
74
82
|
await completion;
|
|
75
83
|
}
|
|
76
84
|
finally {
|
|
85
|
+
options.rpc.off("close", onTransportClose);
|
|
77
86
|
disposeDeadline();
|
|
78
87
|
}
|
|
79
88
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/app-server/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAGnC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AA+BhE,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,OAA8B;IAE9B,MAAM,OAAO,GAAG,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/app-server/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,10 @@ export class JsonRpcTransport extends EventEmitter {
|
|
|
20
20
|
#closed = false;
|
|
21
21
|
constructor(input, output, maxPending = 256) {
|
|
22
22
|
super();
|
|
23
|
+
// The shared transport intentionally fans notifications out to every active
|
|
24
|
+
// HTTP request. Those request lifecycles detach their listeners, so a fixed
|
|
25
|
+
// warning threshold would misdiagnose valid configured concurrency as a leak.
|
|
26
|
+
this.setMaxListeners(0);
|
|
23
27
|
this.#output = output;
|
|
24
28
|
this.#maxPending = maxPending;
|
|
25
29
|
const lines = createInterface({ input, crlfDelay: Infinity });
|
|
@@ -117,9 +121,15 @@ export class JsonRpcTransport extends EventEmitter {
|
|
|
117
121
|
if (!pending)
|
|
118
122
|
return;
|
|
119
123
|
this.#pending.delete(message.id);
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
if ("error" in message) {
|
|
125
|
+
const error = record(message.error);
|
|
126
|
+
if (!error || typeof error.code !== "number") {
|
|
127
|
+
this.emit("malformed", line);
|
|
128
|
+
pending.reject(new Error("app-server emitted malformed JSON-RPC error"));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
122
131
|
pending.reject(new RpcError(error.code, String(error.message ?? "JSON-RPC error")));
|
|
132
|
+
}
|
|
123
133
|
else
|
|
124
134
|
pending.resolve(message.result);
|
|
125
135
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-rpc.js","sourceRoot":"","sources":["../../src/app-server/json-rpc.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"json-rpc.js","sourceRoot":"","sources":["../../src/app-server/json-rpc.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,12 +4,15 @@ export { bindingHash, canonicalJson };
|
|
|
4
4
|
/** Context that must remain identical over a Codex thread's lifetime. */
|
|
5
5
|
export interface ThreadBinding {
|
|
6
6
|
model: string;
|
|
7
|
+
reasoningEffort?: string;
|
|
7
8
|
cwd: string;
|
|
8
9
|
toolsHash: string;
|
|
9
10
|
policyHash: string;
|
|
10
11
|
}
|
|
11
12
|
/** One opaque response-to-thread record persisted by the proxy. */
|
|
12
13
|
export interface ResponseRecord extends ThreadBinding {
|
|
14
|
+
/** Marks records written after reasoning effort became an exact binding. */
|
|
15
|
+
reasoningEffortBound?: true;
|
|
13
16
|
responseId: string;
|
|
14
17
|
threadId: string;
|
|
15
18
|
state: "ready" | "pending_tool" | "expired" | "superseded" | "corrupt";
|
|
@@ -60,6 +63,8 @@ export declare class ContinuationCoordinator {
|
|
|
60
63
|
suspend(responseId: string, binding: ThreadBinding, calls: PendingToolCall[]): void;
|
|
61
64
|
/** Returns the live suspension, distinguishing restart tombstones from unknown IDs. */
|
|
62
65
|
pending(responseId: string): PendingToolCall[] | undefined;
|
|
66
|
+
/** Restarts the deadline for one live suspension selected by a request. */
|
|
67
|
+
refreshPending(responseId: string): boolean;
|
|
63
68
|
/** Resolves live pending tool IDs to exactly one suspended response. */
|
|
64
69
|
findPendingResponse(callIds: readonly string[]): string;
|
|
65
70
|
/** Answers pending calls in deterministic call order and consumes the suspension. */
|
|
@@ -60,6 +60,8 @@ export class ResponseStore {
|
|
|
60
60
|
const now = Date.now();
|
|
61
61
|
const stored = {
|
|
62
62
|
...record,
|
|
63
|
+
// Absence identifies ambiguous records written by pre-upgrade releases.
|
|
64
|
+
reasoningEffortBound: true,
|
|
63
65
|
createdAt: now,
|
|
64
66
|
expiresAt: now + this.retentionMs,
|
|
65
67
|
};
|
|
@@ -231,6 +233,15 @@ export class ContinuationCoordinator {
|
|
|
231
233
|
// A concurrently closed transport has already failed the request.
|
|
232
234
|
}
|
|
233
235
|
}
|
|
236
|
+
/** Expires a suspension without letting lifecycle cleanup fail on disk errors. */
|
|
237
|
+
#expireBestEffort(responseId) {
|
|
238
|
+
try {
|
|
239
|
+
this.store.update(responseId, { state: "expired" });
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
// Restart turns a stale pending-tool record into the same expired tombstone.
|
|
243
|
+
}
|
|
244
|
+
}
|
|
234
245
|
/** Routes one dynamic-tool callback to the sole owner of its thread. */
|
|
235
246
|
#routeToolRequest = (request) => {
|
|
236
247
|
if (request.method !== "item/tool/call")
|
|
@@ -322,7 +333,7 @@ export class ContinuationCoordinator {
|
|
|
322
333
|
}
|
|
323
334
|
this.#pending.delete(responseId);
|
|
324
335
|
this.#busy.delete(threadId);
|
|
325
|
-
this
|
|
336
|
+
this.#expireBestEffort(responseId);
|
|
326
337
|
}, this.toolTimeoutMs);
|
|
327
338
|
timer.unref();
|
|
328
339
|
this.#pending.set(responseId, { calls, timer });
|
|
@@ -331,6 +342,14 @@ export class ContinuationCoordinator {
|
|
|
331
342
|
pending(responseId) {
|
|
332
343
|
return this.#pending.get(responseId)?.calls;
|
|
333
344
|
}
|
|
345
|
+
/** Restarts the deadline for one live suspension selected by a request. */
|
|
346
|
+
refreshPending(responseId) {
|
|
347
|
+
const entry = this.#pending.get(responseId);
|
|
348
|
+
if (!entry)
|
|
349
|
+
return false;
|
|
350
|
+
entry.timer.refresh();
|
|
351
|
+
return true;
|
|
352
|
+
}
|
|
334
353
|
/** Resolves live pending tool IDs to exactly one suspended response. */
|
|
335
354
|
findPendingResponse(callIds) {
|
|
336
355
|
const requested = new Set(callIds);
|
|
@@ -400,7 +419,7 @@ export class ContinuationCoordinator {
|
|
|
400
419
|
clearTimeout(entry.timer);
|
|
401
420
|
for (const call of entry.calls)
|
|
402
421
|
this.#failRequestReplaced(call.request.id);
|
|
403
|
-
this
|
|
422
|
+
this.#expireBestEffort(responseId);
|
|
404
423
|
}
|
|
405
424
|
this.#pending.clear();
|
|
406
425
|
}
|
|
@@ -415,6 +434,8 @@ function isResponseRecord(value) {
|
|
|
415
434
|
"threadId",
|
|
416
435
|
"state",
|
|
417
436
|
"model",
|
|
437
|
+
"reasoningEffort",
|
|
438
|
+
"reasoningEffortBound",
|
|
418
439
|
"cwd",
|
|
419
440
|
"toolsHash",
|
|
420
441
|
"policyHash",
|
|
@@ -438,6 +459,11 @@ function isResponseRecord(value) {
|
|
|
438
459
|
record.threadId.length > 0 &&
|
|
439
460
|
typeof record.model === "string" &&
|
|
440
461
|
record.model.length > 0 &&
|
|
462
|
+
(record.reasoningEffort === undefined ||
|
|
463
|
+
(typeof record.reasoningEffort === "string" &&
|
|
464
|
+
record.reasoningEffort.length > 0)) &&
|
|
465
|
+
(record.reasoningEffortBound === undefined ||
|
|
466
|
+
record.reasoningEffortBound === true) &&
|
|
441
467
|
typeof record.cwd === "string" &&
|
|
442
468
|
record.cwd.length > 0 &&
|
|
443
469
|
validHash(record.toolsHash) &&
|