@langgraph-js/sdk 4.5.0 → 4.6.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/dist/History.d.ts +10 -4
- package/dist/LangGraphClient.d.ts +17 -11
- package/dist/LangGraphClient.js +33 -8
- package/dist/TestKit.d.ts +1 -164
- package/dist/react/ChatContext.d.ts +7 -1
- package/dist/solid/ChatContext.d.ts +7 -1
- package/dist/ui-store/createChatStore.d.ts +18 -1
- package/dist/ui-store/createChatStore.js +85 -4
- package/dist/vue/ChatContext.d.ts +7 -1
- package/package.json +1 -1
- package/src/History.ts +9 -3
- package/src/LangGraphClient.ts +30 -11
- package/src/TestKit.ts +1 -1
- package/src/ui-store/createChatStore.ts +115 -5
package/dist/History.d.ts
CHANGED
|
@@ -94,11 +94,17 @@ export declare class History {
|
|
|
94
94
|
* @en Lists all sessions from remote
|
|
95
95
|
*/
|
|
96
96
|
listRemoteSessions(options?: {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
97
|
+
ids?: string[];
|
|
98
|
+
metadata?: Record<string, any>;
|
|
99
|
+
status?: "idle" | "busy" | "interrupted" | "error";
|
|
100
|
+
values?: any;
|
|
100
101
|
limit?: number;
|
|
101
|
-
|
|
102
|
+
offset?: number;
|
|
103
|
+
sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
|
|
104
|
+
sortOrder?: "asc" | "desc";
|
|
105
|
+
select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
|
|
106
|
+
withoutDetails?: boolean;
|
|
107
|
+
}): Promise<Thread<unknown, unknown>[]>;
|
|
102
108
|
/**
|
|
103
109
|
* @zh 从远程同步会话到本地(仅同步元数据,不创建 Client)
|
|
104
110
|
* @en Syncs sessions from remote to local (metadata only, no client created)
|
|
@@ -153,7 +153,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
|
|
|
153
153
|
threadId?: string;
|
|
154
154
|
ifExists?: import("@langchain/langgraph-sdk").OnConflictBehavior;
|
|
155
155
|
graphId?: string;
|
|
156
|
-
}): Promise<Thread<TStateType>>;
|
|
156
|
+
}): Promise<Thread<TStateType, unknown>>;
|
|
157
157
|
search(query?: {
|
|
158
158
|
metadata?: import("@langchain/langgraph-sdk").Metadata;
|
|
159
159
|
limit?: number;
|
|
@@ -161,10 +161,10 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
|
|
|
161
161
|
status?: import("@langchain/langgraph-sdk").ThreadStatus;
|
|
162
162
|
sortBy?: import("@langgraph-js/pure-graph/dist/types.js").ThreadSortBy;
|
|
163
163
|
sortOrder?: import("@langgraph-js/pure-graph/dist/types.js").SortOrder;
|
|
164
|
-
}): Promise<Thread<TStateType>[]>;
|
|
165
|
-
get(threadId: string): Promise<Thread<TStateType>>;
|
|
164
|
+
}): Promise<Thread<TStateType, unknown>[]>;
|
|
165
|
+
get(threadId: string): Promise<Thread<TStateType, unknown>>;
|
|
166
166
|
delete(threadId: string): Promise<void>;
|
|
167
|
-
updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
|
|
167
|
+
updateState(threadId: string, thread: Partial<Thread<TStateType, unknown>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
|
|
168
168
|
};
|
|
169
169
|
/** 代理 runs 属性到内部 client */
|
|
170
170
|
get runs(): ILangGraphClient["runs"];
|
|
@@ -185,24 +185,30 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
|
|
|
185
185
|
createThread({ threadId, graphId }?: {
|
|
186
186
|
threadId?: string;
|
|
187
187
|
graphId?: string;
|
|
188
|
-
}): Promise<Thread<TStateType>>;
|
|
188
|
+
}): Promise<Thread<TStateType, unknown>>;
|
|
189
189
|
graphVisualize(): Promise<import("@langchain/langgraph-sdk").AssistantGraph>;
|
|
190
190
|
/**
|
|
191
191
|
* @zh 列出所有的 Thread。
|
|
192
192
|
* @en Lists all Threads.
|
|
193
193
|
*/
|
|
194
194
|
listThreads(options?: {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
ids?: string[];
|
|
196
|
+
metadata?: Record<string, any>;
|
|
197
|
+
status?: "idle" | "busy" | "interrupted" | "error";
|
|
198
|
+
values?: any;
|
|
198
199
|
limit?: number;
|
|
199
|
-
|
|
200
|
+
offset?: number;
|
|
201
|
+
sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
|
|
202
|
+
sortOrder?: "asc" | "desc";
|
|
203
|
+
select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
|
|
204
|
+
withoutDetails?: boolean;
|
|
205
|
+
}): Promise<Thread<TStateType, unknown>[]>;
|
|
200
206
|
deleteThread(threadId: string): Promise<void>;
|
|
201
207
|
/**
|
|
202
208
|
* @zh 从历史中恢复 Thread 数据。
|
|
203
209
|
* @en Resets the Thread data from history.
|
|
204
210
|
*/
|
|
205
|
-
resetThread(agent: string, threadId: string): Promise<Thread<TStateType>>;
|
|
211
|
+
resetThread(agent: string, threadId: string): Promise<Thread<TStateType, unknown>>;
|
|
206
212
|
resetStream(): Promise<void>;
|
|
207
213
|
cloneMessage(message: Message): Message;
|
|
208
214
|
/**
|
|
@@ -283,7 +289,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
|
|
|
283
289
|
* @zh 获取当前的 Thread。
|
|
284
290
|
* @en Gets the current Thread.
|
|
285
291
|
*/
|
|
286
|
-
getCurrentThread(): Thread<TStateType> | null;
|
|
292
|
+
getCurrentThread(): Thread<TStateType, unknown> | null;
|
|
287
293
|
/**
|
|
288
294
|
* @zh 获取当前的 Assistant。
|
|
289
295
|
* @en Gets the current Assistant.
|
package/dist/LangGraphClient.js
CHANGED
|
@@ -112,14 +112,39 @@ export class LangGraphClient extends EventEmitter {
|
|
|
112
112
|
* @en Lists all Threads.
|
|
113
113
|
*/
|
|
114
114
|
async listThreads(options = {}) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
115
|
+
const searchOptions = {};
|
|
116
|
+
if (options.ids)
|
|
117
|
+
searchOptions.ids = options.ids;
|
|
118
|
+
if (options.metadata)
|
|
119
|
+
searchOptions.metadata = options.metadata;
|
|
120
|
+
if (options.status)
|
|
121
|
+
searchOptions.status = options.status;
|
|
122
|
+
if (options.values)
|
|
123
|
+
searchOptions.values = options.values;
|
|
124
|
+
if (options.limit !== undefined)
|
|
125
|
+
searchOptions.limit = options.limit;
|
|
126
|
+
if (options.offset !== undefined)
|
|
127
|
+
searchOptions.offset = options.offset;
|
|
128
|
+
if (options.sortBy)
|
|
129
|
+
searchOptions.sortBy = options.sortBy;
|
|
130
|
+
if (options.sortOrder)
|
|
131
|
+
searchOptions.sortOrder = options.sortOrder;
|
|
132
|
+
if (options.select)
|
|
133
|
+
searchOptions.select = options.select;
|
|
134
|
+
if (options.withoutDetails !== undefined)
|
|
135
|
+
searchOptions.without_details = options.withoutDetails;
|
|
136
|
+
// 设置默认值
|
|
137
|
+
if (!options.sortBy)
|
|
138
|
+
searchOptions.sortBy = "updated_at";
|
|
139
|
+
if (!options.sortOrder)
|
|
140
|
+
searchOptions.sortOrder = "desc";
|
|
141
|
+
if (!options.limit)
|
|
142
|
+
searchOptions.limit = 10;
|
|
143
|
+
if (!options.offset)
|
|
144
|
+
searchOptions.offset = 0;
|
|
145
|
+
if (!options.withoutDetails)
|
|
146
|
+
searchOptions.without_details = true;
|
|
147
|
+
return this.threads.search(searchOptions);
|
|
123
148
|
}
|
|
124
149
|
async deleteThread(threadId) {
|
|
125
150
|
return this.threads.delete(threadId);
|
package/dist/TestKit.d.ts
CHANGED
|
@@ -146,169 +146,6 @@ export declare class TestLangGraphChat {
|
|
|
146
146
|
*/
|
|
147
147
|
findLast(type: "human" | "ai" | "tool", options?: {
|
|
148
148
|
before?: (item: RenderMessage) => boolean;
|
|
149
|
-
}):
|
|
150
|
-
additional_kwargs?: {
|
|
151
|
-
[x: string]: unknown;
|
|
152
|
-
} | undefined;
|
|
153
|
-
content: string | ({
|
|
154
|
-
type: "text";
|
|
155
|
-
text: string;
|
|
156
|
-
} | {
|
|
157
|
-
type: "image_url";
|
|
158
|
-
image_url: string | {
|
|
159
|
-
url: string;
|
|
160
|
-
detail?: ("auto" | "low" | "high") | undefined;
|
|
161
|
-
};
|
|
162
|
-
})[];
|
|
163
|
-
id?: string | undefined;
|
|
164
|
-
name?: string | undefined;
|
|
165
|
-
response_metadata?: Record<string, unknown> | undefined;
|
|
166
|
-
} & {
|
|
167
|
-
type: "human";
|
|
168
|
-
example?: boolean | undefined;
|
|
169
|
-
} & {
|
|
170
|
-
name?: string;
|
|
171
|
-
node_name?: string;
|
|
172
|
-
tool_input?: string;
|
|
173
|
-
additional_kwargs?: {
|
|
174
|
-
create_time: string;
|
|
175
|
-
update_time: string;
|
|
176
|
-
done?: boolean;
|
|
177
|
-
tool_calls?: {
|
|
178
|
-
function: {
|
|
179
|
-
arguments: string;
|
|
180
|
-
};
|
|
181
|
-
}[];
|
|
182
|
-
};
|
|
183
|
-
usage_metadata?: {
|
|
184
|
-
total_tokens: number;
|
|
185
|
-
input_tokens: number;
|
|
186
|
-
output_tokens: number;
|
|
187
|
-
};
|
|
188
|
-
tool_call_id?: string;
|
|
189
|
-
sub_messages?: RenderMessage[];
|
|
190
|
-
spend_time?: number;
|
|
191
|
-
unique_id?: string;
|
|
192
|
-
done?: boolean;
|
|
193
|
-
}) | ({
|
|
194
|
-
additional_kwargs?: {
|
|
195
|
-
[x: string]: unknown;
|
|
196
|
-
} | undefined;
|
|
197
|
-
content: string | ({
|
|
198
|
-
type: "text";
|
|
199
|
-
text: string;
|
|
200
|
-
} | {
|
|
201
|
-
type: "image_url";
|
|
202
|
-
image_url: string | {
|
|
203
|
-
url: string;
|
|
204
|
-
detail?: ("auto" | "low" | "high") | undefined;
|
|
205
|
-
};
|
|
206
|
-
})[];
|
|
207
|
-
id?: string | undefined;
|
|
208
|
-
name?: string | undefined;
|
|
209
|
-
response_metadata?: Record<string, unknown> | undefined;
|
|
210
|
-
} & {
|
|
211
|
-
type: "ai";
|
|
212
|
-
example?: boolean | undefined;
|
|
213
|
-
tool_calls?: {
|
|
214
|
-
name: string;
|
|
215
|
-
args: {
|
|
216
|
-
[x: string]: any;
|
|
217
|
-
};
|
|
218
|
-
id?: string | undefined;
|
|
219
|
-
type?: "tool_call" | undefined;
|
|
220
|
-
}[] | undefined;
|
|
221
|
-
invalid_tool_calls?: {
|
|
222
|
-
name?: string | undefined;
|
|
223
|
-
args?: string | undefined;
|
|
224
|
-
id?: string | undefined;
|
|
225
|
-
error?: string | undefined;
|
|
226
|
-
type?: "invalid_tool_call" | undefined;
|
|
227
|
-
}[] | undefined;
|
|
228
|
-
usage_metadata?: {
|
|
229
|
-
input_tokens: number;
|
|
230
|
-
output_tokens: number;
|
|
231
|
-
total_tokens: number;
|
|
232
|
-
input_token_details?: {
|
|
233
|
-
audio?: number | undefined;
|
|
234
|
-
cache_read?: number | undefined;
|
|
235
|
-
cache_creation?: number | undefined;
|
|
236
|
-
} | undefined;
|
|
237
|
-
output_token_details?: {
|
|
238
|
-
audio?: number | undefined;
|
|
239
|
-
reasoning?: number | undefined;
|
|
240
|
-
} | undefined;
|
|
241
|
-
} | undefined;
|
|
242
|
-
} & {
|
|
243
|
-
name?: string;
|
|
244
|
-
node_name?: string;
|
|
245
|
-
tool_input?: string;
|
|
246
|
-
additional_kwargs?: {
|
|
247
|
-
create_time: string;
|
|
248
|
-
update_time: string;
|
|
249
|
-
done?: boolean;
|
|
250
|
-
tool_calls?: {
|
|
251
|
-
function: {
|
|
252
|
-
arguments: string;
|
|
253
|
-
};
|
|
254
|
-
}[];
|
|
255
|
-
};
|
|
256
|
-
usage_metadata?: {
|
|
257
|
-
total_tokens: number;
|
|
258
|
-
input_tokens: number;
|
|
259
|
-
output_tokens: number;
|
|
260
|
-
};
|
|
261
|
-
tool_call_id?: string;
|
|
262
|
-
sub_messages?: RenderMessage[];
|
|
263
|
-
spend_time?: number;
|
|
264
|
-
unique_id?: string;
|
|
265
|
-
done?: boolean;
|
|
266
|
-
}) | ({
|
|
267
|
-
additional_kwargs?: {
|
|
268
|
-
[x: string]: unknown;
|
|
269
|
-
} | undefined;
|
|
270
|
-
content: string | ({
|
|
271
|
-
type: "text";
|
|
272
|
-
text: string;
|
|
273
|
-
} | {
|
|
274
|
-
type: "image_url";
|
|
275
|
-
image_url: string | {
|
|
276
|
-
url: string;
|
|
277
|
-
detail?: ("auto" | "low" | "high") | undefined;
|
|
278
|
-
};
|
|
279
|
-
})[];
|
|
280
|
-
id?: string | undefined;
|
|
281
|
-
name?: string | undefined;
|
|
282
|
-
response_metadata?: Record<string, unknown> | undefined;
|
|
283
|
-
} & {
|
|
284
|
-
type: "tool";
|
|
285
|
-
status?: "error" | "success" | undefined;
|
|
286
|
-
tool_call_id: string;
|
|
287
|
-
artifact?: any;
|
|
288
|
-
} & {
|
|
289
|
-
name?: string;
|
|
290
|
-
node_name?: string;
|
|
291
|
-
tool_input?: string;
|
|
292
|
-
additional_kwargs?: {
|
|
293
|
-
create_time: string;
|
|
294
|
-
update_time: string;
|
|
295
|
-
done?: boolean;
|
|
296
|
-
tool_calls?: {
|
|
297
|
-
function: {
|
|
298
|
-
arguments: string;
|
|
299
|
-
};
|
|
300
|
-
}[];
|
|
301
|
-
};
|
|
302
|
-
usage_metadata?: {
|
|
303
|
-
total_tokens: number;
|
|
304
|
-
input_tokens: number;
|
|
305
|
-
output_tokens: number;
|
|
306
|
-
};
|
|
307
|
-
tool_call_id?: string;
|
|
308
|
-
sub_messages?: RenderMessage[];
|
|
309
|
-
spend_time?: number;
|
|
310
|
-
unique_id?: string;
|
|
311
|
-
done?: boolean;
|
|
312
|
-
});
|
|
149
|
+
}): RenderMessage;
|
|
313
150
|
}
|
|
314
151
|
export {};
|
|
@@ -26,7 +26,9 @@ export declare const useChat: () => UnionStore<{
|
|
|
26
26
|
showHistory: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
27
27
|
historyList: import("nanostores").PreinitializedWritableAtom<import("@langchain/langgraph-sdk").Thread<{
|
|
28
28
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
29
|
-
}>[]> & object;
|
|
29
|
+
}, unknown>[]> & object;
|
|
30
|
+
historyPagination: import("nanostores").PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryPagination> & object;
|
|
31
|
+
historyFilter: import("nanostores").PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryFilter> & object;
|
|
30
32
|
};
|
|
31
33
|
mutations: {
|
|
32
34
|
setCurrentArtifactById: (id: string, tool_id: string) => void;
|
|
@@ -62,6 +64,10 @@ export declare const useChat: () => UnionStore<{
|
|
|
62
64
|
deleteHistoryChat(thread: import("@langchain/langgraph-sdk").Thread<{
|
|
63
65
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
64
66
|
}>): Promise<void>;
|
|
67
|
+
setHistoryPage(page: number): void;
|
|
68
|
+
setHistoryPageSize(pageSize: number): void;
|
|
69
|
+
setHistoryFilter(filter: Partial<import("../ui-store/createChatStore.js").HistoryFilter>): void;
|
|
70
|
+
resetHistoryFilter(): void;
|
|
65
71
|
};
|
|
66
72
|
}>;
|
|
67
73
|
interface ChatProviderProps {
|
|
@@ -26,7 +26,9 @@ export declare const useChat: () => UnionStoreSolid<{
|
|
|
26
26
|
showHistory: PreinitializedWritableAtom<boolean> & object;
|
|
27
27
|
historyList: PreinitializedWritableAtom<import("@langchain/langgraph-sdk").Thread<{
|
|
28
28
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
29
|
-
}>[]> & object;
|
|
29
|
+
}, unknown>[]> & object;
|
|
30
|
+
historyPagination: PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryPagination> & object;
|
|
31
|
+
historyFilter: PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryFilter> & object;
|
|
30
32
|
};
|
|
31
33
|
mutations: {
|
|
32
34
|
setCurrentArtifactById: (id: string, tool_id: string) => void;
|
|
@@ -62,6 +64,10 @@ export declare const useChat: () => UnionStoreSolid<{
|
|
|
62
64
|
deleteHistoryChat(thread: import("@langchain/langgraph-sdk").Thread<{
|
|
63
65
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
64
66
|
}>): Promise<void>;
|
|
67
|
+
setHistoryPage(page: number): void;
|
|
68
|
+
setHistoryPageSize(pageSize: number): void;
|
|
69
|
+
setHistoryFilter(filter: Partial<import("../ui-store/createChatStore.js").HistoryFilter>): void;
|
|
70
|
+
resetHistoryFilter(): void;
|
|
65
71
|
};
|
|
66
72
|
}>;
|
|
67
73
|
interface ChatProviderProps {
|
|
@@ -17,6 +17,17 @@ interface ChatStoreContext {
|
|
|
17
17
|
/** 初始化时是否自动激活最近的历史会话(默认 false,创建新会话) */
|
|
18
18
|
autoRestoreLastSession?: boolean;
|
|
19
19
|
}
|
|
20
|
+
export interface HistoryPagination {
|
|
21
|
+
page: number;
|
|
22
|
+
pageSize: number;
|
|
23
|
+
total: number;
|
|
24
|
+
}
|
|
25
|
+
export interface HistoryFilter {
|
|
26
|
+
metadata: Record<string, any> | null;
|
|
27
|
+
status: "idle" | "busy" | "interrupted" | "error" | null;
|
|
28
|
+
sortBy: "thread_id" | "status" | "created_at" | "updated_at";
|
|
29
|
+
sortOrder: "asc" | "desc";
|
|
30
|
+
}
|
|
20
31
|
export declare const createChatStore: (initClientName: string, config: Partial<LangGraphClientConfig>, context?: ChatStoreContext) => {
|
|
21
32
|
data: {
|
|
22
33
|
artifacts: import("nanostores").PreinitializedWritableAtom<import("../artifacts/index.js").ComposedArtifact[]> & object;
|
|
@@ -42,7 +53,9 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
|
|
|
42
53
|
showHistory: import("nanostores").PreinitializedWritableAtom<boolean> & object;
|
|
43
54
|
historyList: import("nanostores").PreinitializedWritableAtom<Thread<{
|
|
44
55
|
messages: Message[];
|
|
45
|
-
}>[]> & object;
|
|
56
|
+
}, unknown>[]> & object;
|
|
57
|
+
historyPagination: import("nanostores").PreinitializedWritableAtom<HistoryPagination> & object;
|
|
58
|
+
historyFilter: import("nanostores").PreinitializedWritableAtom<HistoryFilter> & object;
|
|
46
59
|
};
|
|
47
60
|
mutations: {
|
|
48
61
|
setCurrentArtifactById: (id: string, tool_id: string) => void;
|
|
@@ -78,6 +91,10 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
|
|
|
78
91
|
deleteHistoryChat(thread: Thread<{
|
|
79
92
|
messages: Message[];
|
|
80
93
|
}>): Promise<void>;
|
|
94
|
+
setHistoryPage(page: number): void;
|
|
95
|
+
setHistoryPageSize(pageSize: number): void;
|
|
96
|
+
setHistoryFilter(filter: Partial<HistoryFilter>): void;
|
|
97
|
+
resetHistoryFilter(): void;
|
|
81
98
|
};
|
|
82
99
|
};
|
|
83
100
|
export {};
|
|
@@ -70,6 +70,19 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
70
70
|
const showHistory = atom(context.showHistory ?? false);
|
|
71
71
|
const showGraph = atom(context.showGraph ?? false);
|
|
72
72
|
const graphVisualize = atom(null);
|
|
73
|
+
// 分页状态
|
|
74
|
+
const historyPagination = atom({
|
|
75
|
+
page: 1,
|
|
76
|
+
pageSize: 10,
|
|
77
|
+
total: 0,
|
|
78
|
+
});
|
|
79
|
+
// 历史记录筛选状态
|
|
80
|
+
const historyFilter = atom({
|
|
81
|
+
metadata: null,
|
|
82
|
+
status: null,
|
|
83
|
+
sortBy: "updated_at",
|
|
84
|
+
sortOrder: "desc",
|
|
85
|
+
});
|
|
73
86
|
// ============ 内部状态 ============
|
|
74
87
|
let cleanupCurrentClient = null;
|
|
75
88
|
// ============ 计算属性 ============
|
|
@@ -113,7 +126,6 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
113
126
|
});
|
|
114
127
|
await historyManager.init(currentAgent.get(), { fallbackToAvailableAssistants: context.fallbackToAvailableAssistants });
|
|
115
128
|
history.set(historyManager);
|
|
116
|
-
// 同步远程会话列表
|
|
117
129
|
// 根据配置决定初始化行为
|
|
118
130
|
if (context.autoRestoreLastSession) {
|
|
119
131
|
await refreshSessionList();
|
|
@@ -137,9 +149,35 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
137
149
|
if (!historyManager)
|
|
138
150
|
return;
|
|
139
151
|
try {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
152
|
+
const pagination = historyPagination.get();
|
|
153
|
+
const filter = historyFilter.get();
|
|
154
|
+
// 计算偏移量
|
|
155
|
+
const offset = (pagination.page - 1) * pagination.pageSize;
|
|
156
|
+
// 使用 listRemoteSessions 支持筛选
|
|
157
|
+
const threads = await historyManager.listRemoteSessions({
|
|
158
|
+
limit: pagination.pageSize,
|
|
159
|
+
offset,
|
|
160
|
+
metadata: filter.metadata || undefined,
|
|
161
|
+
status: filter.status || undefined,
|
|
162
|
+
sortBy: filter.sortBy,
|
|
163
|
+
sortOrder: filter.sortOrder,
|
|
164
|
+
withoutDetails: true,
|
|
165
|
+
});
|
|
166
|
+
// 注意:后端可能不返回总数,这里需要根据返回的记录数判断是否有下一页
|
|
167
|
+
// 如果返回的记录数小于 pageSize,说明没有更多数据了
|
|
168
|
+
const hasMore = threads.length === pagination.pageSize;
|
|
169
|
+
const estimatedTotal = (pagination.page - 1) * pagination.pageSize + threads.length;
|
|
170
|
+
sessions.set(threads.map((thread) => ({
|
|
171
|
+
sessionId: thread.thread_id,
|
|
172
|
+
thread,
|
|
173
|
+
agentName: currentAgent.get(),
|
|
174
|
+
})));
|
|
175
|
+
historyList.set(threads);
|
|
176
|
+
// 更新分页状态(注意:这里只是估计值,实际总数可能需要从后端获取)
|
|
177
|
+
historyPagination.set({
|
|
178
|
+
...pagination,
|
|
179
|
+
total: hasMore ? pagination.page * pagination.pageSize + 1 : estimatedTotal,
|
|
180
|
+
});
|
|
143
181
|
}
|
|
144
182
|
catch (error) {
|
|
145
183
|
console.error("Failed to sync sessions:", error);
|
|
@@ -364,6 +402,9 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
364
402
|
// 历史记录
|
|
365
403
|
showHistory,
|
|
366
404
|
historyList,
|
|
405
|
+
// 分页和筛选
|
|
406
|
+
historyPagination,
|
|
407
|
+
historyFilter,
|
|
367
408
|
...artifactHook.data,
|
|
368
409
|
},
|
|
369
410
|
mutations: {
|
|
@@ -429,6 +470,46 @@ export const createChatStore = (initClientName, config, context = {}) => {
|
|
|
429
470
|
await refreshSessionList();
|
|
430
471
|
}
|
|
431
472
|
},
|
|
473
|
+
// 分页和筛选操作
|
|
474
|
+
setHistoryPage(page) {
|
|
475
|
+
historyPagination.set({
|
|
476
|
+
...historyPagination.get(),
|
|
477
|
+
page,
|
|
478
|
+
});
|
|
479
|
+
refreshSessionList();
|
|
480
|
+
},
|
|
481
|
+
setHistoryPageSize(pageSize) {
|
|
482
|
+
historyPagination.set({
|
|
483
|
+
...historyPagination.get(),
|
|
484
|
+
pageSize,
|
|
485
|
+
page: 1, // 重置到第一页
|
|
486
|
+
});
|
|
487
|
+
refreshSessionList();
|
|
488
|
+
},
|
|
489
|
+
setHistoryFilter(filter) {
|
|
490
|
+
historyFilter.set({
|
|
491
|
+
...historyFilter.get(),
|
|
492
|
+
...filter,
|
|
493
|
+
});
|
|
494
|
+
historyPagination.set({
|
|
495
|
+
...historyPagination.get(),
|
|
496
|
+
page: 1, // 筛选变更时重置到第一页
|
|
497
|
+
});
|
|
498
|
+
refreshSessionList();
|
|
499
|
+
},
|
|
500
|
+
resetHistoryFilter() {
|
|
501
|
+
historyFilter.set({
|
|
502
|
+
metadata: null,
|
|
503
|
+
status: null,
|
|
504
|
+
sortBy: "updated_at",
|
|
505
|
+
sortOrder: "desc",
|
|
506
|
+
});
|
|
507
|
+
historyPagination.set({
|
|
508
|
+
...historyPagination.get(),
|
|
509
|
+
page: 1,
|
|
510
|
+
});
|
|
511
|
+
refreshSessionList();
|
|
512
|
+
},
|
|
432
513
|
...artifactHook.mutation,
|
|
433
514
|
},
|
|
434
515
|
};
|
|
@@ -70,7 +70,9 @@ export declare const useChatProvider: (props: ChatProviderProps) => {
|
|
|
70
70
|
showHistory: PreinitializedWritableAtom<boolean> & object;
|
|
71
71
|
historyList: PreinitializedWritableAtom<import("@langchain/langgraph-sdk").Thread<{
|
|
72
72
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
73
|
-
}>[]> & object;
|
|
73
|
+
}, unknown>[]> & object;
|
|
74
|
+
historyPagination: PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryPagination> & object;
|
|
75
|
+
historyFilter: PreinitializedWritableAtom<import("../ui-store/createChatStore.js").HistoryFilter> & object;
|
|
74
76
|
};
|
|
75
77
|
mutations: {
|
|
76
78
|
setCurrentArtifactById: (id: string, tool_id: string) => void;
|
|
@@ -106,6 +108,10 @@ export declare const useChatProvider: (props: ChatProviderProps) => {
|
|
|
106
108
|
deleteHistoryChat(thread: import("@langchain/langgraph-sdk").Thread<{
|
|
107
109
|
messages: import("@langchain/langgraph-sdk").Message[];
|
|
108
110
|
}>): Promise<void>;
|
|
111
|
+
setHistoryPage(page: number): void;
|
|
112
|
+
setHistoryPageSize(pageSize: number): void;
|
|
113
|
+
setHistoryFilter(filter: Partial<import("../ui-store/createChatStore.js").HistoryFilter>): void;
|
|
114
|
+
resetHistoryFilter(): void;
|
|
109
115
|
};
|
|
110
116
|
}>;
|
|
111
117
|
};
|
package/package.json
CHANGED
package/src/History.ts
CHANGED
|
@@ -230,10 +230,16 @@ export class History {
|
|
|
230
230
|
*/
|
|
231
231
|
async listRemoteSessions(
|
|
232
232
|
options: {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
233
|
+
ids?: string[];
|
|
234
|
+
metadata?: Record<string, any>;
|
|
235
|
+
status?: "idle" | "busy" | "interrupted" | "error";
|
|
236
|
+
values?: any;
|
|
236
237
|
limit?: number;
|
|
238
|
+
offset?: number;
|
|
239
|
+
sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
|
|
240
|
+
sortOrder?: "asc" | "desc";
|
|
241
|
+
select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
|
|
242
|
+
withoutDetails?: boolean;
|
|
237
243
|
} = {}
|
|
238
244
|
) {
|
|
239
245
|
return this.virtualClient.listThreads(options);
|
package/src/LangGraphClient.ts
CHANGED
|
@@ -212,20 +212,39 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
|
|
|
212
212
|
*/
|
|
213
213
|
async listThreads(
|
|
214
214
|
options: {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
215
|
+
ids?: string[];
|
|
216
|
+
metadata?: Record<string, any>;
|
|
217
|
+
status?: "idle" | "busy" | "interrupted" | "error";
|
|
218
|
+
values?: any;
|
|
218
219
|
limit?: number;
|
|
220
|
+
offset?: number;
|
|
221
|
+
sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
|
|
222
|
+
sortOrder?: "asc" | "desc";
|
|
223
|
+
select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
|
|
224
|
+
withoutDetails?: boolean;
|
|
219
225
|
} = {}
|
|
220
226
|
) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
227
|
+
const searchOptions: any = {};
|
|
228
|
+
|
|
229
|
+
if (options.ids) searchOptions.ids = options.ids;
|
|
230
|
+
if (options.metadata) searchOptions.metadata = options.metadata;
|
|
231
|
+
if (options.status) searchOptions.status = options.status;
|
|
232
|
+
if (options.values) searchOptions.values = options.values;
|
|
233
|
+
if (options.limit !== undefined) searchOptions.limit = options.limit;
|
|
234
|
+
if (options.offset !== undefined) searchOptions.offset = options.offset;
|
|
235
|
+
if (options.sortBy) searchOptions.sortBy = options.sortBy;
|
|
236
|
+
if (options.sortOrder) searchOptions.sortOrder = options.sortOrder;
|
|
237
|
+
if (options.select) searchOptions.select = options.select;
|
|
238
|
+
if (options.withoutDetails !== undefined) searchOptions.without_details = options.withoutDetails;
|
|
239
|
+
|
|
240
|
+
// 设置默认值
|
|
241
|
+
if (!options.sortBy) searchOptions.sortBy = "updated_at";
|
|
242
|
+
if (!options.sortOrder) searchOptions.sortOrder = "desc";
|
|
243
|
+
if (!options.limit) searchOptions.limit = 10;
|
|
244
|
+
if (!options.offset) searchOptions.offset = 0;
|
|
245
|
+
if (!options.withoutDetails) searchOptions.without_details = true;
|
|
246
|
+
|
|
247
|
+
return this.threads.search(searchOptions);
|
|
229
248
|
}
|
|
230
249
|
async deleteThread(threadId: string) {
|
|
231
250
|
return this.threads.delete(threadId);
|
package/src/TestKit.ts
CHANGED
|
@@ -292,7 +292,7 @@ export class TestLangGraphChat {
|
|
|
292
292
|
* const lastHuman = testChat.findLast("human");
|
|
293
293
|
* ```
|
|
294
294
|
*/
|
|
295
|
-
findLast(type: "human" | "ai" | "tool", options: { before?: (item: RenderMessage) => boolean } = {}) {
|
|
295
|
+
findLast(type: "human" | "ai" | "tool", options: { before?: (item: RenderMessage) => boolean } = {}): RenderMessage {
|
|
296
296
|
const messages = this.getMessages();
|
|
297
297
|
|
|
298
298
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
@@ -61,6 +61,21 @@ interface ChatStoreContext {
|
|
|
61
61
|
autoRestoreLastSession?: boolean;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
// 分页状态类型
|
|
65
|
+
export interface HistoryPagination {
|
|
66
|
+
page: number;
|
|
67
|
+
pageSize: number;
|
|
68
|
+
total: number;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// 历史记录筛选类型
|
|
72
|
+
export interface HistoryFilter {
|
|
73
|
+
metadata: Record<string, any> | null;
|
|
74
|
+
status: "idle" | "busy" | "interrupted" | "error" | null;
|
|
75
|
+
sortBy: "thread_id" | "status" | "created_at" | "updated_at";
|
|
76
|
+
sortOrder: "asc" | "desc";
|
|
77
|
+
}
|
|
78
|
+
|
|
64
79
|
// ============ Store 创建函数 ============
|
|
65
80
|
|
|
66
81
|
export const createChatStore = (initClientName: string, config: Partial<LangGraphClientConfig>, context: ChatStoreContext = {}) => {
|
|
@@ -91,6 +106,21 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
|
|
|
91
106
|
const showGraph = atom<boolean>(context.showGraph ?? false);
|
|
92
107
|
const graphVisualize = atom<AssistantGraph | null>(null);
|
|
93
108
|
|
|
109
|
+
// 分页状态
|
|
110
|
+
const historyPagination = atom<HistoryPagination>({
|
|
111
|
+
page: 1,
|
|
112
|
+
pageSize: 10,
|
|
113
|
+
total: 0,
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// 历史记录筛选状态
|
|
117
|
+
const historyFilter = atom<HistoryFilter>({
|
|
118
|
+
metadata: null,
|
|
119
|
+
status: null,
|
|
120
|
+
sortBy: "updated_at",
|
|
121
|
+
sortOrder: "desc",
|
|
122
|
+
});
|
|
123
|
+
|
|
94
124
|
// ============ 内部状态 ============
|
|
95
125
|
|
|
96
126
|
let cleanupCurrentClient: (() => void) | null = null;
|
|
@@ -145,8 +175,6 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
|
|
|
145
175
|
await historyManager.init(currentAgent.get(), { fallbackToAvailableAssistants: context.fallbackToAvailableAssistants });
|
|
146
176
|
history.set(historyManager);
|
|
147
177
|
|
|
148
|
-
// 同步远程会话列表
|
|
149
|
-
|
|
150
178
|
// 根据配置决定初始化行为
|
|
151
179
|
if (context.autoRestoreLastSession) {
|
|
152
180
|
await refreshSessionList();
|
|
@@ -170,9 +198,46 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
|
|
|
170
198
|
if (!historyManager) return;
|
|
171
199
|
|
|
172
200
|
try {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
|
|
201
|
+
const pagination = historyPagination.get();
|
|
202
|
+
const filter = historyFilter.get();
|
|
203
|
+
|
|
204
|
+
// 计算偏移量
|
|
205
|
+
const offset = (pagination.page - 1) * pagination.pageSize;
|
|
206
|
+
|
|
207
|
+
// 使用 listRemoteSessions 支持筛选
|
|
208
|
+
const threads = await historyManager.listRemoteSessions({
|
|
209
|
+
limit: pagination.pageSize,
|
|
210
|
+
offset,
|
|
211
|
+
metadata: filter.metadata || undefined,
|
|
212
|
+
status: filter.status || undefined,
|
|
213
|
+
sortBy: filter.sortBy,
|
|
214
|
+
sortOrder: filter.sortOrder,
|
|
215
|
+
withoutDetails: true,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// 注意:后端可能不返回总数,这里需要根据返回的记录数判断是否有下一页
|
|
219
|
+
// 如果返回的记录数小于 pageSize,说明没有更多数据了
|
|
220
|
+
const hasMore = threads.length === pagination.pageSize;
|
|
221
|
+
const estimatedTotal = (pagination.page - 1) * pagination.pageSize + threads.length;
|
|
222
|
+
|
|
223
|
+
sessions.set(
|
|
224
|
+
threads.map(
|
|
225
|
+
(thread) =>
|
|
226
|
+
({
|
|
227
|
+
sessionId: thread.thread_id,
|
|
228
|
+
thread,
|
|
229
|
+
agentName: currentAgent.get(),
|
|
230
|
+
}) as SessionInfo
|
|
231
|
+
)
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
historyList.set(threads as Thread<{ messages: Message[] }>[]);
|
|
235
|
+
|
|
236
|
+
// 更新分页状态(注意:这里只是估计值,实际总数可能需要从后端获取)
|
|
237
|
+
historyPagination.set({
|
|
238
|
+
...pagination,
|
|
239
|
+
total: hasMore ? pagination.page * pagination.pageSize + 1 : estimatedTotal,
|
|
240
|
+
});
|
|
176
241
|
} catch (error) {
|
|
177
242
|
console.error("Failed to sync sessions:", error);
|
|
178
243
|
}
|
|
@@ -427,6 +492,10 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
|
|
|
427
492
|
showHistory,
|
|
428
493
|
historyList,
|
|
429
494
|
|
|
495
|
+
// 分页和筛选
|
|
496
|
+
historyPagination,
|
|
497
|
+
historyFilter,
|
|
498
|
+
|
|
430
499
|
...artifactHook.data,
|
|
431
500
|
},
|
|
432
501
|
mutations: {
|
|
@@ -500,6 +569,47 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
|
|
|
500
569
|
}
|
|
501
570
|
},
|
|
502
571
|
|
|
572
|
+
// 分页和筛选操作
|
|
573
|
+
setHistoryPage(page: number) {
|
|
574
|
+
historyPagination.set({
|
|
575
|
+
...historyPagination.get(),
|
|
576
|
+
page,
|
|
577
|
+
});
|
|
578
|
+
refreshSessionList();
|
|
579
|
+
},
|
|
580
|
+
setHistoryPageSize(pageSize: number) {
|
|
581
|
+
historyPagination.set({
|
|
582
|
+
...historyPagination.get(),
|
|
583
|
+
pageSize,
|
|
584
|
+
page: 1, // 重置到第一页
|
|
585
|
+
});
|
|
586
|
+
refreshSessionList();
|
|
587
|
+
},
|
|
588
|
+
setHistoryFilter(filter: Partial<HistoryFilter>) {
|
|
589
|
+
historyFilter.set({
|
|
590
|
+
...historyFilter.get(),
|
|
591
|
+
...filter,
|
|
592
|
+
});
|
|
593
|
+
historyPagination.set({
|
|
594
|
+
...historyPagination.get(),
|
|
595
|
+
page: 1, // 筛选变更时重置到第一页
|
|
596
|
+
});
|
|
597
|
+
refreshSessionList();
|
|
598
|
+
},
|
|
599
|
+
resetHistoryFilter() {
|
|
600
|
+
historyFilter.set({
|
|
601
|
+
metadata: null,
|
|
602
|
+
status: null,
|
|
603
|
+
sortBy: "updated_at",
|
|
604
|
+
sortOrder: "desc",
|
|
605
|
+
});
|
|
606
|
+
historyPagination.set({
|
|
607
|
+
...historyPagination.get(),
|
|
608
|
+
page: 1,
|
|
609
|
+
});
|
|
610
|
+
refreshSessionList();
|
|
611
|
+
},
|
|
612
|
+
|
|
503
613
|
...artifactHook.mutation,
|
|
504
614
|
},
|
|
505
615
|
};
|