@langchain/google-genai 0.1.0 → 0.1.2

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.
@@ -525,21 +525,56 @@ class ChatGoogleGenerativeAI extends chat_models_1.BaseChatModel {
525
525
  return this.bind({ tools: (0, common_js_1.convertToGenerativeAITools)(tools), ...kwargs });
526
526
  }
527
527
  invocationParams(options) {
528
- if (options?.tool_choice) {
529
- throw new Error("'tool_choice' call option is not supported by ChatGoogleGenerativeAI.");
530
- }
531
- const tools = options?.tools;
532
- if (Array.isArray(tools) &&
533
- !tools.some(
528
+ let genaiTools;
529
+ if (Array.isArray(options?.tools) &&
530
+ !options?.tools.some(
534
531
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
535
532
  (t) => !("lc_namespace" in t))) {
536
533
  // Tools are in StructuredToolInterface format. Convert to GenAI format
537
- return {
538
- tools: (0, common_js_1.convertToGenerativeAITools)(options?.tools),
539
- };
534
+ genaiTools = (0, common_js_1.convertToGenerativeAITools)(options?.tools);
535
+ }
536
+ else {
537
+ genaiTools = options?.tools;
538
+ }
539
+ let toolConfig;
540
+ if (genaiTools?.length && options?.tool_choice) {
541
+ if (["any", "auto", "none"].some((c) => c === options.tool_choice)) {
542
+ const modeMap = {
543
+ any: generative_ai_1.FunctionCallingMode.ANY,
544
+ auto: generative_ai_1.FunctionCallingMode.AUTO,
545
+ none: generative_ai_1.FunctionCallingMode.NONE,
546
+ };
547
+ toolConfig = {
548
+ functionCallingConfig: {
549
+ mode: modeMap[options.tool_choice] ??
550
+ "MODE_UNSPECIFIED",
551
+ allowedFunctionNames: options.allowedFunctionNames,
552
+ },
553
+ };
554
+ }
555
+ else if (typeof options.tool_choice === "string") {
556
+ toolConfig = {
557
+ functionCallingConfig: {
558
+ mode: generative_ai_1.FunctionCallingMode.ANY,
559
+ allowedFunctionNames: [
560
+ ...(options.allowedFunctionNames ?? []),
561
+ options.tool_choice,
562
+ ],
563
+ },
564
+ };
565
+ }
566
+ if (!options.tool_choice && options.allowedFunctionNames) {
567
+ toolConfig = {
568
+ functionCallingConfig: {
569
+ mode: generative_ai_1.FunctionCallingMode.ANY,
570
+ allowedFunctionNames: options.allowedFunctionNames,
571
+ },
572
+ };
573
+ }
540
574
  }
541
575
  return {
542
- tools: options?.tools,
576
+ tools: genaiTools,
577
+ toolConfig,
543
578
  };
544
579
  }
545
580
  async _generate(messages, options, runManager) {
@@ -13,6 +13,11 @@ export type BaseMessageExamplePair = {
13
13
  };
14
14
  export interface GoogleGenerativeAIChatCallOptions extends BaseChatModelCallOptions {
15
15
  tools?: GoogleGenerativeAIToolType[];
16
+ /**
17
+ * Allowed functions to call when the mode is "any".
18
+ * If empty, any one of the provided functions are called.
19
+ */
20
+ allowedFunctionNames?: string[];
16
21
  /**
17
22
  * Whether or not to include usage data, like token counts
18
23
  * in the streamed response chunks.
@@ -1,4 +1,4 @@
1
- import { GoogleGenerativeAI as GenerativeAI, } from "@google/generative-ai";
1
+ import { GoogleGenerativeAI as GenerativeAI, FunctionCallingMode, } from "@google/generative-ai";
2
2
  import { getEnvironmentVariable } from "@langchain/core/utils/env";
3
3
  import { BaseChatModel, } from "@langchain/core/language_models/chat_models";
4
4
  import { RunnablePassthrough, RunnableSequence, } from "@langchain/core/runnables";
@@ -522,21 +522,56 @@ export class ChatGoogleGenerativeAI extends BaseChatModel {
522
522
  return this.bind({ tools: convertToGenerativeAITools(tools), ...kwargs });
523
523
  }
524
524
  invocationParams(options) {
525
- if (options?.tool_choice) {
526
- throw new Error("'tool_choice' call option is not supported by ChatGoogleGenerativeAI.");
527
- }
528
- const tools = options?.tools;
529
- if (Array.isArray(tools) &&
530
- !tools.some(
525
+ let genaiTools;
526
+ if (Array.isArray(options?.tools) &&
527
+ !options?.tools.some(
531
528
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
532
529
  (t) => !("lc_namespace" in t))) {
533
530
  // Tools are in StructuredToolInterface format. Convert to GenAI format
534
- return {
535
- tools: convertToGenerativeAITools(options?.tools),
536
- };
531
+ genaiTools = convertToGenerativeAITools(options?.tools);
532
+ }
533
+ else {
534
+ genaiTools = options?.tools;
535
+ }
536
+ let toolConfig;
537
+ if (genaiTools?.length && options?.tool_choice) {
538
+ if (["any", "auto", "none"].some((c) => c === options.tool_choice)) {
539
+ const modeMap = {
540
+ any: FunctionCallingMode.ANY,
541
+ auto: FunctionCallingMode.AUTO,
542
+ none: FunctionCallingMode.NONE,
543
+ };
544
+ toolConfig = {
545
+ functionCallingConfig: {
546
+ mode: modeMap[options.tool_choice] ??
547
+ "MODE_UNSPECIFIED",
548
+ allowedFunctionNames: options.allowedFunctionNames,
549
+ },
550
+ };
551
+ }
552
+ else if (typeof options.tool_choice === "string") {
553
+ toolConfig = {
554
+ functionCallingConfig: {
555
+ mode: FunctionCallingMode.ANY,
556
+ allowedFunctionNames: [
557
+ ...(options.allowedFunctionNames ?? []),
558
+ options.tool_choice,
559
+ ],
560
+ },
561
+ };
562
+ }
563
+ if (!options.tool_choice && options.allowedFunctionNames) {
564
+ toolConfig = {
565
+ functionCallingConfig: {
566
+ mode: FunctionCallingMode.ANY,
567
+ allowedFunctionNames: options.allowedFunctionNames,
568
+ },
569
+ };
570
+ }
537
571
  }
538
572
  return {
539
- tools: options?.tools,
573
+ tools: genaiTools,
574
+ toolConfig,
540
575
  };
541
576
  }
542
577
  async _generate(messages, options, runManager) {
@@ -221,7 +221,7 @@ function convertResponseContentToChatGenerationChunk(response, extra) {
221
221
  const functionCalls = response.functionCalls();
222
222
  const [candidate] = response.candidates;
223
223
  const { content, ...generationInfo } = candidate;
224
- const text = content?.parts[0]?.text ?? "";
224
+ const text = content?.parts?.[0]?.text ?? "";
225
225
  const toolCallChunks = [];
226
226
  if (functionCalls) {
227
227
  toolCallChunks.push(...functionCalls.map((fc) => ({
@@ -213,7 +213,7 @@ export function convertResponseContentToChatGenerationChunk(response, extra) {
213
213
  const functionCalls = response.functionCalls();
214
214
  const [candidate] = response.candidates;
215
215
  const { content, ...generationInfo } = candidate;
216
- const text = content?.parts[0]?.text ?? "";
216
+ const text = content?.parts?.[0]?.text ?? "";
217
217
  const toolCallChunks = [];
218
218
  if (functionCalls) {
219
219
  toolCallChunks.push(...functionCalls.map((fc) => ({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langchain/google-genai",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Google Generative AI integration for LangChain.js",
5
5
  "type": "module",
6
6
  "engines": {