@langgraph-js/sdk 4.3.1 → 4.3.2

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.
@@ -13,6 +13,8 @@ export type RenderMessage = Message & {
13
13
  /** 工具入参 ,聚合而来*/
14
14
  tool_input?: string;
15
15
  additional_kwargs?: {
16
+ create_time: string;
17
+ update_time: string;
16
18
  done?: boolean;
17
19
  tool_calls?: {
18
20
  function: {
@@ -26,9 +28,6 @@ export type RenderMessage = Message & {
26
28
  output_tokens: number;
27
29
  };
28
30
  tool_call_id?: string;
29
- response_metadata?: {
30
- create_time: string;
31
- };
32
31
  sub_messages?: RenderMessage[];
33
32
  /** 耗时 */
34
33
  spend_time?: number;
@@ -136,10 +135,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
136
135
  /** 代理 assistants 属性到内部 client */
137
136
  get assistants(): {
138
137
  search(query?: {
139
- graphId? /**
140
- * The maximum number of retries that can be made for a single call,
141
- * with an exponential backoff between each attempt. Defaults to 6.
142
- */: string;
138
+ graphId?: string;
143
139
  metadata?: import("@langchain/langgraph-sdk").Metadata;
144
140
  limit?: number;
145
141
  offset?: number;
@@ -341,6 +341,7 @@ export class LangGraphClient extends EventEmitter {
341
341
  else if (chunk.event === "messages/partial" || chunk.event === "messages/complete") {
342
342
  for (const message of chunk.data) {
343
343
  this.messageProcessor.updateStreamingMessage(message);
344
+ this.messageProcessor.spendTime.setSpendTime(message.id);
344
345
  }
345
346
  this.emit("message", chunk);
346
347
  return true;
@@ -1,5 +1,6 @@
1
1
  import { Message, AIMessage, ToolMessage } from "@langchain/langgraph-sdk";
2
2
  import { RenderMessage } from "./LangGraphClient.js";
3
+ import { SpendTime } from "./SpendTime.js";
3
4
  /**
4
5
  * @zh StreamingMessageType 类用于判断消息的类型。
5
6
  * @en The StreamingMessageType class is used to determine the type of a message.
@@ -17,6 +18,7 @@ export declare class MessageProcessor {
17
18
  private streamingMessage;
18
19
  /** 图发过来的更新信息 */
19
20
  private graphMessages;
21
+ spendTime: SpendTime;
20
22
  constructor();
21
23
  /**
22
24
  * @zh 获取流式消息
@@ -1,3 +1,5 @@
1
+ import { SpendTime } from "./SpendTime.js";
2
+ import { formatFullTime } from "./ui-store/createChatStore.js";
1
3
  /**
2
4
  * @zh StreamingMessageType 类用于判断消息的类型。
3
5
  * @en The StreamingMessageType class is used to determine the type of a message.
@@ -20,6 +22,7 @@ export class MessageProcessor {
20
22
  streamingMessage = [];
21
23
  /** 图发过来的更新信息 */
22
24
  graphMessages = [];
25
+ spendTime = new SpendTime();
23
26
  constructor() { }
24
27
  /**
25
28
  * @zh 获取流式消息
@@ -101,10 +104,13 @@ export class MessageProcessor {
101
104
  let lastMessage = null;
102
105
  const result = [...messages]; // 创建副本避免修改原数组
103
106
  for (const message of result) {
104
- const createTime = message.response_metadata?.create_time || "";
107
+ const createTime = message.additional_kwargs?.create_time || formatFullTime(this.spendTime.getStartTime(message.id));
108
+ const updateTime = message.additional_kwargs?.update_time || formatFullTime(this.spendTime.getEndTime(message.id));
109
+ message.additional_kwargs.create_time = createTime;
110
+ message.additional_kwargs.update_time = updateTime;
105
111
  // 工具必须要使用 tool_call_id 来保证一致性
106
112
  message.unique_id = message.tool_call_id || message.id;
107
- message.spend_time = new Date(createTime).getTime() - new Date(lastMessage?.response_metadata?.create_time || createTime).getTime();
113
+ message.spend_time = new Date(updateTime).getTime() - new Date(createTime).getTime();
108
114
  if (!message.usage_metadata && message.response_metadata?.usage) {
109
115
  const usage = message.response_metadata.usage;
110
116
  message.usage_metadata = {
package/dist/TestKit.d.ts CHANGED
@@ -171,6 +171,8 @@ export declare class TestLangGraphChat {
171
171
  node_name?: string;
172
172
  tool_input?: string;
173
173
  additional_kwargs?: {
174
+ create_time: string;
175
+ update_time: string;
174
176
  done?: boolean;
175
177
  tool_calls?: {
176
178
  function: {
@@ -184,9 +186,6 @@ export declare class TestLangGraphChat {
184
186
  output_tokens: number;
185
187
  };
186
188
  tool_call_id?: string;
187
- response_metadata?: {
188
- create_time: string;
189
- };
190
189
  sub_messages?: RenderMessage[];
191
190
  spend_time?: number;
192
191
  unique_id?: string;
@@ -245,6 +244,8 @@ export declare class TestLangGraphChat {
245
244
  node_name?: string;
246
245
  tool_input?: string;
247
246
  additional_kwargs?: {
247
+ create_time: string;
248
+ update_time: string;
248
249
  done?: boolean;
249
250
  tool_calls?: {
250
251
  function: {
@@ -258,9 +259,6 @@ export declare class TestLangGraphChat {
258
259
  output_tokens: number;
259
260
  };
260
261
  tool_call_id?: string;
261
- response_metadata?: {
262
- create_time: string;
263
- };
264
262
  sub_messages?: RenderMessage[];
265
263
  spend_time?: number;
266
264
  unique_id?: string;
@@ -292,6 +290,8 @@ export declare class TestLangGraphChat {
292
290
  node_name?: string;
293
291
  tool_input?: string;
294
292
  additional_kwargs?: {
293
+ create_time: string;
294
+ update_time: string;
295
295
  done?: boolean;
296
296
  tool_calls?: {
297
297
  function: {
@@ -305,9 +305,6 @@ export declare class TestLangGraphChat {
305
305
  output_tokens: number;
306
306
  };
307
307
  tool_call_id?: string;
308
- response_metadata?: {
309
- create_time: string;
310
- };
311
308
  sub_messages?: RenderMessage[];
312
309
  spend_time?: number;
313
310
  unique_id?: string;
@@ -5,6 +5,7 @@ import { RevertChatToOptions } from "../time-travel/index.js";
5
5
  import { History, SessionInfo } from "../History.js";
6
6
  import { InterruptData } from "../humanInTheLoop.js";
7
7
  export declare const formatTime: (date: Date) => string;
8
+ export declare const formatFullTime: (date: Date) => string;
8
9
  export declare const formatTokens: (tokens: number) => string;
9
10
  export declare const getMessageContent: (content: any) => string;
10
11
  export declare const getHistoryContent: (thread: Thread) => string | any[];
@@ -6,6 +6,16 @@ import { useArtifacts } from "../artifacts/index.js";
6
6
  import { History } from "../History.js";
7
7
  // ============ 工具函数 ============
8
8
  export const formatTime = (date) => date.toLocaleTimeString();
9
+ export const formatFullTime = (date) => {
10
+ const pad = (n) => n.toString().padStart(2, "0");
11
+ const yyyy = date.getFullYear();
12
+ const mm = pad(date.getMonth() + 1);
13
+ const dd = pad(date.getDate());
14
+ const hh = pad(date.getHours());
15
+ const mi = pad(date.getMinutes());
16
+ const ss = pad(date.getSeconds());
17
+ return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`;
18
+ };
9
19
  export const formatTokens = (tokens) => tokens.toLocaleString("en");
10
20
  export const getMessageContent = (content) => {
11
21
  if (typeof content === "string")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgraph-js/sdk",
3
- "version": "4.3.1",
3
+ "version": "4.3.2",
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",
@@ -2,6 +2,7 @@ import type { Thread, Message, Assistant, HumanMessage, AIMessage, ToolMessage,
2
2
  import { EventEmitter } from "eventemitter3";
3
3
  import { ToolManager } from "./ToolManager.js";
4
4
  import { CallToolResult } from "./tool/createTool.js";
5
+ import { SpendTime } from "./SpendTime.js";
5
6
  import { createActionRequestID, HumanInTheLoopDecision, HumanInTheLoopState, InterruptData } from "./humanInTheLoop.js";
6
7
  import { type ILangGraphClient } from "@langgraph-js/pure-graph/dist/types.js";
7
8
  import { MessageProcessor } from "./MessageProcessor.js";
@@ -16,6 +17,8 @@ export type RenderMessage = Message & {
16
17
  /** 工具入参 ,聚合而来*/
17
18
  tool_input?: string;
18
19
  additional_kwargs?: {
20
+ create_time: string;
21
+ update_time: string;
19
22
  done?: boolean;
20
23
  tool_calls?: {
21
24
  function: {
@@ -29,9 +32,6 @@ export type RenderMessage = Message & {
29
32
  output_tokens: number;
30
33
  };
31
34
  tool_call_id?: string;
32
- response_metadata?: {
33
- create_time: string;
34
- };
35
35
  // 子消息
36
36
  sub_messages?: RenderMessage[];
37
37
  /** 耗时 */
@@ -105,6 +105,7 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
105
105
  private currentAssistant: Assistant | null = null;
106
106
  private currentThread: Thread<TStateType> | null = null;
107
107
  tools: ToolManager = new ToolManager();
108
+
108
109
  availableAssistants: Assistant[] = [];
109
110
  graphState: any = {};
110
111
  currentRun?: { run_id: string };
@@ -459,6 +460,7 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
459
460
  } else if (chunk.event === "messages/partial" || chunk.event === "messages/complete") {
460
461
  for (const message of chunk.data) {
461
462
  this.messageProcessor.updateStreamingMessage(message);
463
+ this.messageProcessor.spendTime.setSpendTime(message.id!);
462
464
  }
463
465
  this.emit("message", chunk);
464
466
  return true;
@@ -1,5 +1,7 @@
1
1
  import { Message, AIMessage, ToolMessage } from "@langchain/langgraph-sdk";
2
2
  import { RenderMessage } from "./LangGraphClient.js";
3
+ import { SpendTime } from "./SpendTime.js";
4
+ import { formatFullTime, formatTime } from "./ui-store/createChatStore.js";
3
5
 
4
6
  /**
5
7
  * @zh StreamingMessageType 类用于判断消息的类型。
@@ -25,7 +27,7 @@ export class MessageProcessor {
25
27
  private streamingMessage: RenderMessage[] = [];
26
28
  /** 图发过来的更新信息 */
27
29
  private graphMessages: RenderMessage[] = [];
28
-
30
+ public spendTime = new SpendTime();
29
31
  constructor() {}
30
32
 
31
33
  /**
@@ -117,11 +119,14 @@ export class MessageProcessor {
117
119
  const result = [...messages]; // 创建副本避免修改原数组
118
120
 
119
121
  for (const message of result) {
120
- const createTime = message.response_metadata?.create_time || "";
122
+ const createTime = message.additional_kwargs?.create_time || formatFullTime(this.spendTime.getStartTime(message.id!));
123
+ const updateTime = message.additional_kwargs?.update_time || formatFullTime(this.spendTime.getEndTime(message.id!));
124
+ message.additional_kwargs!.create_time = createTime;
125
+ message.additional_kwargs!.update_time = updateTime;
121
126
  // 工具必须要使用 tool_call_id 来保证一致性
122
127
  message.unique_id = message.tool_call_id! || message.id!;
123
128
 
124
- message.spend_time = new Date(createTime).getTime() - new Date(lastMessage?.response_metadata?.create_time || createTime).getTime();
129
+ message.spend_time = new Date(updateTime).getTime() - new Date(createTime).getTime();
125
130
  if (!message.usage_metadata && (message as AIMessage).response_metadata?.usage) {
126
131
  const usage = (message as AIMessage).response_metadata!.usage as {
127
132
  prompt_tokens: number;
@@ -170,7 +175,7 @@ export class MessageProcessor {
170
175
  ...(parentMessage?.additional_kwargs || {}),
171
176
  ...(message.additional_kwargs || {}),
172
177
  done: isDone,
173
- };
178
+ } as RenderMessage["additional_kwargs"];
174
179
  }
175
180
  if (parentMessage) {
176
181
  message.usage_metadata = parentMessage.usage_metadata;
@@ -13,6 +13,16 @@ import { InterruptData, InterruptResponse } from "../humanInTheLoop.js";
13
13
  // ============ 工具函数 ============
14
14
 
15
15
  export const formatTime = (date: Date) => date.toLocaleTimeString();
16
+ export const formatFullTime = (date: Date) => {
17
+ const pad = (n: number) => n.toString().padStart(2, "0");
18
+ const yyyy = date.getFullYear();
19
+ const mm = pad(date.getMonth() + 1);
20
+ const dd = pad(date.getDate());
21
+ const hh = pad(date.getHours());
22
+ const mi = pad(date.getMinutes());
23
+ const ss = pad(date.getSeconds());
24
+ return `${yyyy}-${mm}-${dd} ${hh}:${mi}:${ss}`;
25
+ };
16
26
  export const formatTokens = (tokens: number) => tokens.toLocaleString("en");
17
27
 
18
28
  export const getMessageContent = (content: any) => {