mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-21 16:41:56 +00:00
fix: suppress SUBAGENT_SPAWN_ACCEPTED_NOTE for cron isolated sessions
The 'do not poll/sleep' note added to sessions_spawn tool results causes
cron isolated agents to immediately end their turn, since the note tells
them not to wait for subagent results. In cron isolated sessions, the
agent turn IS the entire run, so ending early means subagent results
are never collected.
Fix: detect cron sessions via includes(':cron:') in agentSessionKey
and suppress the note, allowing the agent to poll/wait naturally.
Note: PR #27330 used startsWith('cron:') which never matches because
the session key format is 'agent:main:cron:...' (starts with 'agent:').
Fixes #27308
Fixes #25069
This commit is contained in:
committed by
Ayaan Zaidi
parent
46eba86b45
commit
69590de276
@@ -0,0 +1,63 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import "./test-helpers/fast-core-tools.js";
|
||||
import {
|
||||
getCallGatewayMock,
|
||||
getSessionsSpawnTool,
|
||||
resetSessionsSpawnConfigOverride,
|
||||
setupSessionsSpawnGatewayMock,
|
||||
} from "./openclaw-tools.subagents.sessions-spawn.test-harness.js";
|
||||
import { resetSubagentRegistryForTests } from "./subagent-registry.js";
|
||||
import { SUBAGENT_SPAWN_ACCEPTED_NOTE } from "./subagent-spawn.js";
|
||||
|
||||
const callGatewayMock = getCallGatewayMock();
|
||||
|
||||
type SpawnResult = { status?: string; note?: string };
|
||||
|
||||
describe("sessions_spawn: cron isolated session note suppression", () => {
|
||||
beforeEach(() => {
|
||||
callGatewayMock.mockReset();
|
||||
resetSubagentRegistryForTests();
|
||||
resetSessionsSpawnConfigOverride();
|
||||
});
|
||||
|
||||
it("suppresses ACCEPTED_NOTE for cron isolated sessions (mode=run)", async () => {
|
||||
setupSessionsSpawnGatewayMock({});
|
||||
const tool = await getSessionsSpawnTool({
|
||||
agentSessionKey: "agent:main:cron:dd871818:run:cf959c9f",
|
||||
});
|
||||
const result = await tool.execute("call-cron-run", { task: "test task", mode: "run" });
|
||||
const details = result.details as SpawnResult;
|
||||
expect(details.note).toBeUndefined();
|
||||
expect(details.status).toBe("accepted");
|
||||
});
|
||||
|
||||
it("preserves ACCEPTED_NOTE for regular sessions (mode=run)", async () => {
|
||||
setupSessionsSpawnGatewayMock({});
|
||||
const tool = await getSessionsSpawnTool({
|
||||
agentSessionKey: "agent:main:telegram:63448508",
|
||||
});
|
||||
const result = await tool.execute("call-regular-run", { task: "test task", mode: "run" });
|
||||
const details = result.details as SpawnResult;
|
||||
expect(details.note).toBe(SUBAGENT_SPAWN_ACCEPTED_NOTE);
|
||||
expect(details.status).toBe("accepted");
|
||||
});
|
||||
|
||||
it("suppresses ACCEPTED_NOTE for any agent with :cron: in session key", async () => {
|
||||
setupSessionsSpawnGatewayMock({});
|
||||
// Ensure the check uses includes(":cron:") not startsWith("cron:")
|
||||
const tool = await getSessionsSpawnTool({
|
||||
agentSessionKey: "agent:marian-job-search:cron:a7c7874a:run:abc123",
|
||||
});
|
||||
const result = await tool.execute("call-other-agent-cron", { task: "test task", mode: "run" });
|
||||
expect((result.details as SpawnResult).note).toBeUndefined();
|
||||
});
|
||||
|
||||
it("does not suppress note when agentSessionKey is undefined", async () => {
|
||||
setupSessionsSpawnGatewayMock({});
|
||||
const tool = await getSessionsSpawnTool({
|
||||
agentSessionKey: undefined,
|
||||
});
|
||||
const result = await tool.execute("call-no-key", { task: "test task", mode: "run" });
|
||||
expect((result.details as SpawnResult).note).toBe(SUBAGENT_SPAWN_ACCEPTED_NOTE);
|
||||
});
|
||||
});
|
||||
@@ -524,13 +524,23 @@ export async function spawnSubagentDirect(
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're in a cron isolated session - don't add "do not poll" note
|
||||
// because cron sessions end immediately after the agent produces a response,
|
||||
// so the agent needs to wait for subagent results to keep the turn alive.
|
||||
const isCronSession = ctx.agentSessionKey?.includes(":cron:");
|
||||
const note =
|
||||
spawnMode === "session"
|
||||
? SUBAGENT_SPAWN_SESSION_ACCEPTED_NOTE
|
||||
: isCronSession
|
||||
? undefined
|
||||
: SUBAGENT_SPAWN_ACCEPTED_NOTE;
|
||||
|
||||
return {
|
||||
status: "accepted",
|
||||
childSessionKey,
|
||||
runId: childRunId,
|
||||
mode: spawnMode,
|
||||
note:
|
||||
spawnMode === "session" ? SUBAGENT_SPAWN_SESSION_ACCEPTED_NOTE : SUBAGENT_SPAWN_ACCEPTED_NOTE,
|
||||
note,
|
||||
modelApplied: resolvedModel ? modelApplied : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user