mirror of
https://github.com/langchain-ai/langgraph.git
synced 2026-08-17 21:25:46 +02:00
Added a js-example to show it builds Adapted integration tests after removing the test CLI command --------- Co-authored-by: Nuno Campos <nuno@langchain.dev>
105 lines
3.1 KiB
TypeScript
105 lines
3.1 KiB
TypeScript
/**
|
|
* Starter LangGraph.js Template
|
|
* Make this code your own!
|
|
*/
|
|
import { StateGraph } from "@langchain/langgraph";
|
|
import { RunnableConfig } from "@langchain/core/runnables";
|
|
import { StateAnnotation } from "./state.js";
|
|
|
|
/**
|
|
* Define a node, these do the work of the graph and should have most of the logic.
|
|
* Must return a subset of the properties set in StateAnnotation.
|
|
* @param state The current state of the graph.
|
|
* @param config Extra parameters passed into the state graph.
|
|
* @returns Some subset of parameters of the graph state, used to update the state
|
|
* for the edges and nodes executed next.
|
|
*/
|
|
const callModel = async (
|
|
state: typeof StateAnnotation.State,
|
|
_config: RunnableConfig,
|
|
): Promise<typeof StateAnnotation.Update> => {
|
|
/**
|
|
* Do some work... (e.g. call an LLM)
|
|
* For example, with LangChain you could do something like:
|
|
*
|
|
* ```bash
|
|
* $ npm i @langchain/anthropic
|
|
* ```
|
|
*
|
|
* ```ts
|
|
* import { ChatAnthropic } from "@langchain/anthropic";
|
|
* const model = new ChatAnthropic({
|
|
* model: "claude-3-5-sonnet-20240620",
|
|
* apiKey: process.env.ANTHROPIC_API_KEY,
|
|
* });
|
|
* const res = await model.invoke(state.messages);
|
|
* ```
|
|
*
|
|
* Or, with an SDK directly:
|
|
*
|
|
* ```bash
|
|
* $ npm i openai
|
|
* ```
|
|
*
|
|
* ```ts
|
|
* import OpenAI from "openai";
|
|
* const openai = new OpenAI({
|
|
* apiKey: process.env.OPENAI_API_KEY,
|
|
* });
|
|
*
|
|
* const chatCompletion = await openai.chat.completions.create({
|
|
* messages: [{
|
|
* role: state.messages[0]._getType(),
|
|
* content: state.messages[0].content,
|
|
* }],
|
|
* model: "gpt-4o-mini",
|
|
* });
|
|
* ```
|
|
*/
|
|
console.log("Current state:", state);
|
|
return {
|
|
messages: [
|
|
{
|
|
role: "assistant",
|
|
content: `Hi there! How are you?`,
|
|
},
|
|
],
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Routing function: Determines whether to continue research or end the builder.
|
|
* This function decides if the gathered information is satisfactory or if more research is needed.
|
|
*
|
|
* @param state - The current state of the research builder
|
|
* @returns Either "callModel" to continue research or END to finish the builder
|
|
*/
|
|
export const route = (
|
|
state: typeof StateAnnotation.State,
|
|
): "__end__" | "callModel" => {
|
|
if (state.messages.length > 0) {
|
|
return "__end__";
|
|
}
|
|
// Loop back
|
|
return "callModel";
|
|
};
|
|
|
|
// Finally, create the graph itself.
|
|
const builder = new StateGraph(StateAnnotation)
|
|
// Add the nodes to do the work.
|
|
// Chaining the nodes together in this way
|
|
// updates the types of the StateGraph instance
|
|
// so you have static type checking when it comes time
|
|
// to add the edges.
|
|
.addNode("callModel", callModel)
|
|
// Regular edges mean "always transition to node B after node A is done"
|
|
// The "__start__" and "__end__" nodes are "virtual" nodes that are always present
|
|
// and represent the beginning and end of the builder.
|
|
.addEdge("__start__", "callModel")
|
|
// Conditional edges optionally route to different nodes (or end)
|
|
.addConditionalEdges("callModel", route);
|
|
|
|
export const graph = builder.compile();
|
|
|
|
graph.name = "New Agent";
|