@langchain/google 0.2.9 → 0.2.10

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.
@@ -290,6 +290,7 @@ const convertToolsToGeminiTools = (tools) => {
290
290
  * - `"auto"` → `"AUTO"` - Model decides whether to call functions
291
291
  * - `"any"` or `"required"` → `"ANY"` - Model must call at least one function
292
292
  * - `"none"` → `"NONE"` - Model cannot call functions
293
+ * - `"validated"` → `"VALIDATED"` - Calls must follow the function schema
293
294
  * - Function name string → `"ANY"` - Forces function use
294
295
  * - Object with `mode` → Maps the mode string to Gemini format
295
296
  * - Object with `function` → `"ANY"` - Forces function use
@@ -299,6 +300,8 @@ const convertToolsToGeminiTools = (tools) => {
299
300
  * - **AUTO**: The model can choose whether to call functions based on the conversation
300
301
  * - **ANY**: The model must call at least one function before responding
301
302
  * - **NONE**: The model cannot call any functions
303
+ * - **VALIDATED**: The model may call functions or respond with text, and function
304
+ * calls must follow the provided schema
302
305
  *
303
306
  * When a specific function is requested (via function name string or `{ function: { name } }`),
304
307
  * the converter uses `"ANY"` mode to force function usage, as Gemini doesn't support
@@ -337,9 +340,11 @@ function convertToolChoiceToGeminiConfig(toolChoice, hasTools) {
337
340
  toolChoiceMode = toolChoice.mode;
338
341
  toolChoiceFunction = toolChoice.function?.name;
339
342
  } else toolChoiceMode = toolChoice;
340
- if (toolChoiceMode === "auto") mode = "AUTO";
341
- else if (toolChoiceMode === "any" || toolChoiceMode === "required") mode = "ANY";
342
- else if (toolChoiceMode === "none") mode = "NONE";
343
+ const normalizedMode = toolChoiceMode?.toLowerCase();
344
+ if (normalizedMode === "auto") mode = "AUTO";
345
+ else if (normalizedMode === "any" || normalizedMode === "required") mode = "ANY";
346
+ else if (normalizedMode === "none") mode = "NONE";
347
+ else if (normalizedMode === "validated") mode = "VALIDATED";
343
348
  else if (typeof toolChoiceMode === "string") {
344
349
  mode = "ANY";
345
350
  toolChoiceFunction = toolChoiceMode;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","names":[],"sources":["../../src/converters/tools.ts"],"sourcesContent":["import { isLangChainTool } from \"@langchain/core/utils/function_calling\";\nimport { isOpenAITool } from \"@langchain/core/language_models/base\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type JsonSchema7Type,\n toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\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 { InvalidInputError, InvalidToolError } from \"../utils/errors.js\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\n\n/**\n * Adjusts a JSON Schema object type to be compatible with Gemini's function schema format.\n *\n * Gemini's function schema format has specific requirements:\n * - Type must be a string, not an array\n * - Nullable types should use the `nullable` property instead of including \"null\" in a type array\n * - Union types are not supported\n *\n * @param obj - The JSON Schema object to adjust\n * @returns The adjusted object with type converted to Gemini-compatible format\n * @throws {Error} If the type is a union type or null-only type, which Gemini cannot handle\n *\n * @internal\n */\nfunction adjustObjectType(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n obj: Record<string, any>\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> {\n if (!Array.isArray(obj.type)) {\n return obj;\n }\n\n const len = obj.type.length;\n const nullIndex = obj.type.indexOf(\"null\");\n if (len === 2 && nullIndex >= 0) {\n // There are only two values set for the type, and one of them is \"null\".\n // Set the type to the other one and set nullable to true.\n const typeIndex = nullIndex === 0 ? 1 : 0;\n obj.type = obj.type[typeIndex];\n obj.nullable = true;\n } else if (len === 1 && nullIndex === 0) {\n // This is nullable only without a type, which doesn't make sense for Gemini\n throw new InvalidInputError(\n \"Gemini does not support null-only types in function schemas. Provide a non-null type alongside nullable.\"\n );\n } else if (len === 1) {\n // Although an array, it has only one value.\n // So set it to the string to match what Gemini expects.\n obj.type = obj?.type[0];\n } else if (len === 0) {\n // Empty type array is invalid\n throw new InvalidInputError(\n \"Gemini does not support empty type arrays in function schemas. Provide at least one type.\"\n );\n } else {\n // Anything else could be a union type, so reject it.\n throw new InvalidInputError(\n \"Gemini does not support union types in function schemas. Use a single type instead.\"\n );\n }\n return obj;\n}\n\n// Keywords Gemini's function schema accepts. Keep in sync with Gemini.Tools.Schema (api-types.ts); anything else 400s (#8584).\nconst GEMINI_SCHEMA_KEYS = new Set([\n \"anyOf\",\n \"default\",\n \"description\",\n \"enum\",\n \"example\",\n \"format\",\n \"items\",\n \"maxItems\",\n \"maxLength\",\n \"maxProperties\",\n \"maximum\",\n \"minItems\",\n \"minLength\",\n \"minProperties\",\n \"minimum\",\n \"nullable\",\n \"pattern\",\n \"properties\",\n \"propertyOrdering\",\n \"required\",\n \"title\",\n \"type\",\n]);\n\n// Recursively allowlist-filters a schema node; `properties`' own keys are user field names, not schema keywords, so only its values recurse.\nfunction sanitizeGeminiSchema(node: unknown): unknown {\n if (Array.isArray(node)) {\n return node.map(sanitizeGeminiSchema);\n }\n if (typeof node !== \"object\" || node === null) {\n return node;\n }\n\n if (\"$ref\" in node) {\n throw new InvalidInputError(\n \"Gemini does not support recursive or referenced ($ref) schemas in function or response schemas. Inline the schema instead.\"\n );\n }\n\n const source = node as Record<string, unknown>;\n const schema: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n if (GEMINI_SCHEMA_KEYS.has(key)) {\n schema[key] = source[key];\n }\n }\n\n adjustObjectType(schema);\n\n if (schema.properties && typeof schema.properties === \"object\") {\n // fromEntries defines properties (safe for a field literally named \"__proto__\"), unlike bracket assignment on a plain {}.\n schema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([name, value]) => [\n name,\n sanitizeGeminiSchema(value),\n ])\n );\n }\n if (schema.items !== undefined) {\n schema.items = sanitizeGeminiSchema(schema.items);\n }\n if (Array.isArray(schema.anyOf)) {\n schema.anyOf = schema.anyOf.map(sanitizeGeminiSchema);\n }\n\n return schema;\n}\n\n/**\n * Converts a Zod schema or JSON Schema to Gemini function parameters format.\n *\n * This function handles the conversion of schema definitions from various formats\n * (Zod schemas, JSON Schema 7) to Gemini's function schema format. It removes\n * unsupported properties and adjusts type definitions to be compatible with Gemini.\n *\n * @param schema - The schema to convert (Zod schema or JSON Schema 7)\n * @returns A schema object compatible with Gemini's API\n *\n * @internal\n */\nexport function schemaToGeminiParameters<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n schema:\n | SerializableSchema<RunOutput>\n | InteropZodType<RunOutput>\n | JsonSchema7Type\n): Gemini.Tools.Schema {\n return sanitizeGeminiSchema(\n isInteropZodSchema(schema) || isSerializableSchema(schema)\n ? toJsonSchema(schema)\n : schema\n ) as Gemini.Tools.Schema;\n}\n\n/**\n * Converts a JSON Schema object to Gemini function parameters format.\n *\n * @param schema - The JSON Schema object to convert\n * @returns A schema object compatible with Gemini's API\n *\n * @internal\n */\nfunction jsonSchemaToGeminiParameters(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>\n): Gemini.Tools.Schema {\n return sanitizeGeminiSchema(schema) as Gemini.Tools.Schema;\n}\n\n/**\n * Type guard to check if a tool is already in Gemini's native format.\n *\n * Gemini tools can be:\n * - Function declarations (`functionDeclarations`)\n * - Code execution tools (`codeExecution`)\n * - Google Search retrieval tools (`googleSearchRetrieval` or `googleSearch`)\n *\n * The full list of tool types are those defined by the `Gemini.Tool` type.\n * Updating that list requires a change to the `geminiToolAttributes` below.\n *\n * @param tool - The tool to check\n * @returns `true` if the tool is already in Gemini format, `false` otherwise\n *\n * @internal\n */\nfunction isGeminiTool(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 \"urlContext\",\n \"googleMaps\",\n \"fileSearch\",\n \"computerUse\",\n \"mcpServers\",\n ];\n\n return geminiToolAttributes.some((attr) => attr in tool);\n}\n\n/**\n * Converts an array of LangChain tools to Gemini function declarations.\n *\n * This converter transforms various tool formats into Gemini's function declaration\n * format. It supports:\n * - LangChain structured tools (with Zod schemas)\n * - OpenAI format tools (with JSON Schema)\n * - Gemini-native function declarations (passed through)\n * - Raw function declaration objects\n *\n * @remarks\n * The converter handles each tool type differently:\n * - **LangChain tools**: Extracts name, description, and schema, converting the schema\n * to Gemini-compatible format\n * - **OpenAI tools**: Extracts function name, description, and parameters from the\n * OpenAI tool format\n * - **Gemini tools**: If the tool contains `functionDeclarations`, extracts and returns\n * them directly. Non-function Gemini tools (like `codeExecution`) are skipped.\n * - **Raw objects**: Assumes the object is a function declaration and validates it has\n * a `name` property\n *\n * @example\n * ```typescript\n * import { StructuredTool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const weatherTool = new StructuredTool({\n * name: \"get_weather\",\n * description: \"Get the weather for a location\",\n * schema: z.object({\n * location: z.string().describe(\"The city name\"),\n * unit: z.enum([\"celsius\", \"fahrenheit\"]).optional()\n * }),\n * func: async (args) => { /* ... *\\/ }\n * });\n *\n * const declarations = convertToolsToGeminiFunctionDeclarations([weatherTool]);\n * // Returns: [{\n * // name: \"get_weather\",\n * // description: \"Get the weather for a location\",\n * // parameters: {\n * // type: \"object\",\n * // properties: {\n * // location: { type: \"string\", description: \"The city name\" },\n * // unit: { type: \"string\", enum: [\"celsius\", \"fahrenheit\"], nullable: true }\n * // },\n * // required: [\"location\"]\n * // }\n * // }]\n * ```\n *\n * @param tools - Array of tools in various formats (LangChain, OpenAI, or Gemini)\n * @returns Array of Gemini function declarations ready for API submission\n * @throws {Error} If a tool cannot be converted (invalid format)\n */\nexport const convertToolsToGeminiFunctionDeclarations: Converter<\n BindToolsInput[],\n Gemini.Tools.FunctionDeclaration[]\n> = (tools) => {\n const functionDeclarations: Gemini.Tools.FunctionDeclaration[] = [];\n\n for (const tool of tools) {\n // Skip if already in Gemini format (non-function tools)\n if (isGeminiTool(tool) && !(\"functionDeclarations\" in tool)) {\n continue;\n }\n\n // Handle Gemini format with functionDeclarations\n if (\n isGeminiTool(tool) &&\n \"functionDeclarations\" in tool &&\n Array.isArray(tool.functionDeclarations)\n ) {\n functionDeclarations.push(...tool.functionDeclarations);\n continue;\n }\n\n // Handle LangChain structured tools\n if (isLangChainTool(tool)) {\n const jsonSchema = schemaToGeminiParameters(tool.schema);\n functionDeclarations.push({\n name: tool.name,\n description: tool.description ?? `A function available to call.`,\n parameters: jsonSchema,\n });\n continue;\n }\n\n // Handle OpenAI format tools\n if (isOpenAITool(tool)) {\n functionDeclarations.push({\n name: tool.function.name,\n description:\n tool.function.description ?? `A function available to call.`,\n parameters: jsonSchemaToGeminiParameters(tool.function.parameters),\n });\n continue;\n }\n\n // Handle raw function declaration objects\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 functionDeclarations.push({\n name: funcDecl.name!,\n description: funcDecl.description ?? `A function available to call.`,\n parameters: funcDecl.parameters,\n });\n continue;\n }\n\n throw new InvalidToolError(tool);\n }\n\n return functionDeclarations;\n};\n\n/**\n * Converts an array of tools to Gemini's Tools array format.\n *\n * This converter groups function declarations into a single tool object while\n * preserving Gemini-native tools (like code execution and Google Search retrieval)\n * as separate tool objects. This matches Gemini's API structure where:\n * - Function declarations are grouped together in a single tool\n * - Non-function tools (codeExecution, googleSearchRetrieval) are separate tools\n *\n * @remarks\n * The conversion process:\n * 1. Separates Gemini-native tools from function declarations\n * 2. Converts LangChain/OpenAI tools to function declarations\n * 3. Groups all function declarations into a single Tool object\n * 4. Returns an array with the grouped function declarations tool plus any\n * non-function Gemini tools\n *\n * @example\n * ```typescript\n * import { StructuredTool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const weatherTool = new StructuredTool({\n * name: \"get_weather\",\n * description: \"Get the weather\",\n * schema: z.object({ location: z.string() }),\n * func: async () => {}\n * });\n *\n * const geminiCodeTool: Gemini.Tool = {\n * codeExecution: { enabled: true }\n * };\n *\n * const tools = convertToolsToGeminiTools([weatherTool, geminiCodeTool]);\n * // Returns: [\n * // { functionDeclarations: [{ name: \"get_weather\", ... }] },\n * // { codeExecution: { enabled: true } }\n * // ]\n * ```\n *\n * @param tools - Array of tools in various formats (LangChain, OpenAI, or Gemini)\n * @returns Array of Tool objects ready for API submission\n */\nexport const convertToolsToGeminiTools: Converter<\n BindToolsInput[],\n Gemini.Tool[]\n> = (tools) => {\n if (tools.length === 0) {\n return [];\n }\n\n const geminiTools: Gemini.Tool[] = [];\n const functionDeclarations: Gemini.Tools.FunctionDeclaration[] = [];\n\n // Separate Gemini-native tools from function declarations\n for (const tool of tools) {\n if (isGeminiTool(tool)) {\n if (\"functionDeclarations\" in tool) {\n // Already a Gemini tool with function declarations\n geminiTools.push(tool);\n } else {\n // Non-function Gemini tool (codeExecution, googleSearch, etc.)\n geminiTools.push(tool);\n }\n } else if (\"googleSearchRetrieval\" in tool) {\n // Convert the obsolete search into the modern one\n const searchTool: Gemini.Tool = {\n googleSearch: {},\n };\n geminiTools.push(searchTool);\n } else {\n // Convert to function declaration\n const funcDecls = convertToolsToGeminiFunctionDeclarations([tool]);\n functionDeclarations.push(...funcDecls);\n }\n }\n\n // Add function declarations as a single tool if we have any\n if (functionDeclarations.length > 0) {\n geminiTools.push({\n functionDeclarations,\n });\n }\n\n return geminiTools;\n};\n\n/**\n * Converts tool choice to Gemini's function calling configuration.\n *\n * This converter transforms LangChain's tool choice format into Gemini's\n * `toolConfig.functionCallingConfig` format. The configuration is only\n * created when tools are present (`hasTools` is true).\n *\n * @remarks\n * The conversion logic:\n * - If `hasTools` is `false`, returns `undefined` (no config needed)\n * - If `toolChoice` is provided, converts it to a Gemini mode:\n * - `\"auto\"` → `\"AUTO\"` - Model decides whether to call functions\n * - `\"any\"` or `\"required\"` → `\"ANY\"` - Model must call at least one function\n * - `\"none\"` → `\"NONE\"` - Model cannot call functions\n * - Function name string → `\"ANY\"` - Forces function use\n * - Object with `mode` → Maps the mode string to Gemini format\n * - Object with `function` → `\"ANY\"` - Forces function use\n * - If `toolChoice` is not provided but tools exist, defaults to `\"AUTO\"`\n *\n * Gemini's function calling modes:\n * - **AUTO**: The model can choose whether to call functions based on the conversation\n * - **ANY**: The model must call at least one function before responding\n * - **NONE**: The model cannot call any functions\n *\n * When a specific function is requested (via function name string or `{ function: { name } }`),\n * the converter uses `\"ANY\"` mode to force function usage, as Gemini doesn't support\n * specifying individual functions in the mode.\n *\n * @example\n * ```typescript\n * // With explicit tool choice\n * convertToolChoiceToGeminiConfig(\"auto\", true);\n * // Returns: { functionCallingConfig: { mode: \"AUTO\" } }\n *\n * // Required mode - must call a function\n * convertToolChoiceToGeminiConfig(\"any\", true);\n * // Returns: { functionCallingConfig: { mode: \"ANY\" } }\n *\n * // Without tool choice (defaults to AUTO when tools exist)\n * convertToolChoiceToGeminiConfig(undefined, true);\n * // Returns: { functionCallingConfig: { mode: \"AUTO\" } }\n *\n * // No tools - returns undefined\n * convertToolChoiceToGeminiConfig(\"auto\", false);\n * // Returns: undefined\n * ```\n *\n * @param toolChoice - The tool choice option from LangChain (string, object, or undefined)\n * @param hasTools - Whether tools are present. If false, returns undefined\n * @returns The Gemini tool configuration object, or undefined if no tools are present\n */\nexport function convertToolChoiceToGeminiConfig(\n toolChoice: ToolChoice | undefined,\n hasTools: boolean\n): Gemini.Tools.ToolConfig | undefined {\n if (!hasTools || toolChoice === undefined) {\n return undefined;\n }\n\n let mode: Gemini.Tools.FunctionCallingConfigMode | undefined;\n let allowedFunctionNames: string[] | undefined;\n\n let toolChoiceMode: string | undefined;\n let toolChoiceFunction: string | string[] | undefined;\n if (typeof toolChoice === \"object\") {\n toolChoiceMode = toolChoice.mode;\n toolChoiceFunction = toolChoice.function?.name;\n } else {\n toolChoiceMode = toolChoice;\n }\n\n if (toolChoiceMode === \"auto\") {\n mode = \"AUTO\";\n } else if (toolChoiceMode === \"any\" || toolChoiceMode === \"required\") {\n mode = \"ANY\";\n } else if (toolChoiceMode === \"none\") {\n mode = \"NONE\";\n } else if (typeof toolChoiceMode === \"string\") {\n mode = \"ANY\";\n toolChoiceFunction = toolChoiceMode;\n }\n\n if (toolChoiceFunction) {\n if (Array.isArray(toolChoiceFunction)) {\n allowedFunctionNames = toolChoiceFunction;\n } else {\n allowedFunctionNames = [toolChoiceFunction];\n }\n }\n\n const functionCallingConfig: Gemini.Tools.FunctionCallingConfig = {};\n if (allowedFunctionNames?.length) {\n functionCallingConfig.allowedFunctionNames = allowedFunctionNames;\n }\n if (mode) {\n functionCallingConfig.mode = mode;\n }\n return {\n functionCallingConfig,\n };\n}\n\n/**\n * Checks whether a tools array mixes server-side built-in tools (e.g.\n * `googleSearch`, `codeExecution`) with function-declaration tools.\n *\n * Gemini rejects such a mix with a 400 unless\n * `toolConfig.includeServerSideToolInvocations` is set.\n * See https://ai.google.dev/gemini-api/docs/tool-combination\n */\nexport function mixesBuiltinAndFunctionTools(tools: Gemini.Tool[]): boolean {\n const isFunctionDeclarationTool = (tool: Gemini.Tool) =>\n \"functionDeclarations\" in tool && !!tool.functionDeclarations?.length;\n return (\n tools.some(isFunctionDeclarationTool) &&\n tools.some((tool) => !isFunctionDeclarationTool(tool))\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","names":[],"sources":["../../src/converters/tools.ts"],"sourcesContent":["import { isLangChainTool } from \"@langchain/core/utils/function_calling\";\nimport { isOpenAITool } from \"@langchain/core/language_models/base\";\nimport {\n InteropZodType,\n isInteropZodSchema,\n} from \"@langchain/core/utils/types\";\nimport {\n type JsonSchema7Type,\n toJsonSchema,\n} from \"@langchain/core/utils/json_schema\";\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 { InvalidInputError, InvalidToolError } from \"../utils/errors.js\";\nimport {\n isSerializableSchema,\n SerializableSchema,\n} from \"@langchain/core/utils/standard_schema\";\n\n/**\n * Adjusts a JSON Schema object type to be compatible with Gemini's function schema format.\n *\n * Gemini's function schema format has specific requirements:\n * - Type must be a string, not an array\n * - Nullable types should use the `nullable` property instead of including \"null\" in a type array\n * - Union types are not supported\n *\n * @param obj - The JSON Schema object to adjust\n * @returns The adjusted object with type converted to Gemini-compatible format\n * @throws {Error} If the type is a union type or null-only type, which Gemini cannot handle\n *\n * @internal\n */\nfunction adjustObjectType(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n obj: Record<string, any>\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n): Record<string, any> {\n if (!Array.isArray(obj.type)) {\n return obj;\n }\n\n const len = obj.type.length;\n const nullIndex = obj.type.indexOf(\"null\");\n if (len === 2 && nullIndex >= 0) {\n // There are only two values set for the type, and one of them is \"null\".\n // Set the type to the other one and set nullable to true.\n const typeIndex = nullIndex === 0 ? 1 : 0;\n obj.type = obj.type[typeIndex];\n obj.nullable = true;\n } else if (len === 1 && nullIndex === 0) {\n // This is nullable only without a type, which doesn't make sense for Gemini\n throw new InvalidInputError(\n \"Gemini does not support null-only types in function schemas. Provide a non-null type alongside nullable.\"\n );\n } else if (len === 1) {\n // Although an array, it has only one value.\n // So set it to the string to match what Gemini expects.\n obj.type = obj?.type[0];\n } else if (len === 0) {\n // Empty type array is invalid\n throw new InvalidInputError(\n \"Gemini does not support empty type arrays in function schemas. Provide at least one type.\"\n );\n } else {\n // Anything else could be a union type, so reject it.\n throw new InvalidInputError(\n \"Gemini does not support union types in function schemas. Use a single type instead.\"\n );\n }\n return obj;\n}\n\n// Keywords Gemini's function schema accepts. Keep in sync with Gemini.Tools.Schema (api-types.ts); anything else 400s (#8584).\nconst GEMINI_SCHEMA_KEYS = new Set([\n \"anyOf\",\n \"default\",\n \"description\",\n \"enum\",\n \"example\",\n \"format\",\n \"items\",\n \"maxItems\",\n \"maxLength\",\n \"maxProperties\",\n \"maximum\",\n \"minItems\",\n \"minLength\",\n \"minProperties\",\n \"minimum\",\n \"nullable\",\n \"pattern\",\n \"properties\",\n \"propertyOrdering\",\n \"required\",\n \"title\",\n \"type\",\n]);\n\n// Recursively allowlist-filters a schema node; `properties`' own keys are user field names, not schema keywords, so only its values recurse.\nfunction sanitizeGeminiSchema(node: unknown): unknown {\n if (Array.isArray(node)) {\n return node.map(sanitizeGeminiSchema);\n }\n if (typeof node !== \"object\" || node === null) {\n return node;\n }\n\n if (\"$ref\" in node) {\n throw new InvalidInputError(\n \"Gemini does not support recursive or referenced ($ref) schemas in function or response schemas. Inline the schema instead.\"\n );\n }\n\n const source = node as Record<string, unknown>;\n const schema: Record<string, unknown> = {};\n for (const key of Object.keys(source)) {\n if (GEMINI_SCHEMA_KEYS.has(key)) {\n schema[key] = source[key];\n }\n }\n\n adjustObjectType(schema);\n\n if (schema.properties && typeof schema.properties === \"object\") {\n // fromEntries defines properties (safe for a field literally named \"__proto__\"), unlike bracket assignment on a plain {}.\n schema.properties = Object.fromEntries(\n Object.entries(schema.properties).map(([name, value]) => [\n name,\n sanitizeGeminiSchema(value),\n ])\n );\n }\n if (schema.items !== undefined) {\n schema.items = sanitizeGeminiSchema(schema.items);\n }\n if (Array.isArray(schema.anyOf)) {\n schema.anyOf = schema.anyOf.map(sanitizeGeminiSchema);\n }\n\n return schema;\n}\n\n/**\n * Converts a Zod schema or JSON Schema to Gemini function parameters format.\n *\n * This function handles the conversion of schema definitions from various formats\n * (Zod schemas, JSON Schema 7) to Gemini's function schema format. It removes\n * unsupported properties and adjusts type definitions to be compatible with Gemini.\n *\n * @param schema - The schema to convert (Zod schema or JSON Schema 7)\n * @returns A schema object compatible with Gemini's API\n *\n * @internal\n */\nexport function schemaToGeminiParameters<\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n RunOutput extends Record<string, any> = Record<string, any>,\n>(\n schema:\n | SerializableSchema<RunOutput>\n | InteropZodType<RunOutput>\n | JsonSchema7Type\n): Gemini.Tools.Schema {\n return sanitizeGeminiSchema(\n isInteropZodSchema(schema) || isSerializableSchema(schema)\n ? toJsonSchema(schema)\n : schema\n ) as Gemini.Tools.Schema;\n}\n\n/**\n * Converts a JSON Schema object to Gemini function parameters format.\n *\n * @param schema - The JSON Schema object to convert\n * @returns A schema object compatible with Gemini's API\n *\n * @internal\n */\nfunction jsonSchemaToGeminiParameters(\n // oxlint-disable-next-line @typescript-eslint/no-explicit-any\n schema: Record<string, any>\n): Gemini.Tools.Schema {\n return sanitizeGeminiSchema(schema) as Gemini.Tools.Schema;\n}\n\n/**\n * Type guard to check if a tool is already in Gemini's native format.\n *\n * Gemini tools can be:\n * - Function declarations (`functionDeclarations`)\n * - Code execution tools (`codeExecution`)\n * - Google Search retrieval tools (`googleSearchRetrieval` or `googleSearch`)\n *\n * The full list of tool types are those defined by the `Gemini.Tool` type.\n * Updating that list requires a change to the `geminiToolAttributes` below.\n *\n * @param tool - The tool to check\n * @returns `true` if the tool is already in Gemini format, `false` otherwise\n *\n * @internal\n */\nfunction isGeminiTool(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 \"urlContext\",\n \"googleMaps\",\n \"fileSearch\",\n \"computerUse\",\n \"mcpServers\",\n ];\n\n return geminiToolAttributes.some((attr) => attr in tool);\n}\n\n/**\n * Converts an array of LangChain tools to Gemini function declarations.\n *\n * This converter transforms various tool formats into Gemini's function declaration\n * format. It supports:\n * - LangChain structured tools (with Zod schemas)\n * - OpenAI format tools (with JSON Schema)\n * - Gemini-native function declarations (passed through)\n * - Raw function declaration objects\n *\n * @remarks\n * The converter handles each tool type differently:\n * - **LangChain tools**: Extracts name, description, and schema, converting the schema\n * to Gemini-compatible format\n * - **OpenAI tools**: Extracts function name, description, and parameters from the\n * OpenAI tool format\n * - **Gemini tools**: If the tool contains `functionDeclarations`, extracts and returns\n * them directly. Non-function Gemini tools (like `codeExecution`) are skipped.\n * - **Raw objects**: Assumes the object is a function declaration and validates it has\n * a `name` property\n *\n * @example\n * ```typescript\n * import { StructuredTool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const weatherTool = new StructuredTool({\n * name: \"get_weather\",\n * description: \"Get the weather for a location\",\n * schema: z.object({\n * location: z.string().describe(\"The city name\"),\n * unit: z.enum([\"celsius\", \"fahrenheit\"]).optional()\n * }),\n * func: async (args) => { /* ... *\\/ }\n * });\n *\n * const declarations = convertToolsToGeminiFunctionDeclarations([weatherTool]);\n * // Returns: [{\n * // name: \"get_weather\",\n * // description: \"Get the weather for a location\",\n * // parameters: {\n * // type: \"object\",\n * // properties: {\n * // location: { type: \"string\", description: \"The city name\" },\n * // unit: { type: \"string\", enum: [\"celsius\", \"fahrenheit\"], nullable: true }\n * // },\n * // required: [\"location\"]\n * // }\n * // }]\n * ```\n *\n * @param tools - Array of tools in various formats (LangChain, OpenAI, or Gemini)\n * @returns Array of Gemini function declarations ready for API submission\n * @throws {Error} If a tool cannot be converted (invalid format)\n */\nexport const convertToolsToGeminiFunctionDeclarations: Converter<\n BindToolsInput[],\n Gemini.Tools.FunctionDeclaration[]\n> = (tools) => {\n const functionDeclarations: Gemini.Tools.FunctionDeclaration[] = [];\n\n for (const tool of tools) {\n // Skip if already in Gemini format (non-function tools)\n if (isGeminiTool(tool) && !(\"functionDeclarations\" in tool)) {\n continue;\n }\n\n // Handle Gemini format with functionDeclarations\n if (\n isGeminiTool(tool) &&\n \"functionDeclarations\" in tool &&\n Array.isArray(tool.functionDeclarations)\n ) {\n functionDeclarations.push(...tool.functionDeclarations);\n continue;\n }\n\n // Handle LangChain structured tools\n if (isLangChainTool(tool)) {\n const jsonSchema = schemaToGeminiParameters(tool.schema);\n functionDeclarations.push({\n name: tool.name,\n description: tool.description ?? `A function available to call.`,\n parameters: jsonSchema,\n });\n continue;\n }\n\n // Handle OpenAI format tools\n if (isOpenAITool(tool)) {\n functionDeclarations.push({\n name: tool.function.name,\n description:\n tool.function.description ?? `A function available to call.`,\n parameters: jsonSchemaToGeminiParameters(tool.function.parameters),\n });\n continue;\n }\n\n // Handle raw function declaration objects\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 functionDeclarations.push({\n name: funcDecl.name!,\n description: funcDecl.description ?? `A function available to call.`,\n parameters: funcDecl.parameters,\n });\n continue;\n }\n\n throw new InvalidToolError(tool);\n }\n\n return functionDeclarations;\n};\n\n/**\n * Converts an array of tools to Gemini's Tools array format.\n *\n * This converter groups function declarations into a single tool object while\n * preserving Gemini-native tools (like code execution and Google Search retrieval)\n * as separate tool objects. This matches Gemini's API structure where:\n * - Function declarations are grouped together in a single tool\n * - Non-function tools (codeExecution, googleSearchRetrieval) are separate tools\n *\n * @remarks\n * The conversion process:\n * 1. Separates Gemini-native tools from function declarations\n * 2. Converts LangChain/OpenAI tools to function declarations\n * 3. Groups all function declarations into a single Tool object\n * 4. Returns an array with the grouped function declarations tool plus any\n * non-function Gemini tools\n *\n * @example\n * ```typescript\n * import { StructuredTool } from \"@langchain/core/tools\";\n * import { z } from \"zod\";\n *\n * const weatherTool = new StructuredTool({\n * name: \"get_weather\",\n * description: \"Get the weather\",\n * schema: z.object({ location: z.string() }),\n * func: async () => {}\n * });\n *\n * const geminiCodeTool: Gemini.Tool = {\n * codeExecution: { enabled: true }\n * };\n *\n * const tools = convertToolsToGeminiTools([weatherTool, geminiCodeTool]);\n * // Returns: [\n * // { functionDeclarations: [{ name: \"get_weather\", ... }] },\n * // { codeExecution: { enabled: true } }\n * // ]\n * ```\n *\n * @param tools - Array of tools in various formats (LangChain, OpenAI, or Gemini)\n * @returns Array of Tool objects ready for API submission\n */\nexport const convertToolsToGeminiTools: Converter<\n BindToolsInput[],\n Gemini.Tool[]\n> = (tools) => {\n if (tools.length === 0) {\n return [];\n }\n\n const geminiTools: Gemini.Tool[] = [];\n const functionDeclarations: Gemini.Tools.FunctionDeclaration[] = [];\n\n // Separate Gemini-native tools from function declarations\n for (const tool of tools) {\n if (isGeminiTool(tool)) {\n if (\"functionDeclarations\" in tool) {\n // Already a Gemini tool with function declarations\n geminiTools.push(tool);\n } else {\n // Non-function Gemini tool (codeExecution, googleSearch, etc.)\n geminiTools.push(tool);\n }\n } else if (\"googleSearchRetrieval\" in tool) {\n // Convert the obsolete search into the modern one\n const searchTool: Gemini.Tool = {\n googleSearch: {},\n };\n geminiTools.push(searchTool);\n } else {\n // Convert to function declaration\n const funcDecls = convertToolsToGeminiFunctionDeclarations([tool]);\n functionDeclarations.push(...funcDecls);\n }\n }\n\n // Add function declarations as a single tool if we have any\n if (functionDeclarations.length > 0) {\n geminiTools.push({\n functionDeclarations,\n });\n }\n\n return geminiTools;\n};\n\n/**\n * Converts tool choice to Gemini's function calling configuration.\n *\n * This converter transforms LangChain's tool choice format into Gemini's\n * `toolConfig.functionCallingConfig` format. The configuration is only\n * created when tools are present (`hasTools` is true).\n *\n * @remarks\n * The conversion logic:\n * - If `hasTools` is `false`, returns `undefined` (no config needed)\n * - If `toolChoice` is provided, converts it to a Gemini mode:\n * - `\"auto\"` → `\"AUTO\"` - Model decides whether to call functions\n * - `\"any\"` or `\"required\"` → `\"ANY\"` - Model must call at least one function\n * - `\"none\"` → `\"NONE\"` - Model cannot call functions\n * - `\"validated\"` → `\"VALIDATED\"` - Calls must follow the function schema\n * - Function name string → `\"ANY\"` - Forces function use\n * - Object with `mode` → Maps the mode string to Gemini format\n * - Object with `function` → `\"ANY\"` - Forces function use\n * - If `toolChoice` is not provided but tools exist, defaults to `\"AUTO\"`\n *\n * Gemini's function calling modes:\n * - **AUTO**: The model can choose whether to call functions based on the conversation\n * - **ANY**: The model must call at least one function before responding\n * - **NONE**: The model cannot call any functions\n * - **VALIDATED**: The model may call functions or respond with text, and function\n * calls must follow the provided schema\n *\n * When a specific function is requested (via function name string or `{ function: { name } }`),\n * the converter uses `\"ANY\"` mode to force function usage, as Gemini doesn't support\n * specifying individual functions in the mode.\n *\n * @example\n * ```typescript\n * // With explicit tool choice\n * convertToolChoiceToGeminiConfig(\"auto\", true);\n * // Returns: { functionCallingConfig: { mode: \"AUTO\" } }\n *\n * // Required mode - must call a function\n * convertToolChoiceToGeminiConfig(\"any\", true);\n * // Returns: { functionCallingConfig: { mode: \"ANY\" } }\n *\n * // Without tool choice (defaults to AUTO when tools exist)\n * convertToolChoiceToGeminiConfig(undefined, true);\n * // Returns: { functionCallingConfig: { mode: \"AUTO\" } }\n *\n * // No tools - returns undefined\n * convertToolChoiceToGeminiConfig(\"auto\", false);\n * // Returns: undefined\n * ```\n *\n * @param toolChoice - The tool choice option from LangChain (string, object, or undefined)\n * @param hasTools - Whether tools are present. If false, returns undefined\n * @returns The Gemini tool configuration object, or undefined if no tools are present\n */\nexport function convertToolChoiceToGeminiConfig(\n toolChoice: ToolChoice | undefined,\n hasTools: boolean\n): Gemini.Tools.ToolConfig | undefined {\n if (!hasTools || toolChoice === undefined) {\n return undefined;\n }\n\n let mode: Gemini.Tools.FunctionCallingConfigMode | undefined;\n let allowedFunctionNames: string[] | undefined;\n\n let toolChoiceMode: string | undefined;\n let toolChoiceFunction: string | string[] | undefined;\n if (typeof toolChoice === \"object\") {\n toolChoiceMode = toolChoice.mode;\n toolChoiceFunction = toolChoice.function?.name;\n } else {\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\") {\n mode = \"ANY\";\n toolChoiceFunction = toolChoiceMode;\n }\n\n if (toolChoiceFunction) {\n if (Array.isArray(toolChoiceFunction)) {\n allowedFunctionNames = toolChoiceFunction;\n } else {\n allowedFunctionNames = [toolChoiceFunction];\n }\n }\n\n const functionCallingConfig: Gemini.Tools.FunctionCallingConfig = {};\n if (allowedFunctionNames?.length) {\n functionCallingConfig.allowedFunctionNames = allowedFunctionNames;\n }\n if (mode) {\n functionCallingConfig.mode = mode;\n }\n return {\n functionCallingConfig,\n };\n}\n\n/**\n * Checks whether a tools array mixes server-side built-in tools (e.g.\n * `googleSearch`, `codeExecution`) with function-declaration tools.\n *\n * Gemini rejects such a mix with a 400 unless\n * `toolConfig.includeServerSideToolInvocations` is set.\n * See https://ai.google.dev/gemini-api/docs/tool-combination\n */\nexport function mixesBuiltinAndFunctionTools(tools: Gemini.Tool[]): boolean {\n const isFunctionDeclarationTool = (tool: Gemini.Tool) =>\n \"functionDeclarations\" in tool && !!tool.functionDeclarations?.length;\n return (\n tools.some(isFunctionDeclarationTool) &&\n tools.some((tool) => !isFunctionDeclarationTool(tool))\n );\n}\n"],"mappings":"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"}
@@ -16,7 +16,7 @@
16
16
  *
17
17
  * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys
18
18
  */
19
- interface GCPCredentials {
19
+ export interface GCPCredentials {
20
20
  /** The type of credential, typically "service_account" */
21
21
  type: string;
22
22
  /** The GCP project ID associated with this service account */
@@ -39,5 +39,4 @@ interface GCPCredentials {
39
39
  client_x509_cert_url: string;
40
40
  }
41
41
  //#endregion
42
- export { GCPCredentials };
43
42
  //# sourceMappingURL=gcp-auth.d.cts.map
@@ -16,7 +16,7 @@
16
16
  *
17
17
  * @see https://cloud.google.com/iam/docs/creating-managing-service-account-keys
18
18
  */
19
- interface GCPCredentials {
19
+ export interface GCPCredentials {
20
20
  /** The type of credential, typically "service_account" */
21
21
  type: string;
22
22
  /** The GCP project ID associated with this service account */
@@ -39,5 +39,4 @@ interface GCPCredentials {
39
39
  client_x509_cert_url: string;
40
40
  }
41
41
  //#endregion
42
- export { GCPCredentials };
43
42
  //# sourceMappingURL=gcp-auth.d.ts.map
@@ -1,17 +1,17 @@
1
1
  import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
2
2
  //#region src/utils/handler.d.ts
3
- interface GoogleCustomEventInfo {
3
+ export interface GoogleCustomEventInfo {
4
4
  subEvent: string;
5
5
  module: string;
6
6
  }
7
- declare abstract class GoogleRequestCallbackHandler extends BaseCallbackHandler {
7
+ export declare abstract class GoogleRequestCallbackHandler extends BaseCallbackHandler {
8
8
  customEventInfo(eventName: string): GoogleCustomEventInfo;
9
9
  abstract handleCustomRequestEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
10
10
  abstract handleCustomResponseEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
11
11
  abstract handleCustomChunkEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
12
12
  handleCustomEvent(eventName: string, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
13
13
  }
14
- declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
14
+ export declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
15
15
  name: string;
16
16
  shortenStringLength: number;
17
17
  log(eventName: string, data: any, tags?: string[]): undefined;
@@ -19,7 +19,7 @@ declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
19
19
  handleCustomResponseEvent(eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, tags?: string[], _metadata?: Record<string, any>): any;
20
20
  handleCustomChunkEvent(eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, tags?: string[], _metadata?: Record<string, any>): any;
21
21
  }
22
- declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
22
+ export declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
23
23
  name: string;
24
24
  request: any;
25
25
  response: any;
@@ -29,5 +29,4 @@ declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
29
29
  handleCustomChunkEvent(_eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, _tags?: string[], _metadata?: Record<string, any>): any;
30
30
  }
31
31
  //#endregion
32
- export { GoogleCustomEventInfo, GoogleRequestCallbackHandler, GoogleRequestLogger, GoogleRequestRecorder };
33
32
  //# sourceMappingURL=handler.d.cts.map
@@ -1,17 +1,17 @@
1
1
  import { BaseCallbackHandler } from "@langchain/core/callbacks/base";
2
2
  //#region src/utils/handler.d.ts
3
- interface GoogleCustomEventInfo {
3
+ export interface GoogleCustomEventInfo {
4
4
  subEvent: string;
5
5
  module: string;
6
6
  }
7
- declare abstract class GoogleRequestCallbackHandler extends BaseCallbackHandler {
7
+ export declare abstract class GoogleRequestCallbackHandler extends BaseCallbackHandler {
8
8
  customEventInfo(eventName: string): GoogleCustomEventInfo;
9
9
  abstract handleCustomRequestEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
10
10
  abstract handleCustomResponseEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
11
11
  abstract handleCustomChunkEvent(eventName: string, eventInfo: GoogleCustomEventInfo, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
12
12
  handleCustomEvent(eventName: string, data: any, runId: string, tags?: string[], metadata?: Record<string, any>): any;
13
13
  }
14
- declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
14
+ export declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
15
15
  name: string;
16
16
  shortenStringLength: number;
17
17
  log(eventName: string, data: any, tags?: string[]): undefined;
@@ -19,7 +19,7 @@ declare class GoogleRequestLogger extends GoogleRequestCallbackHandler {
19
19
  handleCustomResponseEvent(eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, tags?: string[], _metadata?: Record<string, any>): any;
20
20
  handleCustomChunkEvent(eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, tags?: string[], _metadata?: Record<string, any>): any;
21
21
  }
22
- declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
22
+ export declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
23
23
  name: string;
24
24
  request: any;
25
25
  response: any;
@@ -29,5 +29,4 @@ declare class GoogleRequestRecorder extends GoogleRequestCallbackHandler {
29
29
  handleCustomChunkEvent(_eventName: string, _eventInfo: GoogleCustomEventInfo, data: any, _runId: string, _tags?: string[], _metadata?: Record<string, any>): any;
30
30
  }
31
31
  //#endregion
32
- export { GoogleCustomEventInfo, GoogleRequestCallbackHandler, GoogleRequestLogger, GoogleRequestRecorder };
33
32
  //# sourceMappingURL=handler.d.ts.map
@@ -7,12 +7,11 @@
7
7
  * type Input = { a: string } & { b: number };
8
8
  * type Output = Prettify<Input>; // { a: string; b: number }
9
9
  */
10
- type Prettify<T> = T extends object ? { [K in keyof T]: Prettify<T[K]>; } : T;
10
+ export type Prettify<T> = T extends object ? { [K in keyof T]: Prettify<T[K]>; } : T;
11
11
  /**
12
12
  * Distributes over a string union and applies Lowercase only to
13
13
  * string-literal members, filtering out wide `string` / `string & {}`.
14
14
  */
15
- type LowercaseLiteral<T> = T extends string ? string extends T ? never : Lowercase<T> : never;
15
+ export type LowercaseLiteral<T> = T extends string ? string extends T ? never : Lowercase<T> : never;
16
16
  //#endregion
17
- export { LowercaseLiteral, Prettify };
18
17
  //# sourceMappingURL=misc.d.cts.map
@@ -7,12 +7,11 @@
7
7
  * type Input = { a: string } & { b: number };
8
8
  * type Output = Prettify<Input>; // { a: string; b: number }
9
9
  */
10
- type Prettify<T> = T extends object ? { [K in keyof T]: Prettify<T[K]>; } : T;
10
+ export type Prettify<T> = T extends object ? { [K in keyof T]: Prettify<T[K]>; } : T;
11
11
  /**
12
12
  * Distributes over a string union and applies Lowercase only to
13
13
  * string-literal members, filtering out wide `string` / `string & {}`.
14
14
  */
15
- type LowercaseLiteral<T> = T extends string ? string extends T ? never : Lowercase<T> : never;
15
+ export type LowercaseLiteral<T> = T extends string ? string extends T ? never : Lowercase<T> : never;
16
16
  //#endregion
17
- export { LowercaseLiteral, Prettify };
18
17
  //# sourceMappingURL=misc.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Google integrations for LangChain.js",
5
5
  "author": "LangChain",
6
6
  "license": "MIT",
@@ -14,23 +14,23 @@
14
14
  "directory": "libs/providers/langchain-google"
15
15
  },
16
16
  "dependencies": {
17
- "eventsource-parser": "^4.1.0",
17
+ "eventsource-parser": "^4.1.1",
18
18
  "google-auth-library": "^11.1.0",
19
- "jose": "^6.2.10"
19
+ "jose": "^6.2.12"
20
20
  },
21
21
  "peerDependencies": {
22
- "@langchain/core": "^1.2.14"
22
+ "@langchain/core": "^1.2.17"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@tsconfig/recommended": "^1.0.10",
26
- "@types/node": "^26.4.0",
26
+ "@types/node": "^26.6.3",
27
27
  "dpdm": "^4.3.0",
28
28
  "sparktype": "^0.1.3",
29
29
  "typescript": "~7.0.2",
30
- "vitest": "^4.1.11",
30
+ "vitest": "^5.0.2",
31
31
  "zod": "^3.25.76 || ^4",
32
32
  "zod-to-json-schema": "^3.25.2",
33
- "@langchain/core": "^1.2.14",
33
+ "@langchain/core": "^1.2.17",
34
34
  "@langchain/standard-tests": "0.0.23"
35
35
  },
36
36
  "publishConfig": {