@langgraph-js/sdk 4.3.1 → 4.3.3

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,17 @@ 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
+ if (!message.additional_kwargs) {
108
+ /** @ts-ignore 初始化,一些前端传递的 message 是没有这个字段的 */
109
+ message.additional_kwargs = {};
110
+ }
111
+ const createTime = message.additional_kwargs?.create_time || formatFullTime(this.spendTime.getStartTime(message.id));
112
+ const updateTime = message.additional_kwargs?.update_time || formatFullTime(this.spendTime.getEndTime(message.id));
113
+ message.additional_kwargs.create_time = createTime;
114
+ message.additional_kwargs.update_time = updateTime;
105
115
  // 工具必须要使用 tool_call_id 来保证一致性
106
116
  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();
117
+ message.spend_time = new Date(updateTime).getTime() - new Date(createTime).getTime();
108
118
  if (!message.usage_metadata && message.response_metadata?.usage) {
109
119
  const usage = message.response_metadata.usage;
110
120
  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.3",
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,18 @@ 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
+ if (!message.additional_kwargs) {
123
+ /** @ts-ignore 初始化,一些前端传递的 message 是没有这个字段的 */
124
+ message.additional_kwargs = {};
125
+ }
126
+ const createTime = message.additional_kwargs?.create_time || formatFullTime(this.spendTime.getStartTime(message.id!));
127
+ const updateTime = message.additional_kwargs?.update_time || formatFullTime(this.spendTime.getEndTime(message.id!));
128
+ message.additional_kwargs!.create_time = createTime;
129
+ message.additional_kwargs!.update_time = updateTime;
121
130
  // 工具必须要使用 tool_call_id 来保证一致性
122
131
  message.unique_id = message.tool_call_id! || message.id!;
123
132
 
124
- message.spend_time = new Date(createTime).getTime() - new Date(lastMessage?.response_metadata?.create_time || createTime).getTime();
133
+ message.spend_time = new Date(updateTime).getTime() - new Date(createTime).getTime();
125
134
  if (!message.usage_metadata && (message as AIMessage).response_metadata?.usage) {
126
135
  const usage = (message as AIMessage).response_metadata!.usage as {
127
136
  prompt_tokens: number;
@@ -170,7 +179,7 @@ export class MessageProcessor {
170
179
  ...(parentMessage?.additional_kwargs || {}),
171
180
  ...(message.additional_kwargs || {}),
172
181
  done: isDone,
173
- };
182
+ } as RenderMessage["additional_kwargs"];
174
183
  }
175
184
  if (parentMessage) {
176
185
  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) => {