import * as readline from 'node:readline/promises';
import type { Message, GrawkusConfig } from './types.js';
import type { Mode } from './modes.js';
/**
 * Count how many NON-OVERLAPPING occurrences of the last `windowSize`
 * characters of `fullText` appear in the full string. Bails as soon as
 * `threshold` is reached so the cost is O(threshold * windowSize) in
 * the common stuck-model case rather than O(fullText.length).
 *
 * Non-overlapping by stepping the search index by `windowSize` after
 * each match. Overlapping counts cause false positives on self-similar
 * text (markdown tables, repeated import lines, ASCII art) — the audit
 * found that `idx++` made a single copy match 3+ times when there were
 * only two genuine repeats.
 *
 * Exported so the loop-detector behavior can be unit-tested without
 * driving the full streamChat loop.
 */
export declare function countTailRepetitions(fullText: string, windowSize: number, threshold: number): number;
export interface QueryContext {
    config: GrawkusConfig;
    messages: Message[];
    cwd: string;
    rl: readline.Interface;
    sessionId: string;
    mode: Mode;
}
export interface InputGuard {
    pause(): void;
    resume(): void;
    /** Return whatever the user typed during streaming, then clear the buffer. */
    drainQueuedInput(): string;
    /**
     * Register a callback invoked when the user presses Ctrl+G (Steer).
     * The handler is responsible for aborting the active stream / chain
     * and treating the queued buffer as the next user message.
     */
    onSteer(handler: () => void): void;
    restore(): void;
}
/**
 * Main query loop: sends messages to the API, handles tool calls, loops until done.
 */
export declare function runQuery(ctx: QueryContext): Promise<void>;
