@nbardy/oompa 0.4.4 → 0.4.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.
|
@@ -141,8 +141,8 @@
|
|
|
141
141
|
[harness model]
|
|
142
142
|
(try
|
|
143
143
|
(let [cmd (case harness
|
|
144
|
-
:claude ["claude" "--model" model "-p" "say ok" "--max-turns" "1"]
|
|
145
|
-
:codex ["codex" "exec" "--dangerously-bypass-approvals-and-sandbox" "--skip-git-repo-check" "--model" model "--" "say ok"])
|
|
144
|
+
:claude ["claude" "--model" model "-p" "[oompa:probe] say ok" "--max-turns" "1"]
|
|
145
|
+
:codex ["codex" "exec" "--dangerously-bypass-approvals-and-sandbox" "--skip-git-repo-check" "--model" model "--" "[oompa:probe] say ok"])
|
|
146
146
|
null-in (io/input-stream (io/file "/dev/null"))
|
|
147
147
|
proc (process/process cmd {:out :string :err :string :in null-in})
|
|
148
148
|
result (deref proc 30000 :timeout)]
|
|
@@ -97,6 +97,26 @@
|
|
|
97
97
|
"Root of the oompa package — set by bin/oompa.js, falls back to cwd."
|
|
98
98
|
(or (System/getenv "OOMPA_PACKAGE_ROOT") "."))
|
|
99
99
|
|
|
100
|
+
;; Resolve absolute paths for CLI binaries at first use.
|
|
101
|
+
;; ProcessBuilder with :dir set can fail to find bare command names on some
|
|
102
|
+
;; platforms (macOS + babashka), so we resolve once via `which` and cache.
|
|
103
|
+
(def ^:private binary-paths* (atom {}))
|
|
104
|
+
|
|
105
|
+
(defn- resolve-binary!
|
|
106
|
+
"Resolve the absolute path of a CLI binary. Caches result.
|
|
107
|
+
Throws if binary not found on PATH."
|
|
108
|
+
[name]
|
|
109
|
+
(or (get @binary-paths* name)
|
|
110
|
+
(let [result (try
|
|
111
|
+
(process/sh ["which" name] {:out :string :err :string})
|
|
112
|
+
(catch Exception _ {:exit -1 :out "" :err ""}))
|
|
113
|
+
path (when (zero? (:exit result))
|
|
114
|
+
(str/trim (:out result)))]
|
|
115
|
+
(if path
|
|
116
|
+
(do (swap! binary-paths* assoc name path)
|
|
117
|
+
path)
|
|
118
|
+
(throw (ex-info (str "Binary not found on PATH: " name) {:binary name}))))))
|
|
119
|
+
|
|
100
120
|
(defn- load-prompt
|
|
101
121
|
"Load a prompt file. Tries path as-is first, then from package root."
|
|
102
122
|
[path]
|
|
@@ -172,14 +192,14 @@
|
|
|
172
192
|
;; Build command — both harnesses run with cwd=worktree, no sandbox
|
|
173
193
|
;; so agents can `..` to reach project root for task management
|
|
174
194
|
cmd (case harness
|
|
175
|
-
:codex (cond-> ["codex" "exec"
|
|
195
|
+
:codex (cond-> [(resolve-binary! "codex") "exec"
|
|
176
196
|
"--dangerously-bypass-approvals-and-sandbox"
|
|
177
197
|
"--skip-git-repo-check"
|
|
178
198
|
"-C" abs-worktree]
|
|
179
199
|
model (into ["--model" model])
|
|
180
200
|
reasoning (into ["-c" (str "model_reasoning_effort=\"" reasoning "\"")])
|
|
181
201
|
true (conj "--" full-prompt))
|
|
182
|
-
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"
|
|
202
|
+
:claude (cond-> [(resolve-binary! "claude") "-p" "--dangerously-skip-permissions"
|
|
183
203
|
"--session-id" session-id]
|
|
184
204
|
model (into ["--model" model])))
|
|
185
205
|
|
|
@@ -227,13 +247,13 @@
|
|
|
227
247
|
|
|
228
248
|
;; Build command — cwd=worktree, no sandbox
|
|
229
249
|
cmd (case review-harness
|
|
230
|
-
:codex (cond-> ["codex" "exec"
|
|
250
|
+
:codex (cond-> [(resolve-binary! "codex") "exec"
|
|
231
251
|
"--dangerously-bypass-approvals-and-sandbox"
|
|
232
252
|
"--skip-git-repo-check"
|
|
233
253
|
"-C" abs-wt]
|
|
234
254
|
review-model (into ["--model" review-model])
|
|
235
255
|
true (conj "--" review-prompt))
|
|
236
|
-
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"]
|
|
256
|
+
:claude (cond-> [(resolve-binary! "claude") "-p" "--dangerously-skip-permissions"]
|
|
237
257
|
review-model (into ["--model" review-model])))
|
|
238
258
|
|
|
239
259
|
;; Run reviewer — cwd=worktree
|
|
@@ -265,13 +285,13 @@
|
|
|
265
285
|
abs-wt (.getAbsolutePath (io/file worktree-path))
|
|
266
286
|
|
|
267
287
|
cmd (case harness
|
|
268
|
-
:codex (cond-> ["codex" "exec"
|
|
288
|
+
:codex (cond-> [(resolve-binary! "codex") "exec"
|
|
269
289
|
"--dangerously-bypass-approvals-and-sandbox"
|
|
270
290
|
"--skip-git-repo-check"
|
|
271
291
|
"-C" abs-wt]
|
|
272
292
|
model (into ["--model" model])
|
|
273
293
|
true (conj "--" fix-prompt))
|
|
274
|
-
:claude (cond-> ["claude" "-p" "--dangerously-skip-permissions"]
|
|
294
|
+
:claude (cond-> [(resolve-binary! "claude") "-p" "--dangerously-skip-permissions"]
|
|
275
295
|
model (into ["--model" model])))
|
|
276
296
|
|
|
277
297
|
result (try
|
|
@@ -356,8 +376,16 @@
|
|
|
356
376
|
wt-path (str project-root "/" wt-dir)]
|
|
357
377
|
|
|
358
378
|
(try
|
|
359
|
-
;;
|
|
360
|
-
(process/sh ["git" "worktree" "
|
|
379
|
+
;; Clean stale worktree/branch from previous failed runs before creating
|
|
380
|
+
(process/sh ["git" "worktree" "remove" wt-dir "--force"] {:dir project-root})
|
|
381
|
+
(process/sh ["git" "branch" "-D" wt-branch] {:dir project-root})
|
|
382
|
+
|
|
383
|
+
;; Setup worktree (in project root)
|
|
384
|
+
(let [wt-result (process/sh ["git" "worktree" "add" wt-dir "-b" wt-branch]
|
|
385
|
+
{:dir project-root :out :string :err :string})]
|
|
386
|
+
(when-not (zero? (:exit wt-result))
|
|
387
|
+
(throw (ex-info (str "Failed to create worktree: " (:err wt-result))
|
|
388
|
+
{:dir wt-dir :branch wt-branch}))))
|
|
361
389
|
|
|
362
390
|
;; Build context
|
|
363
391
|
(let [context (build-context)
|
|
@@ -391,8 +419,9 @@
|
|
|
391
419
|
{:status :continue})))))
|
|
392
420
|
|
|
393
421
|
(finally
|
|
394
|
-
;; Cleanup worktree (in project root)
|
|
395
|
-
(process/sh ["git" "worktree" "remove" wt-dir "--force"] {:dir project-root})
|
|
422
|
+
;; Cleanup worktree and branch (in project root)
|
|
423
|
+
(process/sh ["git" "worktree" "remove" wt-dir "--force"] {:dir project-root})
|
|
424
|
+
(process/sh ["git" "branch" "-D" wt-branch] {:dir project-root})))))
|
|
396
425
|
|
|
397
426
|
;; =============================================================================
|
|
398
427
|
;; Worker Loop
|
|
@@ -400,6 +429,7 @@
|
|
|
400
429
|
|
|
401
430
|
(def ^:private max-wait-for-tasks 60)
|
|
402
431
|
(def ^:private wait-poll-interval 5)
|
|
432
|
+
(def ^:private max-consecutive-errors 3)
|
|
403
433
|
|
|
404
434
|
(defn- wait-for-tasks!
|
|
405
435
|
"Wait up to 60s for pending/current tasks to appear. Used for backpressure
|
|
@@ -436,7 +466,8 @@
|
|
|
436
466
|
(wait-for-tasks! id))
|
|
437
467
|
|
|
438
468
|
(loop [iter 1
|
|
439
|
-
completed 0
|
|
469
|
+
completed 0
|
|
470
|
+
consec-errors 0]
|
|
440
471
|
(if (> iter iterations)
|
|
441
472
|
(do
|
|
442
473
|
(println (format "[%s] Completed %d iterations" id completed))
|
|
@@ -450,12 +481,18 @@
|
|
|
450
481
|
(assoc worker :completed iter :status :done))
|
|
451
482
|
|
|
452
483
|
:error
|
|
453
|
-
(
|
|
454
|
-
(
|
|
455
|
-
|
|
484
|
+
(let [errors (inc consec-errors)]
|
|
485
|
+
(if (>= errors max-consecutive-errors)
|
|
486
|
+
(do
|
|
487
|
+
(println (format "[%s] %d consecutive errors, stopping worker" id errors))
|
|
488
|
+
(assoc worker :completed completed :status :error))
|
|
489
|
+
(do
|
|
490
|
+
(println (format "[%s] Error at iteration %d/%d (%d/%d), continuing..."
|
|
491
|
+
id iter iterations errors max-consecutive-errors))
|
|
492
|
+
(recur (inc iter) completed errors))))
|
|
456
493
|
|
|
457
494
|
:continue
|
|
458
|
-
(recur (inc iter) (inc completed))))))))
|
|
495
|
+
(recur (inc iter) (inc completed) 0))))))))
|
|
459
496
|
|
|
460
497
|
;; =============================================================================
|
|
461
498
|
;; Multi-Worker Execution
|
package/bin/test-models
CHANGED
|
@@ -37,9 +37,9 @@ if [ -z "$MODELS" ]; then
|
|
|
37
37
|
exit 1
|
|
38
38
|
fi
|
|
39
39
|
|
|
40
|
-
# Create results directory
|
|
40
|
+
# Create results directory in /tmp so it doesn't litter the project
|
|
41
41
|
RUN_ID=$(python3 -c "import uuid; print(str(uuid.uuid4())[:8])")
|
|
42
|
-
RESULTS_DIR="
|
|
42
|
+
RESULTS_DIR="/tmp/oompa_tst_${RUN_ID}"
|
|
43
43
|
mkdir -p "$RESULTS_DIR"
|
|
44
44
|
|
|
45
45
|
MODEL_COUNT=$(echo "$MODELS" | wc -l | tr -d ' ')
|