{"version":3,"file":"google_scholar.cjs","names":["Tool"],"sources":["../../src/tools/google_scholar.ts"],"sourcesContent":["import { Tool } from \"@langchain/core/tools\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\n\n/**\n * Interface for parameters required by the SERPGoogleScholarAPITool class.\n */\nexport interface GoogleScholarAPIParams {\n  /**\n   * Optional API key for accessing the SerpApi service.\n   */\n  apiKey?: string;\n}\n\n/**\n * Tool for querying Google Scholar using the SerpApi service.\n */\nexport class SERPGoogleScholarAPITool extends Tool {\n  /**\n   * Specifies the name of the tool, used internally by LangChain.\n   */\n  static lc_name() {\n    return \"SERPGoogleScholarAPITool\";\n  }\n\n  /**\n   * Returns a mapping of secret environment variable names to their usage in the tool.\n   * @returns {object} Mapping of secret names to their environment variable counterparts.\n   */\n  get lc_secrets(): { [key: string]: string } | undefined {\n    return {\n      apiKey: \"SERPAPI_API_KEY\",\n    };\n  }\n\n  // Name of the tool, used for logging or identification within LangChain.\n  name = \"serp_google_scholar\";\n\n  // The API key used for making requests to SerpApi.\n  protected apiKey: string;\n\n  /**\n   * Description of the tool for usage documentation.\n   */\n  description = `A wrapper around Google Scholar API via SerpApi. Useful for querying academic \n  articles and papers by keywords or authors. Input should be a search query string.`;\n\n  /**\n   * Constructs a new instance of SERPGoogleScholarAPITool.\n   * @param fields - Optional parameters including an API key.\n   */\n  constructor(fields?: GoogleScholarAPIParams) {\n    super(...arguments);\n\n    // Retrieve API key from fields or environment variables.\n    const apiKey = fields?.apiKey ?? getEnvironmentVariable(\"SERPAPI_API_KEY\");\n\n    // Throw an error if no API key is found.\n    if (!apiKey) {\n      throw new Error(\n        `SerpApi key not set. You can set it as \"SERPAPI_API_KEY\" in your environment variables.`\n      );\n    }\n    this.apiKey = apiKey;\n  }\n\n  /**\n   * Makes a request to SerpApi for Google Scholar results.\n   * @param input - Search query string.\n   * @returns A JSON string containing the search results.\n   * @throws Error if the API request fails or returns an error.\n   */\n  async _call(input: string): Promise<string> {\n    // Construct the URL for the API request.\n    const url = `https://serpapi.com/search.json?q=${encodeURIComponent(\n      input\n    )}&engine=google_scholar&api_key=${this.apiKey}`;\n\n    // Make an HTTP GET request to the SerpApi service.\n    const response = await fetch(url);\n\n    // Handle non-OK responses by extracting the error message.\n    if (!response.ok) {\n      let message;\n      try {\n        const json = await response.json(); // Attempt to parse the error response.\n        message = json.error; // Extract the error message from the response.\n      } catch {\n        // Handle cases where the response isn't valid JSON.\n        message =\n          \"Unable to parse error message: SerpApi did not return a JSON response.\";\n      }\n      // Throw an error with detailed information about the failure.\n      throw new Error(\n        `Got ${response.status}: ${response.statusText} error from SerpApi: ${message}`\n      );\n    }\n\n    // Parse the JSON response from SerpApi.\n    const json = (await response.json()) as {\n      organic_results: {\n        title: string;\n        link: string;\n        snippet: string;\n        publication_info: { summary: string; authors: { name: string }[] };\n        authors: { name: string }[];\n        inline_links: { cited_by: { total: string } };\n      }[];\n    };\n\n    // Transform the raw response into a structured format.\n    const results =\n      json.organic_results?.map((item) => ({\n        title: item.title, // Title of the article or paper.\n        link: item.link, // Direct link to the article or paper.\n        snippet: item.snippet, // Brief snippet or description.\n        publication_info:\n          item.publication_info?.summary\n            ?.split(\" - \") // Split the summary at hyphens.\n            .slice(1) // Remove the authors from the start of the string.\n            .join(\" - \") ?? \"\", // Rejoin remaining parts as publication info.\n        authors:\n          item.publication_info?.authors\n            ?.map((author: { name: string }) => author.name) // Extract the list of author names.\n            .join(\", \") ?? \"\", // Join author names with a comma.\n        total_citations: item.inline_links?.cited_by?.total ?? \"\", // Total number of citations.\n      })) ?? `No results found for ${input} on Google Scholar.`;\n\n    // Return the results as a formatted JSON string.\n    return JSON.stringify(results, null, 2);\n  }\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAa,2BAAb,cAA8CA,sBAAAA,KAAK;;;;CAIjD,OAAO,UAAU;AACf,SAAO;;;;;;CAOT,IAAI,aAAoD;AACtD,SAAO,EACL,QAAQ,mBACT;;CAIH,OAAO;CAGP;;;;CAKA,cAAc;;;;;;CAOd,YAAY,QAAiC;AAC3C,QAAM,GAAG,UAAU;EAGnB,MAAM,SAAS,QAAQ,WAAA,GAAA,0BAAA,wBAAiC,kBAAkB;AAG1E,MAAI,CAAC,OACH,OAAM,IAAI,MACR,0FACD;AAEH,OAAK,SAAS;;;;;;;;CAShB,MAAM,MAAM,OAAgC;EAE1C,MAAM,MAAM,qCAAqC,mBAC/C,MACD,CAAC,iCAAiC,KAAK;EAGxC,MAAM,WAAW,MAAM,MAAM,IAAI;AAGjC,MAAI,CAAC,SAAS,IAAI;GAChB,IAAI;AACJ,OAAI;AAEF,eADa,MAAM,SAAS,MAAM,EACnB;WACT;AAEN,cACE;;AAGJ,SAAM,IAAI,MACR,OAAO,SAAS,OAAO,IAAI,SAAS,WAAW,uBAAuB,UACvE;;EAgBH,MAAM,WAZQ,MAAM,SAAS,MAAM,EAa5B,iBAAiB,KAAK,UAAU;GACnC,OAAO,KAAK;GACZ,MAAM,KAAK;GACX,SAAS,KAAK;GACd,kBACE,KAAK,kBAAkB,SACnB,MAAM,MAAM,CACb,MAAM,EAAE,CACR,KAAK,MAAM,IAAI;GACpB,SACE,KAAK,kBAAkB,SACnB,KAAK,WAA6B,OAAO,KAAK,CAC/C,KAAK,KAAK,IAAI;GACnB,iBAAiB,KAAK,cAAc,UAAU,SAAS;GACxD,EAAE,IAAI,wBAAwB,MAAM;AAGvC,SAAO,KAAK,UAAU,SAAS,MAAM,EAAE"}