refactor(agent): dedupe harness and command workflows

This commit is contained in:
Peter Steinberger
2026-02-16 14:52:09 +00:00
parent 04892ee230
commit f717a13039
204 changed files with 7366 additions and 11540 deletions

View File

@@ -33,6 +33,43 @@ describe("subagent registry persistence", () => {
const envSnapshot = captureEnv(["OPENCLAW_STATE_DIR"]);
let tempStateDir: string | null = null;
const writePersistedRegistry = async (persisted: Record<string, unknown>) => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-"));
process.env.OPENCLAW_STATE_DIR = tempStateDir;
const registryPath = path.join(tempStateDir, "subagents", "runs.json");
await fs.mkdir(path.dirname(registryPath), { recursive: true });
await fs.writeFile(registryPath, `${JSON.stringify(persisted)}\n`, "utf8");
return registryPath;
};
const createPersistedEndedRun = (params: {
runId: string;
childSessionKey: string;
task: string;
cleanup: "keep" | "delete";
}) => ({
version: 2,
runs: {
[params.runId]: {
runId: params.runId,
childSessionKey: params.childSessionKey,
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: params.task,
cleanup: params.cleanup,
createdAt: 1,
startedAt: 1,
endedAt: 2,
},
},
});
const restartRegistryAndFlush = async () => {
resetSubagentRegistryForTests({ persist: false });
initSubagentRegistry();
await new Promise((r) => setTimeout(r, 0));
};
afterEach(async () => {
announceSpy.mockClear();
resetSubagentRegistryForTests({ persist: false });
@@ -139,10 +176,6 @@ describe("subagent registry persistence", () => {
});
it("maps legacy announce fields into cleanup state", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-"));
process.env.OPENCLAW_STATE_DIR = tempStateDir;
const registryPath = path.join(tempStateDir, "subagents", "runs.json");
const persisted = {
version: 1,
runs: {
@@ -163,8 +196,7 @@ describe("subagent registry persistence", () => {
},
},
};
await fs.mkdir(path.dirname(registryPath), { recursive: true });
await fs.writeFile(registryPath, `${JSON.stringify(persisted)}\n`, "utf8");
const registryPath = await writePersistedRegistry(persisted);
const runs = loadSubagentRegistryFromDisk();
const entry = runs.get("run-legacy");
@@ -178,33 +210,16 @@ describe("subagent registry persistence", () => {
});
it("retries cleanup announce after a failed announce", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-"));
process.env.OPENCLAW_STATE_DIR = tempStateDir;
const registryPath = path.join(tempStateDir, "subagents", "runs.json");
const persisted = {
version: 2,
runs: {
"run-3": {
runId: "run-3",
childSessionKey: "agent:main:subagent:three",
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "retry announce",
cleanup: "keep",
createdAt: 1,
startedAt: 1,
endedAt: 2,
},
},
};
await fs.mkdir(path.dirname(registryPath), { recursive: true });
await fs.writeFile(registryPath, `${JSON.stringify(persisted)}\n`, "utf8");
const persisted = createPersistedEndedRun({
runId: "run-3",
childSessionKey: "agent:main:subagent:three",
task: "retry announce",
cleanup: "keep",
});
const registryPath = await writePersistedRegistry(persisted);
announceSpy.mockResolvedValueOnce(false);
resetSubagentRegistryForTests({ persist: false });
initSubagentRegistry();
await new Promise((r) => setTimeout(r, 0));
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(1);
const afterFirst = JSON.parse(await fs.readFile(registryPath, "utf8")) as {
@@ -214,9 +229,7 @@ describe("subagent registry persistence", () => {
expect(afterFirst.runs["run-3"].cleanupCompletedAt).toBeUndefined();
announceSpy.mockResolvedValueOnce(true);
resetSubagentRegistryForTests({ persist: false });
initSubagentRegistry();
await new Promise((r) => setTimeout(r, 0));
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(2);
const afterSecond = JSON.parse(await fs.readFile(registryPath, "utf8")) as {
@@ -226,33 +239,16 @@ describe("subagent registry persistence", () => {
});
it("keeps delete-mode runs retryable when announce is deferred", async () => {
tempStateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-subagent-"));
process.env.OPENCLAW_STATE_DIR = tempStateDir;
const registryPath = path.join(tempStateDir, "subagents", "runs.json");
const persisted = {
version: 2,
runs: {
"run-4": {
runId: "run-4",
childSessionKey: "agent:main:subagent:four",
requesterSessionKey: "agent:main:main",
requesterDisplayKey: "main",
task: "deferred announce",
cleanup: "delete",
createdAt: 1,
startedAt: 1,
endedAt: 2,
},
},
};
await fs.mkdir(path.dirname(registryPath), { recursive: true });
await fs.writeFile(registryPath, `${JSON.stringify(persisted)}\n`, "utf8");
const persisted = createPersistedEndedRun({
runId: "run-4",
childSessionKey: "agent:main:subagent:four",
task: "deferred announce",
cleanup: "delete",
});
const registryPath = await writePersistedRegistry(persisted);
announceSpy.mockResolvedValueOnce(false);
resetSubagentRegistryForTests({ persist: false });
initSubagentRegistry();
await new Promise((r) => setTimeout(r, 0));
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(1);
const afterFirst = JSON.parse(await fs.readFile(registryPath, "utf8")) as {
@@ -261,9 +257,7 @@ describe("subagent registry persistence", () => {
expect(afterFirst.runs["run-4"]?.cleanupHandled).toBe(false);
announceSpy.mockResolvedValueOnce(true);
resetSubagentRegistryForTests({ persist: false });
initSubagentRegistry();
await new Promise((r) => setTimeout(r, 0));
await restartRegistryAndFlush();
expect(announceSpy).toHaveBeenCalledTimes(2);
const afterSecond = JSON.parse(await fs.readFile(registryPath, "utf8")) as {