ocpipe 0.6.6 → 0.6.8
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 +4 -4
- package/package.json +5 -5
- package/src/agent.ts +1 -1
- package/src/codex.ts +194 -143
- package/src/index.ts +10 -0
- package/src/types.ts +94 -18
package/README.md
CHANGED
|
@@ -76,11 +76,11 @@ defaultModel: { backend: 'claude-code', modelID: 'sonnet' },
|
|
|
76
76
|
claudeCode: { permissionMode: 'acceptEdits' },
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
**Codex** - Uses `@openai/codex`. Install as a peer dependency.
|
|
79
|
+
**Codex** - Uses `@openai/codex-sdk`. Install as a peer dependency.
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
82
|
defaultModel: { backend: 'codex', modelID: 'gpt-5.4' },
|
|
83
|
-
codex: { sandbox: 'read-only',
|
|
83
|
+
codex: { sandbox: 'read-only', reasoningEffort: 'high' },
|
|
84
84
|
```
|
|
85
85
|
|
|
86
86
|
### Requirements
|
|
@@ -96,10 +96,10 @@ codex: { sandbox: 'read-only', ephemeral: true },
|
|
|
96
96
|
bun add @anthropic-ai/claude-agent-sdk
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
-
**For Codex backend:** Install the Codex
|
|
99
|
+
**For Codex backend:** Install the Codex SDK package as a peer dependency:
|
|
100
100
|
|
|
101
101
|
```bash
|
|
102
|
-
bun add @openai/codex
|
|
102
|
+
bun add @openai/codex-sdk
|
|
103
103
|
```
|
|
104
104
|
|
|
105
105
|
### Documentation
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ocpipe",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.8",
|
|
4
4
|
"description": "SDK for LLM pipelines with OpenCode, Codex, and Zod",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -32,20 +32,21 @@
|
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"zod": "4.4.3",
|
|
34
34
|
"@anthropic-ai/claude-agent-sdk": "0.2.126",
|
|
35
|
-
"@openai/codex": "0.
|
|
35
|
+
"@openai/codex-sdk": "0.130.0"
|
|
36
36
|
},
|
|
37
37
|
"peerDependenciesMeta": {
|
|
38
38
|
"@anthropic-ai/claude-agent-sdk": {
|
|
39
39
|
"optional": true
|
|
40
40
|
},
|
|
41
|
-
"@openai/codex": {
|
|
41
|
+
"@openai/codex-sdk": {
|
|
42
42
|
"optional": true
|
|
43
43
|
}
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@anthropic-ai/claude-agent-sdk": "^0.2.132",
|
|
47
|
-
"@openai/codex": "^0.128.0",
|
|
48
47
|
"@eslint/js": "^10.0.1",
|
|
48
|
+
"@openai/codex-sdk": "0.130.0",
|
|
49
|
+
"@typescript/native-preview": "^7.0.0-dev.20260506.1",
|
|
49
50
|
"bun-types": "^1.3.13",
|
|
50
51
|
"eslint": "^10.3.0",
|
|
51
52
|
"globals": "^17.6.0",
|
|
@@ -53,7 +54,6 @@
|
|
|
53
54
|
"prettier": "^3.8.3",
|
|
54
55
|
"typescript": "^6.0.3",
|
|
55
56
|
"typescript-eslint": "^8.59.2",
|
|
56
|
-
"@typescript/native-preview": "^7.0.0-dev.20260506.1",
|
|
57
57
|
"vitest": "^4.1.5"
|
|
58
58
|
},
|
|
59
59
|
"scripts": {
|
package/src/agent.ts
CHANGED
package/src/codex.ts
CHANGED
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ocpipe Codex
|
|
2
|
+
* ocpipe Codex SDK integration.
|
|
3
3
|
*
|
|
4
|
-
* Runs Codex
|
|
4
|
+
* Runs Codex through @openai/codex-sdk threads.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import {
|
|
8
|
+
Codex,
|
|
9
|
+
type CodexOptions as CodexSdkClientOptions,
|
|
10
|
+
type RunResult,
|
|
11
|
+
type ThreadOptions,
|
|
12
|
+
} from '@openai/codex-sdk'
|
|
13
|
+
import { PROJECT_ROOT } from './paths.js'
|
|
14
|
+
import type {
|
|
15
|
+
CodexOptions,
|
|
16
|
+
CodexRunSummary,
|
|
17
|
+
RunAgentOptions,
|
|
18
|
+
RunAgentResult,
|
|
19
|
+
} from './types.js'
|
|
12
20
|
|
|
13
21
|
class CodexLogFilter {
|
|
14
22
|
private buf = ''
|
|
@@ -79,157 +87,200 @@ export async function runCodexAgent(
|
|
|
79
87
|
signal,
|
|
80
88
|
} = options
|
|
81
89
|
|
|
82
|
-
if (sessionId) {
|
|
83
|
-
throw new Error('Codex backend does not support session resume yet')
|
|
84
|
-
}
|
|
85
90
|
if (signal?.aborted) {
|
|
86
91
|
throw new Error('Request aborted')
|
|
87
92
|
}
|
|
88
93
|
|
|
89
94
|
const cwd = workdir ?? PROJECT_ROOT
|
|
90
|
-
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
'exec',
|
|
97
|
-
'--color',
|
|
98
|
-
'never',
|
|
99
|
-
'--model',
|
|
100
|
-
model.modelID,
|
|
101
|
-
'--sandbox',
|
|
102
|
-
codex?.sandbox ?? 'read-only',
|
|
103
|
-
'--cd',
|
|
104
|
-
cwd,
|
|
105
|
-
'--output-last-message',
|
|
106
|
-
outputFile,
|
|
107
|
-
]
|
|
108
|
-
|
|
109
|
-
if (codex?.ephemeral ?? true) {
|
|
110
|
-
args.push('--ephemeral')
|
|
111
|
-
}
|
|
112
|
-
if (codex?.ignoreUserConfig) {
|
|
113
|
-
args.push('--ignore-user-config')
|
|
114
|
-
}
|
|
115
|
-
if (codex?.ignoreRules) {
|
|
116
|
-
args.push('--ignore-rules')
|
|
117
|
-
}
|
|
118
|
-
if (codex?.reasoningEffort) {
|
|
119
|
-
args.push('-c', `model_reasoning_effort="${codex.reasoningEffort}"`)
|
|
120
|
-
}
|
|
121
|
-
for (const dir of codex?.addDirs ?? []) {
|
|
122
|
-
args.push('--add-dir', dir)
|
|
123
|
-
}
|
|
124
|
-
for (const [key, value] of Object.entries(codex?.config ?? {})) {
|
|
125
|
-
args.push('-c', `${key}=${value}`)
|
|
126
|
-
}
|
|
127
|
-
args.push('-')
|
|
95
|
+
const client = new Codex(buildCodexClientOptions(codex))
|
|
96
|
+
const threadOptions = buildCodexThreadOptions(model.modelID, cwd, codex)
|
|
97
|
+
const thread =
|
|
98
|
+
sessionId && !codex?.ephemeral ?
|
|
99
|
+
client.resumeThread(sessionId, threadOptions)
|
|
100
|
+
: client.startThread(threadOptions)
|
|
128
101
|
|
|
129
102
|
const promptPreview = prompt.slice(0, 50).replace(/\n/g, ' ')
|
|
103
|
+
const sessionInfo =
|
|
104
|
+
sessionId && !codex?.ephemeral ? `[thread:${sessionId}]` : '[new thread]'
|
|
130
105
|
console.error(
|
|
131
|
-
`\n>>> Codex [${model.modelID}]
|
|
106
|
+
`\n>>> Codex SDK [${model.modelID}] ${sessionInfo}: ${promptPreview}...`,
|
|
132
107
|
)
|
|
133
108
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
109
|
+
const abort = new AbortController()
|
|
110
|
+
let timedOut = false
|
|
111
|
+
const abortHandler = () => abort.abort()
|
|
112
|
+
signal?.addEventListener('abort', abortHandler, { once: true })
|
|
113
|
+
const timeout =
|
|
114
|
+
timeoutSec > 0 ?
|
|
115
|
+
setTimeout(() => {
|
|
116
|
+
timedOut = true
|
|
117
|
+
abort.abort()
|
|
118
|
+
}, timeoutSec * 1000)
|
|
119
|
+
: null
|
|
144
120
|
|
|
145
|
-
|
|
146
|
-
|
|
121
|
+
try {
|
|
122
|
+
const result = await thread.run(prompt, { signal: abort.signal })
|
|
123
|
+
const response = result.finalResponse.trim()
|
|
124
|
+
if (!response) {
|
|
125
|
+
throw new Error('Codex returned an empty response')
|
|
147
126
|
}
|
|
148
127
|
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
128
|
+
const nextSessionId = codex?.ephemeral ? '' : (thread.id ?? '')
|
|
129
|
+
const sessionStr = nextSessionId || 'none'
|
|
130
|
+
const runSummary = buildCodexRunSummary(result)
|
|
131
|
+
console.error(
|
|
132
|
+
`<<< Codex SDK done [thread:${sessionStr}]\n${formatCodexRunSummary(runSummary)}`,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
text: response,
|
|
137
|
+
sessionId: nextSessionId,
|
|
138
|
+
runSummary,
|
|
139
|
+
}
|
|
140
|
+
} catch (err) {
|
|
141
|
+
if (timedOut) {
|
|
142
|
+
throw new Error(`Timeout after ${timeoutSec}s`, { cause: err })
|
|
159
143
|
}
|
|
160
|
-
signal?.
|
|
144
|
+
if (signal?.aborted) {
|
|
145
|
+
throw new Error('Request aborted', { cause: err })
|
|
146
|
+
}
|
|
147
|
+
throw err
|
|
148
|
+
} finally {
|
|
149
|
+
if (timeout) clearTimeout(timeout)
|
|
150
|
+
signal?.removeEventListener('abort', abortHandler)
|
|
151
|
+
}
|
|
152
|
+
}
|
|
161
153
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
proc.stderr.on('data', (data: Buffer) => {
|
|
169
|
-
const text = stderrFilter.write(data.toString())
|
|
170
|
-
stderrChunks.push(text)
|
|
171
|
-
if (text) {
|
|
172
|
-
process.stderr.write(text)
|
|
173
|
-
}
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
const timeout =
|
|
177
|
-
timeoutSec > 0 ?
|
|
178
|
-
setTimeout(() => {
|
|
179
|
-
proc.kill()
|
|
180
|
-
void cleanup()
|
|
181
|
-
reject(new Error(`Timeout after ${timeoutSec}s`))
|
|
182
|
-
}, timeoutSec * 1000)
|
|
183
|
-
: null
|
|
184
|
-
|
|
185
|
-
proc.stdin.end(prompt)
|
|
186
|
-
|
|
187
|
-
proc.on('close', async (code) => {
|
|
188
|
-
if (timeout) clearTimeout(timeout)
|
|
189
|
-
signal?.removeEventListener('abort', abortHandler)
|
|
190
|
-
if (aborted) return
|
|
191
|
-
|
|
192
|
-
const stdoutTail = stdoutFilter.flush()
|
|
193
|
-
if (stdoutTail) {
|
|
194
|
-
process.stderr.write(stdoutTail)
|
|
195
|
-
}
|
|
196
|
-
const stderrTail = stderrFilter.flush()
|
|
197
|
-
if (stderrTail) {
|
|
198
|
-
stderrChunks.push(stderrTail)
|
|
199
|
-
process.stderr.write(stderrTail)
|
|
200
|
-
}
|
|
201
|
-
const stderr = stderrChunks.join('').trim()
|
|
202
|
-
if (code !== 0) {
|
|
203
|
-
await cleanup()
|
|
204
|
-
const detail =
|
|
205
|
-
stderr ? `\n${stderr.split('\n').slice(-10).join('\n')}` : ''
|
|
206
|
-
reject(new Error(`Codex exited with code ${code}${detail}`))
|
|
207
|
-
return
|
|
208
|
-
}
|
|
154
|
+
/** buildCodexRunSummary projects a Codex turn into a parent-readable summary. */
|
|
155
|
+
export function buildCodexRunSummary(result: RunResult): CodexRunSummary {
|
|
156
|
+
const commands: CodexRunSummary['commands'] = []
|
|
157
|
+
const fileChanges: CodexRunSummary['fileChanges'] = []
|
|
158
|
+
let errorMessage = ''
|
|
159
|
+
let finalMessage = result.finalResponse.trim()
|
|
209
160
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
if (
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
sessionId: '',
|
|
161
|
+
for (const item of result.items) {
|
|
162
|
+
switch (item.type) {
|
|
163
|
+
case 'agent_message':
|
|
164
|
+
if (item.text) finalMessage = item.text
|
|
165
|
+
break
|
|
166
|
+
case 'command_execution':
|
|
167
|
+
commands.push({
|
|
168
|
+
command: item.command,
|
|
169
|
+
status: item.status,
|
|
170
|
+
exitCode: item.exit_code ?? null,
|
|
221
171
|
})
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
172
|
+
break
|
|
173
|
+
case 'file_change':
|
|
174
|
+
for (const change of item.changes) {
|
|
175
|
+
fileChanges.push({
|
|
176
|
+
path: change.path,
|
|
177
|
+
kind: change.kind,
|
|
178
|
+
status: item.status,
|
|
179
|
+
})
|
|
180
|
+
}
|
|
181
|
+
break
|
|
182
|
+
case 'error':
|
|
183
|
+
errorMessage = item.message
|
|
184
|
+
break
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const usage = result.usage
|
|
189
|
+
return {
|
|
190
|
+
status: errorMessage ? 'failed' : 'completed',
|
|
191
|
+
finalMessage: finalMessage.trim(),
|
|
192
|
+
errorMessage,
|
|
193
|
+
commands,
|
|
194
|
+
fileChanges,
|
|
195
|
+
tokens:
|
|
196
|
+
usage ?
|
|
197
|
+
{
|
|
198
|
+
input: usage.input_tokens,
|
|
199
|
+
cached: usage.cached_input_tokens,
|
|
200
|
+
output: usage.output_tokens,
|
|
201
|
+
reasoning: usage.reasoning_output_tokens,
|
|
202
|
+
}
|
|
203
|
+
: null,
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/** formatCodexRunSummary renders a Codex run summary as a clean text block. */
|
|
208
|
+
export function formatCodexRunSummary(summary: CodexRunSummary): string {
|
|
209
|
+
const lines: string[] = [`status: ${summary.status}`]
|
|
210
|
+
if (summary.errorMessage) {
|
|
211
|
+
lines.push(`error: ${summary.errorMessage}`)
|
|
212
|
+
}
|
|
213
|
+
if (summary.commands.length > 0) {
|
|
214
|
+
const failed = summary.commands.filter(isFailedCommand).length
|
|
215
|
+
lines.push(
|
|
216
|
+
`commands: ${summary.commands.length} completed, ${failed} failed`,
|
|
217
|
+
)
|
|
218
|
+
}
|
|
219
|
+
if (summary.fileChanges.length > 0) {
|
|
220
|
+
let add = 0
|
|
221
|
+
let update = 0
|
|
222
|
+
let del = 0
|
|
223
|
+
for (const change of summary.fileChanges) {
|
|
224
|
+
if (change.kind === 'add') add++
|
|
225
|
+
else if (change.kind === 'delete') del++
|
|
226
|
+
else update++
|
|
227
|
+
}
|
|
228
|
+
lines.push(`files: add=${add} update=${update} delete=${del}`)
|
|
229
|
+
}
|
|
230
|
+
if (summary.tokens) {
|
|
231
|
+
const t = summary.tokens
|
|
232
|
+
lines.push(
|
|
233
|
+
`tokens: input=${t.input} cached=${t.cached} output=${t.output} reasoning=${t.reasoning}`,
|
|
234
|
+
)
|
|
235
|
+
}
|
|
236
|
+
if (summary.finalMessage) {
|
|
237
|
+
lines.push(`final_message:\n${summary.finalMessage}`)
|
|
238
|
+
}
|
|
239
|
+
return lines.join('\n')
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function isFailedCommand(command: CodexRunSummary['commands'][number]): boolean {
|
|
243
|
+
return (
|
|
244
|
+
command.status === 'failed' ||
|
|
245
|
+
(command.exitCode !== null && command.exitCode !== 0)
|
|
246
|
+
)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function buildCodexClientOptions(
|
|
250
|
+
codex: CodexOptions | undefined,
|
|
251
|
+
): CodexSdkClientOptions {
|
|
252
|
+
return {
|
|
253
|
+
...(codex?.pathToCodexExecutable ?
|
|
254
|
+
{ codexPathOverride: codex.pathToCodexExecutable }
|
|
255
|
+
: {}),
|
|
256
|
+
...(codex?.baseUrl ? { baseUrl: codex.baseUrl } : {}),
|
|
257
|
+
...(codex?.apiKey ? { apiKey: codex.apiKey } : {}),
|
|
258
|
+
...(codex?.env ? { env: codex.env } : {}),
|
|
259
|
+
...(codex?.config ? { config: codex.config } : {}),
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
function buildCodexThreadOptions(
|
|
264
|
+
modelID: string,
|
|
265
|
+
cwd: string,
|
|
266
|
+
codex: CodexOptions | undefined,
|
|
267
|
+
): ThreadOptions {
|
|
268
|
+
return {
|
|
269
|
+
model: modelID,
|
|
270
|
+
workingDirectory: cwd,
|
|
271
|
+
skipGitRepoCheck: true,
|
|
272
|
+
sandboxMode: codex?.sandbox ?? 'read-only',
|
|
273
|
+
...(codex?.reasoningEffort ?
|
|
274
|
+
{ modelReasoningEffort: codex.reasoningEffort }
|
|
275
|
+
: {}),
|
|
276
|
+
...(codex?.addDirs ? { additionalDirectories: codex.addDirs } : {}),
|
|
277
|
+
...(codex?.approvalPolicy ? { approvalPolicy: codex.approvalPolicy } : {}),
|
|
278
|
+
...(codex?.networkAccessEnabled !== undefined ?
|
|
279
|
+
{ networkAccessEnabled: codex.networkAccessEnabled }
|
|
280
|
+
: {}),
|
|
281
|
+
...(codex?.webSearchMode ? { webSearchMode: codex.webSearchMode } : {}),
|
|
282
|
+
...(codex?.webSearchEnabled !== undefined ?
|
|
283
|
+
{ webSearchEnabled: codex.webSearchEnabled }
|
|
284
|
+
: {}),
|
|
285
|
+
}
|
|
235
286
|
}
|
package/src/index.ts
CHANGED
|
@@ -50,6 +50,7 @@ export { createSessionId, createBaseState, extendBaseState } from './state.js'
|
|
|
50
50
|
|
|
51
51
|
// Agent integration
|
|
52
52
|
export { runAgent, logStep } from './agent.js'
|
|
53
|
+
export { buildCodexRunSummary, formatCodexRunSummary } from './codex.js'
|
|
53
54
|
|
|
54
55
|
// Response parsing
|
|
55
56
|
export {
|
|
@@ -91,7 +92,12 @@ export type {
|
|
|
91
92
|
BackendType,
|
|
92
93
|
PermissionMode,
|
|
93
94
|
ClaudeCodeOptions,
|
|
95
|
+
CodexApprovalPolicy,
|
|
96
|
+
CodexConfigValue,
|
|
94
97
|
CodexOptions,
|
|
98
|
+
CodexReasoningEffort,
|
|
99
|
+
CodexSandboxMode,
|
|
100
|
+
CodexWebSearchMode,
|
|
95
101
|
ModelConfig,
|
|
96
102
|
ExecutionContext,
|
|
97
103
|
StepResult,
|
|
@@ -111,6 +117,10 @@ export type {
|
|
|
111
117
|
// Agent types
|
|
112
118
|
RunAgentOptions,
|
|
113
119
|
RunAgentResult,
|
|
120
|
+
CodexRunSummary,
|
|
121
|
+
CodexRunCommand,
|
|
122
|
+
CodexRunFileChange,
|
|
123
|
+
CodexRunTokens,
|
|
114
124
|
// Correction types
|
|
115
125
|
CorrectionMethod,
|
|
116
126
|
CorrectionConfig,
|
package/src/types.ts
CHANGED
|
@@ -11,6 +11,38 @@ import type { z } from 'zod/v4'
|
|
|
11
11
|
/** Backend type for running agents. */
|
|
12
12
|
export type BackendType = 'opencode' | 'claude-code' | 'codex'
|
|
13
13
|
|
|
14
|
+
/** Reasoning effort for Codex SDK threads. */
|
|
15
|
+
export type CodexReasoningEffort =
|
|
16
|
+
| 'minimal'
|
|
17
|
+
| 'low'
|
|
18
|
+
| 'medium'
|
|
19
|
+
| 'high'
|
|
20
|
+
| 'xhigh'
|
|
21
|
+
|
|
22
|
+
/** Codex sandbox mode. */
|
|
23
|
+
export type CodexSandboxMode =
|
|
24
|
+
| 'read-only'
|
|
25
|
+
| 'workspace-write'
|
|
26
|
+
| 'danger-full-access'
|
|
27
|
+
|
|
28
|
+
/** Codex approval policy. */
|
|
29
|
+
export type CodexApprovalPolicy =
|
|
30
|
+
| 'never'
|
|
31
|
+
| 'on-request'
|
|
32
|
+
| 'on-failure'
|
|
33
|
+
| 'untrusted'
|
|
34
|
+
|
|
35
|
+
/** Codex web search mode. */
|
|
36
|
+
export type CodexWebSearchMode = 'disabled' | 'cached' | 'live'
|
|
37
|
+
|
|
38
|
+
/** Codex SDK config override value. */
|
|
39
|
+
export type CodexConfigValue =
|
|
40
|
+
| string
|
|
41
|
+
| number
|
|
42
|
+
| boolean
|
|
43
|
+
| CodexConfigValue[]
|
|
44
|
+
| { [key: string]: CodexConfigValue }
|
|
45
|
+
|
|
14
46
|
/** Permission mode for Claude Code sessions. */
|
|
15
47
|
export type PermissionMode =
|
|
16
48
|
| 'default'
|
|
@@ -57,24 +89,34 @@ export interface ClaudeCodeOptions {
|
|
|
57
89
|
allowedTools?: string[]
|
|
58
90
|
}
|
|
59
91
|
|
|
60
|
-
/** Codex
|
|
92
|
+
/** Codex SDK specific session options. */
|
|
61
93
|
export interface CodexOptions {
|
|
62
|
-
/** Path
|
|
94
|
+
/** Path override for the Codex executable used by the SDK. */
|
|
63
95
|
pathToCodexExecutable?: string
|
|
64
|
-
/**
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
|
|
70
|
-
/**
|
|
96
|
+
/** Base URL passed to the Codex SDK. */
|
|
97
|
+
baseUrl?: string
|
|
98
|
+
/** API key passed to the Codex SDK. */
|
|
99
|
+
apiKey?: string
|
|
100
|
+
/** Environment variables passed to the Codex subprocess. */
|
|
101
|
+
env?: Record<string, string>
|
|
102
|
+
/** Sandbox mode for Codex (default: `read-only`). */
|
|
103
|
+
sandbox?: CodexSandboxMode
|
|
104
|
+
/** Extra config overrides passed through the Codex SDK. */
|
|
105
|
+
config?: { [key: string]: CodexConfigValue }
|
|
106
|
+
/** Reasoning effort passed to Codex. */
|
|
107
|
+
reasoningEffort?: CodexReasoningEffort
|
|
108
|
+
/** Start a new SDK thread instead of resuming the provided session ID. */
|
|
71
109
|
ephemeral?: boolean
|
|
72
|
-
/** Ignore user config for deterministic automation (default: false). */
|
|
73
|
-
ignoreUserConfig?: boolean
|
|
74
|
-
/** Ignore user and project execpolicy rules (default: false). */
|
|
75
|
-
ignoreRules?: boolean
|
|
76
110
|
/** Additional directories Codex may access alongside the working directory. */
|
|
77
111
|
addDirs?: string[]
|
|
112
|
+
/** Approval policy passed to Codex. */
|
|
113
|
+
approvalPolicy?: CodexApprovalPolicy
|
|
114
|
+
/** Enable network access in workspace-write sandboxes. */
|
|
115
|
+
networkAccessEnabled?: boolean
|
|
116
|
+
/** Web search mode passed to Codex. */
|
|
117
|
+
webSearchMode?: CodexWebSearchMode
|
|
118
|
+
/** Legacy boolean web search control passed to Codex. */
|
|
119
|
+
webSearchEnabled?: boolean
|
|
78
120
|
}
|
|
79
121
|
|
|
80
122
|
/** Model configuration for LLM backends. */
|
|
@@ -108,9 +150,9 @@ export interface ExecutionContext {
|
|
|
108
150
|
workdir?: string
|
|
109
151
|
/** Claude Code specific options. */
|
|
110
152
|
claudeCode?: ClaudeCodeOptions
|
|
111
|
-
/** Codex
|
|
153
|
+
/** Codex SDK specific options. */
|
|
112
154
|
codex?: CodexOptions
|
|
113
|
-
/** AbortSignal for cancelling
|
|
155
|
+
/** AbortSignal for cancelling in-flight backend requests. */
|
|
114
156
|
signal?: AbortSignal
|
|
115
157
|
}
|
|
116
158
|
|
|
@@ -328,7 +370,7 @@ export interface PipelineConfig {
|
|
|
328
370
|
workdir?: string
|
|
329
371
|
/** Claude Code specific options. */
|
|
330
372
|
claudeCode?: ClaudeCodeOptions
|
|
331
|
-
/** Codex
|
|
373
|
+
/** Codex SDK specific options. */
|
|
332
374
|
codex?: CodexOptions
|
|
333
375
|
}
|
|
334
376
|
|
|
@@ -364,9 +406,9 @@ export interface RunAgentOptions {
|
|
|
364
406
|
workdir?: string
|
|
365
407
|
/** Claude Code specific options. */
|
|
366
408
|
claudeCode?: ClaudeCodeOptions
|
|
367
|
-
/** Codex
|
|
409
|
+
/** Codex SDK specific options. */
|
|
368
410
|
codex?: CodexOptions
|
|
369
|
-
/** AbortSignal for cancelling the request.
|
|
411
|
+
/** AbortSignal for cancelling the request. */
|
|
370
412
|
signal?: AbortSignal
|
|
371
413
|
}
|
|
372
414
|
|
|
@@ -376,4 +418,38 @@ export interface RunAgentResult {
|
|
|
376
418
|
text: string
|
|
377
419
|
/** Session ID (for continuing the conversation). */
|
|
378
420
|
sessionId: string
|
|
421
|
+
/** Clean run summary, set for the Codex backend. */
|
|
422
|
+
runSummary?: CodexRunSummary
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** CodexRunCommand records one command the Codex agent executed. */
|
|
426
|
+
export interface CodexRunCommand {
|
|
427
|
+
command: string
|
|
428
|
+
status: string
|
|
429
|
+
exitCode: number | null
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/** CodexRunFileChange records one file the Codex agent changed. */
|
|
433
|
+
export interface CodexRunFileChange {
|
|
434
|
+
path: string
|
|
435
|
+
kind: 'add' | 'update' | 'delete'
|
|
436
|
+
status: string
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/** CodexRunTokens records token usage for a Codex turn. */
|
|
440
|
+
export interface CodexRunTokens {
|
|
441
|
+
input: number
|
|
442
|
+
cached: number
|
|
443
|
+
output: number
|
|
444
|
+
reasoning: number
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/** CodexRunSummary is the parent-readable projection of a Codex turn. */
|
|
448
|
+
export interface CodexRunSummary {
|
|
449
|
+
status: 'completed' | 'failed' | 'unknown'
|
|
450
|
+
finalMessage: string
|
|
451
|
+
errorMessage: string
|
|
452
|
+
commands: CodexRunCommand[]
|
|
453
|
+
fileChanges: CodexRunFileChange[]
|
|
454
|
+
tokens: CodexRunTokens | null
|
|
379
455
|
}
|