diff --git a/src/agents/openclaw-tools.subagents.sessions-spawn.cron-note.test.ts b/src/agents/openclaw-tools.subagents.sessions-spawn.cron-note.test.ts index 789ff410d..6e25419cf 100644 --- a/src/agents/openclaw-tools.subagents.sessions-spawn.cron-note.test.ts +++ b/src/agents/openclaw-tools.subagents.sessions-spawn.cron-note.test.ts @@ -42,14 +42,16 @@ describe("sessions_spawn: cron isolated session note suppression", () => { expect(details.status).toBe("accepted"); }); - it("suppresses ACCEPTED_NOTE for any agent with :cron: in session key", async () => { + it("does not suppress ACCEPTED_NOTE for non-canonical cron-like keys", async () => { setupSessionsSpawnGatewayMock({}); - // Ensure the check uses includes(":cron:") not startsWith("cron:") const tool = await getSessionsSpawnTool({ - agentSessionKey: "agent:marian-job-search:cron:a7c7874a:run:abc123", + agentSessionKey: "agent:main:slack:cron:job:run:uuid", }); - const result = await tool.execute("call-other-agent-cron", { task: "test task", mode: "run" }); - expect((result.details as SpawnResult).note).toBeUndefined(); + const result = await tool.execute("call-cron-like-noncanonical", { + task: "test task", + mode: "run", + }); + expect((result.details as SpawnResult).note).toBe(SUBAGENT_SPAWN_ACCEPTED_NOTE); }); it("does not suppress note when agentSessionKey is undefined", async () => { diff --git a/src/agents/subagent-spawn.ts b/src/agents/subagent-spawn.ts index c3773c46f..9624d09ae 100644 --- a/src/agents/subagent-spawn.ts +++ b/src/agents/subagent-spawn.ts @@ -4,7 +4,11 @@ import { DEFAULT_SUBAGENT_MAX_SPAWN_DEPTH } from "../config/agent-limits.js"; import { loadConfig } from "../config/config.js"; import { callGateway } from "../gateway/call.js"; import { getGlobalHookRunner } from "../plugins/hook-runner-global.js"; -import { normalizeAgentId, parseAgentSessionKey } from "../routing/session-key.js"; +import { + isCronSessionKey, + normalizeAgentId, + parseAgentSessionKey, +} from "../routing/session-key.js"; import { normalizeDeliveryContext } from "../utils/delivery-context.js"; import { resolveAgentConfig } from "./agent-scope.js"; import { AGENT_LANE_SUBAGENT } from "./lanes.js"; @@ -527,7 +531,7 @@ 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 isCronSession = isCronSessionKey(ctx.agentSessionKey); const note = spawnMode === "session" ? SUBAGENT_SPAWN_SESSION_ACCEPTED_NOTE