Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Google Finance Integration #7289

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
33 changes: 33 additions & 0 deletions docs/core_docs/docs/integrations/tools/google_finance.mdx
joshuajyu marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
hide_table_of_contents: true
---

import CodeBlock from "@theme/CodeBlock";

# Google Finance Tool
The Google Finance Tool allows your agent to utilize the Google Finance API to retrieve financial data, such as stock prices, market trends,
exchange rates, and other investment-related information from Google Finance.

## Setup
Before using the tool, ensure you have your API key. You can create an account on [SerpAPI](https://serpapi.com/users/sign_in) and obtain your API key
under **Your Private API Key** in your account dashboard. The Google Finance API is included in the free plan offered by SerpAPI.
Once you have the key, set it to the `SERPAPI_API_KEY` environment variable or pass it in as the `apiKey` argument when initializing the tool.

## Usage

import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx";

<IntegrationInstallTooltip></IntegrationInstallTooltip>

```bash npm2yarn
npm install @langchain/openai @langchain/community @langchain/core
```

import ToolExample from "@examples/tools/google_finance.ts";

<CodeBlock language="typescript">{ToolExample}</CodeBlock>

## Related

- Tool [conceptual guide](/docs/concepts/tools)
- Tool [how-to guides](/docs/how_to/#tools)
23 changes: 23 additions & 0 deletions examples/src/tools/google_finance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { GoogleFinanceAPI } from "@langchain/community/tools/google_finance";
import { OpenAI } from "@langchain/openai";
import { initializeAgentExecutorWithOptions } from "langchain/agents";

export async function run() {
const model = new OpenAI({
temperature: 0,
apiKey: process.env.OPENAI_API_KEY,
});

const tools = [new GoogleFinanceAPI()];

const financeAgent = await initializeAgentExecutorWithOptions(tools, model, {
joshuajyu marked this conversation as resolved.
Show resolved Hide resolved
agentType: "zero-shot-react-description",
verbose: true,
});

const result = await financeAgent.invoke({
input: "What is the price of GOOG:NASDAQ?",
});

console.log(result.output);
}
1 change: 1 addition & 0 deletions libs/langchain-community/langchain.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const config = {
"tools/gmail": "tools/gmail/index",
"tools/google_calendar": "tools/google_calendar/index",
"tools/google_custom_search": "tools/google_custom_search",
"tools/google_finance": "tools/google_finance",
"tools/google_places": "tools/google_places",
"tools/google_routes": "tools/google_routes",
"tools/ifttt": "tools/ifttt",
Expand Down
114 changes: 114 additions & 0 deletions libs/langchain-community/src/tools/google_finance.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import { Tool } from "@langchain/core/tools";
import { getEnvironmentVariable } from "@langchain/core/utils/env";

/**
* Interface for parameters required by the GoogleFinanceAPI class.
*/
export interface GoogleFinanceAPIParams {
/**
* Optional API key for accessing the SerpApi service.
*/
apiKey?: string;
}

/**
* Tool for querying Google Finance using the SerpApi service.
*/
export class GoogleFinanceAPI extends Tool {
joshuajyu marked this conversation as resolved.
Show resolved Hide resolved
static lc_name() {
return "GoogleFinanceAPI";
}

/**
* Returns a mapping of secret environment variable names to their usage in the tool.
* @returns {object} Mapping of secret names to their environment variable counterparts.
*/
get lc_secrets(): { [key: string]: string } | undefined {
return {
apiKey: "SERPAPI_API_KEY",
};
}

// Name of the tool, used for logging or identification within LangChain.
name = "google_finance";

// The API key used for making requests to SerpApi.
protected apiKey: string;

/**
* Description of the tool for usage documentation.
*/
description = `A wrapper around Google Finance Search.
Useful for when you need to get information about
google search Finance from Google Finance.
Input should be a search query that includes a stock ticker
(e.g. GOOG:NASDAQ). It provides detailed information on:
- Stock summary
- Markets
- Graph (price per minute)
- Knowledge graph
- News articles
- Financials
- Related searches that may be of interest `;

/**
* Constructs a new instance of GoogleFinanceAPI.
* @param fields - Optional parameters including an API key.
*/
constructor(fields?: GoogleFinanceAPIParams) {
super(...arguments);

// Retrieve API key from fields or environment variables.
const apiKey = fields?.apiKey ?? getEnvironmentVariable("SERPAPI_API_KEY");

// Throw an error if no API key is found.
if (!apiKey) {
throw new Error(
`SerpApi key not set. You can set it as "SERPAPI_API_KEY" in your environment variables.`
);
}
this.apiKey = apiKey;
}

/**
* Makes a request to SerpApi for Google Finance results.
* @param input - Search query string.
* @returns A JSON string containing the search results.
* @throws Error if the API request fails or returns an error.
*/
async _call(input: string): Promise<string> {
// Construct the URL for the API request.
const url = `https://serpapi.com/search.json?q=${encodeURIComponent(
input
)}&engine=google_finance&api_key=05f88ace01a07cc3ca26bd86664b5d2e579d2a5db45407f55a39d86ac7d47d1b`;

// Make an HTTP GET request to the SerpApi service.
const response = await fetch(url);

// Handle non-OK responses by extracting the error message.
if (!response.ok) {
let message;
try {
const json = await response.json();
message = json.error;
} catch (error) {
message =
"Unable to parse error message: SerpApi did not return a JSON response.";
}
// Throw an error with detailed information about the failure.
throw new Error(
`Got ${response.status}: ${response.statusText} error from SerpApi: ${message}`
);
}

// Parse the JSON response from SerpApi.
const json = await response.json();

// Remove metadata and search parameters from result.
if (json.search_metadata) delete json.search_metadata;
if (json.search_parameters) delete json.search_parameters;

// Return the results as a formatted JSON string.
return JSON.stringify(json, null, 2);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { expect, describe } from "@jest/globals";
import { GoogleFinanceAPI } from "../google_finance.js";

describe("GoogleFinanceAPI", () => {
test("should be setup with correct parameters", async () => {
const instance = new GoogleFinanceAPI();
expect(instance.name).toBe("google_finance");
});

test("GoogleFinanceAPI returns expected result for valid query", async () => {
const tool = new GoogleFinanceAPI();

const result = await tool.invoke("GOOG:NASDAQ");

expect(result).toContain("Alphabet Inc.");
expect(result).toContain("GOOG");
expect(result).toContain("NASDAQ");
});

test("GoogleFinanceAPI returns '' for query on a non-existent ticker symbol", async () => {
const tool = new GoogleFinanceAPI();

const result = await tool.invoke("mkvdfmvkdmvkdovkam");

expect(result).toContain("");
});
});