ai-sdk-provider-gemini-cli
Version:
Community AI SDK provider for Google Gemini using the official CLI/SDK
1 lines • 46.1 kB
Source Map (JSON)
{"version":3,"sources":["../src/gemini-language-model.ts","../src/client.ts","../src/message-mapper.ts","../src/tool-mapper.ts","../src/error.ts","../src/extract-json.ts","../src/validation.ts","../src/gemini-provider.ts"],"sourcesContent":["import { randomUUID } from 'node:crypto';\nimport type {\n LanguageModelV1,\n LanguageModelV1CallOptions,\n LanguageModelV1CallWarning,\n LanguageModelV1FinishReason,\n LanguageModelV1FunctionTool,\n LanguageModelV1FunctionToolCall,\n LanguageModelV1StreamPart,\n} from '@ai-sdk/provider';\nimport type {\n ContentGenerator,\n ContentGeneratorConfig,\n} from '@google/gemini-cli-core';\nimport type {\n GenerateContentParameters,\n GenerateContentConfig,\n Part,\n Content,\n} from '@google/genai';\nimport { initializeGeminiClient } from './client';\nimport { mapPromptToGeminiFormat } from './message-mapper';\nimport { mapToolsToGeminiFormat } from './tool-mapper';\nimport { mapGeminiError } from './error';\nimport { extractJson } from './extract-json';\nimport type { GeminiProviderOptions } from './types';\n\nexport interface GeminiLanguageModelOptions {\n modelId: string;\n providerOptions: GeminiProviderOptions;\n settings?: Record<string, unknown>;\n}\n\n/**\n * Map Gemini finish reasons to Vercel AI SDK finish reasons\n */\nfunction mapGeminiFinishReason(\n geminiReason?: string\n): LanguageModelV1FinishReason {\n switch (geminiReason) {\n case 'STOP':\n return 'stop';\n case 'MAX_TOKENS':\n return 'length';\n case 'SAFETY':\n case 'RECITATION':\n return 'content-filter';\n case 'OTHER':\n return 'other';\n default:\n return 'unknown';\n }\n}\n\nexport class GeminiLanguageModel implements LanguageModelV1 {\n readonly specificationVersion = 'v1' as const;\n readonly provider = 'gemini-cli-core';\n readonly defaultObjectGenerationMode = 'json' as const;\n readonly supportsImageUrls = false; // CLI Core uses base64 data, not URLs\n readonly supportsStructuredOutputs = true;\n\n private contentGenerator?: ContentGenerator;\n private config?: ContentGeneratorConfig;\n private initPromise?: Promise<void>;\n\n readonly modelId: string;\n readonly settings?: Record<string, unknown>;\n private providerOptions: GeminiProviderOptions;\n\n constructor(options: GeminiLanguageModelOptions) {\n this.modelId = options.modelId;\n this.providerOptions = options.providerOptions;\n this.settings = options.settings;\n }\n\n private async ensureInitialized(): Promise<{\n contentGenerator: ContentGenerator;\n config: ContentGeneratorConfig;\n }> {\n if (this.contentGenerator && this.config) {\n return { contentGenerator: this.contentGenerator, config: this.config };\n }\n\n if (!this.initPromise) {\n this.initPromise = this.initialize();\n }\n\n await this.initPromise;\n return { contentGenerator: this.contentGenerator!, config: this.config! };\n }\n\n private async initialize(): Promise<void> {\n try {\n const { client, config } = await initializeGeminiClient(\n this.providerOptions,\n this.modelId\n );\n this.contentGenerator = client;\n this.config = config;\n } catch (error) {\n throw new Error(`Failed to initialize Gemini model: ${String(error)}`);\n }\n }\n\n /**\n * Non-streaming generation method\n */\n async doGenerate(options: LanguageModelV1CallOptions): Promise<{\n text?: string;\n toolCalls?: LanguageModelV1FunctionToolCall[];\n finishReason: LanguageModelV1FinishReason;\n usage: {\n promptTokens: number;\n completionTokens: number;\n };\n rawCall: {\n rawPrompt: unknown;\n rawSettings: Record<string, unknown>;\n };\n rawResponse?: {\n headers?: Record<string, string>;\n body?: unknown;\n };\n request?: {\n body?: string;\n };\n response?: {\n id?: string;\n timestamp?: Date;\n modelId?: string;\n };\n warnings?: LanguageModelV1CallWarning[];\n }> {\n try {\n const { contentGenerator } = await this.ensureInitialized();\n\n // Map the prompt to Gemini format\n const { contents, systemInstruction } = mapPromptToGeminiFormat(options);\n\n // Prepare generation config\n const generationConfig: GenerateContentConfig = {\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n maxOutputTokens: options.maxTokens || 65536, // Default to 65536 (64K) - max supported by Gemini 2.5 models\n stopSequences: options.stopSequences,\n responseMimeType:\n options.mode.type === 'object-json'\n ? 'application/json'\n : 'text/plain',\n };\n\n // Map tools if provided in regular mode\n let tools;\n if (options.mode.type === 'regular' && options.mode.tools) {\n // Filter to only function tools (not provider-defined tools)\n const functionTools = options.mode.tools.filter(\n (tool): tool is LanguageModelV1FunctionTool =>\n tool.type === 'function'\n );\n if (functionTools.length > 0) {\n tools = mapToolsToGeminiFormat(functionTools);\n }\n }\n\n // Create the request parameters\n const request: GenerateContentParameters & {\n systemInstruction?: Content;\n tools?: unknown;\n } = {\n model: this.modelId,\n contents,\n config: generationConfig,\n };\n\n // Add system instruction if present - Gemini supports this as a separate field\n if (systemInstruction) {\n request.systemInstruction = systemInstruction;\n }\n\n // Add tools if present\n if (tools) {\n request.tools = tools;\n }\n\n // Generate content\n const response = await contentGenerator.generateContent(request);\n\n // Extract the result\n const candidate = response.candidates?.[0];\n const responseContent = candidate?.content;\n let text = responseContent?.parts?.[0]?.text || '';\n\n // Extract JSON if in object-json mode\n if (options.mode.type === 'object-json' && text) {\n text = extractJson(text);\n }\n\n // Parse tool calls if present\n let toolCalls: LanguageModelV1FunctionToolCall[] | undefined;\n if (responseContent?.parts) {\n toolCalls = responseContent.parts\n .filter((part): part is Part => !!part.functionCall)\n .map((part) => ({\n toolCallType: 'function' as const,\n toolCallId: randomUUID(),\n toolName: part.functionCall!.name || '',\n args: JSON.stringify(part.functionCall!.args || {}),\n }));\n }\n\n return {\n text,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n finishReason: mapGeminiFinishReason(candidate?.finishReason),\n usage: {\n promptTokens: response.usageMetadata?.promptTokenCount || 0,\n completionTokens: response.usageMetadata?.candidatesTokenCount || 0,\n },\n rawCall: {\n rawPrompt: { contents, systemInstruction, generationConfig, tools },\n rawSettings: generationConfig as Record<string, unknown>,\n },\n rawResponse: {\n body: response,\n },\n response: {\n id: randomUUID(),\n timestamp: new Date(),\n modelId: this.modelId,\n },\n };\n } catch (error) {\n throw mapGeminiError(error);\n }\n }\n\n /**\n * Streaming generation method\n */\n async doStream(options: LanguageModelV1CallOptions): Promise<{\n stream: ReadableStream<LanguageModelV1StreamPart>;\n rawCall: {\n rawPrompt: unknown;\n rawSettings: Record<string, unknown>;\n };\n rawResponse?: {\n headers?: Record<string, string>;\n };\n warnings?: LanguageModelV1CallWarning[];\n }> {\n try {\n const { contentGenerator } = await this.ensureInitialized();\n\n // Map the prompt to Gemini format\n const { contents, systemInstruction } = mapPromptToGeminiFormat(options);\n\n // Prepare generation config\n const generationConfig: GenerateContentConfig = {\n temperature: options.temperature,\n topP: options.topP,\n topK: options.topK,\n maxOutputTokens: options.maxTokens || 65536, // Default to 65536 (64K) - max supported by Gemini 2.5 models\n stopSequences: options.stopSequences,\n responseMimeType:\n options.mode.type === 'object-json'\n ? 'application/json'\n : 'text/plain',\n };\n\n // Map tools if provided in regular mode\n let tools;\n if (options.mode.type === 'regular' && options.mode.tools) {\n // Filter to only function tools (not provider-defined tools)\n const functionTools = options.mode.tools.filter(\n (tool): tool is LanguageModelV1FunctionTool =>\n tool.type === 'function'\n );\n if (functionTools.length > 0) {\n tools = mapToolsToGeminiFormat(functionTools);\n }\n }\n\n // Create the request parameters\n const request: GenerateContentParameters & {\n systemInstruction?: Content;\n tools?: unknown;\n } = {\n model: this.modelId,\n contents,\n config: generationConfig,\n };\n\n // Add system instruction if present - Gemini supports this as a separate field\n if (systemInstruction) {\n request.systemInstruction = systemInstruction;\n }\n\n // Add tools if present\n if (tools) {\n request.tools = tools;\n }\n\n // Create streaming response\n const streamResponse =\n await contentGenerator.generateContentStream(request);\n\n // Transform the stream to AI SDK format\n const stream = new ReadableStream<LanguageModelV1StreamPart>({\n async start(controller) {\n try {\n let accumulatedText = '';\n const isObjectJsonMode = options.mode.type === 'object-json';\n\n for await (const chunk of streamResponse) {\n const candidate = chunk.candidates?.[0];\n const content = candidate?.content;\n\n if (content?.parts) {\n for (const part of content.parts) {\n if (part.text) {\n if (isObjectJsonMode) {\n // In object-json mode, accumulate text\n accumulatedText += part.text;\n } else {\n // In regular mode, stream immediately\n controller.enqueue({\n type: 'text-delta',\n textDelta: part.text,\n });\n }\n } else if (part.functionCall) {\n controller.enqueue({\n type: 'tool-call',\n toolCallType: 'function',\n toolCallId: randomUUID(),\n toolName: part.functionCall.name || '',\n args: JSON.stringify(part.functionCall.args || {}),\n });\n }\n }\n }\n\n if (candidate?.finishReason) {\n // If in object-json mode, extract and emit the JSON before finishing\n if (isObjectJsonMode && accumulatedText) {\n const extractedJson = extractJson(accumulatedText);\n controller.enqueue({\n type: 'text-delta',\n textDelta: extractedJson,\n });\n }\n\n controller.enqueue({\n type: 'finish',\n finishReason: mapGeminiFinishReason(candidate.finishReason),\n usage: {\n promptTokens: chunk.usageMetadata?.promptTokenCount || 0,\n completionTokens:\n chunk.usageMetadata?.candidatesTokenCount || 0,\n },\n });\n }\n }\n\n // Final check for object-json mode if we didn't get a finish reason\n if (\n isObjectJsonMode &&\n accumulatedText &&\n !controller.desiredSize\n ) {\n const extractedJson = extractJson(accumulatedText);\n controller.enqueue({\n type: 'text-delta',\n textDelta: extractedJson,\n });\n }\n\n controller.close();\n } catch (error) {\n controller.error(mapGeminiError(error));\n }\n },\n });\n\n return {\n stream,\n rawCall: {\n rawPrompt: { contents, systemInstruction, generationConfig, tools },\n rawSettings: generationConfig as Record<string, unknown>,\n },\n };\n } catch (error) {\n throw mapGeminiError(error);\n }\n }\n}\n","import type {\n ContentGenerator,\n ContentGeneratorConfig,\n} from '@google/gemini-cli-core';\nimport {\n createContentGenerator,\n createContentGeneratorConfig,\n AuthType,\n} from '@google/gemini-cli-core';\nimport type { GeminiProviderOptions } from './types';\n\nexport interface GeminiClient {\n client: ContentGenerator;\n config: ContentGeneratorConfig;\n}\n\n/**\n * Initializes the Gemini client with the provided authentication options\n */\nexport async function initializeGeminiClient(\n options: GeminiProviderOptions,\n modelId: string\n): Promise<GeminiClient> {\n // Map our auth types to Gemini CLI Core auth types\n let authType: AuthType | undefined;\n\n if (options.authType === 'api-key' || options.authType === 'gemini-api-key') {\n authType = AuthType.USE_GEMINI;\n } else if (options.authType === 'vertex-ai') {\n authType = AuthType.USE_VERTEX_AI;\n } else if (\n options.authType === 'oauth' ||\n options.authType === 'oauth-personal'\n ) {\n authType = AuthType.LOGIN_WITH_GOOGLE;\n } else if (options.authType === 'google-auth-library') {\n // Google Auth Library is not directly supported by AuthType enum\n // We'll need to handle this differently or use a default\n authType = AuthType.USE_GEMINI;\n }\n\n // Create a minimal config object that implements the required methods\n const configMock = {\n getModel: () => modelId,\n getProxy: () =>\n options.proxy ||\n process.env.HTTP_PROXY ||\n process.env.HTTPS_PROXY ||\n undefined,\n };\n\n // Create the configuration\n const config = createContentGeneratorConfig(\n configMock as Parameters<typeof createContentGeneratorConfig>[0],\n authType\n );\n\n // Apply additional configuration based on auth type\n if (\n (options.authType === 'api-key' || options.authType === 'gemini-api-key') &&\n options.apiKey\n ) {\n config.apiKey = options.apiKey;\n } else if (options.authType === 'vertex-ai' && options.vertexAI) {\n config.vertexai = true;\n // Note: Vertex AI project/location configuration might need to be\n // handled through environment variables or other means\n }\n\n // Create content generator - pass the configMock as the second parameter\n const client = await createContentGenerator(\n config,\n configMock as Parameters<typeof createContentGenerator>[1]\n );\n\n return { client, config };\n}\n","import type {\n LanguageModelV1CallOptions,\n LanguageModelV1Message,\n LanguageModelV1ImagePart,\n LanguageModelV1ToolResultPart,\n} from '@ai-sdk/provider';\nimport type { Content, Part } from '@google/genai';\n\nexport interface GeminiPromptResult {\n contents: Content[];\n systemInstruction?: Content;\n}\n\n/**\n * Maps Vercel AI SDK messages to Gemini format\n */\nexport function mapPromptToGeminiFormat(\n options: LanguageModelV1CallOptions\n): GeminiPromptResult {\n let messages = options.prompt;\n const contents: Content[] = [];\n let systemInstruction: Content | undefined;\n\n // If in object-json mode, enhance the last user message with schema information\n if (\n options.mode?.type === 'object-json' &&\n options.mode.schema &&\n messages.length > 0\n ) {\n const lastMessage = messages[messages.length - 1];\n if (lastMessage.role === 'user' && Array.isArray(lastMessage.content)) {\n const schemaPrompt = `\\n\\nYou must respond with a JSON object that exactly matches this schema:\\n${JSON.stringify(options.mode.schema, null, 2)}\\n\\nIMPORTANT: Use the exact field names from the schema. Do not add extra fields.`;\n\n // Clone the messages array and modify the last message\n messages = [...messages];\n const lastContent = [...lastMessage.content];\n\n // Find the last text content and append to it\n for (let i = lastContent.length - 1; i >= 0; i--) {\n const content = lastContent[i];\n if (content.type === 'text') {\n lastContent[i] = {\n ...content,\n text: content.text + schemaPrompt,\n };\n break;\n }\n }\n\n messages[messages.length - 1] = {\n ...lastMessage,\n content: lastContent,\n };\n }\n }\n\n for (const message of messages) {\n switch (message.role) {\n case 'system':\n // Gemini uses a separate systemInstruction field\n systemInstruction = {\n role: 'user',\n parts: [{ text: message.content }],\n };\n break;\n\n case 'user':\n contents.push(mapUserMessage(message));\n break;\n\n case 'assistant':\n contents.push(mapAssistantMessage(message));\n break;\n\n case 'tool':\n // Tool results are typically merged with the previous assistant message\n // For now, we'll add them as a user message\n contents.push({\n role: 'user',\n parts: message.content.map((part: LanguageModelV1ToolResultPart) =>\n mapToolResultPart(part)\n ),\n });\n break;\n }\n }\n\n return { contents, systemInstruction };\n}\n\n/**\n * Maps a user message to Gemini format\n */\nfunction mapUserMessage(\n message: LanguageModelV1Message & { role: 'user' }\n): Content {\n const parts: Part[] = [];\n\n for (const part of message.content) {\n switch (part.type) {\n case 'text':\n parts.push({ text: part.text });\n break;\n\n case 'image':\n parts.push(mapImagePart(part));\n break;\n }\n }\n\n return { role: 'user', parts };\n}\n\n/**\n * Maps an assistant message to Gemini format\n */\nfunction mapAssistantMessage(\n message: LanguageModelV1Message & { role: 'assistant' }\n): Content {\n const parts: Part[] = [];\n\n for (const part of message.content) {\n switch (part.type) {\n case 'text':\n parts.push({ text: part.text });\n break;\n\n case 'tool-call':\n parts.push({\n functionCall: {\n name: part.toolName,\n args: (part.args || {}) as Record<string, unknown>,\n },\n });\n break;\n }\n }\n\n return { role: 'model', parts };\n}\n\n/**\n * Maps an image part to Gemini format\n */\nfunction mapImagePart(part: LanguageModelV1ImagePart): Part {\n if (part.image instanceof URL) {\n throw new Error(\n 'URL images are not supported by Gemini CLI Core. Please provide base64-encoded image data.'\n );\n }\n\n // Extract mime type and base64 data\n const mimeType = part.mimeType || 'image/jpeg';\n let base64Data: string;\n\n if (typeof part.image === 'string') {\n // Already base64 encoded\n base64Data = part.image;\n } else if (part.image instanceof Uint8Array) {\n // Convert Uint8Array to base64\n base64Data = Buffer.from(part.image).toString('base64');\n } else {\n throw new Error('Unsupported image format');\n }\n\n return {\n inlineData: {\n mimeType,\n data: base64Data,\n },\n };\n}\n\n/**\n * Maps a tool result part to Gemini format\n */\nfunction mapToolResultPart(part: LanguageModelV1ToolResultPart): Part {\n return {\n functionResponse: {\n name: part.toolName,\n response: part.result as Record<string, unknown>,\n },\n };\n}\n","import type { LanguageModelV1FunctionTool } from '@ai-sdk/provider';\nimport type { Tool, FunctionDeclaration, Schema } from '@google/genai';\nimport { zodToJsonSchema } from 'zod-to-json-schema';\nimport { z } from 'zod';\n\n// Type for JSON Schema objects with common properties\ninterface JsonSchemaObject {\n $schema?: string;\n $ref?: string;\n $defs?: unknown;\n definitions?: unknown;\n properties?: Record<string, unknown>;\n items?: unknown;\n additionalProperties?: unknown;\n allOf?: unknown[];\n anyOf?: unknown[];\n oneOf?: unknown[];\n [key: string]: unknown;\n}\n\n/**\n * Maps Vercel AI SDK tools to Gemini format\n */\nexport function mapToolsToGeminiFormat(\n tools: LanguageModelV1FunctionTool[]\n): Tool[] {\n const functionDeclarations: FunctionDeclaration[] = [];\n\n for (const tool of tools) {\n functionDeclarations.push({\n name: tool.name,\n description: tool.description,\n parameters: convertToolParameters(tool.parameters),\n });\n }\n\n return [{ functionDeclarations }];\n}\n\n/**\n * Converts tool parameters from Zod schema or JSON schema to Gemini format\n */\nfunction convertToolParameters(parameters: unknown): Schema {\n // If it's already a plain object (JSON schema), clean it\n if (isJsonSchema(parameters)) {\n return cleanJsonSchema(parameters as JsonSchemaObject) as Schema;\n }\n\n // If it's a Zod schema, convert to JSON schema first\n if (isZodSchema(parameters)) {\n const jsonSchema = zodToJsonSchema(parameters as z.ZodSchema);\n return cleanJsonSchema(jsonSchema) as Schema;\n }\n\n // Return a basic schema if we can't identify the format\n return parameters as Schema;\n}\n\n/**\n * Checks if an object is a JSON schema\n */\nfunction isJsonSchema(obj: unknown): boolean {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n ('type' in obj || 'properties' in obj || '$schema' in obj)\n );\n}\n\n/**\n * Checks if an object is a Zod schema\n */\nfunction isZodSchema(obj: unknown): obj is z.ZodTypeAny {\n return (\n typeof obj === 'object' &&\n obj !== null &&\n '_def' in obj &&\n typeof (obj as z.ZodTypeAny)._def === 'object'\n );\n}\n\n/**\n * Cleans JSON schema for Gemini compatibility\n * Removes $schema and other metadata that Gemini doesn't support\n */\nfunction cleanJsonSchema(schema: JsonSchemaObject): JsonSchemaObject {\n if (typeof schema !== 'object' || schema === null) {\n return schema;\n }\n\n const cleaned = { ...schema };\n\n // Remove $schema property\n delete cleaned.$schema;\n delete cleaned.$ref;\n delete cleaned.$defs;\n delete cleaned.definitions;\n\n // Recursively clean nested schemas\n if (cleaned.properties && typeof cleaned.properties === 'object') {\n const cleanedProps: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(cleaned.properties)) {\n cleanedProps[key] = cleanJsonSchema(value as JsonSchemaObject);\n }\n cleaned.properties = cleanedProps;\n }\n\n if (cleaned.items) {\n cleaned.items = cleanJsonSchema(cleaned.items as JsonSchemaObject);\n }\n\n if (\n cleaned.additionalProperties &&\n typeof cleaned.additionalProperties === 'object'\n ) {\n cleaned.additionalProperties = cleanJsonSchema(\n cleaned.additionalProperties as JsonSchemaObject\n );\n }\n\n // Clean arrays\n for (const key of ['allOf', 'anyOf', 'oneOf'] as const) {\n const arrayProp = cleaned[key];\n if (Array.isArray(arrayProp)) {\n cleaned[key] = arrayProp.map((item) =>\n cleanJsonSchema(item as JsonSchemaObject)\n );\n }\n }\n\n return cleaned;\n}\n","import { APICallError } from '@ai-sdk/provider';\n\n/**\n * Maps Gemini errors to Vercel AI SDK errors\n */\nexport function mapGeminiError(error: unknown): APICallError {\n if (error instanceof Error) {\n const message = error.message.toLowerCase();\n\n // Check for rate limit errors\n if (message.includes('rate limit') || message.includes('quota')) {\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 429,\n responseHeaders: {},\n message: error.message,\n cause: error,\n data: {},\n isRetryable: true,\n });\n }\n\n // Check for authentication errors\n if (\n message.includes('unauthorized') ||\n message.includes('authentication') ||\n message.includes('api key')\n ) {\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 401,\n responseHeaders: {},\n message: error.message,\n cause: error,\n data: {},\n isRetryable: false,\n });\n }\n\n // Check for invalid request errors\n if (message.includes('invalid') || message.includes('bad request')) {\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 400,\n responseHeaders: {},\n message: error.message,\n cause: error,\n data: {},\n isRetryable: false,\n });\n }\n\n // Check for model not found\n if (message.includes('not found') || message.includes('model')) {\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 404,\n responseHeaders: {},\n message: error.message,\n cause: error,\n data: {},\n isRetryable: false,\n });\n }\n\n // Default to internal server error\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 500,\n responseHeaders: {},\n message: error.message,\n cause: error,\n data: {},\n isRetryable: true,\n });\n }\n\n // Unknown error type\n return new APICallError({\n url: 'gemini-cli-core',\n requestBodyValues: {},\n statusCode: 500,\n responseHeaders: {},\n message: 'An unknown error occurred',\n cause: error,\n data: {},\n isRetryable: true,\n });\n}\n","/**\n * Extract JSON from model response using a tolerant parser.\n * Removes common wrappers such as markdown fences or variable declarations.\n */\nexport function extractJson(text: string): string {\n let content = text.trim();\n\n // Strip ```json or ``` fences\n const fenceMatch = /```(?:json)?\\s*([\\s\\S]*?)\\s*```/i.exec(content);\n if (fenceMatch) {\n content = fenceMatch[1];\n }\n\n // Strip variable declarations like `const foo =` or `let foo =`\n const varMatch = /^\\s*(?:const|let|var)\\s+\\w+\\s*=\\s*([\\s\\S]*)/i.exec(content);\n if (varMatch) {\n content = varMatch[1];\n // Remove trailing semicolon if present\n if (content.trim().endsWith(';')) {\n content = content.trim().slice(0, -1);\n }\n }\n\n // Find the first opening bracket\n const firstObj = content.indexOf('{');\n const firstArr = content.indexOf('[');\n if (firstObj === -1 && firstArr === -1) {\n return text;\n }\n const start =\n firstArr === -1\n ? firstObj\n : firstObj === -1\n ? firstArr\n : Math.min(firstObj, firstArr);\n content = content.slice(start);\n\n // Try to parse the entire string\n try {\n const parsed = JSON.parse(content) as unknown;\n return JSON.stringify(parsed);\n } catch {\n // Continue with more lenient parsing\n }\n\n // Find valid JSON boundaries by tracking nesting depth\n const openChar = content[0];\n const closeChar = openChar === '{' ? '}' : ']';\n\n const closingPositions: number[] = [];\n let depth = 0;\n let inString = false;\n let escapeNext = false;\n\n for (let i = 0; i < content.length; i++) {\n const char = content[i];\n\n if (escapeNext) {\n escapeNext = false;\n continue;\n }\n\n if (char === '\\\\') {\n escapeNext = true;\n continue;\n }\n\n if (char === '\"' && !inString) {\n inString = true;\n continue;\n }\n\n if (char === '\"' && inString) {\n inString = false;\n continue;\n }\n\n // Skip content inside strings\n if (inString) continue;\n\n if (char === openChar) {\n depth++;\n } else if (char === closeChar) {\n depth--;\n if (depth === 0) {\n closingPositions.push(i + 1);\n }\n }\n }\n\n // Try parsing at each valid closing position, starting from the end\n for (let i = closingPositions.length - 1; i >= 0; i--) {\n try {\n const attempt = content.slice(0, closingPositions[i]);\n const parsed = JSON.parse(attempt) as unknown;\n return JSON.stringify(parsed);\n } catch {\n // Continue trying\n }\n }\n\n return text;\n}\n","import type { GeminiProviderOptions } from './types';\n\n/**\n * Validates the authentication options for the Gemini provider.\n * Ensures that the provided configuration has valid authentication credentials.\n *\n * @param options - The provider options to validate\n * @returns The validated options\n * @throws Error if authentication configuration is invalid\n */\nexport function validateAuthOptions(\n options: GeminiProviderOptions = {}\n): GeminiProviderOptions {\n // Default to oauth-personal if no authType specified\n const authType = options.authType || 'oauth-personal';\n\n // Validate based on auth type\n switch (authType) {\n case 'api-key':\n case 'gemini-api-key':\n if (!('apiKey' in options) || !options.apiKey) {\n throw new Error(`API key is required for ${authType} auth type`);\n }\n return { ...options, authType };\n\n case 'vertex-ai':\n if ('vertexAI' in options && options.vertexAI) {\n if (\n !options.vertexAI.projectId ||\n options.vertexAI.projectId.trim() === ''\n ) {\n throw new Error('Project ID is required for vertex-ai auth type');\n }\n if (\n !options.vertexAI.location ||\n options.vertexAI.location.trim() === ''\n ) {\n throw new Error('Location is required for vertex-ai auth type');\n }\n } else {\n throw new Error(\n 'Vertex AI configuration is required for vertex-ai auth type'\n );\n }\n return { ...options, authType };\n\n case 'oauth':\n case 'oauth-personal':\n // No additional validation needed for oauth\n return { ...options, authType };\n\n case 'google-auth-library':\n if (!('googleAuth' in options) || !options.googleAuth) {\n throw new Error(\n 'Google Auth Library instance is required for google-auth-library auth type'\n );\n }\n return { ...options, authType };\n\n default:\n throw new Error(`Invalid auth type: ${String(authType)}`);\n }\n}\n","import type { ProviderV1 } from '@ai-sdk/provider';\nimport { GeminiLanguageModel } from './gemini-language-model';\nimport type { GeminiProviderOptions } from './types';\nimport { validateAuthOptions } from './validation';\n\nexport interface GeminiProvider extends ProviderV1 {\n (modelId: string, settings?: Record<string, unknown>): GeminiLanguageModel;\n languageModel(\n modelId: string,\n settings?: Record<string, unknown>\n ): GeminiLanguageModel;\n chat(\n modelId: string,\n settings?: Record<string, unknown>\n ): GeminiLanguageModel;\n}\n\n/**\n * Creates a new Gemini provider instance.\n *\n * @param options - Configuration options for the provider\n * @returns A configured provider function\n * @throws Error if authentication options are invalid\n *\n * @example\n * ```typescript\n * // Using API key authentication\n * const gemini = createGeminiProvider({\n * authType: 'gemini-api-key',\n * apiKey: process.env.GEMINI_API_KEY\n * });\n *\n * // Use with Vercel AI SDK\n * const model = gemini('gemini-1.5-flash');\n * const result = await generateText({\n * model,\n * prompt: 'Hello, world!'\n * });\n * ```\n */\nexport function createGeminiProvider(\n options: GeminiProviderOptions = {}\n): GeminiProvider {\n // Validate authentication options\n const validatedOptions = validateAuthOptions(options);\n\n // Create the language model factory function\n const createLanguageModel = (\n modelId: string,\n settings?: Record<string, unknown>\n ) => {\n return new GeminiLanguageModel({\n modelId,\n providerOptions: validatedOptions,\n settings,\n });\n };\n\n // Create the provider function\n const provider = function (\n modelId: string,\n settings?: Record<string, unknown>\n ) {\n if (new.target) {\n throw new Error(\n 'The provider function cannot be called with the new keyword.'\n );\n }\n\n return createLanguageModel(modelId, settings);\n } as GeminiProvider;\n\n // Attach methods\n provider.languageModel = createLanguageModel;\n provider.chat = createLanguageModel;\n\n return provider;\n}\n"],"mappings":"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","names":[]}