generated from langchain-ai/langgraphjs-starter-template
-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathgraph.ts
104 lines (99 loc) · 3.06 KB
/
graph.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/**
* 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";