fix(checkins): use systemEvent for cron triggers instead of agentTurn

Isolated agent sessions load plugins fresh with storage=null, causing
the tool factory to return null and no tools to be available. The agent
then outputs XML-like text instead of making proper tool calls.

Switch cron jobs to use systemEvent payload which runs in the main
gateway process where storage IS initialized. The message_received
hook already handles [system] checkins:trigger: and checkins:cleanup:
events.
This commit is contained in:
Simon KP 2026-01-27 10:16:20 +11:00
parent 9e9aea6482
commit 75c9496cd2
2 changed files with 10 additions and 19 deletions

View File

@ -59,6 +59,7 @@ export function buildCleanupCronJobs(storage: CheckinsStorage): CronJobCreate[]
}
// Build cleanup job for each timezone
// Use systemEvent to run in main gateway process (has access to initialized storage)
const jobs: CronJobCreate[] = [];
for (const tz of timezones) {
jobs.push({
@ -70,12 +71,11 @@ export function buildCleanupCronJobs(storage: CheckinsStorage): CronJobCreate[]
expr: "5 0 * * *", // 00:05 (5 minutes past midnight per RESEARCH.md)
tz,
},
sessionTarget: "isolated",
sessionTarget: "main",
wakeMode: "now",
payload: {
kind: "agentTurn",
message: `[system] checkins:cleanup:${tz}`,
deliver: false,
kind: "systemEvent",
text: `[system] checkins:cleanup:${tz}`,
},
});
}

View File

@ -32,17 +32,8 @@ export function getCheckInJobId(memberId: string): string {
* @returns CronJobCreate configuration
*/
export function buildCheckInCronJob(member: Member, team: Team): CronJobCreate {
// Build a clear instruction for the agent to call the trigger tool
const triggerMessage = [
"SCHEDULED CHECK-IN TRIGGER",
"",
"You must call the checkins_trigger tool with these exact parameters:",
` memberId: "${member.id}"`,
` teamId: "${team.id}"`,
"",
"Do not respond with any other message. Just call the tool.",
].join("\n");
// Use systemEvent to trigger check-in via the main gateway process
// This avoids isolated agent sessions which don't have initialized plugin storage
return {
name: `Check-in: ${member.displayName ?? member.discordUserId}`,
description: `Daily check-in for team ${team.name}`,
@ -52,12 +43,12 @@ export function buildCheckInCronJob(member: Member, team: Team): CronJobCreate {
expr: convertTimeToCronExpr(member.schedule.checkInTime),
tz: member.schedule.timezone,
},
sessionTarget: "isolated",
// sessionTarget is auto-set to "main" for systemEvent payloads
sessionTarget: "main",
wakeMode: "now",
payload: {
kind: "agentTurn",
message: triggerMessage,
deliver: false,
kind: "systemEvent",
text: `[system] checkins:trigger:${member.id}:${team.id}`,
},
};
}