import type { SessionStore } from '../session/store.js';
export type CronDeliveryMode = 'none' | 'announce' | 'direct';
export interface CronDelivery {
    mode: CronDeliveryMode;
    channel?: string;
    to?: string;
    bestEffort?: boolean;
}
export type CronPayload = {
    kind: 'systemEvent';
    text: string;
} | {
    kind: 'agentTurn';
    message: string;
    model?: string;
    timeoutSeconds?: number;
};
export type CronSessionTarget = 'main' | 'isolated';
export interface JobData {
    id: string;
    name?: string;
    schedule: string;
    enabled: boolean;
    timezone?: string;
    maxRetries: number;
    timeout: number;
    created_at: string;
    updated_at: string;
    sessionTarget?: CronSessionTarget;
    /** When set, isolated agent runs use this agent id in the session key (multi-agent). */
    agentId?: string;
    /**
     * Optional absolute workspace root for isolated agent runs (same semantics as chat working directory).
     * Omit to use the effective agent profile default workspace.
     */
    workingDirectory?: string;
    payload: CronPayload;
    delivery?: CronDelivery;
    model?: string;
    state?: JobState;
}
export interface JobState {
    nextRunAtMs?: number;
    runningAtMs?: number;
    lastRunAtMs?: number;
    lastStatus?: 'ok' | 'error' | 'skipped';
    lastError?: string;
    lastDurationMs?: number;
    consecutiveErrors?: number;
    scheduleErrorCount?: number;
}
export interface JobExecution {
    id: string;
    jobId: string;
    status: 'running' | 'success' | 'failed' | 'cancelled' | 'skipped';
    startedAt: string;
    endedAt?: string;
    duration?: number;
    error?: string;
    output?: string;
    retryCount: number;
    summary?: string;
    sessionId?: string;
    sessionKey?: string;
    /** Persisted for local run logs (e.g. `cron` for isolated agent jobs). */
    sessionType?: string;
    model?: string;
    provider?: string;
    usage?: CronUsageSummary;
}
export interface CronUsageSummary {
    input_tokens?: number;
    output_tokens?: number;
    total_tokens?: number;
}
/** One row for GET /api/cron/runs/history (optional display name from job definition). */
export interface CronRunHistoryRow extends JobExecution {
    jobName?: string;
}
export type CronRunStatus = 'ok' | 'error' | 'skipped';
export interface CronRunOutcome {
    status: CronRunStatus;
    error?: string;
    summary?: string;
    sessionId?: string;
    sessionKey?: string;
    sessionType?: string;
    model?: string;
    provider?: string;
    usage?: CronUsageSummary;
}
/** Optional hook after a successful cron run (e.g. wake gateway heartbeat). */
export interface HeartbeatWakeSink {
    requestNow(opts?: {
        reason?: string;
    }): void;
}
export interface JobExecutorDeps {
    agentService?: any;
    messageBus?: any;
    heartbeatService?: HeartbeatWakeSink;
    /** When set, weixin cron `delivery.to` may be a bare ilink user id; accountId is inferred from sessions. */
    sessionStore?: SessionStore;
    /**
     * When a job has no `agentId`, isolated cron runs use this id for the session key
     * (same as {@link JobData.agentId} set to the default agent). Typically `getDefaultAgentId(config)`.
     */
    getDefaultCronAgentId?: () => string;
}
export interface JobExecutor {
    execute(job: JobData, signal: AbortSignal, deps?: JobExecutorDeps): Promise<void>;
}
export interface CronMetrics {
    totalJobs: number;
    runningJobs: number;
    enabledJobs: number;
    failedLastHour: number;
    avgExecutionTime: number;
    nextScheduledJob?: {
        id: string;
        name?: string;
        runAt: Date;
    };
}
export interface CronHealth {
    status: 'healthy' | 'degraded' | 'unhealthy';
    issues: string[];
    lastError?: string;
}
export interface AddJobOptions {
    name?: string;
    timezone?: string;
    maxRetries?: number;
    timeout?: number;
    sessionTarget?: CronSessionTarget;
    agentId?: string;
    workingDirectory?: string;
    payload: CronPayload;
    delivery?: CronDelivery;
    model?: string;
}
export interface JobWithNextRun extends Omit<JobData, 'created_at' | 'updated_at' | 'state'> {
    next_run?: string;
}
export interface JobHistoryQuery {
    jobId: string;
    limit?: number;
    before?: Date;
}
