fix(cron): improve cron job stability and visibility by adding immediate Telegram feedback and robust logging

This commit is contained in:
larchanka
2026-04-01 09:23:26 +02:00
committed by Mikhail Larchanka
parent 9b949f7a3a
commit 5cceb959a8
2 changed files with 39 additions and 33 deletions

View File

@@ -191,22 +191,25 @@ export class Orchestrator {
return;
}
// Handle cron AI query events from cron-manager
if (fromProcess === "cron-manager" && envelope.type === "event.cron.ai_query") {
this.handleCronAIQueryEvent(envelope);
return;
}
if (fromProcess === "cron-manager") {
if (envelope.type === "event.cron.ai_query") {
this.handleCronAIQueryEvent(envelope);
} else if (envelope.type === "event.cron.completed") {
this.handleCronReminderEvent(envelope);
}
// Handle cron reminder events from cron-manager
if (fromProcess === "cron-manager" && envelope.type === "event.cron.completed") {
this.handleCronReminderEvent(envelope);
// Also forward to logger as before
// Always forward cron events to logger for audit trail
const logger = this.children.get("logger");
if (logger?.stdin.writable) {
logger.stdin.write(trimmed + "\n");
ConsoleLogger.ipc("core", "→", envelope);
this.broadcastIpcLog("→", "core", "logger", envelope);
}
return;
// If it was one of our handled events, we're done
if (envelope.type === "event.cron.ai_query" || envelope.type === "event.cron.completed") {
return;
}
}
if (to === "core") {
@@ -999,6 +1002,9 @@ export class Orchestrator {
ConsoleLogger.info("core", `Triggering autonomous AI task: "${query}" for chatId ${chatIdNum} (taskId: ${taskId})`);
// Immediate feedback so user knows the cron triggered
this.sendToTelegram(chatIdNum, `🤖 <b>Autonomous task triggered</b>: <i>"${query}"</i>\n\nStarting planning...`, true, "HTML");
// Route to task queue (priority 0 for synthetic)
this.enqueueTask({
chatId: chatIdNum,

View File

@@ -72,27 +72,15 @@ export class CronManager extends BaseProcess {
private runJob(row: ScheduleRow): void {
const now = Date.now();
this.emitEvent("event.cron.started", { scheduleId: row.id, taskType: row.task_type, timestamp: now });
this.emitEvent("event.cron.started", {
scheduleId: row.id,
taskType: row.task_type,
timestamp: now,
});
try {
const payload = row.payload ? JSON.parse(row.payload) : {};
// AI Query task type
if (row.task_type === "ai_query") {
const query = payload.reminderMessage || payload.query || "";
const chatId = payload.chatId;
const userId = payload.userId;
this.emitEvent("event.cron.ai_query", {
scheduleId: row.id,
taskType: row.task_type,
query,
chatId,
userId,
timestamp: Date.now()
});
return;
}
// Default: Reminder or generic task payload
const reminderPayload: Record<string, unknown> = {
scheduleId: row.id,
@@ -101,13 +89,25 @@ export class CronManager extends BaseProcess {
timestamp: Date.now(),
};
// If this is a reminder task, extract structured fields
if (row.task_type === "reminder" || payload.chatId || payload.reminderMessage) {
reminderPayload.chatId = payload.chatId;
reminderPayload.reminderMessage = payload.reminderMessage;
reminderPayload.userId = payload.userId;
// Extract common fields for easier routing in Orchestrator if present
const q = payload.reminderMessage || payload.query;
if (q) reminderPayload.reminderMessage = q;
if (payload.chatId !== undefined) reminderPayload.chatId = payload.chatId;
if (payload.userId !== undefined) reminderPayload.userId = payload.userId;
// Emit specific event types for legacy/orchestrator compatibility
if (row.task_type === "ai_query") {
this.emitEvent("event.cron.ai_query", {
scheduleId: row.id,
taskType: row.task_type,
query: payload.reminderMessage || payload.query || "",
chatId: payload.chatId,
userId: payload.userId,
timestamp: Date.now(),
});
}
// Always emit completed event for tracking and logging
this.emitEvent("event.cron.completed", reminderPayload);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);