424458e99d
Reverted branch-side edits to spawn-policy prompts/tests, settings tab groups, mermaid cache typing, prewalk todo gating, and packages/ai test churn back to merge-base content; trimmed their changelog entries. These repaired stale CI against an older main and are stale or conflicting against current main.
113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import { buildCoordinationAdvisory, composeSpawnAdvisory } from "@oh-my-pi/pi-coding-agent/task";
|
|
import type { TaskItem } from "@oh-my-pi/pi-coding-agent/task/types";
|
|
import { prompt } from "@oh-my-pi/pi-utils";
|
|
import subagentSystemPromptTemplate from "../../src/prompts/system/subagent-system-prompt.md" with { type: "text" };
|
|
|
|
// Contract: a multi-sibling spawn with spawn capacity and IRC available draws
|
|
// a proactive coordinate-via-irc suggestion, and the subagent COOP prompt
|
|
// actively tells peers to coordinate before overlapping edits.
|
|
|
|
const item = (): TaskItem => ({ task: "do the thing" });
|
|
|
|
describe("buildCoordinationAdvisory", () => {
|
|
it("suggests hub coordination for >=2 siblings with capacity and hub messaging enabled", () => {
|
|
const advice = buildCoordinationAdvisory([item(), item()], true, true);
|
|
expect(advice).toBeDefined();
|
|
expect(advice).toContain("`hub`");
|
|
});
|
|
|
|
it("stays silent for a single spawn", () => {
|
|
expect(buildCoordinationAdvisory([item()], true, true)).toBeUndefined();
|
|
});
|
|
|
|
it("stays silent when irc is unavailable", () => {
|
|
expect(buildCoordinationAdvisory([item(), item()], true, false)).toBeUndefined();
|
|
});
|
|
|
|
it("stays silent at max depth (no spawn capacity)", () => {
|
|
expect(buildCoordinationAdvisory([item(), item()], false, true)).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe("subagent COOP irc guidance", () => {
|
|
it("prompts coordination before overlapping edits when peers are present", () => {
|
|
const out = prompt.render(subagentSystemPromptTemplate, {
|
|
agent: "Base worker.",
|
|
ircPeers: "- `Sib` — task (sub, running)",
|
|
ircSelfId: "Self",
|
|
});
|
|
expect(out).toContain("before you edit");
|
|
expect(out).toMatch(/overlapping edits collide/i);
|
|
});
|
|
});
|
|
|
|
// Contract: TaskTool.execute composes the specialization nudge with the
|
|
// coordination suggestion, gating the latter to the async path (sync siblings
|
|
// have already finished). composeSpawnAdvisory is the seam that decision flows
|
|
// through, so the gating is pinned here rather than only inside the builders.
|
|
describe("composeSpawnAdvisory", () => {
|
|
const worker = (): TaskItem => ({ task: "x" });
|
|
|
|
it("joins the specialization tip and the irc coordination suggestion for an async generic fanout", () => {
|
|
const advisory = composeSpawnAdvisory({
|
|
agents: ["task", "task"],
|
|
items: [worker(), worker()],
|
|
depthCapacity: true,
|
|
ircEnabled: true,
|
|
willRunAsync: true,
|
|
});
|
|
expect(advisory).toContain("generic");
|
|
expect(advisory).toContain('`agent: "scout"`');
|
|
expect(advisory).toContain("Coordinate:");
|
|
});
|
|
|
|
it("drops the coordination suggestion on the sync path but keeps the specialization tip", () => {
|
|
const advisory = composeSpawnAdvisory({
|
|
agents: ["task", "task"],
|
|
items: [worker(), worker()],
|
|
depthCapacity: true,
|
|
ircEnabled: true,
|
|
willRunAsync: false,
|
|
});
|
|
expect(advisory).toContain("generic");
|
|
expect(advisory).not.toContain("Coordinate:");
|
|
});
|
|
|
|
it("omits coordination when irc is unavailable, even async", () => {
|
|
const advisory = composeSpawnAdvisory({
|
|
agents: ["task", "task"],
|
|
items: [worker(), worker()],
|
|
depthCapacity: true,
|
|
ircEnabled: false,
|
|
willRunAsync: true,
|
|
});
|
|
expect(advisory).toContain("generic");
|
|
expect(advisory).not.toContain("Coordinate:");
|
|
});
|
|
|
|
it("returns undefined for a single non-generic spawn", () => {
|
|
expect(
|
|
composeSpawnAdvisory({
|
|
agents: ["reviewer"],
|
|
items: [worker()],
|
|
depthCapacity: true,
|
|
ircEnabled: true,
|
|
willRunAsync: true,
|
|
}),
|
|
).toBeUndefined();
|
|
});
|
|
|
|
it("returns undefined at max depth (no spawn capacity)", () => {
|
|
expect(
|
|
composeSpawnAdvisory({
|
|
agents: ["task", "task"],
|
|
items: [worker(), worker()],
|
|
depthCapacity: false,
|
|
ircEnabled: true,
|
|
willRunAsync: true,
|
|
}),
|
|
).toBeUndefined();
|
|
});
|
|
});
|