@langgraph-js/sdk 1.5.5 → 1.6.1
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/.env +0 -0
- package/LICENSE +201 -201
- package/README.md +163 -163
- package/dist/LangGraphClient.d.ts +15 -4
- package/dist/LangGraphClient.js +46 -24
- package/dist/ui-store/createChatStore.js +1 -2
- package/package.json +1 -1
- package/src/LangGraphClient.ts +638 -622
- package/src/SpendTime.ts +60 -60
- package/src/ToolManager.ts +131 -131
- package/src/index.ts +5 -5
- package/src/tool/ToolUI.ts +33 -33
- package/src/tool/copilotkit-actions.ts +72 -72
- package/src/tool/createTool.ts +89 -89
- package/src/tool/index.ts +3 -3
- package/src/tool/utils.ts +158 -158
- package/src/ui-store/UnionStore.ts +29 -29
- package/src/ui-store/createChatStore.ts +294 -296
- package/src/ui-store/index.ts +2 -2
- package/src/ui-store/rafDebounce.ts +29 -29
- package/test/testResponse.json +5418 -5418
- package/tsconfig.json +112 -112
package/README.md
CHANGED
|
@@ -1,163 +1,163 @@
|
|
|
1
|
-
# @langgraph-js/sdk
|
|
2
|
-
|
|
3
|
-

|
|
4
|
-

|
|
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
|
+

|
|
4
|
+

|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { Client, Thread, Message, Assistant, HumanMessage, ToolMessage, Command } from "@langchain/langgraph-sdk";
|
|
1
|
+
import { Client, Thread, Message, Assistant, HumanMessage, AIMessage, ToolMessage, Command } from "@langchain/langgraph-sdk";
|
|
2
2
|
import { ToolManager } from "./ToolManager.js";
|
|
3
3
|
import { CallToolResult } from "./tool/createTool.js";
|
|
4
4
|
interface AsyncCallerParams {
|
|
@@ -71,8 +71,8 @@ export interface LangGraphClientConfig {
|
|
|
71
71
|
export declare class StreamingMessageType {
|
|
72
72
|
static isUser(m: Message): m is HumanMessage;
|
|
73
73
|
static isTool(m: Message): m is ToolMessage;
|
|
74
|
-
static isAssistant(m: Message):
|
|
75
|
-
static isToolAssistant(m: Message):
|
|
74
|
+
static isAssistant(m: Message): m is AIMessage;
|
|
75
|
+
static isToolAssistant(m: Message): m is AIMessage;
|
|
76
76
|
}
|
|
77
77
|
type StreamingUpdateEvent = {
|
|
78
78
|
type: "message" | "value" | "update" | "error" | "thread" | "done" | "start";
|
|
@@ -120,7 +120,8 @@ export declare class LangGraphClient extends Client {
|
|
|
120
120
|
graphMessages: RenderMessage[];
|
|
121
121
|
cloneMessage(message: Message): Message;
|
|
122
122
|
private updateStreamingMessage;
|
|
123
|
-
|
|
123
|
+
/** 将 graphMessages 和 streamingMessage 合并,并返回新的消息数组 */
|
|
124
|
+
private combineGraphMessagesWithStreamingMessages;
|
|
124
125
|
/**
|
|
125
126
|
* @zh 用于 UI 中的流式渲染中的消息。
|
|
126
127
|
* @en Messages used for streaming rendering in the UI.
|
|
@@ -165,6 +166,16 @@ export declare class LangGraphClient extends Client {
|
|
|
165
166
|
* @en Sends a message to the LangGraph backend.
|
|
166
167
|
*/
|
|
167
168
|
sendMessage(input: string | Message[], { extraParams, _debug, command }?: SendMessageOptions): Promise<any[]>;
|
|
169
|
+
/** 当前子图位置,但是依赖 stream,不太适合稳定使用*/
|
|
170
|
+
private graphPosition;
|
|
171
|
+
getGraphPosition(): {
|
|
172
|
+
id: string;
|
|
173
|
+
name: string;
|
|
174
|
+
}[];
|
|
175
|
+
getGraphNodeNow(): {
|
|
176
|
+
id: string;
|
|
177
|
+
name: string;
|
|
178
|
+
};
|
|
168
179
|
/** 子图的数据需要通过 merge 的方式重新进行合并更新 */
|
|
169
180
|
private mergeSubGraphMessagesToStreamingMessages;
|
|
170
181
|
private runFETool;
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -37,6 +37,8 @@ export class LangGraphClient extends Client {
|
|
|
37
37
|
/** 图发过来的更新信息 */
|
|
38
38
|
this.graphMessages = [];
|
|
39
39
|
this.graphState = {};
|
|
40
|
+
/** 当前子图位置,但是依赖 stream,不太适合稳定使用*/
|
|
41
|
+
this.graphPosition = "";
|
|
40
42
|
}
|
|
41
43
|
listAssistants() {
|
|
42
44
|
return this.assistants.search({
|
|
@@ -134,17 +136,20 @@ export class LangGraphClient extends Client {
|
|
|
134
136
|
}
|
|
135
137
|
this.streamingMessage[this.streamingMessage.length - 1] = message;
|
|
136
138
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
/** 将 graphMessages 和 streamingMessage 合并,并返回新的消息数组 */
|
|
140
|
+
combineGraphMessagesWithStreamingMessages() {
|
|
141
|
+
const idMap = new Map(this.streamingMessage.map((i) => [i.id, i]));
|
|
142
|
+
return [
|
|
143
|
+
...this.graphMessages.map((i) => {
|
|
144
|
+
if (idMap.has(i.id)) {
|
|
145
|
+
const newValue = idMap.get(i.id);
|
|
146
|
+
idMap.delete(i.id);
|
|
147
|
+
return newValue;
|
|
148
|
+
}
|
|
149
|
+
return i;
|
|
150
|
+
}),
|
|
151
|
+
...idMap.values(),
|
|
152
|
+
];
|
|
148
153
|
}
|
|
149
154
|
/**
|
|
150
155
|
* @zh 用于 UI 中的流式渲染中的消息。
|
|
@@ -155,7 +160,7 @@ export class LangGraphClient extends Client {
|
|
|
155
160
|
const previousMessage = new Map();
|
|
156
161
|
const closedToolCallIds = new Set();
|
|
157
162
|
const result = [];
|
|
158
|
-
const inputMessages =
|
|
163
|
+
const inputMessages = this.combineGraphMessagesWithStreamingMessages();
|
|
159
164
|
console.log(inputMessages);
|
|
160
165
|
// 从后往前遍历,这样可以保证最新的消息在前面
|
|
161
166
|
for (let i = inputMessages.length - 1; i >= 0; i--) {
|
|
@@ -164,12 +169,13 @@ export class LangGraphClient extends Client {
|
|
|
164
169
|
result.unshift(message);
|
|
165
170
|
continue;
|
|
166
171
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
if (message.type === "ai") {
|
|
173
|
+
/** @ts-ignore */
|
|
174
|
+
if (!message.name)
|
|
175
|
+
message.name = this.getGraphNodeNow().name;
|
|
170
176
|
}
|
|
171
177
|
if (StreamingMessageType.isToolAssistant(message)) {
|
|
172
|
-
const m =
|
|
178
|
+
const m = message;
|
|
173
179
|
// 记录这个 id 的消息,并添加到结果中
|
|
174
180
|
previousMessage.set(message.id, m);
|
|
175
181
|
/** @ts-ignore */
|
|
@@ -180,7 +186,7 @@ export class LangGraphClient extends Client {
|
|
|
180
186
|
})
|
|
181
187
|
.map((tool, index) => {
|
|
182
188
|
var _a, _b, _c, _d;
|
|
183
|
-
return
|
|
189
|
+
return {
|
|
184
190
|
type: "tool",
|
|
185
191
|
additional_kwargs: {},
|
|
186
192
|
/** @ts-ignore */
|
|
@@ -189,7 +195,8 @@ export class LangGraphClient extends Client {
|
|
|
189
195
|
name: tool.name,
|
|
190
196
|
response_metadata: {},
|
|
191
197
|
tool_call_id: tool.id,
|
|
192
|
-
|
|
198
|
+
content: "",
|
|
199
|
+
};
|
|
193
200
|
});
|
|
194
201
|
for (const tool of new_tool_calls) {
|
|
195
202
|
if (!previousMessage.has(tool.id)) {
|
|
@@ -203,10 +210,8 @@ export class LangGraphClient extends Client {
|
|
|
203
210
|
if (message.type === "tool" && message.tool_call_id) {
|
|
204
211
|
closedToolCallIds.add(message.tool_call_id);
|
|
205
212
|
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
previousMessage.set(message.id, m);
|
|
209
|
-
result.unshift(m);
|
|
213
|
+
previousMessage.set(message.id, message);
|
|
214
|
+
result.unshift(message);
|
|
210
215
|
}
|
|
211
216
|
}
|
|
212
217
|
return this.attachInfoForMessage(this.composeToolMessages(result));
|
|
@@ -245,7 +250,7 @@ export class LangGraphClient extends Client {
|
|
|
245
250
|
* @en Composes tool messages, associating AI tool calls with tool execution results.
|
|
246
251
|
*/
|
|
247
252
|
composeToolMessages(messages) {
|
|
248
|
-
var _a;
|
|
253
|
+
var _a, _b;
|
|
249
254
|
const result = [];
|
|
250
255
|
const assistantToolMessages = new Map();
|
|
251
256
|
const toolParentMessage = new Map();
|
|
@@ -278,8 +283,11 @@ export class LangGraphClient extends Client {
|
|
|
278
283
|
if (parentMessage) {
|
|
279
284
|
message.usage_metadata = parentMessage.usage_metadata;
|
|
280
285
|
message.node_name = parentMessage.name;
|
|
286
|
+
// 修补特殊情况下,tool name 丢失的问题
|
|
287
|
+
if (!message.name) {
|
|
288
|
+
message.name = (_b = parentMessage.tool_calls.find((i) => i.id === message.tool_call_id)) === null || _b === void 0 ? void 0 : _b.name;
|
|
289
|
+
}
|
|
281
290
|
}
|
|
282
|
-
message.id = message.tool_call_id;
|
|
283
291
|
}
|
|
284
292
|
result.push(message);
|
|
285
293
|
}
|
|
@@ -418,6 +426,7 @@ export class LangGraphClient extends Client {
|
|
|
418
426
|
if (chunk.data.messages) {
|
|
419
427
|
this.mergeSubGraphMessagesToStreamingMessages(chunk.data.messages);
|
|
420
428
|
}
|
|
429
|
+
this.graphPosition = chunk.event.split("|")[1];
|
|
421
430
|
}
|
|
422
431
|
}
|
|
423
432
|
const data = await this.runFETool();
|
|
@@ -432,6 +441,19 @@ export class LangGraphClient extends Client {
|
|
|
432
441
|
this.streamingMessage = [];
|
|
433
442
|
return streamRecord;
|
|
434
443
|
}
|
|
444
|
+
getGraphPosition() {
|
|
445
|
+
return this.graphPosition.split("|").map((i) => {
|
|
446
|
+
const [name, id] = i.split(":");
|
|
447
|
+
return {
|
|
448
|
+
id,
|
|
449
|
+
name,
|
|
450
|
+
};
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
getGraphNodeNow() {
|
|
454
|
+
const position = this.getGraphPosition();
|
|
455
|
+
return position[position.length - 1];
|
|
456
|
+
}
|
|
435
457
|
/** 子图的数据需要通过 merge 的方式重新进行合并更新 */
|
|
436
458
|
mergeSubGraphMessagesToStreamingMessages(messages) {
|
|
437
459
|
const map = new Map(messages.filter((i) => i.id).map((i) => [i.id, i]));
|
|
@@ -102,9 +102,8 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
102
102
|
// await newClient.createThread();
|
|
103
103
|
inChatError.set(null);
|
|
104
104
|
newClient.onStreamingUpdate((event) => {
|
|
105
|
-
if (event.type === "start")
|
|
105
|
+
if (event.type === "start")
|
|
106
106
|
loading.set(true);
|
|
107
|
-
}
|
|
108
107
|
if (event.type === "thread" || event.type === "done") {
|
|
109
108
|
// console.log(event.data);
|
|
110
109
|
// 创建新流程时,默认为 __start__
|