agsamantha/node_modules/@langchain/community/dist/tools/wikipedia_query_run.js
2024-10-02 15:15:21 -05:00

185 lines
5.8 KiB
JavaScript

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)
*
* <details open>
* <summary><strong>Instantiate</strong></summary>
*
* ```typescript
* import { WikipediaQueryRun } from "@langchain/community/tools/wikipedia_query_run";
*
* const tool = new WikipediaQueryRun({
* topKResults: 3,
* maxDocContentLength: 4000,
* });
* ```
* </details>
*
* <br />
*
* <details>
*
* <summary><strong>Invocation</strong></summary>
*
* ```typescript
* await tool.invoke("what is the current weather in sf?");
* ```
* </details>
*
* <br />
*
* <details>
*
* <summary><strong>Invocation with tool call</strong></summary>
*
* ```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"
* }
* ```
* </details>
*/
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];
}
}