@langgraph-js/sdk 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,163 +1,163 @@
1
- # @langgraph-js/sdk
2
-
3
- ![npm version](https://img.shields.io/npm/v/@langgraph-js/sdk)
4
- ![license](https://img.shields.io/npm/l/@langgraph-js/sdk)
5
-
6
- > The missing UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces
7
-
8
- ## Why @langgraph-js/sdk?
9
-
10
- Building AI agent applications is complex, especially when you need to bridge the gap between LangGraph agents and interactive user interfaces. This SDK solves the critical challenges of frontend integration:
11
-
12
- - **Provides a complete UI integration layer** - no more complex custom code to handle tools, streaming, and state management
13
- - **Simplifies human-in-the-loop interactions** - easily incorporate user feedback within agent workflows
14
- - **Handles edge cases automatically** - interruptions, errors, token management and more
15
- - **Offers a rich set of UI components** - ready-to-use elements to display agent interactions
16
-
17
- [DOCS](https://langgraph-js.netlify.app)
18
-
19
- ## Installation
20
-
21
- ```bash
22
- # Using npm
23
- npm install @langgraph-js/sdk
24
-
25
- # Using yarn
26
- yarn add @langgraph-js/sdk
27
-
28
- # Using pnpm
29
- pnpm add @langgraph-js/sdk
30
- ```
31
-
32
- ## Key Features
33
-
34
- ### Generative UI
35
-
36
- - ✅ Custom Tool Messages
37
- - ✅ Token Counter
38
- - ✅ Stop Graph Progress
39
- - ✅ Interrupt Handling
40
- - ✅ Error Handling
41
- - ✅ Spend Time Tracking
42
- - ✅ Time Persistence
43
-
44
- ### Frontend Actions
45
-
46
- - ✅ Definition of Union Tools
47
- - ✅ Frontend Functions As Tools
48
- - ✅ Human-in-the-Loop Interaction
49
- - ✅ Interrupt Mode
50
-
51
- ### Authorization
52
-
53
- - ✅ Cookie-Based Authentication
54
- - ✅ Custom Token Authentication
55
-
56
- ### Persistence
57
-
58
- - ✅ Read History from LangGraph
59
-
60
- ## Advanced Usage
61
-
62
- ### Creating a Chat Store
63
-
64
- You can easily create a reactive store for your LangGraph client:
65
-
66
- ```typescript
67
- import { createChatStore } from "@langgraph-js/sdk";
68
-
69
- export const globalChatStore = createChatStore(
70
- "agent",
71
- {
72
- // Custom LangGraph backend interaction
73
- apiUrl: "http://localhost:8123",
74
- // Custom headers for authentication
75
- defaultHeaders: JSON.parse(localStorage.getItem("code") || "{}"),
76
- callerOptions: {
77
- // Example for including cookies
78
- // fetch(url: string, options: RequestInit) {
79
- // options.credentials = "include";
80
- // return fetch(url, options);
81
- // },
82
- },
83
- },
84
- {
85
- onInit(client) {
86
- client.tools.bindTools([]);
87
- },
88
- }
89
- );
90
- ```
91
-
92
- ### React Integration
93
-
94
- First, install the nanostores React integration:
95
-
96
- ```bash
97
- pnpm i @nanostores/react
98
- ```
99
-
100
- Then create a context provider for your chat:
101
-
102
- ```tsx
103
- import React, { createContext, useContext, useEffect } from "react";
104
- import { globalChatStore } from "../store"; // Import your store
105
- import { UnionStore, useUnionStore } from "@langgraph-js/sdk";
106
- import { useStore } from "@nanostores/react";
107
-
108
- type ChatContextType = UnionStore<typeof globalChatStore>;
109
-
110
- const ChatContext = createContext<ChatContextType | undefined>(undefined);
111
-
112
- export const useChat = () => {
113
- const context = useContext(ChatContext);
114
- if (!context) {
115
- throw new Error("useChat must be used within a ChatProvider");
116
- }
117
- return context;
118
- };
119
-
120
- export const ChatProvider = ({ children }) => {
121
- // Use store to ensure React gets reactive state updates
122
- const store = useUnionStore(globalChatStore, useStore);
123
-
124
- useEffect(() => {
125
- // Initialize client
126
- store.initClient().then(() => {
127
- // Initialize conversation history
128
- store.refreshHistoryList();
129
- });
130
- }, [store.currentAgent]);
131
-
132
- return <ChatContext.Provider value={store}>{children}</ChatContext.Provider>;
133
- };
134
- ```
135
-
136
- Use it in your components:
137
-
138
- ```tsx
139
- export const MyChat = () => {
140
- return (
141
- <ChatProvider>
142
- <ChatComp></ChatComp>
143
- </ChatProvider>
144
- );
145
- };
146
-
147
- function ChatComp() {
148
- const chat = useChat();
149
- // Use chat store methods and state here
150
- }
151
- ```
152
-
153
- ## Documentation
154
-
155
- For complete documentation, visit our [official docs](https://langgraph-js.netlify.app).
156
-
157
- ## Contributing
158
-
159
- Contributions are welcome! Please feel free to submit a Pull Request.
160
-
161
- ## License
162
-
163
- This project is licensed under the Apache-2.0 License.
1
+ # @langgraph-js/sdk
2
+
3
+ ![npm version](https://img.shields.io/npm/v/@langgraph-js/sdk)
4
+ ![license](https://img.shields.io/npm/l/@langgraph-js/sdk)
5
+
6
+ > The missing UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces
7
+
8
+ ## Why @langgraph-js/sdk?
9
+
10
+ Building AI agent applications is complex, especially when you need to bridge the gap between LangGraph agents and interactive user interfaces. This SDK solves the critical challenges of frontend integration:
11
+
12
+ - **Provides a complete UI integration layer** - no more complex custom code to handle tools, streaming, and state management
13
+ - **Simplifies human-in-the-loop interactions** - easily incorporate user feedback within agent workflows
14
+ - **Handles edge cases automatically** - interruptions, errors, token management and more
15
+ - **Offers a rich set of UI components** - ready-to-use elements to display agent interactions
16
+
17
+ [DOCS](https://langgraph-js.netlify.app)
18
+
19
+ ## Installation
20
+
21
+ ```bash
22
+ # Using npm
23
+ npm install @langgraph-js/sdk
24
+
25
+ # Using yarn
26
+ yarn add @langgraph-js/sdk
27
+
28
+ # Using pnpm
29
+ pnpm add @langgraph-js/sdk
30
+ ```
31
+
32
+ ## Key Features
33
+
34
+ ### Generative UI
35
+
36
+ - ✅ Custom Tool Messages
37
+ - ✅ Token Counter
38
+ - ✅ Stop Graph Progress
39
+ - ✅ Interrupt Handling
40
+ - ✅ Error Handling
41
+ - ✅ Spend Time Tracking
42
+ - ✅ Time Persistence
43
+
44
+ ### Frontend Actions
45
+
46
+ - ✅ Definition of Union Tools
47
+ - ✅ Frontend Functions As Tools
48
+ - ✅ Human-in-the-Loop Interaction
49
+ - ✅ Interrupt Mode
50
+
51
+ ### Authorization
52
+
53
+ - ✅ Cookie-Based Authentication
54
+ - ✅ Custom Token Authentication
55
+
56
+ ### Persistence
57
+
58
+ - ✅ Read History from LangGraph
59
+
60
+ ## Advanced Usage
61
+
62
+ ### Creating a Chat Store
63
+
64
+ You can easily create a reactive store for your LangGraph client:
65
+
66
+ ```typescript
67
+ import { createChatStore } from "@langgraph-js/sdk";
68
+
69
+ export const globalChatStore = createChatStore(
70
+ "agent",
71
+ {
72
+ // Custom LangGraph backend interaction
73
+ apiUrl: "http://localhost:8123",
74
+ // Custom headers for authentication
75
+ defaultHeaders: JSON.parse(localStorage.getItem("code") || "{}"),
76
+ callerOptions: {
77
+ // Example for including cookies
78
+ // fetch(url: string, options: RequestInit) {
79
+ // options.credentials = "include";
80
+ // return fetch(url, options);
81
+ // },
82
+ },
83
+ },
84
+ {
85
+ onInit(client) {
86
+ client.tools.bindTools([]);
87
+ },
88
+ }
89
+ );
90
+ ```
91
+
92
+ ### React Integration
93
+
94
+ First, install the nanostores React integration:
95
+
96
+ ```bash
97
+ pnpm i @nanostores/react
98
+ ```
99
+
100
+ Then create a context provider for your chat:
101
+
102
+ ```tsx
103
+ import React, { createContext, useContext, useEffect } from "react";
104
+ import { globalChatStore } from "../store"; // Import your store
105
+ import { UnionStore, useUnionStore } from "@langgraph-js/sdk";
106
+ import { useStore } from "@nanostores/react";
107
+
108
+ type ChatContextType = UnionStore<typeof globalChatStore>;
109
+
110
+ const ChatContext = createContext<ChatContextType | undefined>(undefined);
111
+
112
+ export const useChat = () => {
113
+ const context = useContext(ChatContext);
114
+ if (!context) {
115
+ throw new Error("useChat must be used within a ChatProvider");
116
+ }
117
+ return context;
118
+ };
119
+
120
+ export const ChatProvider = ({ children }) => {
121
+ // Use store to ensure React gets reactive state updates
122
+ const store = useUnionStore(globalChatStore, useStore);
123
+
124
+ useEffect(() => {
125
+ // Initialize client
126
+ store.initClient().then(() => {
127
+ // Initialize conversation history
128
+ store.refreshHistoryList();
129
+ });
130
+ }, [store.currentAgent]);
131
+
132
+ return <ChatContext.Provider value={store}>{children}</ChatContext.Provider>;
133
+ };
134
+ ```
135
+
136
+ Use it in your components:
137
+
138
+ ```tsx
139
+ export const MyChat = () => {
140
+ return (
141
+ <ChatProvider>
142
+ <ChatComp></ChatComp>
143
+ </ChatProvider>
144
+ );
145
+ };
146
+
147
+ function ChatComp() {
148
+ const chat = useChat();
149
+ // Use chat store methods and state here
150
+ }
151
+ ```
152
+
153
+ ## Documentation
154
+
155
+ For complete documentation, visit our [official docs](https://langgraph-js.netlify.app).
156
+
157
+ ## Contributing
158
+
159
+ Contributions are welcome! Please feel free to submit a Pull Request.
160
+
161
+ ## License
162
+
163
+ This project is licensed under the Apache-2.0 License.
@@ -21,6 +21,10 @@ interface AsyncCallerParams {
21
21
  fetch?: typeof fetch | ((...args: any[]) => any);
22
22
  }
23
23
  export type RenderMessage = Message & {
24
+ /** 对于 AIMessage 来说是节点名称,对于工具节点来说是工具名称 */
25
+ name?: string;
26
+ /** 工具节点的触发节点名称 */
27
+ node_name?: string;
24
28
  /** 工具入参 ,聚合而来*/
25
29
  tool_input?: string;
26
30
  additional_kwargs?: {
@@ -55,7 +55,6 @@ export class LangGraphClient extends Client {
55
55
  this.availableAssistants = assistants;
56
56
  if (assistants.length > 0) {
57
57
  if (agentName) {
58
- console.log("agentName", agentName);
59
58
  this.currentAssistant = assistants.find((assistant) => assistant.graph_id === agentName) || null;
60
59
  if (!this.currentAssistant) {
61
60
  throw new Error("Agent not found: " + agentName);
@@ -261,6 +260,7 @@ export class LangGraphClient extends Client {
261
260
  }
262
261
  if (parentMessage) {
263
262
  message.usage_metadata = parentMessage.usage_metadata;
263
+ message.node_name = parentMessage.name;
264
264
  }
265
265
  }
266
266
  result.push(message);
@@ -472,12 +472,13 @@ export class LangGraphClient extends Client {
472
472
  */
473
473
  async reset() {
474
474
  var _a;
475
- await this.initAssistant((_a = this.currentAssistant) === null || _a === void 0 ? void 0 : _a.name);
475
+ await this.initAssistant((_a = this.currentAssistant) === null || _a === void 0 ? void 0 : _a.graph_id);
476
476
  this.currentThread = null;
477
477
  this.graphState = {};
478
478
  this.graphMessages = [];
479
479
  this.streamingMessage = [];
480
480
  this.currentRun = undefined;
481
+ this.tools.reset();
481
482
  this.emitStreamingUpdate({
482
483
  type: "value",
483
484
  data: {
@@ -7,6 +7,7 @@ import { CallToolResult, UnionTool } from "./tool/createTool.js";
7
7
  */
8
8
  export declare class ToolManager {
9
9
  private tools;
10
+ private waitingMap;
10
11
  /**
11
12
  * @zh 注册一个工具。
12
13
  * @en Registers a tool.
@@ -37,6 +38,7 @@ export declare class ToolManager {
37
38
  * @en Clears all tools.
38
39
  */
39
40
  clearTools(): void;
41
+ reset(): void;
40
42
  /**
41
43
  * @zh 调用指定名称的工具。
42
44
  * @en Calls the tool with the specified name.
@@ -59,7 +61,6 @@ export declare class ToolManager {
59
61
  } | undefined;
60
62
  };
61
63
  }[];
62
- private waitingMap;
63
64
  /**
64
65
  * @zh 标记指定 ID 的工具等待已完成,并传递结果。
65
66
  * @en Marks the tool waiting with the specified ID as completed and passes the result.
@@ -54,6 +54,10 @@ export class ToolManager {
54
54
  clearTools() {
55
55
  this.tools.clear();
56
56
  }
57
+ reset() {
58
+ this.clearTools();
59
+ this.waitingMap.clear();
60
+ }
57
61
  /**
58
62
  * @zh 调用指定名称的工具。
59
63
  * @en Calls the tool with the specified name.
@@ -44,6 +44,7 @@ export declare const createChatStore: (initClientName: string, config: LangGraph
44
44
  currentChatId: import("nanostores").PreinitializedWritableAtom<string | null> & object;
45
45
  showGraph: import("nanostores").PreinitializedWritableAtom<boolean> & object;
46
46
  graphVisualize: import("nanostores").PreinitializedWritableAtom<AssistantGraph | null> & object;
47
+ currentNodeName: import("nanostores").PreinitializedWritableAtom<string> & object;
47
48
  };
48
49
  mutations: {
49
50
  initClient: () => Promise<LangGraphClient>;
@@ -73,6 +73,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
73
73
  const showHistory = atom((_a = context.showHistory) !== null && _a !== void 0 ? _a : false);
74
74
  const currentAgent = atom(initClientName);
75
75
  const currentChatId = atom(null);
76
+ const currentNodeName = atom("__start__");
76
77
  // 显示 langgraph 可视化图
77
78
  const showGraph = atom((_b = context.showGraph) !== null && _b !== void 0 ? _b : false);
78
79
  const graphVisualize = atom(null);
@@ -82,7 +83,10 @@ export const createChatStore = (initClientName, config, context = {}) => {
82
83
  graphVisualize.set((await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.graphVisualize())) || null);
83
84
  };
84
85
  const updateUI = rafDebounce((newClient) => {
85
- renderMessages.set(newClient.renderMessage);
86
+ const messages = newClient.renderMessage;
87
+ const lastMessage = messages[messages.length - 1];
88
+ currentNodeName.set((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.node_name) || (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.name) || "__start__");
89
+ renderMessages.set(messages);
86
90
  });
87
91
  /**
88
92
  * @zh 初始化 LangGraph 客户端。
@@ -99,6 +103,8 @@ export const createChatStore = (initClientName, config, context = {}) => {
99
103
  newClient.onStreamingUpdate((event) => {
100
104
  if (event.type === "thread" || event.type === "done") {
101
105
  // console.log(event.data);
106
+ // 创建新流程时,默认为 __start__
107
+ currentNodeName.set("__start__");
102
108
  // 创建新会话时,需要自动刷新历史面板
103
109
  return refreshHistoryList();
104
110
  }
@@ -195,6 +201,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
195
201
  currentChatId,
196
202
  showGraph,
197
203
  graphVisualize,
204
+ currentNodeName,
198
205
  },
199
206
  mutations: {
200
207
  initClient,
@@ -241,6 +248,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
241
248
  var _a;
242
249
  (_a = client.get()) === null || _a === void 0 ? void 0 : _a.reset();
243
250
  inChatError.set(null);
251
+ loading.set(false);
244
252
  },
245
253
  /**
246
254
  * @zh 切换到指定的历史聊天会话。
@@ -248,6 +256,8 @@ export const createChatStore = (initClientName, config, context = {}) => {
248
256
  */
249
257
  toHistoryChat(thread) {
250
258
  var _a, _b;
259
+ inChatError.set(null);
260
+ loading.set(false);
251
261
  (_a = client.get()) === null || _a === void 0 ? void 0 : _a.resetThread((_b = thread.metadata) === null || _b === void 0 ? void 0 : _b.graph_id, thread.thread_id);
252
262
  },
253
263
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgraph-js/sdk",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "description": "The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -29,12 +29,11 @@
29
29
  "url": "https://github.com/KonghaYao/YaoAgent/issues"
30
30
  },
31
31
  "dependencies": {
32
- "@langchain/langgraph-sdk": "^0.0.76",
32
+ "@langchain/langgraph-sdk": "^0.0.77",
33
33
  "nanostores": "^1.0.1",
34
- "zod": "^3.24.3",
35
- "zod-to-json-schema": "^3.24.3"
34
+ "zod": "^3.25.17",
35
+ "zod-to-json-schema": "^3.24.5"
36
36
  },
37
- "devDependencies": {},
38
37
  "scripts": {
39
38
  "build": "tsc",
40
39
  "prepublish": "pnpm build"