import { GoogleGenAI, Content, Part } from "@google/genai"; import { BaseLLM, ChatMessage, ChatParams, ChatResult, SummarizeParams, SummarizeResult, ChatMessageContent, FileCapabilities } from "@memberjunction/ai"; export declare class GeminiLLM extends BaseLLM { protected _gemini: GoogleGenAI | null; private _geminiPromise; private _streamingState; private _cacheDiagContext; constructor(apiKey: string); /** * Factory method to create the GoogleGenAI client instance * Subclasses can override this to provide custom configuration * * @returns Promise that resolves to a configured GoogleGenAI client */ protected createClient(): Promise; /** * Ensure the Gemini client is initialized before use * This method should be called at the start of any method that uses the client */ private ensureGeminiClient; /** * Gemini supports a wide range of file types natively, including via the Files API. */ GetFileCapabilities(): FileCapabilities | null; /** * Read only getter method to get the Gemini client instance * Note: This is async now because the client may not be initialized yet */ get GeminiClient(): GoogleGenAI; /** * Convert MJ effort level (1-100) to Gemini thinkingBudget (0-24576) * * Mapping strategy: * - 1 (minimal): 0 (disabled) on Flash; clamped to ~1024 on Pro * - 2-33 (low): 1024-4096 tokens * - 34-66 (medium): 4097-12288 tokens * - 67-100 (high): 12289-24576 tokens * - undefined: No thinkingConfig (Gemini default ~8192) * * Model-specific behavior: * - Gemini 2.5 Flash/Flash-Lite: Can disable thinking with budget=0 * - Gemini 2.5 Pro: Cannot disable thinking, minimum ~1024 * - Gemini 3 models: Use thinkingLevel instead (future consideration) * * @param effortLevel - MJ normalized effort level (1-100) as string or number * @param modelName - The Gemini model name to check capabilities * @returns thinkingBudget value or undefined for default behavior */ private getThinkingBudget; /** * Check if a model supports thinking configuration * Thinking is supported on Gemini 2.5+ models */ private supportsThinking; /** * Gemini supports streaming */ get SupportsStreaming(): boolean; protected geminiMessageSpacing(messages: Content[]): Content[]; /** * Implementation of non-streaming chat completion for Gemini */ protected nonStreamingChatCompletion(params: ChatParams): Promise; private setThinkingConfig; /** * Reset streaming state for a new request */ protected resetStreamingState(): void; /** * Create a streaming request for Gemini */ protected createStreamingRequest(params: ChatParams): Promise; /** * Process a streaming chunk from Gemini */ protected processStreamingChunk(chunk: any): { content: string; finishReason?: string; usage?: any; }; /** * Builds a {@link GeminiCacheDiagContext} snapshot for the current request. Cheap (one djb2 * pass over the system prompt); only called when GEMINI_CACHE_DEBUG is set. */ private buildCacheDiagContext; /** * Emits a one-line prompt-cache diagnostic for a Gemini call, gated behind the * GEMINI_CACHE_DEBUG env var so it is silent in normal operation. Surfaces exactly what we need * to explain a cache miss: whether a stable systemInstruction prefix was sent (chars + hash so * two runs can be compared), the history depth, the provider's native token split * (prompt/cached/net/completion), and whether a cache hit occurred. Warns when the input is * below Gemini's implicit-cache minimum or when no systemInstruction was sent at all. */ private logCacheDiagnostics; /** * djb2 string hash → 8-char hex. Non-cryptographic; used only to compare whether the system * prompt prefix is byte-identical across two runs (a changing hash means the prefix is unstable * and implicit caching cannot engage). Dependency-free on purpose to keep this provider-local. */ private stableHash; /** * Process pending content to extract thinking blocks * Returns content that should be emitted to the user */ private processThinkingInStreamingContent; /** * Create the final response from streaming results for Gemini */ protected finalizeStreamingResponse(accumulatedContent: string | null | undefined, lastChunk: any | null | undefined, usage: any | null | undefined): ChatResult; SummarizeText(params: SummarizeParams): Promise; ClassifyText(params: any): Promise; /** * The default mimeType to assume for a media content block when neither an explicit * `mimeType` nor a data-URL-embedded mime is available. Keyed by MJ content-block type. */ private static geminiDefaultMimeForBlockType; /** * Convert a single MJ content block into the matching Gemini {@link Part}. This is the one * type-aware mapping site so that text-only behavior stays byte-identical and every media * block (image/audio/video/file) becomes a real Gemini media part instead of a text blob of * its data URL. * * - `text` → `{ text }` (unchanged). * - any media block whose `content` is a `data:;base64,` data URL → * `{ inlineData: { mimeType, data } }` carrying the raw base64 (prefix stripped). * - any media block whose `content` is an http(s) URL → `{ fileData: { mimeType, fileUri } }`, * Gemini's remote-file part (mirrors how geminiImage.ts reads fileData.fileUri). * - a media block whose `content` is bare base64 (no data-URL prefix, but valid base64) → * `{ inlineData }`, preserving the prior behavior. * - anything else (e.g. placeholder strings tagged onto a file_url block) → `{ text }` fallback. */ private static mjContentBlockToGeminiPart; static MapMJContentToGeminiParts(content: ChatMessageContent): Array; static MapMJMessageToGeminiHistoryEntry(message: ChatMessage): Content; /** * Flatten an MJ message's content to a plain-text string for the Gemini systemInstruction. * Images and other media MUST NOT ride in the system instruction — emitting a giant base64 * data URL there would both blow the cacheable prefix and fail to be interpreted as an image. * So we keep only `text` blocks here; a pure-string content stays as-is. */ private static mjContentToSystemInstructionText; } export * from './geminiImage.js'; export * from './geminiRealtime.js'; export * from './geminiEmbedding2.js'; //# sourceMappingURL=index.d.ts.map