ocpipe 0.6.4 → 0.6.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ocpipe",
3
- "version": "0.6.4",
3
+ "version": "0.6.6",
4
4
  "description": "SDK for LLM pipelines with OpenCode, Codex, and Zod",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
package/src/codex.ts CHANGED
@@ -10,6 +10,61 @@ import { join } from 'path'
10
10
  import { PROJECT_ROOT, TMP_DIR } from './paths.js'
11
11
  import type { RunAgentOptions, RunAgentResult } from './types.js'
12
12
 
13
+ class CodexLogFilter {
14
+ private buf = ''
15
+ private suppressHtml = false
16
+
17
+ write(text: string): string {
18
+ this.buf += text
19
+ let out = ''
20
+ for (;;) {
21
+ const idx = this.buf.indexOf('\n')
22
+ if (idx < 0) {
23
+ return out
24
+ }
25
+ const line = this.buf.slice(0, idx + 1)
26
+ this.buf = this.buf.slice(idx + 1)
27
+ out += this.filterLine(line)
28
+ }
29
+ }
30
+
31
+ flush(): string {
32
+ const line = this.buf
33
+ this.buf = ''
34
+ return this.filterLine(line)
35
+ }
36
+
37
+ private filterLine(line: string): string {
38
+ if (this.suppressHtml) {
39
+ if (line.includes('</html>')) {
40
+ this.suppressHtml = false
41
+ }
42
+ return ''
43
+ }
44
+ if (suppressCodexLogLine(line)) {
45
+ return ''
46
+ }
47
+ if (suppressCodexHtmlLine(line)) {
48
+ this.suppressHtml = !line.includes('</html>')
49
+ return ''
50
+ }
51
+ return line
52
+ }
53
+ }
54
+
55
+ export function filterCodexLogText(text: string): string {
56
+ const filter = new CodexLogFilter()
57
+ return filter.write(text) + filter.flush()
58
+ }
59
+
60
+ function suppressCodexLogLine(line: string): boolean {
61
+ return /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s+WARN\s+codex_/.test(line)
62
+ }
63
+
64
+ function suppressCodexHtmlLine(line: string): boolean {
65
+ return /^\s*(<!doctype html>|<html\b|<head\b)/i.test(line)
66
+ }
67
+
13
68
  /** runCodexAgent executes a Codex agent with a prompt. */
14
69
  export async function runCodexAgent(
15
70
  options: RunAgentOptions,
@@ -60,6 +115,9 @@ export async function runCodexAgent(
60
115
  if (codex?.ignoreRules) {
61
116
  args.push('--ignore-rules')
62
117
  }
118
+ if (codex?.reasoningEffort) {
119
+ args.push('-c', `model_reasoning_effort="${codex.reasoningEffort}"`)
120
+ }
63
121
  for (const dir of codex?.addDirs ?? []) {
64
122
  args.push('--add-dir', dir)
65
123
  }
@@ -80,6 +138,8 @@ export async function runCodexAgent(
80
138
  })
81
139
 
82
140
  const stderrChunks: string[] = []
141
+ const stdoutFilter = new CodexLogFilter()
142
+ const stderrFilter = new CodexLogFilter()
83
143
  let aborted = false
84
144
 
85
145
  const cleanup = async () => {
@@ -100,12 +160,17 @@ export async function runCodexAgent(
100
160
  signal?.addEventListener('abort', abortHandler, { once: true })
101
161
 
102
162
  proc.stdout.on('data', (data: Buffer) => {
103
- process.stderr.write(data.toString())
163
+ const text = stdoutFilter.write(data.toString())
164
+ if (text) {
165
+ process.stderr.write(text)
166
+ }
104
167
  })
105
168
  proc.stderr.on('data', (data: Buffer) => {
106
- const text = data.toString()
169
+ const text = stderrFilter.write(data.toString())
107
170
  stderrChunks.push(text)
108
- process.stderr.write(text)
171
+ if (text) {
172
+ process.stderr.write(text)
173
+ }
109
174
  })
110
175
 
111
176
  const timeout =
@@ -124,10 +189,20 @@ export async function runCodexAgent(
124
189
  signal?.removeEventListener('abort', abortHandler)
125
190
  if (aborted) return
126
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
+ }
127
201
  const stderr = stderrChunks.join('').trim()
128
202
  if (code !== 0) {
129
203
  await cleanup()
130
- const detail = stderr ? `\n${stderr.split('\n').slice(-10).join('\n')}` : ''
204
+ const detail =
205
+ stderr ? `\n${stderr.split('\n').slice(-10).join('\n')}` : ''
131
206
  reject(new Error(`Codex exited with code ${code}${detail}`))
132
207
  return
133
208
  }
package/src/predict.ts CHANGED
@@ -77,6 +77,7 @@ export class Predict<S extends AnySignature> {
77
77
  timeoutSec: ctx.timeoutSec,
78
78
  workdir: ctx.workdir,
79
79
  claudeCode: ctx.claudeCode,
80
+ codex: ctx.codex,
80
81
  signal: ctx.signal,
81
82
  })
82
83
 
@@ -207,6 +208,7 @@ export class Predict<S extends AnySignature> {
207
208
  timeoutSec: ctx.timeoutSec,
208
209
  workdir: ctx.workdir,
209
210
  claudeCode: ctx.claudeCode,
211
+ codex: ctx.codex,
210
212
  signal: ctx.signal,
211
213
  })
212
214
 
@@ -284,6 +286,7 @@ export class Predict<S extends AnySignature> {
284
286
  timeoutSec: ctx.timeoutSec,
285
287
  workdir: ctx.workdir,
286
288
  claudeCode: ctx.claudeCode,
289
+ codex: ctx.codex,
287
290
  signal: ctx.signal,
288
291
  })
289
292
 
package/src/types.ts CHANGED
@@ -65,6 +65,8 @@ export interface CodexOptions {
65
65
  sandbox?: 'read-only' | 'workspace-write' | 'danger-full-access'
66
66
  /** Extra config overrides passed as repeated `-c key=value` flags. */
67
67
  config?: Record<string, string>
68
+ /** Reasoning effort passed to Codex (for example: `low`, `medium`, `high`, `xhigh`). */
69
+ reasoningEffort?: string
68
70
  /** Run without persisting Codex session files (default: true). */
69
71
  ephemeral?: boolean
70
72
  /** Ignore user config for deterministic automation (default: false). */