@langchain/google 0.2.11 → 0.2.13
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 +29 -0
- package/dist/chat_models/{api-types.d.ts → api_types/generate_content.d.cts} +198 -200
- package/dist/chat_models/{api-types.d.cts → api_types/generate_content.d.ts} +198 -200
- 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 +60 -403
- package/dist/chat_models/base.cjs.map +1 -1
- package/dist/chat_models/base.d.cts +13 -200
- package/dist/chat_models/base.d.ts +15 -202
- package/dist/chat_models/base.js +61 -402
- package/dist/chat_models/base.js.map +1 -1
- package/dist/chat_models/handlers/base.cjs +62 -0
- package/dist/chat_models/handlers/base.cjs.map +1 -0
- package/dist/chat_models/handlers/base.d.cts +46 -0
- package/dist/chat_models/handlers/base.d.ts +46 -0
- package/dist/chat_models/handlers/base.js +62 -0
- package/dist/chat_models/handlers/base.js.map +1 -0
- package/dist/chat_models/handlers/generate_content.cjs +344 -0
- package/dist/chat_models/handlers/generate_content.cjs.map +1 -0
- package/dist/chat_models/handlers/generate_content.d.cts +32 -0
- package/dist/chat_models/handlers/generate_content.d.ts +32 -0
- package/dist/chat_models/handlers/generate_content.js +344 -0
- package/dist/chat_models/handlers/generate_content.js.map +1 -0
- package/dist/chat_models/handlers/index.cjs +6 -0
- package/dist/chat_models/handlers/index.d.cts +4 -0
- package/dist/chat_models/handlers/index.d.ts +4 -0
- package/dist/chat_models/handlers/index.js +4 -0
- 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 +14 -6
- package/dist/chat_models/index.cjs.map +1 -1
- package/dist/chat_models/index.d.cts +7 -3
- package/dist/chat_models/index.d.ts +7 -3
- package/dist/chat_models/index.js +8 -4
- package/dist/chat_models/index.js.map +1 -1
- package/dist/chat_models/node.cjs +4 -5
- package/dist/chat_models/node.cjs.map +1 -1
- 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/node.js.map +1 -1
- 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 +776 -88
- package/dist/chat_models/types.d.ts +776 -88
- 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/{messages.cjs → generate_content/messages.cjs} +4 -5
- package/dist/converters/generate_content/messages.cjs.map +1 -0
- package/dist/converters/{messages.js → generate_content/messages.js} +4 -5
- package/dist/converters/generate_content/messages.js.map +1 -0
- package/dist/converters/generate_content/params.cjs +135 -0
- package/dist/converters/generate_content/params.cjs.map +1 -0
- package/dist/converters/generate_content/params.js +131 -0
- package/dist/converters/generate_content/params.js.map +1 -0
- package/dist/{utils → converters/generate_content}/stream_events.cjs +2 -3
- package/dist/converters/generate_content/stream_events.cjs.map +1 -0
- package/dist/{utils → converters/generate_content}/stream_events.js +2 -3
- package/dist/converters/generate_content/stream_events.js.map +1 -0
- package/dist/converters/{tools.cjs → generate_content/tools.cjs} +4 -5
- package/dist/converters/generate_content/tools.cjs.map +1 -0
- package/dist/converters/{tools.js → generate_content/tools.js} +4 -5
- package/dist/converters/generate_content/tools.js.map +1 -0
- 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/{params.cjs → shared/params.cjs} +8 -94
- package/dist/converters/shared/params.cjs.map +1 -0
- package/dist/converters/{params.js → shared/params.js} +8 -92
- package/dist/converters/shared/params.js.map +1 -0
- package/dist/index.cjs +8 -0
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -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 +1 -2
- package/dist/utils/errors.js +1 -2
- 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 +9 -2
- package/dist/utils/metadata.cjs.map +1 -1
- package/dist/utils/metadata.js +9 -3
- package/dist/utils/metadata.js.map +1 -1
- package/dist/utils/misc.cjs +1 -2
- package/dist/utils/misc.cjs.map +1 -1
- package/dist/utils/misc.d.cts +2 -3
- package/dist/utils/misc.d.ts +2 -3
- package/dist/utils/misc.js +1 -2
- package/dist/utils/misc.js.map +1 -1
- package/dist/utils/stream.cjs +1 -2
- package/dist/utils/stream.js +1 -2
- package/package.json +12 -10
- package/dist/converters/messages.cjs.map +0 -1
- package/dist/converters/messages.js.map +0 -1
- package/dist/converters/params.cjs.map +0 -1
- package/dist/converters/params.js.map +0 -1
- package/dist/converters/tools.cjs.map +0 -1
- package/dist/converters/tools.js.map +0 -1
- package/dist/utils/stream_events.cjs.map +0 -1
- package/dist/utils/stream_events.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream_events.js","names":["uuidv4"],"sources":["../../../src/converters/interactions/stream_events.ts"],"sourcesContent":["import { CallbackManagerForLLMRun } from \"@langchain/core/callbacks/manager\";\nimport { finalizeContentBlock } from \"@langchain/core/language_models/compat\";\nimport type {\n ChatModelStreamEvent,\n FinishReason,\n} from \"@langchain/core/language_models/event\";\nimport {\n AIMessageChunk,\n type ContentBlock,\n type UsageMetadata,\n} from \"@langchain/core/messages\";\nimport type { ToolCall, ToolCallChunk } from \"@langchain/core/messages/tool\";\nimport { ChatGenerationChunk } from \"@langchain/core/outputs\";\nimport { v4 as uuidv4 } from \"@langchain/core/utils/uuid\";\nimport type { Gemini } from \"../../chat_models/types.js\";\nimport { GoogleError } from \"../../utils/errors.js\";\nimport {\n convertGeminiPartToContentBlock,\n convertGeminiPartsToToolCalls,\n} from \"../generate_content/messages.js\";\nimport {\n convertInteractionsContentToGeminiPart,\n convertInteractionsUsageToUsageMetadata,\n normalizeInteractionStep,\n synthesizeMetadataFromInteractions,\n} from \"./messages.js\";\n\nexport interface ConvertInteractionsStreamOptions {\n streamUsage?: boolean;\n model?: string;\n runManager?: CallbackManagerForLLMRun;\n}\n\ninterface TrackedFunctionCallState {\n id: string;\n name: string;\n argsText: string;\n argsObject?: Record<string, unknown>;\n thoughtSignature?: string;\n toolIndex: number;\n emittedToolCall: boolean;\n}\n\ninterface TrackedStepState {\n stepType?: string;\n hasThoughtSummary?: boolean;\n thoughtSignature?: string;\n textIndex?: number;\n functionCall?: TrackedFunctionCallState;\n}\n\n/**\n * Converts a stream of Interactions API SSE events (`InteractionSseEvent`) into\n * LangChain `ChatGenerationChunk` instances for `streamResponseChunks`.\n *\n * ### ThoughtStep & `thoughtSignature` Streaming Design\n *\n * During SSE streaming, a `ThoughtStep` arrives as a sequence of `step.delta` events:\n * - `{ type: \"thought_summary\", content: { type: \"text\", text: \"...\" } }`\n * - `{ type: \"thought_signature\", signature: \"...\" }`\n *\n * Matching `convertInteractionToAIMessage`:\n * 1. If a `ThoughtStep` emits one or more `thought_summary` deltas, we emit `AIMessageChunk`s\n * containing `{ type: \"text\", thought: true, text }` and attach `thoughtSignature` when\n * `thought_signature` arrives for that step. When concatenated via `concat()`, this forms\n * a reasoning block with its `thoughtSignature`.\n * 2. If a `ThoughtStep` only emits `thought_signature` (no `thought_summary`), we do NOT emit\n * a `{ thought: true }` block (which would prevent single-text responses from collapsing to\n * a string on `concat()`). Instead, we store `pendingThoughtSignature` and attach it to the\n * subsequent `function_call` or `model_output` chunk (or as a metadata-only\n * `{ type: \"text\", text: \"\", thoughtSignature }` chunk at the end of the stream).\n */\nexport async function* convertInteractionsStreamToChunks(\n source: AsyncIterable<Gemini.Interactions.InteractionSseEvent>,\n options: ConvertInteractionsStreamOptions = {}\n): AsyncGenerator<ChatGenerationChunk> {\n const shouldStreamUsage = options.streamUsage ?? true;\n const runManager = options.runManager;\n\n const stepStates = new Map<number, TrackedStepState>();\n const textSegments: Array<{\n text: string;\n annotations?: Gemini.Interactions.Annotation[];\n }> = [];\n const builtInToolSteps: Gemini.Interactions.Step[] = [];\n\n let interactionId: string | undefined;\n let interactionStatus: string | undefined;\n let interactionRole: string | undefined;\n let previousInteractionId: string | undefined;\n let modelName: string | undefined = options.model;\n let latestUsage: Gemini.Interactions.Usage | undefined;\n let pendingThoughtSignature: string | undefined;\n let pendingFunctionCallSignature: string | undefined;\n let hasEmittedStepDelta = false;\n let nextToolIndex = 0;\n\n const getOrCreateStepState = (index: number): TrackedStepState => {\n let state = stepStates.get(index);\n if (!state) {\n state = {};\n stepStates.set(index, state);\n }\n return state;\n };\n\n const emitFunctionCallChunk = (\n fcState: TrackedFunctionCallState\n ): ChatGenerationChunk => {\n let parsedArgs: Record<string, unknown> = fcState.argsObject ?? {};\n if (!fcState.argsObject && fcState.argsText.trim().length > 0) {\n try {\n const parsed = JSON.parse(fcState.argsText);\n if (typeof parsed === \"object\" && parsed !== null) {\n parsedArgs = parsed as Record<string, unknown>;\n }\n } catch {\n parsedArgs = {};\n }\n }\n\n const argsString =\n fcState.argsText.length > 0\n ? fcState.argsText\n : JSON.stringify(parsedArgs);\n\n const toolCall: ToolCall & { thoughtSignature?: string } = {\n type: \"tool_call\",\n id: fcState.id,\n name: fcState.name,\n args: parsedArgs,\n ...(fcState.thoughtSignature\n ? { thoughtSignature: fcState.thoughtSignature }\n : {}),\n };\n\n const toolCallChunk: ToolCallChunk = {\n type: \"tool_call_chunk\",\n id: fcState.id,\n name: fcState.name,\n args: argsString,\n index: fcState.toolIndex,\n };\n\n const part: Gemini.Part = {\n functionCall: {\n id: fcState.id,\n name: fcState.name,\n args: parsedArgs,\n },\n ...(fcState.thoughtSignature\n ? { thoughtSignature: fcState.thoughtSignature }\n : {}),\n };\n const block = convertGeminiPartToContentBlock(part);\n\n fcState.emittedToolCall = true;\n\n return new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: block ? [block] : \"\",\n tool_calls: [toolCall],\n tool_call_chunks: [toolCallChunk],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n };\n\n for await (const event of source) {\n switch (event.event_type) {\n case \"interaction.created\":\n case \"interaction.start\": {\n if (event.interaction) {\n interactionId = event.interaction.id ?? interactionId;\n interactionStatus = event.interaction.status ?? interactionStatus;\n interactionRole = event.interaction.role ?? interactionRole;\n previousInteractionId =\n event.interaction.previous_interaction_id ?? previousInteractionId;\n modelName = event.interaction.model ?? modelName;\n if (event.interaction.usage) {\n latestUsage = event.interaction.usage;\n }\n }\n break;\n }\n\n case \"step.start\":\n case \"content.start\": {\n const state = getOrCreateStepState(event.index);\n const rawStep = event.step ?? event.content;\n if (rawStep) {\n const step = normalizeInteractionStep(rawStep);\n state.stepType = step.type;\n if (step.type === \"function_call\") {\n const sig = pendingThoughtSignature ?? pendingFunctionCallSignature;\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n const hasInitialArgs =\n step.arguments && Object.keys(step.arguments).length > 0;\n state.functionCall = {\n id: step.id || `lc-tool-call-${uuidv4().replace(/-/g, \"\")}`,\n name: step.name || \"\",\n argsText: hasInitialArgs ? JSON.stringify(step.arguments) : \"\",\n argsObject: hasInitialArgs ? step.arguments : undefined,\n thoughtSignature: sig,\n toolIndex: nextToolIndex++,\n emittedToolCall: false,\n };\n } else if (step.type === \"thought\" && step.signature) {\n state.thoughtSignature = step.signature;\n pendingFunctionCallSignature = step.signature;\n }\n }\n break;\n }\n\n case \"step.delta\":\n case \"content.delta\": {\n const state = getOrCreateStepState(event.index);\n if (event.metadata?.total_usage) {\n latestUsage = event.metadata.total_usage;\n }\n\n const delta = event.delta;\n if (!delta) break;\n\n switch (delta.type) {\n case \"text\": {\n hasEmittedStepDelta = true;\n if (state.textIndex === undefined) {\n state.textIndex = textSegments.length;\n textSegments.push({ text: \"\", annotations: [] });\n }\n const seg = textSegments[state.textIndex];\n seg.text += delta.text;\n\n const sig = pendingThoughtSignature;\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n\n const part: Gemini.Part = {\n text: delta.text,\n ...(sig ? { thoughtSignature: sig } : {}),\n };\n const textBlock = convertGeminiPartToContentBlock(part)!;\n\n const chunk = new ChatGenerationChunk({\n text: delta.text,\n message: new AIMessageChunk({\n content: delta.text,\n additional_kwargs: {\n originalTextContentBlock: textBlock,\n },\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n yield chunk;\n await runManager?.handleLLMNewToken(delta.text);\n break;\n }\n\n case \"text_annotation_delta\":\n case \"text_annotation\": {\n if (state.textIndex === undefined) {\n state.textIndex = textSegments.length;\n textSegments.push({ text: \"\", annotations: [] });\n }\n const seg = textSegments[state.textIndex];\n seg.annotations = [\n ...(seg.annotations ?? []),\n ...(delta.annotations ?? []),\n ];\n break;\n }\n\n case \"thought_summary\": {\n hasEmittedStepDelta = true;\n state.hasThoughtSummary = true;\n const summaryText =\n delta.content?.type === \"text\" ? delta.content.text : \"\";\n if (summaryText) {\n const part: Gemini.Part = {\n text: summaryText,\n thought: true,\n ...(state.thoughtSignature\n ? { thoughtSignature: state.thoughtSignature }\n : {}),\n };\n const block = convertGeminiPartToContentBlock(part)!;\n state.thoughtSignature = undefined;\n\n const chunk = new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: [block],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n yield chunk;\n await runManager?.handleLLMNewToken(summaryText);\n }\n break;\n }\n\n case \"thought_signature\": {\n if (delta.signature) {\n pendingFunctionCallSignature = delta.signature;\n if (state.hasThoughtSummary) {\n hasEmittedStepDelta = true;\n const part: Gemini.Part = {\n text: \"\",\n thought: true,\n thoughtSignature: delta.signature,\n };\n const block = convertGeminiPartToContentBlock(part)!;\n yield new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: [block],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n } else {\n pendingThoughtSignature = delta.signature;\n state.thoughtSignature = delta.signature;\n }\n }\n break;\n }\n\n case \"arguments_delta\":\n case \"function_call\": {\n hasEmittedStepDelta = true;\n const fcSig =\n pendingThoughtSignature ?? pendingFunctionCallSignature;\n if (!state.functionCall) {\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n state.functionCall = {\n id: delta.id || `lc-tool-call-${uuidv4().replace(/-/g, \"\")}`,\n name: delta.name || \"\",\n argsText: \"\",\n thoughtSignature: fcSig,\n toolIndex: nextToolIndex++,\n emittedToolCall: false,\n };\n } else {\n if (delta.id) state.functionCall.id = delta.id;\n if (delta.name) state.functionCall.name = delta.name;\n if (fcSig && !state.functionCall.thoughtSignature) {\n state.functionCall.thoughtSignature = fcSig;\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n }\n }\n\n if (typeof delta.arguments === \"string\") {\n state.functionCall.argsText += delta.arguments;\n } else if (\n typeof delta.arguments === \"object\" &&\n delta.arguments !== null\n ) {\n state.functionCall.argsObject = delta.arguments;\n state.functionCall.argsText = JSON.stringify(delta.arguments);\n yield emitFunctionCallChunk(state.functionCall);\n await runManager?.handleLLMNewToken(\"\");\n }\n break;\n }\n\n case \"image\":\n case \"audio\":\n case \"document\":\n case \"video\": {\n hasEmittedStepDelta = true;\n const sig = pendingThoughtSignature;\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n const part = convertInteractionsContentToGeminiPart(\n delta as Gemini.Interactions.Content,\n sig\n );\n if (part) {\n const block = convertGeminiPartToContentBlock(part);\n if (block) {\n yield new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: [block],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n await runManager?.handleLLMNewToken(\"\");\n }\n }\n break;\n }\n\n case \"code_execution_call\": {\n hasEmittedStepDelta = true;\n const sig = delta.signature ?? pendingThoughtSignature;\n pendingThoughtSignature = undefined;\n const part: Gemini.Part = {\n executableCode: {\n code: delta.arguments?.code ?? \"\",\n language: \"PYTHON\",\n },\n ...(sig ? { thoughtSignature: sig } : {}),\n };\n const block = convertGeminiPartToContentBlock(part);\n if (block) {\n yield new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: [block],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n await runManager?.handleLLMNewToken(\"\");\n }\n break;\n }\n\n case \"code_execution_result\": {\n hasEmittedStepDelta = true;\n const sig = delta.signature ?? pendingThoughtSignature;\n pendingThoughtSignature = undefined;\n const part: Gemini.Part = {\n codeExecutionResult: {\n output: delta.result ?? \"\",\n outcome: delta.is_error ? \"OUTCOME_FAILED\" : \"OUTCOME_OK\",\n },\n ...(sig ? { thoughtSignature: sig } : {}),\n };\n const block = convertGeminiPartToContentBlock(part);\n if (block) {\n yield new ChatGenerationChunk({\n text: \"\",\n message: new AIMessageChunk({\n content: [block],\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n await runManager?.handleLLMNewToken(\"\");\n }\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(delta as unknown as Gemini.Interactions.Step);\n break;\n }\n\n default:\n break;\n }\n break;\n }\n\n case \"step.stop\":\n case \"content.stop\": {\n const state = stepStates.get(event.index);\n if (event.usage) {\n latestUsage = event.usage;\n } else if (event.step_usage && !latestUsage) {\n latestUsage = event.step_usage;\n }\n if (state?.functionCall && !state.functionCall.emittedToolCall) {\n hasEmittedStepDelta = true;\n yield emitFunctionCallChunk(state.functionCall);\n await runManager?.handleLLMNewToken(\"\");\n }\n break;\n }\n\n case \"interaction.status_update\": {\n interactionId = event.interaction_id ?? interactionId;\n interactionStatus = event.status ?? interactionStatus;\n if (event.usage) {\n latestUsage = event.usage;\n }\n break;\n }\n\n case \"interaction.completed\":\n case \"interaction.complete\": {\n if (event.interaction) {\n interactionId = event.interaction.id ?? interactionId;\n interactionStatus = event.interaction.status ?? interactionStatus;\n interactionRole = event.interaction.role ?? interactionRole;\n previousInteractionId =\n event.interaction.previous_interaction_id ?? previousInteractionId;\n modelName = event.interaction.model ?? modelName;\n if (event.interaction.usage) {\n latestUsage = event.interaction.usage;\n }\n\n // If no step deltas were emitted before interaction.completed (e.g. a non-delta\n // completed event containing full steps), emit chunks from the completed steps.\n const completedItems =\n event.interaction.steps ?? event.interaction.outputs ?? [];\n if (!hasEmittedStepDelta && completedItems.length > 0) {\n const steps = completedItems.map(normalizeInteractionStep);\n const parts: Gemini.Part[] = [];\n for (const step of steps) {\n if (step.type === \"thought\") {\n const summaries = (step.summary ?? []).filter(\n (c): c is Gemini.Interactions.TextContent =>\n c.type === \"text\" &&\n typeof c.text === \"string\" &&\n c.text.length > 0\n );\n if (summaries.length > 0) {\n for (let i = 0; i < summaries.length; i++) {\n parts.push({\n text: summaries[i].text,\n thought: true,\n ...(i === summaries.length - 1 && 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 } else if (step.type === \"model_output\") {\n const contents =\n typeof step.content === \"string\"\n ? [{ type: \"text\" as const, text: step.content }]\n : (step.content ?? []);\n for (const c of contents) {\n if (c.type === \"text\") {\n textSegments.push({\n text: c.text,\n annotations: c.annotations,\n });\n }\n const p = convertInteractionsContentToGeminiPart(\n c,\n pendingThoughtSignature\n );\n if (p) {\n parts.push(p);\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n }\n }\n } else if (step.type === \"function_call\") {\n const fcSig =\n pendingThoughtSignature ?? pendingFunctionCallSignature;\n parts.push({\n functionCall: {\n id: step.id,\n name: step.name,\n args: step.arguments ?? {},\n },\n ...(fcSig ? { thoughtSignature: fcSig } : {}),\n });\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n } else if (\n step.type === \"google_search_call\" ||\n step.type === \"google_search_result\" ||\n step.type === \"google_maps_call\" ||\n step.type === \"google_maps_result\" ||\n step.type === \"file_search_call\" ||\n step.type === \"file_search_result\" ||\n step.type === \"url_context_call\" ||\n step.type === \"url_context_result\"\n ) {\n builtInToolSteps.push(step);\n }\n }\n\n if (parts.length > 0) {\n const blockContent = parts\n .map((p) => convertGeminiPartToContentBlock(p))\n .filter((b): b is ContentBlock => b !== null);\n const toolCalls = convertGeminiPartsToToolCalls(parts);\n const toolCallChunks: ToolCallChunk[] = toolCalls.map(\n (tc, idx) => ({\n type: \"tool_call_chunk\",\n id: tc.id,\n name: tc.name,\n args: JSON.stringify(tc.args ?? {}),\n index: idx,\n })\n );\n const singleText =\n blockContent.length === 1 &&\n blockContent[0].type === \"text\" &&\n !blockContent[0].thought\n ? (blockContent[0].text as string)\n : undefined;\n\n hasEmittedStepDelta = true;\n yield new ChatGenerationChunk({\n text: singleText ?? \"\",\n message: new AIMessageChunk({\n content: singleText ?? blockContent,\n tool_calls: toolCalls,\n tool_call_chunks: toolCallChunks,\n additional_kwargs: singleText\n ? { originalTextContentBlock: blockContent[0] }\n : {},\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n },\n }),\n });\n await runManager?.handleLLMNewToken(singleText ?? \"\");\n }\n }\n }\n break;\n }\n\n case \"error\": {\n throw new GoogleError(\n `Google Interactions API stream error (${event.error?.code ?? \"unknown\"}): ${event.error?.message ?? \"Unknown error\"}`\n );\n }\n\n default:\n break;\n }\n }\n\n // Flush any un-emitted function calls if a stream ended without step.stop\n for (const state of stepStates.values()) {\n if (state.functionCall && !state.functionCall.emittedToolCall) {\n hasEmittedStepDelta = true;\n yield emitFunctionCallChunk(state.functionCall);\n await runManager?.handleLLMNewToken(\"\");\n }\n }\n\n const usageMetadata = shouldStreamUsage\n ? convertInteractionsUsageToUsageMetadata(latestUsage)\n : undefined;\n\n const synthesized = synthesizeMetadataFromInteractions({\n textSegments,\n builtInToolSteps,\n });\n\n let finishReason: string | undefined;\n if (\n interactionStatus === \"completed\" ||\n interactionStatus === \"requires_action\"\n ) {\n finishReason = \"STOP\";\n } else if (interactionStatus) {\n finishReason = interactionStatus.toUpperCase();\n }\n\n const trailingSigBlock: ContentBlock | undefined = pendingThoughtSignature\n ? {\n type: \"text\",\n text: \"\",\n thoughtSignature: pendingThoughtSignature,\n }\n : undefined;\n\n if (\n usageMetadata ||\n finishReason ||\n trailingSigBlock ||\n Object.keys(synthesized).length > 0 ||\n interactionId ||\n !hasEmittedStepDelta\n ) {\n yield new ChatGenerationChunk({\n text: \"\",\n generationInfo: {\n ...(finishReason ? { finishReason } : {}),\n },\n message: new AIMessageChunk({\n content: \"\",\n ...(usageMetadata ? { usage_metadata: usageMetadata } : {}),\n additional_kwargs: {\n ...(finishReason ? { finishReason } : {}),\n ...(trailingSigBlock\n ? { originalTextContentBlock: trailingSigBlock }\n : {}),\n },\n response_metadata: {\n model_provider: \"google\",\n ...(modelName ? { model_name: modelName } : {}),\n ...(finishReason ? { finishReason } : {}),\n ...synthesized,\n ...(builtInToolSteps.length > 0\n ? { interactionSteps: builtInToolSteps }\n : {}),\n ...(interactionId || interactionStatus\n ? {\n interaction: {\n ...(interactionId ? { id: interactionId } : {}),\n ...(interactionStatus ? { status: interactionStatus } : {}),\n ...(interactionRole ? { role: interactionRole } : {}),\n ...(previousInteractionId\n ? { previous_interaction_id: previousInteractionId }\n : {}),\n },\n }\n : {}),\n },\n }),\n });\n }\n}\n\ntype BlockKey = \"text\" | \"reasoning\" | `tool:${number}`;\n\n/**\n * Converts a stream of Interactions API SSE events (`InteractionSseEvent`) into\n * LangChain `ChatModelStreamEvent`s for `streamChatModelEvents`.\n */\nexport async function* convertInteractionsStream(\n source: AsyncIterable<Gemini.Interactions.InteractionSseEvent>,\n options: { streamUsage?: boolean; model?: string } = {}\n): AsyncGenerator<ChatModelStreamEvent> {\n const shouldStreamUsage = options.streamUsage ?? true;\n const blockAccumulators = new Map<\n number,\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n Record<string, any>\n >();\n const blockKeyToIndex = new Map<BlockKey, number>();\n let nextBlockIndex = 0;\n let messageStarted = false;\n let usageSnapshot: UsageMetadata | undefined;\n const finishReason: FinishReason = \"stop\";\n let pendingThoughtSignature: string | undefined;\n let pendingFunctionCallSignature: string | undefined;\n let nextToolIdx = 0;\n\n const stepStates = new Map<\n number,\n {\n hasThoughtSummary?: boolean;\n toolIdx?: number;\n toolId?: string;\n toolName?: string;\n textIndex?: number;\n }\n >();\n const textSegments: Array<{\n text: string;\n annotations?: Gemini.Interactions.Annotation[];\n }> = [];\n const builtInToolSteps: Gemini.Interactions.Step[] = [];\n\n const getOrCreateBlockIndex = (\n key: BlockKey,\n initial: Record<string, unknown>\n ): { index: number; isNew: boolean } => {\n const existing = blockKeyToIndex.get(key);\n if (existing !== undefined) {\n return { index: existing, isNew: false };\n }\n const index = nextBlockIndex++;\n blockKeyToIndex.set(key, index);\n blockAccumulators.set(index, { ...initial });\n return { index, isNew: true };\n };\n\n const ensureMessageStarted = (): ChatModelStreamEvent | undefined => {\n if (!messageStarted) {\n messageStarted = true;\n return { event: \"message-start\" as const };\n }\n return undefined;\n };\n\n for await (const event of source) {\n const startEv = ensureMessageStarted();\n if (startEv) yield startEv;\n\n if (\n event.event_type === \"step.start\" ||\n event.event_type === \"content.start\"\n ) {\n const rawStep = event.step ?? event.content;\n if (rawStep) {\n const step = normalizeInteractionStep(rawStep);\n if (step.type === \"function_call\") {\n stepStates.set(event.index, {\n toolIdx: nextToolIdx++,\n toolId: step.id,\n toolName: step.name,\n });\n } else {\n stepStates.set(event.index, {});\n }\n }\n continue;\n }\n\n if (\n event.event_type === \"step.delta\" ||\n event.event_type === \"content.delta\"\n ) {\n if (shouldStreamUsage && event.metadata?.total_usage) {\n usageSnapshot = convertInteractionsUsageToUsageMetadata(\n event.metadata.total_usage\n );\n if (usageSnapshot) {\n yield { event: \"usage\" as const, usage: usageSnapshot };\n }\n }\n\n const delta = event.delta;\n if (!delta) continue;\n\n let state = stepStates.get(event.index);\n if (!state) {\n state = {};\n stepStates.set(event.index, state);\n }\n\n if (delta.type === \"text\") {\n if (state.textIndex === undefined) {\n state.textIndex = textSegments.length;\n textSegments.push({ text: \"\", annotations: [] });\n }\n textSegments[state.textIndex].text += delta.text;\n\n const key: BlockKey = \"text\";\n const { index, isNew } = getOrCreateBlockIndex(key, {\n type: \"text\",\n text: \"\",\n });\n if (isNew) {\n yield {\n event: \"content-block-start\" as const,\n index,\n content: { type: \"text\", text: \"\" } as ContentBlock,\n };\n }\n const acc = blockAccumulators.get(index)!;\n acc.text = (acc.text ?? \"\") + delta.text;\n if (pendingThoughtSignature) {\n acc.thoughtSignature = pendingThoughtSignature;\n pendingThoughtSignature = undefined;\n }\n pendingFunctionCallSignature = undefined;\n yield {\n event: \"content-block-delta\" as const,\n index,\n delta: { type: \"text-delta\" as const, text: delta.text },\n };\n } else if (\n delta.type === \"text_annotation_delta\" ||\n delta.type === \"text_annotation\"\n ) {\n if (state.textIndex === undefined) {\n state.textIndex = textSegments.length;\n textSegments.push({ text: \"\", annotations: [] });\n }\n const seg = textSegments[state.textIndex];\n seg.annotations = [\n ...(seg.annotations ?? []),\n ...(delta.annotations ?? []),\n ];\n } else if (delta.type === \"thought_summary\") {\n state.hasThoughtSummary = true;\n const summaryText =\n delta.content?.type === \"text\" ? delta.content.text : \"\";\n if (summaryText) {\n const key: BlockKey = \"reasoning\";\n const { index, isNew } = getOrCreateBlockIndex(key, {\n type: \"reasoning\",\n reasoning: \"\",\n });\n if (isNew) {\n yield {\n event: \"content-block-start\" as const,\n index,\n content: { type: \"reasoning\", reasoning: \"\" } as ContentBlock,\n };\n }\n const acc = blockAccumulators.get(index)!;\n acc.reasoning = (acc.reasoning ?? \"\") + summaryText;\n yield {\n event: \"content-block-delta\" as const,\n index,\n delta: { type: \"reasoning-delta\" as const, reasoning: summaryText },\n };\n }\n } else if (delta.type === \"thought_signature\") {\n if (delta.signature) {\n pendingFunctionCallSignature = delta.signature;\n if (state.hasThoughtSummary) {\n const existingIdx = blockKeyToIndex.get(\"reasoning\");\n if (existingIdx !== undefined) {\n const acc = blockAccumulators.get(existingIdx)!;\n acc.thoughtSignature = delta.signature;\n }\n } else {\n pendingThoughtSignature = delta.signature;\n }\n }\n } else if (\n delta.type === \"arguments_delta\" ||\n delta.type === \"function_call\"\n ) {\n if (state.toolIdx === undefined) {\n state.toolIdx = nextToolIdx++;\n }\n const toolIdx = state.toolIdx;\n const key: BlockKey = `tool:${toolIdx}`;\n const candidateId =\n delta.id ||\n state.toolId ||\n `lc-tool-call-${uuidv4().replace(/-/g, \"\")}`;\n const candidateName = delta.name || state.toolName || \"\";\n const { index, isNew } = getOrCreateBlockIndex(key, {\n type: \"tool_call_chunk\",\n id: candidateId,\n name: candidateName,\n args: \"\",\n index: toolIdx,\n });\n const acc = blockAccumulators.get(index)!;\n if (delta.id) acc.id = delta.id;\n if (delta.name) acc.name = delta.name;\n const id = acc.id as string;\n\n if (isNew) {\n yield {\n event: \"content-block-start\" as const,\n index,\n content: {\n type: \"tool_call_chunk\",\n id,\n name: acc.name,\n args: \"\",\n index: toolIdx,\n } as ContentBlock,\n };\n }\n\n const argsDelta =\n typeof delta.arguments === \"string\"\n ? delta.arguments\n : JSON.stringify(delta.arguments ?? {});\n acc.args =\n typeof delta.arguments === \"string\"\n ? (acc.args ?? \"\") + argsDelta\n : argsDelta;\n\n const fcSig = pendingThoughtSignature ?? pendingFunctionCallSignature;\n if (fcSig) {\n acc.thoughtSignature = fcSig;\n pendingThoughtSignature = undefined;\n pendingFunctionCallSignature = undefined;\n }\n\n yield {\n event: \"content-block-delta\" as const,\n index,\n delta: {\n type: \"block-delta\" as const,\n fields: {\n type: \"tool_call_chunk\",\n id,\n name: acc.name,\n args: argsDelta,\n },\n },\n };\n } else if (\n delta.type === \"google_search_call\" ||\n delta.type === \"google_search_result\" ||\n delta.type === \"google_maps_call\" ||\n delta.type === \"google_maps_result\" ||\n delta.type === \"file_search_call\" ||\n delta.type === \"file_search_result\" ||\n delta.type === \"url_context_call\" ||\n delta.type === \"url_context_result\"\n ) {\n builtInToolSteps.push(delta as unknown as Gemini.Interactions.Step);\n }\n continue;\n }\n\n if (\n event.event_type === \"interaction.completed\" ||\n event.event_type === \"interaction.complete\"\n ) {\n if (shouldStreamUsage && event.interaction?.usage) {\n usageSnapshot = convertInteractionsUsageToUsageMetadata(\n event.interaction.usage\n );\n if (usageSnapshot) {\n yield { event: \"usage\" as const, usage: usageSnapshot };\n }\n }\n continue;\n }\n\n if (event.event_type === \"error\") {\n throw new GoogleError(\n `Google Interactions API stream error (${event.error?.code ?? \"unknown\"}): ${event.error?.message ?? \"Unknown error\"}`\n );\n }\n }\n\n for (const [index, acc] of blockAccumulators) {\n const finalized = finalizeContentBlock(acc as ContentBlock);\n yield {\n event: \"content-block-finish\" as const,\n index,\n content: acc.thoughtSignature\n ? ({\n ...finalized,\n thoughtSignature: acc.thoughtSignature,\n } as ContentBlock)\n : finalized,\n };\n }\n\n const synthesized = synthesizeMetadataFromInteractions({\n textSegments,\n builtInToolSteps,\n });\n\n yield {\n event: \"message-finish\" as const,\n reason: finishReason,\n ...(usageSnapshot ? { usage: usageSnapshot } : {}),\n responseMetadata: {\n model_provider: \"google\",\n ...synthesized,\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
const require_errors = require("../../utils/errors.cjs");
|
|
2
|
+
const require_tools = require("../generate_content/tools.cjs");
|
|
3
|
+
let _langchain_core_utils_function_calling = require("@langchain/core/utils/function_calling");
|
|
4
|
+
let _langchain_core_language_models_base = require("@langchain/core/language_models/base");
|
|
5
|
+
// src/converters/interactions/tools.ts
|
|
6
|
+
const INTERACTIONS_TOOL_TYPES = /* @__PURE__ */ new Set([
|
|
7
|
+
"function",
|
|
8
|
+
"google_search",
|
|
9
|
+
"code_execution",
|
|
10
|
+
"url_context",
|
|
11
|
+
"computer_use",
|
|
12
|
+
"file_search",
|
|
13
|
+
"google_maps",
|
|
14
|
+
"mcp_server",
|
|
15
|
+
"retrieval"
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Type guard to check if a tool is already in Interactions API format.
|
|
19
|
+
* Note: OpenAI tools also have `type: "function"`, so we exclude objects
|
|
20
|
+
* that have an OpenAI-style nested `function` object.
|
|
21
|
+
*/
|
|
22
|
+
function isInteractionsTool(tool) {
|
|
23
|
+
if (typeof tool !== "object" || tool === null) return false;
|
|
24
|
+
if ((0, _langchain_core_language_models_base.isOpenAITool)(tool)) return false;
|
|
25
|
+
if (!("type" in tool) || typeof tool.type !== "string") return false;
|
|
26
|
+
return INTERACTIONS_TOOL_TYPES.has(tool.type);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Type guard to check if a tool is in GenerateContent `Gemini.Tool` format.
|
|
30
|
+
*/
|
|
31
|
+
function isGenerateContentTool(tool) {
|
|
32
|
+
if (typeof tool !== "object" || tool === null) return false;
|
|
33
|
+
return [
|
|
34
|
+
"functionDeclarations",
|
|
35
|
+
"codeExecution",
|
|
36
|
+
"googleSearch",
|
|
37
|
+
"googleSearchRetrieval",
|
|
38
|
+
"urlContext",
|
|
39
|
+
"googleMaps",
|
|
40
|
+
"fileSearch",
|
|
41
|
+
"computerUse",
|
|
42
|
+
"mcpServers",
|
|
43
|
+
"retrieval"
|
|
44
|
+
].some((attr) => attr in tool);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Converts a GenerateContent-formatted `Gemini.Tool` object into one or more
|
|
48
|
+
* flat Interactions API `Gemini.Interactions.Tool` objects, translating
|
|
49
|
+
* camelCase properties to snake_case where appropriate.
|
|
50
|
+
*/
|
|
51
|
+
function convertGenerateContentToolToInteractionsTools(tool) {
|
|
52
|
+
const results = [];
|
|
53
|
+
if ("functionDeclarations" in tool && Array.isArray(tool.functionDeclarations)) for (const decl of tool.functionDeclarations) {
|
|
54
|
+
const parameters = decl.parameters ?? decl.parametersJsonSchema;
|
|
55
|
+
results.push({
|
|
56
|
+
type: "function",
|
|
57
|
+
name: decl.name ?? "",
|
|
58
|
+
description: decl.description ?? "A function available to call.",
|
|
59
|
+
...parameters ? { parameters } : {}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if ("googleSearch" in tool && tool.googleSearch) {
|
|
63
|
+
const gs = tool.googleSearch;
|
|
64
|
+
const searchTypes = [];
|
|
65
|
+
if (gs.searchTypes?.webSearch) searchTypes.push("web_search");
|
|
66
|
+
if (gs.searchTypes?.imageSearch) searchTypes.push("image_search");
|
|
67
|
+
const timeRangeFilter = gs.time_range_filter ?? (gs.timeRangeFilter ? {
|
|
68
|
+
start_time: gs.timeRangeFilter.startTime,
|
|
69
|
+
end_time: gs.timeRangeFilter.endTime
|
|
70
|
+
} : void 0);
|
|
71
|
+
results.push({
|
|
72
|
+
type: "google_search",
|
|
73
|
+
...searchTypes.length > 0 ? { search_types: searchTypes } : {},
|
|
74
|
+
...timeRangeFilter ? { time_range_filter: timeRangeFilter } : {}
|
|
75
|
+
});
|
|
76
|
+
} else if ("googleSearchRetrieval" in tool) results.push({ type: "google_search" });
|
|
77
|
+
if ("codeExecution" in tool && tool.codeExecution) results.push({ type: "code_execution" });
|
|
78
|
+
if ("urlContext" in tool && tool.urlContext) results.push({ type: "url_context" });
|
|
79
|
+
if ("googleMaps" in tool && tool.googleMaps) {
|
|
80
|
+
const gm = tool.googleMaps;
|
|
81
|
+
const enableWidget = gm.enable_widget ?? gm.enableWidget;
|
|
82
|
+
results.push({
|
|
83
|
+
type: "google_maps",
|
|
84
|
+
...typeof enableWidget === "boolean" ? { enable_widget: enableWidget } : {},
|
|
85
|
+
...typeof gm.latitude === "number" ? { latitude: gm.latitude } : {},
|
|
86
|
+
...typeof gm.longitude === "number" ? { longitude: gm.longitude } : {}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if ("fileSearch" in tool && tool.fileSearch) {
|
|
90
|
+
const fs = tool.fileSearch;
|
|
91
|
+
const storeNames = fs.file_search_store_names ?? fs.fileSearchStoreNames;
|
|
92
|
+
const topK = fs.top_k ?? fs.topK;
|
|
93
|
+
const metadataFilter = fs.metadata_filter ?? fs.metadataFilter;
|
|
94
|
+
results.push({
|
|
95
|
+
type: "file_search",
|
|
96
|
+
...storeNames ? { file_search_store_names: storeNames } : {},
|
|
97
|
+
...typeof topK === "number" ? { top_k: topK } : {},
|
|
98
|
+
...metadataFilter ? { metadata_filter: metadataFilter } : {}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if ("computerUse" in tool && tool.computerUse) {
|
|
102
|
+
const cu = tool.computerUse;
|
|
103
|
+
const rawEnv = cu.environment;
|
|
104
|
+
const environment = rawEnv === "ENVIRONMENT_BROWSER" || rawEnv === "browser" ? "browser" : void 0;
|
|
105
|
+
const excludedPredefinedFunctions = cu.excluded_predefined_functions ?? cu.excludedPredefinedFunctions;
|
|
106
|
+
results.push({
|
|
107
|
+
type: "computer_use",
|
|
108
|
+
...environment ? { environment } : {},
|
|
109
|
+
...excludedPredefinedFunctions ? { excluded_predefined_functions: excludedPredefinedFunctions } : {}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if ("mcpServers" in tool && Array.isArray(tool.mcpServers)) for (const server of tool.mcpServers) {
|
|
113
|
+
const transport = server.streamableHttpTransport;
|
|
114
|
+
const url = server.url ?? transport?.url;
|
|
115
|
+
const headers = server.headers ?? transport?.headers;
|
|
116
|
+
const allowedTools = server.allowed_tools ?? server.allowedTools;
|
|
117
|
+
results.push({
|
|
118
|
+
type: "mcp_server",
|
|
119
|
+
...typeof server.name === "string" ? { name: server.name } : {},
|
|
120
|
+
...url ? { url } : {},
|
|
121
|
+
...headers ? { headers } : {},
|
|
122
|
+
...allowedTools ? { allowed_tools: allowedTools } : {}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if ("retrieval" in tool && tool.retrieval) {
|
|
126
|
+
const ret = tool.retrieval;
|
|
127
|
+
const vas = ret.vertex_ai_search_config ?? ret.vertexAiSearch;
|
|
128
|
+
const datastores = Array.isArray(vas?.datastores) ? vas.datastores : typeof vas?.datastore === "string" ? [vas.datastore] : void 0;
|
|
129
|
+
results.push({
|
|
130
|
+
type: "retrieval",
|
|
131
|
+
...vas ? {
|
|
132
|
+
retrieval_types: ["vertex_ai_search"],
|
|
133
|
+
vertex_ai_search_config: {
|
|
134
|
+
...datastores ? { datastores } : {},
|
|
135
|
+
...typeof vas.engine === "string" ? { engine: vas.engine } : {}
|
|
136
|
+
}
|
|
137
|
+
} : {}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return results;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Converts an array of tools in any supported format (LangChain `StructuredTool`,
|
|
144
|
+
* OpenAI tool, GenerateContent `Gemini.Tool`, raw `FunctionDeclaration`, or native
|
|
145
|
+
* Interactions `Tool`) into flat `Gemini.Interactions.Tool[]` items.
|
|
146
|
+
*/
|
|
147
|
+
const convertToolsToInteractionsTools = (tools) => {
|
|
148
|
+
if (tools.length === 0) return [];
|
|
149
|
+
const interactionsTools = [];
|
|
150
|
+
for (const tool of tools) {
|
|
151
|
+
if (isInteractionsTool(tool)) {
|
|
152
|
+
interactionsTools.push(tool);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (isGenerateContentTool(tool)) {
|
|
156
|
+
interactionsTools.push(...convertGenerateContentToolToInteractionsTools(tool));
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if ((0, _langchain_core_utils_function_calling.isLangChainTool)(tool)) {
|
|
160
|
+
const jsonSchema = require_tools.schemaToGeminiParameters(tool.schema);
|
|
161
|
+
interactionsTools.push({
|
|
162
|
+
type: "function",
|
|
163
|
+
name: tool.name,
|
|
164
|
+
description: tool.description ?? "A function available to call.",
|
|
165
|
+
parameters: jsonSchema
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if ((0, _langchain_core_language_models_base.isOpenAITool)(tool)) {
|
|
170
|
+
interactionsTools.push({
|
|
171
|
+
type: "function",
|
|
172
|
+
name: tool.function.name,
|
|
173
|
+
description: tool.function.description ?? "A function available to call.",
|
|
174
|
+
parameters: tool.function.parameters ? require_tools.schemaToGeminiParameters(tool.function.parameters) : void 0
|
|
175
|
+
});
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (typeof tool === "object" && tool !== null && "name" in tool && typeof tool.name === "string") {
|
|
179
|
+
const funcDecl = tool;
|
|
180
|
+
interactionsTools.push({
|
|
181
|
+
type: "function",
|
|
182
|
+
name: funcDecl.name,
|
|
183
|
+
description: funcDecl.description ?? "A function available to call.",
|
|
184
|
+
...funcDecl.parameters ? { parameters: funcDecl.parameters } : {}
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
throw new require_errors.InvalidToolError(tool);
|
|
189
|
+
}
|
|
190
|
+
return interactionsTools;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Converts LangChain's `tool_choice` option into the Interactions API
|
|
194
|
+
* `generation_config.tool_choice` format (`ToolChoiceType | ToolChoiceConfig`).
|
|
195
|
+
*/
|
|
196
|
+
function convertToolChoiceToInteractionsConfig(toolChoice, hasTools) {
|
|
197
|
+
if (!hasTools || toolChoice === void 0) return;
|
|
198
|
+
if (typeof toolChoice === "object" && toolChoice !== null) {
|
|
199
|
+
if ("allowed_tools" in toolChoice) return toolChoice;
|
|
200
|
+
}
|
|
201
|
+
let mode;
|
|
202
|
+
let allowedFunctionNames;
|
|
203
|
+
let toolChoiceMode;
|
|
204
|
+
let toolChoiceFunction;
|
|
205
|
+
if (typeof toolChoice === "object" && toolChoice !== null) {
|
|
206
|
+
const obj = toolChoice;
|
|
207
|
+
toolChoiceMode = obj.mode;
|
|
208
|
+
toolChoiceFunction = obj.function?.name ?? obj.allowedFunctionNames;
|
|
209
|
+
} else if (typeof toolChoice === "string") toolChoiceMode = toolChoice;
|
|
210
|
+
const normalizedMode = toolChoiceMode?.toLowerCase();
|
|
211
|
+
if (normalizedMode === "auto") mode = "auto";
|
|
212
|
+
else if (normalizedMode === "any" || normalizedMode === "required") mode = "any";
|
|
213
|
+
else if (normalizedMode === "none") mode = "none";
|
|
214
|
+
else if (normalizedMode === "validated") mode = "validated";
|
|
215
|
+
else if (typeof toolChoiceMode === "string" && toolChoiceMode.length > 0) {
|
|
216
|
+
mode = "any";
|
|
217
|
+
toolChoiceFunction = toolChoiceMode;
|
|
218
|
+
}
|
|
219
|
+
if (toolChoiceFunction) allowedFunctionNames = Array.isArray(toolChoiceFunction) ? toolChoiceFunction : [toolChoiceFunction];
|
|
220
|
+
if (allowedFunctionNames && allowedFunctionNames.length > 0) return { allowed_tools: {
|
|
221
|
+
mode: mode ?? "any",
|
|
222
|
+
tools: allowedFunctionNames
|
|
223
|
+
} };
|
|
224
|
+
return mode;
|
|
225
|
+
}
|
|
226
|
+
exports.convertToolChoiceToInteractionsConfig = convertToolChoiceToInteractionsConfig;
|
|
227
|
+
exports.convertToolsToInteractionsTools = convertToolsToInteractionsTools;
|
|
228
|
+
|
|
229
|
+
//# sourceMappingURL=tools.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.cjs","names":["isOpenAITool","isLangChainTool","schemaToGeminiParameters","InvalidToolError"],"sources":["../../../src/converters/interactions/tools.ts"],"sourcesContent":["import { isLangChainTool } from \"@langchain/core/utils/function_calling\";\nimport { isOpenAITool } from \"@langchain/core/language_models/base\";\nimport { Converter } from \"@langchain/core/utils/format\";\nimport type {\n BindToolsInput,\n ToolChoice,\n} from \"@langchain/core/language_models/chat_models\";\nimport type { Gemini } from \"../../chat_models/types.js\";\nimport { InvalidToolError } from \"../../utils/errors.js\";\nimport { schemaToGeminiParameters } from \"../generate_content/tools.js\";\n\nconst INTERACTIONS_TOOL_TYPES = new Set([\n \"function\",\n \"google_search\",\n \"code_execution\",\n \"url_context\",\n \"computer_use\",\n \"file_search\",\n \"google_maps\",\n \"mcp_server\",\n \"retrieval\",\n]);\n\n/**\n * Type guard to check if a tool is already in Interactions API format.\n * Note: OpenAI tools also have `type: \"function\"`, so we exclude objects\n * that have an OpenAI-style nested `function` object.\n */\nfunction isInteractionsTool(\n tool: BindToolsInput\n): tool is Gemini.Interactions.Tool {\n if (typeof tool !== \"object\" || tool === null) {\n return false;\n }\n if (isOpenAITool(tool)) {\n return false;\n }\n if (!(\"type\" in tool) || typeof tool.type !== \"string\") {\n return false;\n }\n return INTERACTIONS_TOOL_TYPES.has(tool.type);\n}\n\n/**\n * Type guard to check if a tool is in GenerateContent `Gemini.Tool` format.\n */\nfunction isGenerateContentTool(tool: BindToolsInput): tool is Gemini.Tool {\n if (typeof tool !== \"object\" || tool === null) {\n return false;\n }\n\n const geminiToolAttributes = [\n \"functionDeclarations\",\n \"codeExecution\",\n \"googleSearch\",\n \"googleSearchRetrieval\",\n \"urlContext\",\n \"googleMaps\",\n \"fileSearch\",\n \"computerUse\",\n \"mcpServers\",\n \"retrieval\",\n ];\n\n return geminiToolAttributes.some((attr) => attr in tool);\n}\n\n/**\n * Converts a GenerateContent-formatted `Gemini.Tool` object into one or more\n * flat Interactions API `Gemini.Interactions.Tool` objects, translating\n * camelCase properties to snake_case where appropriate.\n */\nfunction convertGenerateContentToolToInteractionsTools(\n tool: Gemini.Tool & Record<string, unknown>\n): Gemini.Interactions.Tool[] {\n const results: Gemini.Interactions.Tool[] = [];\n\n if (\n \"functionDeclarations\" in tool &&\n Array.isArray(tool.functionDeclarations)\n ) {\n for (const decl of tool.functionDeclarations) {\n const parameters = (decl.parameters ?? decl.parametersJsonSchema) as\n | Record<string, unknown>\n | undefined;\n results.push({\n type: \"function\",\n name: decl.name ?? \"\",\n description: decl.description ?? \"A function available to call.\",\n ...(parameters ? { parameters } : {}),\n });\n }\n }\n\n if (\"googleSearch\" in tool && tool.googleSearch) {\n const gs = tool.googleSearch as Gemini.Tools.GoogleSearch &\n Record<string, unknown>;\n const searchTypes: Array<\n \"web_search\" | \"image_search\" | \"enterprise_web_search\"\n > = [];\n if (gs.searchTypes?.webSearch) {\n searchTypes.push(\"web_search\");\n }\n if (gs.searchTypes?.imageSearch) {\n searchTypes.push(\"image_search\");\n }\n const timeRangeFilter =\n (gs.time_range_filter as Gemini.Interactions.GoogleSearch[\"time_range_filter\"]) ??\n (gs.timeRangeFilter\n ? {\n start_time: gs.timeRangeFilter.startTime,\n end_time: gs.timeRangeFilter.endTime,\n }\n : undefined);\n\n results.push({\n type: \"google_search\",\n ...(searchTypes.length > 0 ? { search_types: searchTypes } : {}),\n ...(timeRangeFilter ? { time_range_filter: timeRangeFilter } : {}),\n });\n } else if (\"googleSearchRetrieval\" in tool) {\n results.push({\n type: \"google_search\",\n });\n }\n\n if (\"codeExecution\" in tool && tool.codeExecution) {\n results.push({\n type: \"code_execution\",\n });\n }\n\n if (\"urlContext\" in tool && tool.urlContext) {\n results.push({\n type: \"url_context\",\n });\n }\n\n if (\"googleMaps\" in tool && tool.googleMaps) {\n const gm = tool.googleMaps as Gemini.Tools.GoogleMaps &\n Record<string, unknown>;\n const enableWidget =\n (gm.enable_widget as boolean | undefined) ?? gm.enableWidget;\n results.push({\n type: \"google_maps\",\n ...(typeof enableWidget === \"boolean\"\n ? { enable_widget: enableWidget }\n : {}),\n ...(typeof gm.latitude === \"number\" ? { latitude: gm.latitude } : {}),\n ...(typeof gm.longitude === \"number\" ? { longitude: gm.longitude } : {}),\n });\n }\n\n if (\"fileSearch\" in tool && tool.fileSearch) {\n const fs = tool.fileSearch as Gemini.Tools.FileSearch &\n Record<string, unknown>;\n const storeNames =\n (fs.file_search_store_names as string[] | undefined) ??\n fs.fileSearchStoreNames;\n const topK = (fs.top_k as number | undefined) ?? fs.topK;\n const metadataFilter =\n (fs.metadata_filter as string | undefined) ?? fs.metadataFilter;\n results.push({\n type: \"file_search\",\n ...(storeNames ? { file_search_store_names: storeNames } : {}),\n ...(typeof topK === \"number\" ? { top_k: topK } : {}),\n ...(metadataFilter ? { metadata_filter: metadataFilter } : {}),\n });\n }\n\n if (\"computerUse\" in tool && tool.computerUse) {\n const cu = tool.computerUse as Gemini.Tools.ComputerUse &\n Record<string, unknown>;\n const rawEnv = cu.environment;\n const environment =\n rawEnv === \"ENVIRONMENT_BROWSER\" || rawEnv === \"browser\"\n ? (\"browser\" as const)\n : undefined;\n const excludedPredefinedFunctions =\n (cu.excluded_predefined_functions as string[] | undefined) ??\n cu.excludedPredefinedFunctions;\n results.push({\n type: \"computer_use\",\n ...(environment ? { environment } : {}),\n ...(excludedPredefinedFunctions\n ? { excluded_predefined_functions: excludedPredefinedFunctions }\n : {}),\n });\n }\n\n if (\"mcpServers\" in tool && Array.isArray(tool.mcpServers)) {\n for (const server of tool.mcpServers as Array<Record<string, unknown>>) {\n const transport = server.streamableHttpTransport as\n | Record<string, unknown>\n | undefined;\n const url = (server.url ?? transport?.url) as string | undefined;\n const headers = (server.headers ?? transport?.headers) as\n | Record<string, string>\n | undefined;\n const allowedTools = (server.allowed_tools ?? server.allowedTools) as\n | Gemini.Interactions.AllowedTools[]\n | undefined;\n results.push({\n type: \"mcp_server\",\n ...(typeof server.name === \"string\" ? { name: server.name } : {}),\n ...(url ? { url } : {}),\n ...(headers ? { headers } : {}),\n ...(allowedTools ? { allowed_tools: allowedTools } : {}),\n });\n }\n }\n\n if (\"retrieval\" in tool && tool.retrieval) {\n const ret = tool.retrieval as Record<string, unknown>;\n const vas = (ret.vertex_ai_search_config ?? ret.vertexAiSearch) as\n | Record<string, unknown>\n | undefined;\n const datastores = Array.isArray(vas?.datastores)\n ? (vas.datastores as string[])\n : typeof vas?.datastore === \"string\"\n ? [vas.datastore]\n : undefined;\n results.push({\n type: \"retrieval\",\n ...(vas\n ? {\n retrieval_types: [\"vertex_ai_search\"],\n vertex_ai_search_config: {\n ...(datastores ? { datastores } : {}),\n ...(typeof vas.engine === \"string\" ? { engine: vas.engine } : {}),\n },\n }\n : {}),\n });\n }\n\n return results;\n}\n\n/**\n * Converts an array of tools in any supported format (LangChain `StructuredTool`,\n * OpenAI tool, GenerateContent `Gemini.Tool`, raw `FunctionDeclaration`, or native\n * Interactions `Tool`) into flat `Gemini.Interactions.Tool[]` items.\n */\nexport const convertToolsToInteractionsTools: Converter<\n BindToolsInput[],\n Gemini.Interactions.Tool[]\n> = (tools) => {\n if (tools.length === 0) {\n return [];\n }\n\n const interactionsTools: Gemini.Interactions.Tool[] = [];\n\n for (const tool of tools) {\n if (isInteractionsTool(tool)) {\n interactionsTools.push(tool);\n continue;\n }\n\n if (isGenerateContentTool(tool)) {\n interactionsTools.push(\n ...convertGenerateContentToolToInteractionsTools(\n tool as Gemini.Tool & Record<string, unknown>\n )\n );\n continue;\n }\n\n if (isLangChainTool(tool)) {\n const jsonSchema = schemaToGeminiParameters(tool.schema);\n interactionsTools.push({\n type: \"function\",\n name: tool.name,\n description: tool.description ?? \"A function available to call.\",\n parameters: jsonSchema as unknown as Record<string, unknown>,\n });\n continue;\n }\n\n if (isOpenAITool(tool)) {\n interactionsTools.push({\n type: \"function\",\n name: tool.function.name,\n description:\n tool.function.description ?? \"A function available to call.\",\n parameters: tool.function.parameters\n ? (schemaToGeminiParameters(\n tool.function.parameters\n ) as unknown as Record<string, unknown>)\n : undefined,\n });\n continue;\n }\n\n if (\n typeof tool === \"object\" &&\n tool !== null &&\n \"name\" in tool &&\n typeof tool.name === \"string\"\n ) {\n const funcDecl = tool as Partial<Gemini.Tools.FunctionDeclaration>;\n interactionsTools.push({\n type: \"function\",\n name: funcDecl.name!,\n description: funcDecl.description ?? \"A function available to call.\",\n ...(funcDecl.parameters\n ? {\n parameters: funcDecl.parameters as unknown as Record<\n string,\n unknown\n >,\n }\n : {}),\n });\n continue;\n }\n\n throw new InvalidToolError(tool);\n }\n\n return interactionsTools;\n};\n\n/**\n * Converts LangChain's `tool_choice` option into the Interactions API\n * `generation_config.tool_choice` format (`ToolChoiceType | ToolChoiceConfig`).\n */\nexport function convertToolChoiceToInteractionsConfig(\n toolChoice: ToolChoice | undefined,\n hasTools: boolean\n): Gemini.Interactions.ToolChoice | undefined {\n if (!hasTools || toolChoice === undefined) {\n return undefined;\n }\n\n if (typeof toolChoice === \"object\" && toolChoice !== null) {\n if (\"allowed_tools\" in toolChoice) {\n return toolChoice as Gemini.Interactions.ToolChoiceConfig;\n }\n }\n\n let mode: Gemini.Interactions.ToolChoiceType | undefined;\n let allowedFunctionNames: string[] | undefined;\n\n let toolChoiceMode: string | undefined;\n let toolChoiceFunction: string | string[] | undefined;\n\n if (typeof toolChoice === \"object\" && toolChoice !== null) {\n const obj = toolChoice as {\n mode?: string;\n function?: { name?: string };\n allowedFunctionNames?: string[];\n };\n toolChoiceMode = obj.mode;\n toolChoiceFunction = obj.function?.name ?? obj.allowedFunctionNames;\n } else if (typeof toolChoice === \"string\") {\n toolChoiceMode = toolChoice;\n }\n\n const normalizedMode = toolChoiceMode?.toLowerCase();\n if (normalizedMode === \"auto\") {\n mode = \"auto\";\n } else if (normalizedMode === \"any\" || normalizedMode === \"required\") {\n mode = \"any\";\n } else if (normalizedMode === \"none\") {\n mode = \"none\";\n } else if (normalizedMode === \"validated\") {\n mode = \"validated\";\n } else if (typeof toolChoiceMode === \"string\" && toolChoiceMode.length > 0) {\n mode = \"any\";\n toolChoiceFunction = toolChoiceMode;\n }\n\n if (toolChoiceFunction) {\n allowedFunctionNames = Array.isArray(toolChoiceFunction)\n ? toolChoiceFunction\n : [toolChoiceFunction];\n }\n\n if (allowedFunctionNames && allowedFunctionNames.length > 0) {\n return {\n allowed_tools: {\n mode: mode ?? \"any\",\n tools: allowedFunctionNames,\n },\n };\n }\n\n return mode;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { InvalidToolError } from "../../utils/errors.js";
|
|
2
|
+
import { schemaToGeminiParameters } from "../generate_content/tools.js";
|
|
3
|
+
import { isLangChainTool } from "@langchain/core/utils/function_calling";
|
|
4
|
+
import { isOpenAITool } from "@langchain/core/language_models/base";
|
|
5
|
+
// src/converters/interactions/tools.ts
|
|
6
|
+
const INTERACTIONS_TOOL_TYPES = /* @__PURE__ */ new Set([
|
|
7
|
+
"function",
|
|
8
|
+
"google_search",
|
|
9
|
+
"code_execution",
|
|
10
|
+
"url_context",
|
|
11
|
+
"computer_use",
|
|
12
|
+
"file_search",
|
|
13
|
+
"google_maps",
|
|
14
|
+
"mcp_server",
|
|
15
|
+
"retrieval"
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Type guard to check if a tool is already in Interactions API format.
|
|
19
|
+
* Note: OpenAI tools also have `type: "function"`, so we exclude objects
|
|
20
|
+
* that have an OpenAI-style nested `function` object.
|
|
21
|
+
*/
|
|
22
|
+
function isInteractionsTool(tool) {
|
|
23
|
+
if (typeof tool !== "object" || tool === null) return false;
|
|
24
|
+
if (isOpenAITool(tool)) return false;
|
|
25
|
+
if (!("type" in tool) || typeof tool.type !== "string") return false;
|
|
26
|
+
return INTERACTIONS_TOOL_TYPES.has(tool.type);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Type guard to check if a tool is in GenerateContent `Gemini.Tool` format.
|
|
30
|
+
*/
|
|
31
|
+
function isGenerateContentTool(tool) {
|
|
32
|
+
if (typeof tool !== "object" || tool === null) return false;
|
|
33
|
+
return [
|
|
34
|
+
"functionDeclarations",
|
|
35
|
+
"codeExecution",
|
|
36
|
+
"googleSearch",
|
|
37
|
+
"googleSearchRetrieval",
|
|
38
|
+
"urlContext",
|
|
39
|
+
"googleMaps",
|
|
40
|
+
"fileSearch",
|
|
41
|
+
"computerUse",
|
|
42
|
+
"mcpServers",
|
|
43
|
+
"retrieval"
|
|
44
|
+
].some((attr) => attr in tool);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Converts a GenerateContent-formatted `Gemini.Tool` object into one or more
|
|
48
|
+
* flat Interactions API `Gemini.Interactions.Tool` objects, translating
|
|
49
|
+
* camelCase properties to snake_case where appropriate.
|
|
50
|
+
*/
|
|
51
|
+
function convertGenerateContentToolToInteractionsTools(tool) {
|
|
52
|
+
const results = [];
|
|
53
|
+
if ("functionDeclarations" in tool && Array.isArray(tool.functionDeclarations)) for (const decl of tool.functionDeclarations) {
|
|
54
|
+
const parameters = decl.parameters ?? decl.parametersJsonSchema;
|
|
55
|
+
results.push({
|
|
56
|
+
type: "function",
|
|
57
|
+
name: decl.name ?? "",
|
|
58
|
+
description: decl.description ?? "A function available to call.",
|
|
59
|
+
...parameters ? { parameters } : {}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if ("googleSearch" in tool && tool.googleSearch) {
|
|
63
|
+
const gs = tool.googleSearch;
|
|
64
|
+
const searchTypes = [];
|
|
65
|
+
if (gs.searchTypes?.webSearch) searchTypes.push("web_search");
|
|
66
|
+
if (gs.searchTypes?.imageSearch) searchTypes.push("image_search");
|
|
67
|
+
const timeRangeFilter = gs.time_range_filter ?? (gs.timeRangeFilter ? {
|
|
68
|
+
start_time: gs.timeRangeFilter.startTime,
|
|
69
|
+
end_time: gs.timeRangeFilter.endTime
|
|
70
|
+
} : void 0);
|
|
71
|
+
results.push({
|
|
72
|
+
type: "google_search",
|
|
73
|
+
...searchTypes.length > 0 ? { search_types: searchTypes } : {},
|
|
74
|
+
...timeRangeFilter ? { time_range_filter: timeRangeFilter } : {}
|
|
75
|
+
});
|
|
76
|
+
} else if ("googleSearchRetrieval" in tool) results.push({ type: "google_search" });
|
|
77
|
+
if ("codeExecution" in tool && tool.codeExecution) results.push({ type: "code_execution" });
|
|
78
|
+
if ("urlContext" in tool && tool.urlContext) results.push({ type: "url_context" });
|
|
79
|
+
if ("googleMaps" in tool && tool.googleMaps) {
|
|
80
|
+
const gm = tool.googleMaps;
|
|
81
|
+
const enableWidget = gm.enable_widget ?? gm.enableWidget;
|
|
82
|
+
results.push({
|
|
83
|
+
type: "google_maps",
|
|
84
|
+
...typeof enableWidget === "boolean" ? { enable_widget: enableWidget } : {},
|
|
85
|
+
...typeof gm.latitude === "number" ? { latitude: gm.latitude } : {},
|
|
86
|
+
...typeof gm.longitude === "number" ? { longitude: gm.longitude } : {}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if ("fileSearch" in tool && tool.fileSearch) {
|
|
90
|
+
const fs = tool.fileSearch;
|
|
91
|
+
const storeNames = fs.file_search_store_names ?? fs.fileSearchStoreNames;
|
|
92
|
+
const topK = fs.top_k ?? fs.topK;
|
|
93
|
+
const metadataFilter = fs.metadata_filter ?? fs.metadataFilter;
|
|
94
|
+
results.push({
|
|
95
|
+
type: "file_search",
|
|
96
|
+
...storeNames ? { file_search_store_names: storeNames } : {},
|
|
97
|
+
...typeof topK === "number" ? { top_k: topK } : {},
|
|
98
|
+
...metadataFilter ? { metadata_filter: metadataFilter } : {}
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
if ("computerUse" in tool && tool.computerUse) {
|
|
102
|
+
const cu = tool.computerUse;
|
|
103
|
+
const rawEnv = cu.environment;
|
|
104
|
+
const environment = rawEnv === "ENVIRONMENT_BROWSER" || rawEnv === "browser" ? "browser" : void 0;
|
|
105
|
+
const excludedPredefinedFunctions = cu.excluded_predefined_functions ?? cu.excludedPredefinedFunctions;
|
|
106
|
+
results.push({
|
|
107
|
+
type: "computer_use",
|
|
108
|
+
...environment ? { environment } : {},
|
|
109
|
+
...excludedPredefinedFunctions ? { excluded_predefined_functions: excludedPredefinedFunctions } : {}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
if ("mcpServers" in tool && Array.isArray(tool.mcpServers)) for (const server of tool.mcpServers) {
|
|
113
|
+
const transport = server.streamableHttpTransport;
|
|
114
|
+
const url = server.url ?? transport?.url;
|
|
115
|
+
const headers = server.headers ?? transport?.headers;
|
|
116
|
+
const allowedTools = server.allowed_tools ?? server.allowedTools;
|
|
117
|
+
results.push({
|
|
118
|
+
type: "mcp_server",
|
|
119
|
+
...typeof server.name === "string" ? { name: server.name } : {},
|
|
120
|
+
...url ? { url } : {},
|
|
121
|
+
...headers ? { headers } : {},
|
|
122
|
+
...allowedTools ? { allowed_tools: allowedTools } : {}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
if ("retrieval" in tool && tool.retrieval) {
|
|
126
|
+
const ret = tool.retrieval;
|
|
127
|
+
const vas = ret.vertex_ai_search_config ?? ret.vertexAiSearch;
|
|
128
|
+
const datastores = Array.isArray(vas?.datastores) ? vas.datastores : typeof vas?.datastore === "string" ? [vas.datastore] : void 0;
|
|
129
|
+
results.push({
|
|
130
|
+
type: "retrieval",
|
|
131
|
+
...vas ? {
|
|
132
|
+
retrieval_types: ["vertex_ai_search"],
|
|
133
|
+
vertex_ai_search_config: {
|
|
134
|
+
...datastores ? { datastores } : {},
|
|
135
|
+
...typeof vas.engine === "string" ? { engine: vas.engine } : {}
|
|
136
|
+
}
|
|
137
|
+
} : {}
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return results;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Converts an array of tools in any supported format (LangChain `StructuredTool`,
|
|
144
|
+
* OpenAI tool, GenerateContent `Gemini.Tool`, raw `FunctionDeclaration`, or native
|
|
145
|
+
* Interactions `Tool`) into flat `Gemini.Interactions.Tool[]` items.
|
|
146
|
+
*/
|
|
147
|
+
const convertToolsToInteractionsTools = (tools) => {
|
|
148
|
+
if (tools.length === 0) return [];
|
|
149
|
+
const interactionsTools = [];
|
|
150
|
+
for (const tool of tools) {
|
|
151
|
+
if (isInteractionsTool(tool)) {
|
|
152
|
+
interactionsTools.push(tool);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (isGenerateContentTool(tool)) {
|
|
156
|
+
interactionsTools.push(...convertGenerateContentToolToInteractionsTools(tool));
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (isLangChainTool(tool)) {
|
|
160
|
+
const jsonSchema = schemaToGeminiParameters(tool.schema);
|
|
161
|
+
interactionsTools.push({
|
|
162
|
+
type: "function",
|
|
163
|
+
name: tool.name,
|
|
164
|
+
description: tool.description ?? "A function available to call.",
|
|
165
|
+
parameters: jsonSchema
|
|
166
|
+
});
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (isOpenAITool(tool)) {
|
|
170
|
+
interactionsTools.push({
|
|
171
|
+
type: "function",
|
|
172
|
+
name: tool.function.name,
|
|
173
|
+
description: tool.function.description ?? "A function available to call.",
|
|
174
|
+
parameters: tool.function.parameters ? schemaToGeminiParameters(tool.function.parameters) : void 0
|
|
175
|
+
});
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (typeof tool === "object" && tool !== null && "name" in tool && typeof tool.name === "string") {
|
|
179
|
+
const funcDecl = tool;
|
|
180
|
+
interactionsTools.push({
|
|
181
|
+
type: "function",
|
|
182
|
+
name: funcDecl.name,
|
|
183
|
+
description: funcDecl.description ?? "A function available to call.",
|
|
184
|
+
...funcDecl.parameters ? { parameters: funcDecl.parameters } : {}
|
|
185
|
+
});
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
throw new InvalidToolError(tool);
|
|
189
|
+
}
|
|
190
|
+
return interactionsTools;
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Converts LangChain's `tool_choice` option into the Interactions API
|
|
194
|
+
* `generation_config.tool_choice` format (`ToolChoiceType | ToolChoiceConfig`).
|
|
195
|
+
*/
|
|
196
|
+
function convertToolChoiceToInteractionsConfig(toolChoice, hasTools) {
|
|
197
|
+
if (!hasTools || toolChoice === void 0) return;
|
|
198
|
+
if (typeof toolChoice === "object" && toolChoice !== null) {
|
|
199
|
+
if ("allowed_tools" in toolChoice) return toolChoice;
|
|
200
|
+
}
|
|
201
|
+
let mode;
|
|
202
|
+
let allowedFunctionNames;
|
|
203
|
+
let toolChoiceMode;
|
|
204
|
+
let toolChoiceFunction;
|
|
205
|
+
if (typeof toolChoice === "object" && toolChoice !== null) {
|
|
206
|
+
const obj = toolChoice;
|
|
207
|
+
toolChoiceMode = obj.mode;
|
|
208
|
+
toolChoiceFunction = obj.function?.name ?? obj.allowedFunctionNames;
|
|
209
|
+
} else if (typeof toolChoice === "string") toolChoiceMode = toolChoice;
|
|
210
|
+
const normalizedMode = toolChoiceMode?.toLowerCase();
|
|
211
|
+
if (normalizedMode === "auto") mode = "auto";
|
|
212
|
+
else if (normalizedMode === "any" || normalizedMode === "required") mode = "any";
|
|
213
|
+
else if (normalizedMode === "none") mode = "none";
|
|
214
|
+
else if (normalizedMode === "validated") mode = "validated";
|
|
215
|
+
else if (typeof toolChoiceMode === "string" && toolChoiceMode.length > 0) {
|
|
216
|
+
mode = "any";
|
|
217
|
+
toolChoiceFunction = toolChoiceMode;
|
|
218
|
+
}
|
|
219
|
+
if (toolChoiceFunction) allowedFunctionNames = Array.isArray(toolChoiceFunction) ? toolChoiceFunction : [toolChoiceFunction];
|
|
220
|
+
if (allowedFunctionNames && allowedFunctionNames.length > 0) return { allowed_tools: {
|
|
221
|
+
mode: mode ?? "any",
|
|
222
|
+
tools: allowedFunctionNames
|
|
223
|
+
} };
|
|
224
|
+
return mode;
|
|
225
|
+
}
|
|
226
|
+
export { convertToolChoiceToInteractionsConfig, convertToolsToInteractionsTools };
|
|
227
|
+
|
|
228
|
+
//# sourceMappingURL=tools.js.map
|