oh-pi 0.1.34 → 0.1.35
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
|
@@ -323,7 +323,7 @@ export async function runColony(opts: QueenOptions): Promise<ColonyState> {
|
|
|
323
323
|
};
|
|
324
324
|
|
|
325
325
|
try {
|
|
326
|
-
// ═══ Phase 1:
|
|
326
|
+
// ═══ Phase 1: 侦察(接力机制) ═══
|
|
327
327
|
let scoutAttempt = 0;
|
|
328
328
|
const MAX_SCOUT_RETRIES = 2;
|
|
329
329
|
let workerTasks: Task[] = [];
|
|
@@ -331,7 +331,7 @@ export async function runColony(opts: QueenOptions): Promise<ColonyState> {
|
|
|
331
331
|
while (scoutAttempt <= MAX_SCOUT_RETRIES) {
|
|
332
332
|
callbacks.onPhase("scouting", scoutAttempt === 0
|
|
333
333
|
? "Dispatching scout ants to explore codebase..."
|
|
334
|
-
: `Scout
|
|
334
|
+
: `Scout relay ${scoutAttempt}/${MAX_SCOUT_RETRIES} (building on previous discoveries)...`);
|
|
335
335
|
|
|
336
336
|
await runAntWave({ ...waveBase, caste: "scout" });
|
|
337
337
|
|
|
@@ -340,10 +340,33 @@ export async function runColony(opts: QueenOptions): Promise<ColonyState> {
|
|
|
340
340
|
|
|
341
341
|
scoutAttempt++;
|
|
342
342
|
if (scoutAttempt <= MAX_SCOUT_RETRIES) {
|
|
343
|
-
//
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
343
|
+
// 接力:检查是否有信息素(前一只 scout 的部分发现)
|
|
344
|
+
const pheromones = nest.getAllPheromones();
|
|
345
|
+
const hasDiscoveries = pheromones.some(p => p.type === "discovery");
|
|
346
|
+
|
|
347
|
+
// 创建接力 scout 任务(而非重置旧任务)
|
|
348
|
+
const relayDescription = hasDiscoveries
|
|
349
|
+
? `Continue exploring the codebase. Previous scouts made partial discoveries (see pheromone trail). Focus on areas NOT yet explored and generate worker tasks.\n\nOriginal goal:\n${opts.goal}`
|
|
350
|
+
: `Explore the codebase and identify all files, modules, and dependencies relevant to this goal:\n\n${opts.goal}\n\nBe thorough. The colony depends on your intelligence.`;
|
|
351
|
+
|
|
352
|
+
const relayTask: Task = {
|
|
353
|
+
id: makeTaskId(),
|
|
354
|
+
parentId: null,
|
|
355
|
+
title: hasDiscoveries ? "Scout relay: continue exploration" : "Scout: explore codebase for goal",
|
|
356
|
+
description: relayDescription,
|
|
357
|
+
caste: "scout",
|
|
358
|
+
status: "pending",
|
|
359
|
+
priority: 1,
|
|
360
|
+
files: [],
|
|
361
|
+
claimedBy: null,
|
|
362
|
+
result: null,
|
|
363
|
+
error: null,
|
|
364
|
+
spawnedTasks: [],
|
|
365
|
+
createdAt: Date.now(),
|
|
366
|
+
startedAt: null,
|
|
367
|
+
finishedAt: null,
|
|
368
|
+
};
|
|
369
|
+
nest.writeTask(relayTask);
|
|
347
370
|
}
|
|
348
371
|
}
|
|
349
372
|
|
|
@@ -50,6 +50,7 @@ const CASTE_PROMPTS: Record<AntCaste, string> = {
|
|
|
50
50
|
Behavior:
|
|
51
51
|
- Quickly scan the codebase to understand structure and locate relevant code
|
|
52
52
|
- Identify files, functions, dependencies related to the goal
|
|
53
|
+
- IMPORTANT: After EACH tool call, summarize what you found so far. Do NOT wait until the end.
|
|
53
54
|
- Report findings as structured intelligence for Worker Ants
|
|
54
55
|
|
|
55
56
|
Output format (MUST follow exactly):
|
|
@@ -261,6 +262,17 @@ export async function spawnAnt(
|
|
|
261
262
|
const event = JSON.parse(line);
|
|
262
263
|
if (event.type === "turn_end") {
|
|
263
264
|
turnCount++;
|
|
265
|
+
// 实时提取信息素:从当前所有 assistant 消息中提取发现
|
|
266
|
+
if (antConfig.caste === "scout") {
|
|
267
|
+
const currentOutput = getFinalOutput(messages);
|
|
268
|
+
if (currentOutput) {
|
|
269
|
+
const livePheromones = extractPheromones(antId, antConfig.caste, task.id, currentOutput, task.files);
|
|
270
|
+
for (const p of livePheromones) {
|
|
271
|
+
p.id = makePheromoneId(); // 确保唯一 ID
|
|
272
|
+
nest.dropPheromone(p);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
264
276
|
if (antConfig.maxTurns && turnCount === antConfig.maxTurns) {
|
|
265
277
|
stderr += `[ant-colony] Warning: ant reached maxTurns (${antConfig.maxTurns}), 1 grace turn remaining\n`;
|
|
266
278
|
} else if (antConfig.maxTurns && turnCount > antConfig.maxTurns) {
|
|
@@ -328,13 +340,13 @@ export async function spawnAnt(
|
|
|
328
340
|
return { ant, output, messages, newTasks: [], pheromones: [], rateLimited: true };
|
|
329
341
|
}
|
|
330
342
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
// 解析子任务和信息素
|
|
343
|
+
// 无论成功或失败,都尝试解析子任务和信息素(支持部分产出)
|
|
334
344
|
const newTasks = parseSubTasks(output);
|
|
335
345
|
const pheromones = extractPheromones(antId, antConfig.caste, task.id, output, task.files);
|
|
336
346
|
for (const p of pheromones) nest.dropPheromone(p);
|
|
337
347
|
|
|
348
|
+
nest.updateTaskStatus(task.id, success ? "done" : "failed", output, success ? undefined : stderr || output);
|
|
349
|
+
|
|
338
350
|
return { ant, output, messages, newTasks, pheromones, rateLimited: false };
|
|
339
351
|
} finally {
|
|
340
352
|
try { fs.unlinkSync(tmpFile); } catch { /* ignore */ }
|