@langgraph-js/sdk 3.7.0 → 3.8.0
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/README.md +29 -0
- package/dist/History.d.ts +115 -0
- package/dist/History.js +226 -0
- package/dist/LangGraphClient.d.ts +23 -2
- package/dist/LangGraphClient.js +118 -80
- package/dist/MessageProcessor.js +18 -24
- package/dist/SpendTime.js +4 -9
- package/dist/TestKit.d.ts +1 -1
- package/dist/TestKit.js +16 -15
- package/dist/ToolManager.js +4 -7
- package/dist/artifacts/index.js +1 -1
- package/dist/client/LanggraphServer.js +1 -1
- package/dist/client/LowJSServer.d.ts +3 -0
- package/dist/client/LowJSServer.js +80 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +2 -0
- package/dist/client/utils/sse.d.ts +8 -0
- package/dist/client/utils/sse.js +151 -0
- package/dist/client/utils/stream.d.ts +15 -0
- package/dist/client/utils/stream.js +104 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/react/ChatContext.d.ts +31 -20
- package/dist/react/ChatContext.js +10 -4
- package/dist/tool/ToolUI.js +3 -2
- package/dist/tool/createTool.js +3 -6
- package/dist/tool/utils.js +3 -4
- package/dist/ui-store/createChatStore.d.ts +33 -66
- package/dist/ui-store/createChatStore.js +261 -247
- package/dist/vue/ChatContext.d.ts +41 -21
- package/dist/vue/ChatContext.js +8 -2
- package/package.json +3 -1
- package/src/History.ts +294 -0
- package/src/LangGraphClient.ts +98 -48
- package/src/client/LanggraphServer.ts +1 -2
- package/src/client/LowJSServer.ts +80 -0
- package/src/client/index.ts +2 -0
- package/src/client/utils/sse.ts +176 -0
- package/src/client/utils/stream.ts +114 -0
- package/src/index.ts +2 -0
- package/src/react/ChatContext.ts +25 -16
- package/src/ui-store/createChatStore.ts +310 -236
- package/src/vue/ChatContext.ts +12 -0
- package/test/TestKit.test.ts +10 -2
- package/tsconfig.json +1 -1
|
@@ -1,27 +1,12 @@
|
|
|
1
1
|
import { atom } from "nanostores";
|
|
2
|
-
import { LangGraphClient } from "../LangGraphClient.js";
|
|
3
2
|
import { debounce } from "ts-debounce";
|
|
4
3
|
import { ToolRenderData } from "../tool/ToolUI.js";
|
|
5
4
|
import { createLangGraphServerClient } from "../client/LanggraphServer.js";
|
|
6
5
|
import { useArtifacts } from "../artifacts/index.js";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export const formatTime = (date) => {
|
|
12
|
-
return date.toLocaleTimeString();
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* @zh 格式化数字为带千位分隔符的字符串。
|
|
16
|
-
* @en Formats a number into a string with thousand separators.
|
|
17
|
-
*/
|
|
18
|
-
export const formatTokens = (tokens) => {
|
|
19
|
-
return tokens.toLocaleString("en");
|
|
20
|
-
};
|
|
21
|
-
/**
|
|
22
|
-
* @zh 获取消息内容的文本表示,处理不同类型的消息内容。
|
|
23
|
-
* @en Gets the text representation of message content, handling different types of message content.
|
|
24
|
-
*/
|
|
6
|
+
import { History } from "../History.js";
|
|
7
|
+
// ============ 工具函数 ============
|
|
8
|
+
export const formatTime = (date) => date.toLocaleTimeString();
|
|
9
|
+
export const formatTokens = (tokens) => tokens.toLocaleString("en");
|
|
25
10
|
export const getMessageContent = (content) => {
|
|
26
11
|
if (typeof content === "string")
|
|
27
12
|
return content;
|
|
@@ -40,45 +25,56 @@ export const getMessageContent = (content) => {
|
|
|
40
25
|
}
|
|
41
26
|
return JSON.stringify(content);
|
|
42
27
|
};
|
|
43
|
-
/**
|
|
44
|
-
* @zh 获取历史记录中 Thread 内容的文本表示。
|
|
45
|
-
* @en Gets the text representation of Thread content in history.
|
|
46
|
-
*/
|
|
47
28
|
export const getHistoryContent = (thread) => {
|
|
48
|
-
var _a, _b, _c;
|
|
49
29
|
/** @ts-ignore */
|
|
50
|
-
const content = thread.title || thread.name ||
|
|
30
|
+
const content = thread.title || thread.name || thread?.values?.messages?.[0]?.content;
|
|
51
31
|
if (content && Array.isArray(content)) {
|
|
52
|
-
return content.map((item) =>
|
|
53
|
-
if (item.type === "text") {
|
|
54
|
-
return item.text;
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
else if (typeof content === "string") {
|
|
59
|
-
return content;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
return "";
|
|
32
|
+
return content.map((item) => (item.type === "text" ? item.text : undefined)).filter(Boolean);
|
|
63
33
|
}
|
|
34
|
+
return typeof content === "string" ? content : "";
|
|
64
35
|
};
|
|
65
|
-
|
|
66
|
-
* @zh 创建一个用于聊天界面的状态管理器 (store)。
|
|
67
|
-
* @en Creates a state manager (store) for the chat interface.
|
|
68
|
-
*/
|
|
36
|
+
// ============ Store 创建函数 ============
|
|
69
37
|
export const createChatStore = (initClientName, config, context = {}) => {
|
|
70
|
-
|
|
38
|
+
// ============ 状态原子 ============
|
|
39
|
+
// 会话管理
|
|
40
|
+
const history = atom(null);
|
|
41
|
+
const sessions = atom([]);
|
|
71
42
|
const client = atom(null);
|
|
43
|
+
const historyList = atom([]);
|
|
44
|
+
// UI 状态
|
|
72
45
|
const renderMessages = atom([]);
|
|
73
46
|
const userInput = atom("");
|
|
74
|
-
const loading = atom(false);
|
|
75
|
-
const collapsedTools = atom([]);
|
|
76
47
|
const inChatError = atom(null);
|
|
77
|
-
const showHistory = atom((_a = context.showHistory) !== null && _a !== void 0 ? _a : false);
|
|
78
48
|
const currentAgent = atom(initClientName);
|
|
79
49
|
const currentChatId = atom(null);
|
|
80
50
|
const currentNodeName = atom("__start__");
|
|
51
|
+
// 工具和图表
|
|
81
52
|
const tools = atom([]);
|
|
53
|
+
const collapsedTools = atom([]);
|
|
54
|
+
const showHistory = atom(context.showHistory ?? false);
|
|
55
|
+
const showGraph = atom(context.showGraph ?? false);
|
|
56
|
+
const graphVisualize = atom(null);
|
|
57
|
+
// ============ 内部状态 ============
|
|
58
|
+
let cleanupCurrentClient = null;
|
|
59
|
+
// ============ 计算属性 ============
|
|
60
|
+
/** 基于 client.status 的 loading 状态 */
|
|
61
|
+
const loading = atom(false);
|
|
62
|
+
const updateLoadingFromClientStatus = () => {
|
|
63
|
+
const c = client.get();
|
|
64
|
+
if (c) {
|
|
65
|
+
loading.set(c.status === "busy");
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
// ============ UI 更新逻辑 ============
|
|
69
|
+
const updateUI = debounce((newClient) => {
|
|
70
|
+
if (client.get() !== newClient)
|
|
71
|
+
return;
|
|
72
|
+
const messages = newClient.renderMessage;
|
|
73
|
+
const lastMessage = messages[messages.length - 1];
|
|
74
|
+
currentNodeName.set(lastMessage?.node_name || lastMessage?.name || "__start__");
|
|
75
|
+
renderMessages.set(messages);
|
|
76
|
+
}, 10);
|
|
77
|
+
// ============ 工具和图表辅助函数 ============
|
|
82
78
|
const refreshTools = async () => {
|
|
83
79
|
const c = client.get();
|
|
84
80
|
if (!c)
|
|
@@ -86,93 +82,174 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
86
82
|
c.tools.clearTools();
|
|
87
83
|
c.tools.bindTools(tools.get());
|
|
88
84
|
};
|
|
89
|
-
// 显示 langgraph 可视化图
|
|
90
|
-
const showGraph = atom((_b = context.showGraph) !== null && _b !== void 0 ? _b : false);
|
|
91
|
-
const graphVisualize = atom(null);
|
|
92
85
|
const refreshGraph = async () => {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
86
|
+
if (showGraph.get()) {
|
|
87
|
+
graphVisualize.set((await client.get()?.graphVisualize()) || null);
|
|
88
|
+
}
|
|
96
89
|
};
|
|
97
|
-
|
|
98
|
-
const messages = newClient.renderMessage;
|
|
99
|
-
const lastMessage = messages[messages.length - 1];
|
|
100
|
-
currentNodeName.set((lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.node_name) || (lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.name) || "__start__");
|
|
101
|
-
renderMessages.set(messages);
|
|
102
|
-
}, 10);
|
|
103
|
-
/**
|
|
104
|
-
* @zh 初始化 LangGraph 客户端。
|
|
105
|
-
* @en Initializes the LangGraph client.
|
|
106
|
-
*/
|
|
90
|
+
// ============ 会话管理核心逻辑 ============
|
|
107
91
|
async function initClient() {
|
|
108
|
-
|
|
109
|
-
const newClient = new LangGraphClient({
|
|
92
|
+
const historyManager = new History({
|
|
110
93
|
...config,
|
|
111
|
-
client:
|
|
112
|
-
});
|
|
113
|
-
await newClient.initAssistant(currentAgent.get(), { fallbackToAvailableAssistants: (_b = context.fallbackToAvailableAssistants) !== null && _b !== void 0 ? _b : false });
|
|
114
|
-
currentAgent.set(newClient.getCurrentAssistant().graph_id);
|
|
115
|
-
// 不再需要创建,sendMessage 会自动创建
|
|
116
|
-
// await newClient.createThread();
|
|
117
|
-
inChatError.set(null);
|
|
118
|
-
// 监听流开始事件
|
|
119
|
-
newClient.on("start", () => {
|
|
120
|
-
loading.set(true);
|
|
94
|
+
client: config.client ?? (await createLangGraphServerClient(config)),
|
|
121
95
|
});
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
96
|
+
await historyManager.init(currentAgent.get());
|
|
97
|
+
history.set(historyManager);
|
|
98
|
+
// 同步远程会话列表
|
|
99
|
+
await refreshSessionList();
|
|
100
|
+
// 根据配置决定初始化行为
|
|
101
|
+
const syncedSessions = sessions.get();
|
|
102
|
+
if (context.autoRestoreLastSession && syncedSessions.length > 0) {
|
|
103
|
+
// 自动激活最近的历史会话
|
|
104
|
+
await activateSession(syncedSessions[0].sessionId);
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
// 创建新会话
|
|
108
|
+
await createNewSession();
|
|
109
|
+
}
|
|
110
|
+
return historyManager;
|
|
111
|
+
}
|
|
112
|
+
async function refreshSessionList() {
|
|
113
|
+
const historyManager = history.get();
|
|
114
|
+
if (!historyManager)
|
|
115
|
+
return;
|
|
116
|
+
try {
|
|
117
|
+
const syncedSessions = await historyManager.syncFromRemote({ limit: 100 });
|
|
118
|
+
sessions.set(syncedSessions);
|
|
119
|
+
historyList.set(syncedSessions.filter((s) => s.thread).map((s) => s.thread));
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error("Failed to sync sessions:", error);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function createNewSession() {
|
|
126
|
+
const historyManager = history.get();
|
|
127
|
+
if (!historyManager)
|
|
128
|
+
return;
|
|
129
|
+
try {
|
|
130
|
+
const session = await historyManager.createSession();
|
|
131
|
+
await refreshSessionList();
|
|
132
|
+
await activateSession(session.sessionId);
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
console.error("Failed to create new session:", error);
|
|
136
|
+
inChatError.set(error.message);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
// ============ 客户端事件监听器 ============
|
|
140
|
+
function setupClientListeners(newClient) {
|
|
141
|
+
const isActiveClient = () => client.get() === newClient;
|
|
142
|
+
const onStart = () => {
|
|
143
|
+
if (isActiveClient())
|
|
144
|
+
updateLoadingFromClientStatus();
|
|
145
|
+
};
|
|
146
|
+
const onThread = () => {
|
|
147
|
+
if (!isActiveClient())
|
|
148
|
+
return;
|
|
149
|
+
const thread = newClient.getCurrentThread();
|
|
150
|
+
currentChatId.set(thread?.thread_id || null);
|
|
127
151
|
currentNodeName.set("__start__");
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
152
|
+
const historyManager = history.get();
|
|
153
|
+
const activeSession = historyManager?.getActiveSession();
|
|
154
|
+
if (activeSession && thread) {
|
|
155
|
+
activeSession.thread = thread;
|
|
156
|
+
}
|
|
157
|
+
refreshSessionList();
|
|
158
|
+
};
|
|
159
|
+
const onDone = () => {
|
|
160
|
+
if (isActiveClient()) {
|
|
161
|
+
updateLoadingFromClientStatus();
|
|
162
|
+
updateUI(newClient);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
const onError = (event) => {
|
|
166
|
+
if (isActiveClient()) {
|
|
167
|
+
updateLoadingFromClientStatus();
|
|
168
|
+
inChatError.set(event.data);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const onMessage = () => {
|
|
172
|
+
if (isActiveClient()) {
|
|
173
|
+
currentChatId.set(newClient.getCurrentThread()?.thread_id || null);
|
|
174
|
+
updateLoadingFromClientStatus();
|
|
175
|
+
updateUI(newClient);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
const onValue = () => {
|
|
179
|
+
if (isActiveClient()) {
|
|
180
|
+
currentChatId.set(newClient.getCurrentThread()?.thread_id || null);
|
|
181
|
+
updateLoadingFromClientStatus();
|
|
182
|
+
updateUI(newClient);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
newClient.on("start", onStart);
|
|
186
|
+
newClient.on("thread", onThread);
|
|
187
|
+
newClient.on("done", onDone);
|
|
188
|
+
newClient.on("error", onError);
|
|
189
|
+
newClient.on("message", onMessage);
|
|
190
|
+
newClient.on("value", onValue);
|
|
191
|
+
return () => {
|
|
192
|
+
newClient.off("start", onStart);
|
|
193
|
+
newClient.off("thread", onThread);
|
|
194
|
+
newClient.off("done", onDone);
|
|
195
|
+
newClient.off("error", onError);
|
|
196
|
+
newClient.off("message", onMessage);
|
|
197
|
+
newClient.off("value", onValue);
|
|
198
|
+
};
|
|
158
199
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
200
|
+
// ============ 会话激活逻辑 ============
|
|
201
|
+
async function activateSession(sessionId) {
|
|
202
|
+
const historyManager = history.get();
|
|
203
|
+
if (!historyManager)
|
|
204
|
+
return;
|
|
205
|
+
try {
|
|
206
|
+
if (cleanupCurrentClient) {
|
|
207
|
+
cleanupCurrentClient();
|
|
208
|
+
cleanupCurrentClient = null;
|
|
209
|
+
}
|
|
210
|
+
inChatError.set(null);
|
|
211
|
+
const session = await historyManager.activateSession(sessionId);
|
|
212
|
+
const activeClient = session.client;
|
|
213
|
+
if (activeClient) {
|
|
214
|
+
cleanupCurrentClient = setupClientListeners(activeClient);
|
|
215
|
+
context.onInit?.(activeClient);
|
|
216
|
+
client.set(activeClient);
|
|
217
|
+
currentChatId.set(sessionId);
|
|
218
|
+
const messages = activeClient.renderMessage;
|
|
219
|
+
renderMessages.set(messages);
|
|
220
|
+
const lastMessage = messages[messages.length - 1];
|
|
221
|
+
currentNodeName.set(lastMessage?.node_name || lastMessage?.name || "__start__");
|
|
222
|
+
updateLoadingFromClientStatus();
|
|
223
|
+
if (showGraph.get())
|
|
224
|
+
refreshGraph();
|
|
225
|
+
refreshTools();
|
|
226
|
+
const currentThread = activeClient.getCurrentThread();
|
|
227
|
+
if (currentThread && (currentThread.status === "running" || currentThread.status === "pending")) {
|
|
228
|
+
await activeClient.resetStream();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
catch (error) {
|
|
233
|
+
console.error("Failed to activate session:", error);
|
|
234
|
+
inChatError.set(error.message);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// ============ 消息和交互逻辑 ============
|
|
238
|
+
async function sendMessage(message, extraData, withoutCheck = false) {
|
|
239
|
+
const c = client.get();
|
|
240
|
+
if ((!withoutCheck && !userInput.get().trim() && !message?.length) || !c)
|
|
241
|
+
return;
|
|
242
|
+
// 使用 client.status 判断是否正在加载
|
|
243
|
+
if (c.status === "busy")
|
|
166
244
|
return;
|
|
167
|
-
loading.set(true);
|
|
168
245
|
inChatError.set(null);
|
|
169
246
|
try {
|
|
170
|
-
await
|
|
247
|
+
await c.sendMessage(message || userInput.get(), extraData);
|
|
171
248
|
}
|
|
172
249
|
catch (e) {
|
|
173
250
|
const isThreadRunning = e.message.includes("422");
|
|
174
251
|
if (isThreadRunning) {
|
|
175
|
-
await
|
|
252
|
+
await c.resetStream();
|
|
176
253
|
}
|
|
177
254
|
else {
|
|
178
255
|
throw e;
|
|
@@ -180,112 +257,76 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
180
257
|
}
|
|
181
258
|
finally {
|
|
182
259
|
userInput.set("");
|
|
183
|
-
|
|
260
|
+
updateLoadingFromClientStatus();
|
|
184
261
|
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
const stopGeneration = () => {
|
|
191
|
-
var _a;
|
|
192
|
-
(_a = client.get()) === null || _a === void 0 ? void 0 : _a.cancelRun();
|
|
193
|
-
};
|
|
194
|
-
/**
|
|
195
|
-
* @zh 切换工具消息的折叠状态。
|
|
196
|
-
* @en Toggles the collapsed state of a tool message.
|
|
197
|
-
*/
|
|
198
|
-
const toggleToolCollapse = (toolId) => {
|
|
262
|
+
}
|
|
263
|
+
function stopGeneration() {
|
|
264
|
+
client.get()?.cancelRun();
|
|
265
|
+
}
|
|
266
|
+
function toggleToolCollapse(toolId) {
|
|
199
267
|
const prev = collapsedTools.get();
|
|
200
268
|
collapsedTools.set(prev.includes(toolId) ? prev.filter((id) => id !== toolId) : [...prev, toolId]);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
* @zh 切换历史记录面板的可见性。
|
|
204
|
-
* @en Toggles the visibility of the history panel.
|
|
205
|
-
*/
|
|
206
|
-
const toggleHistoryVisible = () => {
|
|
269
|
+
}
|
|
270
|
+
function toggleHistoryVisible() {
|
|
207
271
|
showHistory.set(!showHistory.get());
|
|
208
272
|
if (showHistory.get()) {
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
};
|
|
212
|
-
const historyList = atom([]);
|
|
213
|
-
/**
|
|
214
|
-
* @zh 刷新历史记录列表。
|
|
215
|
-
* @en Refreshes the history list.
|
|
216
|
-
*/
|
|
217
|
-
const refreshHistoryList = async () => {
|
|
218
|
-
var _a;
|
|
219
|
-
if (!client.get() || !showHistory.get())
|
|
220
|
-
return;
|
|
221
|
-
try {
|
|
222
|
-
const response = await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.listThreads());
|
|
223
|
-
historyList.set(response || []);
|
|
273
|
+
refreshSessionList();
|
|
224
274
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
/**
|
|
230
|
-
* @zh 将一个 Thread 添加到历史记录列表的开头。
|
|
231
|
-
* @en Adds a Thread to the beginning of the history list.
|
|
232
|
-
*/
|
|
233
|
-
const addToHistory = (thread) => {
|
|
275
|
+
}
|
|
276
|
+
function addToHistory(thread) {
|
|
234
277
|
const prev = historyList.get();
|
|
235
278
|
historyList.set([thread, ...prev]);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
279
|
+
}
|
|
280
|
+
function getToolUIRender(tool_name) {
|
|
281
|
+
const c = client.get();
|
|
282
|
+
if (!c)
|
|
283
|
+
return null;
|
|
284
|
+
const toolsDefine = c.tools.getAllTools();
|
|
285
|
+
const tool = toolsDefine.find((i) => i.name === tool_name)?.render;
|
|
286
|
+
return tool ? (message) => tool(new ToolRenderData(message, c)) : null;
|
|
287
|
+
}
|
|
288
|
+
// ============ 返回 Store API ============
|
|
243
289
|
const artifactHook = useArtifacts(renderMessages, client);
|
|
244
290
|
return {
|
|
245
291
|
data: {
|
|
292
|
+
// 核心客户端
|
|
246
293
|
client,
|
|
294
|
+
history,
|
|
295
|
+
sessions,
|
|
296
|
+
// UI 状态
|
|
247
297
|
renderMessages,
|
|
248
298
|
userInput,
|
|
249
299
|
loading,
|
|
250
300
|
inChatError,
|
|
251
301
|
currentAgent,
|
|
252
|
-
collapsedTools,
|
|
253
|
-
showHistory,
|
|
254
|
-
historyList,
|
|
255
302
|
currentChatId,
|
|
256
|
-
showGraph,
|
|
257
|
-
graphVisualize,
|
|
258
303
|
currentNodeName,
|
|
304
|
+
// 工具和图表
|
|
259
305
|
tools,
|
|
306
|
+
collapsedTools,
|
|
307
|
+
showGraph,
|
|
308
|
+
graphVisualize,
|
|
309
|
+
// 历史记录
|
|
310
|
+
showHistory,
|
|
311
|
+
historyList,
|
|
260
312
|
...artifactHook.data,
|
|
261
313
|
},
|
|
262
314
|
mutations: {
|
|
263
|
-
|
|
264
|
-
setTools(new_tools) {
|
|
265
|
-
tools.set(new_tools);
|
|
266
|
-
refreshTools();
|
|
267
|
-
},
|
|
268
|
-
isFELocking() {
|
|
269
|
-
var _a;
|
|
270
|
-
return (_a = client.get()) === null || _a === void 0 ? void 0 : _a.isFELocking(renderMessages.get());
|
|
271
|
-
},
|
|
272
|
-
getClient() {
|
|
273
|
-
return client.get();
|
|
274
|
-
},
|
|
315
|
+
// 初始化
|
|
275
316
|
initClient,
|
|
317
|
+
getClient: () => client.get(),
|
|
318
|
+
getHistory: () => history.get(),
|
|
319
|
+
// 会话管理
|
|
320
|
+
activateSession,
|
|
321
|
+
createNewSession,
|
|
322
|
+
refreshSessionList,
|
|
323
|
+
refreshHistoryList: refreshSessionList, // 向后兼容
|
|
324
|
+
// 消息操作
|
|
276
325
|
sendMessage,
|
|
277
326
|
stopGeneration,
|
|
278
|
-
|
|
279
|
-
toggleHistoryVisible,
|
|
280
|
-
refreshHistoryList,
|
|
281
|
-
addToHistory,
|
|
282
|
-
/**
|
|
283
|
-
* @zh 回滚到指定的消息。
|
|
284
|
-
* @en Reverts to the specified message.
|
|
285
|
-
*/
|
|
327
|
+
setUserInput: (input) => userInput.set(input),
|
|
286
328
|
async revertChatTo(messageId, resend = false, sendOptions) {
|
|
287
|
-
|
|
288
|
-
await ((_a = client.get()) === null || _a === void 0 ? void 0 : _a.revertChatTo(messageId, sendOptions || {}));
|
|
329
|
+
await client.get()?.revertChatTo(messageId, sendOptions || {});
|
|
289
330
|
if (resend) {
|
|
290
331
|
return sendMessage([], sendOptions, true);
|
|
291
332
|
}
|
|
@@ -293,66 +334,39 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
293
334
|
updateUI(client.get());
|
|
294
335
|
}
|
|
295
336
|
},
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
userInput.set(input);
|
|
302
|
-
},
|
|
303
|
-
/**
|
|
304
|
-
* @zh 设置当前的 Agent 并重新初始化客户端。
|
|
305
|
-
* @en Sets the current Agent and reinitializes the client.
|
|
306
|
-
*/
|
|
307
|
-
setCurrentAgent(agent) {
|
|
308
|
-
currentAgent.set(agent);
|
|
309
|
-
return initClient().then(() => {
|
|
310
|
-
if (showHistory.get()) {
|
|
311
|
-
refreshHistoryList();
|
|
312
|
-
}
|
|
313
|
-
});
|
|
337
|
+
// 工具操作
|
|
338
|
+
refreshTools,
|
|
339
|
+
setTools(new_tools) {
|
|
340
|
+
tools.set(new_tools);
|
|
341
|
+
refreshTools();
|
|
314
342
|
},
|
|
343
|
+
toggleToolCollapse,
|
|
344
|
+
getToolUIRender,
|
|
345
|
+
isFELocking: () => client.get()?.isFELocking(renderMessages.get()),
|
|
346
|
+
// UI 切换
|
|
347
|
+
toggleHistoryVisible,
|
|
315
348
|
toggleGraphVisible() {
|
|
316
349
|
showGraph.set(!showGraph.get());
|
|
317
|
-
if (showGraph.get())
|
|
350
|
+
if (showGraph.get())
|
|
318
351
|
refreshGraph();
|
|
319
|
-
}
|
|
320
352
|
},
|
|
321
353
|
refreshGraph,
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
createNewChat() {
|
|
327
|
-
var _a;
|
|
328
|
-
(_a = client.get()) === null || _a === void 0 ? void 0 : _a.reset();
|
|
329
|
-
inChatError.set(null);
|
|
330
|
-
loading.set(false);
|
|
331
|
-
},
|
|
332
|
-
/**
|
|
333
|
-
* @zh 切换到指定的历史聊天会话。
|
|
334
|
-
* @en Switches to the specified historical chat session.
|
|
335
|
-
*/
|
|
336
|
-
async toHistoryChat(thread) {
|
|
337
|
-
var _a, _b, _c;
|
|
338
|
-
inChatError.set(null);
|
|
339
|
-
loading.set(false);
|
|
340
|
-
const nowThread = await ((_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));
|
|
341
|
-
if (nowThread) {
|
|
342
|
-
(_c = client.get()) === null || _c === void 0 ? void 0 : _c.resetStream();
|
|
343
|
-
}
|
|
344
|
-
return nowThread;
|
|
354
|
+
// Agent 切换
|
|
355
|
+
setCurrentAgent(agent) {
|
|
356
|
+
currentAgent.set(agent);
|
|
357
|
+
return initClient();
|
|
345
358
|
},
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
359
|
+
// 历史记录(兼容旧 API)
|
|
360
|
+
addToHistory,
|
|
361
|
+
createNewChat: createNewSession,
|
|
362
|
+
toHistoryChat: (thread) => activateSession(thread.thread_id),
|
|
350
363
|
async deleteHistoryChat(thread) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
364
|
+
const historyManager = history.get();
|
|
365
|
+
if (historyManager) {
|
|
366
|
+
await historyManager.deleteSession(thread.thread_id);
|
|
367
|
+
await refreshSessionList();
|
|
368
|
+
}
|
|
354
369
|
},
|
|
355
|
-
getToolUIRender,
|
|
356
370
|
...artifactHook.mutation,
|
|
357
371
|
},
|
|
358
372
|
};
|