@providerprotocol/ai 0.0.33 → 0.0.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/README.md +542 -3
  2. package/dist/anthropic/index.d.ts +2 -1
  3. package/dist/anthropic/index.js +151 -145
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/cerebras/index.d.ts +392 -0
  6. package/dist/cerebras/index.js +648 -0
  7. package/dist/cerebras/index.js.map +1 -0
  8. package/dist/chunk-3GWM5GR3.js +153 -0
  9. package/dist/chunk-3GWM5GR3.js.map +1 -0
  10. package/dist/chunk-4OGB7JZA.js +157 -0
  11. package/dist/chunk-4OGB7JZA.js.map +1 -0
  12. package/dist/chunk-7DXVRILR.js +49 -0
  13. package/dist/chunk-7DXVRILR.js.map +1 -0
  14. package/dist/{chunk-3C7O2RNO.js → chunk-A2IM7PGT.js} +6 -4
  15. package/dist/{chunk-3C7O2RNO.js.map → chunk-A2IM7PGT.js.map} +1 -1
  16. package/dist/{chunk-3D6XGGVG.js → chunk-ARVM24K2.js} +2 -2
  17. package/dist/{chunk-4J6OFUKX.js → chunk-AY55T37A.js} +70 -162
  18. package/dist/chunk-AY55T37A.js.map +1 -0
  19. package/dist/{chunk-ILR2D5PN.js → chunk-BRP5XJ6Q.js} +2 -86
  20. package/dist/chunk-BRP5XJ6Q.js.map +1 -0
  21. package/dist/chunk-C4JP64VW.js +298 -0
  22. package/dist/chunk-C4JP64VW.js.map +1 -0
  23. package/dist/chunk-COS4ON4G.js +111 -0
  24. package/dist/chunk-COS4ON4G.js.map +1 -0
  25. package/dist/chunk-ETBFOLQN.js +34 -0
  26. package/dist/chunk-ETBFOLQN.js.map +1 -0
  27. package/dist/chunk-HB4ZIH3T.js +31 -0
  28. package/dist/chunk-HB4ZIH3T.js.map +1 -0
  29. package/dist/chunk-I53CI6ZZ.js +142 -0
  30. package/dist/chunk-I53CI6ZZ.js.map +1 -0
  31. package/dist/chunk-IDZOVWP3.js +29 -0
  32. package/dist/chunk-IDZOVWP3.js.map +1 -0
  33. package/dist/chunk-JA3UZALR.js +88 -0
  34. package/dist/chunk-JA3UZALR.js.map +1 -0
  35. package/dist/{chunk-WAKD3OO5.js → chunk-N5DX5JW3.js} +31 -31
  36. package/dist/chunk-N5DX5JW3.js.map +1 -0
  37. package/dist/chunk-OIEWDFQU.js +97 -0
  38. package/dist/chunk-OIEWDFQU.js.map +1 -0
  39. package/dist/{chunk-TOJCZMVU.js → chunk-PMK5LZ5Z.js} +40 -40
  40. package/dist/chunk-PMK5LZ5Z.js.map +1 -0
  41. package/dist/chunk-UFFJDYCE.js +94 -0
  42. package/dist/chunk-UFFJDYCE.js.map +1 -0
  43. package/dist/chunk-VGKZIGVI.js +222 -0
  44. package/dist/chunk-VGKZIGVI.js.map +1 -0
  45. package/dist/chunk-VOEWHQUB.js +31 -0
  46. package/dist/chunk-VOEWHQUB.js.map +1 -0
  47. package/dist/{chunk-KUPF5KHT.js → chunk-Y5H7C5J4.js} +2 -2
  48. package/dist/chunk-ZI67WIQS.js +30 -0
  49. package/dist/chunk-ZI67WIQS.js.map +1 -0
  50. package/dist/{embedding-D2BYIehX.d.ts → embedding-CW6SaOOz.d.ts} +1 -1
  51. package/dist/google/index.d.ts +2 -1
  52. package/dist/google/index.js +202 -199
  53. package/dist/google/index.js.map +1 -1
  54. package/dist/groq/index.d.ts +410 -0
  55. package/dist/groq/index.js +649 -0
  56. package/dist/groq/index.js.map +1 -0
  57. package/dist/http/index.d.ts +3 -2
  58. package/dist/http/index.js +5 -4
  59. package/dist/image-stream-C0ciACM2.d.ts +11 -0
  60. package/dist/index.d.ts +8 -118
  61. package/dist/index.js +518 -767
  62. package/dist/index.js.map +1 -1
  63. package/dist/{llm-BQJZj3cD.d.ts → llm-DwbUK7un.d.ts} +12 -1632
  64. package/dist/middleware/logging/index.d.ts +76 -0
  65. package/dist/middleware/logging/index.js +74 -0
  66. package/dist/middleware/logging/index.js.map +1 -0
  67. package/dist/middleware/parsed-object/index.d.ts +45 -0
  68. package/dist/middleware/parsed-object/index.js +73 -0
  69. package/dist/middleware/parsed-object/index.js.map +1 -0
  70. package/dist/middleware/pubsub/index.d.ts +104 -0
  71. package/dist/middleware/pubsub/index.js +230 -0
  72. package/dist/middleware/pubsub/index.js.map +1 -0
  73. package/dist/middleware/pubsub/server/express/index.d.ts +52 -0
  74. package/dist/middleware/pubsub/server/express/index.js +11 -0
  75. package/dist/middleware/pubsub/server/express/index.js.map +1 -0
  76. package/dist/middleware/pubsub/server/fastify/index.d.ts +53 -0
  77. package/dist/middleware/pubsub/server/fastify/index.js +11 -0
  78. package/dist/middleware/pubsub/server/fastify/index.js.map +1 -0
  79. package/dist/middleware/pubsub/server/h3/index.d.ts +56 -0
  80. package/dist/middleware/pubsub/server/h3/index.js +11 -0
  81. package/dist/middleware/pubsub/server/h3/index.js.map +1 -0
  82. package/dist/middleware/pubsub/server/index.d.ts +78 -0
  83. package/dist/middleware/pubsub/server/index.js +34 -0
  84. package/dist/middleware/pubsub/server/index.js.map +1 -0
  85. package/dist/middleware/pubsub/server/webapi/index.d.ts +53 -0
  86. package/dist/middleware/pubsub/server/webapi/index.js +11 -0
  87. package/dist/middleware/pubsub/server/webapi/index.js.map +1 -0
  88. package/dist/ollama/index.d.ts +2 -1
  89. package/dist/ollama/index.js +48 -45
  90. package/dist/ollama/index.js.map +1 -1
  91. package/dist/openai/index.d.ts +2 -1
  92. package/dist/openai/index.js +319 -313
  93. package/dist/openai/index.js.map +1 -1
  94. package/dist/openrouter/index.d.ts +2 -1
  95. package/dist/openrouter/index.js +379 -383
  96. package/dist/openrouter/index.js.map +1 -1
  97. package/dist/proxy/index.d.ts +10 -914
  98. package/dist/proxy/index.js +275 -1007
  99. package/dist/proxy/index.js.map +1 -1
  100. package/dist/proxy/server/express/index.d.ts +161 -0
  101. package/dist/proxy/server/express/index.js +24 -0
  102. package/dist/proxy/server/express/index.js.map +1 -0
  103. package/dist/proxy/server/fastify/index.d.ts +162 -0
  104. package/dist/proxy/server/fastify/index.js +24 -0
  105. package/dist/proxy/server/fastify/index.js.map +1 -0
  106. package/dist/proxy/server/h3/index.d.ts +189 -0
  107. package/dist/proxy/server/h3/index.js +28 -0
  108. package/dist/proxy/server/h3/index.js.map +1 -0
  109. package/dist/proxy/server/index.d.ts +151 -0
  110. package/dist/proxy/server/index.js +48 -0
  111. package/dist/proxy/server/index.js.map +1 -0
  112. package/dist/proxy/server/webapi/index.d.ts +278 -0
  113. package/dist/proxy/server/webapi/index.js +32 -0
  114. package/dist/proxy/server/webapi/index.js.map +1 -0
  115. package/dist/responses/index.d.ts +650 -0
  116. package/dist/responses/index.js +930 -0
  117. package/dist/responses/index.js.map +1 -0
  118. package/dist/{retry-8Ch-WWgX.d.ts → retry-YayV42GV.d.ts} +1 -1
  119. package/dist/stream-CecfVCPO.d.ts +1632 -0
  120. package/dist/types-C8Gciizr.d.ts +168 -0
  121. package/dist/utils/index.d.ts +53 -0
  122. package/dist/utils/index.js +7 -0
  123. package/dist/utils/index.js.map +1 -0
  124. package/dist/xai/index.d.ts +2 -1
  125. package/dist/xai/index.js +310 -310
  126. package/dist/xai/index.js.map +1 -1
  127. package/package.json +94 -4
  128. package/dist/chunk-4J6OFUKX.js.map +0 -1
  129. package/dist/chunk-ILR2D5PN.js.map +0 -1
  130. package/dist/chunk-TOJCZMVU.js.map +0 -1
  131. package/dist/chunk-WAKD3OO5.js.map +0 -1
  132. /package/dist/{chunk-3D6XGGVG.js.map → chunk-ARVM24K2.js.map} +0 -0
  133. /package/dist/{chunk-KUPF5KHT.js.map → chunk-Y5H7C5J4.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/providers/google/transform.ts","../../src/providers/google/llm.ts","../../src/providers/google/embed.ts","../../src/providers/google/image.ts","../../src/providers/google/cache.ts","../../src/providers/google/types.ts","../../src/providers/google/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation functions between UPP format and Google Gemini API format.\n *\n * This module handles the bidirectional conversion of requests, responses, and\n * streaming chunks between the Unified Provider Protocol (UPP) format and\n * Google's Generative Language API format.\n *\n * Key transformations:\n * - UPP messages with content blocks to Google's parts-based content structure\n * - UPP tools to Google's functionDeclarations format\n * - Google responses back to UPP LLMResponse with proper message types\n * - Streaming chunks to UPP StreamEvents\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type {\n ContentBlock,\n AssistantContent,\n ImageBlock,\n DocumentBlock,\n AudioBlock,\n VideoBlock,\n} from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport type {\n GoogleLLMParams,\n GoogleRequest,\n GoogleContent,\n GooglePart,\n GoogleTextPart,\n GoogleTool,\n GoogleResponse,\n GoogleStreamChunk,\n GoogleFunctionCallPart,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLM request into Google Gemini API format.\n *\n * Converts the UPP message structure, system prompt, tools, and generation\n * parameters into Google's expected request body format. Provider-specific\n * parameters are passed through to `generationConfig` to support new API\n * features without library updates.\n *\n * @typeParam TParams - Type extending GoogleLLMParams for provider-specific options\n * @param request - The UPP-formatted LLM request\n * @param modelId - The target Gemini model identifier\n * @returns Google API request body ready for submission\n *\n * @example\n * ```typescript\n * const googleRequest = transformRequest({\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * system: 'You are a helpful assistant',\n * params: { temperature: 0.7 },\n * config: { apiKey: '...' },\n * }, 'gemini-1.5-pro');\n * ```\n */\nexport function transformRequest<TParams extends GoogleLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): GoogleRequest {\n const params = (request.params ?? {}) as GoogleLLMParams;\n const { cachedContent, tools: builtInTools, toolConfig, ...generationParams } = params;\n\n const googleRequest: GoogleRequest = {\n contents: transformMessages(request.messages),\n };\n\n const normalizedSystem = normalizeSystem(request.system);\n if (normalizedSystem !== undefined) {\n if (typeof normalizedSystem === 'string') {\n googleRequest.systemInstruction = {\n parts: [{ text: normalizedSystem }],\n };\n } else if (normalizedSystem.length > 0) {\n googleRequest.systemInstruction = {\n parts: normalizedSystem,\n };\n }\n }\n\n const generationConfig: NonNullable<GoogleRequest['generationConfig']> = {\n ...generationParams,\n };\n\n if (request.structure) {\n generationConfig.responseMimeType = 'application/json';\n generationConfig.responseSchema = request.structure as unknown as Record<string, unknown>;\n }\n\n if (Object.keys(generationConfig).length > 0) {\n googleRequest.generationConfig = generationConfig;\n }\n\n // Collect all tools: function declarations + built-in tools\n const requestTools: NonNullable<GoogleRequest['tools']> = [];\n\n if (request.tools && request.tools.length > 0) {\n requestTools.push({\n functionDeclarations: request.tools.map(transformTool),\n });\n }\n\n // Add built-in tools (googleSearch, codeExecution, urlContext, etc.)\n // These are added as separate tool objects, not as function declarations\n if (builtInTools && builtInTools.length > 0) {\n requestTools.push(...builtInTools);\n }\n\n if (requestTools.length > 0) {\n googleRequest.tools = requestTools;\n }\n\n // Add tool config if provided (e.g., for retrievalConfig with Google Maps)\n if (toolConfig) {\n googleRequest.toolConfig = toolConfig;\n }\n\n if (cachedContent) {\n googleRequest.cachedContent = cachedContent;\n }\n\n return googleRequest;\n}\n\nfunction normalizeSystem(system: string | unknown[] | undefined): string | GooglePart[] | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text parts',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const parts: GooglePart[] = [];\n for (const part of system) {\n if (!part || typeof part !== 'object' || !('text' in part)) {\n throw new UPPError(\n 'Google system prompt array must contain text parts',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n const textValue = (part as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'Google system prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n parts.push(part as GooglePart);\n }\n\n return parts.length > 0 ? parts : undefined;\n}\n\nconst GOOGLE_TOOLCALL_PREFIX = 'google_toolcall';\n\nfunction createGoogleToolCallId(name: string, index: number): string {\n return `${GOOGLE_TOOLCALL_PREFIX}:${index}:${name}`;\n}\n\nfunction extractGoogleToolName(toolCallId: string): string {\n const prefix = `${GOOGLE_TOOLCALL_PREFIX}:`;\n if (!toolCallId.startsWith(prefix)) {\n return toolCallId;\n }\n const rest = toolCallId.slice(prefix.length);\n const separatorIndex = rest.indexOf(':');\n if (separatorIndex === -1) {\n return toolCallId;\n }\n return rest.slice(separatorIndex + 1);\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @typeParam T - Content block type with optional type property\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type property\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transforms UPP message array to Google's content format.\n *\n * Handles the conversion of user messages, assistant messages (including\n * tool calls), and tool result messages to Google's role-based content\n * structure with parts arrays.\n *\n * @param messages - Array of UPP-formatted messages\n * @returns Array of Google content objects with role and parts\n */\nfunction transformMessages(messages: Message[]): GoogleContent[] {\n const contents: GoogleContent[] = [];\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const validContent = filterValidContent(msg.content);\n const parts = validContent.map(transformContentBlock);\n if (parts.length === 0) {\n parts.push({ text: '' });\n }\n contents.push({\n role: 'user',\n parts,\n });\n } else if (isAssistantMessage(msg)) {\n const validContent = filterValidContent(msg.content);\n // Filter out reasoning blocks - they're preserved via thoughtSignature in metadata\n const nonReasoningContent = validContent.filter(c => c.type !== 'reasoning');\n const parts: GooglePart[] = nonReasoningContent.map(transformContentBlock);\n\n const googleMeta = msg.metadata?.google as {\n functionCallParts?: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }>;\n // Thought signature from text response (Gemini 3+ multi-turn context)\n thoughtSignature?: string;\n } | undefined;\n\n // Add thoughtSignature to the last text part for multi-turn context preservation\n if (googleMeta?.thoughtSignature) {\n // Find the last text part and add the signature\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i];\n if (part && 'text' in part) {\n (part as GoogleTextPart).thoughtSignature = googleMeta.thoughtSignature;\n break;\n }\n }\n }\n\n if (googleMeta?.functionCallParts && googleMeta.functionCallParts.length > 0) {\n for (const fc of googleMeta.functionCallParts) {\n const part: GoogleFunctionCallPart = {\n functionCall: {\n id: fc.id,\n name: fc.name,\n args: fc.args,\n },\n };\n if (fc.thoughtSignature) {\n part.thoughtSignature = fc.thoughtSignature;\n }\n parts.push(part);\n }\n } else if (msg.toolCalls) {\n for (const call of msg.toolCalls) {\n parts.push({\n functionCall: {\n name: call.toolName,\n args: call.arguments,\n },\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ text: '' });\n }\n\n contents.push({\n role: 'model',\n parts,\n });\n } else if (isToolResultMessage(msg)) {\n contents.push({\n role: 'user',\n parts: msg.results.map((result) => ({\n functionResponse: {\n name: extractGoogleToolName(result.toolCallId),\n response:\n typeof result.result === 'object'\n ? (result.result as Record<string, unknown>)\n : { result: result.result },\n },\n })),\n });\n }\n }\n\n return contents;\n}\n\n/**\n * Converts a Uint8Array to a base64 string.\n *\n * @param bytes - The byte array to encode\n * @returns Base64-encoded string\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64');\n}\n\n/**\n * Transforms a UPP content block to a Google part.\n *\n * Supports text, image, document, audio, and video content types.\n * Binary data (images, audio, video, PDFs) is sent as base64-encoded inlineData.\n * URL sources are not supported by Google's API directly.\n *\n * @param block - The UPP content block to transform\n * @returns Google-formatted part object\n * @throws Error if the content type is unsupported or uses URL source\n */\nfunction transformContentBlock(block: ContentBlock): GooglePart {\n switch (block.type) {\n case 'text':\n return { text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n let data: string;\n\n if (imageBlock.source.type === 'base64') {\n data = imageBlock.source.data;\n } else if (imageBlock.source.type === 'bytes') {\n data = uint8ArrayToBase64(imageBlock.source.data);\n } else {\n throw new Error('Google API does not support URL image sources directly');\n }\n\n return {\n inlineData: {\n mimeType: imageBlock.mimeType,\n data,\n },\n };\n }\n\n case 'document': {\n const documentBlock = block as DocumentBlock;\n\n if (documentBlock.source.type === 'base64') {\n return {\n inlineData: {\n mimeType: documentBlock.mimeType,\n data: documentBlock.source.data,\n },\n };\n }\n\n if (documentBlock.source.type === 'text') {\n return { text: documentBlock.source.data };\n }\n\n throw new Error('Google API does not support URL document sources directly');\n }\n\n case 'audio': {\n const audioBlock = block as AudioBlock;\n return {\n inlineData: {\n mimeType: audioBlock.mimeType,\n data: uint8ArrayToBase64(audioBlock.data),\n },\n };\n }\n\n case 'video': {\n const videoBlock = block as VideoBlock;\n return {\n inlineData: {\n mimeType: videoBlock.mimeType,\n data: uint8ArrayToBase64(videoBlock.data),\n },\n };\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms a UPP tool definition to Google's function declaration format.\n *\n * @param tool - The UPP tool definition with name, description, and parameters\n * @returns Google function declaration object\n */\nfunction transformTool(tool: Tool): GoogleTool['functionDeclarations'][0] {\n return {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n };\n}\n\n/**\n * Transforms a Google API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, structured data, and usage metadata\n * from Google's response format. Preserves Google-specific metadata like\n * finish reason, safety ratings, and thought signatures for multi-turn\n * tool call conversations.\n *\n * @param data - The raw Google API response\n * @returns Normalized UPP LLMResponse with message, usage, and stop reason\n * @throws Error if response contains no candidates\n *\n * @example\n * ```typescript\n * const response = await fetch(googleApiUrl, options);\n * const data = await response.json();\n * const uppResponse = transformResponse(data);\n * console.log(uppResponse.message.content);\n * ```\n */\nexport function transformResponse(data: GoogleResponse): LLMResponse {\n const candidate = data.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidates in Google response');\n }\n\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n let lastThoughtSignature: string | undefined;\n const functionCallParts: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }> = [];\n\n for (const part of candidate.content.parts) {\n if ('text' in part) {\n const textPart = part as GoogleTextPart;\n // Capture thoughtSignature from the last text part (Gemini 3+ includes on final part)\n if (textPart.thoughtSignature) {\n lastThoughtSignature = textPart.thoughtSignature;\n }\n if (textPart.thought) {\n content.push({ type: 'reasoning', text: textPart.text });\n } else {\n content.push({ type: 'text', text: textPart.text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(textPart.text);\n } catch {\n // Not JSON - may not be structured output\n }\n }\n }\n } else if ('functionCall' in part) {\n const fc = part as GoogleFunctionCallPart;\n const toolCallId = fc.functionCall.id ?? createGoogleToolCallId(fc.functionCall.name, toolCalls.length);\n toolCalls.push({\n toolCallId,\n toolName: fc.functionCall.name,\n arguments: fc.functionCall.args,\n });\n functionCallParts.push({\n id: fc.functionCall.id,\n name: fc.functionCall.name,\n args: fc.functionCall.args,\n thoughtSignature: fc.thoughtSignature,\n });\n } else if ('inlineData' in part) {\n const imagePart = part as { inlineData: { mimeType?: string; data?: string } };\n const dataString = imagePart.inlineData.data;\n if (dataString) {\n content.push({\n type: 'image',\n mimeType: imagePart.inlineData.mimeType ?? 'image/png',\n source: { type: 'base64', data: dataString },\n } as ImageBlock);\n }\n } else if ('codeExecutionResult' in part) {\n // Append code execution output to text content\n const codeResult = part as { codeExecutionResult: { outcome: string; output: string } };\n if (codeResult.codeExecutionResult.output) {\n content.push({ type: 'text', text: `\\n\\`\\`\\`\\n${codeResult.codeExecutionResult.output}\\`\\`\\`\\n` });\n }\n }\n // executableCode parts are tracked for context but the output is in codeExecutionResult\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n google: {\n finishReason: candidate.finishReason,\n safetyRatings: candidate.safetyRatings,\n functionCallParts: functionCallParts.length > 0 ? functionCallParts : undefined,\n // Store thoughtSignature for multi-turn context preservation (Gemini 3+)\n thoughtSignature: lastThoughtSignature,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n totalTokens: data.usageMetadata?.totalTokenCount ?? 0,\n cacheReadTokens: data.usageMetadata?.cachedContentTokenCount ?? 0,\n cacheWriteTokens: 0,\n };\n\n return {\n message,\n usage,\n stopReason: normalizeStopReason(candidate.finishReason),\n data: structuredData,\n };\n}\n\n/**\n * Accumulator state for streaming responses.\n *\n * Tracks partial content, tool calls, token counts, and stream lifecycle\n * as chunks arrive from the Google streaming API.\n */\nexport interface StreamState {\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated reasoning/thinking content from thought parts. */\n reasoning: string;\n /** Encrypted thought signature for multi-turn context (Gemini 3+). */\n thoughtSignature?: string;\n /** Accumulated tool calls with their arguments and optional thought signatures. */\n toolCalls: Array<{ id: string; nativeId?: string; name: string; args: Record<string, unknown>; thoughtSignature?: string }>;\n /** Base64 image data from inline image response parts. */\n images: Array<{ data: string; mimeType: string }>;\n /** The finish reason from the final chunk, if received. */\n finishReason: string | null;\n /** Total input tokens reported by the API. */\n inputTokens: number;\n /** Total output tokens reported by the API. */\n outputTokens: number;\n /** Number of tokens read from cached content. */\n cacheReadTokens: number;\n /** Flag indicating whether this is the first chunk (for message_start event). */\n isFirstChunk: boolean;\n}\n\n/**\n * Creates a fresh stream state for accumulating streaming responses.\n *\n * @returns Initialized StreamState with empty content and default values\n */\nexport function createStreamState(): StreamState {\n return {\n content: '',\n reasoning: '',\n thoughtSignature: undefined,\n toolCalls: [],\n images: [],\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n isFirstChunk: true,\n };\n}\n\n/**\n * Transforms a Google streaming chunk to UPP StreamEvent array.\n *\n * Processes each streaming chunk, updating the accumulator state and\n * generating appropriate stream events for text deltas, tool calls,\n * and message lifecycle (start/stop).\n *\n * @param chunk - The Google streaming response chunk\n * @param state - Mutable accumulator state updated by this function\n * @returns Array of UPP StreamEvents generated from this chunk\n */\nexport function transformStreamChunk(\n chunk: GoogleStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n if (state.isFirstChunk) {\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n if (chunk.usageMetadata) {\n state.inputTokens = chunk.usageMetadata.promptTokenCount;\n state.outputTokens = chunk.usageMetadata.candidatesTokenCount;\n state.cacheReadTokens = chunk.usageMetadata.cachedContentTokenCount ?? 0;\n }\n\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return events;\n }\n\n for (const part of candidate.content?.parts ?? []) {\n if ('text' in part) {\n const textPart = part as GoogleTextPart;\n if (textPart.thoughtSignature) {\n state.thoughtSignature = textPart.thoughtSignature;\n }\n if (textPart.thought) {\n state.reasoning += textPart.text;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: textPart.text },\n });\n } else {\n state.content += textPart.text;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: textPart.text },\n });\n }\n } else if ('functionCall' in part) {\n const fc = part as GoogleFunctionCallPart;\n const toolCallId = fc.functionCall.id ?? createGoogleToolCallId(fc.functionCall.name, state.toolCalls.length);\n state.toolCalls.push({\n id: toolCallId,\n nativeId: fc.functionCall.id,\n name: fc.functionCall.name,\n args: fc.functionCall.args,\n thoughtSignature: fc.thoughtSignature,\n });\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: state.toolCalls.length - 1,\n delta: {\n toolCallId,\n toolName: fc.functionCall.name,\n argumentsJson: JSON.stringify(fc.functionCall.args),\n },\n });\n } else if ('inlineData' in part) {\n const imagePart = part as { inlineData: { mimeType?: string; data?: string } };\n const dataString = imagePart.inlineData.data;\n if (dataString) {\n state.images.push({\n data: dataString,\n mimeType: imagePart.inlineData.mimeType ?? 'image/png',\n });\n events.push({\n type: StreamEventType.ImageDelta,\n index: state.images.length - 1,\n delta: { data: decodeBase64(dataString) },\n });\n }\n } else if ('codeExecutionResult' in part) {\n // Append code execution output to content and emit as text delta\n const codeResult = part as { codeExecutionResult: { outcome: string; output: string } };\n if (codeResult.codeExecutionResult.output) {\n const outputText = `\\n\\`\\`\\`\\n${codeResult.codeExecutionResult.output}\\`\\`\\`\\n`;\n state.content += outputText;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: outputText },\n });\n }\n }\n // executableCode parts are tracked for context but the output is in codeExecutionResult\n }\n\n if (candidate.finishReason) {\n state.finishReason = candidate.finishReason;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Constructs a complete LLMResponse from accumulated stream state.\n *\n * Called after streaming completes to build the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * @param state - The final accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n const functionCallParts: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }> = [];\n\n if (state.reasoning) {\n content.push({ type: 'reasoning', text: state.reasoning });\n }\n\n if (state.content) {\n content.push({ type: 'text', text: state.content });\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not JSON - may not be structured output\n }\n }\n\n for (const imageData of state.images) {\n content.push({\n type: 'image',\n mimeType: imageData.mimeType,\n source: { type: 'base64', data: imageData.data },\n } as ImageBlock);\n }\n\n for (const tc of state.toolCalls) {\n const toolCallId = tc.id || createGoogleToolCallId(tc.name, toolCalls.length);\n toolCalls.push({\n toolCallId,\n toolName: tc.name,\n arguments: tc.args,\n });\n functionCallParts.push({\n id: tc.nativeId,\n name: tc.name,\n args: tc.args,\n thoughtSignature: tc.thoughtSignature,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n google: {\n finishReason: state.finishReason,\n functionCallParts: functionCallParts.length > 0 ? functionCallParts : undefined,\n thoughtSignature: state.thoughtSignature,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n return {\n message,\n usage,\n stopReason: normalizeStopReason(state.finishReason),\n data: structuredData,\n };\n}\n\nfunction normalizeStopReason(reason: string | null | undefined): string {\n switch (reason) {\n case 'STOP':\n return 'end_turn';\n case 'MAX_TOKENS':\n return 'max_tokens';\n case 'SAFETY':\n case 'RECITATION':\n return 'content_filter';\n case 'TOOL_USE':\n return 'tool_use';\n case 'OTHER':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\nfunction decodeBase64(base64: string): Uint8Array {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i += 1) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\n","import type { BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { LLMHandler } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType, objectDelta } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { GoogleLLMParams, GoogleResponse, GoogleStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Base URL for the Google Generative Language API (v1beta). */\nconst GOOGLE_API_BASE = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Capability flags for the Google Gemini API.\n *\n * Gemini models support streaming responses, function/tool calling,\n * structured JSON output, and multimodal inputs including images,\n * video, and audio.\n */\nconst GOOGLE_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n documentInput: true,\n videoInput: true,\n audioInput: true,\n imageOutput: true,\n};\n\n/**\n * Constructs the Google API endpoint URL for a specific model and action.\n *\n * @param modelId - The Gemini model identifier (e.g., 'gemini-1.5-pro')\n * @param action - The API action to perform\n * @returns Fully qualified URL for the model action\n */\nfunction buildUrl(modelId: string, action: 'generateContent' | 'streamGenerateContent'): string {\n return `${GOOGLE_API_BASE}/models/${modelId}:${action}`;\n}\n\n/**\n * Creates an LLM handler for Google Gemini models.\n *\n * The handler implements the UPP LLMHandler interface, providing `bind()`\n * to create model instances that support both synchronous completion and\n * streaming responses.\n *\n * @returns An LLMHandler configured for Google Gemini API\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const model = handler.bind('gemini-1.5-pro');\n *\n * const response = await model.complete({\n * messages: [...],\n * config: { apiKey: 'your-api-key' },\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<GoogleLLMParams> {\n let providerRef: LLMProvider<GoogleLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<GoogleLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<GoogleLLMParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<GoogleLLMParams> = {\n modelId,\n capabilities: GOOGLE_CAPABILITIES,\n\n get provider(): LLMProvider<GoogleLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<GoogleLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'llm'\n );\n\n const url = request.config.baseUrl\n ? `${request.config.baseUrl}/models/${modelId}:generateContent`\n : buildUrl(modelId, 'generateContent');\n\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'google',\n 'llm'\n );\n\n const data = await parseJsonResponse<GoogleResponse>(response, 'google', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<GoogleLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'llm'\n );\n\n const url = request.config.baseUrl\n ? `${request.config.baseUrl}/models/${modelId}:streamGenerateContent?alt=sse`\n : `${buildUrl(modelId, 'streamGenerateContent')}?alt=sse`;\n\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'google',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'google', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'google',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n if (typeof data === 'object' && data !== null) {\n const chunk = data as GoogleStreamChunk;\n\n if (chunk.error) {\n const error = new UPPError(\n chunk.error.message,\n ErrorCode.ProviderError,\n 'google',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n if (request.structure && event.type === StreamEventType.TextDelta) {\n // Emit ObjectDelta without parsing - middleware handles parsing\n yield objectDelta(event.delta.text ?? '', event.index);\n } else {\n yield event;\n }\n }\n }\n }\n\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Google Gemini Embeddings API Handler\n *\n * This module implements the embedding handler for Google's Gemini embeddings API.\n * Supports gemini-embedding-001 and text-embedding-004 models.\n *\n * @see {@link https://ai.google.dev/gemini-api/docs/embeddings Google Embeddings API Reference}\n * @module providers/google/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Base URL for Google's Gemini API */\nconst GOOGLE_API_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Google task types for embedding optimization.\n */\nexport type GoogleTaskType =\n | 'RETRIEVAL_QUERY'\n | 'RETRIEVAL_DOCUMENT'\n | 'SEMANTIC_SIMILARITY'\n | 'CLASSIFICATION'\n | 'CLUSTERING'\n | 'QUESTION_ANSWERING'\n | 'FACT_VERIFICATION'\n | 'CODE_RETRIEVAL_QUERY'\n | 'TASK_TYPE_UNSPECIFIED';\n\n/**\n * Google embedding parameters.\n * Passed through unchanged to the API.\n */\nexport interface GoogleEmbedParams {\n /** Task type for optimization */\n taskType?: GoogleTaskType;\n /** Document title (for RETRIEVAL_DOCUMENT taskType) */\n title?: string;\n /** Output dimensionality */\n outputDimensionality?: number;\n /** Whether to automatically truncate inputs exceeding token limits (default: true) */\n autoTruncate?: boolean;\n}\n\n/**\n * Google embeddings API response structure.\n */\ninterface GoogleEmbeddingsResponse {\n embeddings: Array<{\n values: number[];\n statistics?: {\n truncated?: boolean;\n tokenCount?: number;\n };\n }>;\n}\n\n/**\n * Creates an embedding handler for Google's Gemini Embeddings API.\n *\n * @returns An embedding handler configured for Google\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('gemini-embedding-001');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * params: { taskType: 'RETRIEVAL_DOCUMENT' },\n * config: { apiKey: 'AIza...' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<GoogleEmbedParams> {\n let providerRef: EmbeddingProvider<GoogleEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<GoogleEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<GoogleEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Embedding\n );\n }\n\n const model: BoundEmbeddingModel<GoogleEmbedParams> = {\n modelId,\n maxBatchSize: 100,\n maxInputLength: 2048,\n dimensions: 3072,\n\n get provider(): EmbeddingProvider<GoogleEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<GoogleEmbedParams>): Promise<EmbeddingResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'embedding'\n );\n\n const baseUrl = request.config.baseUrl ?? GOOGLE_API_URL;\n\n // Transform inputs to Google's format\n const requests = request.inputs.map((input) => {\n const text = typeof input === 'string' ? input : ('text' in input ? input.text : '');\n\n if (!text) {\n throw new UPPError(\n 'Google embeddings only support text input',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Embedding\n );\n }\n\n const embedRequest: Record<string, unknown> = {\n ...request.params,\n model: `models/${modelId}`,\n content: { parts: [{ text }] },\n };\n\n return embedRequest;\n });\n\n const url = `${baseUrl}/models/${modelId}:batchEmbedContents`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ requests }),\n signal: request.signal,\n }, request.config, 'google', 'embedding');\n\n const data = await parseJsonResponse<GoogleEmbeddingsResponse>(response, 'google', 'embedding');\n\n // Calculate total tokens\n let totalTokens = 0;\n for (const emb of data.embeddings) {\n totalTokens += emb.statistics?.tokenCount ?? 0;\n }\n\n // Return EmbeddingResponse - preserve ALL metadata\n return {\n embeddings: data.embeddings.map((e, index) => ({\n vector: e.values,\n index,\n tokens: e.statistics?.tokenCount,\n // Per-embedding metadata namespaced under provider (Spec 15.4)\n metadata: e.statistics ? {\n google: { truncated: e.statistics.truncated },\n } : undefined,\n })),\n usage: { totalTokens },\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Google Imagen Image Generation API Handler\n *\n * This module implements the image handler for Google's Imagen API via Google AI.\n * Supports Imagen 3 and 4 models through the Gemini API.\n *\n * @see {@link https://ai.google.dev/gemini-api/docs/imagen Imagen API Reference}\n * @module providers/google/image\n */\n\nimport type { ImageProvider, ImageHandler } from '../../types/provider.ts';\nimport type {\n BoundImageModel,\n ImageRequest,\n ImageResponse,\n ImageCapabilities,\n GeneratedImage,\n} from '../../types/image.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { Image } from '../../core/media/Image.ts';\n\nconst GOOGLE_AI_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Google Imagen generation parameters.\n * Passed through unchanged to the API.\n */\nexport interface GoogleImagenParams {\n /** Number of images to generate (1-4) */\n sampleCount?: number;\n /** Image size: '1K' (1024px) or '2K' (2048px) */\n imageSize?: '1K' | '2K';\n /** Aspect ratio */\n aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';\n /** Person generation setting */\n personGeneration?: 'dont_allow' | 'allow_adult' | 'allow_all';\n /** Safety filter level */\n safetyFilterLevel?: 'block_low_and_above' | 'block_medium_and_above' | 'block_only_high' | 'block_none';\n /** Add invisible SynthID watermark (default: true) */\n addWatermark?: boolean;\n /**\n * Negative prompt to exclude concepts.\n * @deprecated Not supported on Imagen 3.0-002+ and Imagen 4 models. Will be ignored.\n */\n negativePrompt?: string;\n}\n\n/**\n * Google Imagen API response structure.\n */\ninterface GoogleImagenResponse {\n predictions?: Array<{\n bytesBase64Encoded: string;\n mimeType?: string;\n }>;\n}\n\n/**\n * Determines capabilities based on model ID.\n */\nfunction getCapabilities(): ImageCapabilities {\n return {\n generate: true,\n streaming: false,\n edit: false,\n maxImages: 4,\n };\n}\n\n/**\n * Creates an image handler for Google's Imagen API.\n *\n * @returns An image handler configured for Google Imagen\n *\n * @example\n * ```typescript\n * const handler = createImageHandler();\n * const model = handler.bind('imagen-4.0-generate-001');\n *\n * const response = await model.generate({\n * prompt: 'A sunset over mountains',\n * config: { apiKey: '...' },\n * params: { aspectRatio: '16:9', sampleCount: 4 }\n * });\n * ```\n */\nexport function createImageHandler(): ImageHandler<GoogleImagenParams> {\n let providerRef: ImageProvider<GoogleImagenParams> | null = null;\n\n return {\n _setProvider(provider: ImageProvider<GoogleImagenParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundImageModel<GoogleImagenParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Image\n );\n }\n\n const capabilities = getCapabilities();\n\n const model: BoundImageModel<GoogleImagenParams> = {\n modelId,\n capabilities,\n\n get provider(): ImageProvider<GoogleImagenParams> {\n return providerRef!;\n },\n\n async generate(request: ImageRequest<GoogleImagenParams>): Promise<ImageResponse> {\n return executeGenerate(modelId, request);\n },\n };\n\n return model;\n },\n };\n}\n\n/**\n * Execute a non-streaming image generation request.\n */\nasync function executeGenerate(\n modelId: string,\n request: ImageRequest<GoogleImagenParams>\n): Promise<ImageResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'image'\n );\n\n const baseUrl = request.config.baseUrl?.replace(/\\/$/, '') ?? GOOGLE_AI_BASE_URL;\n const url = `${baseUrl}/models/${modelId}:predict`;\n\n const body: Record<string, unknown> = {\n instances: [{\n prompt: request.prompt,\n }],\n parameters: buildParameters(request.params),\n };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'google', 'image');\n\n const data = await parseJsonResponse<GoogleImagenResponse>(response, 'google', 'image');\n\n return transformResponse(data);\n}\n\n/**\n * Build parameters object for the API.\n */\nfunction buildParameters(params?: GoogleImagenParams): Record<string, unknown> {\n return params ? { ...params } : {};\n}\n\n/**\n * Transform Google response to ImageResponse.\n */\nfunction transformResponse(data: GoogleImagenResponse): ImageResponse {\n if (!data.predictions || data.predictions.length === 0) {\n throw new UPPError(\n 'No images in response',\n ErrorCode.ProviderError,\n 'google',\n ModalityType.Image\n );\n }\n\n const images: GeneratedImage[] = data.predictions.map((prediction) => {\n const mimeType = prediction.mimeType ?? 'image/png';\n const image = Image.fromBase64(prediction.bytesBase64Encoded, mimeType);\n return { image };\n });\n\n return {\n images,\n usage: {\n imagesGenerated: images.length,\n },\n };\n}\n","/**\n * @fileoverview Google Gemini caching utilities.\n *\n * Provides functions for creating and managing cached content entries\n * that can be reused across multiple Gemini API requests to reduce\n * costs and latency for repeated context.\n *\n * @see {@link https://ai.google.dev/api/caching Google Caching API docs}\n * @module providers/google/cache\n */\n\nimport type {\n GoogleCacheCreateRequest,\n GoogleCacheResponse,\n GoogleCacheUpdateRequest,\n GoogleCacheListResponse,\n GoogleContent,\n GoogleTool,\n} from './types.ts';\nimport type { ProviderConfig } from '../../types/provider.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\n\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\nfunction resolveBaseUrl(config?: ProviderConfig): string {\n if (config?.baseUrl) {\n const trimmed = config.baseUrl.replace(/\\/$/, '');\n return trimmed.endsWith('/v1beta') ? trimmed : `${trimmed}/v1beta`;\n }\n return DEFAULT_BASE_URL;\n}\n\n/**\n * Options for creating a cached content entry.\n */\nexport interface CacheCreateOptions {\n /** API key for authentication */\n apiKey: string;\n /** Provider configuration (timeout, retry strategy, custom fetch) */\n config?: ProviderConfig;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Model to associate with this cache (e.g., \"gemini-3-flash-preview\") */\n model: string;\n /** Optional display name for the cache (max 128 chars) */\n displayName?: string;\n /** Content messages to cache */\n contents?: GoogleContent[];\n /** System instruction text to cache */\n systemInstruction?: string;\n /** Tool declarations to cache */\n tools?: GoogleTool[];\n /** Time-to-live duration (e.g., \"3600s\" for 1 hour) */\n ttl?: string;\n /** Absolute expiration time (RFC 3339 format, alternative to ttl) */\n expireTime?: string;\n}\n\n/**\n * Options for listing cached content entries.\n */\nexport interface CacheListOptions {\n /** API key for authentication */\n apiKey: string;\n /** Provider configuration (timeout, retry strategy, custom fetch) */\n config?: ProviderConfig;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Maximum number of caches to return per page */\n pageSize?: number;\n /** Token for fetching the next page of results */\n pageToken?: string;\n}\n\n/**\n * Creates a new cached content entry.\n *\n * Caches can contain system instructions, conversation content, and tool\n * declarations that are reused across multiple requests. This reduces\n * token costs and processing time for repeated context.\n *\n * @param options - Cache creation options\n * @returns The created cache entry with its name/ID for use in requests\n *\n * @example\n * ```typescript\n * import { google } from '@anthropic/provider-protocol';\n *\n * // Create a cache with system instruction and large context\n * const cache = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * displayName: 'Code Review Context',\n * systemInstruction: 'You are an expert code reviewer...',\n * contents: [\n * { role: 'user', parts: [{ text: largeCodebaseContent }] }\n * ],\n * ttl: '3600s', // 1 hour\n * });\n *\n * // Use the cache in subsequent requests\n * const response = await model.complete({\n * messages: [userMessage('Review this function')],\n * params: { cachedContent: cache.name },\n * });\n * ```\n */\nexport async function create(options: CacheCreateOptions): Promise<GoogleCacheResponse> {\n const {\n apiKey,\n config,\n signal,\n model,\n displayName,\n contents,\n systemInstruction,\n tools,\n ttl,\n expireTime,\n } = options;\n const baseUrl = resolveBaseUrl(config);\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const requestBody: GoogleCacheCreateRequest = {\n model: model.startsWith('models/') ? model : `models/${model}`,\n };\n\n if (displayName) {\n requestBody.displayName = displayName;\n }\n\n if (contents && contents.length > 0) {\n requestBody.contents = contents;\n }\n\n if (systemInstruction) {\n requestBody.systemInstruction = {\n parts: [{ text: systemInstruction }],\n };\n }\n\n if (tools && tools.length > 0) {\n requestBody.tools = tools;\n }\n\n if (ttl) {\n requestBody.ttl = ttl;\n } else if (expireTime) {\n requestBody.expireTime = expireTime;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n `${baseUrl}/cachedContents`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Retrieves a cached content entry by name.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n * @returns The cache entry details\n *\n * @example\n * ```typescript\n * const cache = await google.cache.get('cachedContents/abc123', apiKey);\n * console.log(`Cache expires at: ${cache.expireTime}`);\n * ```\n */\nexport async function get(\n name: string,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<GoogleCacheResponse> {\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const url = `${baseUrl}/${cacheName}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'GET',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Lists all cached content entries.\n *\n * @param options - List options including API key and pagination\n * @returns Array of cache entries and optional next page token\n *\n * @example\n * ```typescript\n * const { cachedContents, nextPageToken } = await google.cache.list({\n * apiKey: process.env.GOOGLE_API_KEY,\n * pageSize: 10,\n * });\n *\n * for (const cache of cachedContents ?? []) {\n * console.log(`${cache.displayName}: ${cache.name}`);\n * }\n * ```\n */\nexport async function list(options: CacheListOptions): Promise<GoogleCacheListResponse> {\n const { apiKey, config, signal, pageSize, pageToken } = options;\n const baseUrl = resolveBaseUrl(config);\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const params = new URLSearchParams();\n if (pageSize) params.set('pageSize', String(pageSize));\n if (pageToken) params.set('pageToken', pageToken);\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n `${baseUrl}/cachedContents?${params}`,\n {\n method: 'GET',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheListResponse>(response, 'google', 'llm');\n}\n\n/**\n * Updates a cached content entry's expiration time.\n *\n * Only the expiration time can be updated; all other fields\n * (contents, systemInstruction, tools) are immutable after creation.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param update - The update to apply (exactly one of ttl or expireTime)\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n * @returns The updated cache entry\n *\n * @example\n * ```typescript\n * // Extend cache expiration by 2 hours\n * const updated = await google.cache.update(\n * 'cachedContents/abc123',\n * { ttl: '7200s' },\n * apiKey\n * );\n * ```\n */\nexport async function update(\n name: string,\n updateRequest: GoogleCacheUpdateRequest,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<GoogleCacheResponse> {\n if (updateRequest.expireTime && updateRequest.ttl) {\n throw new UPPError(\n 'Provide either expireTime or ttl (not both)',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const updateMaskParts: string[] = [];\n if (updateRequest.expireTime) {\n updateMaskParts.push('expireTime');\n }\n if (updateRequest.ttl) {\n updateMaskParts.push('ttl');\n }\n\n if (updateMaskParts.length === 0) {\n throw new UPPError(\n 'Update request must include expireTime or ttl',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const params = new URLSearchParams({ updateMask: updateMaskParts.join(',') });\n const url = `${baseUrl}/${cacheName}?${params.toString()}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'PATCH',\n headers,\n body: JSON.stringify(updateRequest),\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Deletes a cached content entry.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n *\n * @example\n * ```typescript\n * await google.cache.delete('cachedContents/abc123', apiKey);\n * ```\n */\nasync function deleteCache(\n name: string,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<void> {\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const url = `${baseUrl}/${cacheName}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'DELETE',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n}\n\n/**\n * Cache utilities namespace.\n *\n * Provides functions for creating and managing Google Gemini cached content\n * entries. Use cached content to reduce costs and latency when repeatedly\n * sending the same context (system instructions, large documents, etc.)\n * across multiple requests.\n *\n * @example\n * ```typescript\n * import { google } from '@anthropic/provider-protocol';\n *\n * // Create a cache\n * const cache = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * systemInstruction: 'You are an expert assistant...',\n * contents: [{ role: 'user', parts: [{ text: largeDocument }] }],\n * ttl: '3600s',\n * });\n *\n * // Use cache.name in requests via params.cachedContent\n * const response = await model.complete({\n * messages: [userMessage('Summarize the document')],\n * params: { cachedContent: cache.name },\n * });\n *\n * // Manage caches\n * const caches = await google.cache.list({ apiKey });\n * await google.cache.update(cache.name, { ttl: '7200s' }, apiKey);\n * await google.cache.delete(cache.name, apiKey);\n * ```\n */\nexport const cache = {\n create,\n get,\n list,\n update,\n delete: deleteCache,\n};\n","/**\n * Provider-specific parameters for Google Gemini API requests.\n *\n * These parameters are passed through to the Google `generationConfig` field\n * and control model behavior such as output length, randomness, and sampling\n * strategies. All fields are optional and will use Google's defaults if omitted.\n *\n * @example\n * ```typescript\n * const params: GoogleLLMParams = {\n * maxOutputTokens: 2048,\n * temperature: 0.7,\n * topP: 0.9,\n * stopSequences: ['\\n\\n'],\n * };\n *\n * const response = await model.complete({\n * messages: [...],\n * config: { apiKey: '...' },\n * params,\n * });\n * ```\n *\n * @see {@link https://ai.google.dev/api/rest/v1beta/GenerationConfig Google GenerationConfig docs}\n */\nexport interface GoogleLLMParams {\n /** Maximum number of tokens to generate */\n maxOutputTokens?: number;\n\n /** Temperature for randomness (0.0 - 2.0) */\n temperature?: number;\n\n /** Top-p (nucleus) sampling */\n topP?: number;\n\n /** Top-k sampling */\n topK?: number;\n\n /** Stop sequences */\n stopSequences?: string[];\n\n /** Number of candidates to generate */\n candidateCount?: number;\n\n /** Response MIME type */\n responseMimeType?: 'text/plain' | 'application/json';\n\n /** Response schema for structured output */\n responseSchema?: Record<string, unknown>;\n\n /**\n * Modalities to generate in the response.\n *\n * Use `['IMAGE']` or `['TEXT', 'IMAGE']` with Gemini image generation models\n * (e.g., gemini-2.5-flash-image aka Nano Banana).\n */\n responseModalities?: GoogleResponseModality[];\n\n /**\n * Image generation configuration for Gemini image response modalities.\n */\n imageConfig?: GoogleImageConfig;\n\n /**\n * Presence penalty for new topics\n * Positive values encourage discussing new topics\n */\n presencePenalty?: number;\n\n /**\n * Frequency penalty for repeated tokens\n * Positive values discourage repetition\n */\n frequencyPenalty?: number;\n\n /**\n * Seed for deterministic sampling\n * Same seed with same parameters should produce same results\n */\n seed?: number;\n\n /**\n * Whether to return log probabilities in response\n */\n responseLogprobs?: boolean;\n\n /**\n * Number of log probabilities to return (requires responseLogprobs: true)\n */\n logprobs?: number;\n\n /**\n * Whether to include audio timestamps in response\n */\n audioTimestamp?: boolean;\n\n /**\n * Thinking/reasoning configuration for Gemini 3+ models\n */\n thinkingConfig?: GoogleThinkingConfig;\n\n /**\n * Cached content name to use for this request.\n * Format: \"cachedContents/{id}\" as returned from cache creation.\n * When set, the cached content is prepended to the request.\n */\n cachedContent?: string;\n\n /**\n * Built-in tools for server-side execution.\n *\n * Use the tool helper constructors from the `tools` namespace:\n * - `tools.googleSearch()` - Google Search grounding\n * - `tools.codeExecution()` - Python code execution\n * - `tools.urlContext()` - URL fetching and analysis\n * - `tools.googleMaps()` - Google Maps grounding\n * - `tools.fileSearch()` - Document RAG search\n *\n * Note: File Search cannot be combined with other built-in tools.\n *\n * @example\n * ```typescript\n * import { google, tools } from 'provider-protocol/google';\n *\n * const model = llm({\n * model: google('gemini-2.5-flash'),\n * params: {\n * tools: [\n * tools.googleSearch(),\n * tools.codeExecution(),\n * ],\n * },\n * });\n * ```\n */\n tools?: GoogleBuiltInTool[];\n\n /**\n * Tool configuration for retrieval (e.g., user location for Maps).\n *\n * @example\n * ```typescript\n * const params: GoogleLLMParams = {\n * tools: [tools.googleMaps()],\n * toolConfig: {\n * retrievalConfig: {\n * latLng: { latitude: 40.758896, longitude: -73.985130 },\n * },\n * },\n * };\n * ```\n */\n toolConfig?: GoogleToolConfig;\n}\n\n/**\n * Output modality enum values for Gemini responseModalities.\n *\n * The API supports TEXT, IMAGE, and AUDIO response types. Some SDK examples\n * use Title Case values, so both are accepted here.\n */\nexport type GoogleResponseModality =\n | 'TEXT'\n | 'IMAGE'\n | 'AUDIO'\n | 'Text'\n | 'Image'\n | 'Audio';\n\n/**\n * Image generation configuration for Gemini response modalities.\n */\nexport interface GoogleImageConfig {\n /**\n * Preferred aspect ratio for generated images.\n * Example: \"1:1\", \"9:16\", \"16:9\".\n */\n aspectRatio?: string;\n\n /**\n * Preferred output size for generated images.\n * Example: \"1024x1024\".\n */\n imageSize?: string;\n}\n\n/**\n * Configuration for extended thinking/reasoning in Gemini 2.5+ and 3+ models.\n *\n * Enables models to spend additional compute on reasoning before\n * generating a response, improving quality for complex tasks.\n *\n * For Gemini 2.5 models: Use `thinkingBudget` to control token allocation.\n * For Gemini 3+ models: Use `thinkingLevel` (recommended) to set reasoning depth.\n *\n * Set `includeThoughts: true` to receive thought/reasoning content in the response.\n */\nexport interface GoogleThinkingConfig {\n /**\n * Token budget allocated for model thinking/reasoning (Gemini 2.5 models).\n * - `-1`: Dynamic thinking (default)\n * - `0`: Disable thinking (Flash models only)\n * - `128-32768`: Specific token budget\n */\n thinkingBudget?: number;\n\n /**\n * Thinking level for Gemini 3+ models (recommended over thinkingBudget).\n * - `\"minimal\"`: Likely prevents thinking (Gemini 3 Flash only)\n * - `\"low\"`: Minimizes latency and cost\n * - `\"medium\"`: Balanced (Gemini 3 Flash only)\n * - `\"high\"`: Maximizes reasoning depth (default for Gemini 3)\n */\n thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';\n\n /**\n * Whether to include thought summaries in the response.\n * When true, response parts with `thought: true` contain reasoning content.\n */\n includeThoughts?: boolean;\n}\n\n/**\n * Request body structure for Google Generative Language API.\n *\n * This interface represents the complete request payload sent to Google's\n * generateContent or streamGenerateContent endpoints.\n */\nexport interface GoogleRequest {\n /** Array of content turns representing the conversation history. */\n contents: GoogleContent[];\n /** Optional system instruction provided separately from conversation content. */\n systemInstruction?: {\n parts: GooglePart[];\n };\n /** Generation parameters controlling model output behavior. */\n generationConfig?: {\n maxOutputTokens?: number;\n temperature?: number;\n topP?: number;\n topK?: number;\n stopSequences?: string[];\n candidateCount?: number;\n responseMimeType?: string;\n responseSchema?: Record<string, unknown>;\n responseModalities?: GoogleResponseModality[];\n imageConfig?: GoogleImageConfig;\n presencePenalty?: number;\n frequencyPenalty?: number;\n seed?: number;\n responseLogprobs?: boolean;\n logprobs?: number;\n audioTimestamp?: boolean;\n thinkingConfig?: GoogleThinkingConfig;\n };\n /** Function/tool declarations and built-in tools available for the model to call. */\n tools?: (GoogleTool | GoogleBuiltInTool)[];\n /** Safety filter settings to control content moderation. */\n safetySettings?: GoogleSafetySetting[];\n /**\n * Cached content name to use for this request.\n * Format: \"cachedContents/{id}\" as returned from cache creation.\n */\n cachedContent?: string;\n /** Tool configuration for retrieval (e.g., user location for Maps). */\n toolConfig?: GoogleToolConfig;\n}\n\n/**\n * A single content turn in the Google conversation format.\n *\n * Represents either a user message or model response, containing\n * one or more parts that can be text, images, or function calls/responses.\n */\nexport interface GoogleContent {\n /** Role indicating message source: 'user' for user input, 'model' for assistant responses. */\n role: 'user' | 'model';\n /** Array of content parts within this message turn. */\n parts: GooglePart[];\n}\n\n/**\n * Union type for all possible content part types in Google messages.\n *\n * Parts can contain text, inline images, function calls (from model),\n * function responses (from user providing tool results), or code execution\n * results (from built-in code execution tool).\n */\nexport type GooglePart =\n | GoogleTextPart\n | GoogleImagePart\n | GoogleFunctionCallPart\n | GoogleFunctionResponsePart\n | GoogleExecutableCodePart\n | GoogleCodeExecutionResultPart;\n\n/**\n * Text content part.\n */\nexport interface GoogleTextPart {\n /** The text content. */\n text: string;\n /** If true, this part contains thinking/reasoning content (Gemini 2.5+/3+). */\n thought?: boolean;\n /**\n * Encrypted thought signature for Gemini 3+ models.\n * Must be forwarded back in subsequent requests to maintain reasoning context.\n * Required for Gemini 3 multi-turn conversations; recommended for Gemini 2.5.\n */\n thoughtSignature?: string;\n}\n\n/**\n * Inline image content part with base64-encoded data.\n */\nexport interface GoogleImagePart {\n /** Inline image data container. */\n inlineData: {\n /** MIME type of the image (e.g., 'image/png', 'image/jpeg'). */\n mimeType: string;\n /** Base64-encoded image data. */\n data: string;\n };\n}\n\n/**\n * Function call part generated by the model.\n *\n * Represents the model's request to invoke a declared function with\n * specific arguments.\n */\nexport interface GoogleFunctionCallPart {\n /** Function call details. */\n functionCall: {\n /** Unique identifier for this function call (native ID from API). */\n id?: string;\n /** Name of the function to call. */\n name: string;\n /** Arguments to pass to the function. */\n args: Record<string, unknown>;\n };\n /** Thought signature for Gemini 3+ models to maintain context across multi-turn tool calls. */\n thoughtSignature?: string;\n}\n\n/**\n * Function response part provided by the user.\n *\n * Contains the result of executing a function call, sent back to\n * the model to continue the conversation.\n */\nexport interface GoogleFunctionResponsePart {\n /** Function response details. */\n functionResponse: {\n /** Unique identifier to correlate with the function call (matches functionCall.id if provided). */\n id?: string;\n /** Name of the function that was called. */\n name: string;\n /** Response data from the function execution. */\n response: Record<string, unknown>;\n };\n}\n\n/**\n * Executable code part generated by the model.\n *\n * Contains code that was written by the model for execution\n * via the built-in code execution tool.\n */\nexport interface GoogleExecutableCodePart {\n /** Executable code details. */\n executableCode: {\n /** Programming language of the code. */\n language: 'PYTHON' | 'LANGUAGE_UNSPECIFIED';\n /** The code to execute. */\n code: string;\n };\n}\n\n/**\n * Code execution result part from built-in code execution.\n *\n * Contains the output from executing code via the code execution tool.\n * Always follows an ExecutableCode part.\n */\nexport interface GoogleCodeExecutionResultPart {\n /** Code execution result details. */\n codeExecutionResult: {\n /** Execution outcome. */\n outcome: 'OUTCOME_UNSPECIFIED' | 'OUTCOME_OK' | 'OUTCOME_FAILED' | 'OUTCOME_DEADLINE_EXCEEDED';\n /** Execution output (stdout on success, stderr on failure). */\n output: string;\n };\n}\n\n/**\n * Tool definition containing function declarations.\n *\n * Google groups function declarations within a tools array, where each\n * tool object contains an array of function declarations.\n */\nexport interface GoogleTool {\n /** Array of function declarations available for the model to call. */\n functionDeclarations: GoogleFunctionDeclaration[];\n}\n\n/**\n * Declaration of a callable function/tool for the model.\n *\n * Describes the function signature including its name, purpose,\n * and expected parameters in JSON Schema format.\n */\nexport interface GoogleFunctionDeclaration {\n /** Unique name of the function. */\n name: string;\n /** Human-readable description of what the function does. */\n description: string;\n /** JSON Schema describing the function parameters. */\n parameters: {\n /** Schema type, always 'object' for function parameters. */\n type: 'object';\n /** Map of parameter names to their JSON Schema definitions. */\n properties: Record<string, unknown>;\n /** Array of required parameter names. */\n required?: string[];\n };\n}\n\n/**\n * Safety filter configuration for content moderation.\n *\n * Allows customization of safety thresholds for different harm categories.\n */\nexport interface GoogleSafetySetting {\n /** Harm category to configure (e.g., 'HARM_CATEGORY_HARASSMENT'). */\n category: string;\n /** Blocking threshold (e.g., 'BLOCK_NONE', 'BLOCK_LOW_AND_ABOVE'). */\n threshold: string;\n}\n\n/**\n * Response structure from Google's generateContent endpoint.\n *\n * Contains one or more candidate responses along with usage metadata.\n */\nexport interface GoogleResponse {\n /** Array of candidate responses (typically one unless candidateCount > 1). */\n candidates: GoogleCandidate[];\n /** Token usage statistics for billing and monitoring. */\n usageMetadata?: {\n /** Number of tokens in the input prompt. */\n promptTokenCount: number;\n /** Number of tokens in the generated candidates. */\n candidatesTokenCount: number;\n /** Total tokens (prompt + candidates). */\n totalTokenCount: number;\n /** Number of tokens read from cached content. */\n cachedContentTokenCount?: number;\n };\n}\n\n/**\n * A single candidate response from the model.\n */\nexport interface GoogleCandidate {\n /** The generated content including role and parts. */\n content: {\n /** Always 'model' for generated responses. */\n role: 'model';\n /** Array of response parts (text and/or function calls). */\n parts: GoogleResponsePart[];\n };\n /** Reason the model stopped generating. */\n finishReason: 'STOP' | 'MAX_TOKENS' | 'SAFETY' | 'RECITATION' | 'OTHER' | 'TOOL_USE' | null;\n /** Index of this candidate in the candidates array. */\n index: number;\n /** Safety ratings for the generated content. */\n safetyRatings?: GoogleSafetyRating[];\n}\n\n/**\n * Part types that can appear in model responses.\n *\n * Responses may contain text, inline images (when responseModalities includes IMAGE),\n * function calls, or code execution results.\n */\nexport type GoogleResponsePart =\n | GoogleTextPart\n | GoogleImagePart\n | GoogleFunctionCallPart\n | GoogleExecutableCodePart\n | GoogleCodeExecutionResultPart;\n\n/**\n * Safety rating for a specific harm category.\n */\nexport interface GoogleSafetyRating {\n /** The harm category being rated. */\n category: string;\n /** Probability level of the harm (e.g., 'NEGLIGIBLE', 'LOW', 'MEDIUM', 'HIGH'). */\n probability: string;\n}\n\n/**\n * Streaming response chunk from Google's streamGenerateContent endpoint.\n *\n * Has the same structure as GoogleResponse but fields may be partial\n * or omitted depending on what data is available in the current chunk.\n */\nexport interface GoogleStreamChunk {\n /** Partial candidate data for this chunk. */\n candidates?: GoogleCandidate[];\n /** Cumulative token usage (updated with each chunk). */\n usageMetadata?: {\n /** Number of tokens in the input prompt. */\n promptTokenCount: number;\n /** Number of tokens generated so far. */\n candidatesTokenCount: number;\n /** Total tokens consumed so far. */\n totalTokenCount: number;\n /** Number of tokens read from cached content. */\n cachedContentTokenCount?: number;\n };\n /** Error response from the API (when streaming fails). */\n error?: {\n /** Error message from the API. */\n message: string;\n /** Error code. */\n code?: number;\n /** Error status string. */\n status?: string;\n };\n}\n\n// ============================================\n// Caching API Types\n// ============================================\n\n/**\n * Request body for creating a cached content entry.\n *\n * @see {@link https://ai.google.dev/api/caching Google Caching API docs}\n */\nexport interface GoogleCacheCreateRequest {\n /** Model to use with this cache (format: models/{model}) */\n model: string;\n /** Optional display name for the cache (max 128 chars) */\n displayName?: string;\n /** Content to cache (immutable after creation) */\n contents?: GoogleContent[];\n /** System instruction to cache (text-only, immutable after creation) */\n systemInstruction?: {\n role?: 'user';\n parts: Array<{ text: string }>;\n };\n /** Tool declarations to cache (immutable after creation) */\n tools?: GoogleTool[];\n /** Tool configuration to cache (immutable after creation) */\n toolConfig?: {\n functionCallingConfig?: {\n mode?: 'AUTO' | 'ANY' | 'NONE' | 'VALIDATED';\n allowedFunctionNames?: string[];\n };\n };\n /** Absolute expiration time (RFC 3339 format, mutually exclusive with ttl) */\n expireTime?: string;\n /** Time-to-live duration (e.g., \"300s\", \"3600s\", mutually exclusive with expireTime) */\n ttl?: string;\n}\n\n/**\n * Response from creating or retrieving a cached content entry.\n */\nexport interface GoogleCacheResponse {\n /** Cache identifier in format \"cachedContents/{id}\" - use this in requests */\n name: string;\n /** Model this cache is associated with */\n model: string;\n /** Display name for the cache */\n displayName?: string;\n /** When the cache was created (RFC 3339 format) */\n createTime: string;\n /** When the cache was last updated (RFC 3339 format) */\n updateTime: string;\n /** When the cache expires (RFC 3339 format) */\n expireTime: string;\n /** Token usage metadata */\n usageMetadata?: {\n /** Total tokens in the cached content */\n totalTokenCount: number;\n };\n}\n\n/**\n * Request body for updating a cached content entry.\n * Only expiration can be updated; all other fields are immutable.\n */\nexport interface GoogleCacheUpdateRequest {\n /** New absolute expiration time (RFC 3339 format, mutually exclusive with ttl) */\n expireTime?: string;\n /** New time-to-live duration (e.g., \"3600s\", mutually exclusive with expireTime) */\n ttl?: string;\n}\n\n/**\n * Response from listing cached content entries.\n */\nexport interface GoogleCacheListResponse {\n /** Array of cached content entries */\n cachedContents?: GoogleCacheResponse[];\n /** Token for fetching the next page of results */\n nextPageToken?: string;\n}\n\n/**\n * Google Gemini-specific HTTP headers for API requests.\n *\n * @example\n * ```typescript\n * const headers: GoogleHeaders = {\n * 'x-goog-api-client': 'myapp/1.0.0',\n * };\n * ```\n */\nexport interface GoogleHeaders {\n /** Client identification header for partners and libraries. */\n 'x-goog-api-client'?: string;\n /** Quota project ID for Vertex AI billing. */\n 'x-goog-user-project'?: string;\n [key: string]: string | undefined;\n}\n\n// ============================================\n// Built-in Tools\n// ============================================\n\n/**\n * Google Search grounding tool for real-time web information.\n *\n * Enables Gemini to search the web using Google Search for up-to-date information.\n * Results are returned with grounding metadata including sources and citations.\n *\n * Pricing:\n * - Gemini 2.x and earlier: $35 per 1,000 grounded prompts\n * - Gemini 3.x: $14 per 1,000 search queries\n *\n * @example\n * ```typescript\n * const tool: GoogleSearchTool = {\n * googleSearch: {},\n * };\n * ```\n */\nexport interface GoogleSearchTool {\n /** Empty object to enable Google Search grounding */\n googleSearch: Record<string, never>;\n}\n\n/**\n * Code execution tool for running Python in a sandbox.\n *\n * Enables Gemini to write and execute Python code in a secure environment.\n * Supports data analysis, calculations, and visualization.\n *\n * No additional cost - standard token pricing applies.\n *\n * @example\n * ```typescript\n * const tool: GoogleCodeExecutionTool = {\n * codeExecution: {},\n * };\n * ```\n */\nexport interface GoogleCodeExecutionTool {\n /** Empty object to enable code execution */\n codeExecution: Record<string, never>;\n}\n\n/**\n * URL context tool for fetching and processing URLs.\n *\n * Enables Gemini to fetch and analyze content from URLs.\n * Supports text, images, and PDF documents.\n *\n * Limits:\n * - Maximum 20 URLs per request\n * - Maximum 34MB content per URL\n *\n * @example\n * ```typescript\n * const tool: GoogleUrlContextTool = {\n * urlContext: {},\n * };\n * ```\n */\nexport interface GoogleUrlContextTool {\n /** Empty object to enable URL context */\n urlContext: Record<string, never>;\n}\n\n/**\n * Google Maps grounding tool for location-based queries.\n *\n * Enables Gemini to search for places, businesses, and locations\n * using Google Maps data.\n *\n * Pricing: $25 per 1,000 grounded prompts.\n *\n * Note: Not supported in Gemini 3 models.\n *\n * @example\n * ```typescript\n * const tool: GoogleMapsTool = {\n * googleMaps: {\n * enableWidget: true,\n * },\n * };\n * ```\n */\nexport interface GoogleMapsTool {\n /** Google Maps configuration */\n googleMaps: {\n /** Return widget context token for Places widget */\n enableWidget?: boolean;\n };\n}\n\n/**\n * File search (RAG) tool for document retrieval.\n *\n * Enables Gemini to search through uploaded documents\n * using semantic search on FileSearchStore.\n *\n * Pricing:\n * - Embeddings at indexing: $0.15 per 1M tokens\n * - Storage and query embeddings: Free\n *\n * Note: Cannot be combined with other built-in tools.\n *\n * @example\n * ```typescript\n * const tool: GoogleFileSearchTool = {\n * fileSearch: {\n * fileSearchStoreNames: ['fileSearchStores/abc123'],\n * },\n * };\n * ```\n */\nexport interface GoogleFileSearchTool {\n /** File search configuration */\n fileSearch: {\n /** FileSearchStore names to query */\n fileSearchStoreNames: string[];\n /** AIP-160 filter syntax for metadata filtering */\n metadataFilter?: string;\n };\n}\n\n/**\n * Union type for all Google built-in tools.\n *\n * Note: Google's built-in tools use a different structure than function tools.\n * They are passed directly in the tools array alongside functionDeclarations.\n */\nexport type GoogleBuiltInTool =\n | GoogleSearchTool\n | GoogleCodeExecutionTool\n | GoogleUrlContextTool\n | GoogleMapsTool\n | GoogleFileSearchTool;\n\n/**\n * Tool configuration for retrieval (e.g., user location for Maps).\n */\nexport interface GoogleToolConfig {\n /** Retrieval configuration */\n retrievalConfig?: {\n /** User location for \"near me\" queries */\n latLng?: {\n /** User latitude */\n latitude: number;\n /** User longitude */\n longitude: number;\n };\n };\n}\n\n/**\n * Grounding metadata returned with search/maps results.\n */\nexport interface GoogleGroundingMetadata {\n /** Web search queries executed */\n webSearchQueries?: string[];\n /** Search entry point with rendered HTML */\n searchEntryPoint?: {\n renderedContent: string;\n };\n /** Grounding chunks (sources) */\n groundingChunks?: Array<{\n web?: {\n uri: string;\n title: string;\n };\n maps?: {\n uri: string;\n placeId: string;\n title: string;\n };\n }>;\n /** Grounding supports (citations) */\n groundingSupports?: Array<{\n segment: {\n startIndex: number;\n endIndex: number;\n text: string;\n };\n groundingChunkIndices: number[];\n confidenceScores: number[];\n }>;\n /** Google Maps widget context token */\n googleMapsWidgetContextToken?: string;\n}\n\n/**\n * Code execution result in response.\n */\nexport interface GoogleCodeExecutionResult {\n /** Execution outcome */\n outcome: 'OUTCOME_OK' | 'OUTCOME_FAILED' | 'OUTCOME_DEADLINE_EXCEEDED';\n /** Execution output (stdout) */\n output: string;\n}\n\n// ============================================\n// Tool Helper Constructors\n// ============================================\n\n/**\n * Creates a Google Search grounding tool configuration.\n *\n * Enables Gemini to search the web using Google Search for up-to-date information.\n *\n * @returns A Google Search tool configuration object\n *\n * @example\n * ```typescript\n * const search = googleSearchTool();\n * ```\n */\nexport function googleSearchTool(): GoogleSearchTool {\n return { googleSearch: {} };\n}\n\n/**\n * Creates a code execution tool configuration.\n *\n * Enables Gemini to write and execute Python code in a sandbox.\n *\n * @returns A code execution tool configuration object\n *\n * @example\n * ```typescript\n * const codeExec = codeExecutionTool();\n * ```\n */\nexport function codeExecutionTool(): GoogleCodeExecutionTool {\n return { codeExecution: {} };\n}\n\n/**\n * Creates a URL context tool configuration.\n *\n * Enables Gemini to fetch and analyze content from URLs.\n *\n * @returns A URL context tool configuration object\n *\n * @example\n * ```typescript\n * const urlCtx = urlContextTool();\n * ```\n */\nexport function urlContextTool(): GoogleUrlContextTool {\n return { urlContext: {} };\n}\n\n/**\n * Creates a Google Maps grounding tool configuration.\n *\n * Enables Gemini to search for places using Google Maps data.\n *\n * Note: Not supported in Gemini 3 models.\n *\n * @param options - Optional configuration\n * @returns A Google Maps tool configuration object\n *\n * @example\n * ```typescript\n * const maps = googleMapsTool();\n *\n * // With widget enabled\n * const mapsWithWidget = googleMapsTool({ enableWidget: true });\n * ```\n */\nexport function googleMapsTool(options?: {\n enableWidget?: boolean;\n}): GoogleMapsTool {\n return {\n googleMaps: {\n ...(options?.enableWidget !== undefined && { enableWidget: options.enableWidget }),\n },\n };\n}\n\n/**\n * Creates a file search (RAG) tool configuration.\n *\n * Enables Gemini to search through uploaded documents.\n *\n * Note: Cannot be combined with other built-in tools.\n *\n * @param options - File search configuration\n * @returns A file search tool configuration object\n *\n * @example\n * ```typescript\n * const fileSearch = fileSearchTool({\n * fileSearchStoreNames: ['fileSearchStores/abc123'],\n * });\n * ```\n */\nexport function fileSearchTool(options: {\n fileSearchStoreNames: string[];\n metadataFilter?: string;\n}): GoogleFileSearchTool {\n return {\n fileSearch: options,\n };\n}\n\n/**\n * Namespace object containing all Google tool helper constructors.\n *\n * Provides a convenient way to create built-in tool configurations.\n *\n * @example\n * ```typescript\n * import { google, tools } from 'provider-protocol/google';\n *\n * const model = llm({\n * model: google('gemini-2.5-flash'),\n * params: {\n * tools: [\n * tools.googleSearch(),\n * tools.codeExecution(),\n * ],\n * },\n * });\n * ```\n */\nexport const tools = {\n /** Creates a Google Search grounding tool configuration */\n googleSearch: googleSearchTool,\n /** Creates a code execution tool configuration */\n codeExecution: codeExecutionTool,\n /** Creates a URL context tool configuration */\n urlContext: urlContextTool,\n /** Creates a Google Maps grounding tool configuration */\n googleMaps: googleMapsTool,\n /** Creates a file search (RAG) tool configuration */\n fileSearch: fileSearchTool,\n};\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\nimport { createImageHandler } from './image.ts';\nimport { cache } from './cache.ts';\n\nconst baseProvider = createProvider({\n name: 'google',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n image: createImageHandler(),\n },\n});\n\n/**\n * Google Gemini provider for the Unified Provider Protocol (UPP).\n *\n * Provides access to Google's Gemini family of large language models through\n * a standardized interface. Supports text generation, multimodal inputs\n * (images, video, audio), tool/function calling, and structured output.\n *\n * @example\n * ```typescript\n * import { google } from './providers/google';\n * import { llm } from './core/llm';\n * import { StreamEventType } from './types/stream';\n *\n * const gemini = llm({\n * model: google('gemini-1.5-pro'),\n * config: { apiKey: process.env.GOOGLE_API_KEY },\n * });\n *\n * const turn = await gemini.generate('Hello!');\n * console.log(turn.response.text);\n *\n * const stream = gemini.stream('Tell me a story');\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * ```\n *\n * @example Caching\n * ```typescript\n * // Create a cache for repeated context\n * const cacheEntry = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * systemInstruction: 'You are an expert code reviewer...',\n * contents: [{ role: 'user', parts: [{ text: largeCodebase }] }],\n * ttl: '3600s',\n * });\n *\n * // Use cache in requests\n * const cachedModel = llm({\n * model: google('gemini-3-flash-preview'),\n * config: { apiKey: process.env.GOOGLE_API_KEY },\n * params: { cachedContent: cacheEntry.name },\n * });\n *\n * const response = await cachedModel.generate('Review this function');\n *\n * // Manage caches\n * await google.cache.update(cacheEntry.name, { ttl: '7200s' }, apiKey);\n * await google.cache.delete(cacheEntry.name, apiKey);\n * ```\n *\n * @see {@link GoogleLLMParams} for provider-specific configuration options\n * @see {@link cache} for caching utilities\n */\nexport const google = Object.assign(baseProvider, { cache });\n\nexport { cache } from './cache.ts';\nexport { tools } from './types.ts';\nexport type { CacheCreateOptions, CacheListOptions } from './cache.ts';\nexport type {\n GoogleLLMParams,\n GoogleResponseModality,\n GoogleImageConfig,\n GoogleCacheCreateRequest,\n GoogleCacheResponse,\n GoogleCacheUpdateRequest,\n GoogleCacheListResponse,\n GoogleHeaders,\n GoogleBuiltInTool,\n GoogleSearchTool,\n GoogleCodeExecutionTool,\n GoogleUrlContextTool,\n GoogleMapsTool,\n GoogleFileSearchTool,\n GoogleToolConfig,\n GoogleGroundingMetadata,\n GoogleCodeExecutionResult,\n} from './types.ts';\n\nexport type { GoogleEmbedParams, GoogleTaskType } from './embed.ts';\n\nexport type { GoogleImagenParams } from './image.ts';\n"],"mappings":"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","names":["transformResponse","tools"]}
1
+ {"version":3,"sources":["../../src/providers/google/transform.ts","../../src/providers/google/llm.ts","../../src/providers/google/embed.ts","../../src/providers/google/image.ts","../../src/providers/google/cache.ts","../../src/providers/google/types.ts","../../src/providers/google/index.ts"],"sourcesContent":["/**\n * @fileoverview Transformation functions between UPP format and Google Gemini API format.\n *\n * This module handles the bidirectional conversion of requests, responses, and\n * streaming chunks between the Unified Provider Protocol (UPP) format and\n * Google's Generative Language API format.\n *\n * Key transformations:\n * - UPP messages with content blocks to Google's parts-based content structure\n * - UPP tools to Google's functionDeclarations format\n * - Google responses back to UPP LLMResponse with proper message types\n * - Streaming chunks to UPP StreamEvents\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type {\n ContentBlock,\n AssistantContent,\n ImageBlock,\n DocumentBlock,\n AudioBlock,\n VideoBlock,\n} from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport type {\n GoogleLLMParams,\n GoogleRequest,\n GoogleContent,\n GooglePart,\n GoogleTextPart,\n GoogleTool,\n GoogleResponse,\n GoogleStreamChunk,\n GoogleFunctionCallPart,\n} from './types.ts';\n\nfunction normalizeSystem(system: string | unknown[] | undefined): string | GooglePart[] | undefined {\n if (system === undefined || system === null) return undefined;\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text parts',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const parts: GooglePart[] = [];\n for (const part of system) {\n if (!part || typeof part !== 'object' || !('text' in part)) {\n throw new UPPError(\n 'Google system prompt array must contain text parts',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n const textValue = (part as { text?: unknown }).text;\n if (typeof textValue !== 'string') {\n throw new UPPError(\n 'Google system prompt text must be a string',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n parts.push(part as GooglePart);\n }\n\n return parts.length > 0 ? parts : undefined;\n}\n\nconst GOOGLE_TOOLCALL_PREFIX = 'google_toolcall';\n\nfunction createGoogleToolCallId(name: string, index: number): string {\n return `${GOOGLE_TOOLCALL_PREFIX}:${index}:${name}`;\n}\n\nfunction extractGoogleToolName(toolCallId: string): string {\n const prefix = `${GOOGLE_TOOLCALL_PREFIX}:`;\n if (!toolCallId.startsWith(prefix)) {\n return toolCallId;\n }\n const rest = toolCallId.slice(prefix.length);\n const separatorIndex = rest.indexOf(':');\n if (separatorIndex === -1) {\n return toolCallId;\n }\n return rest.slice(separatorIndex + 1);\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @typeParam T - Content block type with optional type property\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type property\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Converts a Uint8Array to a base64 string.\n *\n * @param bytes - The byte array to encode\n * @returns Base64-encoded string\n */\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n return Buffer.from(bytes).toString('base64');\n}\n\n/**\n * Transforms a UPP content block to a Google part.\n *\n * Supports text, image, document, audio, and video content types.\n * Binary data (images, audio, video, PDFs) is sent as base64-encoded inlineData.\n * URL sources are not supported by Google's API directly.\n *\n * @param block - The UPP content block to transform\n * @returns Google-formatted part object\n * @throws Error if the content type is unsupported or uses URL source\n */\nfunction transformContentBlock(block: ContentBlock): GooglePart {\n switch (block.type) {\n case 'text':\n return { text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n let data: string;\n\n if (imageBlock.source.type === 'base64') {\n data = imageBlock.source.data;\n } else if (imageBlock.source.type === 'bytes') {\n data = uint8ArrayToBase64(imageBlock.source.data);\n } else {\n throw new Error('Google API does not support URL image sources directly');\n }\n\n return {\n inlineData: {\n mimeType: imageBlock.mimeType,\n data,\n },\n };\n }\n\n case 'document': {\n const documentBlock = block as DocumentBlock;\n\n if (documentBlock.source.type === 'base64') {\n return {\n inlineData: {\n mimeType: documentBlock.mimeType,\n data: documentBlock.source.data,\n },\n };\n }\n\n if (documentBlock.source.type === 'text') {\n return { text: documentBlock.source.data };\n }\n\n throw new Error('Google API does not support URL document sources directly');\n }\n\n case 'audio': {\n const audioBlock = block as AudioBlock;\n return {\n inlineData: {\n mimeType: audioBlock.mimeType,\n data: uint8ArrayToBase64(audioBlock.data),\n },\n };\n }\n\n case 'video': {\n const videoBlock = block as VideoBlock;\n return {\n inlineData: {\n mimeType: videoBlock.mimeType,\n data: uint8ArrayToBase64(videoBlock.data),\n },\n };\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms UPP message array to Google's content format.\n *\n * Handles the conversion of user messages, assistant messages (including\n * tool calls), and tool result messages to Google's role-based content\n * structure with parts arrays.\n *\n * @param messages - Array of UPP-formatted messages\n * @returns Array of Google content objects with role and parts\n */\nfunction transformMessages(messages: Message[]): GoogleContent[] {\n const contents: GoogleContent[] = [];\n\n for (const msg of messages) {\n if (isUserMessage(msg)) {\n const validContent = filterValidContent(msg.content);\n const parts = validContent.map(transformContentBlock);\n if (parts.length === 0) {\n parts.push({ text: '' });\n }\n contents.push({\n role: 'user',\n parts,\n });\n } else if (isAssistantMessage(msg)) {\n const validContent = filterValidContent(msg.content);\n // Filter out reasoning blocks - they're preserved via thoughtSignature in metadata\n const nonReasoningContent = validContent.filter(c => c.type !== 'reasoning');\n const parts: GooglePart[] = nonReasoningContent.map(transformContentBlock);\n\n const googleMeta = msg.metadata?.google as {\n functionCallParts?: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }>;\n // Thought signature from text response (Gemini 3+ multi-turn context)\n thoughtSignature?: string;\n } | undefined;\n\n // Add thoughtSignature to the last text part for multi-turn context preservation\n if (googleMeta?.thoughtSignature) {\n // Find the last text part and add the signature\n for (let i = parts.length - 1; i >= 0; i--) {\n const part = parts[i];\n if (part && 'text' in part) {\n (part as GoogleTextPart).thoughtSignature = googleMeta.thoughtSignature;\n break;\n }\n }\n }\n\n if (googleMeta?.functionCallParts && googleMeta.functionCallParts.length > 0) {\n for (const fc of googleMeta.functionCallParts) {\n const part: GoogleFunctionCallPart = {\n functionCall: {\n id: fc.id,\n name: fc.name,\n args: fc.args,\n },\n };\n if (fc.thoughtSignature) {\n part.thoughtSignature = fc.thoughtSignature;\n }\n parts.push(part);\n }\n } else if (msg.toolCalls) {\n for (const call of msg.toolCalls) {\n parts.push({\n functionCall: {\n name: call.toolName,\n args: call.arguments,\n },\n });\n }\n }\n\n if (parts.length === 0) {\n parts.push({ text: '' });\n }\n\n contents.push({\n role: 'model',\n parts,\n });\n } else if (isToolResultMessage(msg)) {\n contents.push({\n role: 'user',\n parts: msg.results.map((result) => ({\n functionResponse: {\n name: extractGoogleToolName(result.toolCallId),\n response:\n typeof result.result === 'object'\n ? (result.result as Record<string, unknown>)\n : { result: result.result },\n },\n })),\n });\n }\n }\n\n return contents;\n}\n\n/**\n * Transforms a UPP tool definition to Google's function declaration format.\n *\n * @param tool - The UPP tool definition with name, description, and parameters\n * @returns Google function declaration object\n */\nfunction transformTool(tool: Tool): GoogleTool['functionDeclarations'][0] {\n return {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n },\n };\n}\n\n/**\n * Transforms a UPP LLM request into Google Gemini API format.\n *\n * Converts the UPP message structure, system prompt, tools, and generation\n * parameters into Google's expected request body format. Provider-specific\n * parameters are passed through to `generationConfig` to support new API\n * features without library updates.\n *\n * @typeParam TParams - Type extending GoogleLLMParams for provider-specific options\n * @param request - The UPP-formatted LLM request\n * @param modelId - The target Gemini model identifier\n * @returns Google API request body ready for submission\n *\n * @example\n * ```typescript\n * const googleRequest = transformRequest({\n * messages: [{ role: 'user', content: [{ type: 'text', text: 'Hello' }] }],\n * system: 'You are a helpful assistant',\n * params: { temperature: 0.7 },\n * config: { apiKey: '...' },\n * }, 'gemini-1.5-pro');\n * ```\n */\nexport function transformRequest<TParams extends GoogleLLMParams>(\n request: LLMRequest<TParams>,\n modelId: string\n): GoogleRequest {\n const params = (request.params ?? {}) as GoogleLLMParams;\n const { cachedContent, tools: builtInTools, toolConfig, ...generationParams } = params;\n\n const googleRequest: GoogleRequest = {\n contents: transformMessages(request.messages),\n };\n\n const normalizedSystem = normalizeSystem(request.system);\n if (normalizedSystem !== undefined) {\n if (typeof normalizedSystem === 'string') {\n googleRequest.systemInstruction = {\n parts: [{ text: normalizedSystem }],\n };\n } else if (normalizedSystem.length > 0) {\n googleRequest.systemInstruction = {\n parts: normalizedSystem,\n };\n }\n }\n\n const generationConfig: NonNullable<GoogleRequest['generationConfig']> = {\n ...generationParams,\n };\n\n if (request.structure) {\n generationConfig.responseMimeType = 'application/json';\n generationConfig.responseSchema = request.structure as unknown as Record<string, unknown>;\n }\n\n if (Object.keys(generationConfig).length > 0) {\n googleRequest.generationConfig = generationConfig;\n }\n\n // Collect all tools: function declarations + built-in tools\n const requestTools: NonNullable<GoogleRequest['tools']> = [];\n\n if (request.tools && request.tools.length > 0) {\n requestTools.push({\n functionDeclarations: request.tools.map(transformTool),\n });\n }\n\n // Add built-in tools (googleSearch, codeExecution, urlContext, etc.)\n // These are added as separate tool objects, not as function declarations\n if (builtInTools && builtInTools.length > 0) {\n requestTools.push(...builtInTools);\n }\n\n if (requestTools.length > 0) {\n googleRequest.tools = requestTools;\n }\n\n // Add tool config if provided (e.g., for retrievalConfig with Google Maps)\n if (toolConfig) {\n googleRequest.toolConfig = toolConfig;\n }\n\n if (cachedContent) {\n googleRequest.cachedContent = cachedContent;\n }\n\n return googleRequest;\n}\n\nfunction normalizeStopReason(reason: string | null | undefined): string {\n switch (reason) {\n case 'STOP':\n return 'end_turn';\n case 'MAX_TOKENS':\n return 'max_tokens';\n case 'SAFETY':\n case 'RECITATION':\n return 'content_filter';\n case 'TOOL_USE':\n return 'tool_use';\n case 'OTHER':\n return 'end_turn';\n default:\n return 'end_turn';\n }\n}\n\n/**\n * Transforms a Google API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, structured data, and usage metadata\n * from Google's response format. Preserves Google-specific metadata like\n * finish reason, safety ratings, and thought signatures for multi-turn\n * tool call conversations.\n *\n * @param data - The raw Google API response\n * @returns Normalized UPP LLMResponse with message, usage, and stop reason\n * @throws Error if response contains no candidates\n *\n * @example\n * ```typescript\n * const response = await fetch(googleApiUrl, options);\n * const data = await response.json();\n * const uppResponse = transformResponse(data);\n * console.log(uppResponse.message.content);\n * ```\n */\nexport function transformResponse(data: GoogleResponse): LLMResponse {\n const candidate = data.candidates?.[0];\n if (!candidate) {\n throw new Error('No candidates in Google response');\n }\n\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n let lastThoughtSignature: string | undefined;\n const functionCallParts: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }> = [];\n\n for (const part of candidate.content.parts) {\n if ('text' in part) {\n const textPart = part as GoogleTextPart;\n // Capture thoughtSignature from the last text part (Gemini 3+ includes on final part)\n if (textPart.thoughtSignature) {\n lastThoughtSignature = textPart.thoughtSignature;\n }\n if (textPart.thought) {\n content.push({ type: 'reasoning', text: textPart.text });\n } else {\n content.push({ type: 'text', text: textPart.text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(textPart.text);\n } catch {\n // Not JSON - may not be structured output\n }\n }\n }\n } else if ('functionCall' in part) {\n const fc = part as GoogleFunctionCallPart;\n const toolCallId = fc.functionCall.id ?? createGoogleToolCallId(fc.functionCall.name, toolCalls.length);\n toolCalls.push({\n toolCallId,\n toolName: fc.functionCall.name,\n arguments: fc.functionCall.args,\n });\n functionCallParts.push({\n id: fc.functionCall.id,\n name: fc.functionCall.name,\n args: fc.functionCall.args,\n thoughtSignature: fc.thoughtSignature,\n });\n } else if ('inlineData' in part) {\n const imagePart = part as { inlineData: { mimeType?: string; data?: string } };\n const dataString = imagePart.inlineData.data;\n if (dataString) {\n content.push({\n type: 'image',\n mimeType: imagePart.inlineData.mimeType ?? 'image/png',\n source: { type: 'base64', data: dataString },\n } as ImageBlock);\n }\n } else if ('codeExecutionResult' in part) {\n // Append code execution output to text content\n const codeResult = part as { codeExecutionResult: { outcome: string; output: string } };\n if (codeResult.codeExecutionResult.output) {\n content.push({ type: 'text', text: `\\n\\`\\`\\`\\n${codeResult.codeExecutionResult.output}\\`\\`\\`\\n` });\n }\n }\n // executableCode parts are tracked for context but the output is in codeExecutionResult\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n google: {\n finishReason: candidate.finishReason,\n safetyRatings: candidate.safetyRatings,\n functionCallParts: functionCallParts.length > 0 ? functionCallParts : undefined,\n // Store thoughtSignature for multi-turn context preservation (Gemini 3+)\n thoughtSignature: lastThoughtSignature,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usageMetadata?.promptTokenCount ?? 0,\n outputTokens: data.usageMetadata?.candidatesTokenCount ?? 0,\n totalTokens: data.usageMetadata?.totalTokenCount ?? 0,\n cacheReadTokens: data.usageMetadata?.cachedContentTokenCount ?? 0,\n cacheWriteTokens: 0,\n };\n\n return {\n message,\n usage,\n stopReason: normalizeStopReason(candidate.finishReason),\n data: structuredData,\n };\n}\n\n/**\n * Accumulator state for streaming responses.\n *\n * Tracks partial content, tool calls, token counts, and stream lifecycle\n * as chunks arrive from the Google streaming API.\n */\nexport interface StreamState {\n /** Accumulated text content from all chunks. */\n content: string;\n /** Accumulated reasoning/thinking content from thought parts. */\n reasoning: string;\n /** Encrypted thought signature for multi-turn context (Gemini 3+). */\n thoughtSignature?: string;\n /** Accumulated tool calls with their arguments and optional thought signatures. */\n toolCalls: Array<{ id: string; nativeId?: string; name: string; args: Record<string, unknown>; thoughtSignature?: string }>;\n /** Base64 image data from inline image response parts. */\n images: Array<{ data: string; mimeType: string }>;\n /** The finish reason from the final chunk, if received. */\n finishReason: string | null;\n /** Total input tokens reported by the API. */\n inputTokens: number;\n /** Total output tokens reported by the API. */\n outputTokens: number;\n /** Number of tokens read from cached content. */\n cacheReadTokens: number;\n /** Flag indicating whether this is the first chunk (for message_start event). */\n isFirstChunk: boolean;\n}\n\n/**\n * Creates a fresh stream state for accumulating streaming responses.\n *\n * @returns Initialized StreamState with empty content and default values\n */\nexport function createStreamState(): StreamState {\n return {\n content: '',\n reasoning: '',\n thoughtSignature: undefined,\n toolCalls: [],\n images: [],\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n isFirstChunk: true,\n };\n}\n\nfunction decodeBase64(base64: string): Uint8Array {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i += 1) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n}\n\n/**\n * Transforms a Google streaming chunk to UPP StreamEvent array.\n *\n * Processes each streaming chunk, updating the accumulator state and\n * generating appropriate stream events for text deltas, tool calls,\n * and message lifecycle (start/stop).\n *\n * @param chunk - The Google streaming response chunk\n * @param state - Mutable accumulator state updated by this function\n * @returns Array of UPP StreamEvents generated from this chunk\n */\nexport function transformStreamChunk(\n chunk: GoogleStreamChunk,\n state: StreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n if (state.isFirstChunk) {\n events.push({ type: StreamEventType.MessageStart, index: 0, delta: {} });\n state.isFirstChunk = false;\n }\n\n if (chunk.usageMetadata) {\n state.inputTokens = chunk.usageMetadata.promptTokenCount;\n state.outputTokens = chunk.usageMetadata.candidatesTokenCount;\n state.cacheReadTokens = chunk.usageMetadata.cachedContentTokenCount ?? 0;\n }\n\n const candidate = chunk.candidates?.[0];\n if (!candidate) {\n return events;\n }\n\n for (const part of candidate.content?.parts ?? []) {\n if ('text' in part) {\n const textPart = part as GoogleTextPart;\n if (textPart.thoughtSignature) {\n state.thoughtSignature = textPart.thoughtSignature;\n }\n if (textPart.thought) {\n state.reasoning += textPart.text;\n events.push({\n type: StreamEventType.ReasoningDelta,\n index: 0,\n delta: { text: textPart.text },\n });\n } else {\n state.content += textPart.text;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: textPart.text },\n });\n }\n } else if ('functionCall' in part) {\n const fc = part as GoogleFunctionCallPart;\n const toolCallId = fc.functionCall.id ?? createGoogleToolCallId(fc.functionCall.name, state.toolCalls.length);\n state.toolCalls.push({\n id: toolCallId,\n nativeId: fc.functionCall.id,\n name: fc.functionCall.name,\n args: fc.functionCall.args,\n thoughtSignature: fc.thoughtSignature,\n });\n events.push({\n type: StreamEventType.ToolCallDelta,\n index: state.toolCalls.length - 1,\n delta: {\n toolCallId,\n toolName: fc.functionCall.name,\n argumentsJson: JSON.stringify(fc.functionCall.args),\n },\n });\n } else if ('inlineData' in part) {\n const imagePart = part as { inlineData: { mimeType?: string; data?: string } };\n const dataString = imagePart.inlineData.data;\n if (dataString) {\n state.images.push({\n data: dataString,\n mimeType: imagePart.inlineData.mimeType ?? 'image/png',\n });\n events.push({\n type: StreamEventType.ImageDelta,\n index: state.images.length - 1,\n delta: { data: decodeBase64(dataString) },\n });\n }\n } else if ('codeExecutionResult' in part) {\n // Append code execution output to content and emit as text delta\n const codeResult = part as { codeExecutionResult: { outcome: string; output: string } };\n if (codeResult.codeExecutionResult.output) {\n const outputText = `\\n\\`\\`\\`\\n${codeResult.codeExecutionResult.output}\\`\\`\\`\\n`;\n state.content += outputText;\n events.push({\n type: StreamEventType.TextDelta,\n index: 0,\n delta: { text: outputText },\n });\n }\n }\n // executableCode parts are tracked for context but the output is in codeExecutionResult\n }\n\n if (candidate.finishReason) {\n state.finishReason = candidate.finishReason;\n events.push({ type: StreamEventType.MessageStop, index: 0, delta: {} });\n }\n\n return events;\n}\n\n/**\n * Constructs a complete LLMResponse from accumulated stream state.\n *\n * Called after streaming completes to build the final response object\n * with all accumulated content, tool calls, usage statistics, and metadata.\n *\n * @param state - The final accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: StreamState): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n let structuredData: unknown;\n const functionCallParts: Array<{\n id?: string;\n name: string;\n args: Record<string, unknown>;\n thoughtSignature?: string;\n }> = [];\n\n if (state.reasoning) {\n content.push({ type: 'reasoning', text: state.reasoning });\n }\n\n if (state.content) {\n content.push({ type: 'text', text: state.content });\n try {\n structuredData = JSON.parse(state.content);\n } catch {\n // Not JSON - may not be structured output\n }\n }\n\n for (const imageData of state.images) {\n content.push({\n type: 'image',\n mimeType: imageData.mimeType,\n source: { type: 'base64', data: imageData.data },\n } as ImageBlock);\n }\n\n for (const tc of state.toolCalls) {\n const toolCallId = tc.id || createGoogleToolCallId(tc.name, toolCalls.length);\n toolCalls.push({\n toolCallId,\n toolName: tc.name,\n arguments: tc.args,\n });\n functionCallParts.push({\n id: tc.nativeId,\n name: tc.name,\n args: tc.args,\n thoughtSignature: tc.thoughtSignature,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n metadata: {\n google: {\n finishReason: state.finishReason,\n functionCallParts: functionCallParts.length > 0 ? functionCallParts : undefined,\n thoughtSignature: state.thoughtSignature,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n return {\n message,\n usage,\n stopReason: normalizeStopReason(state.finishReason),\n data: structuredData,\n };\n}\n","import type { BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { LLMHandler } from '../../types/provider.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport { StreamEventType, objectDelta } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { GoogleLLMParams, GoogleResponse, GoogleStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamChunk,\n createStreamState,\n buildResponseFromState,\n} from './transform.ts';\n\n/** Base URL for the Google Generative Language API (v1beta). */\nconst GOOGLE_API_BASE = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Capability flags for the Google Gemini API.\n *\n * Gemini models support streaming responses, function/tool calling,\n * structured JSON output, and multimodal inputs including images,\n * video, and audio.\n */\nconst GOOGLE_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n documentInput: true,\n videoInput: true,\n audioInput: true,\n imageOutput: true,\n};\n\n/**\n * Constructs the Google API endpoint URL for a specific model and action.\n *\n * @param modelId - The Gemini model identifier (e.g., 'gemini-1.5-pro')\n * @param action - The API action to perform\n * @returns Fully qualified URL for the model action\n */\nfunction buildUrl(modelId: string, action: 'generateContent' | 'streamGenerateContent'): string {\n return `${GOOGLE_API_BASE}/models/${modelId}:${action}`;\n}\n\n/**\n * Creates an LLM handler for Google Gemini models.\n *\n * The handler implements the UPP LLMHandler interface, providing `bind()`\n * to create model instances that support both synchronous completion and\n * streaming responses.\n *\n * @returns An LLMHandler configured for Google Gemini API\n *\n * @example\n * ```typescript\n * const handler = createLLMHandler();\n * const model = handler.bind('gemini-1.5-pro');\n *\n * const response = await model.complete({\n * messages: [...],\n * config: { apiKey: 'your-api-key' },\n * });\n * ```\n */\nexport function createLLMHandler(): LLMHandler<GoogleLLMParams> {\n let providerRef: LLMProvider<GoogleLLMParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<GoogleLLMParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<GoogleLLMParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const model: BoundLLMModel<GoogleLLMParams> = {\n modelId,\n capabilities: GOOGLE_CAPABILITIES,\n\n get provider(): LLMProvider<GoogleLLMParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<GoogleLLMParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'llm'\n );\n\n const url = request.config.baseUrl\n ? `${request.config.baseUrl}/models/${modelId}:generateContent`\n : buildUrl(modelId, 'generateContent');\n\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'google',\n 'llm'\n );\n\n const data = await parseJsonResponse<GoogleResponse>(response, 'google', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<GoogleLLMParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'llm'\n );\n\n const url = request.config.baseUrl\n ? `${request.config.baseUrl}/models/${modelId}:streamGenerateContent?alt=sse`\n : `${buildUrl(modelId, 'streamGenerateContent')}?alt=sse`;\n\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'text/event-stream',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'google',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'google', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n ErrorCode.ProviderError,\n 'google',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n if (typeof data === 'object' && data !== null) {\n const chunk = data as GoogleStreamChunk;\n\n if (chunk.error) {\n const error = new UPPError(\n chunk.error.message,\n ErrorCode.ProviderError,\n 'google',\n ModalityType.LLM\n );\n responseReject(error);\n throw error;\n }\n\n const events = transformStreamChunk(chunk, state);\n for (const event of events) {\n yield event;\n // Also emit ObjectDelta for structured output - gives developers explicit hook\n if (request.structure && event.type === StreamEventType.TextDelta) {\n yield objectDelta(event.delta.text ?? '', event.index);\n }\n }\n }\n }\n\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Google Gemini Embeddings API Handler\n *\n * This module implements the embedding handler for Google's Gemini embeddings API.\n * Supports gemini-embedding-001 and text-embedding-004 models.\n *\n * @see {@link https://ai.google.dev/gemini-api/docs/embeddings Google Embeddings API Reference}\n * @module providers/google/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Base URL for Google's Gemini API */\nconst GOOGLE_API_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Google task types for embedding optimization.\n */\nexport type GoogleTaskType =\n | 'RETRIEVAL_QUERY'\n | 'RETRIEVAL_DOCUMENT'\n | 'SEMANTIC_SIMILARITY'\n | 'CLASSIFICATION'\n | 'CLUSTERING'\n | 'QUESTION_ANSWERING'\n | 'FACT_VERIFICATION'\n | 'CODE_RETRIEVAL_QUERY'\n | 'TASK_TYPE_UNSPECIFIED';\n\n/**\n * Google embedding parameters.\n * Passed through unchanged to the API.\n */\nexport interface GoogleEmbedParams {\n /** Task type for optimization */\n taskType?: GoogleTaskType;\n /** Document title (for RETRIEVAL_DOCUMENT taskType) */\n title?: string;\n /** Output dimensionality */\n outputDimensionality?: number;\n /** Whether to automatically truncate inputs exceeding token limits (default: true) */\n autoTruncate?: boolean;\n}\n\n/**\n * Google embeddings API response structure.\n */\ninterface GoogleEmbeddingsResponse {\n embeddings: Array<{\n values: number[];\n statistics?: {\n truncated?: boolean;\n tokenCount?: number;\n };\n }>;\n}\n\n/**\n * Creates an embedding handler for Google's Gemini Embeddings API.\n *\n * @returns An embedding handler configured for Google\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('gemini-embedding-001');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * params: { taskType: 'RETRIEVAL_DOCUMENT' },\n * config: { apiKey: 'AIza...' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<GoogleEmbedParams> {\n let providerRef: EmbeddingProvider<GoogleEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<GoogleEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<GoogleEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Embedding\n );\n }\n\n const model: BoundEmbeddingModel<GoogleEmbedParams> = {\n modelId,\n maxBatchSize: 100,\n maxInputLength: 2048,\n dimensions: 3072,\n\n get provider(): EmbeddingProvider<GoogleEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<GoogleEmbedParams>): Promise<EmbeddingResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'embedding'\n );\n\n const baseUrl = request.config.baseUrl ?? GOOGLE_API_URL;\n\n // Transform inputs to Google's format\n const requests = request.inputs.map((input) => {\n const text = typeof input === 'string' ? input : ('text' in input ? input.text : '');\n\n if (!text) {\n throw new UPPError(\n 'Google embeddings only support text input',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Embedding\n );\n }\n\n const embedRequest: Record<string, unknown> = {\n ...request.params,\n model: `models/${modelId}`,\n content: { parts: [{ text }] },\n };\n\n return embedRequest;\n });\n\n const url = `${baseUrl}/models/${modelId}:batchEmbedContents`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify({ requests }),\n signal: request.signal,\n }, request.config, 'google', 'embedding');\n\n const data = await parseJsonResponse<GoogleEmbeddingsResponse>(response, 'google', 'embedding');\n\n // Calculate total tokens\n let totalTokens = 0;\n for (const emb of data.embeddings) {\n totalTokens += emb.statistics?.tokenCount ?? 0;\n }\n\n // Return EmbeddingResponse - preserve ALL metadata\n return {\n embeddings: data.embeddings.map((e, index) => ({\n vector: e.values,\n index,\n tokens: e.statistics?.tokenCount,\n // Per-embedding metadata namespaced under provider (Spec 15.4)\n metadata: e.statistics ? {\n google: { truncated: e.statistics.truncated },\n } : undefined,\n })),\n usage: { totalTokens },\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Google Imagen Image Generation API Handler\n *\n * This module implements the image handler for Google's Imagen API via Google AI.\n * Supports Imagen 3 and 4 models through the Gemini API.\n *\n * @see {@link https://ai.google.dev/gemini-api/docs/imagen Imagen API Reference}\n * @module providers/google/image\n */\n\nimport type { ImageProvider, ImageHandler } from '../../types/provider.ts';\nimport type {\n BoundImageModel,\n ImageRequest,\n ImageResponse,\n ImageCapabilities,\n GeneratedImage,\n} from '../../types/image.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { Image } from '../../core/media/Image.ts';\n\nconst GOOGLE_AI_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\n/**\n * Google Imagen generation parameters.\n * Passed through unchanged to the API.\n */\nexport interface GoogleImagenParams {\n /** Number of images to generate (1-4) */\n sampleCount?: number;\n /** Image size: '1K' (1024px) or '2K' (2048px) */\n imageSize?: '1K' | '2K';\n /** Aspect ratio */\n aspectRatio?: '1:1' | '3:4' | '4:3' | '9:16' | '16:9';\n /** Person generation setting */\n personGeneration?: 'dont_allow' | 'allow_adult' | 'allow_all';\n /** Safety filter level */\n safetyFilterLevel?: 'block_low_and_above' | 'block_medium_and_above' | 'block_only_high' | 'block_none';\n /** Add invisible SynthID watermark (default: true) */\n addWatermark?: boolean;\n /**\n * Negative prompt to exclude concepts.\n * @deprecated Not supported on Imagen 3.0-002+ and Imagen 4 models. Will be ignored.\n */\n negativePrompt?: string;\n}\n\n/**\n * Google Imagen API response structure.\n */\ninterface GoogleImagenResponse {\n predictions?: Array<{\n bytesBase64Encoded: string;\n mimeType?: string;\n }>;\n}\n\n/**\n * Determines capabilities based on model ID.\n */\nfunction getCapabilities(): ImageCapabilities {\n return {\n generate: true,\n streaming: false,\n edit: false,\n maxImages: 4,\n };\n}\n\n/**\n * Build parameters object for the API.\n */\nfunction buildParameters(params?: GoogleImagenParams): Record<string, unknown> {\n return params ? { ...params } : {};\n}\n\n/**\n * Transform Google response to ImageResponse.\n */\nfunction transformResponse(data: GoogleImagenResponse): ImageResponse {\n if (!data.predictions || data.predictions.length === 0) {\n throw new UPPError(\n 'No images in response',\n ErrorCode.ProviderError,\n 'google',\n ModalityType.Image\n );\n }\n\n const images: GeneratedImage[] = data.predictions.map((prediction) => {\n const mimeType = prediction.mimeType ?? 'image/png';\n const image = Image.fromBase64(prediction.bytesBase64Encoded, mimeType);\n return { image };\n });\n\n return {\n images,\n usage: {\n imagesGenerated: images.length,\n },\n };\n}\n\n/**\n * Execute a non-streaming image generation request.\n */\nasync function executeGenerate(\n modelId: string,\n request: ImageRequest<GoogleImagenParams>\n): Promise<ImageResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'GOOGLE_API_KEY',\n 'google',\n 'image'\n );\n\n const baseUrl = request.config.baseUrl?.replace(/\\/$/, '') ?? GOOGLE_AI_BASE_URL;\n const url = `${baseUrl}/models/${modelId}:predict`;\n\n const body: Record<string, unknown> = {\n instances: [{\n prompt: request.prompt,\n }],\n parameters: buildParameters(request.params),\n };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(url, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'google', 'image');\n\n const data = await parseJsonResponse<GoogleImagenResponse>(response, 'google', 'image');\n\n return transformResponse(data);\n}\n\n/**\n * Creates an image handler for Google's Imagen API.\n *\n * @returns An image handler configured for Google Imagen\n *\n * @example\n * ```typescript\n * const handler = createImageHandler();\n * const model = handler.bind('imagen-4.0-generate-001');\n *\n * const response = await model.generate({\n * prompt: 'A sunset over mountains',\n * config: { apiKey: '...' },\n * params: { aspectRatio: '16:9', sampleCount: 4 }\n * });\n * ```\n */\nexport function createImageHandler(): ImageHandler<GoogleImagenParams> {\n let providerRef: ImageProvider<GoogleImagenParams> | null = null;\n\n return {\n _setProvider(provider: ImageProvider<GoogleImagenParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundImageModel<GoogleImagenParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.Image\n );\n }\n\n const capabilities = getCapabilities();\n\n const model: BoundImageModel<GoogleImagenParams> = {\n modelId,\n capabilities,\n\n get provider(): ImageProvider<GoogleImagenParams> {\n return providerRef!;\n },\n\n async generate(request: ImageRequest<GoogleImagenParams>): Promise<ImageResponse> {\n return executeGenerate(modelId, request);\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview Google Gemini caching utilities.\n *\n * Provides functions for creating and managing cached content entries\n * that can be reused across multiple Gemini API requests to reduce\n * costs and latency for repeated context.\n *\n * @see {@link https://ai.google.dev/api/caching Google Caching API docs}\n * @module providers/google/cache\n */\n\nimport type {\n GoogleCacheCreateRequest,\n GoogleCacheResponse,\n GoogleCacheUpdateRequest,\n GoogleCacheListResponse,\n GoogleContent,\n GoogleTool,\n} from './types.ts';\nimport type { ProviderConfig } from '../../types/provider.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../../types/errors.ts';\n\nconst DEFAULT_BASE_URL = 'https://generativelanguage.googleapis.com/v1beta';\n\nfunction resolveBaseUrl(config?: ProviderConfig): string {\n if (config?.baseUrl) {\n const trimmed = config.baseUrl.replace(/\\/$/, '');\n return trimmed.endsWith('/v1beta') ? trimmed : `${trimmed}/v1beta`;\n }\n return DEFAULT_BASE_URL;\n}\n\n/**\n * Options for creating a cached content entry.\n */\nexport interface CacheCreateOptions {\n /** API key for authentication */\n apiKey: string;\n /** Provider configuration (timeout, retry strategy, custom fetch) */\n config?: ProviderConfig;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Model to associate with this cache (e.g., \"gemini-3-flash-preview\") */\n model: string;\n /** Optional display name for the cache (max 128 chars) */\n displayName?: string;\n /** Content messages to cache */\n contents?: GoogleContent[];\n /** System instruction text to cache */\n systemInstruction?: string;\n /** Tool declarations to cache */\n tools?: GoogleTool[];\n /** Time-to-live duration (e.g., \"3600s\" for 1 hour) */\n ttl?: string;\n /** Absolute expiration time (RFC 3339 format, alternative to ttl) */\n expireTime?: string;\n}\n\n/**\n * Options for listing cached content entries.\n */\nexport interface CacheListOptions {\n /** API key for authentication */\n apiKey: string;\n /** Provider configuration (timeout, retry strategy, custom fetch) */\n config?: ProviderConfig;\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n /** Maximum number of caches to return per page */\n pageSize?: number;\n /** Token for fetching the next page of results */\n pageToken?: string;\n}\n\n/**\n * Creates a new cached content entry.\n *\n * Caches can contain system instructions, conversation content, and tool\n * declarations that are reused across multiple requests. This reduces\n * token costs and processing time for repeated context.\n *\n * @param options - Cache creation options\n * @returns The created cache entry with its name/ID for use in requests\n *\n * @example\n * ```typescript\n * import { google } from '@anthropic/provider-protocol';\n *\n * // Create a cache with system instruction and large context\n * const cache = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * displayName: 'Code Review Context',\n * systemInstruction: 'You are an expert code reviewer...',\n * contents: [\n * { role: 'user', parts: [{ text: largeCodebaseContent }] }\n * ],\n * ttl: '3600s', // 1 hour\n * });\n *\n * // Use the cache in subsequent requests\n * const response = await model.complete({\n * messages: [userMessage('Review this function')],\n * params: { cachedContent: cache.name },\n * });\n * ```\n */\nexport async function create(options: CacheCreateOptions): Promise<GoogleCacheResponse> {\n const {\n apiKey,\n config,\n signal,\n model,\n displayName,\n contents,\n systemInstruction,\n tools,\n ttl,\n expireTime,\n } = options;\n const baseUrl = resolveBaseUrl(config);\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const requestBody: GoogleCacheCreateRequest = {\n model: model.startsWith('models/') ? model : `models/${model}`,\n };\n\n if (displayName) {\n requestBody.displayName = displayName;\n }\n\n if (contents && contents.length > 0) {\n requestBody.contents = contents;\n }\n\n if (systemInstruction) {\n requestBody.systemInstruction = {\n parts: [{ text: systemInstruction }],\n };\n }\n\n if (tools && tools.length > 0) {\n requestBody.tools = tools;\n }\n\n if (ttl) {\n requestBody.ttl = ttl;\n } else if (expireTime) {\n requestBody.expireTime = expireTime;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n `${baseUrl}/cachedContents`,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(requestBody),\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Retrieves a cached content entry by name.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n * @returns The cache entry details\n *\n * @example\n * ```typescript\n * const cache = await google.cache.get('cachedContents/abc123', apiKey);\n * console.log(`Cache expires at: ${cache.expireTime}`);\n * ```\n */\nexport async function get(\n name: string,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<GoogleCacheResponse> {\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const url = `${baseUrl}/${cacheName}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'GET',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Lists all cached content entries.\n *\n * @param options - List options including API key and pagination\n * @returns Array of cache entries and optional next page token\n *\n * @example\n * ```typescript\n * const { cachedContents, nextPageToken } = await google.cache.list({\n * apiKey: process.env.GOOGLE_API_KEY,\n * pageSize: 10,\n * });\n *\n * for (const cache of cachedContents ?? []) {\n * console.log(`${cache.displayName}: ${cache.name}`);\n * }\n * ```\n */\nexport async function list(options: CacheListOptions): Promise<GoogleCacheListResponse> {\n const { apiKey, config, signal, pageSize, pageToken } = options;\n const baseUrl = resolveBaseUrl(config);\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const params = new URLSearchParams();\n if (pageSize) params.set('pageSize', String(pageSize));\n if (pageToken) params.set('pageToken', pageToken);\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n `${baseUrl}/cachedContents?${params}`,\n {\n method: 'GET',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheListResponse>(response, 'google', 'llm');\n}\n\n/**\n * Updates a cached content entry's expiration time.\n *\n * Only the expiration time can be updated; all other fields\n * (contents, systemInstruction, tools) are immutable after creation.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param update - The update to apply (exactly one of ttl or expireTime)\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n * @returns The updated cache entry\n *\n * @example\n * ```typescript\n * // Extend cache expiration by 2 hours\n * const updated = await google.cache.update(\n * 'cachedContents/abc123',\n * { ttl: '7200s' },\n * apiKey\n * );\n * ```\n */\nexport async function update(\n name: string,\n updateRequest: GoogleCacheUpdateRequest,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<GoogleCacheResponse> {\n if (updateRequest.expireTime && updateRequest.ttl) {\n throw new UPPError(\n 'Provide either expireTime or ttl (not both)',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const updateMaskParts: string[] = [];\n if (updateRequest.expireTime) {\n updateMaskParts.push('expireTime');\n }\n if (updateRequest.ttl) {\n updateMaskParts.push('ttl');\n }\n\n if (updateMaskParts.length === 0) {\n throw new UPPError(\n 'Update request must include expireTime or ttl',\n ErrorCode.InvalidRequest,\n 'google',\n ModalityType.LLM\n );\n }\n\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const params = new URLSearchParams({ updateMask: updateMaskParts.join(',') });\n const url = `${baseUrl}/${cacheName}?${params.toString()}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'x-goog-api-key': apiKey,\n };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'PATCH',\n headers,\n body: JSON.stringify(updateRequest),\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n\n return parseJsonResponse<GoogleCacheResponse>(response, 'google', 'llm');\n}\n\n/**\n * Deletes a cached content entry.\n *\n * @param name - The cache name (format: \"cachedContents/{id}\")\n * @param apiKey - API key for authentication\n * @param config - Provider configuration (timeout, retry strategy, custom fetch)\n * @param signal - Abort signal for cancellation\n *\n * @example\n * ```typescript\n * await google.cache.delete('cachedContents/abc123', apiKey);\n * ```\n */\nasync function deleteCache(\n name: string,\n apiKey: string,\n config?: ProviderConfig,\n signal?: AbortSignal\n): Promise<void> {\n const cacheName = name.startsWith('cachedContents/') ? name : `cachedContents/${name}`;\n const baseUrl = resolveBaseUrl(config);\n const url = `${baseUrl}/${cacheName}`;\n const requestConfig: ProviderConfig = { ...config, apiKey };\n\n const headers: Record<string, string> = { 'x-goog-api-key': apiKey };\n if (config?.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n url,\n {\n method: 'DELETE',\n headers,\n signal,\n },\n requestConfig,\n 'google',\n 'llm'\n );\n}\n\n/**\n * Cache utilities namespace.\n *\n * Provides functions for creating and managing Google Gemini cached content\n * entries. Use cached content to reduce costs and latency when repeatedly\n * sending the same context (system instructions, large documents, etc.)\n * across multiple requests.\n *\n * @example\n * ```typescript\n * import { google } from '@anthropic/provider-protocol';\n *\n * // Create a cache\n * const cache = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * systemInstruction: 'You are an expert assistant...',\n * contents: [{ role: 'user', parts: [{ text: largeDocument }] }],\n * ttl: '3600s',\n * });\n *\n * // Use cache.name in requests via params.cachedContent\n * const response = await model.complete({\n * messages: [userMessage('Summarize the document')],\n * params: { cachedContent: cache.name },\n * });\n *\n * // Manage caches\n * const caches = await google.cache.list({ apiKey });\n * await google.cache.update(cache.name, { ttl: '7200s' }, apiKey);\n * await google.cache.delete(cache.name, apiKey);\n * ```\n */\nexport const cache = {\n create,\n get,\n list,\n update,\n delete: deleteCache,\n};\n","/**\n * Provider-specific parameters for Google Gemini API requests.\n *\n * These parameters are passed through to the Google `generationConfig` field\n * and control model behavior such as output length, randomness, and sampling\n * strategies. All fields are optional and will use Google's defaults if omitted.\n *\n * @example\n * ```typescript\n * const params: GoogleLLMParams = {\n * maxOutputTokens: 2048,\n * temperature: 0.7,\n * topP: 0.9,\n * stopSequences: ['\\n\\n'],\n * };\n *\n * const response = await model.complete({\n * messages: [...],\n * config: { apiKey: '...' },\n * params,\n * });\n * ```\n *\n * @see {@link https://ai.google.dev/api/rest/v1beta/GenerationConfig Google GenerationConfig docs}\n */\nexport interface GoogleLLMParams {\n /** Maximum number of tokens to generate */\n maxOutputTokens?: number;\n\n /** Temperature for randomness (0.0 - 2.0) */\n temperature?: number;\n\n /** Top-p (nucleus) sampling */\n topP?: number;\n\n /** Top-k sampling */\n topK?: number;\n\n /** Stop sequences */\n stopSequences?: string[];\n\n /** Number of candidates to generate */\n candidateCount?: number;\n\n /** Response MIME type */\n responseMimeType?: 'text/plain' | 'application/json';\n\n /** Response schema for structured output */\n responseSchema?: Record<string, unknown>;\n\n /**\n * Modalities to generate in the response.\n *\n * Use `['IMAGE']` or `['TEXT', 'IMAGE']` with Gemini image generation models\n * (e.g., gemini-2.5-flash-image aka Nano Banana).\n */\n responseModalities?: GoogleResponseModality[];\n\n /**\n * Image generation configuration for Gemini image response modalities.\n */\n imageConfig?: GoogleImageConfig;\n\n /**\n * Presence penalty for new topics\n * Positive values encourage discussing new topics\n */\n presencePenalty?: number;\n\n /**\n * Frequency penalty for repeated tokens\n * Positive values discourage repetition\n */\n frequencyPenalty?: number;\n\n /**\n * Seed for deterministic sampling\n * Same seed with same parameters should produce same results\n */\n seed?: number;\n\n /**\n * Whether to return log probabilities in response\n */\n responseLogprobs?: boolean;\n\n /**\n * Number of log probabilities to return (requires responseLogprobs: true)\n */\n logprobs?: number;\n\n /**\n * Whether to include audio timestamps in response\n */\n audioTimestamp?: boolean;\n\n /**\n * Thinking/reasoning configuration for Gemini 3+ models\n */\n thinkingConfig?: GoogleThinkingConfig;\n\n /**\n * Cached content name to use for this request.\n * Format: \"cachedContents/{id}\" as returned from cache creation.\n * When set, the cached content is prepended to the request.\n */\n cachedContent?: string;\n\n /**\n * Built-in tools for server-side execution.\n *\n * Use the tool helper constructors from the `tools` namespace:\n * - `tools.googleSearch()` - Google Search grounding\n * - `tools.codeExecution()` - Python code execution\n * - `tools.urlContext()` - URL fetching and analysis\n * - `tools.googleMaps()` - Google Maps grounding\n * - `tools.fileSearch()` - Document RAG search\n *\n * Note: File Search cannot be combined with other built-in tools.\n *\n * @example\n * ```typescript\n * import { google, tools } from 'provider-protocol/google';\n *\n * const model = llm({\n * model: google('gemini-2.5-flash'),\n * params: {\n * tools: [\n * tools.googleSearch(),\n * tools.codeExecution(),\n * ],\n * },\n * });\n * ```\n */\n tools?: GoogleBuiltInTool[];\n\n /**\n * Tool configuration for retrieval (e.g., user location for Maps).\n *\n * @example\n * ```typescript\n * const params: GoogleLLMParams = {\n * tools: [tools.googleMaps()],\n * toolConfig: {\n * retrievalConfig: {\n * latLng: { latitude: 40.758896, longitude: -73.985130 },\n * },\n * },\n * };\n * ```\n */\n toolConfig?: GoogleToolConfig;\n}\n\n/**\n * Output modality enum values for Gemini responseModalities.\n *\n * The API supports TEXT, IMAGE, and AUDIO response types. Some SDK examples\n * use Title Case values, so both are accepted here.\n */\nexport type GoogleResponseModality =\n | 'TEXT'\n | 'IMAGE'\n | 'AUDIO'\n | 'Text'\n | 'Image'\n | 'Audio';\n\n/**\n * Image generation configuration for Gemini response modalities.\n */\nexport interface GoogleImageConfig {\n /**\n * Preferred aspect ratio for generated images.\n * Example: \"1:1\", \"9:16\", \"16:9\".\n */\n aspectRatio?: string;\n\n /**\n * Preferred output size for generated images.\n * Example: \"1024x1024\".\n */\n imageSize?: string;\n}\n\n/**\n * Configuration for extended thinking/reasoning in Gemini 2.5+ and 3+ models.\n *\n * Enables models to spend additional compute on reasoning before\n * generating a response, improving quality for complex tasks.\n *\n * For Gemini 2.5 models: Use `thinkingBudget` to control token allocation.\n * For Gemini 3+ models: Use `thinkingLevel` (recommended) to set reasoning depth.\n *\n * Set `includeThoughts: true` to receive thought/reasoning content in the response.\n */\nexport interface GoogleThinkingConfig {\n /**\n * Token budget allocated for model thinking/reasoning (Gemini 2.5 models).\n * - `-1`: Dynamic thinking (default)\n * - `0`: Disable thinking (Flash models only)\n * - `128-32768`: Specific token budget\n */\n thinkingBudget?: number;\n\n /**\n * Thinking level for Gemini 3+ models (recommended over thinkingBudget).\n * - `\"minimal\"`: Likely prevents thinking (Gemini 3 Flash only)\n * - `\"low\"`: Minimizes latency and cost\n * - `\"medium\"`: Balanced (Gemini 3 Flash only)\n * - `\"high\"`: Maximizes reasoning depth (default for Gemini 3)\n */\n thinkingLevel?: 'minimal' | 'low' | 'medium' | 'high';\n\n /**\n * Whether to include thought summaries in the response.\n * When true, response parts with `thought: true` contain reasoning content.\n */\n includeThoughts?: boolean;\n}\n\n/**\n * Request body structure for Google Generative Language API.\n *\n * This interface represents the complete request payload sent to Google's\n * generateContent or streamGenerateContent endpoints.\n */\nexport interface GoogleRequest {\n /** Array of content turns representing the conversation history. */\n contents: GoogleContent[];\n /** Optional system instruction provided separately from conversation content. */\n systemInstruction?: {\n parts: GooglePart[];\n };\n /** Generation parameters controlling model output behavior. */\n generationConfig?: {\n maxOutputTokens?: number;\n temperature?: number;\n topP?: number;\n topK?: number;\n stopSequences?: string[];\n candidateCount?: number;\n responseMimeType?: string;\n responseSchema?: Record<string, unknown>;\n responseModalities?: GoogleResponseModality[];\n imageConfig?: GoogleImageConfig;\n presencePenalty?: number;\n frequencyPenalty?: number;\n seed?: number;\n responseLogprobs?: boolean;\n logprobs?: number;\n audioTimestamp?: boolean;\n thinkingConfig?: GoogleThinkingConfig;\n };\n /** Function/tool declarations and built-in tools available for the model to call. */\n tools?: (GoogleTool | GoogleBuiltInTool)[];\n /** Safety filter settings to control content moderation. */\n safetySettings?: GoogleSafetySetting[];\n /**\n * Cached content name to use for this request.\n * Format: \"cachedContents/{id}\" as returned from cache creation.\n */\n cachedContent?: string;\n /** Tool configuration for retrieval (e.g., user location for Maps). */\n toolConfig?: GoogleToolConfig;\n}\n\n/**\n * A single content turn in the Google conversation format.\n *\n * Represents either a user message or model response, containing\n * one or more parts that can be text, images, or function calls/responses.\n */\nexport interface GoogleContent {\n /** Role indicating message source: 'user' for user input, 'model' for assistant responses. */\n role: 'user' | 'model';\n /** Array of content parts within this message turn. */\n parts: GooglePart[];\n}\n\n/**\n * Union type for all possible content part types in Google messages.\n *\n * Parts can contain text, inline images, function calls (from model),\n * function responses (from user providing tool results), or code execution\n * results (from built-in code execution tool).\n */\nexport type GooglePart =\n | GoogleTextPart\n | GoogleImagePart\n | GoogleFunctionCallPart\n | GoogleFunctionResponsePart\n | GoogleExecutableCodePart\n | GoogleCodeExecutionResultPart;\n\n/**\n * Text content part.\n */\nexport interface GoogleTextPart {\n /** The text content. */\n text: string;\n /** If true, this part contains thinking/reasoning content (Gemini 2.5+/3+). */\n thought?: boolean;\n /**\n * Encrypted thought signature for Gemini 3+ models.\n * Must be forwarded back in subsequent requests to maintain reasoning context.\n * Required for Gemini 3 multi-turn conversations; recommended for Gemini 2.5.\n */\n thoughtSignature?: string;\n}\n\n/**\n * Inline image content part with base64-encoded data.\n */\nexport interface GoogleImagePart {\n /** Inline image data container. */\n inlineData: {\n /** MIME type of the image (e.g., 'image/png', 'image/jpeg'). */\n mimeType: string;\n /** Base64-encoded image data. */\n data: string;\n };\n}\n\n/**\n * Function call part generated by the model.\n *\n * Represents the model's request to invoke a declared function with\n * specific arguments.\n */\nexport interface GoogleFunctionCallPart {\n /** Function call details. */\n functionCall: {\n /** Unique identifier for this function call (native ID from API). */\n id?: string;\n /** Name of the function to call. */\n name: string;\n /** Arguments to pass to the function. */\n args: Record<string, unknown>;\n };\n /** Thought signature for Gemini 3+ models to maintain context across multi-turn tool calls. */\n thoughtSignature?: string;\n}\n\n/**\n * Function response part provided by the user.\n *\n * Contains the result of executing a function call, sent back to\n * the model to continue the conversation.\n */\nexport interface GoogleFunctionResponsePart {\n /** Function response details. */\n functionResponse: {\n /** Unique identifier to correlate with the function call (matches functionCall.id if provided). */\n id?: string;\n /** Name of the function that was called. */\n name: string;\n /** Response data from the function execution. */\n response: Record<string, unknown>;\n };\n}\n\n/**\n * Executable code part generated by the model.\n *\n * Contains code that was written by the model for execution\n * via the built-in code execution tool.\n */\nexport interface GoogleExecutableCodePart {\n /** Executable code details. */\n executableCode: {\n /** Programming language of the code. */\n language: 'PYTHON' | 'LANGUAGE_UNSPECIFIED';\n /** The code to execute. */\n code: string;\n };\n}\n\n/**\n * Code execution result part from built-in code execution.\n *\n * Contains the output from executing code via the code execution tool.\n * Always follows an ExecutableCode part.\n */\nexport interface GoogleCodeExecutionResultPart {\n /** Code execution result details. */\n codeExecutionResult: {\n /** Execution outcome. */\n outcome: 'OUTCOME_UNSPECIFIED' | 'OUTCOME_OK' | 'OUTCOME_FAILED' | 'OUTCOME_DEADLINE_EXCEEDED';\n /** Execution output (stdout on success, stderr on failure). */\n output: string;\n };\n}\n\n/**\n * Tool definition containing function declarations.\n *\n * Google groups function declarations within a tools array, where each\n * tool object contains an array of function declarations.\n */\nexport interface GoogleTool {\n /** Array of function declarations available for the model to call. */\n functionDeclarations: GoogleFunctionDeclaration[];\n}\n\n/**\n * Declaration of a callable function/tool for the model.\n *\n * Describes the function signature including its name, purpose,\n * and expected parameters in JSON Schema format.\n */\nexport interface GoogleFunctionDeclaration {\n /** Unique name of the function. */\n name: string;\n /** Human-readable description of what the function does. */\n description: string;\n /** JSON Schema describing the function parameters. */\n parameters: {\n /** Schema type, always 'object' for function parameters. */\n type: 'object';\n /** Map of parameter names to their JSON Schema definitions. */\n properties: Record<string, unknown>;\n /** Array of required parameter names. */\n required?: string[];\n };\n}\n\n/**\n * Safety filter configuration for content moderation.\n *\n * Allows customization of safety thresholds for different harm categories.\n */\nexport interface GoogleSafetySetting {\n /** Harm category to configure (e.g., 'HARM_CATEGORY_HARASSMENT'). */\n category: string;\n /** Blocking threshold (e.g., 'BLOCK_NONE', 'BLOCK_LOW_AND_ABOVE'). */\n threshold: string;\n}\n\n/**\n * Response structure from Google's generateContent endpoint.\n *\n * Contains one or more candidate responses along with usage metadata.\n */\nexport interface GoogleResponse {\n /** Array of candidate responses (typically one unless candidateCount > 1). */\n candidates: GoogleCandidate[];\n /** Token usage statistics for billing and monitoring. */\n usageMetadata?: {\n /** Number of tokens in the input prompt. */\n promptTokenCount: number;\n /** Number of tokens in the generated candidates. */\n candidatesTokenCount: number;\n /** Total tokens (prompt + candidates). */\n totalTokenCount: number;\n /** Number of tokens read from cached content. */\n cachedContentTokenCount?: number;\n };\n}\n\n/**\n * A single candidate response from the model.\n */\nexport interface GoogleCandidate {\n /** The generated content including role and parts. */\n content: {\n /** Always 'model' for generated responses. */\n role: 'model';\n /** Array of response parts (text and/or function calls). */\n parts: GoogleResponsePart[];\n };\n /** Reason the model stopped generating. */\n finishReason: 'STOP' | 'MAX_TOKENS' | 'SAFETY' | 'RECITATION' | 'OTHER' | 'TOOL_USE' | null;\n /** Index of this candidate in the candidates array. */\n index: number;\n /** Safety ratings for the generated content. */\n safetyRatings?: GoogleSafetyRating[];\n}\n\n/**\n * Part types that can appear in model responses.\n *\n * Responses may contain text, inline images (when responseModalities includes IMAGE),\n * function calls, or code execution results.\n */\nexport type GoogleResponsePart =\n | GoogleTextPart\n | GoogleImagePart\n | GoogleFunctionCallPart\n | GoogleExecutableCodePart\n | GoogleCodeExecutionResultPart;\n\n/**\n * Safety rating for a specific harm category.\n */\nexport interface GoogleSafetyRating {\n /** The harm category being rated. */\n category: string;\n /** Probability level of the harm (e.g., 'NEGLIGIBLE', 'LOW', 'MEDIUM', 'HIGH'). */\n probability: string;\n}\n\n/**\n * Streaming response chunk from Google's streamGenerateContent endpoint.\n *\n * Has the same structure as GoogleResponse but fields may be partial\n * or omitted depending on what data is available in the current chunk.\n */\nexport interface GoogleStreamChunk {\n /** Partial candidate data for this chunk. */\n candidates?: GoogleCandidate[];\n /** Cumulative token usage (updated with each chunk). */\n usageMetadata?: {\n /** Number of tokens in the input prompt. */\n promptTokenCount: number;\n /** Number of tokens generated so far. */\n candidatesTokenCount: number;\n /** Total tokens consumed so far. */\n totalTokenCount: number;\n /** Number of tokens read from cached content. */\n cachedContentTokenCount?: number;\n };\n /** Error response from the API (when streaming fails). */\n error?: {\n /** Error message from the API. */\n message: string;\n /** Error code. */\n code?: number;\n /** Error status string. */\n status?: string;\n };\n}\n\n// ============================================\n// Caching API Types\n// ============================================\n\n/**\n * Request body for creating a cached content entry.\n *\n * @see {@link https://ai.google.dev/api/caching Google Caching API docs}\n */\nexport interface GoogleCacheCreateRequest {\n /** Model to use with this cache (format: models/{model}) */\n model: string;\n /** Optional display name for the cache (max 128 chars) */\n displayName?: string;\n /** Content to cache (immutable after creation) */\n contents?: GoogleContent[];\n /** System instruction to cache (text-only, immutable after creation) */\n systemInstruction?: {\n role?: 'user';\n parts: Array<{ text: string }>;\n };\n /** Tool declarations to cache (immutable after creation) */\n tools?: GoogleTool[];\n /** Tool configuration to cache (immutable after creation) */\n toolConfig?: {\n functionCallingConfig?: {\n mode?: 'AUTO' | 'ANY' | 'NONE' | 'VALIDATED';\n allowedFunctionNames?: string[];\n };\n };\n /** Absolute expiration time (RFC 3339 format, mutually exclusive with ttl) */\n expireTime?: string;\n /** Time-to-live duration (e.g., \"300s\", \"3600s\", mutually exclusive with expireTime) */\n ttl?: string;\n}\n\n/**\n * Response from creating or retrieving a cached content entry.\n */\nexport interface GoogleCacheResponse {\n /** Cache identifier in format \"cachedContents/{id}\" - use this in requests */\n name: string;\n /** Model this cache is associated with */\n model: string;\n /** Display name for the cache */\n displayName?: string;\n /** When the cache was created (RFC 3339 format) */\n createTime: string;\n /** When the cache was last updated (RFC 3339 format) */\n updateTime: string;\n /** When the cache expires (RFC 3339 format) */\n expireTime: string;\n /** Token usage metadata */\n usageMetadata?: {\n /** Total tokens in the cached content */\n totalTokenCount: number;\n };\n}\n\n/**\n * Request body for updating a cached content entry.\n * Only expiration can be updated; all other fields are immutable.\n */\nexport interface GoogleCacheUpdateRequest {\n /** New absolute expiration time (RFC 3339 format, mutually exclusive with ttl) */\n expireTime?: string;\n /** New time-to-live duration (e.g., \"3600s\", mutually exclusive with expireTime) */\n ttl?: string;\n}\n\n/**\n * Response from listing cached content entries.\n */\nexport interface GoogleCacheListResponse {\n /** Array of cached content entries */\n cachedContents?: GoogleCacheResponse[];\n /** Token for fetching the next page of results */\n nextPageToken?: string;\n}\n\n/**\n * Google Gemini-specific HTTP headers for API requests.\n *\n * @example\n * ```typescript\n * const headers: GoogleHeaders = {\n * 'x-goog-api-client': 'myapp/1.0.0',\n * };\n * ```\n */\nexport interface GoogleHeaders {\n /** Client identification header for partners and libraries. */\n 'x-goog-api-client'?: string;\n /** Quota project ID for Vertex AI billing. */\n 'x-goog-user-project'?: string;\n [key: string]: string | undefined;\n}\n\n// ============================================\n// Built-in Tools\n// ============================================\n\n/**\n * Google Search grounding tool for real-time web information.\n *\n * Enables Gemini to search the web using Google Search for up-to-date information.\n * Results are returned with grounding metadata including sources and citations.\n *\n * Pricing:\n * - Gemini 2.x and earlier: $35 per 1,000 grounded prompts\n * - Gemini 3.x: $14 per 1,000 search queries\n *\n * @example\n * ```typescript\n * const tool: GoogleSearchTool = {\n * googleSearch: {},\n * };\n * ```\n */\nexport interface GoogleSearchTool {\n /** Empty object to enable Google Search grounding */\n googleSearch: Record<string, never>;\n}\n\n/**\n * Code execution tool for running Python in a sandbox.\n *\n * Enables Gemini to write and execute Python code in a secure environment.\n * Supports data analysis, calculations, and visualization.\n *\n * No additional cost - standard token pricing applies.\n *\n * @example\n * ```typescript\n * const tool: GoogleCodeExecutionTool = {\n * codeExecution: {},\n * };\n * ```\n */\nexport interface GoogleCodeExecutionTool {\n /** Empty object to enable code execution */\n codeExecution: Record<string, never>;\n}\n\n/**\n * URL context tool for fetching and processing URLs.\n *\n * Enables Gemini to fetch and analyze content from URLs.\n * Supports text, images, and PDF documents.\n *\n * Limits:\n * - Maximum 20 URLs per request\n * - Maximum 34MB content per URL\n *\n * @example\n * ```typescript\n * const tool: GoogleUrlContextTool = {\n * urlContext: {},\n * };\n * ```\n */\nexport interface GoogleUrlContextTool {\n /** Empty object to enable URL context */\n urlContext: Record<string, never>;\n}\n\n/**\n * Google Maps grounding tool for location-based queries.\n *\n * Enables Gemini to search for places, businesses, and locations\n * using Google Maps data.\n *\n * Pricing: $25 per 1,000 grounded prompts.\n *\n * Note: Not supported in Gemini 3 models.\n *\n * @example\n * ```typescript\n * const tool: GoogleMapsTool = {\n * googleMaps: {\n * enableWidget: true,\n * },\n * };\n * ```\n */\nexport interface GoogleMapsTool {\n /** Google Maps configuration */\n googleMaps: {\n /** Return widget context token for Places widget */\n enableWidget?: boolean;\n };\n}\n\n/**\n * File search (RAG) tool for document retrieval.\n *\n * Enables Gemini to search through uploaded documents\n * using semantic search on FileSearchStore.\n *\n * Pricing:\n * - Embeddings at indexing: $0.15 per 1M tokens\n * - Storage and query embeddings: Free\n *\n * Note: Cannot be combined with other built-in tools.\n *\n * @example\n * ```typescript\n * const tool: GoogleFileSearchTool = {\n * fileSearch: {\n * fileSearchStoreNames: ['fileSearchStores/abc123'],\n * },\n * };\n * ```\n */\nexport interface GoogleFileSearchTool {\n /** File search configuration */\n fileSearch: {\n /** FileSearchStore names to query */\n fileSearchStoreNames: string[];\n /** AIP-160 filter syntax for metadata filtering */\n metadataFilter?: string;\n };\n}\n\n/**\n * Union type for all Google built-in tools.\n *\n * Note: Google's built-in tools use a different structure than function tools.\n * They are passed directly in the tools array alongside functionDeclarations.\n */\nexport type GoogleBuiltInTool =\n | GoogleSearchTool\n | GoogleCodeExecutionTool\n | GoogleUrlContextTool\n | GoogleMapsTool\n | GoogleFileSearchTool;\n\n/**\n * Tool configuration for retrieval (e.g., user location for Maps).\n */\nexport interface GoogleToolConfig {\n /** Retrieval configuration */\n retrievalConfig?: {\n /** User location for \"near me\" queries */\n latLng?: {\n /** User latitude */\n latitude: number;\n /** User longitude */\n longitude: number;\n };\n };\n}\n\n/**\n * Grounding metadata returned with search/maps results.\n */\nexport interface GoogleGroundingMetadata {\n /** Web search queries executed */\n webSearchQueries?: string[];\n /** Search entry point with rendered HTML */\n searchEntryPoint?: {\n renderedContent: string;\n };\n /** Grounding chunks (sources) */\n groundingChunks?: Array<{\n web?: {\n uri: string;\n title: string;\n };\n maps?: {\n uri: string;\n placeId: string;\n title: string;\n };\n }>;\n /** Grounding supports (citations) */\n groundingSupports?: Array<{\n segment: {\n startIndex: number;\n endIndex: number;\n text: string;\n };\n groundingChunkIndices: number[];\n confidenceScores: number[];\n }>;\n /** Google Maps widget context token */\n googleMapsWidgetContextToken?: string;\n}\n\n/**\n * Code execution result in response.\n */\nexport interface GoogleCodeExecutionResult {\n /** Execution outcome */\n outcome: 'OUTCOME_OK' | 'OUTCOME_FAILED' | 'OUTCOME_DEADLINE_EXCEEDED';\n /** Execution output (stdout) */\n output: string;\n}\n\n// ============================================\n// Tool Helper Constructors\n// ============================================\n\n/**\n * Creates a Google Search grounding tool configuration.\n *\n * Enables Gemini to search the web using Google Search for up-to-date information.\n *\n * @returns A Google Search tool configuration object\n *\n * @example\n * ```typescript\n * const search = googleSearchTool();\n * ```\n */\nexport function googleSearchTool(): GoogleSearchTool {\n return { googleSearch: {} };\n}\n\n/**\n * Creates a code execution tool configuration.\n *\n * Enables Gemini to write and execute Python code in a sandbox.\n *\n * @returns A code execution tool configuration object\n *\n * @example\n * ```typescript\n * const codeExec = codeExecutionTool();\n * ```\n */\nexport function codeExecutionTool(): GoogleCodeExecutionTool {\n return { codeExecution: {} };\n}\n\n/**\n * Creates a URL context tool configuration.\n *\n * Enables Gemini to fetch and analyze content from URLs.\n *\n * @returns A URL context tool configuration object\n *\n * @example\n * ```typescript\n * const urlCtx = urlContextTool();\n * ```\n */\nexport function urlContextTool(): GoogleUrlContextTool {\n return { urlContext: {} };\n}\n\n/**\n * Creates a Google Maps grounding tool configuration.\n *\n * Enables Gemini to search for places using Google Maps data.\n *\n * Note: Not supported in Gemini 3 models.\n *\n * @param options - Optional configuration\n * @returns A Google Maps tool configuration object\n *\n * @example\n * ```typescript\n * const maps = googleMapsTool();\n *\n * // With widget enabled\n * const mapsWithWidget = googleMapsTool({ enableWidget: true });\n * ```\n */\nexport function googleMapsTool(options?: {\n enableWidget?: boolean;\n}): GoogleMapsTool {\n return {\n googleMaps: {\n ...(options?.enableWidget !== undefined && { enableWidget: options.enableWidget }),\n },\n };\n}\n\n/**\n * Creates a file search (RAG) tool configuration.\n *\n * Enables Gemini to search through uploaded documents.\n *\n * Note: Cannot be combined with other built-in tools.\n *\n * @param options - File search configuration\n * @returns A file search tool configuration object\n *\n * @example\n * ```typescript\n * const fileSearch = fileSearchTool({\n * fileSearchStoreNames: ['fileSearchStores/abc123'],\n * });\n * ```\n */\nexport function fileSearchTool(options: {\n fileSearchStoreNames: string[];\n metadataFilter?: string;\n}): GoogleFileSearchTool {\n return {\n fileSearch: options,\n };\n}\n\n/**\n * Namespace object containing all Google tool helper constructors.\n *\n * Provides a convenient way to create built-in tool configurations.\n *\n * @example\n * ```typescript\n * import { google, tools } from 'provider-protocol/google';\n *\n * const model = llm({\n * model: google('gemini-2.5-flash'),\n * params: {\n * tools: [\n * tools.googleSearch(),\n * tools.codeExecution(),\n * ],\n * },\n * });\n * ```\n */\nexport const tools = {\n /** Creates a Google Search grounding tool configuration */\n googleSearch: googleSearchTool,\n /** Creates a code execution tool configuration */\n codeExecution: codeExecutionTool,\n /** Creates a URL context tool configuration */\n urlContext: urlContextTool,\n /** Creates a Google Maps grounding tool configuration */\n googleMaps: googleMapsTool,\n /** Creates a file search (RAG) tool configuration */\n fileSearch: fileSearchTool,\n};\n","import { createProvider } from '../../core/provider.ts';\nimport { createLLMHandler } from './llm.ts';\nimport { createEmbeddingHandler } from './embed.ts';\nimport { createImageHandler } from './image.ts';\nimport { cache } from './cache.ts';\n\nconst baseProvider = createProvider({\n name: 'google',\n version: '1.0.0',\n handlers: {\n llm: createLLMHandler(),\n embedding: createEmbeddingHandler(),\n image: createImageHandler(),\n },\n});\n\n/**\n * Google Gemini provider for the Unified Provider Protocol (UPP).\n *\n * Provides access to Google's Gemini family of large language models through\n * a standardized interface. Supports text generation, multimodal inputs\n * (images, video, audio), tool/function calling, and structured output.\n *\n * @example\n * ```typescript\n * import { google } from './providers/google';\n * import { llm } from './core/llm';\n * import { StreamEventType } from './types/stream';\n *\n * const gemini = llm({\n * model: google('gemini-1.5-pro'),\n * config: { apiKey: process.env.GOOGLE_API_KEY },\n * });\n *\n * const turn = await gemini.generate('Hello!');\n * console.log(turn.response.text);\n *\n * const stream = gemini.stream('Tell me a story');\n * for await (const event of stream) {\n * if (event.type === StreamEventType.TextDelta) {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n * ```\n *\n * @example Caching\n * ```typescript\n * // Create a cache for repeated context\n * const cacheEntry = await google.cache.create({\n * apiKey: process.env.GOOGLE_API_KEY,\n * model: 'gemini-3-flash-preview',\n * systemInstruction: 'You are an expert code reviewer...',\n * contents: [{ role: 'user', parts: [{ text: largeCodebase }] }],\n * ttl: '3600s',\n * });\n *\n * // Use cache in requests\n * const cachedModel = llm({\n * model: google('gemini-3-flash-preview'),\n * config: { apiKey: process.env.GOOGLE_API_KEY },\n * params: { cachedContent: cacheEntry.name },\n * });\n *\n * const response = await cachedModel.generate('Review this function');\n *\n * // Manage caches\n * await google.cache.update(cacheEntry.name, { ttl: '7200s' }, apiKey);\n * await google.cache.delete(cacheEntry.name, apiKey);\n * ```\n *\n * @see {@link GoogleLLMParams} for provider-specific configuration options\n * @see {@link cache} for caching utilities\n */\nexport const google = Object.assign(baseProvider, { cache });\n\nexport { cache } from './cache.ts';\nexport { tools } from './types.ts';\nexport type { CacheCreateOptions, CacheListOptions } from './cache.ts';\nexport type {\n GoogleLLMParams,\n GoogleResponseModality,\n GoogleImageConfig,\n GoogleCacheCreateRequest,\n GoogleCacheResponse,\n GoogleCacheUpdateRequest,\n GoogleCacheListResponse,\n GoogleHeaders,\n GoogleBuiltInTool,\n GoogleSearchTool,\n GoogleCodeExecutionTool,\n GoogleUrlContextTool,\n GoogleMapsTool,\n GoogleFileSearchTool,\n GoogleToolConfig,\n GoogleGroundingMetadata,\n GoogleCodeExecutionResult,\n} from './types.ts';\n\nexport type { GoogleEmbedParams, GoogleTaskType } from './embed.ts';\n\nexport type { GoogleImagenParams } from './image.ts';\n"],"mappings":"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","names":["transformResponse","tools"]}