import type { MessengerAdapter, MessageContext, ButtonCallback, ApprovalCardPrompt, ApprovalCardOutcome, ChoiceCardPrompt } from '../../../core/types.js';
export declare class TelegramAdapter implements MessengerAdapter {
    readonly name = "telegram";
    private bot;
    private config;
    private messageHandler?;
    private buttonHandler?;
    private isRunning;
    private typingIntervals;
    private watchdogTimer?;
    private consecutivePingFailures;
    private static readonly WATCHDOG_INTERVAL_MS;
    private static readonly WATCHDOG_FAILURE_THRESHOLD;
    private mediaCleanupTimer?;
    private static readonly MEDIA_CLEANUP_INTERVAL_MS;
    start(): Promise<void>;
    /** Run media cleanup once now (so a long-running agim doesn't accumulate
     *  files indefinitely when restarts are infrequent) and then hourly. The
     *  hourly cadence matches the typical 7-day TTL with plenty of slack. */
    private startMediaCleanup;
    private runPollingLoop;
    private startWatchdog;
    stop(): Promise<void>;
    onMessage(handler: (ctx: MessageContext) => Promise<void>): void;
    /**
     * Download a TG photo / image-document, save it under MEDIA_ROOT, and surface
     * the result to messageHandler as a Message whose `text` includes the
     * caption (if any) plus a "[图片附件：/path/x.jpg]" marker — claude-code
     * picks that up and uses Read to view it.
     *
     * On download failure we still call messageHandler with a "[图片下载失败]"
     * marker so the user's interaction isn't silently dropped — they can resend
     * or be told what went wrong.
     */
    private handleMediaUpload;
    /**
     * Download a TG voice / audio message, transcribe it via whichever provider
     * is configured (OpenAI Whisper or whisper.cpp), and surface the transcript
     * to messageHandler as Message.text. The downloaded audio file path is
     * also included so the agent can reference it (e.g. send it back, replay).
     *
     * Failures are surfaced as text markers, not silent drops:
     *   - download failure → "[语音附件下载失败：…]"
     *   - no provider configured → "[语音附件未转写：未配置 OPENAI_API_KEY 或 IMHUB_WHISPERCPP_BIN]"
     *   - transcribe error → "[语音转写失败（${provider}）：…]"
     *
     * Since transcription can take 5-30s on a slow CPU + whisper.cpp medium,
     * we fire-and-forget the entire operation so grammy's update queue keeps
     * draining for other chats. Within this chat, ordering is still serialized
     * by grammy.
     */
    private handleVoiceUpload;
    /**
     * Download an arbitrary file (PDF / Word / archive / binary) and surface
     * `[文件附件：${path} (${displayName}, ${size})]` to the agent. Same
     * download infra as media/voice; differs only in marker format and
     * filename handling — we keep the user's `file_name` (sanitised) so the
     * on-disk file stays recognisable, falling back to `${msgId}.${ext}` when
     * Telegram doesn't supply one.
     */
    private handleFileUpload;
    /**
     * Download a video / video_note / animation and surface
     * `[视频附件：${path} (${dur}s, ${size})]` to the agent. Same caveats as
     * handleFileUpload; we don't attempt frame extraction or transcription.
     */
    private handleVideoUpload;
    sendMessage(threadId: string, text: string): Promise<void>;
    onButtonCallback(handler: (cb: ButtonCallback) => Promise<void>): void;
    sendApprovalCard(threadId: string, prompt: ApprovalCardPrompt): Promise<{
        messageId: string;
    }>;
    editApprovalCard(threadId: string, messageId: string, outcome: ApprovalCardOutcome): Promise<void>;
    sendChoiceCard(threadId: string, prompt: ChoiceCardPrompt): Promise<{
        messageId: string;
    }>;
    editChoiceCard(threadId: string, messageId: string, finalText: string): Promise<void>;
    sendTyping(threadId: string, isTyping: boolean): Promise<void>;
}
export declare const telegramAdapter: TelegramAdapter;
//# sourceMappingURL=telegram-adapter.d.ts.map