mirror of
https://github.com/eggent-ai/eggent.git
synced 2026-03-07 10:03:19 +00:00
Fix recurring 30s cron normalization and guidance
This commit is contained in:
@@ -190,12 +190,40 @@ function normalizeScheduleFromRecord(input: UnknownRecord): CronSchedule | null
|
||||
: input;
|
||||
|
||||
const rawKind = readString(scheduleRaw.kind)?.toLowerCase();
|
||||
const scheduleKindHint = readString(scheduleRaw.scheduleKind)?.toLowerCase();
|
||||
const explicitEveryKind = rawKind === "every" || scheduleKindHint === "every";
|
||||
const at =
|
||||
readString(scheduleRaw.at) ??
|
||||
readString(scheduleRaw.scheduleAt) ??
|
||||
readString(scheduleRaw.runAt) ??
|
||||
readString(scheduleRaw.when);
|
||||
const everyMs = readNumber(scheduleRaw.everyMs);
|
||||
const everyMsDirect =
|
||||
readNumber(scheduleRaw.everyMs) ??
|
||||
readNumber(scheduleRaw.intervalMs) ??
|
||||
readNumber(scheduleRaw.repeatMs);
|
||||
const everySeconds =
|
||||
readNumber(scheduleRaw.everySeconds) ??
|
||||
readNumber(scheduleRaw.intervalSeconds) ??
|
||||
readNumber(scheduleRaw.repeatSeconds) ??
|
||||
(explicitEveryKind ? readNumber(scheduleRaw.seconds) : undefined);
|
||||
const everyMinutes =
|
||||
readNumber(scheduleRaw.everyMinutes) ??
|
||||
readNumber(scheduleRaw.intervalMinutes) ??
|
||||
readNumber(scheduleRaw.repeatMinutes);
|
||||
const everyHours =
|
||||
readNumber(scheduleRaw.everyHours) ??
|
||||
readNumber(scheduleRaw.intervalHours) ??
|
||||
readNumber(scheduleRaw.repeatHours);
|
||||
const everyMs =
|
||||
typeof everyMsDirect === "number" && everyMsDirect > 0
|
||||
? everyMsDirect
|
||||
: typeof everySeconds === "number" && everySeconds > 0
|
||||
? everySeconds * 1_000
|
||||
: typeof everyMinutes === "number" && everyMinutes > 0
|
||||
? everyMinutes * 60_000
|
||||
: typeof everyHours === "number" && everyHours > 0
|
||||
? everyHours * 3_600_000
|
||||
: undefined;
|
||||
const anchorMs = readNumber(scheduleRaw.anchorMs);
|
||||
const expr = readString(scheduleRaw.expr) ?? readString(scheduleRaw.cronExpr);
|
||||
const tz = readString(scheduleRaw.tz) ?? readString(scheduleRaw.cronTz);
|
||||
@@ -209,7 +237,7 @@ function normalizeScheduleFromRecord(input: UnknownRecord): CronSchedule | null
|
||||
? "every"
|
||||
: expr
|
||||
? "cron"
|
||||
: readString(scheduleRaw.scheduleKind)?.toLowerCase();
|
||||
: scheduleKindHint;
|
||||
|
||||
if (kind === "at" && at) {
|
||||
return { kind: "at", at };
|
||||
@@ -244,6 +272,16 @@ function normalizeScheduleFromRecord(input: UnknownRecord): CronSchedule | null
|
||||
: typeof delaySeconds === "number" && delaySeconds > 0
|
||||
? delaySeconds * 1_000
|
||||
: 0;
|
||||
if (kind === "every" && totalMs > 0) {
|
||||
return {
|
||||
kind: "every",
|
||||
everyMs: Math.max(1, Math.floor(totalMs)),
|
||||
anchorMs:
|
||||
typeof anchorMs === "number" && Number.isFinite(anchorMs)
|
||||
? Math.max(0, Math.floor(anchorMs))
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
if (totalMs > 0) {
|
||||
return { kind: "at", at: new Date(Date.now() + totalMs).toISOString() };
|
||||
}
|
||||
@@ -323,6 +361,9 @@ function explainAddInputFailure(source: UnknownRecord): string {
|
||||
problems.push(
|
||||
"Example: {\"action\":\"add\",\"delaySeconds\":30,\"message\":\"Отправь пользователю: привет\"}"
|
||||
);
|
||||
problems.push(
|
||||
"Recurring example: {\"action\":\"add\",\"schedule\":{\"kind\":\"every\",\"everyMs\":30000},\"payload\":{\"kind\":\"agentTurn\",\"message\":\"Отправь пользователю: привет\"}}"
|
||||
);
|
||||
return problems.join(" ");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@ When the user asks to "remind later", "через N минут/секунд", "
|
||||
Rules:
|
||||
- For one-time reminders: use `action="add"` with `schedule.kind="at"` and ISO timestamp.
|
||||
- For recurring reminders: use `schedule.kind="every"` or `schedule.kind="cron"`.
|
||||
- For sub-minute recurring reminders, use `schedule.kind="every"` with `everyMs` (example: 30s -> `everyMs=30000`).
|
||||
- Put the actual reminder text/instruction in `payload.message`.
|
||||
- Do not send raw natural-language text as the job definition; always send structured fields (`schedule` + `payload` or `delaySeconds` + `message`).
|
||||
- `delaySeconds` / `delayMs` are one-shot delays and should not be used for recurring jobs.
|
||||
- If cron returns a preflight validation error, immediately retry once with normalized args (`action="add"`, explicit `schedule`, explicit `payload.message`) and do not repeat identical invalid arguments.
|
||||
- After creating a job, report `id`, schedule, and expected next run time.
|
||||
- For management requests, use:
|
||||
@@ -32,3 +34,7 @@ Examples:
|
||||
- `action="add"`
|
||||
- `schedule={ "kind":"cron", "expr":"47 19 * * *" }`
|
||||
- `payload={ "kind":"agentTurn", "message":"Отправь пользователю: прогноз погоды в Москве" }`
|
||||
- Every 30 seconds:
|
||||
- `action="add"`
|
||||
- `schedule={ "kind":"every", "everyMs":30000 }`
|
||||
- `payload={ "kind":"agentTurn", "message":"Отправь пользователю: Привет!" }`
|
||||
|
||||
Reference in New Issue
Block a user