/**
 * Module: persistence
 *
 * Modern dialog persistence with strong typing and latest.yaml support.
 * Provides file-based storage with append-only events and atomic operations.
 */
import type { ContextHealthSnapshot } from '@longrun-ai/kernel/types/context-health';
import type { NativeToolCallPayload, WebSearchCallAction, WebSearchCallSource } from '@longrun-ai/kernel/types/dialog';
import type { DialogRuntimePrompt } from '@longrun-ai/kernel/types/drive-intent';
import type { LanguageCode } from '@longrun-ai/kernel/types/language';
import type { ActiveCalleeDispatchRecord, ActiveCalleesFile, AnswerToHumanItem, CallSiteCourseNo, CallSiteGenseqNo, DialogAskerStackState, DialogCourseNumber, DialogLatestFile, DialogMetadataFile, DialogNextStepTrigger, DialogNextStepTriggerDraft, DialogTellaskCallState, HumanQuestion, HumanTextRecord, MainDialogMetadataFile, PersistedDialogRecord, ProviderData, ReasoningPayload, ReconciledRecordWriteTarget, RootGenerationAnchor, SideDialogAssignmentFromAsker, SideDialogMetadataFile, SideDialogRegistryStateRecord, SideDialogResponseStateRecord, TellaskCallRecord, TellaskReplyDirective, TellaskResultRecord } from '@longrun-ai/kernel/types/storage';
import type { DialogsQuarantinedMessage, DialogStatusKind } from '@longrun-ai/kernel/types/wire';
import { WebSocket } from 'ws';
import type { ActiveCalleeDispatch } from './dialog';
import { Dialog, DialogID, DialogStore, MainDialog, SideDialog } from './dialog';
import { ChatMessage, FuncResultMsg, TellaskCarryoverMsg, TellaskResultMsg } from './llm/client';
import type { ToolResultImageIngest, UserImageIngest } from './llm/gen';
import { Reminder } from './tool';
export declare function setDialogsQuarantinedBroadcaster(fn: ((msg: DialogsQuarantinedMessage) => void) | null): void;
export declare function setPrepareDialogQuarantineHook(fn: ((args: {
    dialogId: DialogID;
    mainDialogId: DialogID;
    status: DialogStatusKind;
    reason: string;
    error: Error;
}) => Promise<void> | void) | null): void;
export declare function setFinalizeDialogQuarantineHook(fn: ((args: {
    dialogId: DialogID;
    mainDialogId: DialogID;
    status: DialogStatusKind;
    reason: string;
    error: Error;
    quarantined: boolean;
}) => Promise<void> | void) | null): void;
export interface DialogPersistenceState {
    metadata: DialogMetadataFile;
    currentCourse: number;
    messages: ChatMessage[];
    reminders: Reminder[];
    contextHealth?: ContextHealthSnapshot;
}
export interface Questions4Human {
    course: number;
    questions: HumanQuestion[];
    createdAt: string;
    updatedAt: string;
}
/**
 * Uses append-only pattern for events, exceptional overwrite for reminders
 */
export declare class DiskFileDialogStore extends DialogStore {
    private readonly dialogId;
    constructor(dialogId: DialogID);
    /**
     * Create sideDialog with automatic persistence
     */
    createSideDialog(askerDialog: Dialog, targetAgentId: string, mentionList: string[] | undefined, tellaskContent: string, options: {
        callName: 'tellask' | 'tellaskSessionless' | 'freshBootsReasoning';
        originMemberId: string;
        askerDialogId: string;
        callId: string;
        callSiteCourse: CallSiteCourseNo;
        callSiteGenseq: CallSiteGenseqNo;
        sessionSlug?: string;
        collectiveTargets?: string[];
        effectiveFbrEffort?: number;
    }): Promise<SideDialog>;
    /**
     * Receive and handle function call results (includes logging)
     */
    receiveFuncResult(dialog: Dialog, funcResult: FuncResultMsg): Promise<void>;
    receiveTellaskResult(dialog: Dialog, result: TellaskResultMsg): Promise<void>;
    receiveTellaskCarryover(dialog: Dialog, result: TellaskCarryoverMsg): Promise<void>;
    /**
     * Ensure sideDialog directory exists (delegate to DialogPersistence)
     */
    private ensureSideDialogDirectory;
    private raiseDuplicateCallInvariantViolation;
    private raiseDuplicateCallResultInvariantViolation;
    /**
     * Append event to course JSONL file (delegate to DialogPersistence)
     */
    private appendEvent;
    private appendEvents;
    /**
     * Notify start of LLM generation for frontend bubble management
     * CRITICAL: This must be called BEFORE any substream events (thinking_start, markdown_start, etc.)
     * to ensure proper event ordering on the frontend.
     */
    notifyGeneratingStart(dialog: Dialog, msgId?: string): Promise<readonly DialogNextStepTrigger[]>;
    /**
     * Notify end of LLM generation for frontend bubble management
     */
    notifyGeneratingFinish(dialog: Dialog, contextHealth?: ContextHealthSnapshot, llmGenModel?: string): Promise<void>;
    private sayingContent;
    private thinkingContent;
    private thinkingReasoning;
    private thinkingStarted;
    sayingStart(dialog: Dialog): Promise<void>;
    sayingChunk(dialog: Dialog, chunk: string): Promise<void>;
    sayingFinish(dialog: Dialog): Promise<void>;
    thinkingStart(dialog: Dialog): Promise<void>;
    thinkingChunk(dialog: Dialog, chunk: string): Promise<void>;
    thinkingFinish(dialog: Dialog, reasoning?: ReasoningPayload, provider_data?: ProviderData): Promise<void>;
    markdownStart(dialog: Dialog): Promise<void>;
    markdownChunk(dialog: Dialog, chunk: string): Promise<void>;
    markdownFinish(dialog: Dialog): Promise<void>;
    callingStart(dialog: Dialog, payload: {
        callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'askHuman' | 'freshBootsReasoning';
        callId: string;
        mentionList?: string[];
        sessionSlug?: string;
        tellaskContent: string;
    }): Promise<void>;
    webSearchCall(dialog: Dialog, payload: {
        source?: WebSearchCallSource;
        phase: 'added' | 'done';
        itemId: string;
        status?: string;
        action?: WebSearchCallAction;
    }): Promise<void>;
    nativeToolCall(dialog: Dialog, payload: NativeToolCallPayload): Promise<void>;
    toolResultImageIngest(dialog: Dialog, payload: ToolResultImageIngest): Promise<void>;
    userImageIngest(dialog: Dialog, payload: UserImageIngest): Promise<void>;
    /**
     * Emit stream error for current generation lifecycle (uses active genseq when present)
     */
    streamError(dialog: Dialog, error: string): Promise<void>;
    /**
     * Start new course (append-only JSONL + exceptional reminder persistence)
     */
    startNewCourse(dialog: Dialog, newCoursePrompt: DialogRuntimePrompt): Promise<void>;
    persistPendingRuntimePrompt(dialog: Dialog, prompt: DialogRuntimePrompt): Promise<void>;
    /**
     * Persist reminder state (exceptional overwrite pattern)
     * Note: Event emission is handled by processReminderUpdates() in Dialog
     */
    persistReminders(dialog: Dialog, reminders: Reminder[]): Promise<void>;
    /**
     * Persist a user message to storage
     * Note: The end_of_user_saying_evt is emitted by the driver after user content
     * is rendered and any tellask calls are parsed/executed.
     */
    persistUserMessage(dialog: Dialog, content: string, msgId: string, grammar: 'markdown', origin: 'user' | 'diligence_push' | 'runtime' | undefined, userLanguageCode?: LanguageCode, q4hAnswerCallId?: string, tellaskReplyDirective?: TellaskReplyDirective, contentItems?: HumanTextRecord['contentItems']): Promise<void>;
    appendTellaskReplyResolution(dialog: Dialog, payload: {
        callId: string;
        replyCallName: 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack';
        targetCallId: string;
    }): Promise<void>;
    /**
     * Persist an assistant message to storage
     */
    persistAgentMessage(dialog: Dialog, content: string, genseq: number, type: 'thinking_msg' | 'saying_msg', provider_data?: ProviderData, reasoning?: ReasoningPayload): Promise<void>;
    persistUiOnlyMarkdown(dialog: Dialog, content: string, genseq: number): Promise<void>;
    persistRuntimeGuide(dialog: Dialog, content: string, genseq: number): Promise<void>;
    /**
     * Persist a function call to storage
     */
    persistFunctionCall(dialog: Dialog, id: string, name: string, rawArgumentsText: string, genseq: number, rawId?: string): Promise<void>;
    persistTellaskCall(dialog: Dialog, id: string, name: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'replyTellask' | 'replyTellaskSessionless' | 'replyTellaskBack' | 'askHuman' | 'answerHuman' | 'freshBootsReasoning', rawArgumentsText: string, genseq: number, options?: {
        deliveryMode?: 'tellask_call_start' | 'func_call_requested';
        replyDirective?: TellaskReplyDirective;
    }): Promise<void>;
    /**
     * Update questions for human state (exceptional overwrite pattern)
     */
    updateQuestions4Human(dialog: Dialog, questions: HumanQuestion[]): Promise<void>;
    /**
     * Load Questions for Human state from storage
     */
    loadQuestions4Human(dialogId: DialogID, status: DialogStatusKind): Promise<HumanQuestion[]>;
    loadDialogLatest(dialogId: DialogID, status: DialogStatusKind): Promise<DialogLatestFile | null>;
    loadDialogMetadata(dialogId: DialogID, status: DialogStatusKind): Promise<DialogMetadataFile | null>;
    loadSideDialogAssignmentFromAsker(dialogId: DialogID, status: DialogStatusKind): Promise<SideDialogAssignmentFromAsker | null>;
    loadActiveCalleeDispatches(mainDialogId: DialogID, status: DialogStatusKind): Promise<ActiveCalleeDispatch[]>;
    loadActiveCallees(dialogId: DialogID, status: DialogStatusKind): Promise<ActiveCalleesFile>;
    saveSideDialogRegistry(dialog: MainDialog, mainDialogId: DialogID, entries: Array<{
        key: string;
        sideDialogId: DialogID;
        agentId: string;
        sessionSlug?: string;
    }>, status: DialogStatusKind): Promise<void>;
    loadSideDialogRegistry(mainDialog: MainDialog, status: DialogStatusKind): Promise<void>;
    /**
     * Clear Questions for Human state in storage
     */
    clearQuestions4Human(dialog: Dialog): Promise<void>;
    /**
     * Get current questions for human count for UI decoration
     */
    getQuestions4HumanCount(): Promise<number>;
    /**
     * Load current course number from persisted metadata
     */
    loadCurrentCourse(dialogId: DialogID): Promise<number>;
    /**
     * Get next sequence number for generation
     */
    getNextSeq(dialogId: DialogID, course: number): Promise<number>;
    /**
     * Send dialog events directly to a specific WebSocket connection for dialog restoration
     * CRITICAL: This bypasses PubChan to ensure only the requesting session receives restoration events
     * Unlike replayDialogEvents(), this sends events directly to ws.send() instead of postDialogEvent()
     * @param ws - WebSocket connection to send events to
     * @param dialog - Dialog object containing metadata
     * @param course - Optional course number (uses dialog.currentCourse if not provided)
     * @param totalCourses - Optional total courses count (defaults to course/currentCourse)
     */
    sendDialogEventsDirectly(ws: WebSocket, dialog: Dialog, course?: number, totalCourses?: number, status?: DialogStatusKind, options?: {
        showPrimingEventsInUi?: boolean;
    }): Promise<void>;
    /**
     * Send a single persistence event directly to a WebSocket connection
     * CRITICAL: Avoid PubChan completely for dialog restoration to the single client's display_dialog request
     */
    private sendEventDirectlyToWebSocket;
    /**
     * Create optimal text chunks for websocket transmission
     * Splits content into 1MB pieces for efficient websocket streaming
     */
    private createOptimalChunks;
}
type Q4HMutation = {
    kind: 'noop';
} | {
    kind: 'append';
    question: HumanQuestion;
} | {
    kind: 'remove';
    questionId: string;
} | {
    kind: 'replace';
    questions: HumanQuestion[];
} | {
    kind: 'clear';
};
type Q4HMutateOutcome = {
    previousQuestions: HumanQuestion[];
    questions: HumanQuestion[];
    removedQuestion?: HumanQuestion;
};
type A2HMutation = {
    kind: 'noop';
} | {
    kind: 'append';
    answer: AnswerToHumanItem;
} | {
    kind: 'remove';
    answerId: string;
} | {
    kind: 'replace';
    answers: AnswerToHumanItem[];
} | {
    kind: 'clear';
};
type A2HMutateOutcome = {
    previousAnswers: AnswerToHumanItem[];
    answers: AnswerToHumanItem[];
    removedAnswer?: AnswerToHumanItem;
};
type ActiveCalleeResolveOutcome = Readonly<{
    batchId: string;
    callSiteCourse: CallSiteCourseNo;
    callSiteGenseq: CallSiteGenseqNo;
    batchCompleted: boolean;
    resolvedCallIds: readonly string[];
}>;
type DialogLatestPatch = Partial<Omit<DialogLatestFile, 'currentCourse' | 'lastModified'>> & {
    currentCourse?: number;
    lastModified?: string;
};
type DialogLatestMutation = {
    kind: 'noop';
} | {
    kind: 'patch';
    patch: DialogLatestPatch;
} | {
    kind: 'replace';
    next: DialogLatestFile;
};
type DialogWakeQueueEntry = Readonly<{
    entryId: string;
    kind: 'root_runtime_wake';
    targetDialogId: string;
    reason: string;
} | {
    entryId: string;
    kind: 'requested_work_reply_arrived';
    targetDialogId: string;
    batchId: string;
} | {
    entryId: string;
    kind: 'reply_delivery_recovery';
    targetDialogId: string;
    replyDeliveryId: string;
} | {
    entryId: string;
    kind: 'open_generation_recovery';
    targetDialogId: string;
    course: DialogCourseNumber;
    genseq: CallSiteGenseqNo;
} | {
    entryId: string;
    kind: 'pending_runtime_prompt';
    targetDialogId: string;
    msgId: string;
} | {
    entryId: string;
    kind: 'tool_followup';
    targetDialogId: string;
    triggerId: string;
} | {
    entryId: string;
    kind: 'next_step_trigger';
    targetDialogId: string;
    triggerId: string;
    triggerKind: DialogNextStepTrigger['kind'];
}>;
export type BackendDriveStallWrite = Readonly<{
    dialogId: string;
    rootId: string;
    selfId: string;
    status: DialogStatusKind;
    reason: 'backend_drive_error';
    durableWorkFingerprint: string;
    latestSummary: Record<string, unknown> | null;
    error: {
        name?: string;
        message: string;
        stack?: string;
    };
    context: {
        rootHasPendingNextStepTriggers: boolean;
        wakeQueueEntryCount: number;
    };
}>;
export type BackendDriveStallRecord = BackendDriveStallWrite & Readonly<{
    recordId: string;
    recordedAt: string;
}>;
type MainDialogWriteBackCancellationToken = Readonly<{
    scopeKey: string;
    generation: number;
    mainDialogId: string;
    status: DialogStatusKind;
}>;
/**
 * Utility class for managing dialog persistence
 */
export declare class DialogPersistence {
    private static readonly DIALOGS_DIR;
    private static readonly MALFORMED_DIR;
    private static readonly RUN_DIR;
    private static readonly DONE_DIR;
    private static readonly ARCHIVE_DIR;
    private static readonly SIDE_DIALOGS_DIR;
    private static isSideDialogsDirectoryName;
    private static readonly quarantinedMainDialogScopes;
    private static readonly LATEST_WRITEBACK_WINDOW_MS;
    private static readonly Q4H_WRITEBACK_WINDOW_MS;
    private static readonly A2H_WRITEBACK_WINDOW_MS;
    private static readonly latestWriteBackMutexes;
    private static readonly latestWriteBack;
    private static readonly q4hWriteBackMutexes;
    private static readonly q4hWriteBack;
    private static readonly a2hWriteBackMutexes;
    private static readonly a2hWriteBack;
    private static readonly activeCalleesMutexes;
    private static readonly wakeQueueMutexes;
    private static readonly backendDriveStallMutexes;
    private static readonly courseAppendMutexes;
    private static readonly mainDialogWriteBackCancelGenerations;
    private static getLatestWriteBackMutex;
    private static getQ4HWriteBackMutex;
    private static getA2HWriteBackMutex;
    private static getCourseAppendMutex;
    private static getCourseAppendMutexKey;
    private static getActiveCalleesMutex;
    private static getWakeQueueMutex;
    private static getBackendDriveStallMutex;
    private static getLatestWriteBackKey;
    private static getWakeQueueKey;
    private static getBackendDriveStallKey;
    private static getQ4HWriteBackKey;
    private static getA2HWriteBackKey;
    private static getActiveCalleesKey;
    private static getMainDialogWriteBackCancelScopeKey;
    private static createMainDialogWriteBackCancellationToken;
    private static assertMainDialogWriteBackNotCanceled;
    private static rethrowWriteBackPathMissingAsCanceled;
    private static cancelMainDialogWriteBacks;
    private static getDialogMetadataPath;
    private static getDialogAskerStackPath;
    private static assertDialogMetadataExistsForAppend;
    private static cleanupCanceledAppendPlaceholder;
    private static cloneActiveCalleeDispatchRecords;
    private static cloneQuestions4Human;
    private static cloneRegistryEntries;
    private static cloneSideDialogResponses;
    static appendRemindersReconciledRecord(dialogId: DialogID, reminders: readonly Reminder[], writeTarget: ReconciledRecordWriteTarget, status: DialogStatusKind): Promise<void>;
    static appendQuestions4HumanReconciledRecord(dialogId: DialogID, questions: readonly HumanQuestion[], writeTarget: ReconciledRecordWriteTarget, status: DialogStatusKind): Promise<void>;
    static appendActiveCalleesReconciledRecord(dialogId: DialogID, activeCalleeDispatches: readonly ActiveCalleeDispatchRecord[], writeTarget: ReconciledRecordWriteTarget, status: DialogStatusKind): Promise<void>;
    static appendSideDialogRegistryReconciledRecord(dialogId: DialogID, entries: readonly SideDialogRegistryStateRecord[], writeTarget: ReconciledRecordWriteTarget, status: DialogStatusKind): Promise<void>;
    static appendSideDialogResponsesReconciledRecord(dialogId: DialogID, responses: readonly SideDialogResponseStateRecord[], writeTarget: ReconciledRecordWriteTarget, status: DialogStatusKind): Promise<void>;
    /**
     * Get the base dialogs directory path
     */
    static getDialogsRootDir(): string;
    /**
     * Get the full path for a dialog directory
     */
    static getMainDialogPath(dialogId: DialogID, status?: DialogStatusKind): string;
    /**
     * Get the events/state directory for a dialog (composite ID for sideDialogs)
     */
    static getDialogEventsPath(dialogId: DialogID, status?: DialogStatusKind): string;
    /**
     * Get the path for a sideDialog within an askerDialog
     */
    static getSideDialogPath(dialogId: DialogID, status?: DialogStatusKind): string;
    private static getMalformedMainDialogPath;
    private static inferMainDialogIdFromMetadataRelativeDir;
    private static inferExpectedDialogIdFromMetadataRelativeDir;
    private static listSideDialogIdsUnderRoot;
    private static pathExists;
    private static clearLatestWriteBackState;
    private static clearWriteBackEntriesForMainDialog;
    private static quarantineMalformedDialog;
    static quarantineMalformedRuntimeState(dialogId: DialogID, status: DialogStatusKind, reason: string, detail: string): Promise<void>;
    private static rethrowAfterQuarantiningDialogPersistenceProblem;
    private static parseDialogLatestYaml;
    /**
     * Ensure dialog directory structure exists
     */
    static ensureMainDialogDirectory(dialogId: DialogID, status?: DialogStatusKind): Promise<string>;
    /**
     * Ensure sideDialog directory structure exists
     */
    static ensureSideDialogDirectory(dialogId: DialogID, status?: DialogStatusKind): Promise<string>;
    /**
     * Mark a dialog as completed
     */
    static markDialogCompleted(dialogId: DialogID): Promise<void>;
    /**
     * List candidate main dialog IDs by scanning `dialog.yaml`.
     *
     * This scanner intentionally stays lightweight: it only validates the path<->id identity needed
     * for safe enumeration, and leaves full metadata shape validation to the subsequent lazy-load
     * step. Callers iterating these candidate IDs must therefore tolerate per-dialog load failures
     * and continue after a malformed dialog is quarantined.
     */
    static listDialogs(status?: DialogStatusKind): Promise<string[]>;
    static listMainDialogIds(status?: DialogStatusKind): Promise<DialogID[]>;
    /**
     * List all dialog IDs (main dialogs + sideDialogs) together with their root IDs.
     * This is the only safe way to enumerate sideDialogs because their directory names
     * are not guaranteed to be their selfId.
     *
     * Like `listDialogs()`, this is a candidate scanner rather than a full metadata validator.
     * Callers must treat later metadata/latest loads as lazy, per-dialog operations that can still
     * quarantine one dialog without invalidating the rest of the enumeration.
     */
    static listAllDialogIds(status?: DialogStatusKind): Promise<DialogID[]>;
    /**
     * Append event to course JSONL file (append-only pattern)
     */
    static appendEvents(dialogId: DialogID, course: number, events: readonly PersistedDialogRecord[], status?: DialogStatusKind): Promise<void>;
    static appendEvent(dialogId: DialogID, course: number, event: PersistedDialogRecord, status?: DialogStatusKind): Promise<void>;
    static persistRuntimeGuide(dialog: Dialog, content: string, genseq: number): Promise<void>;
    /**
     * Capture the current byte offset of a course JSONL file.
     * Used as rollback checkpoint before a streaming LLM attempt.
     */
    static captureCourseFileOffset(dialogId: DialogID, course: number, status?: DialogStatusKind): Promise<number>;
    /**
     * Rollback a course JSONL file to a previously captured byte offset.
     * This is used to discard partial streaming artifacts before retrying.
     */
    static rollbackCourseFileToOffset(dialogId: DialogID, course: number, offset: number, status?: DialogStatusKind): Promise<void>;
    /**
     * Read all events from course JSONL file
     */
    static readCourseEvents(dialogId: DialogID, course: number, status?: DialogStatusKind): Promise<PersistedDialogRecord[]>;
    /**
     * Compute next sequence number for a course by scanning existing events
     */
    static getNextSeq(dialogId: DialogID, course: number, status?: DialogStatusKind): Promise<number>;
    /**
     * Get current course number from latest.yaml (performance optimization)
     * UI navigation can assume natural numbering schema back to 1
     */
    static getCurrentCourseNumber(dialogId: DialogID, status?: DialogStatusKind): Promise<number>;
    /**
     * Save reminder state (exceptional overwrite pattern) (internal use only)
     */
    static _saveReminderState(dialogId: DialogID, reminders: Reminder[], status?: DialogStatusKind): Promise<void>;
    /**
     * Load reminder state
     */
    static loadReminderState(dialogId: DialogID, status?: DialogStatusKind): Promise<Reminder[]>;
    /**
     * Save questions for human state (exceptional overwrite pattern) (internal use only)
     */
    static _saveQuestions4HumanState(dialogId: DialogID, questions: HumanQuestion[], status?: DialogStatusKind): Promise<void>;
    static syncUserWaitFromQuestions4HumanState(dialogId: DialogID, questions: readonly HumanQuestion[], status?: DialogStatusKind): Promise<void>;
    /**
     * Load questions for human state
     */
    static loadQuestions4HumanState(dialogId: DialogID, status?: DialogStatusKind): Promise<HumanQuestion[]>;
    private static loadQuestions4HumanStateFromDisk;
    static mutateQuestions4HumanState(dialogId: DialogID, mutator: (previous: HumanQuestion[]) => Q4HMutation, status?: DialogStatusKind): Promise<Q4HMutateOutcome>;
    static appendQuestion4HumanState(dialogId: DialogID, question: HumanQuestion, status?: DialogStatusKind): Promise<void>;
    static removeQuestion4HumanState(dialogId: DialogID, questionId: string, status?: DialogStatusKind): Promise<{
        found: boolean;
        remainingQuestions: HumanQuestion[];
        removedQuestion?: HumanQuestion;
    }>;
    static loadAnswersToHumanState(dialogId: DialogID, status?: DialogStatusKind): Promise<AnswerToHumanItem[]>;
    private static loadAnswersToHumanStateFromDisk;
    static mutateAnswersToHumanState(dialogId: DialogID, mutator: (previous: AnswerToHumanItem[]) => A2HMutation, status?: DialogStatusKind): Promise<A2HMutateOutcome>;
    static appendAnswerToHumanState(dialogId: DialogID, answer: AnswerToHumanItem, status?: DialogStatusKind): Promise<void>;
    static acknowledgeAnswerToHumanState(dialogId: DialogID, answerId: string, status?: DialogStatusKind): Promise<{
        found: boolean;
        remainingAnswers: AnswerToHumanItem[];
        removedAnswer?: AnswerToHumanItem;
    }>;
    private static flushQ4HWriteBack;
    private static writeQ4HStateToDisk;
    private static flushA2HWriteBack;
    private static writeA2HStateToDisk;
    /**
     * Load all Q4H questions from all running dialogs (for global Q4H display)
     * Returns array of questions with their dialog context for frontend display
     */
    static loadAllQ4HState(): Promise<Array<{
        id: string;
        selfId: string;
        rootId: string;
        agentId: string;
        taskDocPath: string;
        tellaskContent: string;
        askedAt: string;
        callId: string;
        callSiteRef: {
            course: number;
            messageIndex: number;
        };
    }>>;
    static loadAllA2HState(): Promise<Array<AnswerToHumanItem & {
        selfId: string;
        rootId: string;
        agentId: string;
        taskDocPath: string;
    }>>;
    static clearQuestions4HumanState(dialogId: DialogID, status?: DialogStatusKind): Promise<void>;
    /**
     * Load active callee dispatches projected from active-callees.json.
     */
    static loadActiveCalleeDispatches(mainDialogId: DialogID, status?: DialogStatusKind): Promise<ActiveCalleeDispatchRecord[]>;
    private static activeCalleeDispatchCalleeDialogId;
    private static buildActiveCalleeRecordFromDispatch;
    private static isActiveCalleeCompletion;
    private static isActiveCalleeRecord;
    private static isActiveCalleeBatch;
    private static isActiveCalleesFile;
    private static assertNoDuplicateSessionedTellaskPendingRecords;
    private static loadActiveCalleeDispatchesFromDisk;
    private static projectActiveCalleeDispatches;
    private static buildActiveCalleesFileFromDispatches;
    static appendActiveCalleeDispatch(mainDialogId: DialogID, record: ActiveCalleeDispatchRecord, rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    static saveActiveCalleeDispatches(mainDialogId: DialogID, dispatches: ActiveCalleeDispatchRecord[], rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    static mutateActiveCalleeDispatches(mainDialogId: DialogID, mutator: (previous: ActiveCalleeDispatchRecord[]) => ActiveCalleeDispatchRecord[], rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<ActiveCalleeDispatchRecord[]>;
    static removeActiveCalleeDispatch(mainDialogId: DialogID, calleeDialogId: string, callId: string, rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    static clearActiveCalleeDispatches(mainDialogId: DialogID, rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    private static loadActiveCalleesFromDisk;
    static loadActiveCallees(dialogId: DialogID, status?: DialogStatusKind): Promise<ActiveCalleesFile>;
    private static writeActiveCalleesToDisk;
    private static getWakeQueueFilePath;
    private static isWakeQueueEntry;
    private static normalizeWakeQueueEntry;
    private static normalizeWakeQueueFile;
    private static buildWakeQueueEntriesForLatest;
    private static loadWakeQueueFromDisk;
    private static writeWakeQueueToDisk;
    private static getBackendDriveStallJsonlPath;
    static buildBackendDriveDurableWorkFingerprint(latest: DialogLatestFile | null, wakeQueueEntries?: readonly DialogWakeQueueEntry[]): string;
    static appendBackendDriveStallRecord(dialogId: DialogID, write: BackendDriveStallWrite, status?: DialogStatusKind): Promise<BackendDriveStallRecord>;
    private static mutateWakeQueue;
    private static removeWithRetry;
    static loadWakeQueueEntries(rootDialogId: DialogID, status?: DialogStatusKind): Promise<readonly DialogWakeQueueEntry[]>;
    static loadWakeQueueTargetDialogIds(rootDialogId: DialogID, status?: DialogStatusKind): Promise<readonly DialogID[]>;
    private static replaceWakeQueueEntriesForDialog;
    static syncWakeQueueForDialogLatest(dialogId: DialogID, latest: DialogLatestFile, status?: DialogStatusKind): Promise<void>;
    static removeWakeQueueEntriesForDialog(dialogId: DialogID, status?: DialogStatusKind): Promise<void>;
    static mutateActiveCallees(dialogId: DialogID, mutator: (previous: ActiveCalleesFile) => ActiveCalleesFile, status?: DialogStatusKind): Promise<ActiveCalleesFile>;
    static upsertActiveCalleeFromPendingRecord(dialogId: DialogID, record: ActiveCalleeDispatchRecord, status?: DialogStatusKind): Promise<void>;
    static resolveActiveCallee(dialogId: DialogID, args: Readonly<{
        batchId: string;
        callId: string;
        sideDialogId: string;
        deliveryMode: 'reply_tool' | 'direct_fallback';
        directFallbackSource?: 'saying' | 'thinking_only';
    }>, status?: DialogStatusKind): Promise<ActiveCalleeResolveOutcome>;
    static removeActiveCalleeBatch(dialogId: DialogID, batchId: string, status?: DialogStatusKind): Promise<void>;
    /**
     * Get the path for storing sideDialog responses (supports both main dialog and sideDialog tellaskers).
     * For Type C sideDialogs created inside another sideDialog, responses are stored at the parent's level.
     */
    static getDialogResponsesPath(dialogId: DialogID, status?: DialogStatusKind): string;
    /**
     * Save responses delivered back from completed sideDialogs.
     */
    static saveSideDialogResponses(mainDialogId: DialogID, responses: SideDialogResponseStateRecord[], rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    /**
     * Load responses delivered back from completed sideDialogs.
     */
    static loadSideDialogResponses(mainDialogId: DialogID, status?: DialogStatusKind): Promise<SideDialogResponseStateRecord[]>;
    static loadSideDialogResponsesQueue(dialogId: DialogID, status?: DialogStatusKind): Promise<SideDialogResponseStateRecord[]>;
    static appendSideDialogResponse(dialogId: DialogID, response: SideDialogResponseStateRecord, rootAnchor?: RootGenerationAnchor, status?: DialogStatusKind): Promise<void>;
    static takeSideDialogResponses(dialogId: DialogID, status?: DialogStatusKind): Promise<Array<{
        responseId: string;
        sideDialogId: string;
        response: string;
        completedAt: string;
        status?: 'completed' | 'failed';
        callType: 'A' | 'B' | 'C';
        callName: 'tellaskBack' | 'tellask' | 'tellaskSessionless' | 'freshBootsReasoning';
        mentionList?: string[];
        tellaskContent: string;
        responderId: string;
        originMemberId: string;
        callId: string;
    }>>;
    static commitTakenSideDialogResponses(dialogId: DialogID, status?: DialogStatusKind): Promise<void>;
    static rollbackTakenSideDialogResponses(dialogId: DialogID, status?: DialogStatusKind): Promise<void>;
    /**
     * Save main dialog metadata (write-once pattern)
     */
    static saveMainDialogMetadata(dialogId: DialogID, metadata: MainDialogMetadataFile, status?: DialogStatusKind): Promise<void>;
    /**
     * Save dialog metadata (universal - works with any DialogID)
     */
    static saveDialogMetadata(dialogId: DialogID, metadata: DialogMetadataFile, status?: DialogStatusKind): Promise<void>;
    /**
     * Save sideDialog metadata under the root dialog's sideDialogs directory.
     */
    static saveSideDialogMetadata(dialogId: DialogID, metadata: SideDialogMetadataFile, status?: DialogStatusKind): Promise<void>;
    static saveSideDialogAskerStackState(dialogId: DialogID, state: DialogAskerStackState, status?: DialogStatusKind): Promise<void>;
    static loadSideDialogAskerStackState(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogAskerStackState | null>;
    static loadSideDialogAssignmentFromAsker(dialogId: DialogID, status?: DialogStatusKind): Promise<SideDialogAssignmentFromAsker>;
    private static parseDialogAskerStackJsonlRows;
    private static appendDialogAskerStackFrames;
    static saveDialogAskerStack(dialogId: DialogID, state: DialogAskerStackState, status?: DialogStatusKind): Promise<void>;
    static loadDialogAskerStack(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogAskerStackState>;
    private static loadDialogAskerStackRows;
    private static truncateDialogAskerStackToDepth;
    private static replaceDialogAskerStackFrameAndAppend;
    static pushTellaskReplyObligation(dialogId: DialogID, obligation: TellaskReplyDirective, status?: DialogStatusKind): Promise<void>;
    static setActiveTellaskReplyObligation(dialogId: DialogID, obligation: TellaskReplyDirective | undefined, status?: DialogStatusKind): Promise<void>;
    static loadActiveTellaskReplyObligation(dialogId: DialogID, status?: DialogStatusKind): Promise<TellaskReplyDirective | undefined>;
    static markReplyDeliveryDelivered(dialogId: DialogID, replyCallId: string, deliveredAt: string, status?: DialogStatusKind): Promise<void>;
    static markReplyDeliveryToolResultRecorded(dialogId: DialogID, replyCallId: string, status?: DialogStatusKind): Promise<void>;
    static clearPendingReplyDeliveryForCall(dialogId: DialogID, replyCallId: string, status?: DialogStatusKind): Promise<void>;
    static lookupRecordedTellaskCall(dialogId: DialogID, callId: string, status?: DialogStatusKind): Promise<DialogTellaskCallState['calls'][number] | undefined>;
    static recordTellaskCall(dialogId: DialogID, record: TellaskCallRecord, course: number, status?: DialogStatusKind): Promise<void>;
    static hasRecordedTellaskResult(dialogId: DialogID, callId: string, status?: DialogStatusKind): Promise<boolean>;
    static recordTellaskResult(dialogId: DialogID, record: TellaskResultRecord, course: number, status?: DialogStatusKind): Promise<void>;
    private static requireSideDialogAskerStackState;
    /**
     * Update assignmentFromAsker for an existing sideDialog.
     */
    static updateSideDialogAssignment(dialogId: DialogID, assignment: SideDialogAssignmentFromAsker, status?: DialogStatusKind, options?: Readonly<{
        replacePendingCallId?: string;
        replacePendingAskerDialogId?: string;
    }>): Promise<void>;
    /**
     * Load main dialog metadata
     */
    static loadMainDialogMetadata(dialogId: DialogID, status?: DialogStatusKind): Promise<MainDialogMetadataFile | null>;
    /**
     * Load dialog metadata from the path implied by the DialogID.
     */
    static loadDialogMetadata(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogMetadataFile | null>;
    /**
     * Save latest.yaml with current course and lastModified info
     */
    private static writeDialogLatestToDisk;
    /**
     * Rename with retry logic to handle filesystem sync issues
     */
    private static renameWithRetry;
    /**
     * Load latest.yaml for current course and lastModified info
     */
    static loadDialogLatest(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogLatestFile | null>;
    /**
     * Delta-only latest.yaml update API.
     *
     * Callers provide a mutation callback which is applied against the most recent
     * staged state (or disk fallback). This avoids read-modify-write races in user code
     * and allows lock-free-ish coalescing to disk via the write-back buffer.
     */
    static mutateDialogLatest(dialogId: DialogID, mutator: (previous: DialogLatestFile) => DialogLatestMutation, status?: DialogStatusKind, cancellationToken?: MainDialogWriteBackCancellationToken): Promise<DialogLatestFile>;
    private static loadDialogLatestFromDisk;
    private static flushLatestWriteBack;
    static upsertRootRuntimeWake(dialogId: DialogID, reason: string, status?: DialogStatusKind): Promise<void>;
    static removeRootRuntimeWake(dialogId: DialogID, status?: DialogStatusKind): Promise<void>;
    static hasRootRuntimeWake(dialogId: DialogID, status?: DialogStatusKind): Promise<boolean>;
    static upsertNextStepTrigger(dialogId: DialogID, trigger: DialogNextStepTriggerDraft, status?: DialogStatusKind): Promise<void>;
    static removeNextStepTriggers(dialogId: DialogID, predicate: (trigger: DialogNextStepTrigger) => boolean, status?: DialogStatusKind): Promise<void>;
    static hasPendingNextStepTriggers(dialogId: DialogID, status?: DialogStatusKind): Promise<boolean>;
    static clearPendingRuntimePrompt(dialogId: DialogID, msgId: string, status?: DialogStatusKind): Promise<void>;
    /**
     * Get course filename from course number
     */
    static getCourseFilename(course: number): string;
    /**
     * Extract course number from filename
     */
    static getCourseFromFilename(filename: string): number;
    /**
     * Get dialog status from file system path
     */
    static getStatusFromPath(dialogPath: string): DialogStatusKind;
    static loadQuestions4Human(dialogId: DialogID, course: number, status?: DialogStatusKind): Promise<Questions4Human | null>;
    /**
     * Count sideDialogs under a main dialog (no single-layer listing exposed)
     */
    static countAllSideDialogsUnderRoot(mainDialogId: DialogID, status?: DialogStatusKind): Promise<number>;
    /**
     * Restore complete dialog tree from disk
     */
    static restoreDialogTree(mainDialogId: DialogID, status?: DialogStatusKind): Promise<DialogPersistenceState | null>;
    /**
     * Restore dialog from disk using JSONL events (optimized: only latest course loaded).
     * Historical-course ask/tellask context that still matters to the current round must already be
     * represented via latest-course carryover records; older courses themselves are not reloaded into
     * LLM context during restore. For historical courses, use loadCourseEvents() on-demand for UI
     * navigation.
     */
    static restoreDialog(dialogId: DialogID, status?: DialogStatusKind): Promise<DialogPersistenceState | null>;
    /**
     * Load specific course events for UI navigation (on-demand)
     */
    static loadCourseEvents(dialogId: DialogID, course: number, status?: DialogStatusKind): Promise<PersistedDialogRecord[]>;
    static resolvePendingUserInterjectionReplyFromCourseEvents(events: readonly PersistedDialogRecord[], course: number): DialogLatestFile['pendingUserInterjectionReply'];
    static resolveAnsweredUserInterjectionA2HFromCourseEvents(args: {
        dialogId: DialogID;
        events: readonly PersistedDialogRecord[];
        course: number;
        pending: DialogLatestFile['pendingUserInterjectionReply'];
    }): AnswerToHumanItem | undefined;
    private static answerRefSettlesPendingUserInterjection;
    private static normalizeDialogLatestPendingUserInterjectionReply;
    /**
     * Reconstruct dialog state from JSONL events (optimized: only latest course needed).
     */
    static rebuildFromEvents(events: PersistedDialogRecord[], metadata: DialogMetadataFile, reminders: Reminder[], currentCourse: number): Promise<DialogPersistenceState>;
    /**
     * Move dialog between status directories (run/done/archive)
     */
    static moveDialogStatus(dialogId: DialogID, fromStatus: DialogStatusKind, toStatus: DialogStatusKind): Promise<void>;
    /**
     * Delete a main dialog directory (including sideDialogs) from disk.
     * Caller must provide the source status explicitly.
     */
    static deleteMainDialog(mainDialogId: DialogID, fromStatus: DialogStatusKind): Promise<boolean>;
    /**
     * Save sideDialog registry (TYPE B entries).
     */
    static saveSideDialogRegistry(mainDialogId: DialogID, entries: Array<{
        key: string;
        sideDialogId: DialogID;
        agentId: string;
        sessionSlug?: string;
    }>, status?: DialogStatusKind): Promise<void>;
    /**
     * Load sideDialog registry.
     */
    static loadSideDialogRegistry(mainDialogId: DialogID, status?: DialogStatusKind): Promise<Array<{
        key: string;
        sideDialogId: DialogID;
        agentId: string;
        sessionSlug?: string;
    }>>;
}
export {};
