fix(cron): force main-target system events onto main session (#28898)

Ignore persisted sessionKey overrides for sessionTarget=main jobs so cron system events consistently route to the agent main session after upgrades.

Closes #28770
This commit is contained in:
Sid
2026-03-01 01:08:53 +08:00
committed by GitHub
parent 2851926314
commit fe9a7c4082
2 changed files with 11 additions and 8 deletions

View File

@@ -509,7 +509,7 @@ describe("CronService", () => {
await store.cleanup();
});
it("passes agentId + sessionKey to runHeartbeatOnce for main-session wakeMode now jobs", async () => {
it("passes agentId and resolves main session for wakeMode now main jobs", async () => {
const runHeartbeatOnce = vi.fn(async () => ({ status: "ran" as const, durationMs: 1 }));
const { store, cron, enqueueSystemEvent, requestHeartbeatNow } =
@@ -534,13 +534,13 @@ describe("CronService", () => {
expect.objectContaining({
reason: `cron:${job.id}`,
agentId: "ops",
sessionKey,
sessionKey: undefined,
}),
);
expect(requestHeartbeatNow).not.toHaveBeenCalled();
expect(enqueueSystemEvent).toHaveBeenCalledWith(
"hello",
expect.objectContaining({ agentId: "ops", sessionKey }),
expect.objectContaining({ agentId: "ops", sessionKey: undefined }),
);
cron.stop();
@@ -578,7 +578,7 @@ describe("CronService", () => {
expect(requestHeartbeatNow).toHaveBeenCalledWith(
expect.objectContaining({
reason: `cron:${job.id}`,
sessionKey,
sessionKey: undefined,
}),
);
expect(job.state.lastStatus).toBe("ok");

View File

@@ -640,9 +640,12 @@ export async function executeJobCore(
: 'main job requires payload.kind="systemEvent"',
};
}
// main-target cron jobs should always resolve via the agent's main session.
// Avoid forwarding persisted channel session keys from legacy records.
const targetMainSessionKey = undefined;
state.deps.enqueueSystemEvent(text, {
agentId: job.agentId,
sessionKey: job.sessionKey,
sessionKey: targetMainSessionKey,
contextKey: `cron:${job.id}`,
});
if (job.wakeMode === "now" && state.deps.runHeartbeatOnce) {
@@ -659,7 +662,7 @@ export async function executeJobCore(
heartbeatResult = await state.deps.runHeartbeatOnce({
reason,
agentId: job.agentId,
sessionKey: job.sessionKey,
sessionKey: targetMainSessionKey,
});
if (
heartbeatResult.status !== "skipped" ||
@@ -677,7 +680,7 @@ export async function executeJobCore(
state.deps.requestHeartbeatNow({
reason,
agentId: job.agentId,
sessionKey: job.sessionKey,
sessionKey: targetMainSessionKey,
});
return { status: "ok", summary: text };
}
@@ -698,7 +701,7 @@ export async function executeJobCore(
state.deps.requestHeartbeatNow({
reason: `cron:${job.id}`,
agentId: job.agentId,
sessionKey: job.sessionKey,
sessionKey: targetMainSessionKey,
});
return { status: "ok", summary: text };
}