import { Tool } from "@langchain/core/tools"; /** * Wikipedia query tool integration. * * Setup: * Install `@langchain/community`. You'll also need an API key. * * ```bash * npm install @langchain/community * ``` * * ## [Constructor args](https://api.js.langchain.com/classes/_langchain_community.tools_wikipedia_query_run.WikipediaQueryRun.html#constructor) * *
* Instantiate * * ```typescript * import { WikipediaQueryRun } from "@langchain/community/tools/wikipedia_query_run"; * * const tool = new WikipediaQueryRun({ * topKResults: 3, * maxDocContentLength: 4000, * }); * ``` *
* *
* *
* * Invocation * * ```typescript * await tool.invoke("what is the current weather in sf?"); * ``` *
* *
* *
* * Invocation with tool call * * ```typescript * // This is usually generated by a model, but we'll create a tool call directly for demo purposes. * const modelGeneratedToolCall = { * args: { * input: "what is the current weather in sf?", * }, * id: "tool_call_id", * name: tool.name, * type: "tool_call", * }; * await tool.invoke(modelGeneratedToolCall); * ``` * * ```text * ToolMessage { * "content": "...", * "name": "wikipedia-api", * "additional_kwargs": {}, * "response_metadata": {}, * "tool_call_id": "tool_call_id" * } * ``` *
*/ export class WikipediaQueryRun extends Tool { static lc_name() { return "WikipediaQueryRun"; } constructor(params = {}) { super(); Object.defineProperty(this, "name", { enumerable: true, configurable: true, writable: true, value: "wikipedia-api" }); Object.defineProperty(this, "description", { enumerable: true, configurable: true, writable: true, value: "A tool for interacting with and fetching data from the Wikipedia API." }); Object.defineProperty(this, "topKResults", { enumerable: true, configurable: true, writable: true, value: 3 }); Object.defineProperty(this, "maxDocContentLength", { enumerable: true, configurable: true, writable: true, value: 4000 }); Object.defineProperty(this, "baseUrl", { enumerable: true, configurable: true, writable: true, value: "https://en.wikipedia.org/w/api.php" }); this.topKResults = params.topKResults ?? this.topKResults; this.maxDocContentLength = params.maxDocContentLength ?? this.maxDocContentLength; this.baseUrl = params.baseUrl ?? this.baseUrl; } async _call(query) { const searchResults = await this._fetchSearchResults(query); const summaries = []; for (let i = 0; i < Math.min(this.topKResults, searchResults.query.search.length); i += 1) { const page = searchResults.query.search[i].title; const pageDetails = await this._fetchPage(page, true); if (pageDetails) { const summary = `Page: ${page}\nSummary: ${pageDetails.extract}`; summaries.push(summary); } } if (summaries.length === 0) { return "No good Wikipedia Search Result was found"; } else { return summaries.join("\n\n").slice(0, this.maxDocContentLength); } } /** * Fetches the content of a specific Wikipedia page. It returns the * extracted content as a string. * @param page The specific Wikipedia page to fetch its content. * @param redirect A boolean value to indicate whether to redirect or not. * @returns The extracted content of the specific Wikipedia page as a string. */ async content(page, redirect = true) { try { const result = await this._fetchPage(page, redirect); return result.extract; } catch (error) { throw new Error(`Failed to fetch content for page "${page}": ${error}`); } } /** * Builds a URL for the Wikipedia API using the provided parameters. * @param parameters The parameters to be used in building the URL. * @returns A string representing the built URL. */ buildUrl(parameters) { const nonUndefinedParams = Object.entries(parameters) .filter(([_, value]) => value !== undefined) .map(([key, value]) => [key, `${value}`]); const searchParams = new URLSearchParams(nonUndefinedParams); return `${this.baseUrl}?${searchParams}`; } async _fetchSearchResults(query) { const searchParams = new URLSearchParams({ action: "query", list: "search", srsearch: query, format: "json", }); const response = await fetch(`${this.baseUrl}?${searchParams.toString()}`); if (!response.ok) throw new Error("Network response was not ok"); const data = await response.json(); return data; } async _fetchPage(page, redirect) { const params = new URLSearchParams({ action: "query", prop: "extracts", explaintext: "true", redirects: redirect ? "1" : "0", format: "json", titles: page, }); const response = await fetch(`${this.baseUrl}?${params.toString()}`); if (!response.ok) throw new Error("Network response was not ok"); const data = await response.json(); const { pages } = data.query; const pageId = Object.keys(pages)[0]; return pages[pageId]; } }