/** * 自动升级:安全窗口判定 + 升级锁。 * * 核心抽象:UpgradeSafenessSource——各执行链(主会话/Cron/Loop/Goal) * 自己实现「是否空闲」,主流程只做汇总,不感知具体任务类型。 * * 设计见 tasks/niubot-engine/auto-update.md。 */ import type { Database } from "better-sqlite3"; /** 升级窗口余量(分钟):窗口结束前不再启动新升级,覆盖升级耗时。 */ export declare const DEFAULT_UPGRADE_MARGIN_MINUTES = 10; /** 等待当前 run 收尾的超时上限(毫秒):长跑任务强制升级,中断靠 continuation 恢复兜底。 */ export declare const UPGRADE_WAIT_RUN_TIMEOUT_MS: number; /** * cron/loop 未来触发检查窗口(毫秒):覆盖「升级执行耗时 + 余量」。 * 不沿用整个可升级窗口——升级只需几分钟,用 30 分钟窗口即可避开 * 真正会撞上升级的 cron,同时不因窗口内远端 cron 白白顺延。 */ export declare const UPGRADE_SAFENESS_WINDOW_MS: number; export interface AutoUpdateConfig { enabled: boolean; /** 当地时区固定可升级窗口(24h 制) */ windowStartHour: number; windowEndHour: number; timezone: string; /** 窗口结束前余量(分钟),覆盖升级耗时 */ marginMinutes: number; /** 默认 true:升级成功结果在白天通知窗口汇报;false = 完全静默 */ notifyOnResult: boolean; } export declare const AUTO_UPDATE_DEFAULTS: Omit; /** 各执行链向自动升级暴露的「空闲」协议。 */ export interface UpgradeSafenessSource { /** 链路名,用于日志/诊断 */ readonly name: string; /** * 是否空闲(safe for upgrade)。 * 语义:该链路上没有「正在运行」也没有「排队中」的任务, * 且未来 upgradeWindowMs 内不会有新触发。 */ isIdle(now: number, upgradeWindowMs: number): boolean; /** 该链路当前不空闲时的原因(诊断用),空串 = 空闲 */ describeBlockers(now: number, upgradeWindowMs: number): string; } /** 汇总结果。 */ export interface SafenessResult { safe: boolean; blockers: string[]; } /** 汇总:所有链路都 idle 才算安全。 */ export declare function isSafeForUpgrade(sources: UpgradeSafenessSource[], now: number, upgradeWindowMs: number): SafenessResult; export interface MainRunStateQuery { /** 全局进行中的 run 数量(RuntimeStateStore.getPipelineHealth().inflightRunIds.length) */ inflightRunCount: () => number; /** 所有 chat 的队列积压消息总数 */ pendingMessageCount: () => number; } /** 主会话 run 链路:无 inflight + 无队列积压。 */ export declare function mainRunSource(state: MainRunStateQuery): UpgradeSafenessSource; export interface GoalStateQuery { activeGoalCount: () => number; } /** Goal 链路:无活跃 Goal 循环。 */ export declare function goalSource(state: GoalStateQuery): UpgradeSafenessSource; export interface CronStateQuery { /** 返回所有 active/running cron 任务的 cronExpr/runAt/timezone */ listJobs: () => Array<{ cronExpr: string | null; runAt: string | null; timezone: string | null; }>; } /** Cron 链路:无 running,且未来 upgradeWindowMs 内无到点触发。 */ export declare function cronSource(db: Database, query?: CronStateQuery): UpgradeSafenessSource; export interface LoopStateQuery { /** 返回所有 loop 任务的运行状态和触发信息 */ listJobs: () => Array<{ status: string; nextRunAt: string | null; }>; } /** Loop 链路:无 running/queued,且未来窗口内无触发。 */ export declare function loopSource(db: Database, query?: LoopStateQuery): UpgradeSafenessSource; /** 本地时区小时是否在 [startHour, endHour) 窗口内(跨天支持)。 */ export declare function isInUpgradeWindow(date: Date, config: AutoUpdateConfig): boolean; /** 距窗口结束的分钟数(若当前在窗口外则返回 0)。 */ export declare function minutesUntilUpgradeWindowEnd(date: Date, config: AutoUpdateConfig): number;