@langgraph-js/sdk 1.12.0 → 2.0.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.
@@ -1,25 +1,10 @@
1
- import { Client, Thread, Message, Assistant, HumanMessage, AIMessage, ToolMessage, Command } from "@langchain/langgraph-sdk";
1
+ import type { Thread, Message, Assistant, HumanMessage, AIMessage, ToolMessage, Command } from "@langchain/langgraph-sdk";
2
+ import { EventEmitter } from "eventemitter3";
2
3
  import { ToolManager } from "./ToolManager.js";
3
4
  import { CallToolResult } from "./tool/createTool.js";
4
- interface AsyncCallerParams {
5
- /**
6
- * The maximum number of concurrent calls that can be made.
7
- * Defaults to `Infinity`, which means no limit.
8
- */
9
- maxConcurrency?: number;
10
- /**
11
- * The maximum number of retries that can be made for a single call,
12
- * with an exponential backoff between each attempt. Defaults to 6.
13
- */
14
- maxRetries?: number;
15
- onFailedResponseHook?: any;
16
- /**
17
- * Specify a custom fetch implementation.
18
- *
19
- * By default we expect the `fetch` is available in the global scope.
20
- */
21
- fetch?: typeof fetch | ((...args: any[]) => any);
22
- }
5
+ import { ILangGraphClient } from "./types.js";
6
+ import { MessageProcessor } from "./MessageProcessor.js";
7
+
23
8
  export type RenderMessage = Message & {
24
9
  /** 对于 AIMessage 来说是节点名称,对于工具节点来说是工具名称 */
25
10
  name?: string;
@@ -61,53 +46,81 @@ export type SendMessageOptions = {
61
46
  export interface LangGraphClientConfig {
62
47
  apiUrl?: string;
63
48
  apiKey?: string;
64
- callerOptions?: AsyncCallerParams;
49
+ callerOptions?: {
50
+ /**
51
+ * The maximum number of concurrent calls that can be made.
52
+ * Defaults to `Infinity`, which means no limit.
53
+ */
54
+ maxConcurrency?: number;
55
+ /**
56
+ * The maximum number of retries that can be made for a single call,
57
+ * with an exponential backoff between each attempt. Defaults to 6.
58
+ */
59
+ maxRetries?: number;
60
+ onFailedResponseHook?: any;
61
+ /**
62
+ * Specify a custom fetch implementation.
63
+ *
64
+ * By default we expect the `fetch` is available in the global scope.
65
+ */
66
+ fetch?: typeof fetch | ((...args: any[]) => any);
67
+ };
65
68
  timeoutMs?: number;
66
69
  defaultHeaders?: Record<string, string | null | undefined>;
70
+ /** 自定义客户端实现,如果不提供则使用官方 Client */
71
+ client: ILangGraphClient;
67
72
  }
68
73
 
69
- /**
70
- * @zh StreamingMessageType 类用于判断消息的类型。
71
- * @en The StreamingMessageType class is used to determine the type of a message.
72
- */
73
- export class StreamingMessageType {
74
- static isUser(m: Message): m is HumanMessage {
75
- return m.type === "human";
76
- }
77
- static isTool(m: Message): m is ToolMessage {
78
- return m.type === "tool";
79
- }
80
- static isAssistant(m: Message): m is AIMessage {
81
- return m.type === "ai" && !this.isToolAssistant(m);
82
- }
83
- static isToolAssistant(m: Message): m is AIMessage {
84
- /** @ts-ignore */
85
- return m.type === "ai" && (m.tool_calls?.length || m.tool_call_chunks?.length);
86
- }
74
+ // 定义事件数据类型
75
+ export interface LangGraphEvents {
76
+ /** 流开始事件 */
77
+ start: { event: "start" };
78
+ /** 消息部分更新事件 */
79
+ message: { event: "messages/partial"; data: Message[] };
80
+ /** 值更新事件 */
81
+ value: { event: "messages/partial" | "values"; data: { messages?: Message[] } };
82
+ /** 错误事件 */
83
+ error: { event: "error"; data: any };
84
+ /** Thread 创建事件 */
85
+ thread: { event: "thread/create"; data: { thread: Thread } };
86
+ /** 流完成事件 */
87
+ done: { event: "done" };
87
88
  }
88
89
 
89
- type StreamingUpdateEvent = {
90
- type: "message" | "value" | "update" | "error" | "thread" | "done" | "start";
91
- data: any;
92
- };
93
-
94
- type StreamingUpdateCallback = (event: StreamingUpdateEvent) => void;
95
-
96
90
  /**
97
91
  * @zh LangGraphClient 类是与 LangGraph 后端交互的主要客户端。
98
92
  * @en The LangGraphClient class is the main client for interacting with the LangGraph backend.
99
93
  */
100
- export class LangGraphClient extends Client {
94
+ export class LangGraphClient<TStateType = unknown, TUpdateType = TStateType> extends EventEmitter<LangGraphEvents> {
95
+ private client: ILangGraphClient<TStateType, TUpdateType>;
101
96
  private currentAssistant: Assistant | null = null;
102
- private currentThread: Thread | null = null;
103
- private streamingCallbacks: Set<StreamingUpdateCallback> = new Set();
97
+ private currentThread: Thread<TStateType> | null = null;
104
98
  tools: ToolManager = new ToolManager();
105
99
  stopController: AbortController | null = null;
106
100
  /** 用于存储 subAgent 状态数据的键 */
107
101
  subAgentsKey = "task_store";
102
+ /** Message 处理器 */
103
+ private messageProcessor: MessageProcessor;
108
104
 
109
105
  constructor(config: LangGraphClientConfig) {
110
- super(config);
106
+ super();
107
+ this.client = config.client;
108
+ this.messageProcessor = new MessageProcessor(this.subAgentsKey);
109
+ }
110
+
111
+ /** 代理 assistants 属性到内部 client */
112
+ get assistants() {
113
+ return this.client.assistants;
114
+ }
115
+
116
+ /** 代理 threads 属性到内部 client */
117
+ get threads() {
118
+ return this.client.threads;
119
+ }
120
+
121
+ /** 代理 runs 属性到内部 client */
122
+ get runs() {
123
+ return this.client.runs;
111
124
  }
112
125
  availableAssistants: Assistant[] = [];
113
126
  private listAssistants() {
@@ -127,7 +140,7 @@ export class LangGraphClient extends Client {
127
140
  this.availableAssistants = assistants;
128
141
  if (assistants.length > 0) {
129
142
  if (agentName) {
130
- this.currentAssistant = assistants.find((assistant) => assistant.graph_id === agentName) || null;
143
+ this.currentAssistant = assistants.find((assistant: any) => assistant.graph_id === agentName) || null;
131
144
  if (!this.currentAssistant) {
132
145
  throw new Error("Agent not found: " + agentName);
133
146
  }
@@ -164,7 +177,7 @@ export class LangGraphClient extends Client {
164
177
  }
165
178
 
166
179
  graphVisualize() {
167
- return this.assistants.getGraph(this.currentAssistant?.assistant_id!, {
180
+ return this.assistants.getGraph((this.currentAssistant as any)?.assistant_id!, {
168
181
  xray: true,
169
182
  });
170
183
  }
@@ -172,11 +185,14 @@ export class LangGraphClient extends Client {
172
185
  * @zh 列出所有的 Thread。
173
186
  * @en Lists all Threads.
174
187
  */
175
- async listThreads<T>() {
176
- return this.threads.search<T>({
188
+ async listThreads() {
189
+ return this.threads.search({
177
190
  sortOrder: "desc",
178
191
  });
179
192
  }
193
+ async deleteThread(threadId: string) {
194
+ return this.threads.delete(threadId);
195
+ }
180
196
 
181
197
  /**
182
198
  * @zh 从历史中恢复 Thread 数据。
@@ -185,249 +201,42 @@ export class LangGraphClient extends Client {
185
201
  async resetThread(agent: string, threadId: string) {
186
202
  await this.initAssistant(agent);
187
203
  this.currentThread = await this.threads.get(threadId);
188
- this.graphState = this.currentThread.values;
189
- this.graphMessages = this.graphState?.messages || [];
190
- this.emitStreamingUpdate({
191
- type: "value",
204
+ this.graphState = (this.currentThread as any).values;
205
+ const graphMessages = this.graphState?.messages || [];
206
+ this.messageProcessor.setGraphMessages(graphMessages);
207
+ this.emit("value", {
208
+ event: "messages/partial",
192
209
  data: {
193
- event: "messages/partial",
194
- data: {
195
- messages: this.graphMessages,
196
- },
210
+ messages: this.messageProcessor.getGraphMessages(),
197
211
  },
198
212
  });
199
213
  return this.currentThread;
200
214
  }
201
215
  // 从历史中恢复时,应该恢复流式状态
202
216
  async resetStream() {
203
- const runs = await this.runs.list(this.currentThread!.thread_id);
204
- const runningRun = runs?.find((run) => run.status === "running" || run.status === "pending");
217
+ const runs = await this.runs.list((this.currentThread as any)!.thread_id);
218
+ const runningRun = runs?.find((run: any) => run.status === "running" || run.status === "pending");
205
219
  if (runningRun) {
206
220
  await this.sendMessage([], { joinRunId: runningRun.run_id });
207
221
  }
208
222
  }
209
223
 
210
- streamingMessage: RenderMessage[] = [];
211
- /** 图发过来的更新信息 */
212
- graphMessages: RenderMessage[] = [];
213
224
  cloneMessage(message: Message): Message {
214
- return JSON.parse(JSON.stringify(message));
215
- }
216
- private updateStreamingMessage(message: RenderMessage) {
217
- const lastMessage = this.streamingMessage[this.streamingMessage.length - 1];
218
- if (!lastMessage?.id || message.id !== lastMessage.id) {
219
- this.streamingMessage.push(message);
220
- return;
221
- }
222
- this.streamingMessage[this.streamingMessage.length - 1] = message;
223
- }
224
- /** 将 graphMessages 和 streamingMessage 合并,并返回新的消息数组 */
225
- private combineGraphMessagesWithStreamingMessages() {
226
- const idMap = new Map<string, RenderMessage>(this.streamingMessage.map((i) => [i.id!, i]));
227
- return [
228
- ...this.graphMessages.map((i) => {
229
- if (idMap.has(i.id!)) {
230
- const newValue = idMap.get(i.id!)!;
231
- idMap.delete(i.id!);
232
- return newValue;
233
- }
234
- return i;
235
- }),
236
- ...idMap.values(),
237
- ];
225
+ return this.messageProcessor.cloneMessage(message);
238
226
  }
239
227
  /**
240
228
  * @zh 用于 UI 中的流式渲染中的消息。
241
229
  * @en Messages used for streaming rendering in the UI.
242
230
  */
243
231
  get renderMessage() {
244
- const previousMessage = new Map<string, Message>();
245
- const closedToolCallIds = new Set<string>();
246
- const result: Message[] = [];
247
- const inputMessages = this.combineGraphMessagesWithStreamingMessages();
248
- // console.log(inputMessages);
249
- // 从后往前遍历,这样可以保证最新的消息在前面
250
- for (let i = inputMessages.length - 1; i >= 0; i--) {
251
- const message = this.cloneMessage(inputMessages[i]);
252
-
253
- if (!message.id) {
254
- result.unshift(message);
255
- continue;
256
- }
257
- if (message.type === "ai") {
258
- /** @ts-ignore */
259
- if (!message.name) message.name = this.getGraphNodeNow().name;
260
- }
261
- if (StreamingMessageType.isToolAssistant(message)) {
262
- const m = message;
263
- // 记录这个 id 的消息,并添加到结果中
264
- previousMessage.set(message.id, m);
265
-
266
- /** @ts-ignore */
267
- const tool_calls: NonNullable<AIMessage["tool_calls"]> = (m as AIMessage).tool_calls?.length ? (m as AIMessage).tool_calls : (m as RenderMessage).tool_call_chunks;
268
- const new_tool_calls = tool_calls
269
- .filter((i) => {
270
- return !closedToolCallIds.has(i.id!);
271
- })!
272
- .map((tool, index) => {
273
- return {
274
- type: "tool",
275
- additional_kwargs: {},
276
- /** @ts-ignore */
277
- tool_input: m.additional_kwargs?.tool_calls?.[index]?.function?.arguments,
278
- id: tool.id,
279
- name: tool.name,
280
- response_metadata: {},
281
- tool_call_id: tool.id!,
282
- content: "",
283
- } as ToolMessage;
284
- });
285
- for (const tool of new_tool_calls) {
286
- if (!previousMessage.has(tool.id!)) {
287
- result.unshift(tool);
288
- previousMessage.set(tool.id!, tool);
289
- }
290
- }
291
- result.unshift(m);
292
- } else {
293
- if (message.type === "tool" && message.tool_call_id) {
294
- closedToolCallIds.add(message.tool_call_id);
295
- }
296
-
297
- previousMessage.set(message.id, message);
298
- result.unshift(message);
299
- }
300
- }
301
-
302
- return this.convertSubAgentMessages(this.attachInfoForMessage(this.composeToolMessages(result as RenderMessage[])));
303
- }
304
- /** 转换 subAgent 消息为工具的子消息 */
305
- private convertSubAgentMessages(messages: RenderMessage[]) {
306
- const origin_task_store = this.graphState[this.subAgentsKey];
307
- if (!origin_task_store) return messages;
308
-
309
- const task_store = JSON.parse(JSON.stringify(origin_task_store));
310
- console.log(messages);
311
- /** 获取 subAgent 消息的 id,用于流式过程中对数据进行标记 */
312
- messages
313
- .filter((i) => {
314
- return i.node_name?.startsWith("subagent_");
315
- })
316
- .forEach((i) => {
317
- const tool_call_id = i.node_name!.replace("subagent_", "");
318
- const store = task_store[tool_call_id];
319
- if (store) {
320
- // 根据 id 进行去重
321
- const exists = (store.messages as RenderMessage[]).some((msg) => msg.id === i.id);
322
- if (!exists) {
323
- (store.messages as RenderMessage[]).push(i);
324
- }
325
- } else {
326
- task_store[tool_call_id] = {
327
- messages: [i],
328
- };
329
- }
330
- });
331
-
332
- const ignoreIds = new Set<string>();
333
- Object.values(task_store).forEach((task: any) => {
334
- task.messages.forEach((message: RenderMessage) => {
335
- ignoreIds.add(message.id!);
336
- });
337
- });
338
- const result: RenderMessage[] = [];
339
- for (const message of messages) {
340
- if (message.type === "tool" && message.tool_call_id) {
341
- const task = task_store[message.tool_call_id];
342
- if (task) {
343
- message.sub_agent_messages = this.attachInfoForMessage(this.composeToolMessages(task.messages));
344
- }
345
- }
346
- if (message.id && ignoreIds.has(message.id)) continue;
347
- result.push(message);
348
- }
349
- return result;
350
- }
351
- /**
352
- * @zh 为消息附加额外的信息,如耗时、唯一 ID 等。
353
- * @en Attaches additional information to messages, such as spend time, unique ID, etc.
354
- */
355
- private attachInfoForMessage(result: RenderMessage[]) {
356
- let lastMessage: RenderMessage | null = null;
357
- for (const message of result) {
358
- const createTime = message.response_metadata?.create_time || "";
359
- // 工具必须要使用 tool_call_id 来保证一致性
360
- message.unique_id = message.tool_call_id! || message.id!;
361
-
362
- message.spend_time = new Date(createTime).getTime() - new Date(lastMessage?.response_metadata?.create_time || createTime).getTime();
363
- if (!message.usage_metadata && (message as AIMessage).response_metadata?.usage) {
364
- const usage = (message as AIMessage).response_metadata!.usage as {
365
- prompt_tokens: number;
366
- completion_tokens: number;
367
- total_tokens: number;
368
- };
369
- message.usage_metadata = {
370
- ...usage,
371
- input_tokens: usage.prompt_tokens,
372
- output_tokens: usage.completion_tokens,
373
- total_tokens: usage.total_tokens,
374
- };
375
- }
376
- lastMessage = message;
377
- }
378
- return result;
379
- }
380
- /**
381
- * @zh 组合工具消息,将 AI 的工具调用和工具的执行结果关联起来。
382
- * @en Composes tool messages, associating AI tool calls with tool execution results.
383
- */
384
- private composeToolMessages(messages: RenderMessage[]): RenderMessage[] {
385
- const result: RenderMessage[] = [];
386
- const assistantToolMessages = new Map<string, { args: string }>();
387
- const toolParentMessage = new Map<string, RenderMessage>();
388
- for (const message of messages) {
389
- if (StreamingMessageType.isToolAssistant(message)) {
390
- /** @ts-ignore 只有 tool_call_chunks 的 args 才是文本 */
391
- (message.tool_calls || message.tool_call_chunks)?.forEach((element) => {
392
- assistantToolMessages.set(element.id!, element);
393
- toolParentMessage.set(element.id!, message);
394
- });
395
- if (!message.content) continue;
396
- }
397
- if (StreamingMessageType.isTool(message) && !message.tool_input) {
398
- const assistantToolMessage = assistantToolMessages.get(message.tool_call_id!);
399
- const parentMessage = toolParentMessage.get(message.tool_call_id!);
400
- if (assistantToolMessage) {
401
- message.tool_input = typeof assistantToolMessage.args !== "string" ? JSON.stringify(assistantToolMessage.args) : assistantToolMessage.args;
402
- if (message.additional_kwargs) {
403
- message.additional_kwargs.done = true;
404
- message.done = true;
405
- } else {
406
- message.done = true;
407
- message.additional_kwargs = {
408
- done: true,
409
- };
410
- }
411
- }
412
- if (parentMessage) {
413
- message.usage_metadata = parentMessage.usage_metadata;
414
- message.node_name = parentMessage.name;
415
- // 修补特殊情况下,tool name 丢失的问题
416
- if (!message.name) {
417
- message.name = (parentMessage as AIMessage).tool_calls!.find((i) => i.id === message.tool_call_id)?.name;
418
- }
419
- }
420
- }
421
- result.push(message);
422
- }
423
- return result;
232
+ return this.messageProcessor.renderMessages(this.graphState, () => this.getGraphNodeNow());
424
233
  }
425
234
  /**
426
235
  * @zh 获取 Token 计数器信息。
427
236
  * @en Gets the Token counter information.
428
237
  */
429
238
  get tokenCounter() {
430
- return this.graphMessages.reduce(
239
+ return this.messageProcessor.getGraphMessages().reduce(
431
240
  (acc, message) => {
432
241
  if (message.usage_metadata) {
433
242
  acc.total_tokens += message.usage_metadata?.total_tokens || 0;
@@ -454,20 +263,6 @@ export class LangGraphClient extends Client {
454
263
  );
455
264
  }
456
265
 
457
- /**
458
- * @zh 注册流式更新的回调函数。
459
- * @en Registers a callback function for streaming updates.
460
- */
461
- onStreamingUpdate(callback: StreamingUpdateCallback) {
462
- this.streamingCallbacks.add(callback);
463
- return () => {
464
- this.streamingCallbacks.delete(callback);
465
- };
466
- }
467
-
468
- private emitStreamingUpdate(event: StreamingUpdateEvent) {
469
- this.streamingCallbacks.forEach((callback) => callback(event));
470
- }
471
266
  /** 前端工具人机交互时,锁住面板 */
472
267
  isFELocking(messages: RenderMessage[]) {
473
268
  const lastMessage = messages[messages.length - 1];
@@ -484,8 +279,8 @@ export class LangGraphClient extends Client {
484
279
  * @en Cancels the current Run.
485
280
  */
486
281
  cancelRun() {
487
- if (this.currentThread?.thread_id && this.currentRun?.run_id) {
488
- this.runs.cancel(this.currentThread!.thread_id, this.currentRun.run_id);
282
+ if ((this.currentThread as any)?.thread_id && this.currentRun?.run_id) {
283
+ this.runs.cancel((this.currentThread as any)!.thread_id, this.currentRun.run_id);
489
284
  }
490
285
  }
491
286
  /**
@@ -498,13 +293,10 @@ export class LangGraphClient extends Client {
498
293
  }
499
294
  if (!this.currentThread) {
500
295
  await this.createThread();
501
- this.emitStreamingUpdate({
502
- type: "thread",
296
+ this.emit("thread", {
297
+ event: "thread/create",
503
298
  data: {
504
- event: "thread/create",
505
- data: {
506
- thread: this.currentThread,
507
- },
299
+ thread: this.currentThread,
508
300
  },
509
301
  });
510
302
  }
@@ -541,43 +333,31 @@ export class LangGraphClient extends Client {
541
333
  const streamResponse = await createStreamResponse();
542
334
 
543
335
  const streamRecord: any[] = [];
544
- this.emitStreamingUpdate({
545
- type: "start",
546
- data: {
547
- event: "start",
548
- },
336
+ this.emit("start", {
337
+ event: "start",
549
338
  });
550
339
  for await (const chunk of streamResponse) {
551
340
  streamRecord.push(chunk);
552
341
  if (chunk.event === "metadata") {
553
342
  this.currentRun = chunk.data;
554
343
  } else if (chunk.event === "error") {
555
- this.emitStreamingUpdate({
556
- type: "error",
557
- data: chunk,
558
- });
344
+ this.emit("error", chunk);
559
345
  } else if (chunk.event === "messages/partial") {
560
346
  for (const message of chunk.data) {
561
- this.updateStreamingMessage(message);
347
+ this.messageProcessor.updateStreamingMessage(message);
562
348
  }
563
- this.emitStreamingUpdate({
564
- type: "message",
565
- data: chunk,
566
- });
349
+ this.emit("message", chunk);
567
350
  continue;
568
351
  } else if (chunk.event === "values") {
569
352
  const data = chunk.data as { messages: Message[] };
570
353
 
571
354
  if (data.messages) {
572
355
  const isResume = !!command?.resume;
573
- const isLongerThanLocal = data.messages.length >= this.graphMessages.length;
356
+ const isLongerThanLocal = data.messages.length >= this.messageProcessor.getGraphMessages().length;
574
357
  // resume 情况下,长度低于前端 message 的统统不接受
575
358
  if (!isResume || (isResume && isLongerThanLocal)) {
576
- this.graphMessages = data.messages as RenderMessage[];
577
- this.emitStreamingUpdate({
578
- type: "value",
579
- data: chunk,
580
- });
359
+ this.messageProcessor.setGraphMessages(data.messages as RenderMessage[]);
360
+ this.emit("value", chunk);
581
361
  }
582
362
  this.graphState = chunk.data;
583
363
  }
@@ -585,20 +365,17 @@ export class LangGraphClient extends Client {
585
365
  } else if (chunk.event.startsWith("values|")) {
586
366
  // 这个 values 必然是子 values
587
367
  if (chunk.data?.messages) {
588
- this.mergeSubGraphMessagesToStreamingMessages(chunk.data.messages);
368
+ this.messageProcessor.mergeSubGraphMessagesToStreamingMessages(chunk.data.messages);
589
369
  }
590
370
  this.graphPosition = chunk.event.split("|")[1];
591
371
  }
592
372
  }
593
373
  const data = await this.runFETool();
594
374
  if (data) streamRecord.push(...data);
595
- this.emitStreamingUpdate({
596
- type: "done",
597
- data: {
598
- event: "done",
599
- },
375
+ this.emit("done", {
376
+ event: "done",
600
377
  });
601
- this.streamingMessage = [];
378
+ this.messageProcessor.clearStreamingMessages();
602
379
  return streamRecord;
603
380
  }
604
381
  /** 当前子图位置,但是依赖 stream,不太适合稳定使用*/
@@ -616,26 +393,9 @@ export class LangGraphClient extends Client {
616
393
  const position = this.getGraphPosition();
617
394
  return position[position.length - 1];
618
395
  }
619
- /** 子图的数据需要通过 merge 的方式重新进行合并更新 */
620
- private mergeSubGraphMessagesToStreamingMessages(messages: Message[]) {
621
- const map = new Map(messages.filter((i) => i.id).map((i) => [i.id!, i]));
622
- this.streamingMessage.forEach((i) => {
623
- if (map.has(i.id!)) {
624
- const newValue = map.get(i.id!)!;
625
- Object.assign(i, newValue);
626
- map.delete(i.id!);
627
- }
628
- });
629
- // 剩余的 message 一定不在 streamMessage 中
630
- map.forEach((i) => {
631
- if (i.type === "tool" && i.tool_call_id) {
632
- this.streamingMessage.push(i as RenderMessage);
633
- }
634
- });
635
- }
636
396
 
637
397
  private runFETool() {
638
- const data = this.streamingMessage; // 需要保证不被清理
398
+ const data = this.messageProcessor.getStreamingMessages(); // 需要保证不被清理
639
399
  const lastMessage = data[data.length - 1];
640
400
  if (!lastMessage) return;
641
401
  // 如果最后一条消息是前端工具消息,则调用工具
@@ -713,14 +473,14 @@ export class LangGraphClient extends Client {
713
473
  await this.initAssistant(this.currentAssistant?.graph_id!);
714
474
  this.currentThread = null;
715
475
  this.graphState = {};
716
- this.graphMessages = [];
717
- this.streamingMessage = [];
476
+ this.messageProcessor.setGraphMessages([]);
477
+ this.messageProcessor.clearStreamingMessages();
718
478
  this.currentRun = undefined;
719
479
  this.tools.clearWaiting();
720
- this.emitStreamingUpdate({
721
- type: "value",
480
+ this.emit("value", {
481
+ event: "messages/partial",
722
482
  data: {
723
- event: "messages/partial",
483
+ messages: [],
724
484
  },
725
485
  });
726
486
  }