ai-sdk-provider-codex-cli 1.0.5 → 1.2.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 +148 -38
- package/dist/index.cjs +4799 -443
- package/dist/index.d.cts +663 -196
- package/dist/index.d.ts +663 -196
- package/dist/index.js +4786 -446
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -10,9 +10,14 @@
|
|
|
10
10
|
[](https://github.com/ben-vargas/ai-sdk-provider-codex-cli/issues)
|
|
11
11
|
[](https://github.com/ben-vargas/ai-sdk-provider-codex-cli/releases/latest)
|
|
12
12
|
|
|
13
|
-
A community provider for Vercel AI SDK v6 that
|
|
13
|
+
A community provider for Vercel AI SDK v6 that integrates OpenAI's Codex CLI with current GPT models such as `gpt-5.5`, `gpt-5.2`, and `gpt-5.1`, plus Codex-specific slugs like `gpt-5.3-codex`, `gpt-5.2-codex`, `*-codex-max`, and `*-codex-mini`, using your ChatGPT Plus/Pro subscription.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
This package ships two provider modes:
|
|
16
|
+
|
|
17
|
+
- `codexExec`: non-interactive `codex exec` (spawn a new process per call)
|
|
18
|
+
- `codexAppServer`: persistent `codex app-server` JSON-RPC client (shared process, true delta streaming, optional stateful threads)
|
|
19
|
+
|
|
20
|
+
- Works with `generateText`, `streamText`, and `generateObject`
|
|
16
21
|
- Uses ChatGPT OAuth from `codex login` (tokens in `~/.codex/auth.json`) or `OPENAI_API_KEY`
|
|
17
22
|
- Node-only (spawns a local process); supports CI and local dev
|
|
18
23
|
- **v1.0.0**: AI SDK v6 stable migration with LanguageModelV3 interface
|
|
@@ -49,7 +54,7 @@ npm i ai ai-sdk-provider-codex-cli
|
|
|
49
54
|
npm i ai@^5.0.0 ai-sdk-provider-codex-cli@ai-sdk-v5
|
|
50
55
|
```
|
|
51
56
|
|
|
52
|
-
> **⚠️ Codex CLI Version**: Requires Codex CLI
|
|
57
|
+
> **⚠️ Codex CLI Version**: Requires the current stable Codex CLI **0.130.x** for full support of both provider modes (`codexExec` and `codexAppServer`). This package pins its optional `@openai/codex` dependency to `^0.130.0`, the latest non-alpha release validated for this maintenance update. If you supply your own Codex CLI (global install or custom `codexPath`), check it with `codex --version` and upgrade if needed.
|
|
53
58
|
>
|
|
54
59
|
> ```bash
|
|
55
60
|
> npm i -g @openai/codex@latest
|
|
@@ -57,13 +62,13 @@ npm i ai@^5.0.0 ai-sdk-provider-codex-cli@ai-sdk-v5
|
|
|
57
62
|
|
|
58
63
|
## Quick Start
|
|
59
64
|
|
|
60
|
-
|
|
65
|
+
### Exec provider (`codexExec`) — process-per-call
|
|
61
66
|
|
|
62
67
|
```js
|
|
63
68
|
import { generateText } from 'ai';
|
|
64
|
-
import {
|
|
69
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
65
70
|
|
|
66
|
-
const model =
|
|
71
|
+
const model = codexExec('gpt-5.5', {
|
|
67
72
|
allowNpx: true,
|
|
68
73
|
skipGitRepoCheck: true,
|
|
69
74
|
approvalMode: 'on-failure',
|
|
@@ -77,31 +82,70 @@ const { text } = await generateText({
|
|
|
77
82
|
console.log(text);
|
|
78
83
|
```
|
|
79
84
|
|
|
80
|
-
|
|
85
|
+
### App-server provider (`createCodexAppServer`) — persistent process
|
|
81
86
|
|
|
82
87
|
```js
|
|
83
88
|
import { streamText } from 'ai';
|
|
84
|
-
import {
|
|
89
|
+
import { createCodexAppServer } from 'ai-sdk-provider-codex-cli';
|
|
90
|
+
|
|
91
|
+
const provider = createCodexAppServer({
|
|
92
|
+
defaultSettings: {
|
|
93
|
+
minCodexVersion: '0.130.0',
|
|
94
|
+
autoApprove: false,
|
|
95
|
+
personality: 'pragmatic',
|
|
96
|
+
},
|
|
97
|
+
});
|
|
85
98
|
|
|
86
|
-
// The provider works with both `gpt-5.1` and `gpt-5.1-codex`; use the latter for
|
|
87
|
-
// the Codex CLI specific slug. Legacy `gpt-5` slugs still work if you need them.
|
|
88
99
|
const { textStream } = await streamText({
|
|
89
|
-
model:
|
|
100
|
+
model: provider('gpt-5.5'),
|
|
90
101
|
prompt: 'Write two short lines of encouragement.',
|
|
91
102
|
});
|
|
92
103
|
for await (const chunk of textStream) process.stdout.write(chunk);
|
|
104
|
+
|
|
105
|
+
await provider.close();
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### App-server stateful threads (optional)
|
|
109
|
+
|
|
110
|
+
By default, `codexAppServer` is stateless (new ephemeral thread per call). To continue a prior conversation across calls, start a persistent thread and then pass its `threadId` in `providerOptions['codex-app-server']`.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
import { generateText } from 'ai';
|
|
114
|
+
import { createCodexAppServer } from 'ai-sdk-provider-codex-cli';
|
|
115
|
+
|
|
116
|
+
const provider = createCodexAppServer();
|
|
117
|
+
|
|
118
|
+
const first = await generateText({
|
|
119
|
+
model: provider('gpt-5.5'),
|
|
120
|
+
prompt: 'Start a migration checklist.',
|
|
121
|
+
providerOptions: {
|
|
122
|
+
'codex-app-server': { threadMode: 'persistent' },
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const threadId = first.providerMetadata?.['codex-app-server']?.threadId;
|
|
127
|
+
|
|
128
|
+
const second = await generateText({
|
|
129
|
+
model: provider('gpt-5.5'),
|
|
130
|
+
prompt: 'Continue from step 2.',
|
|
131
|
+
providerOptions: {
|
|
132
|
+
'codex-app-server': { threadId },
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
await provider.close();
|
|
93
137
|
```
|
|
94
138
|
|
|
95
|
-
Object generation (Zod)
|
|
139
|
+
### Object generation (Zod)
|
|
96
140
|
|
|
97
141
|
```js
|
|
98
142
|
import { generateObject } from 'ai';
|
|
99
143
|
import { z } from 'zod';
|
|
100
|
-
import {
|
|
144
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
101
145
|
|
|
102
146
|
const schema = z.object({ name: z.string(), age: z.number().int() });
|
|
103
147
|
const { object } = await generateObject({
|
|
104
|
-
model:
|
|
148
|
+
model: codexExec('gpt-5.5', { allowNpx: true, skipGitRepoCheck: true }),
|
|
105
149
|
schema,
|
|
106
150
|
prompt: 'Generate a small user profile.',
|
|
107
151
|
});
|
|
@@ -111,6 +155,10 @@ console.log(object);
|
|
|
111
155
|
## Features
|
|
112
156
|
|
|
113
157
|
- AI SDK v6 compatible (LanguageModelV3)
|
|
158
|
+
- Dual provider architecture:
|
|
159
|
+
- `codexExec` / `createCodexExec` for `codex exec`
|
|
160
|
+
- `codexAppServer` / `createCodexAppServer` for `codex app-server`
|
|
161
|
+
- Backward-compatible aliases: `codexCli` / `createCodexCli` map to exec mode
|
|
114
162
|
- Streaming and non‑streaming
|
|
115
163
|
- **Configurable logging** (v0.5.0+) - Verbose mode, custom loggers, or silent operation
|
|
116
164
|
- **Tool streaming support** (v0.3.0+) - Monitor autonomous tool execution in real-time
|
|
@@ -119,7 +167,7 @@ console.log(object);
|
|
|
119
167
|
- Safe defaults for non‑interactive automation (`on-failure`, `workspace-write`, `--skip-git-repo-check`)
|
|
120
168
|
- Fallback to `npx @openai/codex` when not on PATH (`allowNpx`)
|
|
121
169
|
- Usage tracking from experimental JSON event format
|
|
122
|
-
- **Image support** -
|
|
170
|
+
- **Image support** - Local binary images in both providers, plus remote HTTP/HTTPS image URLs in app-server mode
|
|
123
171
|
|
|
124
172
|
### Image Support
|
|
125
173
|
|
|
@@ -127,10 +175,10 @@ The provider supports multimodal (image) inputs for vision-capable models:
|
|
|
127
175
|
|
|
128
176
|
```js
|
|
129
177
|
import { generateText } from 'ai';
|
|
130
|
-
import {
|
|
178
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
131
179
|
import { readFileSync } from 'fs';
|
|
132
180
|
|
|
133
|
-
const model =
|
|
181
|
+
const model = codexExec('gpt-5.5', { allowNpx: true, skipGitRepoCheck: true });
|
|
134
182
|
const imageBuffer = readFileSync('./screenshot.png');
|
|
135
183
|
|
|
136
184
|
const { text } = await generateText({
|
|
@@ -154,13 +202,14 @@ console.log(text);
|
|
|
154
202
|
- Base64 string (without data URL prefix)
|
|
155
203
|
- `Buffer` / `Uint8Array` / `ArrayBuffer`
|
|
156
204
|
|
|
157
|
-
**
|
|
205
|
+
**Remote image URLs:**
|
|
158
206
|
|
|
159
|
-
- HTTP/HTTPS URLs
|
|
207
|
+
- `codexExec` mode: HTTP/HTTPS image URLs are not supported (provide binary/image data)
|
|
208
|
+
- `codexAppServer` mode: HTTP/HTTPS image URLs are supported and forwarded to app-server as remote image inputs
|
|
160
209
|
|
|
161
|
-
|
|
210
|
+
Local image data is written to temporary files and passed to Codex CLI via `--image` (or app-server `localImage`). Temp files are automatically cleaned up after each request.
|
|
162
211
|
|
|
163
|
-
See [examples/image-support.mjs](examples/image-support.mjs) for
|
|
212
|
+
See [examples/exec/image-support.mjs](examples/exec/image-support.mjs) and [examples/app-server/image-support.mjs](examples/app-server/image-support.mjs) for complete working examples.
|
|
164
213
|
|
|
165
214
|
### Tool Streaming (v0.3.0+)
|
|
166
215
|
|
|
@@ -168,10 +217,10 @@ The provider supports comprehensive tool streaming, enabling real-time monitorin
|
|
|
168
217
|
|
|
169
218
|
```js
|
|
170
219
|
import { streamText } from 'ai';
|
|
171
|
-
import {
|
|
220
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
172
221
|
|
|
173
222
|
const result = await streamText({
|
|
174
|
-
model:
|
|
223
|
+
model: codexExec('gpt-5.5', { allowNpx: true, skipGitRepoCheck: true }),
|
|
175
224
|
prompt: 'List files and count lines in the largest one',
|
|
176
225
|
});
|
|
177
226
|
|
|
@@ -192,30 +241,35 @@ for await (const part of result.fullStream) {
|
|
|
192
241
|
- Tool result events with complete output payloads
|
|
193
242
|
- `providerExecuted: true` on all tool calls (Codex executes autonomously, app doesn't need to)
|
|
194
243
|
|
|
195
|
-
**
|
|
244
|
+
**Current behavior:**
|
|
245
|
+
|
|
246
|
+
- `codexExec`: tool outputs are delivered in final `tool-result` events.
|
|
247
|
+
- `codexAppServer`: when Codex emits tool output delta notifications, the provider surfaces `tool-result` parts with `result.type === 'output-delta'` during streaming.
|
|
248
|
+
|
|
249
|
+
See `examples/exec/streaming-tool-calls.mjs`, `examples/exec/streaming-multiple-tools.mjs`, and their app-server counterparts under `examples/app-server/`.
|
|
196
250
|
|
|
197
251
|
### Logging Configuration (v0.5.0+)
|
|
198
252
|
|
|
199
253
|
Control logging verbosity and integrate with your observability stack:
|
|
200
254
|
|
|
201
255
|
```js
|
|
202
|
-
import {
|
|
256
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
203
257
|
|
|
204
258
|
// Default: warn/error only (clean production output)
|
|
205
|
-
const model =
|
|
259
|
+
const model = codexExec('gpt-5.5', {
|
|
206
260
|
allowNpx: true,
|
|
207
261
|
skipGitRepoCheck: true,
|
|
208
262
|
});
|
|
209
263
|
|
|
210
264
|
// Verbose mode: enable debug/info logs for troubleshooting
|
|
211
|
-
const verboseModel =
|
|
265
|
+
const verboseModel = codexExec('gpt-5.5', {
|
|
212
266
|
allowNpx: true,
|
|
213
267
|
skipGitRepoCheck: true,
|
|
214
268
|
verbose: true, // Shows all log levels
|
|
215
269
|
});
|
|
216
270
|
|
|
217
271
|
// Custom logger: integrate with Winston, Pino, Datadog, etc.
|
|
218
|
-
const customModel =
|
|
272
|
+
const customModel = codexExec('gpt-5.5', {
|
|
219
273
|
allowNpx: true,
|
|
220
274
|
skipGitRepoCheck: true,
|
|
221
275
|
verbose: true,
|
|
@@ -228,7 +282,7 @@ const customModel = codexCli('gpt-5.1-codex', {
|
|
|
228
282
|
});
|
|
229
283
|
|
|
230
284
|
// Silent: disable all logging
|
|
231
|
-
const silentModel =
|
|
285
|
+
const silentModel = codexExec('gpt-5.5', {
|
|
232
286
|
allowNpx: true,
|
|
233
287
|
skipGitRepoCheck: true,
|
|
234
288
|
logger: false, // No logs at all
|
|
@@ -244,23 +298,23 @@ const silentModel = codexCli('gpt-5.1-codex', {
|
|
|
244
298
|
|
|
245
299
|
**Default Logger:** Adds level tags `[DEBUG]`, `[INFO]`, `[WARN]`, `[ERROR]` to console output. Use a custom logger or `logger: false` if you need different formatting.
|
|
246
300
|
|
|
247
|
-
See `examples/logging-*.mjs` for complete examples and [docs/ai-sdk-v5/guide.md](docs/ai-sdk-v5/guide.md) for detailed configuration.
|
|
301
|
+
See `examples/exec/logging-*.mjs` and `examples/app-server/logging-*.mjs` for complete examples, and [docs/ai-sdk-v5/guide.md](docs/ai-sdk-v5/guide.md) for detailed configuration.
|
|
248
302
|
|
|
249
303
|
### Text Streaming behavior
|
|
250
304
|
|
|
251
|
-
|
|
305
|
+
**`codexExec` mode:** Incremental streaming is not currently available with `codex exec --experimental-json`.
|
|
252
306
|
|
|
253
307
|
The `--experimental-json` output format (introduced Sept 25, 2025) currently only emits `item.completed` events with full text content. Incremental streaming via `item.updated` or delta events is not yet implemented by OpenAI.
|
|
254
308
|
|
|
255
|
-
**What this means:**
|
|
309
|
+
**What this means in exec mode:**
|
|
256
310
|
|
|
257
311
|
- `streamText()` works functionally but delivers the entire response in a single chunk after generation completes
|
|
258
312
|
- No incremental text deltas—you wait for the full response, then receive it all at once
|
|
259
313
|
- The AI SDK's streaming interface is supported, but actual incremental streaming is not available
|
|
260
314
|
|
|
261
|
-
|
|
315
|
+
**`codexAppServer` mode:** supports true incremental text deltas via `item/agentMessage/delta`, so `streamText()` emits progressively as tokens arrive.
|
|
262
316
|
|
|
263
|
-
When OpenAI adds streaming support
|
|
317
|
+
When OpenAI adds streaming support to `codex exec --experimental-json`, this provider will surface those deltas in exec mode as well.
|
|
264
318
|
|
|
265
319
|
## Documentation
|
|
266
320
|
|
|
@@ -269,7 +323,12 @@ When OpenAI adds streaming support, this provider will be updated to handle thos
|
|
|
269
323
|
- [docs/ai-sdk-v5/configuration.md](docs/ai-sdk-v5/configuration.md) – all settings and how they map to CLI flags
|
|
270
324
|
- [docs/ai-sdk-v5/troubleshooting.md](docs/ai-sdk-v5/troubleshooting.md) – common issues and fixes
|
|
271
325
|
- [docs/ai-sdk-v5/limitations.md](docs/ai-sdk-v5/limitations.md) – known constraints and behavior differences
|
|
326
|
+
- [docs/ai-sdk-v5/migration-app-server-v2.md](docs/ai-sdk-v5/migration-app-server-v2.md) – app-server v2 migration notes
|
|
272
327
|
- See [examples/](examples/) for runnable scripts covering core usage, streaming, permissions/sandboxing, and object generation.
|
|
328
|
+
- Validation helpers:
|
|
329
|
+
- `npm run validate:docs` checks markdown links and example command paths
|
|
330
|
+
- `npm run validate:examples:app-server` runs all app-server examples with intent checks
|
|
331
|
+
- `npm run validate:full` runs build/type/lint/test plus docs and app-server example validation
|
|
273
332
|
|
|
274
333
|
## Authentication
|
|
275
334
|
|
|
@@ -294,14 +353,45 @@ When OpenAI adds streaming support, this provider will be updated to handle thos
|
|
|
294
353
|
|
|
295
354
|
See [docs/ai-sdk-v5/configuration.md](docs/ai-sdk-v5/configuration.md) for the full list and examples.
|
|
296
355
|
|
|
356
|
+
### App-server settings highlights
|
|
357
|
+
|
|
358
|
+
`createCodexAppServer({ defaultSettings })` accepts app-server specific options:
|
|
359
|
+
|
|
360
|
+
- `connectionTimeoutMs`: initialize handshake timeout
|
|
361
|
+
- `requestTimeoutMs`: default per-request JSON-RPC timeout
|
|
362
|
+
- `idleTimeoutMs`: close idle app-server process after inactivity
|
|
363
|
+
- `minCodexVersion`: minimum supported app-server version (semver)
|
|
364
|
+
- `includeRawChunks`: emit raw JSON-RPC notifications as `raw` stream parts by default
|
|
365
|
+
- `serverRequests`: typed handlers for server-initiated JSON-RPC requests
|
|
366
|
+
- `autoApprove`: default approval response when no custom handler is provided
|
|
367
|
+
- `persistExtendedHistory`: request extended thread history persistence
|
|
368
|
+
- `threadMode`: `stateless` (default) or `persistent` automatic thread reuse
|
|
369
|
+
- `resume`: shorthand to resume an existing thread id
|
|
370
|
+
- `onSessionCreated`: receive a session object for `injectMessage()` / `interrupt()`
|
|
371
|
+
|
|
372
|
+
Per-call app-server overrides use `providerOptions['codex-app-server']` (for example `threadId`, `threadMode`, `includeRawChunks`, `personality`, `approvalPolicy`, `sandboxPolicy`, `serverRequests`, `configOverrides`).
|
|
373
|
+
|
|
374
|
+
Additional app-server helpers:
|
|
375
|
+
|
|
376
|
+
- `listModels()`: query available models via a temporary app-server process (or use `provider.listModels()` to query through an existing provider/client)
|
|
377
|
+
- `tool()`, `createLocalMcpServer()`, `createSdkMcpServer()`: define and expose local MCP tools
|
|
378
|
+
|
|
379
|
+
Local MCP security defaults:
|
|
380
|
+
|
|
381
|
+
- `createLocalMcpServer()` binds to loopback hosts by default and rejects non-loopback `host` values unless you set `allowNonLoopbackHost: true`.
|
|
382
|
+
- `createLocalMcpServer()` generates a per-server bearer token and expects `Authorization: Bearer <token>` on direct HTTP calls. The token is available at `server.config.bearerToken`.
|
|
383
|
+
- `createSdkMcpServer()` propagates this auth config automatically, so provider-level MCP wiring works without extra manual headers.
|
|
384
|
+
- Without `cacheKey`, SDK MCP server/tool function identity participates in persistent keying to avoid conflating closure-dependent tool behavior.
|
|
385
|
+
- Use `createSdkMcpServer({ cacheKey })` when you intentionally recreate equivalent SDK MCP definitions per call and want stable persistent model reuse.
|
|
386
|
+
|
|
297
387
|
## Model Parameters & Advanced Options (v0.4.0+)
|
|
298
388
|
|
|
299
389
|
Control reasoning effort, verbosity, and advanced Codex features at model creation time:
|
|
300
390
|
|
|
301
391
|
```ts
|
|
302
|
-
import {
|
|
392
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
303
393
|
|
|
304
|
-
const model =
|
|
394
|
+
const model = codexExec('gpt-5.5', {
|
|
305
395
|
allowNpx: true,
|
|
306
396
|
skipGitRepoCheck: true,
|
|
307
397
|
addDirs: ['../shared'],
|
|
@@ -353,9 +443,9 @@ values take precedence over constructor defaults while leaving other settings in
|
|
|
353
443
|
|
|
354
444
|
```ts
|
|
355
445
|
import { generateText } from 'ai';
|
|
356
|
-
import {
|
|
446
|
+
import { codexExec } from 'ai-sdk-provider-codex-cli';
|
|
357
447
|
|
|
358
|
-
const model =
|
|
448
|
+
const model = codexExec('gpt-5.5', {
|
|
359
449
|
allowNpx: true,
|
|
360
450
|
reasoningEffort: 'medium',
|
|
361
451
|
modelVerbosity: 'medium',
|
|
@@ -387,6 +477,26 @@ const response = await generateText({
|
|
|
387
477
|
|
|
388
478
|
**Precedence:** `providerOptions['codex-cli']` > constructor `CodexCliSettings` > Codex CLI defaults.
|
|
389
479
|
|
|
480
|
+
App-server per-call overrides use `providerOptions['codex-app-server']`:
|
|
481
|
+
|
|
482
|
+
```ts
|
|
483
|
+
import { createCodexAppServer } from 'ai-sdk-provider-codex-cli';
|
|
484
|
+
|
|
485
|
+
const appServerProvider = createCodexAppServer();
|
|
486
|
+
|
|
487
|
+
const response = await generateText({
|
|
488
|
+
model: appServerProvider('gpt-5.5'),
|
|
489
|
+
prompt: 'Continue this task.',
|
|
490
|
+
providerOptions: {
|
|
491
|
+
'codex-app-server': {
|
|
492
|
+
threadId: 'thr_existing',
|
|
493
|
+
personality: 'pragmatic',
|
|
494
|
+
approvalPolicy: 'on-request',
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
```
|
|
499
|
+
|
|
390
500
|
## Zod Compatibility
|
|
391
501
|
|
|
392
502
|
- Peer supports `zod@^3 || ^4`
|