@langgraph-js/sdk 4.5.0 → 4.6.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.
@@ -0,0 +1,4 @@
1
+
2
+ > @langgraph-js/sdk@4.6.0 build /Users/konghayao/code/ai/YaoAgent/apps/langgraph-client
3
+ > tsc
4
+
package/dist/History.d.ts CHANGED
@@ -9,6 +9,8 @@ export interface SessionInfo {
9
9
  thread?: Thread<any>;
10
10
  /** Agent 名称 */
11
11
  agentName: string;
12
+ /** 会话元数据 */
13
+ metadata?: Record<string, any>;
12
14
  }
13
15
  export interface CreateSessionOptions {
14
16
  /** 会话 ID / Thread ID,不提供则自动生成 */
@@ -19,6 +21,8 @@ export interface CreateSessionOptions {
19
21
  restore?: boolean;
20
22
  /** Graph ID */
21
23
  graphId?: string;
24
+ /** 会话元数据 */
25
+ metadata?: Record<string, any>;
22
26
  }
23
27
  /**
24
28
  * @zh History 类用于管理多个 LangGraphClient 实例,支持多会话场景
@@ -94,11 +98,17 @@ export declare class History {
94
98
  * @en Lists all sessions from remote
95
99
  */
96
100
  listRemoteSessions(options?: {
97
- sortOrder?: "asc" | "desc";
98
- sortBy?: "created_at" | "updated_at";
99
- offset?: number;
101
+ ids?: string[];
102
+ metadata?: Record<string, any>;
103
+ status?: "idle" | "busy" | "interrupted" | "error";
104
+ values?: any;
100
105
  limit?: number;
101
- }): Promise<Thread<unknown>[]>;
106
+ offset?: number;
107
+ sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
108
+ sortOrder?: "asc" | "desc";
109
+ select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
110
+ withoutDetails?: boolean;
111
+ }): Promise<Thread<unknown, unknown>[]>;
102
112
  /**
103
113
  * @zh 从远程同步会话到本地(仅同步元数据,不创建 Client)
104
114
  * @en Syncs sessions from remote to local (metadata only, no client created)
package/dist/History.js CHANGED
@@ -32,6 +32,7 @@ export class History {
32
32
  const sessionInfo = {
33
33
  sessionId,
34
34
  agentName,
35
+ metadata: options.metadata,
35
36
  };
36
37
  // 如果是从已有 Thread 恢复,则立即获取 Thread
37
38
  if (options.restore) {
@@ -54,8 +55,14 @@ export class History {
54
55
  if (!session.client) {
55
56
  const client = new LangGraphClient(this.clientConfig);
56
57
  await client.initAssistant(session.agentName);
57
- // 只有在有 thread 的情况下才重置(恢复已有会话)
58
- // 新会话的 thread 会在发送第一条消息时自动创建
58
+ // 如果有 metadata,立即创建 Thread 并带上 metadata
59
+ if (session.metadata && !session.thread) {
60
+ await client.createThread({
61
+ graphId: client.getCurrentAssistant()?.graph_id,
62
+ metadata: session.metadata,
63
+ });
64
+ }
65
+ // 如果已有 thread 或者必须重置,则从历史恢复
59
66
  if (session.thread || mustResetStream) {
60
67
  await client.resetThread(session.agentName, sessionId);
61
68
  }
@@ -43,6 +43,7 @@ export type SendMessageOptions = {
43
43
  };
44
44
  command?: Command;
45
45
  joinRunId?: string;
46
+ metadata?: Record<string, any>;
46
47
  };
47
48
  export interface LangGraphClientConfig {
48
49
  apiUrl?: string;
@@ -153,18 +154,18 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
153
154
  threadId?: string;
154
155
  ifExists?: import("@langchain/langgraph-sdk").OnConflictBehavior;
155
156
  graphId?: string;
156
- }): Promise<Thread<TStateType>>;
157
+ }): Promise<Thread<TStateType, unknown>>;
157
158
  search(query?: {
158
159
  metadata?: import("@langchain/langgraph-sdk").Metadata;
159
- limit?: number;
160
+ limit? /** 自定义客户端实现,如果不提供则使用官方 Client */: number;
160
161
  offset?: number;
161
162
  status?: import("@langchain/langgraph-sdk").ThreadStatus;
162
163
  sortBy?: import("@langgraph-js/pure-graph/dist/types.js").ThreadSortBy;
163
164
  sortOrder?: import("@langgraph-js/pure-graph/dist/types.js").SortOrder;
164
- }): Promise<Thread<TStateType>[]>;
165
- get(threadId: string): Promise<Thread<TStateType>>;
165
+ }): Promise<Thread<TStateType, unknown>[]>;
166
+ get(threadId: string): Promise<Thread<TStateType, unknown>>;
166
167
  delete(threadId: string): Promise<void>;
167
- updateState(threadId: string, thread: Partial<Thread<TStateType>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
168
+ updateState(threadId: string, thread: Partial<Thread<TStateType, unknown>>): Promise<Pick<import("@langchain/langgraph-sdk").Config, "configurable">>;
168
169
  };
169
170
  /** 代理 runs 属性到内部 client */
170
171
  get runs(): ILangGraphClient["runs"];
@@ -182,27 +183,34 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
182
183
  * @zh 创建一个新的 Thread。
183
184
  * @en Creates a new Thread.
184
185
  */
185
- createThread({ threadId, graphId }?: {
186
+ createThread({ threadId, graphId, metadata }?: {
186
187
  threadId?: string;
187
188
  graphId?: string;
188
- }): Promise<Thread<TStateType>>;
189
+ metadata?: Record<string, any>;
190
+ }): Promise<Thread<TStateType, unknown>>;
189
191
  graphVisualize(): Promise<import("@langchain/langgraph-sdk").AssistantGraph>;
190
192
  /**
191
193
  * @zh 列出所有的 Thread。
192
194
  * @en Lists all Threads.
193
195
  */
194
196
  listThreads(options?: {
195
- sortOrder?: "asc" | "desc";
196
- sortBy?: "created_at" | "updated_at";
197
- offset?: number;
197
+ ids?: string[];
198
+ metadata?: Record<string, any>;
199
+ status?: "idle" | "busy" | "interrupted" | "error";
200
+ values?: any;
198
201
  limit?: number;
199
- }): Promise<Thread<TStateType>[]>;
202
+ offset?: number;
203
+ sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
204
+ sortOrder?: "asc" | "desc";
205
+ select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
206
+ withoutDetails?: boolean;
207
+ }): Promise<Thread<TStateType, unknown>[]>;
200
208
  deleteThread(threadId: string): Promise<void>;
201
209
  /**
202
210
  * @zh 从历史中恢复 Thread 数据。
203
211
  * @en Resets the Thread data from history.
204
212
  */
205
- resetThread(agent: string, threadId: string): Promise<Thread<TStateType>>;
213
+ resetThread(agent: string, threadId: string): Promise<Thread<TStateType, unknown>>;
206
214
  resetStream(): Promise<void>;
207
215
  cloneMessage(message: Message): Message;
208
216
  /**
@@ -241,7 +249,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
241
249
  * @zh 发送消息到 LangGraph 后端。
242
250
  * @en Sends a message to the LangGraph backend.
243
251
  */
244
- sendMessage(input: string | Message[], { joinRunId, extraParams, _debug, command }?: SendMessageOptions): Promise<any[]>;
252
+ sendMessage(input: string | Message[], { joinRunId, extraParams, _debug, command, metadata }?: SendMessageOptions): Promise<any[]>;
245
253
  /** 当前子图位置,但是依赖 stream,不太适合稳定使用*/
246
254
  private graphPosition;
247
255
  getGraphPosition(): {
@@ -283,7 +291,7 @@ export declare class LangGraphClient<TStateType = unknown> extends EventEmitter<
283
291
  * @zh 获取当前的 Thread。
284
292
  * @en Gets the current Thread.
285
293
  */
286
- getCurrentThread(): Thread<TStateType> | null;
294
+ getCurrentThread(): Thread<TStateType, unknown> | null;
287
295
  /**
288
296
  * @zh 获取当前的 Assistant。
289
297
  * @en Gets the current Assistant.
@@ -89,9 +89,10 @@ export class LangGraphClient extends EventEmitter {
89
89
  * @zh 创建一个新的 Thread。
90
90
  * @en Creates a new Thread.
91
91
  */
92
- async createThread({ threadId, graphId } = {}) {
92
+ async createThread({ threadId, graphId, metadata } = {}) {
93
93
  try {
94
94
  this.currentThread = await this.threads.create({
95
+ metadata,
95
96
  threadId,
96
97
  graphId,
97
98
  });
@@ -112,14 +113,39 @@ export class LangGraphClient extends EventEmitter {
112
113
  * @en Lists all Threads.
113
114
  */
114
115
  async listThreads(options = {}) {
115
- return this.threads.search({
116
- sortOrder: options.sortOrder || "desc",
117
- sortBy: options.sortBy || "updated_at",
118
- offset: options.offset || 0,
119
- limit: options.limit || 10,
120
- /** @ts-ignore: 用于删除不需要的字段 */
121
- without_details: true,
122
- });
116
+ const searchOptions = {};
117
+ if (options.ids)
118
+ searchOptions.ids = options.ids;
119
+ if (options.metadata)
120
+ searchOptions.metadata = options.metadata;
121
+ if (options.status)
122
+ searchOptions.status = options.status;
123
+ if (options.values)
124
+ searchOptions.values = options.values;
125
+ if (options.limit !== undefined)
126
+ searchOptions.limit = options.limit;
127
+ if (options.offset !== undefined)
128
+ searchOptions.offset = options.offset;
129
+ if (options.sortBy)
130
+ searchOptions.sortBy = options.sortBy;
131
+ if (options.sortOrder)
132
+ searchOptions.sortOrder = options.sortOrder;
133
+ if (options.select)
134
+ searchOptions.select = options.select;
135
+ if (options.withoutDetails !== undefined)
136
+ searchOptions.without_details = options.withoutDetails;
137
+ // 设置默认值
138
+ if (!options.sortBy)
139
+ searchOptions.sortBy = "updated_at";
140
+ if (!options.sortOrder)
141
+ searchOptions.sortOrder = "desc";
142
+ if (!options.limit)
143
+ searchOptions.limit = 10;
144
+ if (!options.offset)
145
+ searchOptions.offset = 0;
146
+ if (!options.withoutDetails)
147
+ searchOptions.without_details = true;
148
+ return this.threads.search(searchOptions);
123
149
  }
124
150
  async deleteThread(threadId) {
125
151
  return this.threads.delete(threadId);
@@ -224,12 +250,15 @@ export class LangGraphClient extends EventEmitter {
224
250
  * @zh 发送消息到 LangGraph 后端。
225
251
  * @en Sends a message to the LangGraph backend.
226
252
  */
227
- async sendMessage(input, { joinRunId, extraParams, _debug, command } = {}) {
253
+ async sendMessage(input, { joinRunId, extraParams, _debug, command, metadata } = {}) {
228
254
  if (!this.currentAssistant) {
229
255
  throw new Error("Thread or Assistant not initialized");
230
256
  }
231
257
  if (!this.currentThread) {
232
- await this.createThread({ graphId: this.currentAssistant.graph_id });
258
+ await this.createThread({
259
+ graphId: this.currentAssistant.graph_id,
260
+ metadata,
261
+ });
233
262
  this.emit("thread", {
234
263
  event: "thread/create",
235
264
  data: {
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;
@@ -38,7 +40,7 @@ export declare const useChat: () => UnionStore<{
38
40
  createNewSession: () => Promise<void>;
39
41
  refreshSessionList: () => Promise<void>;
40
42
  refreshHistoryList: () => Promise<void>;
41
- sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], extraData?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
43
+ sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], options?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
42
44
  stopGeneration: () => void;
43
45
  setUserInput: (input: string) => void;
44
46
  revertChatTo(messageId: string, resend?: boolean, sendOptions?: import("../LangGraphClient.js").SendMessageOptions & import("../time-travel/index.js").RevertChatToOptions): Promise<void>;
@@ -55,13 +57,17 @@ export declare const useChat: () => UnionStore<{
55
57
  addToHistory: (thread: import("@langchain/langgraph-sdk").Thread<{
56
58
  messages: import("@langchain/langgraph-sdk").Message[];
57
59
  }>) => void;
58
- createNewChat: () => Promise<void>;
60
+ createNewChat(metadata?: Record<string, any>): Promise<void>;
59
61
  toHistoryChat: (thread: import("@langchain/langgraph-sdk").Thread<{
60
62
  messages: import("@langchain/langgraph-sdk").Message[];
61
63
  }>) => Promise<void>;
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;
@@ -38,7 +40,7 @@ export declare const useChat: () => UnionStoreSolid<{
38
40
  createNewSession: () => Promise<void>;
39
41
  refreshSessionList: () => Promise<void>;
40
42
  refreshHistoryList: () => Promise<void>;
41
- sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], extraData?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
43
+ sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], options?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
42
44
  stopGeneration: () => void;
43
45
  setUserInput: (input: string) => void;
44
46
  revertChatTo(messageId: string, resend?: boolean, sendOptions?: import("../LangGraphClient.js").SendMessageOptions & import("../time-travel/index.js").RevertChatToOptions): Promise<void>;
@@ -55,13 +57,17 @@ export declare const useChat: () => UnionStoreSolid<{
55
57
  addToHistory: (thread: import("@langchain/langgraph-sdk").Thread<{
56
58
  messages: import("@langchain/langgraph-sdk").Message[];
57
59
  }>) => void;
58
- createNewChat: () => Promise<void>;
60
+ createNewChat(metadata?: Record<string, any>): Promise<void>;
59
61
  toHistoryChat: (thread: import("@langchain/langgraph-sdk").Thread<{
60
62
  messages: import("@langchain/langgraph-sdk").Message[];
61
63
  }>) => Promise<void>;
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;
@@ -54,7 +67,7 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
54
67
  createNewSession: () => Promise<void>;
55
68
  refreshSessionList: () => Promise<void>;
56
69
  refreshHistoryList: () => Promise<void>;
57
- sendMessage: (message?: Message[], extraData?: SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
70
+ sendMessage: (message?: Message[], options?: SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
58
71
  stopGeneration: () => void;
59
72
  setUserInput: (input: string) => void;
60
73
  revertChatTo(messageId: string, resend?: boolean, sendOptions?: SendMessageOptions & RevertChatToOptions): Promise<void>;
@@ -71,13 +84,17 @@ export declare const createChatStore: (initClientName: string, config: Partial<L
71
84
  addToHistory: (thread: Thread<{
72
85
  messages: Message[];
73
86
  }>) => void;
74
- createNewChat: () => Promise<void>;
87
+ createNewChat(metadata?: Record<string, any>): Promise<void>;
75
88
  toHistoryChat: (thread: Thread<{
76
89
  messages: Message[];
77
90
  }>) => Promise<void>;
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,36 @@ export const createChatStore = (initClientName, config, context = {}) => {
137
149
  if (!historyManager)
138
150
  return;
139
151
  try {
140
- const syncedSessions = await historyManager.syncFromRemote({ limit: 10 });
141
- sessions.set(syncedSessions);
142
- historyList.set(syncedSessions.filter((s) => s.thread).map((s) => s.thread));
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
+ metadata: thread.metadata,
175
+ })));
176
+ historyList.set(threads);
177
+ // 更新分页状态(注意:这里只是估计值,实际总数可能需要从后端获取)
178
+ historyPagination.set({
179
+ ...pagination,
180
+ total: hasMore ? pagination.page * pagination.pageSize + 1 : estimatedTotal,
181
+ });
143
182
  }
144
183
  catch (error) {
145
184
  console.error("Failed to sync sessions:", error);
@@ -286,7 +325,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
286
325
  }
287
326
  }
288
327
  // ============ 消息和交互逻辑 ============
289
- async function sendMessage(message, extraData, withoutCheck = false, isResume = false) {
328
+ async function sendMessage(message, options, withoutCheck = false, isResume = false) {
290
329
  const c = client.get();
291
330
  if ((!withoutCheck && !userInput.get().trim() && !message?.length) || !c)
292
331
  return;
@@ -296,7 +335,7 @@ export const createChatStore = (initClientName, config, context = {}) => {
296
335
  inChatError.set(null);
297
336
  try {
298
337
  loading.set(true);
299
- await c.sendMessage(message || userInput.get(), extraData);
338
+ await c.sendMessage(message || userInput.get(), options);
300
339
  }
301
340
  catch (e) {
302
341
  const isThreadRunning = e.message.includes("422");
@@ -364,6 +403,9 @@ export const createChatStore = (initClientName, config, context = {}) => {
364
403
  // 历史记录
365
404
  showHistory,
366
405
  historyList,
406
+ // 分页和筛选
407
+ historyPagination,
408
+ historyFilter,
367
409
  ...artifactHook.data,
368
410
  },
369
411
  mutations: {
@@ -420,7 +462,20 @@ export const createChatStore = (initClientName, config, context = {}) => {
420
462
  },
421
463
  // 历史记录(兼容旧 API)
422
464
  addToHistory,
423
- createNewChat: createNewSession,
465
+ async createNewChat(metadata) {
466
+ const historyManager = history.get();
467
+ if (!historyManager)
468
+ return;
469
+ try {
470
+ const session = await historyManager.createSession({ metadata });
471
+ await refreshSessionList();
472
+ await activateSession(session.sessionId);
473
+ }
474
+ catch (error) {
475
+ console.error("Failed to create new chat:", error);
476
+ inChatError.set(error.message);
477
+ }
478
+ },
424
479
  toHistoryChat: (thread) => activateSession(thread.thread_id, true),
425
480
  async deleteHistoryChat(thread) {
426
481
  const historyManager = history.get();
@@ -429,6 +484,46 @@ export const createChatStore = (initClientName, config, context = {}) => {
429
484
  await refreshSessionList();
430
485
  }
431
486
  },
487
+ // 分页和筛选操作
488
+ setHistoryPage(page) {
489
+ historyPagination.set({
490
+ ...historyPagination.get(),
491
+ page,
492
+ });
493
+ refreshSessionList();
494
+ },
495
+ setHistoryPageSize(pageSize) {
496
+ historyPagination.set({
497
+ ...historyPagination.get(),
498
+ pageSize,
499
+ page: 1, // 重置到第一页
500
+ });
501
+ refreshSessionList();
502
+ },
503
+ setHistoryFilter(filter) {
504
+ historyFilter.set({
505
+ ...historyFilter.get(),
506
+ ...filter,
507
+ });
508
+ historyPagination.set({
509
+ ...historyPagination.get(),
510
+ page: 1, // 筛选变更时重置到第一页
511
+ });
512
+ refreshSessionList();
513
+ },
514
+ resetHistoryFilter() {
515
+ historyFilter.set({
516
+ metadata: null,
517
+ status: null,
518
+ sortBy: "updated_at",
519
+ sortOrder: "desc",
520
+ });
521
+ historyPagination.set({
522
+ ...historyPagination.get(),
523
+ page: 1,
524
+ });
525
+ refreshSessionList();
526
+ },
432
527
  ...artifactHook.mutation,
433
528
  },
434
529
  };
@@ -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;
@@ -82,7 +84,7 @@ export declare const useChatProvider: (props: ChatProviderProps) => {
82
84
  createNewSession: () => Promise<void>;
83
85
  refreshSessionList: () => Promise<void>;
84
86
  refreshHistoryList: () => Promise<void>;
85
- sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], extraData?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
87
+ sendMessage: (message?: import("@langchain/langgraph-sdk").Message[], options?: import("../LangGraphClient.js").SendMessageOptions, withoutCheck?: boolean, isResume?: boolean) => Promise<void>;
86
88
  stopGeneration: () => void;
87
89
  setUserInput: (input: string) => void;
88
90
  revertChatTo(messageId: string, resend?: boolean, sendOptions?: import("../LangGraphClient.js").SendMessageOptions & import("../time-travel/index.js").RevertChatToOptions): Promise<void>;
@@ -99,13 +101,17 @@ export declare const useChatProvider: (props: ChatProviderProps) => {
99
101
  addToHistory: (thread: import("@langchain/langgraph-sdk").Thread<{
100
102
  messages: import("@langchain/langgraph-sdk").Message[];
101
103
  }>) => void;
102
- createNewChat: () => Promise<void>;
104
+ createNewChat(metadata?: Record<string, any>): Promise<void>;
103
105
  toHistoryChat: (thread: import("@langchain/langgraph-sdk").Thread<{
104
106
  messages: import("@langchain/langgraph-sdk").Message[];
105
107
  }>) => Promise<void>;
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@langgraph-js/sdk",
3
- "version": "4.5.0",
3
+ "version": "4.6.1",
4
4
  "description": "The UI SDK for LangGraph - seamlessly integrate your AI agents with frontend interfaces",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
package/src/History.ts CHANGED
@@ -10,6 +10,8 @@ export interface SessionInfo {
10
10
  thread?: Thread<any>;
11
11
  /** Agent 名称 */
12
12
  agentName: string;
13
+ /** 会话元数据 */
14
+ metadata?: Record<string, any>;
13
15
  }
14
16
 
15
17
  export interface CreateSessionOptions {
@@ -21,6 +23,8 @@ export interface CreateSessionOptions {
21
23
  restore?: boolean;
22
24
  /** Graph ID */
23
25
  graphId?: string;
26
+ /** 会话元数据 */
27
+ metadata?: Record<string, any>;
24
28
  }
25
29
 
26
30
  /**
@@ -61,6 +65,7 @@ export class History {
61
65
  const sessionInfo: SessionInfo = {
62
66
  sessionId,
63
67
  agentName,
68
+ metadata: options.metadata,
64
69
  };
65
70
 
66
71
  // 如果是从已有 Thread 恢复,则立即获取 Thread
@@ -89,8 +94,15 @@ export class History {
89
94
  const client = new LangGraphClient(this.clientConfig);
90
95
  await client.initAssistant(session.agentName);
91
96
 
92
- // 只有在有 thread 的情况下才重置(恢复已有会话)
93
- // 新会话的 thread 会在发送第一条消息时自动创建
97
+ // 如果有 metadata,立即创建 Thread 并带上 metadata
98
+ if (session.metadata && !session.thread) {
99
+ await client.createThread({
100
+ graphId: client.getCurrentAssistant()?.graph_id,
101
+ metadata: session.metadata,
102
+ });
103
+ }
104
+
105
+ // 如果已有 thread 或者必须重置,则从历史恢复
94
106
  if (session.thread || mustResetStream) {
95
107
  await client.resetThread(session.agentName, sessionId);
96
108
  }
@@ -230,10 +242,16 @@ export class History {
230
242
  */
231
243
  async listRemoteSessions(
232
244
  options: {
233
- sortOrder?: "asc" | "desc";
234
- sortBy?: "created_at" | "updated_at";
235
- offset?: number;
245
+ ids?: string[];
246
+ metadata?: Record<string, any>;
247
+ status?: "idle" | "busy" | "interrupted" | "error";
248
+ values?: any;
236
249
  limit?: number;
250
+ offset?: number;
251
+ sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
252
+ sortOrder?: "asc" | "desc";
253
+ select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
254
+ withoutDetails?: boolean;
237
255
  } = {}
238
256
  ) {
239
257
  return this.virtualClient.listThreads(options);
@@ -46,6 +46,7 @@ export type SendMessageOptions = {
46
46
  _debug?: { streamResponse?: any };
47
47
  command?: Command;
48
48
  joinRunId?: string;
49
+ metadata?: Record<string, any>;
49
50
  };
50
51
 
51
52
  export interface LangGraphClientConfig {
@@ -188,9 +189,10 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
188
189
  * @zh 创建一个新的 Thread。
189
190
  * @en Creates a new Thread.
190
191
  */
191
- async createThread({ threadId, graphId }: { threadId?: string; graphId?: string } = {}) {
192
+ async createThread({ threadId, graphId, metadata }: { threadId?: string; graphId?: string; metadata?: Record<string, any> } = {}) {
192
193
  try {
193
194
  this.currentThread = await this.threads.create({
195
+ metadata,
194
196
  threadId,
195
197
  graphId,
196
198
  });
@@ -212,20 +214,39 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
212
214
  */
213
215
  async listThreads(
214
216
  options: {
215
- sortOrder?: "asc" | "desc";
216
- sortBy?: "created_at" | "updated_at";
217
- offset?: number;
217
+ ids?: string[];
218
+ metadata?: Record<string, any>;
219
+ status?: "idle" | "busy" | "interrupted" | "error";
220
+ values?: any;
218
221
  limit?: number;
222
+ offset?: number;
223
+ sortBy?: "thread_id" | "status" | "created_at" | "updated_at";
224
+ sortOrder?: "asc" | "desc";
225
+ select?: Array<"thread_id" | "created_at" | "updated_at" | "metadata" | "config" | "context" | "status" | "values" | "interrupts">;
226
+ withoutDetails?: boolean;
219
227
  } = {}
220
228
  ) {
221
- return this.threads.search({
222
- sortOrder: options.sortOrder || "desc",
223
- sortBy: options.sortBy || "updated_at",
224
- offset: options.offset || 0,
225
- limit: options.limit || 10,
226
- /** @ts-ignore: 用于删除不需要的字段 */
227
- without_details: true,
228
- });
229
+ const searchOptions: any = {};
230
+
231
+ if (options.ids) searchOptions.ids = options.ids;
232
+ if (options.metadata) searchOptions.metadata = options.metadata;
233
+ if (options.status) searchOptions.status = options.status;
234
+ if (options.values) searchOptions.values = options.values;
235
+ if (options.limit !== undefined) searchOptions.limit = options.limit;
236
+ if (options.offset !== undefined) searchOptions.offset = options.offset;
237
+ if (options.sortBy) searchOptions.sortBy = options.sortBy;
238
+ if (options.sortOrder) searchOptions.sortOrder = options.sortOrder;
239
+ if (options.select) searchOptions.select = options.select;
240
+ if (options.withoutDetails !== undefined) searchOptions.without_details = options.withoutDetails;
241
+
242
+ // 设置默认值
243
+ if (!options.sortBy) searchOptions.sortBy = "updated_at";
244
+ if (!options.sortOrder) searchOptions.sortOrder = "desc";
245
+ if (!options.limit) searchOptions.limit = 10;
246
+ if (!options.offset) searchOptions.offset = 0;
247
+ if (!options.withoutDetails) searchOptions.without_details = true;
248
+
249
+ return this.threads.search(searchOptions);
229
250
  }
230
251
  async deleteThread(threadId: string) {
231
252
  return this.threads.delete(threadId);
@@ -344,12 +365,15 @@ export class LangGraphClient<TStateType = unknown> extends EventEmitter<LangGrap
344
365
  * @zh 发送消息到 LangGraph 后端。
345
366
  * @en Sends a message to the LangGraph backend.
346
367
  */
347
- async sendMessage(input: string | Message[], { joinRunId, extraParams, _debug, command }: SendMessageOptions = {}) {
368
+ async sendMessage(input: string | Message[], { joinRunId, extraParams, _debug, command, metadata }: SendMessageOptions = {}) {
348
369
  if (!this.currentAssistant) {
349
370
  throw new Error("Thread or Assistant not initialized");
350
371
  }
351
372
  if (!this.currentThread) {
352
- await this.createThread({ graphId: this.currentAssistant!.graph_id! });
373
+ await this.createThread({
374
+ graphId: this.currentAssistant!.graph_id!,
375
+ metadata,
376
+ });
353
377
  this.emit("thread", {
354
378
  event: "thread/create",
355
379
  data: {
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,47 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
170
198
  if (!historyManager) return;
171
199
 
172
200
  try {
173
- const syncedSessions = await historyManager.syncFromRemote({ limit: 10 });
174
- sessions.set(syncedSessions);
175
- historyList.set(syncedSessions.filter((s) => s.thread).map((s) => s.thread!));
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
+ metadata: thread.metadata as Record<string, any> | undefined,
231
+ }) as SessionInfo
232
+ )
233
+ );
234
+
235
+ historyList.set(threads as Thread<{ messages: Message[] }>[]);
236
+
237
+ // 更新分页状态(注意:这里只是估计值,实际总数可能需要从后端获取)
238
+ historyPagination.set({
239
+ ...pagination,
240
+ total: hasMore ? pagination.page * pagination.pageSize + 1 : estimatedTotal,
241
+ });
176
242
  } catch (error) {
177
243
  console.error("Failed to sync sessions:", error);
178
244
  }
@@ -340,7 +406,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
340
406
 
341
407
  // ============ 消息和交互逻辑 ============
342
408
 
343
- async function sendMessage(message?: Message[], extraData?: SendMessageOptions, withoutCheck = false, isResume = false) {
409
+ async function sendMessage(message?: Message[], options?: SendMessageOptions, withoutCheck = false, isResume = false) {
344
410
  const c = client.get();
345
411
  if ((!withoutCheck && !userInput.get().trim() && !message?.length) || !c) return;
346
412
 
@@ -350,7 +416,7 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
350
416
  inChatError.set(null);
351
417
  try {
352
418
  loading.set(true);
353
- await c.sendMessage(message || userInput.get(), extraData);
419
+ await c.sendMessage(message || userInput.get(), options);
354
420
  } catch (e) {
355
421
  const isThreadRunning = (e as Error).message.includes("422");
356
422
  if (isThreadRunning) {
@@ -427,6 +493,10 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
427
493
  showHistory,
428
494
  historyList,
429
495
 
496
+ // 分页和筛选
497
+ historyPagination,
498
+ historyFilter,
499
+
430
500
  ...artifactHook.data,
431
501
  },
432
502
  mutations: {
@@ -490,7 +560,19 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
490
560
  },
491
561
  // 历史记录(兼容旧 API)
492
562
  addToHistory,
493
- createNewChat: createNewSession,
563
+ async createNewChat(metadata?: Record<string, any>) {
564
+ const historyManager = history.get();
565
+ if (!historyManager) return;
566
+
567
+ try {
568
+ const session = await historyManager.createSession({ metadata });
569
+ await refreshSessionList();
570
+ await activateSession(session.sessionId);
571
+ } catch (error) {
572
+ console.error("Failed to create new chat:", error);
573
+ inChatError.set((error as Error).message);
574
+ }
575
+ },
494
576
  toHistoryChat: (thread: Thread<{ messages: Message[] }>) => activateSession(thread.thread_id, true),
495
577
  async deleteHistoryChat(thread: Thread<{ messages: Message[] }>) {
496
578
  const historyManager = history.get();
@@ -500,6 +582,47 @@ export const createChatStore = (initClientName: string, config: Partial<LangGrap
500
582
  }
501
583
  },
502
584
 
585
+ // 分页和筛选操作
586
+ setHistoryPage(page: number) {
587
+ historyPagination.set({
588
+ ...historyPagination.get(),
589
+ page,
590
+ });
591
+ refreshSessionList();
592
+ },
593
+ setHistoryPageSize(pageSize: number) {
594
+ historyPagination.set({
595
+ ...historyPagination.get(),
596
+ pageSize,
597
+ page: 1, // 重置到第一页
598
+ });
599
+ refreshSessionList();
600
+ },
601
+ setHistoryFilter(filter: Partial<HistoryFilter>) {
602
+ historyFilter.set({
603
+ ...historyFilter.get(),
604
+ ...filter,
605
+ });
606
+ historyPagination.set({
607
+ ...historyPagination.get(),
608
+ page: 1, // 筛选变更时重置到第一页
609
+ });
610
+ refreshSessionList();
611
+ },
612
+ resetHistoryFilter() {
613
+ historyFilter.set({
614
+ metadata: null,
615
+ status: null,
616
+ sortBy: "updated_at",
617
+ sortOrder: "desc",
618
+ });
619
+ historyPagination.set({
620
+ ...historyPagination.get(),
621
+ page: 1,
622
+ });
623
+ refreshSessionList();
624
+ },
625
+
503
626
  ...artifactHook.mutation,
504
627
  },
505
628
  };