/**
 * Streaming utilities for filtering and extracting streamable content.
 *
 * This module provides implementations of {@link IStreamExtractor}:
 * - PassthroughExtractor - Simple passthrough (no filtering)
 * - XmlTagExtractor - Extract content from a specific XML tag
 * - ResponseStreamExtractor - Action-aware XML (for DefaultMessageService)
 * - ActionStreamFilter - Content-type aware filter (for action handlers)
 *
 * For the interface definition, see types/streaming.ts.
 * Implementations can use these or create their own extractors.
 */
import type { StreamChunkCallback } from "../types/components";
import type { IStreamExtractor } from "../types/streaming";
/** Error codes for streaming operations */
export type StreamErrorCode = "CHUNK_TOO_LARGE" | "BUFFER_OVERFLOW" | "PARSE_ERROR" | "TIMEOUT" | "ABORTED";
/**
 * Standardized error class for streaming operations.
 * Provides structured error codes for easier handling.
 */
export declare class StreamError extends Error {
    readonly code: StreamErrorCode;
    readonly details?: Record<string, unknown>;
    constructor(code: StreamErrorCode, message: string, details?: Record<string, unknown>);
    /** Check if an error is a StreamError */
    static isStreamError(error: unknown): error is StreamError;
}
/**
 * Streams all content as-is without any filtering.
 * Use when LLM output is already in the desired format (e.g., plain text responses).
 */
export declare class PassthroughExtractor implements IStreamExtractor {
    get done(): boolean;
    push(chunk: string): string;
    reset(): void;
}
/**
 * Extracts content from a specific XML tag, streaming it progressively.
 * Use when you have a simple XML format like `<response><text>content</text></response>`.
 *
 * @example
 * ```ts
 * const extractor = new XmlTagExtractor('text');
 * extractor.push('<response><text>Hello'); // Returns 'Hel' (keeps margin for split tags)
 * extractor.push(' world!</text></response>'); // Returns 'lo world!'
 * ```
 */
export declare class XmlTagExtractor implements IStreamExtractor {
    private readonly openTag;
    private readonly closeTag;
    private buffer;
    private insideTag;
    private finished;
    constructor(tagName: string);
    get done(): boolean;
    push(chunk: string): string;
    reset(): void;
}
/**
 * Extracts streamable text from XML-structured LLM responses with action-based routing.
 *
 * This is the default implementation used by DefaultMessageService.
 * It understands the `<actions>` tag to determine whether to stream `<text>` content.
 *
 * Strategy:
 * - Parse <actions> to determine if response is direct (REPLY) or delegated (other actions)
 * - If direct: stream <text> content immediately
 * - If delegated: skip <text> (action handler will generate its own response via ActionStreamFilter)
 *
 * For simpler use cases without action routing, use {@link XmlTagExtractor} instead.
 */
export declare class ResponseStreamExtractor implements IStreamExtractor {
    private static readonly STREAM_TAGS;
    private static readonly OPEN_TEXT_TAG;
    private static readonly CLOSE_TEXT_TAG;
    private buffer;
    private insideTag;
    private currentTag;
    private finished;
    private responseStrategy;
    get done(): boolean;
    reset(): void;
    push(chunk: string): string;
    /** Detect response strategy from <actions> tag using pre-compiled regex */
    private detectResponseStrategy;
    /** Parse comma-separated actions */
    private parseActions;
    /** Check if actions represent a direct reply */
    private isDirectReply;
    /** Determine if a tag should be streamed based on strategy */
    private shouldStreamTag;
}
/**
 * Filters action handler output for streaming.
 * Used by runtime.ts processActions() for each action's useModel calls.
 *
 * Auto-detects content type from first non-whitespace character:
 * - JSON (starts with { or [) → Don't stream (structured data for parsing)
 * - XML (starts with <) → Look for <text> tag and stream its content
 * - Plain text → Stream immediately
 */
export declare class ActionStreamFilter implements IStreamExtractor {
    private buffer;
    private decided;
    private contentType;
    private insideTextTag;
    private finished;
    get done(): boolean;
    reset(): void;
    push(chunk: string): string;
    /** Detect content type from first non-whitespace character */
    private detectContentType;
    /** Handle plain text - stream everything */
    private handlePlainText;
    /** Handle XML content - extract and stream <text> tag content */
    private handleXml;
}
/**
 * Passthrough extractor that can be marked complete externally.
 *
 * WHY: When using ValidationStreamExtractor inside dynamicPromptExecFromState,
 * extraction/completion is handled internally. But the outer streaming context
 * still needs to know when streaming is complete for retry/fallback logic.
 *
 * This extractor passes through all content and provides a markComplete() method
 * that the caller can invoke when the underlying operation completes successfully.
 *
 * @example
 * ```ts
 * const extractor = new MarkableExtractor();
 * const ctx = createStreamingContext(extractor, callback);
 *
 * const result = await dynamicPromptExecFromState({ ... });
 * if (result) {
 *   extractor.markComplete(); // Signal success
 * }
 *
 * if (ctx.isComplete()) {
 *   // Now returns true after markComplete()
 * }
 * ```
 */
export declare class MarkableExtractor implements IStreamExtractor {
    private _done;
    get done(): boolean;
    push(chunk: string): string;
    flush(): string;
    reset(): void;
    /**
     * Mark the extractor as complete.
     * WHY: Called by the outer code when the underlying operation completes
     * successfully. This allows isComplete() to return true for retry/fallback logic.
     */
    markComplete(): void;
}
import type { SchemaRow, StreamEvent } from "../types/state";
import type { IStreamingRetryState } from "../types/streaming";
/**
 * Extractor state machine for validation-aware streaming.
 */
export type ExtractorState = "streaming" | "validating" | "retrying" | "complete" | "failed";
/**
 * Per-field state tracking for progressive validation.
 */
export type FieldState = "pending" | "partial" | "complete" | "invalid";
/**
 * Configuration for ValidationStreamExtractor.
 */
export interface ValidationStreamExtractorConfig {
    /** Validation level (0-3) */
    level: 0 | 1 | 2 | 3;
    /** Schema rows with field definitions */
    schema: SchemaRow[];
    /** Which fields to stream to the consumer */
    streamFields: string[];
    /** Expected validation codes per field */
    expectedCodes: Map<string, string>;
    /**
     * Callback for streaming chunks.
     * WHY accumulated: consumers (voice detection, client-side merge) need the
     * full field text to avoid re-deriving it from deltas — which caused the
     * dual-extractor garbling bug when two pipelines accumulated differently.
     * The extractor already tracks this as `content` in emitFieldContent, so
     * surfacing it is zero-cost.
     */
    onChunk: (chunk: string, field?: string, accumulated?: string) => void;
    /** Rich event callback for sophisticated consumers */
    onEvent?: (event: StreamEvent) => void;
    /** Abort signal for cancellation */
    abortSignal?: AbortSignal;
    /** Whether the consumer has an onEvent handler */
    hasRichConsumer?: boolean;
}
/**
 * Diagnosis result for error analysis.
 */
export interface ValidationDiagnosis {
    /** Fields that were never started */
    missingFields: string[];
    /** Fields with wrong validation codes */
    invalidFields: string[];
    /** Fields that started but didn't complete */
    incompleteFields: string[];
}
/**
 * Validation-aware stream extractor for dynamicPromptExecFromState.
 *
 * WHY THIS EXISTS:
 * LLMs can silently truncate output when they hit token limits. This is catastrophic
 * for structured outputs - you might get half a JSON object. Traditional streaming
 * has no validation - you might stream half a broken response.
 *
 * This extractor bridges the gap: it enables streaming while detecting truncation.
 * It uses "validation codes" - random UUIDs that the LLM must echo. If the echoed
 * code matches, we know that part wasn't truncated.
 *
 * VALIDATION LEVELS:
 * - Level 0 (Trusted): No codes, stream immediately. Fast but no safety.
 * - Level 1 (Progressive): Per-field codes, emit as each field validates.
 * - Level 2 (First Checkpoint): Code at start only, buffer until validated.
 * - Level 3 (Full): Codes at start AND end, maximum safety.
 */
export declare class ValidationStreamExtractor implements IStreamExtractor {
    private readonly config;
    private buffer;
    private fieldContents;
    private validatedFields;
    private emittedContent;
    private fieldStates;
    private state;
    constructor(config: ValidationStreamExtractorConfig);
    get done(): boolean;
    push(chunk: string): string;
    flush(): string;
    reset(): void;
    /**
     * Signal a retry attempt. Returns info about validated fields for smart retry prompts.
     */
    signalRetry(retryCount: number): {
        validatedFields: string[];
    };
    /**
     * Signal an unrecoverable error.
     */
    signalError(message: string): void;
    /**
     * Get fields that passed validation (for smart retry context).
     */
    getValidatedFields(): Map<string, string>;
    /**
     * Diagnose what went wrong for error reporting.
     */
    diagnose(): ValidationDiagnosis;
    /**
     * Get current extractor state.
     */
    getState(): ExtractorState;
    private extractFieldContents;
    private checkPerFieldEmission;
    private checkValidationCode;
    private emitFieldContent;
    private emitEvent;
}
import type { StreamingContext } from "../streaming-context";
/**
 * Creates a streaming retry state from an extractor.
 */
export declare function createStreamingRetryState(extractor: IStreamExtractor): IStreamingRetryState & {
    appendText: (text: string) => void;
};
/**
 * Creates a complete streaming context with retry state management.
 */
export declare function createStreamingContext(extractor: IStreamExtractor, onStreamChunk: StreamChunkCallback, messageId?: string): StreamingContext & IStreamingRetryState;
//# sourceMappingURL=streaming.d.ts.map