import { StateGraph, MessagesAnnotation } from "@langchain/langgraph";
import { ToolNode } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
// Define tools
const weatherTool = tool(
async ({ location }) => {
// Weather API call
return `Weather in ${location}: 72°F, sunny`;
},
{
name: "get_weather",
description: "Get the current weather for a location",
schema: z.object({
location: z.string().describe("The city name"),
}),
}
);
const tools = [weatherTool];
// Initialize model with tools
const model = new ChatOpenAI({
apiKey: process.env.NORDLYS_API_KEY,
configuration: {
baseURL: "https://api.nordlyslabs.com/v1",
},
modelName: "nordlys/hypernova",
temperature: 0,
}).bindTools(tools);
// Define the agent function
async function callModel(state: typeof MessagesAnnotation.State) {
const response = await model.invoke(state.messages);
return { messages: [response] };
}
// Model selection function
function shouldContinue(state: typeof MessagesAnnotation.State) {
const messages = state.messages;
const lastMessage = messages[messages.length - 1];
if (
lastMessage &&
typeof lastMessage === "object" &&
"tool_calls" in lastMessage &&
Array.isArray(lastMessage.tool_calls) &&
lastMessage.tool_calls.length > 0
) {
return "tools";
}
return "__end__";
}
// Create the graph
const workflow = new StateGraph(MessagesAnnotation)
.addNode("agent", callModel)
.addNode("tools", new ToolNode(tools))
.addEdge("__start__", "agent")
.addConditionalEdges("agent", shouldContinue)
.addEdge("tools", "agent");
const app = workflow.compile();
// Use the agent
const result = await app.invoke({
messages: [{ role: "user", content: "What's the weather in San Francisco?" }],
});