{"version":3,"sources":["../src/adapter.ts","../src/provider.ts"],"names":["BaseAIProvider"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { UniversalMessage, UserMessage, AssistantMessage, SystemMessage, ToolMessage } from '@robota-sdk/core';\nimport type { Content, Part } from '@google/generative-ai';\n\n/**\n * Google AI ConversationHistory adapter\n * \n * Converts UniversalMessage to Google Generative AI format\n */\nexport class GoogleConversationAdapter {\n    /**\n     * Convert UniversalMessage array to Google AI message format\n     */\n    static toGoogleFormat(messages: UniversalMessage[]): Content[] {\n        return messages\n            .filter(msg => msg.role !== 'system') // System messages are handled separately\n            .map(msg => this.convertMessage(msg));\n    }\n\n    /**\n     * Convert a single UniversalMessage to Google AI format\n     */\n    static convertMessage(msg: UniversalMessage): Content {\n        const messageRole = msg.role;\n\n        // Handle user messages\n        if (messageRole === 'user') {\n            const userMsg = msg as UserMessage;\n            return {\n                role: 'user',\n                parts: [{ text: userMsg.content }]\n            };\n        }\n\n        // Handle assistant messages\n        if (messageRole === 'assistant') {\n            const assistantMsg = msg as AssistantMessage;\n            if ((assistantMsg as any).toolCalls) {\n                const parts: Part[] = [{ text: assistantMsg.content || '' }];\n\n                // Add tool calls if they exist\n                const toolCalls = (assistantMsg as any).toolCalls;\n                for (const tc of toolCalls) {\n                    parts.push({\n                        functionCall: {\n                            name: tc.function.name,\n                            args: JSON.parse(tc.function.arguments)\n                        }\n                    } as Part);\n                }\n\n                return {\n                    role: 'model',\n                    parts\n                };\n            }\n            return {\n                role: 'model',\n                parts: [{ text: assistantMsg.content || '' }]\n            };\n        }\n\n        // Handle tool messages\n        if (messageRole === 'tool') {\n            const toolMsg = msg as ToolMessage;\n            return {\n                role: 'function',\n                parts: [\n                    {\n                        functionResponse: {\n                            name: toolMsg.name || 'unknown',\n                            response: toolMsg.content\n                        }\n                    } as any\n                ]\n            };\n        }\n\n        // Handle system messages (convert to user)\n        if (messageRole === 'system') {\n            const systemMsg = msg as SystemMessage;\n            return {\n                role: 'user',\n                parts: [{ text: `[System]: ${systemMsg.content}` }]\n            };\n        }\n\n        // This should never happen but TypeScript requires exhaustive checking\n        const _exhaustiveCheck: never = msg;\n        return _exhaustiveCheck;\n    }\n\n    /**\n     * Extract system messages and combine them as system instruction\n     */\n    static extractSystemInstruction(messages: UniversalMessage[], fallbackSystemPrompt?: string): string | undefined {\n        const systemMessages = messages.filter(msg => msg.role === 'system') as SystemMessage[];\n\n        if (systemMessages.length > 0) {\n            return systemMessages.map(msg => msg.content).join('\\n\\n');\n        }\n\n        return fallbackSystemPrompt;\n    }\n\n    /**\n     * Complete message conversion pipeline\n     */\n    static processMessages(\n        messages: UniversalMessage[],\n        systemPrompt?: string\n    ): {\n        contents: Content[],\n        systemInstruction?: string\n    } {\n        // 1. Extract system instruction\n        const systemInstruction = this.extractSystemInstruction(messages, systemPrompt);\n\n        // 2. Convert messages to Google AI format\n        const contents = this.toGoogleFormat(messages);\n\n        return {\n            contents,\n            systemInstruction\n        };\n    }\n} ","import { GoogleGenerativeAI } from '@google/generative-ai';\nimport { BaseAIProvider } from '@robota-sdk/core';\nimport type {\n    Context,\n    ModelResponse,\n    StreamingResponseChunk,\n    UniversalMessage\n} from '@robota-sdk/core';\nimport type { FunctionSchema } from '@robota-sdk/tools';\nimport type { GoogleProviderOptions } from './types';\nimport { GoogleConversationAdapter } from './adapter';\n\n/**\n * Google AI provider implementation for Robota\n * \n * Provides integration with Google's Generative AI services including Gemini models.\n * Extends BaseAIProvider for common functionality and tool calling support.\n * \n * @see {@link ../../../apps/examples/03-integrations | Provider Integration Examples}\n * \n * @public\n */\nexport class GoogleProvider extends BaseAIProvider {\n    /**\n     * Provider identifier name\n     * @readonly\n     */\n    public readonly name: string = 'google';\n\n    /**\n     * Google AI client instance\n     * @internal\n     */\n    private readonly client: GoogleGenerativeAI;\n\n    /**\n     * Provider configuration options\n     * @readonly\n     */\n    public readonly options: GoogleProviderOptions;\n\n    /**\n     * Create a new Google AI provider instance\n     * \n     * @param options - Configuration options for the Google provider\n     * \n     * @throws {Error} When client is not provided in options\n     */\n    constructor(options: GoogleProviderOptions) {\n        super();\n\n        this.options = {\n            temperature: 0.7,\n            maxTokens: undefined,\n            ...options\n        };\n\n        // Validate required client injection\n        if (!options.client) {\n            throw new Error('Google AI client is not injected. The client option is required.');\n        }\n\n        this.client = options.client;\n    }\n\n    /**\n     * Send a chat request to Google AI and receive a complete response\n     * \n     * @param model - Model name to use (e.g., 'gemini-1.5-pro', 'gemini-1.5-flash')\n     * @param context - Context object containing messages and system prompt\n     * @param options - Optional generation parameters and tools\n     * @returns Promise resolving to the model's response\n     * \n     * @throws {Error} When context is invalid\n     * @throws {Error} When messages array is invalid\n     * @throws {Error} When Google AI API call fails\n     */\n    async chat(model: string, context: Context, options?: any): Promise<ModelResponse> {\n        // Use base class validation\n        this.validateContext(context);\n\n        const { messages, systemPrompt } = context;\n\n        try {\n            // Convert UniversalMessage[] to Google AI format\n            const { contents, systemInstruction } = GoogleConversationAdapter.processMessages(\n                messages as UniversalMessage[],\n                systemPrompt\n            );\n\n            // Configure tools if provided\n            const toolConfig = this.configureTools(options?.tools);\n            const modelConfig: any = {\n                model: model || this.options.model || 'gemini-1.5-flash',\n                systemInstruction: systemInstruction\n            };\n\n            // Add tools to model configuration if available\n            if (toolConfig) {\n                modelConfig.tools = toolConfig.tools;\n            }\n\n            // Get Google AI model instance\n            const generativeModel = this.client.getGenerativeModel(modelConfig);\n\n            // Configure generation parameters\n            const generationConfig = {\n                temperature: options?.temperature ?? this.options.temperature,\n                maxOutputTokens: options?.maxTokens ?? this.options.maxTokens,\n                ...(this.options.responseMimeType && {\n                    responseMimeType: this.options.responseMimeType\n                }),\n                ...(this.options.responseSchema && {\n                    responseSchema: this.options.responseSchema\n                })\n            };\n\n            // Generate content\n            const result = await generativeModel.generateContent({\n                contents,\n                generationConfig\n            });\n\n            return this.parseResponse(result);\n        } catch (error) {\n            this.handleApiError(error, 'chat');\n        }\n    }\n\n    /**\n     * Send a streaming chat request to Google AI and receive response chunks\n     * \n     * Generates an async iterator that yields response chunks as they arrive.\n     * Useful for real-time display of responses or handling large responses incrementally.\n     * \n     * @param model - Model name to use\n     * @param context - Context object containing messages and system prompt\n     * @param options - Optional generation parameters and tools\n     * @returns Async generator yielding response chunks\n     * \n     * @throws {Error} When context is invalid\n     * @throws {Error} When messages array is invalid\n     * @throws {Error} When Google AI API streaming call fails\n     */\n    async *chatStream(model: string, context: Context, options?: any): AsyncGenerator<StreamingResponseChunk, void, unknown> {\n        // Use base class validation\n        this.validateContext(context);\n\n        const { messages, systemPrompt } = context;\n\n        try {\n            // Convert UniversalMessage[] to Google AI format\n            const { contents, systemInstruction } = GoogleConversationAdapter.processMessages(\n                messages as UniversalMessage[],\n                systemPrompt\n            );\n\n            // Configure tools if provided\n            const toolConfig = this.configureTools(options?.tools);\n            const modelConfig: any = {\n                model: model || this.options.model || 'gemini-1.5-flash',\n                systemInstruction: systemInstruction\n            };\n\n            // Add tools to model configuration if available\n            if (toolConfig) {\n                modelConfig.tools = toolConfig.tools;\n            }\n\n            // Get Google AI model instance\n            const generativeModel = this.client.getGenerativeModel(modelConfig);\n\n            // Configure generation parameters\n            const generationConfig = {\n                temperature: options?.temperature ?? this.options.temperature,\n                maxOutputTokens: options?.maxTokens ?? this.options.maxTokens,\n                ...(this.options.responseMimeType && {\n                    responseMimeType: this.options.responseMimeType\n                }),\n                ...(this.options.responseSchema && {\n                    responseSchema: this.options.responseSchema\n                })\n            };\n\n            // Generate streaming content\n            const result = await generativeModel.generateContentStream({\n                contents,\n                generationConfig\n            });\n\n            for await (const chunk of result.stream) {\n                yield this.parseStreamingChunk(chunk);\n            }\n        } catch (error) {\n            this.handleApiError(error, 'chatStream');\n        }\n    }\n\n    /**\n     * Configure tools for Google AI API request\n     * \n     * Google AI supports function calling with Gemini models.\n     * Transforms function schemas into Google AI tool format.\n     * \n     * @param tools - Array of function schemas\n     * @returns Google AI tool configuration object or undefined\n     */\n    protected configureTools(tools?: FunctionSchema[]): { tools: any[] } | undefined {\n        if (!tools || !Array.isArray(tools)) {\n            return undefined;\n        }\n\n        return {\n            tools: [{\n                functionDeclarations: tools.map(fn => ({\n                    name: fn.name,\n                    description: fn.description || '',\n                    parameters: fn.parameters\n                }))\n            }]\n        };\n    }\n\n    /**\n     * Parse Google AI response into universal ModelResponse format\n     * \n     * Extracts content, usage information, and metadata from the Google AI response\n     * and converts it to the standard format used across all providers.\n     * Supports function calling with Gemini models.\n     * \n     * @param response - Raw response from Google AI API\n     * @returns Parsed model response in universal format\n     * \n     * @internal\n     */\n    parseResponse(response: any): ModelResponse {\n        let content = '';\n        const toolCalls: any[] = [];\n\n        // Extract content and function calls from response\n        const candidate = response.response?.candidates?.[0];\n        if (candidate?.content?.parts) {\n            for (const part of candidate.content.parts) {\n                if (part.text) {\n                    content += part.text;\n                } else if (part.functionCall) {\n                    // Convert Google AI function call to OpenAI format for consistency\n                    toolCalls.push({\n                        id: `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,\n                        type: 'function' as const,\n                        function: {\n                            name: part.functionCall.name,\n                            arguments: JSON.stringify(part.functionCall.args || {})\n                        }\n                    });\n                }\n            }\n        }\n\n        // Extract usage information from response if available\n        const usageMetadata = response.response?.usageMetadata;\n        const usage = usageMetadata ? {\n            promptTokens: usageMetadata.promptTokenCount || 0,\n            completionTokens: usageMetadata.candidatesTokenCount || 0,\n            totalTokens: usageMetadata.totalTokenCount || 0\n        } : {\n            promptTokens: 0,\n            completionTokens: 0,\n            totalTokens: 0\n        };\n\n        const result: ModelResponse = {\n            content: content || undefined,\n            usage,\n            metadata: {\n                model: response.response?.model,\n                finishReason: candidate?.finishReason,\n                safetyRatings: candidate?.safetyRatings\n            }\n        };\n\n        // Add tool calls if present\n        if (toolCalls.length > 0) {\n            result.toolCalls = toolCalls;\n        }\n\n        return result;\n    }\n\n    /**\n     * Parse Google AI streaming response chunk into universal format\n     * \n     * Converts individual chunks from the streaming response into the standard\n     * StreamingResponseChunk format used across all providers.\n     * \n     * @param chunk - Raw chunk from Google AI streaming API\n     * @returns Parsed streaming response chunk\n     * \n     * @internal\n     */\n    parseStreamingChunk(chunk: any): StreamingResponseChunk {\n        const text = chunk.text() || '';\n\n        // Determine if this is the final chunk\n        const candidate = chunk.candidates?.[0];\n        const isComplete = candidate?.finishReason !== undefined && candidate.finishReason !== null;\n\n        return {\n            content: text,\n            isComplete\n        };\n    }\n\n    /**\n     * Release resources and close connections\n     * \n     * Performs cleanup operations when the provider is no longer needed.\n     * Google AI client doesn't require explicit cleanup, so this is a no-op.\n     * \n     * @returns Promise that resolves when cleanup is complete\n     */\n    async close(): Promise<void> {\n        // Google AI client doesn't have explicit close method\n        // This is implemented as no-op for interface compliance\n    }\n} "]}