/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { GenerateContentResponse, type Content, type GenerateContentConfig, type SendMessageParameters, type Part, GenerateContentResponseUsageMetadata, type Tool, type PartListUnion } from '@google/genai';
import type { CompletedToolCall } from './coreToolScheduler.js';
import { type ContentGenerator } from './contentGenerator.js';
import { HistoryService } from '../services/history/HistoryService.js';
import type { IContent, ContentBlock } from '../services/history/IContent.js';
import type { AgentRuntimeContext, ToolRegistryView } from '../runtime/AgentRuntimeContext.js';
export declare enum StreamEventType {
    /** A regular content chunk from the API. */
    CHUNK = "chunk",
    /** A signal that a retry is about to happen. The UI should discard any partial
     * content from the attempt that just failed. */
    RETRY = "retry"
}
export type StreamEvent = {
    type: StreamEventType.CHUNK;
    value: GenerateContentResponse;
} | {
    type: StreamEventType.RETRY;
};
/**
 * Aggregates text from content blocks while preserving spacing around non-text blocks.
 * When thinking blocks (or other non-text blocks) appear between text chunks, this ensures
 * proper spacing is maintained in the aggregated output.
 *
 * @param blocks - Array of content blocks to process
 * @param currentText - The current accumulated text
 * @param lastBlockWasNonText - Whether the previous block was a non-text block
 * @returns Object containing the aggregated text and the updated non-text flag
 */
export declare function aggregateTextWithSpacing(blocks: ContentBlock[], currentText: string, lastBlockWasNonText: boolean): {
    text: string;
    lastBlockWasNonText: boolean;
};
/**
 * Checks if a part contains valid non-thought text content.
 * This helps in consolidating text parts properly during stream processing.
 */
export declare function isValidNonThoughtTextPart(part: Part): boolean;
/**
 * Custom error to signal that a stream completed with invalid content,
 * which should trigger a retry.
 */
export declare class InvalidStreamError extends Error {
    readonly type: 'NO_FINISH_REASON' | 'NO_RESPONSE_TEXT' | 'NO_FINISH_REASON_NO_TEXT';
    constructor(message: string, type: 'NO_FINISH_REASON' | 'NO_RESPONSE_TEXT' | 'NO_FINISH_REASON_NO_TEXT');
}
/**
 * Legacy error class for backward compatibility.
 */
export declare class EmptyStreamError extends Error {
    constructor(message: string);
}
/**
 * Chat session that enables sending messages to the model with previous
 * conversation context.
 *
 * @remarks
 * The session maintains all the turns between user and model.
 */
export declare class GeminiChat {
    private static readonly TOKEN_SAFETY_MARGIN;
    private static readonly DEFAULT_COMPLETION_BUDGET;
    private sendPromise;
    private compressionPromise;
    private logger;
    private cachedCompressionThreshold;
    private lastPromptTokenCount;
    private readonly generationConfig;
    /**
     * Runtime state for stateless operation (Phase 6)
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-001.2
     * @pseudocode agent-runtime-context.md lines 83-91 (step 006)
     */
    private readonly runtimeState;
    private readonly historyService;
    private readonly runtimeContext;
    /**
     * Gets the last prompt token count.
     */
    getLastPromptTokenCount(): number;
    /**
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-001.2, REQ-STAT6-002.2, REQ-STAT6-002.3
     * @pseudocode agent-runtime-context.md lines 83-91 (step 006.1-006.2)
     *
     * Phase 6 constructor: Accept AgentRuntimeContext as first parameter
     * Eliminates Config dependency by using runtime view adapters
     */
    constructor(view: AgentRuntimeContext, contentGenerator: ContentGenerator, generationConfig?: GenerateContentConfig, initialHistory?: Content[]);
    /**
     * Create a position-based matcher for Gemini tool responses.
     * It returns the next unmatched tool call from the current history.
     */
    private makePositionMatcher;
    private _getRequestTextFromContents;
    private buildProviderRuntime;
    private extractDirectGeminiOverrides;
    /**
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-002.3
     * @pseudocode agent-runtime-context.md line 88 (step 006.5)
     */
    private _logApiRequest;
    /**
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-002.3
     * @pseudocode agent-runtime-context.md line 88 (step 006.5)
     */
    private _logApiResponse;
    /**
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-002.3
     * @pseudocode agent-runtime-context.md line 88 (step 006.5)
     */
    private _logApiError;
    setSystemInstruction(sysInstr: string): void;
    /**
     * Get the underlying HistoryService instance
     * @returns The HistoryService managing conversation history
     */
    getHistoryService(): HistoryService;
    getToolsView(): ToolRegistryView;
    /**
     * Sends a message to the model and returns the response.
     *
     * @remarks
     * This method will wait for the previous message to be processed before
     * sending the next message.
     *
     * @see {@link Chat#sendMessageStream} for streaming method.
     * @param params - parameters for sending messages within a chat session.
     * @returns The model's response.
     *
     * @example
     * ```ts
     * const chat = ai.chats.create({model: 'gemini-2.0-flash'});
     * const response = await chat.sendMessage({
     *   message: 'Why is the sky blue?'
     * });
     * console.log(response.text);
     * ```
     */
    sendMessage(params: SendMessageParameters, prompt_id: string): Promise<GenerateContentResponse>;
    /**
     * Sends a message to the model and returns the response in chunks.
     *
     * @remarks
     * This method will wait for the previous message to be processed before
     * sending the next message.
     *
     * @see {@link Chat#sendMessage} for non-streaming method.
     * @param params - parameters for sending the message.
     * @return The model's response.
     *
     * @example
     * ```ts
     * const chat = ai.chats.create({model: 'gemini-2.0-flash'});
     * const response = await chat.sendMessageStream({
     *   message: 'Why is the sky blue?'
     * });
     * for await (const chunk of response) {
     *   console.log(chunk.text);
     * }
     * ```
     */
    sendMessageStream(params: SendMessageParameters, prompt_id: string): Promise<AsyncGenerator<StreamEvent>>;
    generateDirectMessage(params: SendMessageParameters, prompt_id: string): Promise<GenerateContentResponse>;
    private makeApiCallAndProcessStream;
    /**
     * Returns the chat history.
     *
     * @remarks
     * The history is a list of contents alternating between user and model.
     *
     * There are two types of history:
     * - The `curated history` contains only the valid turns between user and
     * model, which will be included in the subsequent requests sent to the model.
     * - The `comprehensive history` contains all turns, including invalid or
     *   empty model outputs, providing a complete record of the history.
     *
     * The history is updated after receiving the response from the model,
     * for streaming response, it means receiving the last chunk of the response.
     *
     * The `comprehensive history` is returned by default. To get the `curated
     * history`, set the `curated` parameter to `true`.
     *
     * @param curated - whether to return the curated history or the comprehensive
     *     history.
     * @return History contents alternating between user and model for the entire
     *     chat session.
     */
    getHistory(curated?: boolean): Content[];
    /**
     * Clears the chat history.
     */
    clearHistory(): void;
    /**
     * Adds a new entry to the chat history.
     */
    addHistory(content: Content): void;
    setHistory(history: Content[]): void;
    setTools(tools: Tool[]): void;
    clearTools(): void;
    /**
     * Calculate effective token count based on reasoning settings.
     * This accounts for whether reasoning will be included in API calls.
     *
     * @plan PLAN-20251202-THINKING.P15
     * @requirement REQ-THINK-005.1, REQ-THINK-005.2
     */
    private getEffectiveTokenCount;
    /**
     * Check if compression is needed based on token count
     * @plan PLAN-20251028-STATELESS6.P10
     * @requirement REQ-STAT6-002.2
     * @pseudocode agent-runtime-context.md line 86 (step 006.3)
     */
    private shouldCompress;
    private ensureCompressionBeforeSend;
    private estimatePendingTokens;
    private asNumber;
    private extractCompletionBudgetFromParams;
    private getCompletionBudget;
    private enforceContextWindow;
    /**
     * Perform compression of chat history
     * Made public to allow manual compression triggering
     */
    performCompression(prompt_id: string): Promise<void>;
    /**
     * Get the split point for compression
     */
    private getCompressionSplit;
    /**
     * Adjust compression boundary to not split tool call/response pairs
     */
    private adjustForToolCallBoundary;
    /**
     * Direct API call for compression, bypassing normal message flow
     */
    private directCompressionCall;
    /**
     * Apply compression results to history
     */
    private applyCompression;
    getFinalUsageMetadata(chunks: GenerateContentResponse[]): GenerateContentResponseUsageMetadata | undefined;
    private processStreamResponse;
    /**
     * Records completed tool calls with full metadata.
     * This is called by external components when tool calls complete, before sending responses to Gemini.
     * NOTE: llxprt does not use ChatRecordingService, so this is a no-op stub for compatibility.
     */
    recordCompletedToolCalls(_model: string, _toolCalls: CompletedToolCall[]): void;
    private recordHistory;
    private hasTextContent;
    private isThoughtContent;
    private maybeIncludeSchemaDepthContext;
    /**
     * Convert PartListUnion (user input) to IContent format for provider/history
     */
    convertPartListUnionToIContent(input: PartListUnion): IContent;
    /**
     * Convert IContent (from provider) to GenerateContentResponse for SDK compatibility
     */
    private convertIContentToResponse;
    /**
     * Get the active provider from the ProviderManager via Config
     */
    private getActiveProvider;
    private resolveProviderForRuntime;
    /**
     * Check if a provider supports the IContent interface
     */
    private providerSupportsIContent;
    private resolveProviderBaseUrl;
}
/** Visible for Testing */
export declare function isSchemaDepthError(errorMessage: string): boolean;
