fix(subagents): announce delivery with descendant gating, frozen result refresh, and cron retry (#35080)

Thanks @tyler6204
This commit is contained in:
Tyler Yust
2026-03-05 19:20:24 -08:00
committed by GitHub
parent fa3fafdde5
commit 81b93b9ce0
32 changed files with 3440 additions and 805 deletions

View File

@@ -914,8 +914,9 @@ describe("sessions tools", () => {
const result = await tool.execute("call-subagents-list-orchestrator", { action: "list" });
const details = result.details as {
status?: string;
active?: Array<{ runId?: string; status?: string }>;
active?: Array<{ runId?: string; status?: string; pendingDescendants?: number }>;
recent?: Array<{ runId?: string }>;
text?: string;
};
expect(details.status).toBe("ok");
@@ -923,11 +924,13 @@ describe("sessions tools", () => {
expect.arrayContaining([
expect.objectContaining({
runId: "run-orchestrator-ended",
status: "active",
status: "active (waiting on 1 child)",
pendingDescendants: 1,
}),
]),
);
expect(details.recent?.find((entry) => entry.runId === "run-orchestrator-ended")).toBeFalsy();
expect(details.text).toContain("active (waiting on 1 child)");
});
it("subagents list usage separates io tokens from prompt/cache", async () => {
@@ -1106,6 +1109,74 @@ describe("sessions tools", () => {
expect(details.text).toContain("killed");
});
it("subagents numeric targets treat ended orchestrators waiting on children as active", async () => {
resetSubagentRegistryForTests();
const now = Date.now();
addSubagentRunForTests({
runId: "run-orchestrator-ended",
childSessionKey: "agent:main:subagent:orchestrator-ended",
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "orchestrator",
cleanup: "keep",
createdAt: now - 90_000,
startedAt: now - 90_000,
endedAt: now - 60_000,
outcome: { status: "ok" },
});
addSubagentRunForTests({
runId: "run-leaf-active",
childSessionKey: "agent:main:subagent:orchestrator-ended:subagent:leaf",
requesterSessionKey: "agent:main:subagent:orchestrator-ended",
requesterDisplayKey: "subagent:orchestrator-ended",
task: "leaf",
cleanup: "keep",
createdAt: now - 30_000,
startedAt: now - 30_000,
});
addSubagentRunForTests({
runId: "run-running",
childSessionKey: "agent:main:subagent:running",
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "running",
cleanup: "keep",
createdAt: now - 20_000,
startedAt: now - 20_000,
});
const tool = createOpenClawTools({
agentSessionKey: "agent:main:main",
}).find((candidate) => candidate.name === "subagents");
expect(tool).toBeDefined();
if (!tool) {
throw new Error("missing subagents tool");
}
const list = await tool.execute("call-subagents-list-order-waiting", {
action: "list",
});
const listDetails = list.details as {
active?: Array<{ runId?: string; status?: string }>;
};
expect(listDetails.active).toEqual(
expect.arrayContaining([
expect.objectContaining({
runId: "run-orchestrator-ended",
status: "active (waiting on 1 child)",
}),
]),
);
const result = await tool.execute("call-subagents-kill-order-waiting", {
action: "kill",
target: "1",
});
const details = result.details as { status?: string; runId?: string };
expect(details.status).toBe("ok");
expect(details.runId).toBe("run-running");
});
it("subagents kill stops a running run", async () => {
resetSubagentRegistryForTests();
addSubagentRunForTests({