/** * Opt-in rich-draft streaming for a turn's in-progress preview. * * When the operator opts in (`richDraft.enabled`) the daemon streams LIVE turn * markdown to the Bot API `sendRichMessageDraft` method as a debounced preview. * Every failure is a harmless no-op (warn once, keep the daemon alive), and when * off no draft call is ever made — so the off-state request bodies stay * byte-identical. */ import type { BotApi } from "./telegram-daemon"; import type { ThreadedSend } from "./threaded-render"; /** Minimum gap between two draft sends for one session (debounce floor). */ export declare const DRAFT_DEBOUNCE_MS = 1500; /** * Wrap raw markdown + a monotonic draft id in the `sendRichMessageDraft` request * payload shape: mirrors `buildRichMessage`'s proven `rich_message.markdown` * content wrapper, with a top-level `draft_id` selecting the draft revision to * update (a routing param, like `message_thread_id`). */ export declare function buildRichDraft(draftId: number, raw: string): { draft_id: number; rich_message: { markdown: string; }; }; /** * Whether a granted send should stream a rich draft. Fail-closed: every clause * must hold, otherwise no draft is sent. Mirrors `shouldPromoteRich` but targets * the LIVE lane and the live-only `richDraftMarkdown` marker (set by * `renderThreadedFrame` for non-finalized turn frames). */ export declare function shouldStreamDraft(input: { enabled?: boolean; send: ThreadedSend; }): boolean; /** * Per-session debounce + monotonic draft-id state for draft streaming. Skips a * draft when less than `debounceMs` has elapsed since the session's last SENT * draft (the rate-limit pool already coalesces live frames to the latest, so a * skipped frame is naturally superseded by the next one). `reset` clears a * session's window when its turn finalizes so the next turn starts fresh. */ export declare class DraftStreamState { #private; constructor(debounceMs?: number); /** * If enough time has elapsed since the session's last draft, record `now` as * the new last-sent time and return the next monotonic draft id; otherwise * return `undefined` (debounced — the caller skips this frame). */ tryClaim(sessionId: string, now: number): number | undefined; /** Clear a session's debounce window (called when its turn finalizes). The * global draft id keeps incrementing so ids are never reused across turns. */ reset(sessionId: string): void; } /** * Best-effort delivery of a rich draft. Never throws and has no HTML fallback: a * draft is a purely additive preview, so on any failure (a thrown transport * error or an `{ ok: false }` JSON response — the transport returns `res.json()` * for JSON methods, so `ok:false` does not throw) it warns exactly once and * returns; the unchanged live HTML send still carries the content. */ export declare function deliverDraft(botApi: BotApi, base: { chat_id: string | number; message_thread_id?: number; disable_notification?: true; }, draftId: number, raw: string, log?: { warn(msg: string): void; }): Promise;