@ifi/oh-pi-ant-colony 0.2.8 → 0.2.10
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/README.md +38 -10
- package/extensions/ant-colony/budget-planner.ts +55 -0
- package/extensions/ant-colony/index.ts +313 -79
- package/extensions/ant-colony/multimodal-routing.ts +68 -0
- package/extensions/ant-colony/nest.ts +26 -1
- package/extensions/ant-colony/queen.ts +123 -20
- package/extensions/ant-colony/spawner.ts +147 -18
- package/extensions/ant-colony/types.ts +75 -2
- package/extensions/ant-colony/worktree.ts +244 -0
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -25,6 +25,20 @@ Goal → Scouting → Task Pool → Workers Execute in Parallel → Soldiers Rev
|
|
|
25
25
|
└───────────────────────────┘
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
## Workspace Isolation (Default)
|
|
29
|
+
|
|
30
|
+
By default, each colony runs in an **isolated git worktree** on its own branch (`ant-colony/...`).
|
|
31
|
+
This keeps your current branch untouched while the swarm edits code.
|
|
32
|
+
|
|
33
|
+
If worktree creation is unavailable (e.g. not a git repo), the colony automatically falls back to the shared cwd and
|
|
34
|
+
reports the reason in the final report/status output.
|
|
35
|
+
|
|
36
|
+
You can disable worktree isolation with:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
PI_ANT_COLONY_WORKTREE=0
|
|
40
|
+
```
|
|
41
|
+
|
|
28
42
|
## Adaptive Concurrency
|
|
29
43
|
|
|
30
44
|
Models real ant colony dynamic recruitment:
|
|
@@ -44,7 +58,11 @@ The LLM automatically invokes the `ant_colony` tool when task complexity warrant
|
|
|
44
58
|
### Commands
|
|
45
59
|
|
|
46
60
|
```
|
|
47
|
-
/colony
|
|
61
|
+
/colony <goal> Start a new colony for the given goal
|
|
62
|
+
/colony-count Show number of currently running colonies
|
|
63
|
+
/colony-status [id] Show running colonies (runtime cN or stable colony-... ID)
|
|
64
|
+
/colony-stop [id|all] Cancel one running colony (runtime/stable ID) or all
|
|
65
|
+
/colony-resume [colonyId] Resume a specific stable colony ID, or all resumable by default
|
|
48
66
|
Ctrl+Shift+A Open colony details panel
|
|
49
67
|
```
|
|
50
68
|
|
|
@@ -58,6 +76,11 @@ Ctrl+Shift+A Open colony details panel
|
|
|
58
76
|
/colony Refactor auth system from session-based to JWT, maintaining API compatibility
|
|
59
77
|
```
|
|
60
78
|
|
|
79
|
+
## Usage Tracking Integration
|
|
80
|
+
|
|
81
|
+
Ant inference usage (tokens + cost) is streamed to the `usage-tracker` extension via `pi.events` (`usage:record`).
|
|
82
|
+
So `/usage`, `usage_report`, and session cost totals now include background colony inference, making colony spend visible.
|
|
83
|
+
|
|
61
84
|
## Pheromone System
|
|
62
85
|
|
|
63
86
|
Ants communicate indirectly through pheromones (stigmergy), not direct messages:
|
|
@@ -94,13 +117,17 @@ Each task declares the files it operates on. The queen guarantees:
|
|
|
94
117
|
## Installation
|
|
95
118
|
|
|
96
119
|
```bash
|
|
97
|
-
#
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
#
|
|
120
|
+
# Install just ant-colony
|
|
121
|
+
pi install npm:@ifi/oh-pi-ant-colony
|
|
122
|
+
|
|
123
|
+
# Or install the full oh-pi bundle (includes ant-colony)
|
|
124
|
+
pi install npm:@ifi/oh-pi
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Then enable/configure extensions with:
|
|
101
128
|
|
|
102
|
-
|
|
103
|
-
npx oh-pi
|
|
129
|
+
```bash
|
|
130
|
+
npx @ifi/oh-pi-cli
|
|
104
131
|
```
|
|
105
132
|
|
|
106
133
|
## Module Reference
|
|
@@ -110,9 +137,10 @@ npx oh-pi # Select "Full Power" preset
|
|
|
110
137
|
| `types.ts` | ~150 | Type system: ants, tasks, pheromones, colony state |
|
|
111
138
|
| `nest.ts` | ~500 | Nest: file-system shared state, atomic R/W, pheromone decay |
|
|
112
139
|
| `concurrency.ts` | ~120 | Adaptive concurrency: system sampling, exploration/steady-state adjustment |
|
|
113
|
-
| `spawner.ts` | ~
|
|
114
|
-
| `queen.ts` | ~
|
|
115
|
-
| `
|
|
140
|
+
| `spawner.ts` | ~420 | Ant spawning: session lifecycle, usage streaming, prompt/output handling |
|
|
141
|
+
| `queen.ts` | ~1020 | Queen scheduling: lifecycle, task waves, multi-round iteration |
|
|
142
|
+
| `worktree.ts` | ~180 | Git worktree isolation and resume workspace recovery helpers |
|
|
143
|
+
| `index.ts` | ~1050 | Extension entry: tool/shortcut registration, TUI rendering, status signals |
|
|
116
144
|
| `deps.ts` | ~140 | Lightweight import graph for dependency-aware scheduling |
|
|
117
145
|
| `parser.ts` | ~180 | Sub-task and pheromone extraction from ant output |
|
|
118
146
|
| `prompts.ts` | ~90 | Per-caste system prompts and prompt builder |
|
|
@@ -68,6 +68,18 @@ export interface CasteBudget {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
/** Full budget plan for a colony run. */
|
|
71
|
+
export interface RoutingTelemetrySnapshot {
|
|
72
|
+
totalRoutes: number;
|
|
73
|
+
avgLatencyMs: number;
|
|
74
|
+
outcomeCounts: {
|
|
75
|
+
claimed: number;
|
|
76
|
+
completed: number;
|
|
77
|
+
failed: number;
|
|
78
|
+
escalated: number;
|
|
79
|
+
};
|
|
80
|
+
escalationReasonCounts: Record<string, number>;
|
|
81
|
+
}
|
|
82
|
+
|
|
71
83
|
export interface BudgetPlan {
|
|
72
84
|
/** Per-caste allocations. */
|
|
73
85
|
castes: Record<AntCaste, CasteBudget>;
|
|
@@ -79,6 +91,8 @@ export interface BudgetPlan {
|
|
|
79
91
|
lowestRateLimitPct: number;
|
|
80
92
|
/** Human-readable summary for prompt injection. */
|
|
81
93
|
summary: string;
|
|
94
|
+
/** Aggregated routing telemetry used for reporting and debugging. */
|
|
95
|
+
routingTelemetry: RoutingTelemetrySnapshot;
|
|
82
96
|
}
|
|
83
97
|
|
|
84
98
|
// ═══ Constants ═══
|
|
@@ -210,6 +224,7 @@ export function buildBudgetSummary(
|
|
|
210
224
|
maxCost: number | null,
|
|
211
225
|
tasksDone: number,
|
|
212
226
|
tasksTotal: number,
|
|
227
|
+
routingTelemetry?: RoutingTelemetrySnapshot,
|
|
213
228
|
): string {
|
|
214
229
|
const parts: string[] = [];
|
|
215
230
|
|
|
@@ -233,6 +248,16 @@ export function buildBudgetSummary(
|
|
|
233
248
|
parts.push(`Progress: ${tasksDone}/${tasksTotal} tasks completed.`);
|
|
234
249
|
}
|
|
235
250
|
|
|
251
|
+
if (routingTelemetry && routingTelemetry.totalRoutes > 0) {
|
|
252
|
+
parts.push(
|
|
253
|
+
`Routing: ${routingTelemetry.totalRoutes} outcomes, avg latency ${routingTelemetry.avgLatencyMs}ms, escalations ${routingTelemetry.outcomeCounts.escalated}.`,
|
|
254
|
+
);
|
|
255
|
+
const topEscalation = Object.entries(routingTelemetry.escalationReasonCounts).sort((a, b) => b[1] - a[1])[0];
|
|
256
|
+
if (topEscalation) {
|
|
257
|
+
parts.push(`Top escalation reason: ${topEscalation[0]} (${topEscalation[1]}).`);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
236
261
|
// Severity-specific guidance
|
|
237
262
|
switch (severity) {
|
|
238
263
|
case "critical":
|
|
@@ -265,6 +290,33 @@ export function buildBudgetSummary(
|
|
|
265
290
|
* @param concurrency - Current concurrency config for max bounds.
|
|
266
291
|
* @returns A complete budget plan with per-caste allocations.
|
|
267
292
|
*/
|
|
293
|
+
export function buildRoutingTelemetrySnapshot(metrics: ColonyMetrics): RoutingTelemetrySnapshot {
|
|
294
|
+
const entries = metrics.routingTelemetry ?? [];
|
|
295
|
+
const outcomeCounts = {
|
|
296
|
+
claimed: 0,
|
|
297
|
+
completed: 0,
|
|
298
|
+
failed: 0,
|
|
299
|
+
escalated: 0,
|
|
300
|
+
};
|
|
301
|
+
const escalationReasonCounts: Record<string, number> = {};
|
|
302
|
+
let latencyTotal = 0;
|
|
303
|
+
|
|
304
|
+
for (const entry of entries) {
|
|
305
|
+
outcomeCounts[entry.outcome] += 1;
|
|
306
|
+
latencyTotal += entry.latencyMs;
|
|
307
|
+
for (const reason of entry.escalationReasons) {
|
|
308
|
+
escalationReasonCounts[reason] = (escalationReasonCounts[reason] ?? 0) + 1;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return {
|
|
313
|
+
totalRoutes: entries.length,
|
|
314
|
+
avgLatencyMs: entries.length > 0 ? Math.round(latencyTotal / entries.length) : 0,
|
|
315
|
+
outcomeCounts,
|
|
316
|
+
escalationReasonCounts,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
268
320
|
export function planBudget(
|
|
269
321
|
usageLimits: UsageLimitsEvent | null,
|
|
270
322
|
metrics: ColonyMetrics,
|
|
@@ -311,6 +363,7 @@ export function planBudget(
|
|
|
311
363
|
};
|
|
312
364
|
}
|
|
313
365
|
|
|
366
|
+
const routingTelemetry = buildRoutingTelemetrySnapshot(metrics);
|
|
314
367
|
const summary = buildBudgetSummary(
|
|
315
368
|
severity,
|
|
316
369
|
lowestRateLimitPct,
|
|
@@ -318,6 +371,7 @@ export function planBudget(
|
|
|
318
371
|
maxCost,
|
|
319
372
|
metrics.tasksDone,
|
|
320
373
|
metrics.tasksTotal,
|
|
374
|
+
routingTelemetry,
|
|
321
375
|
);
|
|
322
376
|
|
|
323
377
|
return {
|
|
@@ -326,6 +380,7 @@ export function planBudget(
|
|
|
326
380
|
severity,
|
|
327
381
|
lowestRateLimitPct,
|
|
328
382
|
summary,
|
|
383
|
+
routingTelemetry,
|
|
329
384
|
};
|
|
330
385
|
}
|
|
331
386
|
|