export declare const MAX_PENDING_PER_USER = 50; export declare const MIN_FUTURE_MS: number; export declare const MAX_FUTURE_MS: number; export declare const MAX_TEXT_LEN = 1000; export type ReminderStatus = 'pending' | 'firing' | 'fired' | 'cancelled' | 'failed'; export type PromptMode = 'literal' | 'llm'; export interface Reminder { id: number; fire_at: string; text: string; platform: string; channel_id: string; thread_id: string; user_id: string; status: ReminderStatus; created_at: string; fired_at: string | null; error: string | null; source: string; parent_id: number | null; recurrence: string | null; last_fired_at: string | null; /** 'llm' = at fire time, treat `text` as a prompt and ask the active * agent to compose the actual delivery. 'literal' = deliver `text` as-is. */ prompt_mode: PromptMode; } export interface CreateReminderInput { fireAt: Date; text: string; platform: string; channelId: string; threadId: string; userId: string; source?: 'slash' | 'mcp' | 'api'; parentId?: number; /** Recurrence spec: `every:5m` / `daily:HH:MM` / `weekly:1,3,5:HH:MM`. * When set, the row stays `pending` after each fire and `fire_at` is rolled * forward to the next occurrence. Cancel via /remind cancel . */ recurrence?: string; /** Default 'llm'. Set 'literal' to bypass LLM polish and deliver text as-is. */ promptMode?: PromptMode; } export interface OwnerOpts { /** When set, list/get/cancel/snooze only see rows where user_id matches * OR is empty (legacy/system rows). Same model as schedule.ts. */ creatorId?: string; } export declare class ReminderError extends Error { code: string; constructor(code: string, msg: string); } /** "2m" / "90s" / "3h" / "1d" → milliseconds. Rejects 0/negative/non-int. */ export declare function parseDuration(s: string): number | null; /** "18:30" → today's 18:30 if still in the future, else tomorrow's 18:30. * Uses server TZ (override at process level via TZ=… env). */ export declare function parseClock(s: string, now?: Date): Date | null; /** ISO-ish absolute datetime "2026-05-09T20:00" / "2026-05-09T20:00:00Z" etc. * Trailing seconds and timezone suffix are optional. */ export declare function parseISO(s: string): Date | null; /** Unified parser tried in order: duration → clock → ISO. */ export declare function parseWhen(s: string, now?: Date): { ok: true; fireAt: Date; } | { ok: false; reason: string; }; /** * Consume a time-expression prefix from the head of `s`, supporting Chinese * (no-separator allowed: "40秒喝水" / "下午6点下班") and English/ISO formats. * Returns { fireAt, rest } on success, null when nothing matches. * * This is the main entry point used by the /remind slash handler so users * don't need to remember strict syntax. */ export declare function parseWhenPrefix(s: string, now?: Date): { fireAt: Date; rest: string; } | null; export declare const MIN_RECURRENCE_INTERVAL_MS: number; /** Validate a recurrence spec string. Returns true if parseable. */ export declare function isValidRecurrence(spec: string): boolean; /** * Compute the next fire time for a recurring reminder. * * `anchor` is the previous fire_at (for `every:` we step forward from there; * if we missed cycles while offline, we fast-forward past `now`). For clock- * based recurrences (daily/weekly) anchor is ignored — we always pick the * next future slot from `now`. * * Returns null if the spec is malformed or has no satisfiable next slot. */ export declare function computeNext(spec: string, anchor: Date, now: Date): Date | null; /** Human-readable recurrence label for /remind list. */ export declare function describeRecurrence(spec: string): string; /** * Consume a recurrence prefix from the head of `s`. Supports: * * 每5分钟 / 每隔5分钟 / 每2小时 / 每30秒(拒绝, 不做亚分钟级) * 每天早上8点 / 每日下午6点半 / 每天8:30 * 每周一8点 / 每周一三五9点 / 每周末10点 / 每个工作日9点 * every 5m / every 1h * * Returns `{ recurrence, fireAt, rest }` where `fireAt` is the FIRST occurrence * (≥ now). `null` when no recurrence pattern matched. */ export declare function parseRecurrencePrefix(s: string, now?: Date): { recurrence: string; fireAt: Date; rest: string; } | null; export declare function createReminder(input: CreateReminderInput): number; export declare function listReminders(opts?: OwnerOpts & { status?: ReminderStatus; limit?: number; }): Reminder[]; export declare function getReminder(id: number, opts?: OwnerOpts): Reminder | null; export declare function cancelReminder(id: number, opts?: OwnerOpts): boolean; export declare function clearReminders(opts: { creatorId: string; }): number; /** Snooze an existing reminder by `deltaMs`: clones the row's text and target * thread to a new pending row, then marks the original 'cancelled' (if still * pending) or just chains parent_id (if already fired). Returns new id. */ export declare function snoozeReminder(id: number, deltaMs: number, opts?: OwnerOpts): number; /** Bind (or rebind) an email address to an IM user. Returns the bound email. */ export declare function bindEmail(platform: string, userId: string, email: string): string; /** Look up the bound email for an IM user, or null. */ export declare function getBoundEmail(platform: string, userId: string): string | null; /** Remove the binding for an IM user. Returns true if a row was deleted. */ export declare function unbindEmail(platform: string, userId: string): boolean; /** * Render a compact "background context" block listing the user's pending * reminders for the current platform. Used by router.ts to prepend to the * agent prompt so the agent has live visibility into the user's queue — * lets it answer "what reminders do I have?" without an extra * list_reminders tool call, and avoids creating duplicates. * * Empty string when nothing pending — caller should noop. * * Cost: ~80-200 tokens per message when populated. Bounded to 5 reminders. */ export declare function buildContextSnippet(platform: string, userId: string): string; /** Whether the LLM intent detector should run for this user's non-slash * messages. Default on (no row = enabled). DB-unavailable also returns * true so users on bun/fail-soft don't lose the feature silently. */ export declare function isAiwatchEnabled(platform: string, userId: string): boolean; /** Set the aiwatch enabled flag. UPSERT semantics. Returns the new value. */ export declare function setAiwatchEnabled(platform: string, userId: string, enabled: boolean): boolean; /** Move a failed/cancelled reminder back to pending with a fresh fireAt * (now + MIN_FUTURE_MS). Owner-scoped. Returns true on success. */ export declare function retryReminder(id: number, opts?: OwnerOpts): boolean; /** Run a single tick. Exposed for tests so they can advance the clock manually. */ export declare function tick(now?: Date): Promise; /** Start the periodic ticker. Idempotent. */ export declare function startReminderEngine(): void; export declare function stopReminderEngine(): void; export declare function closeReminderDb(): void; //# sourceMappingURL=reminders.d.ts.map