@langgraph-js/sdk 1.1.6 → 1.1.9
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 +98 -10
- package/dist/LangGraphClient.js +84 -8
- package/dist/SpendTime.d.ts +28 -0
- package/dist/SpendTime.js +28 -0
- package/dist/ToolManager.d.ts +37 -19
- package/dist/ToolManager.js +36 -18
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/tool/createTool.d.ts +1 -1
- package/dist/tool/createTool.js +1 -1
- package/dist/tool/index.d.ts +2 -2
- package/dist/tool/index.js +2 -2
- package/dist/tool/utils.d.ts +1 -1
- package/dist/ui-store/UnionStore.d.ts +8 -0
- package/dist/ui-store/UnionStore.js +4 -0
- package/dist/ui-store/createChatStore.d.ts +41 -1
- package/dist/ui-store/createChatStore.js +84 -9
- package/dist/ui-store/index.d.ts +2 -2
- package/dist/ui-store/index.js +2 -2
- package/dist/ui-store/rafDebounce.d.ts +6 -0
- package/dist/ui-store/rafDebounce.js +26 -0
- package/package.json +3 -5
- package/src/LangGraphClient.ts +108 -14
- package/src/SpendTime.ts +31 -0
- package/src/ToolManager.ts +42 -19
- package/src/index.ts +4 -4
- package/src/tool/createTool.ts +2 -2
- package/src/tool/index.ts +2 -2
- package/src/tool/utils.ts +1 -1
- package/src/ui-store/UnionStore.ts +10 -1
- package/src/ui-store/createChatStore.ts +91 -9
- package/src/ui-store/index.ts +2 -2
- package/src/ui-store/rafDebounce.ts +29 -0
- package/tsconfig.json +2 -2
- package/index.html +0 -12
- package/ui/index.ts +0 -182
- package/ui/tool.ts +0 -55
package/src/SpendTime.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @zh SpendTime 类用于计算和记录操作的耗时。
|
|
3
|
+
* @en The SpendTime class is used to calculate and record the time spent on operations.
|
|
4
|
+
*/
|
|
1
5
|
export class SpendTime {
|
|
2
6
|
private timeCounter = new Map<string, [Date, Date] | [Date]>();
|
|
3
7
|
|
|
8
|
+
/**
|
|
9
|
+
* @zh 开始计时。
|
|
10
|
+
* @en Starts timing.
|
|
11
|
+
*/
|
|
4
12
|
start(key: string) {
|
|
5
13
|
this.timeCounter.set(key, [new Date()]);
|
|
6
14
|
}
|
|
7
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @zh 结束计时。
|
|
18
|
+
* @en Ends timing.
|
|
19
|
+
*/
|
|
8
20
|
end(key: string) {
|
|
9
21
|
this.timeCounter.set(key, [this.timeCounter.get(key)?.[0] || new Date(), new Date()]);
|
|
10
22
|
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @zh 设置或更新指定键的耗时记录。如果键已存在,则更新结束时间;否则,开始新的计时。
|
|
26
|
+
* @en Sets or updates the time spent record for the specified key. If the key already exists, updates the end time; otherwise, starts a new timing.
|
|
27
|
+
*/
|
|
11
28
|
setSpendTime(key: string) {
|
|
12
29
|
if (this.timeCounter.has(key)) {
|
|
13
30
|
this.end(key);
|
|
@@ -15,13 +32,27 @@ export class SpendTime {
|
|
|
15
32
|
this.start(key);
|
|
16
33
|
}
|
|
17
34
|
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @zh 获取指定键的开始时间。
|
|
38
|
+
* @en Gets the start time for the specified key.
|
|
39
|
+
*/
|
|
18
40
|
getStartTime(key: string) {
|
|
19
41
|
return this.timeCounter.get(key)?.[0] || new Date();
|
|
20
42
|
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @zh 获取指定键的结束时间。
|
|
46
|
+
* @en Gets the end time for the specified key.
|
|
47
|
+
*/
|
|
21
48
|
getEndTime(key: string) {
|
|
22
49
|
return this.timeCounter.get(key)?.[1] || new Date();
|
|
23
50
|
}
|
|
24
51
|
|
|
52
|
+
/**
|
|
53
|
+
* @zh 获取指定键的耗时(毫秒)。
|
|
54
|
+
* @en Gets the time spent (in milliseconds) for the specified key.
|
|
55
|
+
*/
|
|
25
56
|
getSpendTime(key: string) {
|
|
26
57
|
const [start, end = new Date()] = this.timeCounter.get(key) || [new Date(), new Date()];
|
|
27
58
|
return end.getTime() - start.getTime();
|
package/src/ToolManager.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { ToolMessage } from "@langchain/langgraph-sdk";
|
|
2
|
-
import { LangGraphClient } from "./LangGraphClient";
|
|
3
|
-
import { CallToolResult, createJSONDefineTool, UnionTool } from "./tool/createTool";
|
|
2
|
+
import { LangGraphClient } from "./LangGraphClient.js";
|
|
3
|
+
import { CallToolResult, createJSONDefineTool, UnionTool } from "./tool/createTool.js";
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* @zh ToolManager 类用于管理和执行工具。
|
|
7
|
+
* @en The ToolManager class is used to manage and execute tools.
|
|
8
|
+
*/
|
|
5
9
|
export class ToolManager {
|
|
6
10
|
private tools: Map<string, UnionTool<any>> = new Map();
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
|
-
*
|
|
10
|
-
* @
|
|
13
|
+
* @zh 注册一个工具。
|
|
14
|
+
* @en Registers a tool.
|
|
11
15
|
*/
|
|
12
16
|
bindTool(tool: UnionTool<any>) {
|
|
13
17
|
if (this.tools.has(tool.name)) {
|
|
@@ -17,45 +21,49 @@ export class ToolManager {
|
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
|
-
*
|
|
21
|
-
* @
|
|
24
|
+
* @zh 注册多个工具。
|
|
25
|
+
* @en Registers multiple tools.
|
|
22
26
|
*/
|
|
23
27
|
bindTools(tools: UnionTool<any>[]) {
|
|
24
28
|
tools.forEach((tool) => this.bindTool(tool));
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
/**
|
|
28
|
-
*
|
|
29
|
-
* @
|
|
32
|
+
* @zh 获取所有已注册的工具。
|
|
33
|
+
* @en Gets all registered tools.
|
|
30
34
|
*/
|
|
31
35
|
getAllTools(): UnionTool<any>[] {
|
|
32
36
|
return Array.from(this.tools.values());
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
/**
|
|
36
|
-
*
|
|
37
|
-
* @
|
|
38
|
-
* @returns 工具实例或 undefined
|
|
40
|
+
* @zh 获取指定名称的工具。
|
|
41
|
+
* @en Gets the tool with the specified name.
|
|
39
42
|
*/
|
|
40
43
|
getTool(name: string): UnionTool<any> | undefined {
|
|
41
44
|
return this.tools.get(name);
|
|
42
45
|
}
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
|
-
*
|
|
46
|
-
* @
|
|
47
|
-
* @returns 是否成功移除
|
|
48
|
+
* @zh 移除指定名称的工具。
|
|
49
|
+
* @en Removes the tool with the specified name.
|
|
48
50
|
*/
|
|
49
51
|
removeTool(name: string): boolean {
|
|
50
52
|
return this.tools.delete(name);
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
|
-
*
|
|
56
|
+
* @zh 清空所有工具。
|
|
57
|
+
* @en Clears all tools.
|
|
55
58
|
*/
|
|
56
59
|
clearTools() {
|
|
57
60
|
this.tools.clear();
|
|
58
61
|
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @zh 调用指定名称的工具。
|
|
65
|
+
* @en Calls the tool with the specified name.
|
|
66
|
+
*/
|
|
59
67
|
async callTool(name: string, args: any, context: { client: LangGraphClient; message: ToolMessage }) {
|
|
60
68
|
const tool = this.getTool(name);
|
|
61
69
|
if (!tool) {
|
|
@@ -63,12 +71,22 @@ export class ToolManager {
|
|
|
63
71
|
}
|
|
64
72
|
return await tool.execute(args, context);
|
|
65
73
|
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @zh 将所有工具转换为 JSON 定义格式。
|
|
77
|
+
* @en Converts all tools to JSON definition format.
|
|
78
|
+
*/
|
|
66
79
|
toJSON() {
|
|
67
80
|
return Array.from(this.tools.values()).map((i) => createJSONDefineTool(i));
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
// === 专门为前端设计的异步触发结构
|
|
71
84
|
private waitingMap: Map<string, (value: CallToolResult) => void> = new Map();
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @zh 标记指定 ID 的工具等待已完成,并传递结果。
|
|
88
|
+
* @en Marks the tool waiting with the specified ID as completed and passes the result.
|
|
89
|
+
*/
|
|
72
90
|
doneWaiting(id: string, value: CallToolResult) {
|
|
73
91
|
if (this.waitingMap.has(id)) {
|
|
74
92
|
this.waitingMap.get(id)!(value);
|
|
@@ -79,6 +97,11 @@ export class ToolManager {
|
|
|
79
97
|
return false;
|
|
80
98
|
}
|
|
81
99
|
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @zh 等待指定 ID 的工具完成。
|
|
103
|
+
* @en Waits for the tool with the specified ID to complete.
|
|
104
|
+
*/
|
|
82
105
|
waitForDone(id: string) {
|
|
83
106
|
if (this.waitingMap.has(id)) {
|
|
84
107
|
return this.waitingMap.get(id);
|
|
@@ -88,10 +111,10 @@ export class ToolManager {
|
|
|
88
111
|
});
|
|
89
112
|
return promise;
|
|
90
113
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
*
|
|
94
|
-
*
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @zh 一个静态方法,用于在前端等待用户界面操作完成。
|
|
117
|
+
* @en A static method used in the frontend to wait for user interface operations to complete.
|
|
95
118
|
*/
|
|
96
119
|
static waitForUIDone<T>(_: T, context: { client: LangGraphClient; message: ToolMessage }) {
|
|
97
120
|
// console.log(context.message);
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export * from "./LangGraphClient";
|
|
2
|
-
export * from "./tool";
|
|
1
|
+
export * from "./LangGraphClient.js";
|
|
2
|
+
export * from "./tool/index.js";
|
|
3
3
|
export * from "@langchain/langgraph-sdk";
|
|
4
|
-
export * from "./ui-store";
|
|
5
|
-
export * from "./ToolManager";
|
|
4
|
+
export * from "./ui-store/index.js";
|
|
5
|
+
export * from "./ToolManager.js";
|
package/src/tool/createTool.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { actionParametersToJsonSchema, convertJsonSchemaToZodRawShape } from "./utils";
|
|
1
|
+
import { actionParametersToJsonSchema, convertJsonSchemaToZodRawShape } from "./utils.js";
|
|
2
2
|
import { z, ZodRawShape, ZodTypeAny } from "zod";
|
|
3
|
-
import { Action, Parameter } from "./copilotkit-actions";
|
|
3
|
+
import { Action, Parameter } from "./copilotkit-actions.js";
|
|
4
4
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5
5
|
import { Message } from "@langchain/langgraph-sdk";
|
|
6
6
|
|
package/src/tool/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./createTool";
|
|
2
|
-
export * from "./copilotkit-actions";
|
|
1
|
+
export * from "./createTool.js";
|
|
2
|
+
export * from "./copilotkit-actions.js";
|
package/src/tool/utils.ts
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { PreinitializedWritableAtom, StoreValue } from "nanostores";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @zh UnionStore 类型用于合并 store 的 data 和 mutations,使其可以直接访问。
|
|
5
|
+
* @en The UnionStore type is used to merge the data and mutations of a store, allowing direct access.
|
|
6
|
+
*/
|
|
2
7
|
export type UnionStore<T extends { data: Record<string, PreinitializedWritableAtom<any>>; mutations: Record<string, any> }> = {
|
|
3
8
|
[k in keyof T["data"]]: StoreValue<T["data"][k]>;
|
|
4
9
|
} & T["mutations"];
|
|
5
10
|
|
|
11
|
+
/**
|
|
12
|
+
* @zh useUnionStore Hook 用于将 nanostores 的 store 结构转换为更易于在 UI 组件中使用的扁平结构。
|
|
13
|
+
* @en The useUnionStore Hook is used to transform the nanostores store structure into a flatter structure that is easier to use in UI components.
|
|
14
|
+
*/
|
|
6
15
|
export const useUnionStore = <T extends { data: Record<string, any>; mutations: Record<string, any> }>(
|
|
7
16
|
store: T,
|
|
8
17
|
useStore: (store: PreinitializedWritableAtom<any>) => StoreValue<T["data"][keyof T["data"]]>
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import { atom } from "nanostores";
|
|
2
|
-
import { LangGraphClient, LangGraphClientConfig, RenderMessage, SendMessageOptions } from "../LangGraphClient";
|
|
2
|
+
import { LangGraphClient, LangGraphClientConfig, RenderMessage, SendMessageOptions } from "../LangGraphClient.js";
|
|
3
3
|
import { Message, Thread } from "@langchain/langgraph-sdk";
|
|
4
|
+
import { rafDebounce } from "./rafDebounce.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @zh 格式化日期对象为时间字符串。
|
|
8
|
+
* @en Formats a Date object into a time string.
|
|
9
|
+
*/
|
|
4
10
|
export const formatTime = (date: Date) => {
|
|
5
11
|
return date.toLocaleTimeString("en-US");
|
|
6
12
|
};
|
|
7
13
|
|
|
14
|
+
/**
|
|
15
|
+
* @zh 格式化数字为带千位分隔符的字符串。
|
|
16
|
+
* @en Formats a number into a string with thousand separators.
|
|
17
|
+
*/
|
|
8
18
|
export const formatTokens = (tokens: number) => {
|
|
9
19
|
return tokens.toLocaleString("en");
|
|
10
20
|
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @zh 获取消息内容的文本表示,处理不同类型的消息内容。
|
|
24
|
+
* @en Gets the text representation of message content, handling different types of message content.
|
|
25
|
+
*/
|
|
11
26
|
export const getMessageContent = (content: any) => {
|
|
12
27
|
if (typeof content === "string") return content;
|
|
13
28
|
if (Array.isArray(content)) {
|
|
@@ -22,6 +37,11 @@ export const getMessageContent = (content: any) => {
|
|
|
22
37
|
}
|
|
23
38
|
return JSON.stringify(content);
|
|
24
39
|
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @zh 获取历史记录中 Thread 内容的文本表示。
|
|
43
|
+
* @en Gets the text representation of Thread content in history.
|
|
44
|
+
*/
|
|
25
45
|
export const getHistoryContent = (thread: Thread) => {
|
|
26
46
|
const content = (thread?.values as any)?.messages?.[0]?.content;
|
|
27
47
|
if (content && Array.isArray(content)) {
|
|
@@ -36,6 +56,11 @@ export const getHistoryContent = (thread: Thread) => {
|
|
|
36
56
|
return "";
|
|
37
57
|
}
|
|
38
58
|
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @zh 创建一个用于聊天界面的状态管理器 (store)。
|
|
62
|
+
* @en Creates a state manager (store) for the chat interface.
|
|
63
|
+
*/
|
|
39
64
|
export const createChatStore = (
|
|
40
65
|
initClientName: string,
|
|
41
66
|
config: LangGraphClientConfig,
|
|
@@ -53,12 +78,20 @@ export const createChatStore = (
|
|
|
53
78
|
const currentAgent = atom<string>(initClientName);
|
|
54
79
|
const currentChatId = atom<string | null>(null);
|
|
55
80
|
|
|
56
|
-
const
|
|
81
|
+
const updateUI = rafDebounce((newClient: LangGraphClient) => {
|
|
82
|
+
renderMessages.set(newClient.renderMessage);
|
|
83
|
+
});
|
|
84
|
+
/**
|
|
85
|
+
* @zh 初始化 LangGraph 客户端。
|
|
86
|
+
* @en Initializes the LangGraph client.
|
|
87
|
+
*/
|
|
88
|
+
async function initClient() {
|
|
57
89
|
const newClient = new LangGraphClient(config);
|
|
58
90
|
await newClient.initAssistant(currentAgent.get());
|
|
91
|
+
currentAgent.set(newClient.getCurrentAssistant()!.graph_id);
|
|
59
92
|
// 不再需要创建,sendMessage 会自动创建
|
|
60
93
|
// await newClient.createThread();
|
|
61
|
-
|
|
94
|
+
inChatError.set(null);
|
|
62
95
|
newClient.onStreamingUpdate((event) => {
|
|
63
96
|
if (event.type === "thread" || event.type === "done") {
|
|
64
97
|
// console.log(event.data);
|
|
@@ -67,17 +100,21 @@ export const createChatStore = (
|
|
|
67
100
|
}
|
|
68
101
|
if (event.type === "error") {
|
|
69
102
|
loading.set(false);
|
|
70
|
-
inChatError.set(event.data
|
|
103
|
+
inChatError.set(event.data);
|
|
71
104
|
}
|
|
72
105
|
// console.log(newClient.renderMessage);
|
|
73
|
-
|
|
106
|
+
|
|
107
|
+
updateUI(newClient);
|
|
74
108
|
});
|
|
75
109
|
context.onInit?.(newClient);
|
|
76
|
-
// newClient.tools.bindTools([fileTool, askUserTool]);
|
|
77
110
|
newClient.graphState = {};
|
|
78
111
|
client.set(newClient);
|
|
79
|
-
}
|
|
112
|
+
}
|
|
80
113
|
|
|
114
|
+
/**
|
|
115
|
+
* @zh 发送消息。
|
|
116
|
+
* @en Sends a message.
|
|
117
|
+
*/
|
|
81
118
|
const sendMessage = async (message?: Message[], extraData?: SendMessageOptions) => {
|
|
82
119
|
if ((!userInput.get().trim() && !message?.length) || loading.get() || !client.get()) return;
|
|
83
120
|
|
|
@@ -90,21 +127,39 @@ export const createChatStore = (
|
|
|
90
127
|
loading.set(false);
|
|
91
128
|
};
|
|
92
129
|
|
|
130
|
+
/**
|
|
131
|
+
* @zh 停止当前的消息生成。
|
|
132
|
+
* @en Stops the current message generation.
|
|
133
|
+
*/
|
|
93
134
|
const stopGeneration = () => {
|
|
94
135
|
client.get()?.cancelRun();
|
|
95
136
|
};
|
|
96
137
|
|
|
138
|
+
/**
|
|
139
|
+
* @zh 切换工具消息的折叠状态。
|
|
140
|
+
* @en Toggles the collapsed state of a tool message.
|
|
141
|
+
*/
|
|
97
142
|
const toggleToolCollapse = (toolId: string) => {
|
|
98
143
|
const prev = collapsedTools.get();
|
|
99
144
|
collapsedTools.set(prev.includes(toolId) ? prev.filter((id) => id !== toolId) : [...prev, toolId]);
|
|
100
145
|
};
|
|
101
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @zh 切换历史记录面板的可见性。
|
|
149
|
+
* @en Toggles the visibility of the history panel.
|
|
150
|
+
*/
|
|
102
151
|
const toggleHistoryVisible = () => {
|
|
103
152
|
showHistory.set(!showHistory.get());
|
|
104
153
|
};
|
|
154
|
+
|
|
105
155
|
const historyList = atom<Thread<{ messages: Message[] }>[]>([]);
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @zh 刷新历史记录列表。
|
|
159
|
+
* @en Refreshes the history list.
|
|
160
|
+
*/
|
|
106
161
|
const refreshHistoryList = async () => {
|
|
107
|
-
if (!client.get()) return;
|
|
162
|
+
if (!client.get() || !showHistory.get()) return;
|
|
108
163
|
try {
|
|
109
164
|
const response = await client.get()?.listThreads<{ messages: Message[] }>();
|
|
110
165
|
historyList.set(response || []);
|
|
@@ -113,6 +168,10 @@ export const createChatStore = (
|
|
|
113
168
|
}
|
|
114
169
|
};
|
|
115
170
|
|
|
171
|
+
/**
|
|
172
|
+
* @zh 将一个 Thread 添加到历史记录列表的开头。
|
|
173
|
+
* @en Adds a Thread to the beginning of the history list.
|
|
174
|
+
*/
|
|
116
175
|
const addToHistory = (thread: Thread<{ messages: Message[] }>) => {
|
|
117
176
|
const prev = historyList.get();
|
|
118
177
|
historyList.set([thread, ...prev]);
|
|
@@ -139,18 +198,37 @@ export const createChatStore = (
|
|
|
139
198
|
toggleHistoryVisible,
|
|
140
199
|
refreshHistoryList,
|
|
141
200
|
addToHistory,
|
|
201
|
+
/**
|
|
202
|
+
* @zh 设置用户输入内容。
|
|
203
|
+
* @en Sets the user input content.
|
|
204
|
+
*/
|
|
142
205
|
setUserInput(input: string) {
|
|
143
206
|
userInput.set(input);
|
|
144
207
|
},
|
|
208
|
+
/**
|
|
209
|
+
* @zh 设置当前的 Agent 并重新初始化客户端。
|
|
210
|
+
* @en Sets the current Agent and reinitializes the client.
|
|
211
|
+
*/
|
|
145
212
|
setCurrentAgent(agent: string) {
|
|
146
213
|
currentAgent.set(agent);
|
|
147
214
|
return initClient().then(() => {
|
|
148
|
-
|
|
215
|
+
if (showHistory.get()) {
|
|
216
|
+
refreshHistoryList();
|
|
217
|
+
}
|
|
149
218
|
});
|
|
150
219
|
},
|
|
220
|
+
/**
|
|
221
|
+
* @zh 创建一个新的聊天会话。
|
|
222
|
+
* @en Creates a new chat session.
|
|
223
|
+
*/
|
|
151
224
|
createNewChat() {
|
|
152
225
|
client.get()?.reset();
|
|
226
|
+
inChatError.set(null);
|
|
153
227
|
},
|
|
228
|
+
/**
|
|
229
|
+
* @zh 切换到指定的历史聊天会话。
|
|
230
|
+
* @en Switches to the specified historical chat session.
|
|
231
|
+
*/
|
|
154
232
|
toHistoryChat(
|
|
155
233
|
thread: Thread<{
|
|
156
234
|
messages: Message[];
|
|
@@ -158,6 +236,10 @@ export const createChatStore = (
|
|
|
158
236
|
) {
|
|
159
237
|
client.get()?.resetThread(thread.metadata?.graph_id as string, thread.thread_id);
|
|
160
238
|
},
|
|
239
|
+
/**
|
|
240
|
+
* @zh 删除指定的历史聊天会话。
|
|
241
|
+
* @en Deletes the specified historical chat session.
|
|
242
|
+
*/
|
|
161
243
|
async deleteHistoryChat(thread: Thread<{ messages: Message[] }>) {
|
|
162
244
|
await client.get()?.threads.delete(thread.thread_id);
|
|
163
245
|
await refreshHistoryList();
|
package/src/ui-store/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from "./createChatStore";
|
|
2
|
-
export * from "./UnionStore";
|
|
1
|
+
export * from "./createChatStore.js";
|
|
2
|
+
export * from "./UnionStore.js";
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a debounced function that executes once per animation frame
|
|
3
|
+
* @param callback - The function to debounce
|
|
4
|
+
* @returns A function that executes the callback on the next animation frame
|
|
5
|
+
*/
|
|
6
|
+
export function rafDebounce<T extends (...args: any[]) => any>(callback: T): (...args: Parameters<T>) => void {
|
|
7
|
+
let rafId: number | null = null;
|
|
8
|
+
let lastArgs: Parameters<T> | null = null;
|
|
9
|
+
|
|
10
|
+
// Return the debounced function
|
|
11
|
+
return function (...args: Parameters<T>): void {
|
|
12
|
+
// Store the most recent arguments
|
|
13
|
+
lastArgs = args;
|
|
14
|
+
|
|
15
|
+
// Cancel any pending animation frame
|
|
16
|
+
if (rafId !== null) {
|
|
17
|
+
cancelAnimationFrame(rafId);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Schedule execution on the next animation frame
|
|
21
|
+
rafId = requestAnimationFrame(() => {
|
|
22
|
+
if (lastArgs !== null) {
|
|
23
|
+
callback(...lastArgs);
|
|
24
|
+
lastArgs = null;
|
|
25
|
+
}
|
|
26
|
+
rafId = null;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
// "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */
|
|
26
26
|
|
|
27
27
|
/* Modules */
|
|
28
|
-
"module": "
|
|
28
|
+
"module": "NodeNext" /* Specify what module code is generated. */,
|
|
29
29
|
// "rootDir": "./", /* Specify the root folder within your source files. */
|
|
30
|
-
"moduleResolution": "
|
|
30
|
+
"moduleResolution": "nodenext" /* Specify how TypeScript looks up a file from a given module specifier. */,
|
|
31
31
|
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
|
|
32
32
|
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
|
|
33
33
|
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
|
package/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>Document</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="message"></div>
|
|
10
|
-
</body>
|
|
11
|
-
<script type="module" src="/ui/index.ts"></script>
|
|
12
|
-
</html>
|