@langgraph-js/sdk 1.1.0 → 1.1.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.
- package/dist/LangGraphClient.d.ts +101 -0
- package/dist/LangGraphClient.js +38 -29
- package/dist/SpendTime.d.ts +9 -0
- package/dist/SpendTime.js +9 -4
- package/dist/ToolManager.d.ts +63 -0
- package/dist/ToolManager.js +5 -3
- package/dist/index.d.ts +5 -0
- package/dist/tool/copilotkit-actions.d.ts +66 -0
- package/dist/tool/createTool.d.ts +47 -0
- package/dist/tool/createTool.js +2 -1
- package/dist/tool/index.d.ts +2 -0
- package/dist/tool/utils.d.ts +36 -0
- package/dist/tool/utils.js +4 -3
- package/dist/ui-store/UnionStore.d.ts +11 -0
- package/dist/ui-store/createChatStore.d.ts +43 -0
- package/dist/ui-store/createChatStore.js +16 -8
- package/dist/ui-store/index.d.ts +2 -0
- package/package.json +2 -2
- package/tsconfig.json +2 -2
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Client, Thread, Message, Assistant, HumanMessage, ToolMessage, Command } from "@langchain/langgraph-sdk";
|
|
2
|
+
import { ToolManager } from "./ToolManager";
|
|
3
|
+
import { CallToolResult } from "./tool";
|
|
4
|
+
import { AsyncCallerParams } from "@langchain/langgraph-sdk/dist/utils/async_caller";
|
|
5
|
+
export type RenderMessage = Message & {
|
|
6
|
+
/** 工具入参 ,聚合而来*/
|
|
7
|
+
tool_input?: string;
|
|
8
|
+
additional_kwargs?: {
|
|
9
|
+
done?: boolean;
|
|
10
|
+
tool_calls?: {
|
|
11
|
+
function: {
|
|
12
|
+
arguments: string;
|
|
13
|
+
};
|
|
14
|
+
}[];
|
|
15
|
+
};
|
|
16
|
+
usage_metadata?: {
|
|
17
|
+
total_tokens: number;
|
|
18
|
+
input_tokens: number;
|
|
19
|
+
output_tokens: number;
|
|
20
|
+
};
|
|
21
|
+
response_metadata?: {
|
|
22
|
+
create_time: string;
|
|
23
|
+
};
|
|
24
|
+
/** 耗时 */
|
|
25
|
+
spend_time?: number;
|
|
26
|
+
/** 渲染时的唯一 id,聚合而来*/
|
|
27
|
+
unique_id?: string;
|
|
28
|
+
};
|
|
29
|
+
export interface LangGraphClientConfig {
|
|
30
|
+
apiUrl?: string;
|
|
31
|
+
apiKey?: string;
|
|
32
|
+
callerOptions?: AsyncCallerParams;
|
|
33
|
+
timeoutMs?: number;
|
|
34
|
+
defaultHeaders?: Record<string, string | null | undefined>;
|
|
35
|
+
}
|
|
36
|
+
export declare class StreamingMessageType {
|
|
37
|
+
static isUser(m: Message): m is HumanMessage;
|
|
38
|
+
static isTool(m: Message): m is ToolMessage;
|
|
39
|
+
static isAssistant(m: Message): boolean;
|
|
40
|
+
static isToolAssistant(m: Message): any;
|
|
41
|
+
}
|
|
42
|
+
type StreamingUpdateEvent = {
|
|
43
|
+
type: "message" | "value" | "update" | "error" | "thread" | "done";
|
|
44
|
+
data: any;
|
|
45
|
+
};
|
|
46
|
+
type StreamingUpdateCallback = (event: StreamingUpdateEvent) => void;
|
|
47
|
+
export declare class LangGraphClient extends Client {
|
|
48
|
+
private currentAssistant;
|
|
49
|
+
private currentThread;
|
|
50
|
+
private streamingCallbacks;
|
|
51
|
+
tools: ToolManager;
|
|
52
|
+
stopController: AbortController | null;
|
|
53
|
+
constructor(config: LangGraphClientConfig);
|
|
54
|
+
availableAssistants: Assistant[];
|
|
55
|
+
private listAssistants;
|
|
56
|
+
initAssistant(agentName: string): Promise<void>;
|
|
57
|
+
createThread({ threadId, }?: {
|
|
58
|
+
threadId?: string;
|
|
59
|
+
}): Promise<Thread<import("@langchain/langgraph-sdk").DefaultValues>>;
|
|
60
|
+
listThreads<T>(): Promise<Thread<T>[]>;
|
|
61
|
+
/** 从历史中恢复数据 */
|
|
62
|
+
resetThread(agent: string, threadId: string): Promise<void>;
|
|
63
|
+
streamingMessage: RenderMessage[];
|
|
64
|
+
/** 图发过来的更新信息 */
|
|
65
|
+
graphMessages: RenderMessage[];
|
|
66
|
+
cloneMessage(message: Message): Message;
|
|
67
|
+
private replaceMessageWithValuesMessage;
|
|
68
|
+
/** 用于 UI 中的流式渲染中的消息 */
|
|
69
|
+
get renderMessage(): RenderMessage[];
|
|
70
|
+
attachInfoForMessage(result: RenderMessage[]): RenderMessage[];
|
|
71
|
+
composeToolMessages(messages: RenderMessage[]): RenderMessage[];
|
|
72
|
+
get tokenCounter(): {
|
|
73
|
+
total_tokens: number;
|
|
74
|
+
input_tokens: number;
|
|
75
|
+
output_tokens: number;
|
|
76
|
+
};
|
|
77
|
+
onStreamingUpdate(callback: StreamingUpdateCallback): () => void;
|
|
78
|
+
private emitStreamingUpdate;
|
|
79
|
+
graphState: any;
|
|
80
|
+
currentRun?: {
|
|
81
|
+
run_id: string;
|
|
82
|
+
};
|
|
83
|
+
cancelRun(): void;
|
|
84
|
+
sendMessage(input: string | Message[], { extraParams, _debug, command }?: {
|
|
85
|
+
extraParams?: Record<string, any>;
|
|
86
|
+
_debug?: {
|
|
87
|
+
streamResponse?: any;
|
|
88
|
+
};
|
|
89
|
+
command?: Command;
|
|
90
|
+
}): Promise<any[]>;
|
|
91
|
+
private runFETool;
|
|
92
|
+
private callFETool;
|
|
93
|
+
/** 恢复消息,当中断流时使用 */
|
|
94
|
+
resume(result: CallToolResult): Promise<any[]>;
|
|
95
|
+
/** 完成工具等待 */
|
|
96
|
+
doneFEToolWaiting(id: string, result: CallToolResult): void;
|
|
97
|
+
getCurrentThread(): Thread<import("@langchain/langgraph-sdk").DefaultValues> | null;
|
|
98
|
+
getCurrentAssistant(): Assistant | null;
|
|
99
|
+
reset(): Promise<void>;
|
|
100
|
+
}
|
|
101
|
+
export {};
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -11,20 +11,25 @@ export class StreamingMessageType {
|
|
|
11
11
|
return m.type === "ai" && !this.isToolAssistant(m);
|
|
12
12
|
}
|
|
13
13
|
static isToolAssistant(m) {
|
|
14
|
+
var _a, _b;
|
|
14
15
|
/** @ts-ignore */
|
|
15
|
-
return m.type === "ai" && (m.tool_calls
|
|
16
|
+
return m.type === "ai" && (((_a = m.tool_calls) === null || _a === void 0 ? void 0 : _a.length) || ((_b = m.tool_call_chunks) === null || _b === void 0 ? void 0 : _b.length));
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
export class LangGraphClient extends Client {
|
|
19
|
-
currentAssistant = null;
|
|
20
|
-
currentThread = null;
|
|
21
|
-
streamingCallbacks = new Set();
|
|
22
|
-
tools = new ToolManager();
|
|
23
|
-
stopController = null;
|
|
24
20
|
constructor(config) {
|
|
25
21
|
super(config);
|
|
22
|
+
this.currentAssistant = null;
|
|
23
|
+
this.currentThread = null;
|
|
24
|
+
this.streamingCallbacks = new Set();
|
|
25
|
+
this.tools = new ToolManager();
|
|
26
|
+
this.stopController = null;
|
|
27
|
+
this.availableAssistants = [];
|
|
28
|
+
this.streamingMessage = [];
|
|
29
|
+
/** 图发过来的更新信息 */
|
|
30
|
+
this.graphMessages = [];
|
|
31
|
+
this.graphState = {};
|
|
26
32
|
}
|
|
27
|
-
availableAssistants = [];
|
|
28
33
|
listAssistants() {
|
|
29
34
|
return this.assistants.search({
|
|
30
35
|
metadata: null,
|
|
@@ -84,9 +89,6 @@ export class LangGraphClient extends Client {
|
|
|
84
89
|
},
|
|
85
90
|
});
|
|
86
91
|
}
|
|
87
|
-
streamingMessage = [];
|
|
88
|
-
/** 图发过来的更新信息 */
|
|
89
|
-
graphMessages = [];
|
|
90
92
|
cloneMessage(message) {
|
|
91
93
|
return JSON.parse(JSON.stringify(message));
|
|
92
94
|
}
|
|
@@ -104,6 +106,7 @@ export class LangGraphClient extends Client {
|
|
|
104
106
|
}
|
|
105
107
|
/** 用于 UI 中的流式渲染中的消息 */
|
|
106
108
|
get renderMessage() {
|
|
109
|
+
var _a;
|
|
107
110
|
const previousMessage = new Map();
|
|
108
111
|
const result = [];
|
|
109
112
|
const inputMessages = [...this.graphMessages, ...this.streamingMessage];
|
|
@@ -123,13 +126,14 @@ export class LangGraphClient extends Client {
|
|
|
123
126
|
// 记录这个 id 的消息,并添加到结果中
|
|
124
127
|
previousMessage.set(message.id, m);
|
|
125
128
|
/** @ts-ignore */
|
|
126
|
-
const tool_calls = m.tool_calls
|
|
129
|
+
const tool_calls = ((_a = m.tool_calls) === null || _a === void 0 ? void 0 : _a.length) ? m.tool_calls : m.tool_call_chunks;
|
|
127
130
|
const new_tool_calls = tool_calls.map((tool, index) => {
|
|
131
|
+
var _a;
|
|
128
132
|
return this.replaceMessageWithValuesMessage({
|
|
129
133
|
type: "tool",
|
|
130
134
|
additional_kwargs: {},
|
|
131
135
|
/** @ts-ignore */
|
|
132
|
-
tool_input: m.additional_kwargs
|
|
136
|
+
tool_input: (_a = m.additional_kwargs) === null || _a === void 0 ? void 0 : _a.tool_calls[index].function.arguments,
|
|
133
137
|
id: tool.id,
|
|
134
138
|
name: tool.name,
|
|
135
139
|
response_metadata: {},
|
|
@@ -154,13 +158,14 @@ export class LangGraphClient extends Client {
|
|
|
154
158
|
return this.attachInfoForMessage(this.composeToolMessages(result));
|
|
155
159
|
}
|
|
156
160
|
attachInfoForMessage(result) {
|
|
161
|
+
var _a, _b, _c;
|
|
157
162
|
let lastMessage = null;
|
|
158
163
|
for (const message of result) {
|
|
159
|
-
const createTime = message.response_metadata
|
|
164
|
+
const createTime = ((_a = message.response_metadata) === null || _a === void 0 ? void 0 : _a.create_time) || "";
|
|
160
165
|
// 用长度作为渲染 id,长度变了就要重新渲染
|
|
161
166
|
message.unique_id = message.id + JSON.stringify(message.content).length;
|
|
162
|
-
message.spend_time = new Date(createTime).getTime() - new Date(lastMessage
|
|
163
|
-
if (!message.usage_metadata && message.response_metadata
|
|
167
|
+
message.spend_time = new Date(createTime).getTime() - new Date(((_b = lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.response_metadata) === null || _b === void 0 ? void 0 : _b.create_time) || createTime).getTime();
|
|
168
|
+
if (!message.usage_metadata && ((_c = message.response_metadata) === null || _c === void 0 ? void 0 : _c.usage)) {
|
|
164
169
|
const usage = message.response_metadata.usage;
|
|
165
170
|
message.usage_metadata = {
|
|
166
171
|
input_tokens: usage.prompt_tokens,
|
|
@@ -173,13 +178,14 @@ export class LangGraphClient extends Client {
|
|
|
173
178
|
return result;
|
|
174
179
|
}
|
|
175
180
|
composeToolMessages(messages) {
|
|
181
|
+
var _a;
|
|
176
182
|
const result = [];
|
|
177
183
|
const assistantToolMessages = new Map();
|
|
178
184
|
const toolParentMessage = new Map();
|
|
179
185
|
for (const message of messages) {
|
|
180
186
|
if (StreamingMessageType.isToolAssistant(message)) {
|
|
181
187
|
/** @ts-ignore 只有 tool_call_chunks 的 args 才是文本 */
|
|
182
|
-
message.tool_call_chunks
|
|
188
|
+
(_a = message.tool_call_chunks) === null || _a === void 0 ? void 0 : _a.forEach((element) => {
|
|
183
189
|
assistantToolMessages.set(element.id, element);
|
|
184
190
|
toolParentMessage.set(element.id, message);
|
|
185
191
|
});
|
|
@@ -210,13 +216,14 @@ export class LangGraphClient extends Client {
|
|
|
210
216
|
}
|
|
211
217
|
get tokenCounter() {
|
|
212
218
|
return this.graphMessages.reduce((acc, message) => {
|
|
219
|
+
var _a, _b, _c, _d, _e;
|
|
213
220
|
if (message.usage_metadata) {
|
|
214
|
-
acc.total_tokens += message.usage_metadata
|
|
215
|
-
acc.input_tokens += message.usage_metadata
|
|
216
|
-
acc.output_tokens += message.usage_metadata
|
|
221
|
+
acc.total_tokens += ((_a = message.usage_metadata) === null || _a === void 0 ? void 0 : _a.total_tokens) || 0;
|
|
222
|
+
acc.input_tokens += ((_b = message.usage_metadata) === null || _b === void 0 ? void 0 : _b.input_tokens) || 0;
|
|
223
|
+
acc.output_tokens += ((_c = message.usage_metadata) === null || _c === void 0 ? void 0 : _c.output_tokens) || 0;
|
|
217
224
|
}
|
|
218
|
-
else if (message.response_metadata
|
|
219
|
-
const usage = message.response_metadata
|
|
225
|
+
else if ((_d = message.response_metadata) === null || _d === void 0 ? void 0 : _d.usage) {
|
|
226
|
+
const usage = (_e = message.response_metadata) === null || _e === void 0 ? void 0 : _e.usage;
|
|
220
227
|
acc.total_tokens += usage.total_tokens || 0;
|
|
221
228
|
acc.input_tokens += usage.prompt_tokens || 0;
|
|
222
229
|
acc.output_tokens += usage.completion_tokens || 0;
|
|
@@ -237,10 +244,9 @@ export class LangGraphClient extends Client {
|
|
|
237
244
|
emitStreamingUpdate(event) {
|
|
238
245
|
this.streamingCallbacks.forEach((callback) => callback(event));
|
|
239
246
|
}
|
|
240
|
-
graphState = {};
|
|
241
|
-
currentRun;
|
|
242
247
|
cancelRun() {
|
|
243
|
-
|
|
248
|
+
var _a, _b;
|
|
249
|
+
if (((_a = this.currentThread) === null || _a === void 0 ? void 0 : _a.thread_id) && ((_b = this.currentRun) === null || _b === void 0 ? void 0 : _b.run_id)) {
|
|
244
250
|
this.runs.cancel(this.currentThread.thread_id, this.currentRun.run_id);
|
|
245
251
|
}
|
|
246
252
|
}
|
|
@@ -268,7 +274,7 @@ export class LangGraphClient extends Client {
|
|
|
268
274
|
content: input,
|
|
269
275
|
},
|
|
270
276
|
];
|
|
271
|
-
const streamResponse = _debug
|
|
277
|
+
const streamResponse = (_debug === null || _debug === void 0 ? void 0 : _debug.streamResponse) ||
|
|
272
278
|
this.runs.stream(this.currentThread.thread_id, this.currentAssistant.assistant_id, {
|
|
273
279
|
input: { ...this.graphState, ...(extraParams || {}), messages: messagesToSend, fe_tools: this.tools.toJSON() },
|
|
274
280
|
streamMode: ["messages", "values"],
|
|
@@ -300,7 +306,7 @@ export class LangGraphClient extends Client {
|
|
|
300
306
|
else if (chunk.event.startsWith("values")) {
|
|
301
307
|
const data = chunk.data;
|
|
302
308
|
if (data.messages) {
|
|
303
|
-
const isResume = !!command
|
|
309
|
+
const isResume = !!(command === null || command === void 0 ? void 0 : command.resume);
|
|
304
310
|
const isLongerThanLocal = data.messages.length >= this.graphMessages.length;
|
|
305
311
|
// resume 情况下,长度低于前端 message 的统统不接受
|
|
306
312
|
if (!isResume || (isResume && isLongerThanLocal)) {
|
|
@@ -329,10 +335,11 @@ export class LangGraphClient extends Client {
|
|
|
329
335
|
return streamRecord;
|
|
330
336
|
}
|
|
331
337
|
runFETool() {
|
|
338
|
+
var _a;
|
|
332
339
|
const data = this.graphMessages;
|
|
333
340
|
const lastMessage = data[data.length - 1];
|
|
334
341
|
// 如果最后一条消息是前端工具消息,则调用工具
|
|
335
|
-
if (lastMessage.type === "ai" && lastMessage.tool_calls
|
|
342
|
+
if (lastMessage.type === "ai" && ((_a = lastMessage.tool_calls) === null || _a === void 0 ? void 0 : _a.length)) {
|
|
336
343
|
const result = lastMessage.tool_calls.map((tool) => {
|
|
337
344
|
if (this.tools.getTool(tool.name)) {
|
|
338
345
|
const toolMessage = {
|
|
@@ -364,8 +371,9 @@ export class LangGraphClient extends Client {
|
|
|
364
371
|
}
|
|
365
372
|
/** 完成工具等待 */
|
|
366
373
|
doneFEToolWaiting(id, result) {
|
|
374
|
+
var _a;
|
|
367
375
|
const done = this.tools.doneWaiting(id, result);
|
|
368
|
-
if (!done && this.currentThread
|
|
376
|
+
if (!done && ((_a = this.currentThread) === null || _a === void 0 ? void 0 : _a.status) === "interrupted") {
|
|
369
377
|
this.resume(result);
|
|
370
378
|
}
|
|
371
379
|
}
|
|
@@ -376,7 +384,8 @@ export class LangGraphClient extends Client {
|
|
|
376
384
|
return this.currentAssistant;
|
|
377
385
|
}
|
|
378
386
|
async reset() {
|
|
379
|
-
|
|
387
|
+
var _a;
|
|
388
|
+
await this.initAssistant((_a = this.currentAssistant) === null || _a === void 0 ? void 0 : _a.name);
|
|
380
389
|
this.currentThread = null;
|
|
381
390
|
this.graphState = {};
|
|
382
391
|
this.graphMessages = [];
|
package/dist/SpendTime.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
export class SpendTime {
|
|
2
|
-
|
|
2
|
+
constructor() {
|
|
3
|
+
this.timeCounter = new Map();
|
|
4
|
+
}
|
|
3
5
|
start(key) {
|
|
4
6
|
this.timeCounter.set(key, [new Date()]);
|
|
5
7
|
}
|
|
6
8
|
end(key) {
|
|
7
|
-
|
|
9
|
+
var _a;
|
|
10
|
+
this.timeCounter.set(key, [((_a = this.timeCounter.get(key)) === null || _a === void 0 ? void 0 : _a[0]) || new Date(), new Date()]);
|
|
8
11
|
}
|
|
9
12
|
setSpendTime(key) {
|
|
10
13
|
if (this.timeCounter.has(key)) {
|
|
@@ -15,10 +18,12 @@ export class SpendTime {
|
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
20
|
getStartTime(key) {
|
|
18
|
-
|
|
21
|
+
var _a;
|
|
22
|
+
return ((_a = this.timeCounter.get(key)) === null || _a === void 0 ? void 0 : _a[0]) || new Date();
|
|
19
23
|
}
|
|
20
24
|
getEndTime(key) {
|
|
21
|
-
|
|
25
|
+
var _a;
|
|
26
|
+
return ((_a = this.timeCounter.get(key)) === null || _a === void 0 ? void 0 : _a[1]) || new Date();
|
|
22
27
|
}
|
|
23
28
|
getSpendTime(key) {
|
|
24
29
|
const [start, end = new Date()] = this.timeCounter.get(key) || [new Date(), new Date()];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ToolMessage } from "@langchain/langgraph-sdk";
|
|
2
|
+
import { LangGraphClient } from "./LangGraphClient";
|
|
3
|
+
import { CallToolResult, UnionTool } from "./tool/createTool";
|
|
4
|
+
export declare class ToolManager {
|
|
5
|
+
private tools;
|
|
6
|
+
/**
|
|
7
|
+
* 注册一个工具
|
|
8
|
+
* @param tool 要注册的工具
|
|
9
|
+
*/
|
|
10
|
+
bindTool(tool: UnionTool<any>): void;
|
|
11
|
+
/**
|
|
12
|
+
* 注册多个工具
|
|
13
|
+
* @param tools 要注册的工具数组
|
|
14
|
+
*/
|
|
15
|
+
bindTools(tools: UnionTool<any>[]): void;
|
|
16
|
+
/**
|
|
17
|
+
* 获取所有已注册的工具
|
|
18
|
+
* @returns 工具数组
|
|
19
|
+
*/
|
|
20
|
+
getAllTools(): UnionTool<any>[];
|
|
21
|
+
/**
|
|
22
|
+
* 获取指定名称的工具
|
|
23
|
+
* @param name 工具名称
|
|
24
|
+
* @returns 工具实例或 undefined
|
|
25
|
+
*/
|
|
26
|
+
getTool(name: string): UnionTool<any> | undefined;
|
|
27
|
+
/**
|
|
28
|
+
* 移除指定名称的工具
|
|
29
|
+
* @param name 工具名称
|
|
30
|
+
* @returns 是否成功移除
|
|
31
|
+
*/
|
|
32
|
+
removeTool(name: string): boolean;
|
|
33
|
+
/**
|
|
34
|
+
* 清空所有工具
|
|
35
|
+
*/
|
|
36
|
+
clearTools(): void;
|
|
37
|
+
callTool(name: string, args: any, context: {
|
|
38
|
+
client: LangGraphClient;
|
|
39
|
+
message: ToolMessage;
|
|
40
|
+
}): Promise<CallToolResult>;
|
|
41
|
+
toJSON(): {
|
|
42
|
+
name: string;
|
|
43
|
+
description: string;
|
|
44
|
+
parameters: import("zod-to-json-schema").JsonSchema7Type & {
|
|
45
|
+
$schema?: string | undefined;
|
|
46
|
+
definitions?: {
|
|
47
|
+
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
48
|
+
} | undefined;
|
|
49
|
+
};
|
|
50
|
+
}[];
|
|
51
|
+
private waitingMap;
|
|
52
|
+
doneWaiting(id: string, value: CallToolResult): boolean;
|
|
53
|
+
waitForDone(id: string): Promise<unknown> | ((value: CallToolResult) => void) | undefined;
|
|
54
|
+
/** 等待用户输入
|
|
55
|
+
* @example
|
|
56
|
+
* // 继续 chat 流
|
|
57
|
+
* client.tools.doneWaiting(message.id!, (e.target as any).value);
|
|
58
|
+
*/
|
|
59
|
+
static waitForUIDone<T>(_: T, context: {
|
|
60
|
+
client: LangGraphClient;
|
|
61
|
+
message: ToolMessage;
|
|
62
|
+
}): Promise<unknown> | ((value: CallToolResult) => void) | undefined;
|
|
63
|
+
}
|
package/dist/ToolManager.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { createJSONDefineTool } from "./tool/createTool";
|
|
2
2
|
export class ToolManager {
|
|
3
|
-
|
|
3
|
+
constructor() {
|
|
4
|
+
this.tools = new Map();
|
|
5
|
+
// === 专门为前端设计的异步触发结构
|
|
6
|
+
this.waitingMap = new Map();
|
|
7
|
+
}
|
|
4
8
|
/**
|
|
5
9
|
* 注册一个工具
|
|
6
10
|
* @param tool 要注册的工具
|
|
@@ -57,8 +61,6 @@ export class ToolManager {
|
|
|
57
61
|
toJSON() {
|
|
58
62
|
return Array.from(this.tools.values()).map((i) => createJSONDefineTool(i));
|
|
59
63
|
}
|
|
60
|
-
// === 专门为前端设计的异步触发结构
|
|
61
|
-
waitingMap = new Map();
|
|
62
64
|
doneWaiting(id, value) {
|
|
63
65
|
if (this.waitingMap.has(id)) {
|
|
64
66
|
this.waitingMap.get(id)(value);
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Message } from "@langchain/langgraph-sdk";
|
|
2
|
+
/**
|
|
3
|
+
* copy and modify from copilotkit
|
|
4
|
+
* https://github.com/copilotkit/copilotkit
|
|
5
|
+
*
|
|
6
|
+
* MIT License
|
|
7
|
+
*/
|
|
8
|
+
type TypeMap = {
|
|
9
|
+
string: string;
|
|
10
|
+
number: number;
|
|
11
|
+
boolean: boolean;
|
|
12
|
+
object: object;
|
|
13
|
+
"string[]": string[];
|
|
14
|
+
"number[]": number[];
|
|
15
|
+
"boolean[]": boolean[];
|
|
16
|
+
"object[]": object[];
|
|
17
|
+
};
|
|
18
|
+
type AbstractParameter = {
|
|
19
|
+
name: string;
|
|
20
|
+
type?: keyof TypeMap;
|
|
21
|
+
description?: string;
|
|
22
|
+
required?: boolean;
|
|
23
|
+
};
|
|
24
|
+
interface StringParameter extends AbstractParameter {
|
|
25
|
+
type: "string";
|
|
26
|
+
enum?: string[];
|
|
27
|
+
}
|
|
28
|
+
interface ObjectParameter extends AbstractParameter {
|
|
29
|
+
type: "object";
|
|
30
|
+
attributes?: Parameter[];
|
|
31
|
+
}
|
|
32
|
+
interface ObjectArrayParameter extends AbstractParameter {
|
|
33
|
+
type: "object[]";
|
|
34
|
+
attributes?: Parameter[];
|
|
35
|
+
}
|
|
36
|
+
type SpecialParameters = StringParameter | ObjectParameter | ObjectArrayParameter;
|
|
37
|
+
interface BaseParameter extends AbstractParameter {
|
|
38
|
+
type?: Exclude<AbstractParameter["type"], SpecialParameters["type"]>;
|
|
39
|
+
}
|
|
40
|
+
export type Parameter = BaseParameter | SpecialParameters;
|
|
41
|
+
type OptionalParameterType<P extends AbstractParameter> = P["required"] extends false ? undefined : never;
|
|
42
|
+
type StringParameterType<P> = P extends StringParameter ? (P extends {
|
|
43
|
+
enum?: Array<infer E>;
|
|
44
|
+
} ? E : string) : never;
|
|
45
|
+
type ObjectParameterType<P> = P extends ObjectParameter ? (P extends {
|
|
46
|
+
attributes?: infer Attributes extends Parameter[];
|
|
47
|
+
} ? MappedParameterTypes<Attributes> : object) : never;
|
|
48
|
+
type ObjectArrayParameterType<P> = P extends ObjectArrayParameter ? (P extends {
|
|
49
|
+
attributes?: infer Attributes extends Parameter[];
|
|
50
|
+
} ? MappedParameterTypes<Attributes>[] : any[]) : never;
|
|
51
|
+
type MappedTypeOrString<T> = T extends keyof TypeMap ? TypeMap[T] : string;
|
|
52
|
+
type BaseParameterType<P extends AbstractParameter> = P extends {
|
|
53
|
+
type: infer T;
|
|
54
|
+
} ? (T extends BaseParameter["type"] ? MappedTypeOrString<T> : never) : string;
|
|
55
|
+
export type MappedParameterTypes<T extends Parameter[] | [] = []> = T extends [] ? Record<string, any> : {
|
|
56
|
+
[P in T[number] as P["name"]]: OptionalParameterType<P> | StringParameterType<P> | ObjectParameterType<P> | ObjectArrayParameterType<P> | BaseParameterType<P>;
|
|
57
|
+
};
|
|
58
|
+
export type Action<T extends Parameter[] | [] = []> = {
|
|
59
|
+
name: string;
|
|
60
|
+
description?: string;
|
|
61
|
+
parameters?: T;
|
|
62
|
+
handler?: T extends [] ? () => any | Promise<any> : (args: MappedParameterTypes<T>, context?: any) => any | Promise<any>;
|
|
63
|
+
returnDirect?: boolean;
|
|
64
|
+
callbackMessage?: () => Message[];
|
|
65
|
+
};
|
|
66
|
+
export {};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { z, ZodRawShape, ZodTypeAny } from "zod";
|
|
2
|
+
import { Action, Parameter } from "./copilotkit-actions";
|
|
3
|
+
import { Message } from "@langchain/langgraph-sdk";
|
|
4
|
+
export interface UnionTool<Args extends ZodRawShape> {
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
parameters: Args;
|
|
8
|
+
/** 是否直接返回工具结果,而不是通过消息返回 */
|
|
9
|
+
returnDirect?: boolean;
|
|
10
|
+
execute: ToolCallback<Args>;
|
|
11
|
+
/** 工具执行成功后触发的附加消息 */
|
|
12
|
+
callbackMessage?: (result: CallToolResult) => Message[];
|
|
13
|
+
}
|
|
14
|
+
export type ToolCallback<Args extends ZodRawShape> = (args: z.objectOutputType<Args, ZodTypeAny>, context?: any) => CallToolResult | Promise<CallToolResult>;
|
|
15
|
+
export type CallToolResult = string | {
|
|
16
|
+
type: "text";
|
|
17
|
+
text: string;
|
|
18
|
+
}[];
|
|
19
|
+
/** 用于格式校验 */
|
|
20
|
+
export declare const createTool: <Args extends ZodRawShape>(tool: UnionTool<Args>) => UnionTool<Args>;
|
|
21
|
+
/** 提供一种兼容 copilotkit 的定义方式,简化定义形式
|
|
22
|
+
* 来自 copilotkit 的 frontend action
|
|
23
|
+
*/
|
|
24
|
+
export declare const createFETool: <const T extends Parameter[], Args extends ZodRawShape>(tool: Action<T>) => UnionTool<Args>;
|
|
25
|
+
export declare const createJSONDefineTool: <Args extends ZodRawShape>(tool: UnionTool<Args>) => {
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
parameters: import("zod-to-json-schema").JsonSchema7Type & {
|
|
29
|
+
$schema?: string | undefined;
|
|
30
|
+
definitions?: {
|
|
31
|
+
[key: string]: import("zod-to-json-schema").JsonSchema7Type;
|
|
32
|
+
} | undefined;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare const createMCPTool: <Args extends ZodRawShape>(tool: UnionTool<Args>) => (string | Args | ((args: z.objectOutputType<Args, ZodTypeAny>) => Promise<{
|
|
36
|
+
content: {
|
|
37
|
+
type: string;
|
|
38
|
+
text: string;
|
|
39
|
+
}[];
|
|
40
|
+
isError?: undefined;
|
|
41
|
+
} | {
|
|
42
|
+
content: {
|
|
43
|
+
type: string;
|
|
44
|
+
text: string;
|
|
45
|
+
}[];
|
|
46
|
+
isError: boolean;
|
|
47
|
+
}>))[];
|
package/dist/tool/createTool.js
CHANGED
|
@@ -16,8 +16,9 @@ export const createFETool = (tool) => {
|
|
|
16
16
|
returnDirect: tool.returnDirect,
|
|
17
17
|
callbackMessage: tool.callbackMessage,
|
|
18
18
|
async execute(args, context) {
|
|
19
|
+
var _a;
|
|
19
20
|
try {
|
|
20
|
-
const result = await tool.handler
|
|
21
|
+
const result = await ((_a = tool.handler) === null || _a === void 0 ? void 0 : _a.call(tool, args, context));
|
|
21
22
|
if (typeof result === "string") {
|
|
22
23
|
return [{ type: "text", text: result }];
|
|
23
24
|
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* copy and modify from copilotkit
|
|
3
|
+
* https://github.com/copilotkit/copilotkit
|
|
4
|
+
*
|
|
5
|
+
* MIT License
|
|
6
|
+
*/
|
|
7
|
+
import { z, ZodRawShape } from "zod";
|
|
8
|
+
import { Parameter } from "./copilotkit-actions";
|
|
9
|
+
export type JSONSchemaString = {
|
|
10
|
+
type: "string";
|
|
11
|
+
description?: string;
|
|
12
|
+
enum?: string[];
|
|
13
|
+
};
|
|
14
|
+
export type JSONSchemaNumber = {
|
|
15
|
+
type: "number";
|
|
16
|
+
description?: string;
|
|
17
|
+
};
|
|
18
|
+
export type JSONSchemaBoolean = {
|
|
19
|
+
type: "boolean";
|
|
20
|
+
description?: string;
|
|
21
|
+
};
|
|
22
|
+
export type JSONSchemaObject = {
|
|
23
|
+
type: "object";
|
|
24
|
+
properties?: Record<string, JSONSchema>;
|
|
25
|
+
required?: string[];
|
|
26
|
+
description?: string;
|
|
27
|
+
};
|
|
28
|
+
export type JSONSchemaArray = {
|
|
29
|
+
type: "array";
|
|
30
|
+
items: JSONSchema;
|
|
31
|
+
description?: string;
|
|
32
|
+
};
|
|
33
|
+
export type JSONSchema = JSONSchemaString | JSONSchemaNumber | JSONSchemaBoolean | JSONSchemaObject | JSONSchemaArray;
|
|
34
|
+
export declare function actionParametersToJsonSchema(actionParameters: Parameter[]): JSONSchema;
|
|
35
|
+
export declare function convertJsonSchemaToZodRawShape(jsonSchema: any): ZodRawShape;
|
|
36
|
+
export declare function convertJsonSchemaToZodSchema(jsonSchema: any, required: boolean): z.ZodSchema;
|
package/dist/tool/utils.js
CHANGED
|
@@ -25,6 +25,7 @@ export function actionParametersToJsonSchema(actionParameters) {
|
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
27
|
function convertAttribute(attribute) {
|
|
28
|
+
var _a, _b, _c;
|
|
28
29
|
switch (attribute.type) {
|
|
29
30
|
case "string":
|
|
30
31
|
return {
|
|
@@ -40,11 +41,11 @@ function convertAttribute(attribute) {
|
|
|
40
41
|
};
|
|
41
42
|
case "object":
|
|
42
43
|
case "object[]":
|
|
43
|
-
const properties = attribute.attributes
|
|
44
|
+
const properties = (_a = attribute.attributes) === null || _a === void 0 ? void 0 : _a.reduce((acc, attr) => {
|
|
44
45
|
acc[attr.name] = convertAttribute(attr);
|
|
45
46
|
return acc;
|
|
46
47
|
}, {});
|
|
47
|
-
const required = attribute.attributes
|
|
48
|
+
const required = (_b = attribute.attributes) === null || _b === void 0 ? void 0 : _b.filter((attr) => attr.required !== false).map((attr) => attr.name);
|
|
48
49
|
if (attribute.type === "object[]") {
|
|
49
50
|
return {
|
|
50
51
|
type: "array",
|
|
@@ -64,7 +65,7 @@ function convertAttribute(attribute) {
|
|
|
64
65
|
};
|
|
65
66
|
default:
|
|
66
67
|
// Handle arrays of primitive types and undefined attribute.type
|
|
67
|
-
if (attribute.type
|
|
68
|
+
if ((_c = attribute.type) === null || _c === void 0 ? void 0 : _c.endsWith("[]")) {
|
|
68
69
|
const itemType = attribute.type.slice(0, -2);
|
|
69
70
|
return {
|
|
70
71
|
type: "array",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PreinitializedWritableAtom, StoreValue } from "nanostores";
|
|
2
|
+
export type UnionStore<T extends {
|
|
3
|
+
data: Record<string, PreinitializedWritableAtom<any>>;
|
|
4
|
+
mutations: Record<string, any>;
|
|
5
|
+
}> = {
|
|
6
|
+
[k in keyof T["data"]]: StoreValue<T["data"][k]>;
|
|
7
|
+
} & T["mutations"];
|
|
8
|
+
export declare const useUnionStore: <T extends {
|
|
9
|
+
data: Record<string, any>;
|
|
10
|
+
mutations: Record<string, any>;
|
|
11
|
+
}>(store: T, useStore: (store: PreinitializedWritableAtom<any>) => StoreValue<T["data"][keyof T["data"]]>) => UnionStore<T>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { LangGraphClient, LangGraphClientConfig, RenderMessage } from "../LangGraphClient";
|
|
2
|
+
import { Message, Thread } from "@langchain/langgraph-sdk";
|
|
3
|
+
export declare const formatTime: (date: Date) => string;
|
|
4
|
+
export declare const formatTokens: (tokens: number) => string;
|
|
5
|
+
export declare const getMessageContent: (content: any) => string;
|
|
6
|
+
export declare const createChatStore: (initClientName: string, config: LangGraphClientConfig, context?: {
|
|
7
|
+
onInit?: (client: LangGraphClient) => void;
|
|
8
|
+
}) => {
|
|
9
|
+
data: {
|
|
10
|
+
client: import("nanostores").PreinitializedWritableAtom<LangGraphClient | null> & object;
|
|
11
|
+
renderMessages: import("nanostores").PreinitializedWritableAtom<RenderMessage[]> & object;
|
|
12
|
+
userInput: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
13
|
+
loading: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
14
|
+
inChatError: import("nanostores").PreinitializedWritableAtom<string | null> & object;
|
|
15
|
+
currentAgent: import("nanostores").PreinitializedWritableAtom<string> & object;
|
|
16
|
+
collapsedTools: import("nanostores").PreinitializedWritableAtom<string[]> & object;
|
|
17
|
+
showHistory: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
18
|
+
historyList: import("nanostores").PreinitializedWritableAtom<Thread<{
|
|
19
|
+
messages: Message[];
|
|
20
|
+
}>[]> & object;
|
|
21
|
+
currentChatId: import("nanostores").PreinitializedWritableAtom<string | null> & object;
|
|
22
|
+
};
|
|
23
|
+
mutations: {
|
|
24
|
+
initClient: () => Promise<void>;
|
|
25
|
+
sendMessage: () => Promise<void>;
|
|
26
|
+
interruptMessage: () => void;
|
|
27
|
+
toggleToolCollapse: (toolId: string) => void;
|
|
28
|
+
toggleHistoryVisible: () => void;
|
|
29
|
+
refreshHistoryList: () => Promise<void>;
|
|
30
|
+
addToHistory: (thread: Thread<{
|
|
31
|
+
messages: Message[];
|
|
32
|
+
}>) => void;
|
|
33
|
+
setUserInput(input: string): void;
|
|
34
|
+
setCurrentAgent(agent: string): Promise<void>;
|
|
35
|
+
createNewChat(): void;
|
|
36
|
+
toHistoryChat(thread: Thread<{
|
|
37
|
+
messages: Message[];
|
|
38
|
+
}>): void;
|
|
39
|
+
deleteHistoryChat(thread: Thread<{
|
|
40
|
+
messages: Message[];
|
|
41
|
+
}>): Promise<void>;
|
|
42
|
+
};
|
|
43
|
+
};
|
|
@@ -35,11 +35,13 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
35
35
|
const currentAgent = atom(initClientName);
|
|
36
36
|
const currentChatId = atom(null);
|
|
37
37
|
const initClient = async () => {
|
|
38
|
+
var _a;
|
|
38
39
|
const newClient = new LangGraphClient(config);
|
|
39
40
|
await newClient.initAssistant(currentAgent.get());
|
|
40
41
|
// 不再需要创建,sendMessage 会自动创建
|
|
41
42
|
// await newClient.createThread();
|
|
42
43
|
newClient.onStreamingUpdate((event) => {
|
|
44
|
+
var _a;
|
|
43
45
|
if (event.type === "thread" || event.type === "done") {
|
|
44
46
|
// console.log(event.data);
|
|
45
47
|
// 创建新会话时,需要自动刷新历史面板
|
|
@@ -47,27 +49,29 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
47
49
|
}
|
|
48
50
|
if (event.type === "error") {
|
|
49
51
|
loading.set(false);
|
|
50
|
-
inChatError.set(event.data
|
|
52
|
+
inChatError.set(((_a = event.data) === null || _a === void 0 ? void 0 : _a.message) || "发生错误");
|
|
51
53
|
}
|
|
52
54
|
console.log(newClient.renderMessage);
|
|
53
55
|
renderMessages.set(newClient.renderMessage);
|
|
54
56
|
});
|
|
55
|
-
context.onInit
|
|
57
|
+
(_a = context.onInit) === null || _a === void 0 ? void 0 : _a.call(context, newClient);
|
|
56
58
|
// newClient.tools.bindTools([fileTool, askUserTool]);
|
|
57
59
|
newClient.graphState = {};
|
|
58
60
|
client.set(newClient);
|
|
59
61
|
};
|
|
60
62
|
const sendMessage = async () => {
|
|
63
|
+
var _a;
|
|
61
64
|
if (!userInput.get().trim() || loading.get() || !client.get())
|
|
62
65
|
return;
|
|
63
66
|
loading.set(true);
|
|
64
67
|
inChatError.set(null);
|
|
65
|
-
await client.get()
|
|
68
|
+
await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.sendMessage(userInput.get()));
|
|
66
69
|
userInput.set("");
|
|
67
70
|
loading.set(false);
|
|
68
71
|
};
|
|
69
72
|
const interruptMessage = () => {
|
|
70
|
-
|
|
73
|
+
var _a;
|
|
74
|
+
(_a = client.get()) === null || _a === void 0 ? void 0 : _a.cancelRun();
|
|
71
75
|
};
|
|
72
76
|
const toggleToolCollapse = (toolId) => {
|
|
73
77
|
const prev = collapsedTools.get();
|
|
@@ -78,10 +82,11 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
78
82
|
};
|
|
79
83
|
const historyList = atom([]);
|
|
80
84
|
const refreshHistoryList = async () => {
|
|
85
|
+
var _a;
|
|
81
86
|
if (!client.get())
|
|
82
87
|
return;
|
|
83
88
|
try {
|
|
84
|
-
const response = await client.get()
|
|
89
|
+
const response = await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.listThreads());
|
|
85
90
|
historyList.set(response || []);
|
|
86
91
|
}
|
|
87
92
|
catch (error) {
|
|
@@ -123,13 +128,16 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
123
128
|
});
|
|
124
129
|
},
|
|
125
130
|
createNewChat() {
|
|
126
|
-
|
|
131
|
+
var _a;
|
|
132
|
+
(_a = client.get()) === null || _a === void 0 ? void 0 : _a.reset();
|
|
127
133
|
},
|
|
128
134
|
toHistoryChat(thread) {
|
|
129
|
-
|
|
135
|
+
var _a, _b;
|
|
136
|
+
(_a = client.get()) === null || _a === void 0 ? void 0 : _a.resetThread((_b = thread.metadata) === null || _b === void 0 ? void 0 : _b.graph_id, thread.thread_id);
|
|
130
137
|
},
|
|
131
138
|
async deleteHistoryChat(thread) {
|
|
132
|
-
|
|
139
|
+
var _a;
|
|
140
|
+
await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.threads.delete(thread.thread_id));
|
|
133
141
|
await refreshHistoryList();
|
|
134
142
|
},
|
|
135
143
|
},
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@langgraph-js/sdk",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
8
8
|
"registry": "https://registry.npmjs.org/",
|
package/tsconfig.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
|
|
12
12
|
|
|
13
13
|
/* Language and Environment */
|
|
14
|
-
"target": "
|
|
14
|
+
"target": "ES2019" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */,
|
|
15
15
|
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
|
|
16
16
|
// "jsx": "preserve", /* Specify what JSX code is generated. */
|
|
17
17
|
// "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
|
52
52
|
|
|
53
53
|
/* Emit */
|
|
54
|
-
|
|
54
|
+
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
|
55
55
|
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
|
56
56
|
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
|
57
57
|
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|