baro-ai 0.70.3 → 0.70.5

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 CHANGED
@@ -47631,7 +47631,10 @@ var LocalStoryExecutor = class {
47631
47631
  });
47632
47632
  agent.join(env);
47633
47633
  void agent.run(env);
47634
- return { dispose: (e2) => agent.leave(e2) };
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;
@@ -47777,7 +47792,7 @@ var Surgeon = class extends BaseObserver {
47777
47792
  this.opts = {
47778
47793
  useLlm: opts.useLlm ?? true,
47779
47794
  model: opts.model ?? "opus",
47780
- maxReplans: opts.maxReplans ?? 10,
47795
+ maxReplans: opts.maxReplans ?? Infinity,
47781
47796
  claudeBin: opts.claudeBin ?? "claude",
47782
47797
  timeoutMs: opts.timeoutMs ?? 9e4,
47783
47798
  snapshot: opts.snapshot,
@@ -47938,7 +47953,7 @@ var SurgeonCodex = class extends BaseObserver {
47938
47953
  this.opts = {
47939
47954
  useLlm: opts.useLlm ?? true,
47940
47955
  model: opts.model,
47941
- maxReplans: opts.maxReplans ?? 10,
47956
+ maxReplans: opts.maxReplans ?? Infinity,
47942
47957
  codexBin: opts.codexBin ?? "codex",
47943
47958
  timeoutMs: opts.timeoutMs ?? 3e5,
47944
47959
  snapshot: opts.snapshot,
@@ -48036,7 +48051,7 @@ var SurgeonOpenAI = class extends BaseObserver {
48036
48051
  constructor(opts) {
48037
48052
  super();
48038
48053
  this.opts = {
48039
- maxReplans: opts.maxReplans ?? 10,
48054
+ maxReplans: opts.maxReplans ?? Infinity,
48040
48055
  model: opts.model ?? "gpt-5.5",
48041
48056
  snapshot: opts.snapshot,
48042
48057
  resolveRoute: opts.resolveRoute
@@ -48125,7 +48140,7 @@ var SurgeonOpenCode = class extends BaseObserver {
48125
48140
  this.opts = {
48126
48141
  useLlm: opts.useLlm ?? true,
48127
48142
  model: opts.model,
48128
- maxReplans: opts.maxReplans ?? 10,
48143
+ maxReplans: opts.maxReplans ?? Infinity,
48129
48144
  opencodeBin: opts.opencodeBin ?? "opencode",
48130
48145
  timeoutMs: opts.timeoutMs ?? 3e5,
48131
48146
  snapshot: opts.snapshot,
@@ -48205,7 +48220,7 @@ var SurgeonPi = class extends BaseObserver {
48205
48220
  useLlm: opts.useLlm ?? true,
48206
48221
  provider: opts.provider,
48207
48222
  model: opts.model,
48208
- maxReplans: opts.maxReplans ?? 10,
48223
+ maxReplans: opts.maxReplans ?? Infinity,
48209
48224
  piBin: opts.piBin ?? "pi",
48210
48225
  timeoutMs: opts.timeoutMs ?? 3e5,
48211
48226
  snapshot: opts.snapshot,
@@ -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
- withSurgeon: false,
48732
- surgeonUseLlm: false,
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,