oh-pi 0.1.51 → 0.1.52

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.51",
3
+ "version": "0.1.52",
4
4
  "description": "One-click setup for pi-coding-agent. Like oh-my-zsh for pi.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,7 +16,7 @@ You command an autonomous ant colony. Complex tasks are delegated to the swarm,
16
16
 
17
17
  ## Workflow
18
18
  1. Assess task scope
19
- 2. If colony-worthy → use `/colony <goal>` command with clear goal
19
+ 2. If colony-worthy → use `ant_colony` tool with clear goal
20
20
  3. If simple → do it directly
21
21
  4. Review colony output, fix gaps manually if needed
22
22
 
@@ -36,16 +36,15 @@
36
36
 
37
37
  ## 使用方式
38
38
 
39
- ### 作为 Tool(LLM 自动调用)
39
+ ### 使用方式
40
40
 
41
- LLM 会在判断任务复杂度足够时自动调用 `ant_colony` tool
41
+ LLM 在判断任务复杂度足够时会自动调用 `ant_colony` tool,无需手动触发。
42
42
 
43
43
  ### 命令
44
44
 
45
45
  ```
46
- /colony <目标描述> 启动蚁群
47
- /colony-status 查看最近蚁群状态
48
- Ctrl+Alt+A 快捷启动
46
+ /colony-stop 中止运行中的蚁群
47
+ Ctrl+Shift+A 展开蚁群详情面板
49
48
  ```
50
49
 
51
50
  ### 示例
@@ -114,4 +113,4 @@ npx oh-pi # 选择 Full Power 预设
114
113
  | `concurrency.ts` | 115 | 自适应并发:系统采样,探索/稳态双阶段调节 |
115
114
  | `spawner.ts` | 316 | 蚂蚁孵化:进程管理,prompt 构建,输出解析 |
116
115
  | `queen.ts` | 331 | 女王调度:生命周期,任务波次,多轮迭代 |
117
- | `index.ts` | 324 | 扩展入口:tool/command/shortcut 注册,TUI 渲染 |
116
+ | `index.ts` | 324 | 扩展入口:tool/shortcut 注册,TUI 渲染 |
@@ -467,37 +467,94 @@ export default function antColonyExtension(pi: ExtensionAPI) {
467
467
  },
468
468
  });
469
469
 
470
- // ═══ Command: /colony ═══
471
- pi.registerCommand("colony", {
472
- description: "Launch an ant colony with a goal",
470
+ // ═══ Tool: ant_colony ═══
471
+ pi.registerTool({
472
+ name: "ant_colony",
473
+ label: "Ant Colony",
474
+ description: [
475
+ "Launch an autonomous ant colony in the BACKGROUND to accomplish a complex goal.",
476
+ "The colony runs asynchronously — you can continue chatting while it works.",
477
+ "Results are automatically injected when the colony finishes.",
478
+ "Scouts explore the codebase, workers execute tasks in parallel, soldiers review quality.",
479
+ "Use for multi-file changes, large refactors, or complex features.",
480
+ ].join(" "),
473
481
  parameters: Type.Object({
474
482
  goal: Type.String({ description: "What the colony should accomplish" }),
483
+ maxAnts: Type.Optional(Type.Number({ description: "Max concurrent ants (default: auto-adapt)", minimum: 1, maximum: 8 })),
484
+ maxCost: Type.Optional(Type.Number({ description: "Max cost budget in USD (default: unlimited)", minimum: 0.01 })),
485
+ scoutModel: Type.Optional(Type.String({ description: "Model for scout ants (default: current session model)" })),
486
+ workerModel: Type.Optional(Type.String({ description: "Model for worker ants (default: current session model)" })),
487
+ soldierModel: Type.Optional(Type.String({ description: "Model for soldier ants (default: current session model)" })),
475
488
  }),
476
- async handler(args, ctx) {
489
+
490
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
491
+ if (activeColony) {
492
+ return {
493
+ content: [{ type: "text", text: "A colony is already running in the background. Use /colony-stop to cancel it first." }],
494
+ isError: true,
495
+ };
496
+ }
497
+
477
498
  const currentModel = ctx.model ? `${ctx.model.provider}/${ctx.model.id}` : null;
478
499
  if (!currentModel) {
479
- ctx.ui.notify("No model available in current session", "error");
480
- return;
500
+ return {
501
+ content: [{ type: "text", text: "Colony failed: no model available in current session" }],
502
+ isError: true,
503
+ };
481
504
  }
482
505
 
506
+ const modelOverrides: Record<string, string> = {};
507
+ if (params.scoutModel) modelOverrides.scout = params.scoutModel;
508
+ if (params.workerModel) modelOverrides.worker = params.workerModel;
509
+ if (params.soldierModel) modelOverrides.soldier = params.soldierModel;
510
+
483
511
  const colonyParams = {
484
- goal: args.goal,
512
+ goal: params.goal,
513
+ maxAnts: params.maxAnts,
514
+ maxCost: params.maxCost,
485
515
  currentModel,
486
- modelOverrides: {},
516
+ modelOverrides,
487
517
  cwd: ctx.cwd,
488
518
  modelRegistry: ctx.modelRegistry ?? undefined,
489
519
  };
490
520
 
521
+ // 非交互模式(print mode):同步等待蚁群完成
491
522
  if (!ctx.hasUI) {
492
- const result = await runSyncColony(colonyParams);
493
- if (result.isError) {
494
- ctx.ui.notify("Colony failed", "error");
495
- }
496
- return;
523
+ return await runSyncColony(colonyParams, _signal);
497
524
  }
498
525
 
526
+ // 交互模式:后台运行
499
527
  launchBackgroundColony(colonyParams);
500
- ctx.ui.notify(`🐜 Colony launched: ${args.goal.slice(0, 50)}`, "success");
528
+
529
+ return {
530
+ content: [{ type: "text", text: `[COLONY_SIGNAL:LAUNCHED]\n🐜 Colony launched in background.\nGoal: ${params.goal}\n\nThe colony is now running autonomously. Results will be injected when it finishes.` }],
531
+ };
532
+ },
533
+
534
+ renderCall(args, theme) {
535
+ const goal = args.goal?.length > 70 ? args.goal.slice(0, 67) + "..." : args.goal;
536
+ let text = theme.fg("toolTitle", theme.bold("🐜 ant_colony"));
537
+ if (args.maxAnts) text += theme.fg("muted", ` ×${args.maxAnts}`);
538
+ if (args.maxCost) text += theme.fg("warning", ` $${args.maxCost}`);
539
+ text += "\n" + theme.fg("dim", ` ${goal || "..."}`);
540
+ return new Text(text, 0, 0);
541
+ },
542
+
543
+ renderResult(result, { expanded }, theme) {
544
+ const text = result.content?.find((c: any) => c.type === "text")?.text || "";
545
+ if (result.isError) {
546
+ return new Text(theme.fg("error", text), 0, 0);
547
+ }
548
+ const container = new Container();
549
+ container.addChild(new Text(
550
+ theme.fg("success", "✓ ") + theme.fg("toolTitle", theme.bold("Colony launched in background")),
551
+ 0, 0,
552
+ ));
553
+ if (activeColony) {
554
+ container.addChild(new Text(theme.fg("dim", ` Goal: ${activeColony.goal.slice(0, 70)}`), 0, 0));
555
+ container.addChild(new Text(theme.fg("muted", ` Ctrl+Shift+A for details │ /colony-stop to cancel`), 0, 0));
556
+ }
557
+ return container;
501
558
  },
502
559
  });
503
560
 
@@ -290,6 +290,9 @@ async function runAntWave(opts: WaveOptions): Promise<"ok"> {
290
290
  * 蚁后主循环
291
291
  */
292
292
  export async function runColony(opts: QueenOptions): Promise<ColonyState> {
293
+ if (!opts.goal || !opts.goal.trim()) {
294
+ throw new Error("Colony goal is empty or undefined. Please provide a clear goal.");
295
+ }
293
296
  const colonyId = makeColonyId();
294
297
  const nest = new Nest(opts.cwd, colonyId);
295
298
 
@@ -1,59 +0,0 @@
1
- ---
2
- name: ant-colony
3
- description: Ant colony multi-agent orchestration. Use when user needs parallel multi-file changes, large refactors, or complex features. Provides colony management commands and strategies.
4
- ---
5
-
6
- # Ant Colony Skill
7
-
8
- ## When to Use
9
- - Multi-file changes (≥3 files)
10
- - Parallel workstreams
11
- - Large refactors, migrations
12
- - User says: colony, swarm, parallel, multi-agent
13
-
14
- ## Quick Start
15
- ```
16
- /colony <goal>
17
- ```
18
-
19
- ## Colony Lifecycle
20
- 1. **Scout** — Explore codebase, identify targets, produce task pool
21
- 2. **Work** — Workers execute in parallel, adaptive concurrency
22
- 3. **Review** — Soldiers audit changes, request fixes if needed
23
- 4. **Fix** — Workers address review findings
24
- 5. **Done** — Summary report
25
-
26
- ## Strategies
27
-
28
- ### File-Scoped Decomposition (default)
29
- Each worker owns distinct files. Zero conflict.
30
- ```
31
- Worker A: [src/auth.ts, src/auth.test.ts]
32
- Worker B: [src/api.ts, src/api.test.ts]
33
- ```
34
-
35
- ### Module-Scoped
36
- Each worker owns a module directory.
37
- ```
38
- Worker A: src/components/
39
- Worker B: src/api/
40
- ```
41
-
42
- ### Pipeline
43
- Sequential handoff when dependencies exist.
44
- ```
45
- Scout → Worker(schema) → Worker(api) → Worker(ui) → Soldier
46
- ```
47
-
48
- ## Tuning
49
- - `maxAnts`: Cap concurrent ants (default: auto-adapt to CPU)
50
- - Colony auto-reduces concurrency on 429 rate limits
51
- - Blocked tasks auto-resume when file locks release
52
-
53
- ## Extending Castes
54
- Add custom ant types by editing `ant-colony/types.ts`:
55
- ```typescript
56
- // In DEFAULT_ANT_CONFIGS, add:
57
- mycaste: { caste: "mycaste", model: "...", tools: [...], maxTurns: 10 }
58
- ```
59
- Then add matching prompt in `spawner.ts` CASTE_PROMPTS.