feat: Implement stock price component and api
This commit is contained in:
@@ -5,6 +5,63 @@ import type ComponentMap from "../../uis/index";
|
||||
import { z } from "zod";
|
||||
import { LangGraphRunnableConfig } from "@langchain/langgraph";
|
||||
import { findToolCall } from "../../find-tool-call";
|
||||
import { format, subDays } from "date-fns";
|
||||
import { Price } from "../../types";
|
||||
|
||||
async function getPricesForTicker(ticker: string): Promise<{
|
||||
oneDayPrices: Price[];
|
||||
thirtyDayPrices: Price[];
|
||||
}> {
|
||||
if (!process.env.FINANCIAL_DATASETS_API_KEY) {
|
||||
throw new Error("Financial datasets API key not set");
|
||||
}
|
||||
|
||||
const options = {
|
||||
method: "GET",
|
||||
headers: { "X-API-KEY": process.env.FINANCIAL_DATASETS_API_KEY },
|
||||
};
|
||||
|
||||
const url = "https://api.financialdatasets.ai/prices";
|
||||
|
||||
const oneMonthAgo = format(subDays(new Date(), 30), "yyyy-MM-dd");
|
||||
const now = format(new Date(), "yyyy-MM-dd");
|
||||
|
||||
const queryParamsOneDay = new URLSearchParams({
|
||||
ticker,
|
||||
interval: "minute",
|
||||
interval_multiplier: "5",
|
||||
start_date: now,
|
||||
end_date: now,
|
||||
limit: "5000",
|
||||
});
|
||||
|
||||
const queryParamsThirtyDays = new URLSearchParams({
|
||||
ticker,
|
||||
interval: "minute",
|
||||
interval_multiplier: "30",
|
||||
start_date: oneMonthAgo,
|
||||
end_date: now,
|
||||
limit: "5000",
|
||||
});
|
||||
|
||||
const [resOneDay, resThirtyDays] = await Promise.all([
|
||||
fetch(`${url}?${queryParamsOneDay.toString()}`, options),
|
||||
fetch(`${url}?${queryParamsThirtyDays.toString()}`, options),
|
||||
]);
|
||||
if (!resOneDay.ok || !resThirtyDays.ok) {
|
||||
throw new Error("Failed to fetch prices");
|
||||
}
|
||||
const { prices: pricesOneDay } = await resOneDay.json();
|
||||
const { prices: pricesThirtyDays } = await resThirtyDays.json();
|
||||
|
||||
console.log("pricesOneDay", pricesOneDay.length);
|
||||
console.log("pricesThirtyDays", pricesThirtyDays.length);
|
||||
|
||||
return {
|
||||
oneDayPrices: pricesOneDay,
|
||||
thirtyDayPrices: pricesThirtyDays,
|
||||
};
|
||||
}
|
||||
|
||||
const llm = new ChatOpenAI({ model: "gpt-4o-mini", temperature: 0 });
|
||||
|
||||
@@ -48,15 +105,15 @@ export async function callTools(
|
||||
findToolCall("stock-price")<typeof getStockPriceSchema>,
|
||||
);
|
||||
const portfolioToolCall = message.tool_calls?.find(
|
||||
findToolCall("portfolio")<typeof getStockPriceSchema>,
|
||||
findToolCall("portfolio")<typeof getPortfolioSchema>,
|
||||
);
|
||||
|
||||
if (stockbrokerToolCall) {
|
||||
const instruction = `The stock price of ${
|
||||
stockbrokerToolCall.args.ticker
|
||||
} is ${Math.random() * 100}`;
|
||||
|
||||
ui.write("stock-price", { instruction, logo: "hey" });
|
||||
const prices = await getPricesForTicker(stockbrokerToolCall.args.ticker);
|
||||
ui.write("stock-price", {
|
||||
ticker: stockbrokerToolCall.args.ticker,
|
||||
...prices,
|
||||
});
|
||||
}
|
||||
|
||||
if (portfolioToolCall) {
|
||||
|
||||
Reference in New Issue
Block a user