@langgraph-js/sdk 3.3.1 → 3.4.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/dist/LangGraphClient.d.ts +1 -0
- package/dist/LangGraphClient.js +6 -1
- package/dist/MessageProcessor.d.ts +9 -3
- package/dist/MessageProcessor.js +10 -9
- package/dist/artifacts/types.d.ts +5 -1
- package/dist/tool/createTool.d.ts +6 -6
- package/package.json +2 -2
- package/src/LangGraphClient.ts +5 -1
- package/src/MessageProcessor.ts +35 -8
- package/src/tool/createTool.ts +6 -6
|
@@ -222,6 +222,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
|
|
|
222
222
|
revertChatTo(messageId: string): Promise<{
|
|
223
223
|
messages: Message[];
|
|
224
224
|
}>;
|
|
225
|
+
messagesMetadata: {};
|
|
225
226
|
/**
|
|
226
227
|
* @zh 发送消息到 LangGraph 后端。
|
|
227
228
|
* @en Sends a message to the LangGraph backend.
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -17,6 +17,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
17
17
|
this.stopController = null;
|
|
18
18
|
/** 用于存储 subAgent 状态数据的键 */
|
|
19
19
|
this.subAgentsKey = "task_store";
|
|
20
|
+
this.messagesMetadata = {};
|
|
20
21
|
/** 当前子图位置,但是依赖 stream,不太适合稳定使用*/
|
|
21
22
|
this.graphPosition = "";
|
|
22
23
|
this.extraParams = {};
|
|
@@ -146,7 +147,7 @@ export class LangGraphClient extends EventEmitter {
|
|
|
146
147
|
* @en Messages used for streaming rendering in the UI.
|
|
147
148
|
*/
|
|
148
149
|
get renderMessage() {
|
|
149
|
-
return this.messageProcessor.renderMessages(this.graphState, () => this.getGraphNodeNow());
|
|
150
|
+
return this.messageProcessor.renderMessages(this.graphState, () => this.getGraphNodeNow(), this.messagesMetadata);
|
|
150
151
|
}
|
|
151
152
|
/**
|
|
152
153
|
* @zh 获取 Token 计数器信息。
|
|
@@ -263,6 +264,10 @@ export class LangGraphClient extends EventEmitter {
|
|
|
263
264
|
else if (chunk.event === "error" || chunk.event === "Error" || chunk.event === "__stream_error__") {
|
|
264
265
|
this.emit("error", chunk);
|
|
265
266
|
}
|
|
267
|
+
else if (chunk.event === "messages/metadata") {
|
|
268
|
+
Object.assign(this.messagesMetadata, chunk.data);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
266
271
|
else if (chunk.event === "messages/partial") {
|
|
267
272
|
for (const message of chunk.data) {
|
|
268
273
|
this.messageProcessor.updateStreamingMessage(message);
|
|
@@ -78,17 +78,23 @@ export declare class MessageProcessor {
|
|
|
78
78
|
* @zh 转换 subAgent 消息为工具的子消息
|
|
79
79
|
* @en Convert subAgent messages to tool sub-messages
|
|
80
80
|
*/
|
|
81
|
-
convertSubAgentMessages(messages: RenderMessage[], graphState: any
|
|
81
|
+
convertSubAgentMessages(messages: RenderMessage[], graphState: any, messagesMetadata: Record<string, {
|
|
82
|
+
subagent_id?: string;
|
|
83
|
+
}>): RenderMessage[];
|
|
82
84
|
/**
|
|
83
85
|
* @zh 生成用于 UI 中的流式渲染的消息
|
|
84
86
|
* @en Generate messages used for streaming rendering in the UI
|
|
85
87
|
*/
|
|
86
88
|
renderMessages(graphState: any, getGraphNodeNow: () => {
|
|
87
89
|
name: string;
|
|
88
|
-
}
|
|
90
|
+
}, messagesMetadata: Record<string, {
|
|
91
|
+
subagent_id?: string;
|
|
92
|
+
}>): RenderMessage[];
|
|
89
93
|
/**
|
|
90
94
|
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
91
95
|
* @en Unified message processing entry point, executing all processing steps in order
|
|
92
96
|
*/
|
|
93
|
-
processMessages(messages: RenderMessage[], graphState
|
|
97
|
+
processMessages(messages: RenderMessage[], graphState: any, messagesMetadata: Record<string, {
|
|
98
|
+
subagent_id?: string;
|
|
99
|
+
}>): RenderMessage[];
|
|
94
100
|
}
|
package/dist/MessageProcessor.js
CHANGED
|
@@ -194,7 +194,7 @@ export class MessageProcessor {
|
|
|
194
194
|
* @zh 转换 subAgent 消息为工具的子消息
|
|
195
195
|
* @en Convert subAgent messages to tool sub-messages
|
|
196
196
|
*/
|
|
197
|
-
convertSubAgentMessages(messages, graphState) {
|
|
197
|
+
convertSubAgentMessages(messages, graphState, messagesMetadata) {
|
|
198
198
|
const origin_task_store = graphState[this.subAgentsKey];
|
|
199
199
|
if (!origin_task_store)
|
|
200
200
|
return messages;
|
|
@@ -202,11 +202,12 @@ export class MessageProcessor {
|
|
|
202
202
|
/** 获取 subAgent 消息的 id,用于流式过程中对数据进行标记 */
|
|
203
203
|
messages
|
|
204
204
|
.filter((i) => {
|
|
205
|
-
var _a;
|
|
206
|
-
return (_a = i.
|
|
205
|
+
var _a, _b;
|
|
206
|
+
return ((_a = messagesMetadata[i.id]) === null || _a === void 0 ? void 0 : _a.subagent_id) || ((_b = i.node_name) === null || _b === void 0 ? void 0 : _b.startsWith("subagent_"));
|
|
207
207
|
})
|
|
208
208
|
.forEach((i) => {
|
|
209
|
-
|
|
209
|
+
var _a;
|
|
210
|
+
const tool_call_id = ((_a = messagesMetadata[i.id]) === null || _a === void 0 ? void 0 : _a.subagent_id) || i.node_name.replace("subagent_", "");
|
|
210
211
|
const store = task_store[tool_call_id];
|
|
211
212
|
if (store) {
|
|
212
213
|
// 根据 id 进行去重
|
|
@@ -233,7 +234,7 @@ export class MessageProcessor {
|
|
|
233
234
|
const task = task_store[message.tool_call_id];
|
|
234
235
|
if (task) {
|
|
235
236
|
// 递归处理子消息,但避免重复处理
|
|
236
|
-
message.sub_agent_messages = this.processMessages(task.messages);
|
|
237
|
+
message.sub_agent_messages = this.processMessages(task.messages, task, messagesMetadata);
|
|
237
238
|
}
|
|
238
239
|
}
|
|
239
240
|
if (message.id && ignoreIds.has(message.id))
|
|
@@ -246,7 +247,7 @@ export class MessageProcessor {
|
|
|
246
247
|
* @zh 生成用于 UI 中的流式渲染的消息
|
|
247
248
|
* @en Generate messages used for streaming rendering in the UI
|
|
248
249
|
*/
|
|
249
|
-
renderMessages(graphState, getGraphNodeNow) {
|
|
250
|
+
renderMessages(graphState, getGraphNodeNow, messagesMetadata) {
|
|
250
251
|
var _a;
|
|
251
252
|
const previousMessage = new Map();
|
|
252
253
|
const closedToolCallIds = new Set();
|
|
@@ -304,20 +305,20 @@ export class MessageProcessor {
|
|
|
304
305
|
result.unshift(message);
|
|
305
306
|
}
|
|
306
307
|
}
|
|
307
|
-
return this.processMessages(result, graphState);
|
|
308
|
+
return this.processMessages(result, graphState, messagesMetadata);
|
|
308
309
|
}
|
|
309
310
|
/**
|
|
310
311
|
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
311
312
|
* @en Unified message processing entry point, executing all processing steps in order
|
|
312
313
|
*/
|
|
313
|
-
processMessages(messages, graphState) {
|
|
314
|
+
processMessages(messages, graphState, messagesMetadata) {
|
|
314
315
|
// 1. 组合工具消息
|
|
315
316
|
const composedMessages = this.composeToolMessages(messages);
|
|
316
317
|
// 2. 附加信息
|
|
317
318
|
const messagesWithInfo = this.attachInfoForMessage(composedMessages);
|
|
318
319
|
// 3. 转换子代理消息(如果提供了 graphState)
|
|
319
320
|
if (graphState) {
|
|
320
|
-
return this.convertSubAgentMessages(messagesWithInfo, graphState);
|
|
321
|
+
return this.convertSubAgentMessages(messagesWithInfo, graphState, messagesMetadata);
|
|
321
322
|
}
|
|
322
323
|
return messagesWithInfo;
|
|
323
324
|
}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export declare const ArtifactCommandSchema: {
|
|
3
|
-
command: z.ZodEnum<
|
|
3
|
+
command: z.ZodEnum<{
|
|
4
|
+
create: "create";
|
|
5
|
+
update: "update";
|
|
6
|
+
rewrite: "rewrite";
|
|
7
|
+
}>;
|
|
4
8
|
id: z.ZodString;
|
|
5
9
|
title: z.ZodString;
|
|
6
10
|
type: z.ZodString;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { z, ZodRawShape
|
|
1
|
+
import { z, ZodRawShape } from "zod";
|
|
2
2
|
import { Action, Parameter } from "./copilotkit-actions.js";
|
|
3
3
|
import { Message } from "@langchain/langgraph-sdk";
|
|
4
4
|
import { ToolRenderData } from "./ToolUI.js";
|
|
@@ -11,8 +11,8 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
11
11
|
execute?: ToolCallback<Args>;
|
|
12
12
|
/** 工具执行成功后触发的附加消息 */
|
|
13
13
|
callbackMessage?: (result: CallToolResult) => Message[];
|
|
14
|
-
handler?: (args: z.
|
|
15
|
-
render?: (tool: ToolRenderData<z.
|
|
14
|
+
handler?: (args: z.infer<z.ZodObject<Args>>, context?: any) => ResponseType | Promise<ResponseType>;
|
|
15
|
+
render?: (tool: ToolRenderData<z.infer<z.ZodObject<Args>>, ResponseType>) => Child;
|
|
16
16
|
onlyRender?: boolean;
|
|
17
17
|
/** 只允许指定的 agent 使用该工具,如果未指定,则所有 agent 都可以使用 */
|
|
18
18
|
allowAgent?: string[];
|
|
@@ -21,7 +21,7 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
21
21
|
/** 是否是纯净的 json schema 参数,而不是 zod 参数 */
|
|
22
22
|
isPureParams?: boolean;
|
|
23
23
|
}
|
|
24
|
-
export type ToolCallback<Args extends ZodRawShape> = (args: z.
|
|
24
|
+
export type ToolCallback<Args extends ZodRawShape> = (args: z.infer<z.ZodObject<Args>>, context?: any) => CallToolResult | Promise<CallToolResult>;
|
|
25
25
|
export type CallToolResult = string | {
|
|
26
26
|
type: "text";
|
|
27
27
|
text: string;
|
|
@@ -70,7 +70,7 @@ export declare const createJSONDefineTool: <Args extends ZodRawShape>(tool: Unio
|
|
|
70
70
|
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
71
71
|
} | undefined;
|
|
72
72
|
}) | ({
|
|
73
|
-
type: ("string" | "number" | "boolean" | "
|
|
73
|
+
type: ("string" | "number" | "boolean" | "null" | "integer") | ("string" | "number" | "boolean" | "null" | "integer")[];
|
|
74
74
|
} & {
|
|
75
75
|
title?: string;
|
|
76
76
|
default?: any;
|
|
@@ -149,7 +149,7 @@ export declare const createJSONDefineTool: <Args extends ZodRawShape>(tool: Unio
|
|
|
149
149
|
} | undefined;
|
|
150
150
|
});
|
|
151
151
|
};
|
|
152
|
-
export declare const createMCPTool: <Args extends ZodRawShape>(tool: UnionTool<Args>) => (string | Args | ((args: z.
|
|
152
|
+
export declare const createMCPTool: <Args extends ZodRawShape>(tool: UnionTool<Args>) => (string | Args | ((args: z.infer<z.ZodObject<Args>>) => Promise<{
|
|
153
153
|
content: {
|
|
154
154
|
type: string;
|
|
155
155
|
text: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langgraph-js/sdk",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.1",
|
|
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",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"jsonrepair": "^3.12.0",
|
|
50
50
|
"nanostores": "^1.0.1",
|
|
51
51
|
"ts-debounce": "^4.0.0",
|
|
52
|
-
"zod": "^
|
|
52
|
+
"zod": "^4",
|
|
53
53
|
"zod-to-json-schema": "^3.24.5"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
package/src/LangGraphClient.ts
CHANGED
|
@@ -240,7 +240,7 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
|
|
|
240
240
|
* @en Messages used for streaming rendering in the UI.
|
|
241
241
|
*/
|
|
242
242
|
get renderMessage() {
|
|
243
|
-
return this.messageProcessor.renderMessages(this.graphState, () => this.getGraphNodeNow());
|
|
243
|
+
return this.messageProcessor.renderMessages(this.graphState, () => this.getGraphNodeNow(), this.messagesMetadata);
|
|
244
244
|
}
|
|
245
245
|
/**
|
|
246
246
|
* @zh 获取 Token 计数器信息。
|
|
@@ -304,6 +304,7 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
|
|
|
304
304
|
this.messageProcessor.setGraphMessages(state.messages! as RenderMessage[]);
|
|
305
305
|
return state;
|
|
306
306
|
}
|
|
307
|
+
public messagesMetadata = {};
|
|
307
308
|
/**
|
|
308
309
|
* @zh 发送消息到 LangGraph 后端。
|
|
309
310
|
* @en Sends a message to the LangGraph backend.
|
|
@@ -363,6 +364,9 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
|
|
|
363
364
|
this.currentRun = chunk.data;
|
|
364
365
|
} else if (chunk.event === "error" || chunk.event === "Error" || chunk.event === "__stream_error__") {
|
|
365
366
|
this.emit("error", chunk);
|
|
367
|
+
} else if (chunk.event === "messages/metadata") {
|
|
368
|
+
Object.assign(this.messagesMetadata, chunk.data);
|
|
369
|
+
continue;
|
|
366
370
|
} else if (chunk.event === "messages/partial") {
|
|
367
371
|
for (const message of chunk.data) {
|
|
368
372
|
this.messageProcessor.updateStreamingMessage(message);
|
package/src/MessageProcessor.ts
CHANGED
|
@@ -216,7 +216,16 @@ export class MessageProcessor {
|
|
|
216
216
|
* @zh 转换 subAgent 消息为工具的子消息
|
|
217
217
|
* @en Convert subAgent messages to tool sub-messages
|
|
218
218
|
*/
|
|
219
|
-
convertSubAgentMessages(
|
|
219
|
+
convertSubAgentMessages(
|
|
220
|
+
messages: RenderMessage[],
|
|
221
|
+
graphState: any,
|
|
222
|
+
messagesMetadata: Record<
|
|
223
|
+
string,
|
|
224
|
+
{
|
|
225
|
+
subagent_id?: string;
|
|
226
|
+
}
|
|
227
|
+
>
|
|
228
|
+
): RenderMessage[] {
|
|
220
229
|
const origin_task_store = graphState[this.subAgentsKey];
|
|
221
230
|
if (!origin_task_store) return messages;
|
|
222
231
|
|
|
@@ -225,10 +234,10 @@ export class MessageProcessor {
|
|
|
225
234
|
/** 获取 subAgent 消息的 id,用于流式过程中对数据进行标记 */
|
|
226
235
|
messages
|
|
227
236
|
.filter((i) => {
|
|
228
|
-
return i.node_name?.startsWith("subagent_");
|
|
237
|
+
return messagesMetadata[i.id!]?.subagent_id || i.node_name?.startsWith("subagent_");
|
|
229
238
|
})
|
|
230
239
|
.forEach((i) => {
|
|
231
|
-
const tool_call_id = i.node_name!.replace("subagent_", "");
|
|
240
|
+
const tool_call_id = messagesMetadata[i.id!]?.subagent_id || i.node_name!.replace("subagent_", "");
|
|
232
241
|
const store = task_store[tool_call_id];
|
|
233
242
|
if (store) {
|
|
234
243
|
// 根据 id 进行去重
|
|
@@ -256,7 +265,7 @@ export class MessageProcessor {
|
|
|
256
265
|
const task = task_store[message.tool_call_id];
|
|
257
266
|
if (task) {
|
|
258
267
|
// 递归处理子消息,但避免重复处理
|
|
259
|
-
message.sub_agent_messages = this.processMessages(task.messages);
|
|
268
|
+
message.sub_agent_messages = this.processMessages(task.messages, task, messagesMetadata);
|
|
260
269
|
}
|
|
261
270
|
}
|
|
262
271
|
if (message.id && ignoreIds.has(message.id)) continue;
|
|
@@ -269,7 +278,16 @@ export class MessageProcessor {
|
|
|
269
278
|
* @zh 生成用于 UI 中的流式渲染的消息
|
|
270
279
|
* @en Generate messages used for streaming rendering in the UI
|
|
271
280
|
*/
|
|
272
|
-
renderMessages(
|
|
281
|
+
renderMessages(
|
|
282
|
+
graphState: any,
|
|
283
|
+
getGraphNodeNow: () => { name: string },
|
|
284
|
+
messagesMetadata: Record<
|
|
285
|
+
string,
|
|
286
|
+
{
|
|
287
|
+
subagent_id?: string;
|
|
288
|
+
}
|
|
289
|
+
>
|
|
290
|
+
): RenderMessage[] {
|
|
273
291
|
const previousMessage = new Map<string, Message>();
|
|
274
292
|
const closedToolCallIds = new Set<string>();
|
|
275
293
|
const result: Message[] = [];
|
|
@@ -328,14 +346,23 @@ export class MessageProcessor {
|
|
|
328
346
|
}
|
|
329
347
|
}
|
|
330
348
|
|
|
331
|
-
return this.processMessages(result as RenderMessage[], graphState);
|
|
349
|
+
return this.processMessages(result as RenderMessage[], graphState, messagesMetadata);
|
|
332
350
|
}
|
|
333
351
|
|
|
334
352
|
/**
|
|
335
353
|
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
336
354
|
* @en Unified message processing entry point, executing all processing steps in order
|
|
337
355
|
*/
|
|
338
|
-
processMessages(
|
|
356
|
+
processMessages(
|
|
357
|
+
messages: RenderMessage[],
|
|
358
|
+
graphState: any,
|
|
359
|
+
messagesMetadata: Record<
|
|
360
|
+
string,
|
|
361
|
+
{
|
|
362
|
+
subagent_id?: string;
|
|
363
|
+
}
|
|
364
|
+
>
|
|
365
|
+
): RenderMessage[] {
|
|
339
366
|
// 1. 组合工具消息
|
|
340
367
|
const composedMessages = this.composeToolMessages(messages);
|
|
341
368
|
|
|
@@ -344,7 +371,7 @@ export class MessageProcessor {
|
|
|
344
371
|
|
|
345
372
|
// 3. 转换子代理消息(如果提供了 graphState)
|
|
346
373
|
if (graphState) {
|
|
347
|
-
return this.convertSubAgentMessages(messagesWithInfo, graphState);
|
|
374
|
+
return this.convertSubAgentMessages(messagesWithInfo, graphState, messagesMetadata);
|
|
348
375
|
}
|
|
349
376
|
|
|
350
377
|
return messagesWithInfo;
|
package/src/tool/createTool.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { actionParametersToJsonSchema, convertJsonSchemaToZodRawShape } from "./utils.js";
|
|
2
|
-
import { z, ZodRawShape
|
|
2
|
+
import { z, ZodRawShape } from "zod";
|
|
3
3
|
import { Action, Parameter } from "./copilotkit-actions.js";
|
|
4
4
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5
5
|
import { Message } from "@langchain/langgraph-sdk";
|
|
@@ -14,8 +14,8 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
14
14
|
execute?: ToolCallback<Args>;
|
|
15
15
|
/** 工具执行成功后触发的附加消息 */
|
|
16
16
|
callbackMessage?: (result: CallToolResult) => Message[];
|
|
17
|
-
handler?: (args: z.
|
|
18
|
-
render?: (tool: ToolRenderData<z.
|
|
17
|
+
handler?: (args: z.infer<z.ZodObject<Args>>, context?: any) => ResponseType | Promise<ResponseType>;
|
|
18
|
+
render?: (tool: ToolRenderData<z.infer<z.ZodObject<Args>>, ResponseType>) => Child;
|
|
19
19
|
onlyRender?: boolean;
|
|
20
20
|
/** 只允许指定的 agent 使用该工具,如果未指定,则所有 agent 都可以使用 */
|
|
21
21
|
allowAgent?: string[];
|
|
@@ -24,7 +24,7 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
24
24
|
/** 是否是纯净的 json schema 参数,而不是 zod 参数 */
|
|
25
25
|
isPureParams?: boolean;
|
|
26
26
|
}
|
|
27
|
-
export type ToolCallback<Args extends ZodRawShape> = (args: z.
|
|
27
|
+
export type ToolCallback<Args extends ZodRawShape> = (args: z.infer<z.ZodObject<Args>>, context?: any) => CallToolResult | Promise<CallToolResult>;
|
|
28
28
|
|
|
29
29
|
export type CallToolResult = string | { type: "text"; text: string }[];
|
|
30
30
|
|
|
@@ -80,7 +80,7 @@ export const createFETool = <const T extends Parameter[], Args extends ZodRawSha
|
|
|
80
80
|
allowGraph: tool.allowGraph,
|
|
81
81
|
async execute(args, context) {
|
|
82
82
|
try {
|
|
83
|
-
const result = await tool.handler?.(args, context);
|
|
83
|
+
const result = await tool.handler?.(args as any, context);
|
|
84
84
|
if (typeof result === "string") {
|
|
85
85
|
return [{ type: "text", text: result }];
|
|
86
86
|
}
|
|
@@ -106,7 +106,7 @@ export const createMCPTool = <Args extends ZodRawShape>(tool: UnionTool<Args>) =
|
|
|
106
106
|
tool.name,
|
|
107
107
|
tool.description,
|
|
108
108
|
tool.parameters,
|
|
109
|
-
async (args: z.
|
|
109
|
+
async (args: z.infer<z.ZodObject<Args>>) => {
|
|
110
110
|
try {
|
|
111
111
|
const result = await tool.execute?.(args);
|
|
112
112
|
if (typeof result === "string") {
|