baro-ai 0.70.2 → 0.70.4
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/dist/cli.mjs +124 -3
- package/dist/cli.mjs.map +1 -1
- package/dist/runner.mjs +1 -1
- package/dist/runner.mjs.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.js +23 -0
package/dist/cli.mjs
CHANGED
|
@@ -47631,7 +47631,10 @@ var LocalStoryExecutor = class {
|
|
|
47631
47631
|
});
|
|
47632
47632
|
agent.join(env);
|
|
47633
47633
|
void agent.run(env);
|
|
47634
|
-
return {
|
|
47634
|
+
return {
|
|
47635
|
+
dispose: (e2) => agent.leave(e2),
|
|
47636
|
+
abort: () => agent.abort?.()
|
|
47637
|
+
};
|
|
47635
47638
|
}
|
|
47636
47639
|
};
|
|
47637
47640
|
|
|
@@ -47664,6 +47667,18 @@ var StoryFactory = class extends BaseObserver {
|
|
|
47664
47667
|
}
|
|
47665
47668
|
}
|
|
47666
47669
|
}
|
|
47670
|
+
/**
|
|
47671
|
+
* Abort a running story mid-flight (the Supervisor calls this on a detected
|
|
47672
|
+
* stall). The agent settles with a failed StoryResult, which the Surgeon
|
|
47673
|
+
* then reacts to (split/escalate). Returns false if the story isn't active
|
|
47674
|
+
* or its executor doesn't support abort.
|
|
47675
|
+
*/
|
|
47676
|
+
abort(storyId) {
|
|
47677
|
+
const exec3 = this.active.get(storyId);
|
|
47678
|
+
if (!exec3?.abort) return false;
|
|
47679
|
+
exec3.abort();
|
|
47680
|
+
return true;
|
|
47681
|
+
}
|
|
47667
47682
|
async spawn(req) {
|
|
47668
47683
|
if (!this.envRef) return;
|
|
47669
47684
|
if (this.active.has(req.storyId) || this.spawning.has(req.storyId)) return;
|
|
@@ -48281,6 +48296,87 @@ ${userPrompt}`;
|
|
|
48281
48296
|
}
|
|
48282
48297
|
};
|
|
48283
48298
|
|
|
48299
|
+
// ../baro-orchestrator/src/participants/supervisor.ts
|
|
48300
|
+
var WRITE_TOOLS2 = /* @__PURE__ */ new Set([
|
|
48301
|
+
"write_file",
|
|
48302
|
+
"edit_file",
|
|
48303
|
+
"edit",
|
|
48304
|
+
"create_file",
|
|
48305
|
+
"apply_patch",
|
|
48306
|
+
"str_replace",
|
|
48307
|
+
"str_replace_editor",
|
|
48308
|
+
"str_replace_based_edit_tool",
|
|
48309
|
+
"multi_edit",
|
|
48310
|
+
"write",
|
|
48311
|
+
"patch"
|
|
48312
|
+
]);
|
|
48313
|
+
var Supervisor = class extends BaseObserver {
|
|
48314
|
+
opts;
|
|
48315
|
+
stories = /* @__PURE__ */ new Map();
|
|
48316
|
+
interventions = 0;
|
|
48317
|
+
constructor(opts) {
|
|
48318
|
+
super();
|
|
48319
|
+
this.opts = {
|
|
48320
|
+
onStall: opts.onStall,
|
|
48321
|
+
noProgressToolCalls: opts.noProgressToolCalls ?? 50,
|
|
48322
|
+
repeatThreshold: opts.repeatThreshold ?? 6,
|
|
48323
|
+
softCapMs: opts.softCapMs ?? 12 * 6e4,
|
|
48324
|
+
maxInterventions: opts.maxInterventions ?? 25,
|
|
48325
|
+
now: opts.now ?? (() => Date.now())
|
|
48326
|
+
};
|
|
48327
|
+
}
|
|
48328
|
+
async onExternalFunctionCall(source, item) {
|
|
48329
|
+
const id = source.agentId;
|
|
48330
|
+
if (typeof id !== "string") return;
|
|
48331
|
+
const st = this.ensure(id);
|
|
48332
|
+
if (st.intervened) return;
|
|
48333
|
+
st.toolCalls += 1;
|
|
48334
|
+
if (WRITE_TOOLS2.has(item.name)) {
|
|
48335
|
+
st.fileChanges += 1;
|
|
48336
|
+
st.sinceLastChange = 0;
|
|
48337
|
+
} else {
|
|
48338
|
+
st.sinceLastChange += 1;
|
|
48339
|
+
}
|
|
48340
|
+
const sig = `${item.name}:${String(item.args ?? "").slice(0, 160)}`;
|
|
48341
|
+
const repeats = (st.sigCounts.get(sig) ?? 0) + 1;
|
|
48342
|
+
st.sigCounts.set(sig, repeats);
|
|
48343
|
+
if (this.interventions >= this.opts.maxInterventions) return;
|
|
48344
|
+
const reason = this.stallReason(st, repeats);
|
|
48345
|
+
if (!reason) return;
|
|
48346
|
+
st.intervened = true;
|
|
48347
|
+
this.interventions += 1;
|
|
48348
|
+
this.opts.onStall(id, `supervisor: ${reason}`);
|
|
48349
|
+
}
|
|
48350
|
+
stallReason(st, repeats) {
|
|
48351
|
+
if (st.sinceLastChange >= this.opts.noProgressToolCalls) {
|
|
48352
|
+
return `${st.sinceLastChange} tool calls with no file change \u2014 exploring, not converging`;
|
|
48353
|
+
}
|
|
48354
|
+
if (repeats >= this.opts.repeatThreshold) {
|
|
48355
|
+
return `same tool call repeated ${repeats}\xD7 \u2014 stuck in a loop`;
|
|
48356
|
+
}
|
|
48357
|
+
const elapsed = this.opts.now() - st.startedAt;
|
|
48358
|
+
if (elapsed >= this.opts.softCapMs && st.fileChanges === 0) {
|
|
48359
|
+
return `${Math.round(elapsed / 6e4)} min elapsed with zero file changes`;
|
|
48360
|
+
}
|
|
48361
|
+
return null;
|
|
48362
|
+
}
|
|
48363
|
+
ensure(id) {
|
|
48364
|
+
let st = this.stories.get(id);
|
|
48365
|
+
if (!st) {
|
|
48366
|
+
st = {
|
|
48367
|
+
startedAt: this.opts.now(),
|
|
48368
|
+
toolCalls: 0,
|
|
48369
|
+
fileChanges: 0,
|
|
48370
|
+
sinceLastChange: 0,
|
|
48371
|
+
sigCounts: /* @__PURE__ */ new Map(),
|
|
48372
|
+
intervened: false
|
|
48373
|
+
};
|
|
48374
|
+
this.stories.set(id, st);
|
|
48375
|
+
}
|
|
48376
|
+
return st;
|
|
48377
|
+
}
|
|
48378
|
+
};
|
|
48379
|
+
|
|
48284
48380
|
// ../baro-orchestrator/src/orchestrate.ts
|
|
48285
48381
|
function storyTimeoutSecs(configured, effort) {
|
|
48286
48382
|
if (typeof configured === "number" && configured > 0) return configured;
|
|
@@ -48623,6 +48719,17 @@ async function orchestrate(config) {
|
|
|
48623
48719
|
});
|
|
48624
48720
|
storyFactory.setEnvironment(env);
|
|
48625
48721
|
storyFactory.join(env);
|
|
48722
|
+
if (config.withSupervisor) {
|
|
48723
|
+
const supervisor = new Supervisor({
|
|
48724
|
+
onStall: (storyId, reason) => {
|
|
48725
|
+
const aborted = storyFactory.abort(storyId);
|
|
48726
|
+
if (aborted && emitTui) {
|
|
48727
|
+
emit({ type: "story_log", id: storyId, line: `\u26A0 ${reason} \u2014 aborting so it can be split/escalated` });
|
|
48728
|
+
}
|
|
48729
|
+
}
|
|
48730
|
+
});
|
|
48731
|
+
supervisor.join(env);
|
|
48732
|
+
}
|
|
48626
48733
|
if (emitTui) {
|
|
48627
48734
|
const prd = loadPrd(config.prdPath);
|
|
48628
48735
|
emit({
|
|
@@ -48728,8 +48835,12 @@ function parseArgs2(argv) {
|
|
|
48728
48835
|
noLibrarian: false,
|
|
48729
48836
|
noMemory: false,
|
|
48730
48837
|
noSentry: false,
|
|
48731
|
-
|
|
48732
|
-
|
|
48838
|
+
// Self-healing on by default: the Supervisor catches a stuck story early
|
|
48839
|
+
// and the Surgeon splits/escalates it, instead of failing the whole run.
|
|
48840
|
+
// Disable with --no-surgeon / --no-supervisor.
|
|
48841
|
+
withSurgeon: true,
|
|
48842
|
+
surgeonUseLlm: true,
|
|
48843
|
+
withSupervisor: true,
|
|
48733
48844
|
endpointSpecs: [],
|
|
48734
48845
|
llm: "claude",
|
|
48735
48846
|
help: false
|
|
@@ -48789,6 +48900,15 @@ function parseArgs2(argv) {
|
|
|
48789
48900
|
case "--surgeon-use-llm":
|
|
48790
48901
|
args.surgeonUseLlm = true;
|
|
48791
48902
|
break;
|
|
48903
|
+
case "--no-surgeon":
|
|
48904
|
+
args.withSurgeon = false;
|
|
48905
|
+
break;
|
|
48906
|
+
case "--no-supervisor":
|
|
48907
|
+
args.withSupervisor = false;
|
|
48908
|
+
break;
|
|
48909
|
+
case "--with-supervisor":
|
|
48910
|
+
args.withSupervisor = true;
|
|
48911
|
+
break;
|
|
48792
48912
|
case "--surgeon-model":
|
|
48793
48913
|
args.surgeonModel = required(argv, ++i2, "--surgeon-model");
|
|
48794
48914
|
break;
|
|
@@ -48975,6 +49095,7 @@ async function main() {
|
|
|
48975
49095
|
withSentry: args.noSentry ? false : void 0,
|
|
48976
49096
|
withSurgeon: args.withSurgeon,
|
|
48977
49097
|
surgeonUseLlm: args.surgeonUseLlm,
|
|
49098
|
+
withSupervisor: args.withSupervisor,
|
|
48978
49099
|
surgeonModel: args.surgeonModel,
|
|
48979
49100
|
intraLevelDelaySecs: args.intraLevelDelaySecs,
|
|
48980
49101
|
llm: args.llm,
|