@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.
@@ -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.
@@ -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): RenderMessage[];
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
- }): RenderMessage[];
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?: any): RenderMessage[];
97
+ processMessages(messages: RenderMessage[], graphState: any, messagesMetadata: Record<string, {
98
+ subagent_id?: string;
99
+ }>): RenderMessage[];
94
100
  }
@@ -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.node_name) === null || _a === void 0 ? void 0 : _a.startsWith("subagent_");
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
- const tool_call_id = i.node_name.replace("subagent_", "");
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<["create", "update", "rewrite"]>;
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, ZodTypeAny } from "zod";
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.objectOutputType<Args, ZodTypeAny>, context?: any) => ResponseType | Promise<ResponseType>;
15
- render?: (tool: ToolRenderData<z.objectOutputType<Args, ZodTypeAny>, ResponseType>) => Child;
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.objectOutputType<Args, ZodTypeAny>, context?: any) => CallToolResult | Promise<CallToolResult>;
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" | "integer" | "null") | ("string" | "number" | "boolean" | "integer" | "null")[];
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.objectOutputType<Args, ZodTypeAny>) => Promise<{
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.1",
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": "^3.25.17",
52
+ "zod": "^4",
53
53
  "zod-to-json-schema": "^3.24.5"
54
54
  },
55
55
  "peerDependencies": {
@@ -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);
@@ -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(messages: RenderMessage[], graphState: any): RenderMessage[] {
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(graphState: any, getGraphNodeNow: () => { name: string }): RenderMessage[] {
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(messages: RenderMessage[], graphState?: any): RenderMessage[] {
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;
@@ -1,5 +1,5 @@
1
1
  import { actionParametersToJsonSchema, convertJsonSchemaToZodRawShape } from "./utils.js";
2
- import { z, ZodRawShape, ZodTypeAny } from "zod";
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.objectOutputType<Args, ZodTypeAny>, context?: any) => ResponseType | Promise<ResponseType>;
18
- render?: (tool: ToolRenderData<z.objectOutputType<Args, ZodTypeAny>, ResponseType>) => Child;
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.objectOutputType<Args, ZodTypeAny>, context?: any) => CallToolResult | Promise<CallToolResult>;
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.objectOutputType<Args, ZodTypeAny>) => {
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") {