@langchain/google 0.2.12 → 0.2.14
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.
- package/CHANGELOG.md +24 -0
- package/dist/chat_models/api_types/generate_content.d.cts +0 -2
- package/dist/chat_models/api_types/generate_content.d.ts +0 -2
- package/dist/chat_models/api_types/interactions.d.cts +1423 -0
- package/dist/chat_models/api_types/interactions.d.ts +1423 -0
- package/dist/chat_models/base.cjs +12 -11
- package/dist/chat_models/base.cjs.map +1 -1
- package/dist/chat_models/base.d.cts +3 -5
- package/dist/chat_models/base.d.ts +3 -5
- package/dist/chat_models/base.js +12 -11
- package/dist/chat_models/base.js.map +1 -1
- package/dist/chat_models/handlers/base.cjs +1 -2
- package/dist/chat_models/handlers/base.d.cts +0 -2
- package/dist/chat_models/handlers/base.d.ts +0 -2
- package/dist/chat_models/handlers/base.js +1 -2
- package/dist/chat_models/handlers/generate_content.cjs +7 -7
- package/dist/chat_models/handlers/generate_content.cjs.map +1 -1
- package/dist/chat_models/handlers/generate_content.d.cts +0 -2
- package/dist/chat_models/handlers/generate_content.d.ts +0 -2
- package/dist/chat_models/handlers/generate_content.js +7 -7
- package/dist/chat_models/handlers/generate_content.js.map +1 -1
- package/dist/chat_models/handlers/index.cjs +2 -0
- package/dist/chat_models/handlers/index.d.cts +2 -1
- package/dist/chat_models/handlers/index.d.ts +2 -1
- package/dist/chat_models/handlers/index.js +2 -1
- package/dist/chat_models/handlers/interactions.cjs +303 -0
- package/dist/chat_models/handlers/interactions.cjs.map +1 -0
- package/dist/chat_models/handlers/interactions.d.cts +33 -0
- package/dist/chat_models/handlers/interactions.d.ts +33 -0
- package/dist/chat_models/handlers/interactions.js +303 -0
- package/dist/chat_models/handlers/interactions.js.map +1 -0
- package/dist/chat_models/index.cjs +5 -4
- package/dist/chat_models/index.cjs.map +1 -1
- package/dist/chat_models/index.d.cts +4 -5
- package/dist/chat_models/index.d.ts +4 -5
- package/dist/chat_models/index.js +5 -5
- package/dist/chat_models/index.js.map +1 -1
- package/dist/chat_models/node.cjs +3 -4
- package/dist/chat_models/node.d.cts +1 -3
- package/dist/chat_models/node.d.ts +1 -3
- package/dist/chat_models/node.js +3 -4
- package/dist/chat_models/profiles.cjs +1 -2
- package/dist/chat_models/profiles.js +1 -2
- package/dist/chat_models/types.cjs +1 -2
- package/dist/chat_models/types.cjs.map +1 -1
- package/dist/chat_models/types.d.cts +524 -23
- package/dist/chat_models/types.d.ts +524 -23
- package/dist/chat_models/types.js +1 -2
- package/dist/chat_models/types.js.map +1 -1
- package/dist/clients/index.cjs +3 -4
- package/dist/clients/index.d.cts +0 -2
- package/dist/clients/index.d.ts +0 -2
- package/dist/clients/index.js +3 -4
- package/dist/clients/node.cjs +4 -5
- package/dist/clients/node.d.cts +0 -2
- package/dist/clients/node.d.ts +0 -2
- package/dist/clients/node.js +4 -5
- package/dist/const.cjs +1 -2
- package/dist/const.js +1 -2
- package/dist/converters/generate_content/messages.cjs +2 -2
- package/dist/converters/generate_content/messages.cjs.map +1 -1
- package/dist/converters/generate_content/messages.js +2 -2
- package/dist/converters/generate_content/messages.js.map +1 -1
- package/dist/converters/generate_content/params.cjs +1 -2
- package/dist/converters/generate_content/params.js +1 -2
- package/dist/converters/generate_content/stream_events.cjs +9 -3
- package/dist/converters/generate_content/stream_events.cjs.map +1 -1
- package/dist/converters/generate_content/stream_events.js +9 -3
- package/dist/converters/generate_content/stream_events.js.map +1 -1
- package/dist/converters/generate_content/tools.cjs +1 -2
- package/dist/converters/generate_content/tools.js +1 -2
- package/dist/converters/interactions/messages.cjs +766 -0
- package/dist/converters/interactions/messages.cjs.map +1 -0
- package/dist/converters/interactions/messages.js +759 -0
- package/dist/converters/interactions/messages.js.map +1 -0
- package/dist/converters/interactions/params.cjs +244 -0
- package/dist/converters/interactions/params.cjs.map +1 -0
- package/dist/converters/interactions/params.js +237 -0
- package/dist/converters/interactions/params.js.map +1 -0
- package/dist/converters/interactions/stream_events.cjs +769 -0
- package/dist/converters/interactions/stream_events.cjs.map +1 -0
- package/dist/converters/interactions/stream_events.js +768 -0
- package/dist/converters/interactions/stream_events.js.map +1 -0
- package/dist/converters/interactions/tools.cjs +229 -0
- package/dist/converters/interactions/tools.cjs.map +1 -0
- package/dist/converters/interactions/tools.js +228 -0
- package/dist/converters/interactions/tools.js.map +1 -0
- package/dist/converters/shared/params.cjs +1 -2
- package/dist/converters/shared/params.js +1 -2
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -1
- package/dist/node.cjs +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/utils/errors.cjs +22 -4
- package/dist/utils/errors.cjs.map +1 -1
- package/dist/utils/errors.js +22 -6
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/gcp-auth.cjs +3 -4
- package/dist/utils/gcp-auth.d.cts +0 -2
- package/dist/utils/gcp-auth.d.ts +0 -2
- package/dist/utils/gcp-auth.js +3 -4
- package/dist/utils/handler.cjs +1 -2
- package/dist/utils/handler.d.cts +0 -2
- package/dist/utils/handler.d.ts +0 -2
- package/dist/utils/handler.js +1 -2
- package/dist/utils/metadata.cjs +1 -2
- package/dist/utils/metadata.js +1 -2
- package/dist/utils/misc.cjs +1 -2
- package/dist/utils/misc.d.cts +0 -2
- package/dist/utils/misc.d.ts +0 -2
- package/dist/utils/misc.js +1 -2
- package/dist/utils/stream.cjs +1 -2
- package/dist/utils/stream.js +1 -2
- package/package.json +11 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","names":[],"sources":["../../../src/converters/interactions/messages.ts"],"sourcesContent":["import {\n AIMessage,\n BaseMessage,\n ContentBlock,\n SystemMessage,\n ToolMessage,\n UsageMetadata,\n InputTokenDetails,\n OutputTokenDetails,\n} from \"@langchain/core/messages\";\nimport type { Gemini } from \"../../chat_models/types.js\";\nimport { GoogleError } from \"../../utils/errors.js\";\nimport {\n convertGeminiPartToContentBlock,\n convertGeminiPartsToToolCalls,\n convertMessagesToGeminiContents,\n convertMessagesToGeminiSystemInstruction,\n} from \"../generate_content/messages.js\";\n\n/**\n * Converts a single LangChain `BaseMessage` into `Gemini.Part[]` by delegating\n * to the existing GenerateContent message converters.\n *\n * When `message` is a `ToolMessage`, `convertMessagesToGeminiContents` requires\n * the preceding `AIMessage` that issued the matching `tool_call_id` to be present\n * in the input array so it can resolve the function name (and avoid throwing\n * `ToolCallNotFoundError`). Pass the full `messages` conversation array when\n * converting a `ToolMessage` so the matching `AIMessage` can be included as\n * context; if none is found (e.g., a standalone `ToolMessage`), a minimal\n * synthetic `AIMessage` is provided as a fallback. Only the `Gemini.Part[]`\n * produced for `message` itself is returned.\n *\n * @param message - The individual message to convert into `Gemini.Part[]`.\n * @param messages - Optional full conversation history used to look up the\n * matching `AIMessage` when `message` is a `ToolMessage`.\n */\nfunction convertSingleMessageToGeminiParts(\n message: BaseMessage,\n messages?: BaseMessage[]\n): Gemini.Part[] {\n if (SystemMessage.isInstance(message)) {\n const sys = convertMessagesToGeminiSystemInstruction([message]);\n return sys?.parts ?? [];\n }\n if (ToolMessage.isInstance(message)) {\n // Look up the AIMessage that originated this tool call so\n // `convertMessagesToGeminiContents` can resolve the tool name and build\n // a `functionResponse` part alongside any sibling media (`inlineData`/`fileData`) parts.\n const aiMsg = messages\n ?.filter(AIMessage.isInstance)\n .find((msg) =>\n msg.tool_calls?.find((tc) => tc.id === message.tool_call_id)\n );\n // If no matching AIMessage is in history, synthesize a minimal one so\n // `convertMessagesToGeminiContents` does not throw `ToolCallNotFoundError`.\n const fallbackAiMsg =\n !aiMsg && message.tool_call_id\n ? new AIMessage({\n tool_calls: [\n {\n type: \"tool_call\",\n id: message.tool_call_id,\n name: message.name ?? \"unknown\",\n args: {},\n },\n ],\n })\n : undefined;\n const contextMessages = [\n ...(aiMsg ? [aiMsg] : fallbackAiMsg ? [fallbackAiMsg] : []),\n message,\n ];\n const contents = convertMessagesToGeminiContents(contextMessages);\n // `contents` contains `[aiContent, toolContent]`; only return the parts\n // generated for the `ToolMessage` itself (the last entry).\n const lastContent = contents[contents.length - 1];\n return lastContent?.parts ?? [];\n }\n const contents = convertMessagesToGeminiContents([message]);\n return contents.flatMap((c) => c.parts ?? []);\n}\n\n/**\n * Extracts and concatenates leading `SystemMessage` instances into the\n * Interactions API `system_instruction` string.\n */\nexport function convertMessagesToInteractionsSystemInstruction(\n messages: BaseMessage[]\n): string | undefined {\n const chunks: string[] = [];\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n if (SystemMessage.isInstance(message)) {\n const parts = convertSingleMessageToGeminiParts(message);\n for (const part of parts) {\n if (typeof part.text === \"string\" && part.text.length > 0) {\n chunks.push(part.text);\n }\n }\n } else {\n break;\n }\n }\n return chunks.length > 0 ? chunks.join(\"\\n\") : undefined;\n}\n\n/**\n * Maps a GenerateContent `Part.MediaResolution` or string into an Interactions `MediaResolution`.\n */\nfunction mapPartResolutionToInteractions(\n partResolution?: Gemini.Part[\"mediaResolution\"] | { level?: string },\n defaultResolution?: Gemini.Interactions.MediaResolution\n): Gemini.Interactions.MediaResolution | undefined {\n const rawLevel =\n typeof partResolution === \"string\" ? partResolution : partResolution?.level;\n if (rawLevel) {\n const lower = rawLevel.toLowerCase();\n if (lower === \"media_resolution_low\" || lower === \"low\") return \"low\";\n if (lower === \"media_resolution_medium\" || lower === \"medium\")\n return \"medium\";\n if (lower === \"media_resolution_high\" || lower === \"high\") return \"high\";\n if (lower === \"media_resolution_ultra_high\" || lower === \"ultra_high\")\n return \"ultra_high\";\n }\n return defaultResolution;\n}\n\n/**\n * Converts a single `Gemini.Part` (produced by `convertMessageToGeminiParts`) into an\n * Interactions API `Content` item (`TextContent`, `ImageContent`, `AudioContent`,\n * `DocumentContent`, or `VideoContent`).\n */\nexport function convertGeminiPartToInteractionsContent(\n part: Gemini.Part,\n defaultMediaResolution?: Gemini.Interactions.MediaResolution\n): Gemini.Interactions.Content | undefined {\n if (typeof part.text === \"string\") {\n return {\n type: \"text\",\n text: part.text,\n };\n }\n\n if (part.inlineData) {\n const mimeType = part.inlineData.mimeType || \"application/octet-stream\";\n const data = part.inlineData.data;\n const resolution = mapPartResolutionToInteractions(\n part.mediaResolution,\n defaultMediaResolution\n );\n\n if (mimeType.startsWith(\"image/\")) {\n return {\n type: \"image\",\n mime_type: mimeType as Gemini.Interactions.ImageContent[\"mime_type\"],\n data,\n ...(resolution ? { resolution } : {}),\n };\n }\n if (mimeType.startsWith(\"audio/\")) {\n return {\n type: \"audio\",\n mime_type: mimeType as Gemini.Interactions.AudioContent[\"mime_type\"],\n data,\n };\n }\n if (mimeType.startsWith(\"video/\")) {\n return {\n type: \"video\",\n mime_type: mimeType as Gemini.Interactions.VideoContent[\"mime_type\"],\n data,\n ...(resolution ? { resolution } : {}),\n };\n }\n return {\n type: \"document\",\n mime_type: mimeType as Gemini.Interactions.DocumentContent[\"mime_type\"],\n data,\n };\n }\n\n if (part.fileData) {\n const mimeType = part.fileData.mimeType || \"application/octet-stream\";\n const uri = part.fileData.fileUri;\n const resolution = mapPartResolutionToInteractions(\n part.mediaResolution,\n defaultMediaResolution\n );\n\n if (mimeType.startsWith(\"image/\")) {\n return {\n type: \"image\",\n mime_type: mimeType as Gemini.Interactions.ImageContent[\"mime_type\"],\n uri,\n ...(resolution ? { resolution } : {}),\n };\n }\n if (mimeType.startsWith(\"audio/\")) {\n return {\n type: \"audio\",\n mime_type: mimeType as Gemini.Interactions.AudioContent[\"mime_type\"],\n uri,\n };\n }\n if (mimeType.startsWith(\"video/\")) {\n return {\n type: \"video\",\n mime_type: mimeType as Gemini.Interactions.VideoContent[\"mime_type\"],\n uri,\n ...(resolution ? { resolution } : {}),\n };\n }\n return {\n type: \"document\",\n mime_type: mimeType as Gemini.Interactions.DocumentContent[\"mime_type\"],\n uri,\n };\n }\n\n return undefined;\n}\n\n/**\n * Converts an Interactions API `Content` item into a `Gemini.Part` so that\n * downstream `convertGeminiPartToContentBlock` produces identical LangChain\n * `AIMessage` content blocks to `GenerateContentApiHandler`.\n */\nexport function convertInteractionsContentToGeminiPart(\n content: Gemini.Interactions.Content,\n thoughtSignature?: string\n): Gemini.Part | undefined {\n const sigSpread = thoughtSignature ? { thoughtSignature } : {};\n\n switch (content.type) {\n case \"text\":\n return {\n text: content.text,\n ...sigSpread,\n };\n case \"image\":\n case \"audio\":\n case \"video\":\n case \"document\": {\n const mimeType = content.mime_type || `${content.type}/unknown`;\n if (content.data) {\n return {\n inlineData: {\n mimeType,\n data: content.data,\n },\n ...sigSpread,\n };\n }\n if (content.uri) {\n return {\n fileData: {\n mimeType,\n fileUri: content.uri,\n },\n ...sigSpread,\n };\n }\n return undefined;\n }\n default:\n return undefined;\n }\n}\n\n/**\n * Converts an array of LangChain `BaseMessage`s into an array of Interactions API `Step`s.\n *\n * ### ThoughtStep & `thoughtSignature` Round-Trip Design\n *\n * In the Interactions API, model reasoning and cryptographic thought signatures are\n * represented as standalone `{ type: \"thought\", signature, summary? }` steps in the\n * step sequence, rather than inline `{ thought: true, thoughtSignature }` fields on\n * text or tool-call parts.\n *\n * When converting an `AIMessage` back into Interactions `Step`s for multi-turn history:\n * 1. If the `AIMessage` contains reasoning blocks (`v1` `{ type: \"reasoning\", reasoning }`\n * or `v0` `{ type: \"text\", thought: true, text, thoughtSignature }`), each reasoning\n * block is emitted as a `{ type: \"thought\", signature, summary: [{ type: \"text\", text }] }` step.\n * 2. In the Interactions API, Gemini 2.5 / 3 models also emit signature-only `ThoughtStep`s\n * (`{ type: \"thought\", signature }` with no `summary`) before `ModelOutputStep` or\n * `FunctionCallStep` when `thinking_summaries` is not enabled. On inbound conversion\n * (`convertInteractionToAIMessage`), we stash those signatures on:\n * - `aiMessage.additional_kwargs.originalTextContentBlock.thoughtSignature` (or non-thought\n * text content blocks), and\n * - `aiMessage.tool_calls[i].thoughtSignature`.\n * When converting that `AIMessage` back to `Step`s here, if a `thoughtSignature` is present\n * on the text block or tool call and has NOT already been emitted by a preceding `ThoughtStep`,\n * we emit `{ type: \"thought\", signature }` immediately before the corresponding\n * `{ type: \"model_output\" }` or `{ type: \"function_call\" }` step.\n */\nexport function convertMessagesToInteractionsInput(\n messages: BaseMessage[],\n defaultMediaResolution?: Gemini.Interactions.MediaResolution\n): Gemini.Interactions.Step[] {\n const steps: Gemini.Interactions.Step[] = [];\n let isLeadingSystemMessages = true;\n\n for (let i = 0; i < messages.length; i++) {\n const message = messages[i];\n\n // Leading SystemMessages are handled via `system_instruction`\n if (isLeadingSystemMessages && SystemMessage.isInstance(message)) {\n continue;\n }\n isLeadingSystemMessages = false;\n\n if (AIMessage.isInstance(message)) {\n const parts = convertSingleMessageToGeminiParts(message);\n const modelOutputContents: Gemini.Interactions.Content[] = [];\n const emittedSignatures = new Set<string>();\n let pendingOutputSignature: string | undefined;\n\n const flushModelOutput = () => {\n if (modelOutputContents.length > 0) {\n if (\n pendingOutputSignature &&\n !emittedSignatures.has(pendingOutputSignature)\n ) {\n const lastStep = steps[steps.length - 1];\n if (lastStep?.type === \"thought\" && !lastStep.signature) {\n lastStep.signature = pendingOutputSignature;\n } else {\n steps.push({\n type: \"thought\",\n signature: pendingOutputSignature,\n });\n }\n emittedSignatures.add(pendingOutputSignature);\n }\n steps.push({\n type: \"model_output\",\n content: [...modelOutputContents],\n });\n modelOutputContents.length = 0;\n pendingOutputSignature = undefined;\n }\n };\n\n let callIndex = 0;\n for (const part of parts) {\n if (part.thought) {\n flushModelOutput();\n const summaryContent: Gemini.Interactions.Content[] = [];\n if (typeof part.text === \"string\" && part.text.length > 0) {\n summaryContent.push({\n type: \"text\",\n text: part.text,\n });\n }\n if (part.thoughtSignature) {\n emittedSignatures.add(part.thoughtSignature);\n }\n steps.push({\n type: \"thought\",\n ...(part.thoughtSignature\n ? { signature: part.thoughtSignature }\n : {}),\n ...(summaryContent.length > 0 ? { summary: summaryContent } : {}),\n });\n } else if (part.executableCode) {\n flushModelOutput();\n steps.push({\n type: \"code_execution_call\",\n id: `code_exec_${callIndex++}`,\n arguments: {\n code: part.executableCode.code,\n language: \"python\",\n },\n ...(part.thoughtSignature\n ? { signature: part.thoughtSignature }\n : {}),\n });\n } else if (part.codeExecutionResult) {\n flushModelOutput();\n steps.push({\n type: \"code_execution_result\",\n call_id: `code_exec_${Math.max(0, callIndex - 1)}`,\n result: part.codeExecutionResult.output ?? \"\",\n is_error:\n part.codeExecutionResult.outcome !== \"OUTCOME_OK\" &&\n part.codeExecutionResult.outcome !== \"OUTCOME_UNSPECIFIED\" &&\n Boolean(part.codeExecutionResult.outcome),\n ...(part.thoughtSignature\n ? { signature: part.thoughtSignature }\n : {}),\n });\n } else if (part.functionCall) {\n flushModelOutput();\n // Note: convertSingleMessageToGeminiParts strips `id` when it starts with \"lc-tool-call-\",\n // so we look up the original tool_call id from `message.tool_calls` as fallback\n // because `id` is required on FunctionCallStep in the Interactions API.\n const originalToolCall = message.tool_calls?.[callIndex];\n const id =\n part.functionCall.id || originalToolCall?.id || `call_${callIndex}`;\n const sig =\n part.thoughtSignature ||\n (originalToolCall as { thoughtSignature?: string } | undefined)\n ?.thoughtSignature;\n\n if (sig && !emittedSignatures.has(sig)) {\n const lastStep = steps[steps.length - 1];\n if (lastStep?.type === \"thought\" && !lastStep.signature) {\n lastStep.signature = sig;\n } else {\n steps.push({\n type: \"thought\",\n signature: sig,\n });\n }\n emittedSignatures.add(sig);\n }\n\n steps.push({\n type: \"function_call\",\n id,\n name: part.functionCall.name,\n arguments: part.functionCall.args ?? {},\n });\n callIndex++;\n } else {\n if (part.thoughtSignature && !pendingOutputSignature) {\n pendingOutputSignature = part.thoughtSignature;\n }\n const converted = convertGeminiPartToInteractionsContent(\n part,\n defaultMediaResolution\n );\n if (converted) {\n modelOutputContents.push(converted);\n }\n }\n }\n\n flushModelOutput();\n // If a signature-only part existed with no text or tool calls, still preserve the ThoughtStep\n if (\n pendingOutputSignature &&\n !emittedSignatures.has(pendingOutputSignature)\n ) {\n steps.push({\n type: \"thought\",\n signature: pendingOutputSignature,\n });\n emittedSignatures.add(pendingOutputSignature);\n }\n } else if (ToolMessage.isInstance(message)) {\n const callId =\n message.tool_call_id ||\n (message.additional_kwargs?.tool_call_id as string | undefined) ||\n \"unknown\";\n const name =\n message.name ||\n (message.additional_kwargs?.name as string | undefined) ||\n messages\n .filter(AIMessage.isInstance)\n .flatMap((m) => m.tool_calls ?? [])\n .find((tc) => tc.id === callId)?.name;\n const isError = message.status === \"error\" ? true : undefined;\n\n let result: Gemini.Interactions.FunctionResultStep[\"result\"];\n if (typeof message.content === \"string\") {\n // Attempt to parse JSON object results if valid, otherwise pass string directly\n try {\n const parsed = JSON.parse(message.content);\n if (\n typeof parsed === \"object\" &&\n parsed !== null &&\n !Array.isArray(parsed)\n ) {\n result = parsed as Record<string, unknown>;\n } else {\n result = message.content;\n }\n } catch {\n result = message.content;\n }\n } else if (Array.isArray(message.content)) {\n // A ToolMessage's `content` can be an array in two distinct cases:\n // 1. Multimodal content blocks (e.g. `[{ type: \"text\", ... }, { type: \"image_url\", ... }]`),\n // where `convertSingleMessageToGeminiParts` produces both a `functionResponse` part\n // (containing the non-media items under `response.result`) and sibling media parts\n // (`inlineData` / `fileData`).\n // 2. Arbitrary JSON array data returned by a tool (e.g. `[{ url: \"...\", error: \"...\" }]`),\n // where `convertSingleMessageToGeminiParts` produces only a `functionResponse` part\n // with `response: { result: message.content }` and no media parts.\n const parts = convertSingleMessageToGeminiParts(message, messages);\n const hasMediaParts = parts.some((p) => !(\"functionResponse\" in p));\n if (hasMediaParts) {\n // Case 1 (multimodal tool output): Interactions `FunctionResultStep.result` must be an\n // array of Content blocks (`TextContent` / `ImageContent`) so the image/media is sent\n // as a sibling block rather than lost or base64-stringified inside JSON (#10297).\n const contents: Gemini.Interactions.Content[] = [];\n for (const part of parts) {\n if (part.functionResponse?.response) {\n // Unwrap text items from `functionResponse.response.result` into `TextContent` blocks\n const resp = part.functionResponse.response;\n if (\n typeof resp === \"object\" &&\n resp !== null &&\n \"result\" in resp &&\n Object.keys(resp).length === 1\n ) {\n if (typeof resp.result === \"string\") {\n contents.push({ type: \"text\", text: resp.result });\n } else if (Array.isArray(resp.result)) {\n for (const item of resp.result) {\n if (typeof item === \"string\") {\n contents.push({ type: \"text\", text: item });\n } else if (\n typeof item === \"object\" &&\n item !== null &&\n \"text\" in item &&\n typeof (item as { text?: unknown }).text === \"string\"\n ) {\n contents.push({\n type: \"text\",\n text: (item as { text: string }).text,\n });\n } else {\n contents.push({\n type: \"text\",\n text: JSON.stringify(item),\n });\n }\n }\n } else {\n contents.push({\n type: \"text\",\n text: JSON.stringify(resp.result),\n });\n }\n } else {\n contents.push({\n type: \"text\",\n text: JSON.stringify(resp),\n });\n }\n } else {\n // Convert sibling media parts (`inlineData` / `fileData`) into Interactions Content blocks\n const converted = convertGeminiPartToInteractionsContent(\n part,\n defaultMediaResolution\n );\n if (converted) {\n contents.push(converted);\n }\n }\n }\n result = contents.length > 0 ? contents : \"\";\n } else {\n // Case 2 (no media blocks, e.g. a JSON array tool result): preserve the structured\n // `{ result: ... }` JSON object from `functionResponse.response` directly on\n // `FunctionResultStep.result` without double-stringifying (#10439).\n const functionResponsePart = parts.find(\n (p): p is Gemini.Part.FunctionResponse =>\n \"functionResponse\" in p && Boolean(p.functionResponse?.response)\n );\n result = (functionResponsePart?.functionResponse?.response as\n | Record<string, unknown>\n | undefined) ?? {\n result: message.content,\n };\n }\n } else if (\n typeof message.content === \"object\" &&\n message.content !== null\n ) {\n // Non-array object content: wrap as `{ result: ... }` to satisfy `Record<string, unknown>`\n result = { result: message.content };\n } else {\n result = String(message.content ?? \"\");\n }\n\n steps.push({\n type: \"function_result\",\n call_id: callId,\n ...(name ? { name } : {}),\n ...(typeof isError === \"boolean\" ? { is_error: isError } : {}),\n result,\n });\n } else {\n // HumanMessage, mid-conversation SystemMessage, or generic BaseMessage -> UserInputStep\n const parts = convertSingleMessageToGeminiParts(message);\n const contents: Gemini.Interactions.Content[] = [];\n for (const part of parts) {\n const converted = convertGeminiPartToInteractionsContent(\n part,\n defaultMediaResolution\n );\n if (converted) {\n contents.push(converted);\n }\n }\n if (contents.length > 0) {\n steps.push({\n type: \"user_input\",\n content: contents,\n });\n }\n }\n }\n\n return steps;\n}\n\n/**\n * Converts Interactions API `ModalityTokens[]` into a modality record (`text`, `image`, `audio`, etc.)\n * compatible with LangChain's `InputTokenDetails` / `OutputTokenDetails`.\n */\nfunction convertInteractionsModalityTokensToRecord(\n modalityTokens?: Gemini.Interactions.ModalityTokens[]\n): Record<string, number> {\n const ret: Record<string, number> = {};\n for (const item of modalityTokens ?? []) {\n if (item.modality && typeof item.tokens === \"number\") {\n const key = item.modality.toLowerCase();\n ret[key] = (ret[key] ?? 0) + item.tokens;\n }\n }\n return ret;\n}\n\n/**\n * Converts an Interactions API `Usage` object into LangChain's `UsageMetadata`.\n */\nexport function convertInteractionsUsageToUsageMetadata(\n usage?: Gemini.Interactions.Usage\n): UsageMetadata | undefined {\n if (!usage) {\n return undefined;\n }\n\n const inputMods = convertInteractionsModalityTokensToRecord(\n usage.input_tokens_by_modality\n );\n const outputMods = convertInteractionsModalityTokensToRecord(\n usage.output_tokens_by_modality\n );\n\n const cacheRead = usage.total_cached_tokens;\n const toolUse = usage.total_tool_use_tokens;\n const inputTokenDetails: InputTokenDetails = {\n ...(typeof cacheRead === \"number\" ? { cache_read: cacheRead } : {}),\n ...(typeof toolUse === \"number\" ? { tool_use: toolUse } : {}),\n ...inputMods,\n };\n\n const reasoning = usage.total_thought_tokens;\n const outputTokenDetails: OutputTokenDetails = {\n ...(typeof reasoning === \"number\" ? { reasoning } : {}),\n ...outputMods,\n };\n\n const rawInput = usage.total_input_tokens ?? 0;\n const rawOutput = usage.total_output_tokens ?? 0;\n const rawThought = usage.total_thought_tokens ?? 0;\n const rawToolUse = usage.total_tool_use_tokens ?? 0;\n\n // Include tool_use tokens in input_tokens if not already counted in total_input_tokens\n const inputTokens =\n typeof usage.total_tokens === \"number\" &&\n rawInput + rawToolUse + rawOutput + rawThought === usage.total_tokens\n ? rawInput + rawToolUse\n : rawInput;\n\n // LangChain's `output_tokens` convention includes reasoning tokens (`total_thought_tokens`).\n // Check whether `total_output_tokens` already includes `total_thought_tokens` by comparing with `total_tokens`.\n const outputTokens =\n typeof usage.total_tokens === \"number\" &&\n rawInput + rawOutput === usage.total_tokens &&\n rawThought > 0\n ? rawOutput\n : rawOutput + rawThought;\n\n const totalTokens = usage.total_tokens ?? inputTokens + outputTokens;\n\n return {\n input_tokens: inputTokens,\n output_tokens: outputTokens,\n total_tokens: totalTokens,\n ...(Object.keys(inputTokenDetails).length > 0\n ? { input_token_details: inputTokenDetails }\n : {}),\n ...(Object.keys(outputTokenDetails).length > 0\n ? { output_token_details: outputTokenDetails }\n : {}),\n };\n}\n\n/**\n * Normalizes an item from `interaction.steps` or legacy `interaction.outputs`\n * into a `Gemini.Interactions.Step`.\n */\nexport function normalizeInteractionStep(\n item: Gemini.Interactions.Step | Gemini.Interactions.Content\n): Gemini.Interactions.Step {\n if (\n item.type === \"text\" ||\n item.type === \"image\" ||\n item.type === \"audio\" ||\n item.type === \"document\" ||\n item.type === \"video\"\n ) {\n return {\n type: \"model_output\",\n content: [item],\n };\n }\n return item;\n}\n\n/**\n * Synthesizes GenerateContent-compatible `groundingMetadata`, `citationMetadata`,\n * `groundingSupport`, and `urlContextMetadata` from Interactions API annotations\n * and built-in tool steps (`google_search_*`, `google_maps_*`, `file_search_*`, `url_context_*`).\n */\nexport function synthesizeMetadataFromInteractions(options: {\n textSegments: Array<{\n text: string;\n annotations?: Gemini.Interactions.Annotation[];\n }>;\n builtInToolSteps: Gemini.Interactions.Step[];\n}): {\n groundingMetadata?: Gemini.GroundingMetadata;\n grounding_metadata?: Gemini.GroundingMetadata;\n groundingSupport?: Gemini.GroundingSupport[];\n citationMetadata?: Gemini.CitationMetadata;\n citation_metadata?: Gemini.CitationMetadata;\n urlContextMetadata?: Gemini.GenContent.Candidate[\"urlContextMetadata\"];\n url_context_metadata?: Gemini.GenContent.Candidate[\"urlContextMetadata\"];\n} {\n const { textSegments, builtInToolSteps } = options;\n\n const webSearchQueries: string[] = [];\n const groundingChunks: NonNullable<\n Gemini.GroundingMetadata[\"groundingChunks\"]\n > = [];\n const groundingSupports: Gemini.GroundingSupport[] = [];\n const citationSources: NonNullable<\n Gemini.CitationMetadata[\"citationSources\"]\n > = [];\n const urlMetadataList: Array<{\n retrievedUrl?: string;\n urlRetrievalStatus?:\n | \"URL_RETRIEVAL_STATUS_UNSPECIFIED\"\n | \"URL_RETRIEVAL_STATUS_SUCCESS\"\n | \"URL_RETRIEVAL_STATUS_ERROR\"\n | \"URL_RETRIEVAL_STATUS_PAYWALL\"\n | \"URL_RETRIEVAL_STATUS_UNSAFE\";\n }> = [];\n let searchEntryPointRenderedContent: string | undefined;\n\n // Map URL/Place/Title to chunk index so citations can reference groundingChunks\n const urlToChunkIndex = new Map<string, number>();\n\n for (const step of builtInToolSteps) {\n if (step.type === \"google_search_call\") {\n for (const q of step.arguments?.queries ?? []) {\n if (q && !webSearchQueries.includes(q)) {\n webSearchQueries.push(q);\n }\n }\n } else if (step.type === \"google_search_result\") {\n for (const item of step.result ?? []) {\n const rawItem = item as Gemini.Interactions.GoogleSearchResultItem & {\n url?: string;\n title?: string;\n rendered_content?: string;\n };\n if (rawItem.rendered_content && !searchEntryPointRenderedContent) {\n searchEntryPointRenderedContent = rawItem.rendered_content;\n }\n if (rawItem.url || rawItem.title) {\n const chunkIndex = groundingChunks.length;\n groundingChunks.push({\n web: {\n ...(rawItem.url ? { uri: rawItem.url } : {}),\n ...(rawItem.title ? { title: rawItem.title } : {}),\n },\n });\n if (rawItem.url && !urlToChunkIndex.has(rawItem.url)) {\n urlToChunkIndex.set(rawItem.url, chunkIndex);\n }\n }\n }\n } else if (step.type === \"google_maps_call\") {\n for (const q of step.arguments?.queries ?? []) {\n if (q && !webSearchQueries.includes(q)) {\n webSearchQueries.push(q);\n }\n }\n } else if (step.type === \"google_maps_result\") {\n for (const item of step.result ?? []) {\n for (const place of item.places ?? []) {\n const chunkIndex = groundingChunks.length;\n groundingChunks.push({\n maps: {\n ...(place.url ? { uri: place.url } : {}),\n ...(place.name ? { title: place.name } : {}),\n ...(place.place_id ? { placeId: place.place_id } : {}),\n },\n });\n if (place.url && !urlToChunkIndex.has(place.url)) {\n urlToChunkIndex.set(place.url, chunkIndex);\n }\n }\n }\n } else if (step.type === \"file_search_result\") {\n for (const item of step.result ?? []) {\n groundingChunks.push({\n retrievedContext: {\n ...(item.title ? { title: item.title } : {}),\n ...(item.text ? { text: item.text } : {}),\n ...(item.file_search_store\n ? { fileSearchStore: item.file_search_store }\n : {}),\n },\n });\n }\n } else if (step.type === \"url_context_result\") {\n for (const item of step.result ?? []) {\n let status:\n | \"URL_RETRIEVAL_STATUS_UNSPECIFIED\"\n | \"URL_RETRIEVAL_STATUS_SUCCESS\"\n | \"URL_RETRIEVAL_STATUS_ERROR\"\n | \"URL_RETRIEVAL_STATUS_PAYWALL\"\n | \"URL_RETRIEVAL_STATUS_UNSAFE\" = \"URL_RETRIEVAL_STATUS_UNSPECIFIED\";\n switch (item.status) {\n case \"success\":\n status = \"URL_RETRIEVAL_STATUS_SUCCESS\";\n break;\n case \"error\":\n status = \"URL_RETRIEVAL_STATUS_ERROR\";\n break;\n case \"paywall\":\n status = \"URL_RETRIEVAL_STATUS_PAYWALL\";\n break;\n case \"unsafe\":\n status = \"URL_RETRIEVAL_STATUS_UNSAFE\";\n break;\n default:\n status = \"URL_RETRIEVAL_STATUS_UNSPECIFIED\";\n }\n urlMetadataList.push({\n ...(item.url ? { retrievedUrl: item.url } : {}),\n urlRetrievalStatus: status,\n });\n if (item.url && !urlToChunkIndex.has(item.url)) {\n const chunkIndex = groundingChunks.length;\n groundingChunks.push({\n web: {\n uri: item.url,\n },\n });\n urlToChunkIndex.set(item.url, chunkIndex);\n }\n }\n }\n }\n\n for (let partIndex = 0; partIndex < textSegments.length; partIndex++) {\n const seg = textSegments[partIndex];\n for (const annotation of seg.annotations ?? []) {\n if (annotation.type === \"url_citation\") {\n citationSources.push({\n ...(typeof annotation.start_index === \"number\"\n ? { startIndex: annotation.start_index }\n : {}),\n ...(typeof annotation.end_index === \"number\"\n ? { endIndex: annotation.end_index }\n : {}),\n ...(annotation.url ? { uri: annotation.url } : {}),\n });\n\n let chunkIdx = annotation.url\n ? urlToChunkIndex.get(annotation.url)\n : undefined;\n if (chunkIdx === undefined && (annotation.url || annotation.title)) {\n chunkIdx = groundingChunks.length;\n groundingChunks.push({\n web: {\n ...(annotation.url ? { uri: annotation.url } : {}),\n ...(annotation.title ? { title: annotation.title } : {}),\n },\n });\n if (annotation.url) {\n urlToChunkIndex.set(annotation.url, chunkIdx);\n }\n }\n\n groundingSupports.push({\n segment: {\n partIndex,\n ...(typeof annotation.start_index === \"number\"\n ? { startIndex: annotation.start_index }\n : {}),\n ...(typeof annotation.end_index === \"number\"\n ? { endIndex: annotation.end_index }\n : {}),\n },\n ...(chunkIdx !== undefined\n ? { groundingChunkIndices: [chunkIdx] }\n : {}),\n });\n } else if (annotation.type === \"place_citation\") {\n citationSources.push({\n ...(typeof annotation.start_index === \"number\"\n ? { startIndex: annotation.start_index }\n : {}),\n ...(typeof annotation.end_index === \"number\"\n ? { endIndex: annotation.end_index }\n : {}),\n ...(annotation.url ? { uri: annotation.url } : {}),\n });\n\n let chunkIdx = annotation.url\n ? urlToChunkIndex.get(annotation.url)\n : undefined;\n if (\n chunkIdx === undefined &&\n (annotation.url || annotation.name || annotation.place_id)\n ) {\n chunkIdx = groundingChunks.length;\n groundingChunks.push({\n maps: {\n ...(annotation.url ? { uri: annotation.url } : {}),\n ...(annotation.name ? { title: annotation.name } : {}),\n ...(annotation.place_id ? { placeId: annotation.place_id } : {}),\n },\n });\n if (annotation.url) {\n urlToChunkIndex.set(annotation.url, chunkIdx);\n }\n }\n\n groundingSupports.push({\n segment: {\n partIndex,\n ...(typeof annotation.start_index === \"number\"\n ? { startIndex: annotation.start_index }\n : {}),\n ...(typeof annotation.end_index === \"number\"\n ? { endIndex: annotation.end_index }\n : {}),\n },\n ...(chunkIdx !== undefined\n ? { groundingChunkIndices: [chunkIdx] }\n : {}),\n });\n } else if (annotation.type === \"file_citation\") {\n citationSources.push({\n ...(typeof annotation.start_index === \"number\"\n ? { startIndex: annotation.start_index }\n : {}),\n ...(typeof annotation.end_index === \"number\"\n ? { endIndex: annotation.end_index }\n : {}),\n ...(annotation.document_uri ? { uri: annotation.document_uri } : {}),\n });\n }\n }\n }\n\n const hasGrounding =\n webSearchQueries.length > 0 ||\n groundingChunks.length > 0 ||\n groundingSupports.length > 0 ||\n Boolean(searchEntryPointRenderedContent);\n\n const groundingMetadata: Gemini.GroundingMetadata | undefined = hasGrounding\n ? {\n ...(webSearchQueries.length > 0 ? { webSearchQueries } : {}),\n ...(groundingChunks.length > 0 ? { groundingChunks } : {}),\n ...(groundingSupports.length > 0 ? { groundingSupports } : {}),\n ...(searchEntryPointRenderedContent\n ? {\n searchEntryPoint: {\n renderedContent: searchEntryPointRenderedContent,\n },\n }\n : {}),\n }\n : undefined;\n\n const groundingSupport = groundingMetadata?.groundingSupports?.filter(\n (s) => (s?.segment?.partIndex ?? 0) === 0\n );\n\n const citationMetadata: Gemini.CitationMetadata | undefined =\n citationSources.length > 0 ? { citationSources } : undefined;\n\n const urlContextMetadata:\n | Gemini.GenContent.Candidate[\"urlContextMetadata\"]\n | undefined =\n urlMetadataList.length > 0 ? { urlMetadata: urlMetadataList } : undefined;\n\n return {\n ...(groundingMetadata\n ? {\n groundingMetadata,\n grounding_metadata: groundingMetadata,\n groundingSupport: groundingSupport ?? [],\n }\n : {}),\n ...(citationMetadata\n ? {\n citationMetadata,\n citation_metadata: citationMetadata,\n }\n : {}),\n ...(urlContextMetadata\n ? {\n urlContextMetadata,\n url_context_metadata: urlContextMetadata,\n }\n : {}),\n };\n}\n\n/**\n * Converts an Interactions API `Interaction` response into a LangChain `AIMessage`\n * along with `finishReason` and `usageMetadata`.\n *\n * ### ThoughtStep & `thoughtSignature` Inbound Mapping\n *\n * In `convertGeminiCandidateToAIMessage` (GenerateContent):\n * - A `Gemini.Part` with `thought: true` is treated as content-bearing (`!!p.thought === true`),\n * which causes `AIMessage.content` to remain an array of content blocks (so the user can inspect\n * the reasoning block alongside the text block).\n * - A `Gemini.Part` with `{ text: \"Hello\", thoughtSignature: \"sig...\" }` (or a trailing\n * metadata-only `{ thoughtSignature: \"sig...\" }` part with `thought` undefined) is NOT a\n * reasoning block: if there is a single text part, `AIMessage.content` collapses to the plain\n * string `\"Hello\"` and `additional_kwargs.originalTextContentBlock` preserves\n * `{ type: \"text\", text: \"Hello\", thoughtSignature: \"sig...\" }`.\n * - A `Gemini.Part` with `{ functionCall: {...}, thoughtSignature: \"sig...\" }` attaches\n * `thoughtSignature` directly to `aiMessage.tool_calls[i].thoughtSignature`.\n *\n * In the Interactions API, the model emits `{ type: \"thought\", signature: \"sig...\", summary?: [...] }`:\n * - Even when `thinking_summaries` is NOT enabled (`summary` is undefined or empty), Gemini 2.5 / 3\n * still emits a `ThoughtStep` containing `signature` before a `ModelOutputStep` or `FunctionCallStep`.\n * - Therefore:\n * 1. If `step.summary` is non-empty, we emit `Gemini.Part`(s) with `thought: true` and\n * `thoughtSignature: step.signature`. This produces a reasoning block in `AIMessage.content`\n * and `AIMessage.contentBlocks`.\n * 2. If `step.summary` is empty/undefined (signature-only), we do NOT emit a `{ thought: true }`\n * part (which would prevent `AIMessage.content` from collapsing to a plain string!). Instead,\n * we hold `pendingThoughtSignature = step.signature` and attach `thoughtSignature` to the\n * next `FunctionCallStep` part or `ModelOutputStep` part (or as a metadata-only\n * `{ thoughtSignature }` part if no step follows).\n */\nexport function convertInteractionToAIMessage(\n interaction: Gemini.Interactions.Interaction\n): {\n message: AIMessage;\n finishReason?: string;\n usageMetadata?: UsageMetadata;\n} {\n const rawItems = interaction.steps ?? interaction.outputs ?? [];\n const steps = rawItems.map(normalizeInteractionStep);\n\n const geminiParts: Gemini.Part[] = [];\n const textSegments: Array<{\n text: string;\n annotations?: Gemini.Interactions.Annotation[];\n }> = [];\n const builtInToolSteps: Gemini.Interactions.Step[] = [];\n\n let pendingThoughtSignature: string | undefined;\n // In the Interactions API, FunctionCallStep never carries its own `signature` field —\n // its signature always lives on the preceding ThoughtStep (whether or not that\n // ThoughtStep also includes `summary` text blocks, e.g. when `reasoningEffort: \"high\"`\n // enables `thinking_summaries: \"auto\"`). We track `pendingFunctionCallSignature` so\n // that any `function_call` step following a `thought` step receives `thoughtSignature`\n // on its `Gemini.Part.FunctionCall` (and consequently on `AIMessage.tool_calls[i]`).\n let pendingFunctionCallSignature: string | undefined;\n\n for (const step of steps) {\n switch (step.type) {\n case \"thought\": {\n const summaries = step.summary ?? [];\n const textSummaries = summaries.filter(\n (c): c is Gemini.Interactions.TextContent =>\n c.type === \"text\" && typeof c.text === \"string\" && c.text.length > 0\n );\n\n if (textSummaries.length > 0) {\n for (let i = 0; i < textSummaries.length; i++) {\n const isLast = i === textSummaries.length - 1;\n geminiParts.push({\n text: textSummaries[i].text,\n thought: true,\n ...(isLast && step.signature\n ? { thoughtSignature: step.signature }\n : {}),\n });\n }\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = step.signature;\n } else if (step.signature) {\n pendingThoughtSignature = step.signature;\n pendingFunctionCallSignature = step.signature;\n }\n break;\n }\n\n case \"model_output\": {\n if (step.error?.message) {\n throw new GoogleError(\n `Google Interactions API model output error (${step.error.code ?? \"unknown\"}): ${step.error.message}`\n );\n }\n\n const contents: Gemini.Interactions.Content[] =\n typeof step.content === \"string\"\n ? [{ type: \"text\", text: step.content }]\n : (step.content ?? []);\n\n for (const contentItem of contents) {\n if (contentItem.type === \"text\") {\n textSegments.push({\n text: contentItem.text,\n annotations: contentItem.annotations,\n });\n }\n const part = convertInteractionsContentToGeminiPart(\n contentItem,\n pendingThoughtSignature\n );\n if (part) {\n geminiParts.push(part);\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n }\n }\n break;\n }\n\n case \"function_call\": {\n const fcSignature =\n pendingThoughtSignature ?? pendingFunctionCallSignature;\n geminiParts.push({\n functionCall: {\n id: step.id,\n name: step.name,\n args: step.arguments ?? {},\n },\n ...(fcSignature ? { thoughtSignature: fcSignature } : {}),\n });\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n break;\n }\n\n case \"code_execution_call\": {\n geminiParts.push({\n executableCode: {\n code: step.arguments?.code ?? \"\",\n language: \"PYTHON\",\n },\n ...(step.signature || pendingThoughtSignature\n ? { thoughtSignature: step.signature ?? pendingThoughtSignature }\n : {}),\n });\n pendingThoughtSignature = undefined;\n break;\n }\n\n case \"code_execution_result\": {\n geminiParts.push({\n codeExecutionResult: {\n output: step.result ?? \"\",\n outcome: step.is_error ? \"OUTCOME_FAILED\" : \"OUTCOME_OK\",\n },\n ...(step.signature || pendingThoughtSignature\n ? { thoughtSignature: step.signature ?? pendingThoughtSignature }\n : {}),\n });\n pendingThoughtSignature = undefined;\n break;\n }\n\n case \"google_search_call\":\n case \"google_search_result\":\n case \"google_maps_call\":\n case \"google_maps_result\":\n case \"file_search_call\":\n case \"file_search_result\":\n case \"url_context_call\":\n case \"url_context_result\":\n case \"mcp_server_tool_call\":\n case \"mcp_server_tool_result\":\n case \"processing_call\":\n case \"processing_result\":\n case \"retrieval_call\":\n case \"retrieval_result\": {\n builtInToolSteps.push(step);\n break;\n }\n\n default:\n break;\n }\n }\n\n // If a signature-only ThoughtStep remained at the end, push a metadata-only part\n // with `thoughtSignature` (and without `thought: true`), matching GenerateContent's\n // trailing `{ text: \"\", thoughtSignature }` behavior.\n if (pendingThoughtSignature) {\n geminiParts.push({\n thoughtSignature: pendingThoughtSignature,\n });\n }\n\n const blockContent: ContentBlock[] = geminiParts\n .map((part) => convertGeminiPartToContentBlock(part))\n .filter((block): block is ContentBlock => block !== null);\n\n let content: string | ContentBlock[] = blockContent;\n let originalTextContentBlock: ContentBlock | undefined;\n\n const hasContentPayload = (p: ContentBlock) =>\n p.type !== \"text\" ||\n (typeof p.text === \"string\" && p.text.length > 0) ||\n !!p.thought;\n const contentBearingParts = blockContent.filter(hasContentPayload);\n\n if (blockContent.length === 1 && blockContent[0].type === \"text\") {\n originalTextContentBlock = blockContent[0];\n content = blockContent[0].text as string;\n } else if (\n contentBearingParts.length === 1 &&\n contentBearingParts[0].type === \"text\" &&\n !contentBearingParts[0].thought\n ) {\n // Collapse when there is one text part and any other parts are metadata-only (e.g. thoughtSignature)\n const textPart = contentBearingParts[0];\n const sigSource = blockContent.find(\n (p) => p !== textPart && p.thoughtSignature\n );\n originalTextContentBlock = sigSource\n ? { ...textPart, thoughtSignature: sigSource.thoughtSignature }\n : textPart;\n content = textPart.text as string;\n } else if (blockContent.length === 0) {\n content = \"\";\n }\n\n const toolCalls = convertGeminiPartsToToolCalls(geminiParts);\n const usageMetadata = convertInteractionsUsageToUsageMetadata(\n interaction.usage\n );\n\n const synthesized = synthesizeMetadataFromInteractions({\n textSegments,\n builtInToolSteps,\n });\n\n let finishReason: string | undefined;\n if (interaction.status === \"completed\") {\n finishReason = \"STOP\";\n } else if (interaction.status === \"requires_action\") {\n finishReason = \"STOP\";\n } else if (interaction.status) {\n finishReason = interaction.status.toUpperCase();\n }\n\n const responseMetadata: Record<string, unknown> = {\n model_provider: \"google\",\n ...(interaction.model ? { model_name: interaction.model } : {}),\n ...(finishReason ? { finishReason } : {}),\n ...synthesized,\n ...(builtInToolSteps.length > 0\n ? { interactionSteps: builtInToolSteps }\n : {}),\n interaction: {\n ...(interaction.id ? { id: interaction.id } : {}),\n ...(interaction.status ? { status: interaction.status } : {}),\n ...(interaction.role ? { role: interaction.role } : {}),\n ...(interaction.previous_interaction_id\n ? { previous_interaction_id: interaction.previous_interaction_id }\n : {}),\n },\n };\n\n const additionalKwargs: Record<string, unknown> = {\n ...(finishReason ? { finishReason } : {}),\n ...(originalTextContentBlock ? { originalTextContentBlock } : {}),\n };\n\n const message = new AIMessage({\n content,\n tool_calls: toolCalls,\n additional_kwargs: additionalKwargs,\n usage_metadata: usageMetadata,\n response_metadata: responseMetadata,\n });\n\n return {\n message,\n finishReason,\n usageMetadata,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
const require_types = require("../../chat_models/types.cjs");
|
|
2
|
+
const require_params = require("../generate_content/params.cjs");
|
|
3
|
+
const require_params$1 = require("../shared/params.cjs");
|
|
4
|
+
let _langchain_core_utils_types = require("@langchain/core/utils/types");
|
|
5
|
+
let _langchain_core_utils_standard_schema = require("@langchain/core/utils/standard_schema");
|
|
6
|
+
let _langchain_core_utils_json_schema = require("@langchain/core/utils/json_schema");
|
|
7
|
+
// src/converters/interactions/params.ts
|
|
8
|
+
/**
|
|
9
|
+
* Merges constructor parameters and per-call options for the Interactions API,
|
|
10
|
+
* giving precedence to `b` over `a` for each field.
|
|
11
|
+
*/
|
|
12
|
+
function combineInteractionsFields(a, b, ...rest) {
|
|
13
|
+
const combined = {
|
|
14
|
+
temperature: b.temperature ?? a.temperature,
|
|
15
|
+
topP: b.topP ?? a.topP,
|
|
16
|
+
topK: b.topK ?? a.topK,
|
|
17
|
+
maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,
|
|
18
|
+
presencePenalty: b.presencePenalty ?? a.presencePenalty,
|
|
19
|
+
frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,
|
|
20
|
+
stopSequences: b.stopSequences ?? a.stopSequences,
|
|
21
|
+
seed: b.seed ?? a.seed,
|
|
22
|
+
safetySettings: b.safetySettings ?? a.safetySettings,
|
|
23
|
+
responseSchema: b.responseSchema ?? a.responseSchema,
|
|
24
|
+
responseMimeType: b.responseMimeType ?? a.responseMimeType,
|
|
25
|
+
tools: b.tools ?? a.tools,
|
|
26
|
+
responseModalities: b.responseModalities ?? a.responseModalities,
|
|
27
|
+
thinkingConfig: b.thinkingConfig ?? a.thinkingConfig,
|
|
28
|
+
speechConfig: b.speechConfig ?? a.speechConfig,
|
|
29
|
+
imageConfig: b.imageConfig ?? a.imageConfig,
|
|
30
|
+
mediaResolution: b.mediaResolution ?? a.mediaResolution,
|
|
31
|
+
detail: b.detail ?? a.detail,
|
|
32
|
+
maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,
|
|
33
|
+
thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,
|
|
34
|
+
reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,
|
|
35
|
+
thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,
|
|
36
|
+
serviceTier: b.serviceTier ?? a.serviceTier,
|
|
37
|
+
responseFormat: b.responseFormat ?? a.responseFormat,
|
|
38
|
+
previousInteractionId: b.previousInteractionId ?? a.previousInteractionId,
|
|
39
|
+
store: b.store ?? a.store,
|
|
40
|
+
background: b.background ?? a.background,
|
|
41
|
+
agent: b.agent ?? a.agent,
|
|
42
|
+
agentConfig: b.agentConfig ?? a.agentConfig,
|
|
43
|
+
webhookConfig: b.webhookConfig ?? a.webhookConfig
|
|
44
|
+
};
|
|
45
|
+
if (rest.length > 0) return combineInteractionsFields(combined, rest[0], ...rest.slice(1));
|
|
46
|
+
return combined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Converts reasoning/thinking fields (`reasoningEffort`, `thinkingLevel`,
|
|
50
|
+
* `maxReasoningTokens`, `thinkingBudget`, or `thinkingConfig`) into the
|
|
51
|
+
* Interactions API `thinking_level` and `thinking_summaries` fields on
|
|
52
|
+
* `generation_config`.
|
|
53
|
+
*/
|
|
54
|
+
function convertFieldsToInteractionsThinking(model, fields) {
|
|
55
|
+
const explicitThinkingConfig = fields.thinkingConfig;
|
|
56
|
+
const computedThinkingConfig = require_params.convertFieldsToThinkingConfig(model, fields);
|
|
57
|
+
const thinkingConfig = explicitThinkingConfig ?? computedThinkingConfig;
|
|
58
|
+
if (!thinkingConfig) return {};
|
|
59
|
+
let thinkingSummaries;
|
|
60
|
+
if (typeof thinkingConfig.includeThoughts === "boolean") thinkingSummaries = thinkingConfig.includeThoughts ? "auto" : "none";
|
|
61
|
+
let levelRaw = thinkingConfig.thinkingLevel ?? computedThinkingConfig?.thinkingLevel ?? fields.reasoningEffort ?? fields.thinkingLevel;
|
|
62
|
+
if (!levelRaw && typeof thinkingConfig.thinkingBudget === "number") levelRaw = require_params$1.convertReasoningTokensToReasoningEffort(model, thinkingConfig.thinkingBudget);
|
|
63
|
+
const normalizedLevel = levelRaw?.toLowerCase();
|
|
64
|
+
return {
|
|
65
|
+
...normalizedLevel ? { thinking_level: normalizedLevel } : {},
|
|
66
|
+
...thinkingSummaries ? { thinking_summaries: thinkingSummaries } : {}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Converts `speechConfig` (either simplified or GenerateContent `SpeechConfig`)
|
|
71
|
+
* into the Interactions API `Array<Gemini.Interactions.SpeechConfig>` format.
|
|
72
|
+
*/
|
|
73
|
+
function convertFieldsToInteractionsSpeechConfig(fields) {
|
|
74
|
+
if (typeof fields.speechConfig === "undefined") return;
|
|
75
|
+
if (Array.isArray(fields.speechConfig) && fields.speechConfig.every((item) => typeof item === "object" && item !== null && ("voice" in item || "language" in item || "speaker" in item))) return fields.speechConfig;
|
|
76
|
+
const genSpeechConfig = require_params.convertFieldsToSpeechConfig(fields);
|
|
77
|
+
if (!genSpeechConfig) return;
|
|
78
|
+
const language = genSpeechConfig.languageCode;
|
|
79
|
+
if (genSpeechConfig.multiSpeakerVoiceConfig?.speakerVoiceConfigs) return genSpeechConfig.multiSpeakerVoiceConfig.speakerVoiceConfigs.map((speakerConfig) => ({
|
|
80
|
+
...speakerConfig.speaker ? { speaker: speakerConfig.speaker } : {},
|
|
81
|
+
...speakerConfig.voiceConfig?.prebuiltVoiceConfig?.voiceName ? { voice: speakerConfig.voiceConfig.prebuiltVoiceConfig.voiceName } : {},
|
|
82
|
+
...language ? { language } : {}
|
|
83
|
+
}));
|
|
84
|
+
const voice = genSpeechConfig.voiceConfig?.prebuiltVoiceConfig?.voiceName;
|
|
85
|
+
if (voice || language) return [{
|
|
86
|
+
...voice ? { voice } : {},
|
|
87
|
+
...language ? { language } : {}
|
|
88
|
+
}];
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Converts a GenerateContent `ImageConfig` (camelCase) or Interactions `ImageResponseFormat`
|
|
92
|
+
* (snake_case) into an Interactions `ImageResponseFormat` (omitting `type`).
|
|
93
|
+
*/
|
|
94
|
+
function convertFieldsToInteractionsImageConfig(imageConfig) {
|
|
95
|
+
if (!imageConfig) return;
|
|
96
|
+
const raw = imageConfig;
|
|
97
|
+
const aspectRatio = raw.aspect_ratio ?? raw.aspectRatio;
|
|
98
|
+
const imageSize = raw.image_size ?? raw.imageSize;
|
|
99
|
+
const mimeType = raw.mime_type;
|
|
100
|
+
const delivery = raw.delivery;
|
|
101
|
+
if (!aspectRatio && !imageSize && !mimeType && !delivery) return;
|
|
102
|
+
return {
|
|
103
|
+
...aspectRatio ? { aspect_ratio: aspectRatio } : {},
|
|
104
|
+
...imageSize ? { image_size: imageSize } : {},
|
|
105
|
+
...mimeType ? { mime_type: mimeType } : {},
|
|
106
|
+
...delivery ? { delivery } : {}
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Maps `mediaResolution` (GenerateContent enum or lowercase) or `detail` ("low" | "high" | "auto")
|
|
111
|
+
* to the Interactions API `MediaResolution` ("low" | "medium" | "high" | "ultra_high").
|
|
112
|
+
*/
|
|
113
|
+
function convertMediaResolutionToInteractions(mediaResolution, detail) {
|
|
114
|
+
const resolved = mediaResolution ?? require_params.mapDetailToMediaResolution(detail);
|
|
115
|
+
if (!resolved) return;
|
|
116
|
+
const normalized = resolved.toLowerCase();
|
|
117
|
+
if (normalized === "media_resolution_low" || normalized === "low") return "low";
|
|
118
|
+
if (normalized === "media_resolution_medium" || normalized === "medium") return "medium";
|
|
119
|
+
if (normalized === "media_resolution_high" || normalized === "high") return "high";
|
|
120
|
+
if (normalized === "media_resolution_ultra_high" || normalized === "ultra_high") return "ultra_high";
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Maps GenerateContent `SafetySetting[]` (`HARM_CATEGORY_*`, `BLOCK_*`) into
|
|
124
|
+
* Interactions API `SafetySetting[]` (`{ type, threshold }` in lowercase snake_case).
|
|
125
|
+
*/
|
|
126
|
+
function convertSafetySettingsToInteractions(safetySettings) {
|
|
127
|
+
if (!safetySettings || safetySettings.length === 0) return;
|
|
128
|
+
const result = [];
|
|
129
|
+
for (const setting of safetySettings) {
|
|
130
|
+
const rawSetting = setting;
|
|
131
|
+
const rawCategory = (rawSetting.category ?? rawSetting.type ?? "").toLowerCase();
|
|
132
|
+
const type = rawCategory.startsWith("harm_category_") ? rawCategory.slice(14) : rawCategory;
|
|
133
|
+
const rawThreshold = (rawSetting.threshold ?? "").toLowerCase();
|
|
134
|
+
const threshold = rawThreshold === "harm_block_threshold_unspecified" || !rawThreshold ? void 0 : rawThreshold;
|
|
135
|
+
if (type && threshold && type !== "unspecified") result.push({
|
|
136
|
+
type,
|
|
137
|
+
threshold,
|
|
138
|
+
...rawSetting.method ? { method: rawSetting.method } : {}
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
return result.length > 0 ? result : void 0;
|
|
142
|
+
}
|
|
143
|
+
function convertImageFieldsToFormat(fields) {
|
|
144
|
+
return {
|
|
145
|
+
type: "image",
|
|
146
|
+
...convertFieldsToInteractionsImageConfig(fields.imageConfig) ?? {},
|
|
147
|
+
...fields.responseMimeType?.startsWith("image/") ? { mime_type: fields.responseMimeType } : {}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function convertAudioFieldsToFormat(fields) {
|
|
151
|
+
return {
|
|
152
|
+
type: "audio",
|
|
153
|
+
...fields.responseMimeType?.startsWith("audio/") ? { mime_type: fields.responseMimeType } : {}
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function convertVideoFieldsToFormat(fields) {
|
|
157
|
+
return {
|
|
158
|
+
type: "video",
|
|
159
|
+
...fields.responseMimeType?.startsWith("video/") ? { mime_type: fields.responseMimeType } : {}
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function fieldsToJsonSchema(fields) {
|
|
163
|
+
if (fields.responseSchema) {
|
|
164
|
+
if ((0, _langchain_core_utils_types.isInteropZodSchema)(fields.responseSchema) || (0, _langchain_core_utils_standard_schema.isSerializableSchema)(fields.responseSchema)) return (0, _langchain_core_utils_json_schema.toJsonSchema)(fields.responseSchema);
|
|
165
|
+
else return fields.responseSchema;
|
|
166
|
+
} else return;
|
|
167
|
+
}
|
|
168
|
+
function convertTextFieldsToFormat(fields) {
|
|
169
|
+
const jsonSchema = fieldsToJsonSchema(fields);
|
|
170
|
+
const textMimeType = fields.responseMimeType === "application/json" || fields.responseMimeType === "text/plain" || fields.responseMimeType?.startsWith("text/") ? fields.responseMimeType : jsonSchema ? "application/json" : void 0;
|
|
171
|
+
return {
|
|
172
|
+
type: "text",
|
|
173
|
+
...textMimeType ? { mime_type: textMimeType } : {},
|
|
174
|
+
...jsonSchema ? { schema: jsonSchema } : {}
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function convertModalityFieldsToFormat(modality, fields) {
|
|
178
|
+
switch (modality.toUpperCase()) {
|
|
179
|
+
case "IMAGE": return convertImageFieldsToFormat(fields);
|
|
180
|
+
case "AUDIO": return convertAudioFieldsToFormat(fields);
|
|
181
|
+
case "VIDEO": return convertVideoFieldsToFormat(fields);
|
|
182
|
+
case "TEXT": return convertTextFieldsToFormat(fields);
|
|
183
|
+
default: return;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Translates `responseFormat`, `responseSchema`, `responseModalities`, `responseMimeType`,
|
|
188
|
+
* and `imageConfig` into the Interactions API `response_format` field.
|
|
189
|
+
*
|
|
190
|
+
* In the Interactions API OpenAPI specification, top-level `response_mime_type`,
|
|
191
|
+
* top-level `response_modalities`, and `generation_config.image_config` are all
|
|
192
|
+
* marked `deprecated: true` (and Vertex AI / `gcp` rejects `response_mime_type`
|
|
193
|
+
* and `response_modalities` as unknown parameters). All of them are superseded by
|
|
194
|
+
* `response_format` (`ResponseFormat | Array<ResponseFormat>`):
|
|
195
|
+
* - Single or multiple `responseModalities` map to a single `ResponseFormat` object
|
|
196
|
+
* or an array of `ResponseFormat` objects (`{ type: "text" | "image" | "audio" | "video", ... }`),
|
|
197
|
+
* folding in `imageConfig`, `responseMimeType`, and `responseSchema` where applicable.
|
|
198
|
+
* - `responseSchema` without `responseModalities` is passed directly as a raw JSON
|
|
199
|
+
* Schema object in `response_format` (one of the variants in `ResponseFormat`'s `anyOf`
|
|
200
|
+
* in the OpenAPI spec; verified with `gai` and assumed to behave the same on `gcp`,
|
|
201
|
+
* though the spec also defines `{ type: "text", mime_type: "application/json", schema }`).
|
|
202
|
+
* - Standalone `responseMimeType` or `imageConfig` maps to the corresponding typed
|
|
203
|
+
* `ResponseFormat` object (`TextResponseFormat`, `ImageResponseFormat`, etc.).
|
|
204
|
+
*/
|
|
205
|
+
function convertFieldsToInteractionsResponseFormat(fields) {
|
|
206
|
+
if (fields.responseFormat) return fields.responseFormat;
|
|
207
|
+
if (fields.responseModalities && fields.responseModalities.length > 0) {
|
|
208
|
+
const formats = [];
|
|
209
|
+
for (const modality of fields.responseModalities) {
|
|
210
|
+
const format = convertModalityFieldsToFormat(modality, fields);
|
|
211
|
+
if (format) formats.push(format);
|
|
212
|
+
}
|
|
213
|
+
if (formats.length === 1) return formats[0];
|
|
214
|
+
if (formats.length > 1) return formats;
|
|
215
|
+
}
|
|
216
|
+
const jsonSchema = fieldsToJsonSchema(fields);
|
|
217
|
+
if (jsonSchema) return jsonSchema;
|
|
218
|
+
if (fields.responseMimeType) {
|
|
219
|
+
if (fields.responseMimeType.startsWith("image/")) return convertImageFieldsToFormat(fields);
|
|
220
|
+
if (fields.responseMimeType.startsWith("audio/")) return convertAudioFieldsToFormat(fields);
|
|
221
|
+
if (fields.responseMimeType.startsWith("video/")) return convertVideoFieldsToFormat(fields);
|
|
222
|
+
if (fields.responseMimeType === "application/json" || fields.responseMimeType === "text/plain" || fields.responseMimeType.startsWith("text/")) return convertTextFieldsToFormat(fields);
|
|
223
|
+
}
|
|
224
|
+
if (convertFieldsToInteractionsImageConfig(fields.imageConfig)) return convertImageFieldsToFormat(fields);
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Builds an object containing `service_tier` when supported by the target platform.
|
|
228
|
+
*/
|
|
229
|
+
function convertFieldsToInteractionsServiceTier(platform, fields) {
|
|
230
|
+
if (platform === "gcp") return {};
|
|
231
|
+
const serviceTier = fields.serviceTier;
|
|
232
|
+
if (!serviceTier || !require_types.settableServiceTier.includes(serviceTier)) return {};
|
|
233
|
+
return { service_tier: serviceTier };
|
|
234
|
+
}
|
|
235
|
+
exports.combineInteractionsFields = combineInteractionsFields;
|
|
236
|
+
exports.convertFieldsToInteractionsImageConfig = convertFieldsToInteractionsImageConfig;
|
|
237
|
+
exports.convertFieldsToInteractionsResponseFormat = convertFieldsToInteractionsResponseFormat;
|
|
238
|
+
exports.convertFieldsToInteractionsServiceTier = convertFieldsToInteractionsServiceTier;
|
|
239
|
+
exports.convertFieldsToInteractionsSpeechConfig = convertFieldsToInteractionsSpeechConfig;
|
|
240
|
+
exports.convertFieldsToInteractionsThinking = convertFieldsToInteractionsThinking;
|
|
241
|
+
exports.convertMediaResolutionToInteractions = convertMediaResolutionToInteractions;
|
|
242
|
+
exports.convertSafetySettingsToInteractions = convertSafetySettingsToInteractions;
|
|
243
|
+
|
|
244
|
+
//# sourceMappingURL=params.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"params.cjs","names":["convertFieldsToThinkingConfig","convertReasoningTokensToReasoningEffort","convertFieldsToSpeechConfig","mapDetailToMediaResolution","isInteropZodSchema","isSerializableSchema","toJsonSchema","settableServiceTier"],"sources":["../../../src/converters/interactions/params.ts"],"sourcesContent":["import { isInteropZodSchema } from \"@langchain/core/utils/types\";\nimport { isSerializableSchema } from \"@langchain/core/utils/standard_schema\";\nimport { toJsonSchema } from \"@langchain/core/utils/json_schema\";\nimport {\n type ChatGoogleFields,\n type GooglePlatformType,\n type InteractionsFields,\n settableServiceTier,\n type Gemini,\n} from \"../../chat_models/types.js\";\nimport {\n convertFieldsToSpeechConfig,\n convertFieldsToThinkingConfig,\n mapDetailToMediaResolution,\n} from \"../generate_content/params.js\";\nimport { convertReasoningTokensToReasoningEffort } from \"../shared/params.js\";\n\n/**\n * Merges constructor parameters and per-call options for the Interactions API,\n * giving precedence to `b` over `a` for each field.\n */\nexport function combineInteractionsFields(\n a: InteractionsFields,\n b: InteractionsFields,\n ...rest: InteractionsFields[]\n): InteractionsFields {\n const combined: InteractionsFields = {\n temperature: b.temperature ?? a.temperature,\n topP: b.topP ?? a.topP,\n topK: b.topK ?? a.topK,\n maxOutputTokens: b.maxOutputTokens ?? a.maxOutputTokens,\n presencePenalty: b.presencePenalty ?? a.presencePenalty,\n frequencyPenalty: b.frequencyPenalty ?? a.frequencyPenalty,\n stopSequences: b.stopSequences ?? a.stopSequences,\n seed: b.seed ?? a.seed,\n safetySettings: b.safetySettings ?? a.safetySettings,\n responseSchema: b.responseSchema ?? a.responseSchema,\n responseMimeType: b.responseMimeType ?? a.responseMimeType,\n tools: b.tools ?? a.tools,\n responseModalities: b.responseModalities ?? a.responseModalities,\n thinkingConfig: b.thinkingConfig ?? a.thinkingConfig,\n speechConfig: b.speechConfig ?? a.speechConfig,\n imageConfig: b.imageConfig ?? a.imageConfig,\n mediaResolution: b.mediaResolution ?? a.mediaResolution,\n detail: b.detail ?? a.detail,\n maxReasoningTokens: b.maxReasoningTokens ?? a.maxReasoningTokens,\n thinkingBudget: b.thinkingBudget ?? a.thinkingBudget,\n reasoningEffort: b.reasoningEffort ?? a.reasoningEffort,\n thinkingLevel: b.thinkingLevel ?? a.thinkingLevel,\n serviceTier: b.serviceTier ?? a.serviceTier,\n responseFormat: b.responseFormat ?? a.responseFormat,\n previousInteractionId: b.previousInteractionId ?? a.previousInteractionId,\n store: b.store ?? a.store,\n background: b.background ?? a.background,\n agent: b.agent ?? a.agent,\n agentConfig: b.agentConfig ?? a.agentConfig,\n webhookConfig: b.webhookConfig ?? a.webhookConfig,\n };\n if (rest.length > 0) {\n return combineInteractionsFields(combined, rest[0], ...rest.slice(1));\n }\n return combined;\n}\n\n/**\n * Converts reasoning/thinking fields (`reasoningEffort`, `thinkingLevel`,\n * `maxReasoningTokens`, `thinkingBudget`, or `thinkingConfig`) into the\n * Interactions API `thinking_level` and `thinking_summaries` fields on\n * `generation_config`.\n */\nexport function convertFieldsToInteractionsThinking(\n model: string,\n fields: ChatGoogleFields\n): {\n thinking_level?: Gemini.Interactions.ThinkingLevel;\n thinking_summaries?: \"auto\" | \"none\";\n} {\n const explicitThinkingConfig = fields.thinkingConfig;\n const computedThinkingConfig = convertFieldsToThinkingConfig(model, fields);\n const thinkingConfig = explicitThinkingConfig ?? computedThinkingConfig;\n\n if (!thinkingConfig) {\n return {};\n }\n\n let thinkingSummaries: \"auto\" | \"none\" | undefined;\n if (typeof thinkingConfig.includeThoughts === \"boolean\") {\n thinkingSummaries = thinkingConfig.includeThoughts ? \"auto\" : \"none\";\n }\n\n let levelRaw: string | undefined =\n thinkingConfig.thinkingLevel ??\n computedThinkingConfig?.thinkingLevel ??\n fields.reasoningEffort ??\n fields.thinkingLevel;\n\n if (!levelRaw && typeof thinkingConfig.thinkingBudget === \"number\") {\n levelRaw = convertReasoningTokensToReasoningEffort(\n model,\n thinkingConfig.thinkingBudget\n );\n }\n\n const normalizedLevel = levelRaw?.toLowerCase() as\n | Gemini.Interactions.ThinkingLevel\n | undefined;\n\n return {\n ...(normalizedLevel ? { thinking_level: normalizedLevel } : {}),\n ...(thinkingSummaries ? { thinking_summaries: thinkingSummaries } : {}),\n };\n}\n\n/**\n * Converts `speechConfig` (either simplified or GenerateContent `SpeechConfig`)\n * into the Interactions API `Array<Gemini.Interactions.SpeechConfig>` format.\n */\nexport function convertFieldsToInteractionsSpeechConfig(\n fields: ChatGoogleFields\n): Array<Gemini.Interactions.SpeechConfig> | undefined {\n if (typeof fields.speechConfig === \"undefined\") {\n return undefined;\n }\n\n // If already passed as an array of Interactions SpeechConfig objects, return as-is\n if (\n Array.isArray(fields.speechConfig) &&\n fields.speechConfig.every(\n (item) =>\n typeof item === \"object\" &&\n item !== null &&\n (\"voice\" in item || \"language\" in item || \"speaker\" in item)\n )\n ) {\n return fields.speechConfig as unknown as Array<Gemini.Interactions.SpeechConfig>;\n }\n\n const genSpeechConfig = convertFieldsToSpeechConfig(fields);\n if (!genSpeechConfig) {\n return undefined;\n }\n\n const language = genSpeechConfig.languageCode;\n\n if (genSpeechConfig.multiSpeakerVoiceConfig?.speakerVoiceConfigs) {\n return genSpeechConfig.multiSpeakerVoiceConfig.speakerVoiceConfigs.map(\n (speakerConfig): Gemini.Interactions.SpeechConfig => ({\n ...(speakerConfig.speaker ? { speaker: speakerConfig.speaker } : {}),\n ...(speakerConfig.voiceConfig?.prebuiltVoiceConfig?.voiceName\n ? { voice: speakerConfig.voiceConfig.prebuiltVoiceConfig.voiceName }\n : {}),\n ...(language ? { language } : {}),\n })\n );\n }\n\n const voice = genSpeechConfig.voiceConfig?.prebuiltVoiceConfig?.voiceName;\n if (voice || language) {\n return [\n {\n ...(voice ? { voice } : {}),\n ...(language ? { language } : {}),\n },\n ];\n }\n\n return undefined;\n}\n\n/**\n * Converts a GenerateContent `ImageConfig` (camelCase) or Interactions `ImageResponseFormat`\n * (snake_case) into an Interactions `ImageResponseFormat` (omitting `type`).\n */\nexport function convertFieldsToInteractionsImageConfig(\n imageConfig?:\n | Gemini.GenContent.ImageConfig\n | Partial<Gemini.Interactions.ImageResponseFormat>\n): Omit<Gemini.Interactions.ImageResponseFormat, \"type\"> | undefined {\n if (!imageConfig) {\n return undefined;\n }\n\n const raw = imageConfig as Gemini.GenContent.ImageConfig &\n Partial<Gemini.Interactions.ImageResponseFormat>;\n const aspectRatio = raw.aspect_ratio ?? raw.aspectRatio;\n const imageSize = raw.image_size ?? raw.imageSize;\n const mimeType = raw.mime_type;\n const delivery = raw.delivery;\n\n if (!aspectRatio && !imageSize && !mimeType && !delivery) {\n return undefined;\n }\n\n return {\n ...(aspectRatio\n ? {\n aspect_ratio:\n aspectRatio as Gemini.Interactions.ImageResponseFormat[\"aspect_ratio\"],\n }\n : {}),\n ...(imageSize\n ? {\n image_size:\n imageSize as Gemini.Interactions.ImageResponseFormat[\"image_size\"],\n }\n : {}),\n ...(mimeType ? { mime_type: mimeType } : {}),\n ...(delivery ? { delivery } : {}),\n };\n}\n\n/**\n * Maps `mediaResolution` (GenerateContent enum or lowercase) or `detail` (\"low\" | \"high\" | \"auto\")\n * to the Interactions API `MediaResolution` (\"low\" | \"medium\" | \"high\" | \"ultra_high\").\n */\nexport function convertMediaResolutionToInteractions(\n mediaResolution?:\n | Gemini.Shared.MediaResolution\n | Gemini.Interactions.MediaResolution,\n detail?: ChatGoogleFields[\"detail\"]\n): Gemini.Interactions.MediaResolution | undefined {\n const resolved = mediaResolution ?? mapDetailToMediaResolution(detail);\n if (!resolved) {\n return undefined;\n }\n\n const normalized = resolved.toLowerCase();\n if (normalized === \"media_resolution_low\" || normalized === \"low\") {\n return \"low\";\n }\n if (normalized === \"media_resolution_medium\" || normalized === \"medium\") {\n return \"medium\";\n }\n if (normalized === \"media_resolution_high\" || normalized === \"high\") {\n return \"high\";\n }\n if (\n normalized === \"media_resolution_ultra_high\" ||\n normalized === \"ultra_high\"\n ) {\n return \"ultra_high\";\n }\n return undefined;\n}\n\n/**\n * Maps GenerateContent `SafetySetting[]` (`HARM_CATEGORY_*`, `BLOCK_*`) into\n * Interactions API `SafetySetting[]` (`{ type, threshold }` in lowercase snake_case).\n */\nexport function convertSafetySettingsToInteractions(\n safetySettings?: Gemini.Shared.SafetySetting[]\n): Gemini.Interactions.SafetySetting[] | undefined {\n if (!safetySettings || safetySettings.length === 0) {\n return undefined;\n }\n\n const result: Gemini.Interactions.SafetySetting[] = [];\n for (const setting of safetySettings) {\n const rawSetting = setting as Gemini.Shared.SafetySetting &\n Partial<Gemini.Interactions.SafetySetting>;\n const rawCategory = (\n rawSetting.category ??\n rawSetting.type ??\n \"\"\n ).toLowerCase();\n const type = (\n rawCategory.startsWith(\"harm_category_\")\n ? rawCategory.slice(\"harm_category_\".length)\n : rawCategory\n ) as Gemini.Interactions.SafetySetting[\"type\"];\n\n const rawThreshold = (rawSetting.threshold ?? \"\").toLowerCase();\n const threshold = (\n rawThreshold === \"harm_block_threshold_unspecified\" || !rawThreshold\n ? undefined\n : rawThreshold\n ) as Gemini.Interactions.SafetySetting[\"threshold\"] | undefined;\n\n if (type && threshold && type !== (\"unspecified\" as string)) {\n result.push({\n type,\n threshold,\n ...(rawSetting.method ? { method: rawSetting.method } : {}),\n });\n }\n }\n\n return result.length > 0 ? result : undefined;\n}\n\nfunction convertImageFieldsToFormat(\n fields: ChatGoogleFields\n): Gemini.Interactions.ImageResponseFormat {\n const imageConfig = convertFieldsToInteractionsImageConfig(\n fields.imageConfig\n );\n return {\n type: \"image\",\n ...(imageConfig ?? {}),\n ...(fields.responseMimeType?.startsWith(\"image/\")\n ? {\n mime_type:\n fields.responseMimeType as Gemini.Interactions.ImageResponseFormat[\"mime_type\"],\n }\n : {}),\n };\n}\n\nfunction convertAudioFieldsToFormat(\n fields: ChatGoogleFields\n): Gemini.Interactions.AudioResponseFormat {\n return {\n type: \"audio\",\n ...(fields.responseMimeType?.startsWith(\"audio/\")\n ? {\n mime_type:\n fields.responseMimeType as Gemini.Interactions.AudioResponseFormat[\"mime_type\"],\n }\n : {}),\n };\n}\n\nfunction convertVideoFieldsToFormat(\n fields: ChatGoogleFields\n): Gemini.Interactions.VideoResponseFormat {\n return {\n type: \"video\",\n ...(fields.responseMimeType?.startsWith(\"video/\")\n ? {\n mime_type:\n fields.responseMimeType as Gemini.Interactions.VideoResponseFormat[\"mime_type\"],\n }\n : {}),\n };\n}\n\nfunction fieldsToJsonSchema(\n fields: ChatGoogleFields\n): Record<string, unknown> | undefined {\n if (fields.responseSchema) {\n if (\n isInteropZodSchema(fields.responseSchema) ||\n isSerializableSchema(fields.responseSchema)\n ) {\n return toJsonSchema(fields.responseSchema) as Record<string, unknown>;\n } else {\n return fields.responseSchema as Record<string, unknown>;\n }\n } else {\n return undefined;\n }\n}\n\nfunction convertTextFieldsToFormat(\n fields: ChatGoogleFields\n): Gemini.Interactions.TextResponseFormat {\n const jsonSchema = fieldsToJsonSchema(fields);\n const textMimeType =\n fields.responseMimeType === \"application/json\" ||\n fields.responseMimeType === \"text/plain\" ||\n fields.responseMimeType?.startsWith(\"text/\")\n ? (fields.responseMimeType as Gemini.Interactions.TextResponseFormat[\"mime_type\"])\n : jsonSchema\n ? \"application/json\"\n : undefined;\n return {\n type: \"text\",\n ...(textMimeType ? { mime_type: textMimeType } : {}),\n ...(jsonSchema ? { schema: jsonSchema } : {}),\n };\n}\n\nfunction convertModalityFieldsToFormat(\n modality: string,\n fields: ChatGoogleFields\n): Gemini.Interactions.ResponseFormat | undefined {\n const m = modality.toUpperCase();\n switch (m) {\n case \"IMAGE\":\n return convertImageFieldsToFormat(fields);\n case \"AUDIO\":\n return convertAudioFieldsToFormat(fields);\n case \"VIDEO\":\n return convertVideoFieldsToFormat(fields);\n case \"TEXT\":\n return convertTextFieldsToFormat(fields);\n default:\n return undefined;\n }\n}\n\n/**\n * Translates `responseFormat`, `responseSchema`, `responseModalities`, `responseMimeType`,\n * and `imageConfig` into the Interactions API `response_format` field.\n *\n * In the Interactions API OpenAPI specification, top-level `response_mime_type`,\n * top-level `response_modalities`, and `generation_config.image_config` are all\n * marked `deprecated: true` (and Vertex AI / `gcp` rejects `response_mime_type`\n * and `response_modalities` as unknown parameters). All of them are superseded by\n * `response_format` (`ResponseFormat | Array<ResponseFormat>`):\n * - Single or multiple `responseModalities` map to a single `ResponseFormat` object\n * or an array of `ResponseFormat` objects (`{ type: \"text\" | \"image\" | \"audio\" | \"video\", ... }`),\n * folding in `imageConfig`, `responseMimeType`, and `responseSchema` where applicable.\n * - `responseSchema` without `responseModalities` is passed directly as a raw JSON\n * Schema object in `response_format` (one of the variants in `ResponseFormat`'s `anyOf`\n * in the OpenAPI spec; verified with `gai` and assumed to behave the same on `gcp`,\n * though the spec also defines `{ type: \"text\", mime_type: \"application/json\", schema }`).\n * - Standalone `responseMimeType` or `imageConfig` maps to the corresponding typed\n * `ResponseFormat` object (`TextResponseFormat`, `ImageResponseFormat`, etc.).\n */\nexport function convertFieldsToInteractionsResponseFormat(\n fields: ChatGoogleFields\n): Gemini.Interactions.CreateInteractionParameters[\"response_format\"] {\n if (fields.responseFormat) {\n return fields.responseFormat;\n }\n\n if (fields.responseModalities && fields.responseModalities.length > 0) {\n const formats: Gemini.Interactions.ResponseFormat[] = [];\n for (const modality of fields.responseModalities) {\n const format = convertModalityFieldsToFormat(modality, fields);\n if (format) {\n formats.push(format);\n }\n }\n\n if (formats.length === 1) {\n return formats[0];\n }\n if (formats.length > 1) {\n return formats;\n }\n }\n\n const jsonSchema: Record<string, unknown> | undefined =\n fieldsToJsonSchema(fields);\n if (jsonSchema) {\n return jsonSchema;\n }\n\n if (fields.responseMimeType) {\n if (fields.responseMimeType.startsWith(\"image/\")) {\n return convertImageFieldsToFormat(fields);\n }\n if (fields.responseMimeType.startsWith(\"audio/\")) {\n return convertAudioFieldsToFormat(fields);\n }\n if (fields.responseMimeType.startsWith(\"video/\")) {\n return convertVideoFieldsToFormat(fields);\n }\n if (\n fields.responseMimeType === \"application/json\" ||\n fields.responseMimeType === \"text/plain\" ||\n fields.responseMimeType.startsWith(\"text/\")\n ) {\n return convertTextFieldsToFormat(fields);\n }\n }\n\n if (convertFieldsToInteractionsImageConfig(fields.imageConfig)) {\n return convertImageFieldsToFormat(fields);\n }\n\n return undefined;\n}\n\n/**\n * Builds an object containing `service_tier` when supported by the target platform.\n */\nexport function convertFieldsToInteractionsServiceTier(\n platform: GooglePlatformType,\n fields: ChatGoogleFields\n): {\n service_tier?: Gemini.Interactions.CreateInteractionParameters[\"service_tier\"];\n} {\n if (platform === \"gcp\") {\n return {};\n }\n\n const serviceTier = fields.serviceTier;\n if (!serviceTier || !settableServiceTier.includes(serviceTier)) {\n return {};\n }\n\n return {\n service_tier: serviceTier,\n };\n}\n"],"mappings":";;;;;;;;;;;AAqBA,SAAgB,0BACd,GACA,GACA,GAAG,MACiB;CACpB,MAAM,WAA+B;EACnC,aAAa,EAAE,eAAe,EAAE;EAChC,MAAM,EAAE,QAAQ,EAAE;EAClB,MAAM,EAAE,QAAQ,EAAE;EAClB,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,kBAAkB,EAAE,oBAAoB,EAAE;EAC1C,eAAe,EAAE,iBAAiB,EAAE;EACpC,MAAM,EAAE,QAAQ,EAAE;EAClB,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,kBAAkB,EAAE,oBAAoB,EAAE;EAC1C,OAAO,EAAE,SAAS,EAAE;EACpB,oBAAoB,EAAE,sBAAsB,EAAE;EAC9C,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,cAAc,EAAE,gBAAgB,EAAE;EAClC,aAAa,EAAE,eAAe,EAAE;EAChC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,QAAQ,EAAE,UAAU,EAAE;EACtB,oBAAoB,EAAE,sBAAsB,EAAE;EAC9C,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,iBAAiB,EAAE,mBAAmB,EAAE;EACxC,eAAe,EAAE,iBAAiB,EAAE;EACpC,aAAa,EAAE,eAAe,EAAE;EAChC,gBAAgB,EAAE,kBAAkB,EAAE;EACtC,uBAAuB,EAAE,yBAAyB,EAAE;EACpD,OAAO,EAAE,SAAS,EAAE;EACpB,YAAY,EAAE,cAAc,EAAE;EAC9B,OAAO,EAAE,SAAS,EAAE;EACpB,aAAa,EAAE,eAAe,EAAE;EAChC,eAAe,EAAE,iBAAiB,EAAE;CACtC;CACA,IAAI,KAAK,SAAS,GAChB,OAAO,0BAA0B,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,CAAC,CAAC;CAEtE,OAAO;AACT;;;;;;;AAQA,SAAgB,oCACd,OACA,QAIA;CACA,MAAM,yBAAyB,OAAO;CACtC,MAAM,yBAAyBA,eAAAA,8BAA8B,OAAO,MAAM;CAC1E,MAAM,iBAAiB,0BAA0B;CAEjD,IAAI,CAAC,gBACH,OAAO,CAAC;CAGV,IAAI;CACJ,IAAI,OAAO,eAAe,oBAAoB,WAC5C,oBAAoB,eAAe,kBAAkB,SAAS;CAGhE,IAAI,WACF,eAAe,iBACf,wBAAwB,iBACxB,OAAO,mBACP,OAAO;CAET,IAAI,CAAC,YAAY,OAAO,eAAe,mBAAmB,UACxD,WAAWC,iBAAAA,wCACT,OACA,eAAe,cACjB;CAGF,MAAM,kBAAkB,UAAU,YAAY;CAI9C,OAAO;EACL,GAAI,kBAAkB,EAAE,gBAAgB,gBAAgB,IAAI,CAAC;EAC7D,GAAI,oBAAoB,EAAE,oBAAoB,kBAAkB,IAAI,CAAC;CACvE;AACF;;;;;AAMA,SAAgB,wCACd,QACqD;CACrD,IAAI,OAAO,OAAO,iBAAiB,aACjC;CAIF,IACE,MAAM,QAAQ,OAAO,YAAY,KACjC,OAAO,aAAa,OACjB,SACC,OAAO,SAAS,YAChB,SAAS,SACR,WAAW,QAAQ,cAAc,QAAQ,aAAa,KAC3D,GAEA,OAAO,OAAO;CAGhB,MAAM,kBAAkBC,eAAAA,4BAA4B,MAAM;CAC1D,IAAI,CAAC,iBACH;CAGF,MAAM,WAAW,gBAAgB;CAEjC,IAAI,gBAAgB,yBAAyB,qBAC3C,OAAO,gBAAgB,wBAAwB,oBAAoB,KAChE,mBAAqD;EACpD,GAAI,cAAc,UAAU,EAAE,SAAS,cAAc,QAAQ,IAAI,CAAC;EAClE,GAAI,cAAc,aAAa,qBAAqB,YAChD,EAAE,OAAO,cAAc,YAAY,oBAAoB,UAAU,IACjE,CAAC;EACL,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;CACjC,EACF;CAGF,MAAM,QAAQ,gBAAgB,aAAa,qBAAqB;CAChE,IAAI,SAAS,UACX,OAAO,CACL;EACE,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;EACzB,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;CACjC,CACF;AAIJ;;;;;AAMA,SAAgB,uCACd,aAGmE;CACnE,IAAI,CAAC,aACH;CAGF,MAAM,MAAM;CAEZ,MAAM,cAAc,IAAI,gBAAgB,IAAI;CAC5C,MAAM,YAAY,IAAI,cAAc,IAAI;CACxC,MAAM,WAAW,IAAI;CACrB,MAAM,WAAW,IAAI;CAErB,IAAI,CAAC,eAAe,CAAC,aAAa,CAAC,YAAY,CAAC,UAC9C;CAGF,OAAO;EACL,GAAI,cACA,EACE,cACE,YACJ,IACA,CAAC;EACL,GAAI,YACA,EACE,YACE,UACJ,IACA,CAAC;EACL,GAAI,WAAW,EAAE,WAAW,SAAS,IAAI,CAAC;EAC1C,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;CACjC;AACF;;;;;AAMA,SAAgB,qCACd,iBAGA,QACiD;CACjD,MAAM,WAAW,mBAAmBC,eAAAA,2BAA2B,MAAM;CACrE,IAAI,CAAC,UACH;CAGF,MAAM,aAAa,SAAS,YAAY;CACxC,IAAI,eAAe,0BAA0B,eAAe,OAC1D,OAAO;CAET,IAAI,eAAe,6BAA6B,eAAe,UAC7D,OAAO;CAET,IAAI,eAAe,2BAA2B,eAAe,QAC3D,OAAO;CAET,IACE,eAAe,iCACf,eAAe,cAEf,OAAO;AAGX;;;;;AAMA,SAAgB,oCACd,gBACiD;CACjD,IAAI,CAAC,kBAAkB,eAAe,WAAW,GAC/C;CAGF,MAAM,SAA8C,CAAC;CACrD,KAAK,MAAM,WAAW,gBAAgB;EACpC,MAAM,aAAa;EAEnB,MAAM,eACJ,WAAW,YACX,WAAW,QACX,GAAA,CACA,YAAY;EACd,MAAM,OACJ,YAAY,WAAW,gBAAgB,IACnC,YAAY,MAAM,EAAuB,IACzC;EAGN,MAAM,gBAAgB,WAAW,aAAa,GAAA,CAAI,YAAY;EAC9D,MAAM,YACJ,iBAAiB,sCAAsC,CAAC,eACpD,KAAA,IACA;EAGN,IAAI,QAAQ,aAAa,SAAU,eACjC,OAAO,KAAK;GACV;GACA;GACA,GAAI,WAAW,SAAS,EAAE,QAAQ,WAAW,OAAO,IAAI,CAAC;EAC3D,CAAC;CAEL;CAEA,OAAO,OAAO,SAAS,IAAI,SAAS,KAAA;AACtC;AAEA,SAAS,2BACP,QACyC;CAIzC,OAAO;EACL,MAAM;EACN,GALkB,uCAClB,OAAO,WAIO,KAAK,CAAC;EACpB,GAAI,OAAO,kBAAkB,WAAW,QAAQ,IAC5C,EACE,WACE,OAAO,iBACX,IACA,CAAC;CACP;AACF;AAEA,SAAS,2BACP,QACyC;CACzC,OAAO;EACL,MAAM;EACN,GAAI,OAAO,kBAAkB,WAAW,QAAQ,IAC5C,EACE,WACE,OAAO,iBACX,IACA,CAAC;CACP;AACF;AAEA,SAAS,2BACP,QACyC;CACzC,OAAO;EACL,MAAM;EACN,GAAI,OAAO,kBAAkB,WAAW,QAAQ,IAC5C,EACE,WACE,OAAO,iBACX,IACA,CAAC;CACP;AACF;AAEA,SAAS,mBACP,QACqC;CACrC,IAAI,OAAO,gBAAgB;EACzB,KAAA,GACEC,4BAAAA,mBAAAA,CAAmB,OAAO,cAAc,MAAA,GACxCC,sCAAAA,qBAAAA,CAAqB,OAAO,cAAc,GAE1C,QAAA,GAAOC,kCAAAA,aAAAA,CAAa,OAAO,cAAc;OAEzC,OAAO,OAAO;CAElB,OACE;AAEJ;AAEA,SAAS,0BACP,QACwC;CACxC,MAAM,aAAa,mBAAmB,MAAM;CAC5C,MAAM,eACJ,OAAO,qBAAqB,sBAC5B,OAAO,qBAAqB,gBAC5B,OAAO,kBAAkB,WAAW,OAAO,IACtC,OAAO,mBACR,aACE,qBACA,KAAA;CACR,OAAO;EACL,MAAM;EACN,GAAI,eAAe,EAAE,WAAW,aAAa,IAAI,CAAC;EAClD,GAAI,aAAa,EAAE,QAAQ,WAAW,IAAI,CAAC;CAC7C;AACF;AAEA,SAAS,8BACP,UACA,QACgD;CAEhD,QADU,SAAS,YACX,GAAR;EACE,KAAK,SACH,OAAO,2BAA2B,MAAM;EAC1C,KAAK,SACH,OAAO,2BAA2B,MAAM;EAC1C,KAAK,SACH,OAAO,2BAA2B,MAAM;EAC1C,KAAK,QACH,OAAO,0BAA0B,MAAM;EACzC,SACE;CACJ;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,0CACd,QACoE;CACpE,IAAI,OAAO,gBACT,OAAO,OAAO;CAGhB,IAAI,OAAO,sBAAsB,OAAO,mBAAmB,SAAS,GAAG;EACrE,MAAM,UAAgD,CAAC;EACvD,KAAK,MAAM,YAAY,OAAO,oBAAoB;GAChD,MAAM,SAAS,8BAA8B,UAAU,MAAM;GAC7D,IAAI,QACF,QAAQ,KAAK,MAAM;EAEvB;EAEA,IAAI,QAAQ,WAAW,GACrB,OAAO,QAAQ;EAEjB,IAAI,QAAQ,SAAS,GACnB,OAAO;CAEX;CAEA,MAAM,aACJ,mBAAmB,MAAM;CAC3B,IAAI,YACF,OAAO;CAGT,IAAI,OAAO,kBAAkB;EAC3B,IAAI,OAAO,iBAAiB,WAAW,QAAQ,GAC7C,OAAO,2BAA2B,MAAM;EAE1C,IAAI,OAAO,iBAAiB,WAAW,QAAQ,GAC7C,OAAO,2BAA2B,MAAM;EAE1C,IAAI,OAAO,iBAAiB,WAAW,QAAQ,GAC7C,OAAO,2BAA2B,MAAM;EAE1C,IACE,OAAO,qBAAqB,sBAC5B,OAAO,qBAAqB,gBAC5B,OAAO,iBAAiB,WAAW,OAAO,GAE1C,OAAO,0BAA0B,MAAM;CAE3C;CAEA,IAAI,uCAAuC,OAAO,WAAW,GAC3D,OAAO,2BAA2B,MAAM;AAI5C;;;;AAKA,SAAgB,uCACd,UACA,QAGA;CACA,IAAI,aAAa,OACf,OAAO,CAAC;CAGV,MAAM,cAAc,OAAO;CAC3B,IAAI,CAAC,eAAe,CAACC,cAAAA,oBAAoB,SAAS,WAAW,GAC3D,OAAO,CAAC;CAGV,OAAO,EACL,cAAc,YAChB;AACF"}
|