langchain-ai / langchainjs

🦜🔗 Build context-aware reasoning applications 🦜🔗
https://js.langchain.com/docs/
MIT License
12.63k stars 2.17k forks source link

Can't use ChatGoogleGenerativeAI with tools in Langraph #6833

Open cnarte opened 1 month ago

cnarte commented 1 month ago

I'm trying to use google generative-ai package with langraph but getting a unhandled response for llm call inside the package with tool call.

Example Code

The following code File < node_modules\@langchain\google-genai\dist\chat_models.js > ::


            usageMetadata,
        });
            await runManager?.handleLLMNewToken(generationResult.generations[0].text ?? "");
            return generationResult;
    }

### Error Message and Stack Trace (if applicable)

``` node_modules\@langchain\google-genai\dist\chat_models.cjs:276
        await runManager?.handleLLMNewToken(generationResult.generations[0].text ?? "");
                                                                            ^     

TypeError: Cannot read properties of undefined (reading 'text')

### Description

I'm trying to use ChatGoogleGenerativeAI for langraph. also defined the tools in gemeni tool format. But the tool call agents are not working.

### System Info

```  "dependencies": {
        "@google-cloud/aiplatform": "^3.29.0",
        "@google-cloud/vertexai": "^1.7.0",
        "@langchain/anthropic": "^0.3.0",
        "@langchain/community": "^0.2.25",
        "@langchain/google-genai": "^0.0.25",
        "@langchain/google-vertexai": "^0.0.27",
        "@langchain/google-vertexai-web": "^0.0.27",
        "@langchain/groq": "^0.0.17",
        "@langchain/langgraph": "^0.0.34",
        "@langchain/ollama": "^0.0.4",
        "@langchain/openai": "^0.2.11",
        "@types/node": "^22.5.4",
        "axios": "^1.7.3",
        "dotenv": "^16.4.5",
        "langchain": "^0.2.13",
        "mongoose": "^8.5.2",
        "node-fetch": "^3.3.2",
        "readline-sync": "^1.4.10",
        "tslab": "^1.0.22",
        "typescript": "^5.5.4",
        "wwebjs-mongo": "^1.1.0"
      }
dosubot[bot] commented 1 month ago

Hello @cnarte! I'm here to help you with any bugs, questions, or contributions you have. Let's tackle this issue together!

I found a similar issue where users encountered a TypeError: Cannot read properties of undefined (reading 'text') when using ChatGoogleGenerativeAI with tools. This error typically occurs when the response from the Google Generative AI API does not contain the expected structure, specifically the text property.

Solution

To address this issue, you should ensure that the response from the API is correctly structured and contains the text property. Additionally, you can add checks to handle cases where the text property might be missing.

Here is a potential fix in the _generate method to handle undefined properties:

async _generate(
  messages: BaseMessage[],
  options: this["ParsedCallOptions"],
  runManager?: CallbackManagerForLLMRun
): Promise<ChatResult> {
  const prompt = convertBaseMessagesToContent(
    messages,
    this._isMultimodalModel
  );
  const parameters = this.invocationParams(options);

  // Handle streaming
  if (this.streaming) {
    const tokenUsage: TokenUsage = {};
    const stream = this._streamResponseChunks(messages, options, runManager);
    const finalChunks: Record<number, ChatGenerationChunk> = {};

    for await (const chunk of stream) {
      if (chunk.text) {
        // Process the chunk
      } else {
        console.error("Received chunk without text property:", chunk);
      }
    }
  } else {
    const response = await this.client.generateContent({
      contents: [prompt],
      ...parameters,
    });

    if (response && response.text) {
      return mapGenerateContentResultToChatResult(response);
    } else {
      throw new Error("Response does not contain text property");
    }
  }
}

This code adds checks to ensure that the text property is present before attempting to access it, which should prevent the TypeError from occurring [1].

Additional Steps

  1. Ensure Correct Dependencies: Make sure you have the necessary dependencies installed and configured correctly:

    npm install @langchain/google-genai @langchain/core
  2. Check package.json: Ensure your package.json includes the correct dependencies and resolutions:

    {
     "name": "your-project",
     "version": "0.0.0",
     "dependencies": {
       "@langchain/core": "^0.3.0",
       "@langchain/google-genai": "^0.0.0"
     },
     "resolutions": {
       "@langchain/core": "^0.3.0"
     },
     "overrides": {
       "@langchain/core": "^0.3.0"
     },
     "pnpm": {
       "overrides": {
         "@langchain/core": "^0.3.0"
       }
     }
    }
  3. Set Up Environment Variable:

    export GOOGLE_API_KEY=your-api-key
  4. Initialize ChatGoogleGenerativeAI Correctly:

    import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
    
    const model = new ChatGoogleGenerativeAI({
     modelName: "gemini-pro",
     maxOutputTokens: 2048,
    });
    const response = await model.invoke(new HumanMessage("Hello world!"));

By following these steps, you should be able to avoid the TypeError and ensure that your integration with the Google Generative AI API works correctly [1][2].

To continue talking to Dosu, mention @dosu.

cnarte commented 1 month ago

But how can I edit the Package implementation?

dosubot[bot] commented 1 month ago

To edit the package implementation, you can follow these steps:

  1. Extract the Package: Use the yarn patch command to extract the package to a temporary directory.
  2. Make Your Changes: Edit the files in the extracted directory as needed.
  3. Commit Your Changes: Use the yarn patch-commit command to commit your changes and create a patch file.

Here is a code snippet to guide you through the process:

# Extract the package
yarn patch @langchain/google-genai

# Make your changes in the extracted directory
# (The directory path will be displayed in the terminal output)

# Commit your changes
yarn patch-commit -s <path-to-extracted-directory>

This will store a patch file based on your changes, which you can then apply to your project [1].

To continue talking to Dosu, mention @dosu.

cnarte commented 1 month ago

@dosu that wont solve problem just throw a new error.

dosubot[bot] commented 1 month ago

To resolve the issue with TypeError: Cannot read properties of undefined (reading 'text') when using ChatGoogleGenerativeAI with tools in Langraph, ensure that the properties you are trying to access are correctly defined and available. In the provided code, the FakeBrowserTool class and its schema are correctly set up, but you should verify that the response structure from modelWithTools.invoke is as expected.

Here is a revised version of the code with additional checks to ensure that the properties are correctly accessed:

import { StructuredTool } from "@langchain/core/tools";
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import { z } from "zod";

const model = new ChatGoogleGenerativeAI({
  model: "gemini-pro",
});

// Define your tool
class FakeBrowserTool extends StructuredTool {
  schema = z.object({
    url: z.string(),
    query: z.string().optional(),
  });

  name = "fake_browser_tool";

  description =
    "useful for when you need to find something on the web or summarize a webpage.";

  async _call(_: z.infer<this["schema"]>): Promise<string> {
    return "fake_browser_tool";
  }
}
const tool = new FakeBrowserTool();

// Bind your tools to the model
const modelWithTools = model.withStructuredOutput(tool.schema, {
  name: tool.name, // this is optional
});
// Optionally, you can pass just a Zod schema, or JSONified Zod schema
// const modelWithTools = model.withStructuredOutput(
//   zodSchema,
// );

const res = await modelWithTools.invoke([
  [
    "human",
    "Search the web and tell me what the weather will be like tonight in new york. use a popular weather website",
  ],
]);

if (res && res.url && res.query) {
  console.log(res);
} else {
  console.error("Unexpected response structure:", res);
}

/*
{
  url: 'https://www.accuweather.com/en/us/new-york-ny/10007/night-weather-forecast/349014',
  query: 'weather tonight'
}
*/

This code includes a check to ensure that res, res.url, and res.query are defined before attempting to access them. This should help prevent the TypeError you are encountering.

Additionally, make sure you have installed the @langchain/google-genai package as required:

npm install @langchain/google-genai

Refer to the LangChain documentation for more details on using the ChatGoogleGenerativeAI class and its methods [1][2][3][4].

To continue talking to Dosu, mention @dosu.

afirstenberg commented 1 month ago

I'd need to dig into the @langchain/google-genai package to be sure, but my guess is that this isn't caused by tools specifically but that a finishReason of "SAFETY" or something else is being triggered. In these cases, there is no text returned, so trying to access the text element (which is what is done internally) is triggering the exception.

A slightly biased suggestion, but you may wish to switch to using the @langchain/google-gauth or @langchain/google-webauth packages instead. These don't avoid the issue, but they do let you manage it a bit better with a SecurityManager. You'll then be using the ChatGoogle class.

Make sure you are using version 0.1.0 of either and version 0.1.1 of @langchain/google-common. You'll also need to explicitly depend on @langchain/common version 0.3.0.

bracesproul commented 1 month ago

@cnarte can you provide some code I can use to reproduce this error?