feat: Implement stock price component and api

This commit is contained in:
bracesproul
2025-03-05 18:02:46 -08:00
parent 10da745533
commit 06b865c1c2
8 changed files with 1116 additions and 937 deletions

View File

@@ -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) {

View File

@@ -25,3 +25,13 @@ export type Accommodation = {
city: string;
image: string;
};
export type Price = {
ticker: string;
open: number;
close: number;
high: number;
low: number;
volume: number;
time: string;
};

File diff suppressed because it is too large Load Diff