@langgraph-js/sdk 3.8.0 → 3.8.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.
- package/dist/MessageProcessor.d.ts +1 -0
- package/dist/MessageProcessor.js +10 -6
- package/dist/tool/ToolUI.d.ts +34 -1
- package/dist/tool/ToolUI.js +26 -0
- package/dist/tool/createTool.d.ts +6 -3
- package/package.json +1 -1
- package/src/MessageProcessor.ts +11 -8
- package/src/tool/ToolUI.ts +26 -0
- package/src/tool/createTool.ts +4 -1
|
@@ -80,6 +80,7 @@ export declare class MessageProcessor {
|
|
|
80
80
|
messages: RenderMessage[];
|
|
81
81
|
}>;
|
|
82
82
|
}, messagesMetadata?: Record<string, any>): RenderMessage[];
|
|
83
|
+
private beforeFold;
|
|
83
84
|
/**
|
|
84
85
|
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
85
86
|
* @en Unified message processing entry point, executing all processing steps in order
|
package/dist/MessageProcessor.js
CHANGED
|
@@ -264,21 +264,25 @@ export class MessageProcessor {
|
|
|
264
264
|
if (rootMessage.type === "tool" && childrenMap.has(rootMessage.tool_call_id)) {
|
|
265
265
|
rootMessage.sub_messages.unshift(...childrenMap.get(rootMessage.tool_call_id));
|
|
266
266
|
// 根据 id 去重
|
|
267
|
-
|
|
267
|
+
const sub_messages = rootMessage.sub_messages.filter((i, index, self) => self.findIndex((t) => t.id === i.id) === index);
|
|
268
|
+
rootMessage.sub_messages = this.beforeFold(sub_messages);
|
|
268
269
|
}
|
|
269
270
|
}
|
|
270
271
|
return rootMessages;
|
|
271
272
|
}
|
|
273
|
+
beforeFold(messages) {
|
|
274
|
+
// 1. 组合工具消息
|
|
275
|
+
const composedMessages = this.composeToolMessages(messages);
|
|
276
|
+
// 2. 附加信息
|
|
277
|
+
const messagesWithInfo = this.attachInfoForMessage(composedMessages);
|
|
278
|
+
return messagesWithInfo;
|
|
279
|
+
}
|
|
272
280
|
/**
|
|
273
281
|
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
274
282
|
* @en Unified message processing entry point, executing all processing steps in order
|
|
275
283
|
*/
|
|
276
284
|
processMessages(messages, graphState, messagesMetadata) {
|
|
277
|
-
// 1. 组合工具消息
|
|
278
|
-
const composedMessages = this.composeToolMessages(messages);
|
|
279
|
-
// 2. 附加信息
|
|
280
|
-
const messagesWithInfo = this.attachInfoForMessage(composedMessages);
|
|
281
285
|
// 3. 折叠树状消息(如果提供了 messagesMetadata)
|
|
282
|
-
return this.foldTreeMessages(
|
|
286
|
+
return this.foldTreeMessages(this.beforeFold(messages), graphState, messagesMetadata);
|
|
283
287
|
}
|
|
284
288
|
}
|
package/dist/tool/ToolUI.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { RenderMessage } from "../LangGraphClient.js";
|
|
2
2
|
import { LangGraphClient } from "../LangGraphClient.js";
|
|
3
|
+
import { InterruptResponse } from "./createTool.js";
|
|
3
4
|
export type DeepPartial<T> = {
|
|
4
5
|
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
5
6
|
};
|
|
@@ -7,7 +8,39 @@ export declare class ToolRenderData<I, D> {
|
|
|
7
8
|
message: RenderMessage;
|
|
8
9
|
client: LangGraphClient;
|
|
9
10
|
constructor(message: RenderMessage, client: LangGraphClient);
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* 获取人机交互数据
|
|
13
|
+
* 直接使用 reviewConfig 获取可以显示的按钮
|
|
14
|
+
* actionRequest 获取当前工具的入参
|
|
15
|
+
*/
|
|
16
|
+
getHumanInTheLoopData(): {
|
|
17
|
+
config: {
|
|
18
|
+
id: string;
|
|
19
|
+
value: {
|
|
20
|
+
actionRequests: {
|
|
21
|
+
name: string;
|
|
22
|
+
description: string;
|
|
23
|
+
args: any;
|
|
24
|
+
}[];
|
|
25
|
+
reviewConfigs: {
|
|
26
|
+
actionName: string;
|
|
27
|
+
allowedDecisions: ("approve" | "edit" | "reject")[];
|
|
28
|
+
}[];
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
reviewConfig: {
|
|
32
|
+
actionName: string;
|
|
33
|
+
allowedDecisions: ("approve" | "edit" | "reject")[];
|
|
34
|
+
};
|
|
35
|
+
actionRequest: {
|
|
36
|
+
name: string;
|
|
37
|
+
description: string;
|
|
38
|
+
args: any;
|
|
39
|
+
};
|
|
40
|
+
} | null;
|
|
41
|
+
/** 发送恢复状态的数据 */
|
|
42
|
+
sendResumeData(response: InterruptResponse["decisions"][number]): void;
|
|
43
|
+
get state(): "idle" | "interrupted" | "done" | "loading";
|
|
11
44
|
get input(): I | null;
|
|
12
45
|
get output(): string;
|
|
13
46
|
getJSONOutput(): D;
|
package/dist/tool/ToolUI.js
CHANGED
|
@@ -7,10 +7,36 @@ export class ToolRenderData {
|
|
|
7
7
|
this.message = message;
|
|
8
8
|
this.client = client;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* 获取人机交互数据
|
|
12
|
+
* 直接使用 reviewConfig 获取可以显示的按钮
|
|
13
|
+
* actionRequest 获取当前工具的入参
|
|
14
|
+
*/
|
|
15
|
+
getHumanInTheLoopData() {
|
|
16
|
+
const configOfHumanInTheLoop = this.client.humanInTheLoop?.find((i) => i.value.reviewConfigs?.some((j) => j.actionName === this.message.name));
|
|
17
|
+
if (!configOfHumanInTheLoop)
|
|
18
|
+
return null;
|
|
19
|
+
return {
|
|
20
|
+
config: configOfHumanInTheLoop,
|
|
21
|
+
reviewConfig: configOfHumanInTheLoop.value.reviewConfigs.find((j) => j.actionName === this.message.name),
|
|
22
|
+
actionRequest: configOfHumanInTheLoop.value.actionRequests.find((j) => j.name === this.message.name),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/** 发送恢复状态的数据 */
|
|
26
|
+
sendResumeData(response) {
|
|
27
|
+
if (response.type === "edit") {
|
|
28
|
+
/**@ts-ignore 修复 sb 的 langchain 官方的命名不统一,我们一致采用下划线版本,而非驼峰版本 */
|
|
29
|
+
response.editedAction = response.edited_action;
|
|
30
|
+
}
|
|
31
|
+
return this.client.doneFEToolWaiting(this.message.id, { decisions: [response] });
|
|
32
|
+
}
|
|
10
33
|
get state() {
|
|
11
34
|
if (this.message.type === "tool" && this.message?.additional_kwargs?.done) {
|
|
12
35
|
return "done";
|
|
13
36
|
}
|
|
37
|
+
if (this.client.status === "interrupted" && this.client.humanInTheLoop?.some((i) => i.value.reviewConfigs?.some((j) => j.actionName === this.message.name))) {
|
|
38
|
+
return "interrupted";
|
|
39
|
+
}
|
|
14
40
|
if (this.message.tool_input) {
|
|
15
41
|
return "loading";
|
|
16
42
|
}
|
|
@@ -22,6 +22,9 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
22
22
|
isPureParams?: boolean;
|
|
23
23
|
}
|
|
24
24
|
export type ToolCallback<Args extends ZodRawShape> = (args: z.infer<z.ZodObject<Args>>, context?: any) => CallToolResult | Promise<CallToolResult>;
|
|
25
|
+
/**
|
|
26
|
+
* HumanInTheLoop 的标准回复格式
|
|
27
|
+
*/
|
|
25
28
|
export type InterruptResponse = {
|
|
26
29
|
decisions: ({
|
|
27
30
|
type: "approve";
|
|
@@ -33,7 +36,7 @@ export type InterruptResponse = {
|
|
|
33
36
|
};
|
|
34
37
|
} | {
|
|
35
38
|
type: "reject";
|
|
36
|
-
message
|
|
39
|
+
message?: string;
|
|
37
40
|
})[];
|
|
38
41
|
};
|
|
39
42
|
export type CallToolResult = string | {
|
|
@@ -170,10 +173,10 @@ export declare const createMCPTool: <Args extends ZodRawShape>(tool: UnionTool<A
|
|
|
170
173
|
}[];
|
|
171
174
|
isError?: undefined;
|
|
172
175
|
} | {
|
|
173
|
-
content: {
|
|
176
|
+
content: InterruptResponse | {
|
|
174
177
|
type: "text";
|
|
175
178
|
text: string;
|
|
176
|
-
}[] |
|
|
179
|
+
}[] | undefined;
|
|
177
180
|
isError?: undefined;
|
|
178
181
|
} | {
|
|
179
182
|
content: {
|
package/package.json
CHANGED
package/src/MessageProcessor.ts
CHANGED
|
@@ -307,23 +307,26 @@ export class MessageProcessor {
|
|
|
307
307
|
if (rootMessage.type === "tool" && childrenMap.has(rootMessage.tool_call_id)) {
|
|
308
308
|
rootMessage.sub_messages.unshift(...childrenMap.get(rootMessage.tool_call_id)!);
|
|
309
309
|
// 根据 id 去重
|
|
310
|
-
|
|
310
|
+
const sub_messages = rootMessage.sub_messages.filter((i, index, self) => self.findIndex((t) => t.id === i.id) === index);
|
|
311
|
+
rootMessage.sub_messages = this.beforeFold(sub_messages);
|
|
311
312
|
}
|
|
312
313
|
}
|
|
313
314
|
return rootMessages;
|
|
314
315
|
}
|
|
315
|
-
|
|
316
|
-
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
317
|
-
* @en Unified message processing entry point, executing all processing steps in order
|
|
318
|
-
*/
|
|
319
|
-
processMessages(messages: RenderMessage[], graphState?: any, messagesMetadata?: Record<string, any>): RenderMessage[] {
|
|
316
|
+
private beforeFold(messages: RenderMessage[]) {
|
|
320
317
|
// 1. 组合工具消息
|
|
321
318
|
const composedMessages = this.composeToolMessages(messages);
|
|
322
319
|
|
|
323
320
|
// 2. 附加信息
|
|
324
321
|
const messagesWithInfo = this.attachInfoForMessage(composedMessages);
|
|
325
|
-
|
|
322
|
+
return messagesWithInfo;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* @zh 统一的消息处理入口,按顺序执行所有处理步骤
|
|
326
|
+
* @en Unified message processing entry point, executing all processing steps in order
|
|
327
|
+
*/
|
|
328
|
+
processMessages(messages: RenderMessage[], graphState?: any, messagesMetadata?: Record<string, any>): RenderMessage[] {
|
|
326
329
|
// 3. 折叠树状消息(如果提供了 messagesMetadata)
|
|
327
|
-
return this.foldTreeMessages(
|
|
330
|
+
return this.foldTreeMessages(this.beforeFold(messages), graphState, messagesMetadata);
|
|
328
331
|
}
|
|
329
332
|
}
|
package/src/tool/ToolUI.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { RenderMessage } from "../LangGraphClient.js";
|
|
|
3
3
|
import { LangGraphClient } from "../LangGraphClient.js";
|
|
4
4
|
import { getMessageContent } from "../ui-store/createChatStore.js";
|
|
5
5
|
import { jsonrepair } from "jsonrepair";
|
|
6
|
+
import { InterruptResponse } from "./createTool.js";
|
|
6
7
|
|
|
7
8
|
export type DeepPartial<T> = {
|
|
8
9
|
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
@@ -12,10 +13,35 @@ export class ToolRenderData<I, D> {
|
|
|
12
13
|
public message: RenderMessage,
|
|
13
14
|
public client: LangGraphClient
|
|
14
15
|
) {}
|
|
16
|
+
/**
|
|
17
|
+
* 获取人机交互数据
|
|
18
|
+
* 直接使用 reviewConfig 获取可以显示的按钮
|
|
19
|
+
* actionRequest 获取当前工具的入参
|
|
20
|
+
*/
|
|
21
|
+
getHumanInTheLoopData() {
|
|
22
|
+
const configOfHumanInTheLoop = this.client.humanInTheLoop?.find((i) => i.value.reviewConfigs?.some((j) => j.actionName === this.message.name));
|
|
23
|
+
if (!configOfHumanInTheLoop) return null;
|
|
24
|
+
return {
|
|
25
|
+
config: configOfHumanInTheLoop,
|
|
26
|
+
reviewConfig: configOfHumanInTheLoop.value.reviewConfigs.find((j) => j.actionName === this.message.name)!,
|
|
27
|
+
actionRequest: configOfHumanInTheLoop.value.actionRequests.find((j) => j.name === this.message.name)!,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/** 发送恢复状态的数据 */
|
|
31
|
+
sendResumeData(response: InterruptResponse["decisions"][number]) {
|
|
32
|
+
if (response.type === "edit") {
|
|
33
|
+
/**@ts-ignore 修复 sb 的 langchain 官方的命名不统一,我们一致采用下划线版本,而非驼峰版本 */
|
|
34
|
+
response.editedAction = response.edited_action;
|
|
35
|
+
}
|
|
36
|
+
return this.client.doneFEToolWaiting(this.message.id!, { decisions: [response] });
|
|
37
|
+
}
|
|
15
38
|
get state() {
|
|
16
39
|
if (this.message.type === "tool" && this.message?.additional_kwargs?.done) {
|
|
17
40
|
return "done";
|
|
18
41
|
}
|
|
42
|
+
if (this.client.status === "interrupted" && this.client.humanInTheLoop?.some((i) => i.value.reviewConfigs?.some((j) => j.actionName === this.message.name))) {
|
|
43
|
+
return "interrupted";
|
|
44
|
+
}
|
|
19
45
|
if (this.message.tool_input) {
|
|
20
46
|
return "loading";
|
|
21
47
|
}
|
package/src/tool/createTool.ts
CHANGED
|
@@ -25,6 +25,9 @@ export interface UnionTool<Args extends ZodRawShape, Child extends Object = Obje
|
|
|
25
25
|
isPureParams?: boolean;
|
|
26
26
|
}
|
|
27
27
|
export type ToolCallback<Args extends ZodRawShape> = (args: z.infer<z.ZodObject<Args>>, context?: any) => CallToolResult | Promise<CallToolResult>;
|
|
28
|
+
/**
|
|
29
|
+
* HumanInTheLoop 的标准回复格式
|
|
30
|
+
*/
|
|
28
31
|
export type InterruptResponse = {
|
|
29
32
|
decisions: (
|
|
30
33
|
| { type: "approve" }
|
|
@@ -35,7 +38,7 @@ export type InterruptResponse = {
|
|
|
35
38
|
args: Record<string, any>;
|
|
36
39
|
};
|
|
37
40
|
}
|
|
38
|
-
| { type: "reject"; message
|
|
41
|
+
| { type: "reject"; message?: string }
|
|
39
42
|
)[];
|
|
40
43
|
};
|
|
41
44
|
export type CallToolResult = string | { type: "text"; text: string }[] | InterruptResponse;
|