oh-pi 0.1.60 → 0.1.62

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": "oh-pi",
3
- "version": "0.1.60",
3
+ "version": "0.1.62",
4
4
  "description": "One-click setup for pi-coding-agent. Like oh-my-zsh for pi.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -169,16 +169,11 @@ async function runAntWave(opts: WaveOptions): Promise<"ok" | "budget"> {
169
169
  const retriedTasks = new Set<string>(); // 防止重复重试
170
170
 
171
171
  const runOne = async (): Promise<"done" | "empty" | "rate_limited" | "budget"> => {
172
- // Budget 刹车:剩余预算不够一只蚂蚁的预估成本就不出发
172
+ // Budget 刹车:预算用完就不出发(drone 免费,不检查)
173
173
  const state = nest.getState();
174
174
  if (state.maxCost != null && caste !== "drone") {
175
175
  const spent = state.ants.reduce((s, a) => s + a.usage.cost, 0);
176
- const remaining = state.maxCost - spent;
177
- const doneAnts = state.ants.filter(a => a.status === "done" && a.usage.cost > 0);
178
- const avgCost = doneAnts.length > 0
179
- ? doneAnts.reduce((s, a) => s + a.usage.cost, 0) / doneAnts.length
180
- : 0.05;
181
- if (remaining < avgCost * 1.5) return "budget";
176
+ if (spent >= state.maxCost) return "budget";
182
177
  }
183
178
 
184
179
  const task = nest.nextPendingTask(caste);
@@ -468,6 +463,37 @@ export async function runColony(opts: QueenOptions): Promise<ColonyState> {
468
463
  }
469
464
  }
470
465
 
466
+ // ═══ 持续探索:Worker 完成后检查是否有新发现,有则再派 Scout ═══
467
+ const discoveries = nest.getAllPheromones().filter(p => p.type === "discovery");
468
+ const allDone = nest.getAllTasks().filter(t => t.status === "done");
469
+ if (discoveries.length > allDone.length && nest.getState().maxCost != null) {
470
+ const spent = nest.getState().ants.reduce((s, a) => s + a.usage.cost, 0);
471
+ if (spent < (nest.getState().maxCost ?? Infinity)) {
472
+ callbacks.onPhase?.("scouting", "Re-exploring based on new discoveries...");
473
+ emitSignal("scouting", "Re-exploring...");
474
+ await runAntWave({ ...waveBase, caste: "scout" });
475
+
476
+ const newTasks = nest.getAllTasks().filter(t =>
477
+ (t.caste === "worker" || t.caste === "drone") && t.status === "pending"
478
+ );
479
+ if (newTasks.length > 0) {
480
+ const drones = newTasks.filter(t => t.caste === "drone");
481
+ if (drones.length > 0) await runAntWave({ ...waveBase, caste: "drone" });
482
+
483
+ callbacks.onPhase?.("working", `${newTasks.length} new tasks from re-exploration`);
484
+ emitSignal("working", `${newTasks.length} new tasks`);
485
+ const result = await runAntWave({ ...waveBase, caste: "worker" });
486
+ if (result === "budget") {
487
+ nest.updateState({ status: "budget_exceeded", finishedAt: Date.now() });
488
+ emitSignal("budget_exceeded", "Budget exhausted");
489
+ const budgetState = nest.getState();
490
+ callbacks.onComplete?.(budgetState);
491
+ return budgetState;
492
+ }
493
+ }
494
+ }
495
+ }
496
+
471
497
  // ═══ Auto-check: run tsc before soldier review ═══
472
498
  let tscPassed = true;
473
499
  try {