import type { TemplateContext } from "../templating.js";
import type { VerboseLevel } from "../thinking.js";
import type { GetReplyOptions, ReplyPayload } from "../types.js";
import type { FollowupRun } from "./queue.js";
import type { TypingSignaler } from "./typing-mode.js";
import { runEmbeddedPiKoi } from "../../koi/pi-embedded.js";
import { type SessionEntry } from "../../config/sessions.js";
import { type BlockReplyPipeline } from "./block-reply-pipeline.js";
export type KoiRunLoopResult = {
    kind: "success";
    runResult: Awaited<ReturnType<typeof runEmbeddedPiKoi>>;
    fallbackProvider?: string;
    fallbackModel?: string;
    didLogHeartbeatStrip: boolean;
    autoCompactionCompleted: boolean;
    /** Payload keys sent directly (not via pipeline) during tool flush. */
    directlySentBlockKeys?: Set<string>;
    /** Number of tool calls made during this run (tracked via koi events). */
    heartbeatToolCallCount?: number;
} | {
    kind: "final";
    payload: ReplyPayload;
};
/**
 * Runs the koi LLM turn with automatic model fallback on context overflow
 * or compaction failure. Retries with a fresh session when necessary.
 *
 * Tracks tool-call counts for heartbeat productivity enforcement and streams
 * block replies through the pipeline when block-streaming is enabled.
 *
 * @returns Either a `"success"` result with the raw run output and metadata,
 *          or a `"final"` result with a pre-built error payload (no further processing needed).
 */
export declare function runKoiTurnWithFallback(params: {
    commandBody: string;
    followupRun: FollowupRun;
    sessionCtx: TemplateContext;
    opts?: GetReplyOptions;
    typingSignals: TypingSignaler;
    blockReplyPipeline: BlockReplyPipeline | null;
    blockStreamingEnabled: boolean;
    blockReplyChunking?: {
        minChars: number;
        maxChars: number;
        breakPreference: "paragraph" | "newline" | "sentence";
        flushOnParagraph?: boolean;
    };
    resolvedBlockStreamingBreak: "text_end" | "message_end";
    applyReplyToMode: (payload: ReplyPayload) => ReplyPayload;
    shouldEmitToolResult: () => boolean;
    shouldEmitToolOutput: () => boolean;
    pendingToolTasks: Set<Promise<void>>;
    resetSessionAfterCompactionFailure: (reason: string) => Promise<boolean>;
    resetSessionAfterRoleOrderingConflict: (reason: string) => Promise<boolean>;
    isHeartbeat: boolean;
    sessionKey?: string;
    getActiveSessionEntry: () => SessionEntry | undefined;
    activeSessionStore?: Record<string, SessionEntry>;
    storePath?: string;
    resolvedVerboseLevel: VerboseLevel;
}): Promise<KoiRunLoopResult>;
