@lobehub/lobehub 2.0.0-next.172 → 2.0.0-next.174

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.
Files changed (48) hide show
  1. package/.cursor/rules/db-migrations.mdc +10 -4
  2. package/.cursor/rules/drizzle-schema-style-guide.mdc +33 -17
  3. package/.cursor/rules/hotkey.mdc +161 -0
  4. package/.cursor/rules/i18n.mdc +2 -5
  5. package/.cursor/rules/project-introduce.mdc +3 -2
  6. package/.cursor/rules/project-structure.mdc +33 -37
  7. package/.cursor/rules/react.mdc +155 -0
  8. package/.cursor/rules/recent-data-usage.mdc +138 -0
  9. package/.cursor/rules/rules-index.mdc +1 -1
  10. package/.cursor/rules/testing-guide/agent-runtime-e2e.mdc +285 -0
  11. package/.cursor/rules/testing-guide/zustand-store-action-test.mdc +11 -16
  12. package/.cursor/rules/typescript.mdc +0 -4
  13. package/.cursor/rules/zustand-action-patterns.mdc +137 -169
  14. package/.cursor/rules/zustand-slice-organization.mdc +16 -8
  15. package/.husky/pre-commit +1 -1
  16. package/.i18nrc.js +3 -1
  17. package/AGENTS.md +3 -2
  18. package/CHANGELOG.md +50 -0
  19. package/CLAUDE.md +10 -3
  20. package/GEMINI.md +2 -1
  21. package/README.md +3 -3
  22. package/README.zh-CN.md +6 -6
  23. package/changelog/v1.json +18 -0
  24. package/docs/development/database-schema.dbml +18 -3
  25. package/docs/development/state-management/state-management-selectors.mdx +1 -1
  26. package/glossary.json +8 -0
  27. package/package.json +3 -3
  28. package/packages/database/migrations/0063_add_columns_for_several_tables.sql +30 -0
  29. package/packages/database/migrations/meta/0063_snapshot.json +9113 -0
  30. package/packages/database/migrations/meta/_journal.json +7 -0
  31. package/packages/database/src/core/migrations.json +29 -0
  32. package/packages/database/src/schemas/_helpers.ts +5 -1
  33. package/packages/database/src/schemas/agent.ts +2 -1
  34. package/packages/database/src/schemas/aiInfra.ts +18 -3
  35. package/packages/database/src/schemas/message.ts +11 -6
  36. package/packages/database/src/schemas/topic.ts +17 -2
  37. package/packages/database/src/schemas/user.ts +5 -2
  38. package/packages/database/src/schemas/userMemories.ts +9 -8
  39. package/packages/model-runtime/src/core/contextBuilders/openai.ts +8 -2
  40. package/packages/model-runtime/src/providers/github/index.test.ts +4 -4
  41. package/packages/types/src/topic/thread.ts +24 -0
  42. package/packages/types/src/user/index.ts +1 -0
  43. package/packages/types/src/user/onboarding.ts +16 -0
  44. package/src/features/KnowledgeBaseModal/AssignKnowledgeBase/List.tsx +5 -2
  45. package/src/store/agent/slices/chat/action.ts +3 -3
  46. package/vitest.config.mts +3 -0
  47. package/.cursor/rules/group-chat.mdc +0 -35
  48. package/.cursor/rules/react-component.mdc +0 -173
@@ -1,137 +1,126 @@
1
1
  ---
2
- description:
2
+ description:
3
3
  globs: src/store/**
4
4
  alwaysApply: false
5
5
  ---
6
- # LobeChat Zustand Action 组织模式
7
6
 
8
- 本文档详细说明了 LobeChat 项目中 Zustand Action 的组织方式、命名规范和实现模式,特别关注乐观更新与后端服务的集成。
7
+ # LobeChat Zustand Action Patterns
9
8
 
10
- ## Action 类型分层
9
+ ## Action Type Hierarchy
11
10
 
12
- LobeChat Action 采用分层架构,明确区分不同职责:
11
+ LobeChat Actions use a layered architecture with clear separation of responsibilities:
13
12
 
14
13
  ### 1. Public Actions
15
- 对外暴露的主要接口,供 UI 组件调用:
16
- - 命名:动词形式(`createTopic`, `sendMessage`, `updateTopicTitle`)
17
- - 职责:参数验证、流程编排、调用 internal actions
18
- - 示例:[src/store/chat/slices/topic/action.ts](mdc:src/store/chat/slices/topic/action.ts)
14
+
15
+ Main interfaces exposed for UI component consumption:
16
+
17
+ - Naming: Verb form (`createTopic`, `sendMessage`, `updateTopicTitle`)
18
+ - Responsibilities: Parameter validation, flow orchestration, calling internal actions
19
+ - Example: [src/store/chat/slices/topic/action.ts](mdc:src/store/chat/slices/topic/action.ts)
19
20
 
20
21
  ```typescript
21
- // Public Action 示例
22
+ // Public Action example
22
23
  createTopic: async () => {
23
- const { activeId, internal_createTopic } = get();
24
- const messages = chatSelectors.activeBaseChats(get());
25
-
26
- if (messages.length === 0) return;
27
-
28
- const topicId = await internal_createTopic({
29
- sessionId: activeId,
30
- title: t('defaultTitle', { ns: 'topic' }),
31
- messages: messages.map((m) => m.id),
32
- });
33
-
24
+ // ...
34
25
  return topicId;
35
26
  },
36
27
  ```
37
28
 
38
29
  ### 2. Internal Actions (`internal_*`)
39
- 内部实现细节,处理核心业务逻辑:
40
- - 命名:`internal_` 前缀 + 动词(`internal_createTopic`, `internal_updateMessageContent`)
41
- - 职责:乐观更新、服务调用、错误处理、状态同步
42
- - 不应该被 UI 组件直接调用
30
+
31
+ Internal implementation details handling core business logic:
32
+
33
+ - Naming: `internal_` prefix + verb (`internal_createTopic`, `internal_updateMessageContent`)
34
+ - Responsibilities: Optimistic updates, service calls, error handling, state synchronization
35
+ - Should not be called directly by UI components
43
36
 
44
37
  ```typescript
45
- // Internal Action 示例 - 乐观更新模式
38
+ // Internal Action example - Optimistic update pattern
46
39
  internal_createTopic: async (params) => {
47
40
  const tmpId = Date.now().toString();
48
-
49
- // 1. 立即更新前端状态(乐观更新)
41
+
42
+ // 1. Immediately update frontend state (optimistic update)
50
43
  get().internal_dispatchTopic(
51
44
  { type: 'addTopic', value: { ...params, id: tmpId } },
52
45
  'internal_createTopic',
53
46
  );
54
47
  get().internal_updateTopicLoading(tmpId, true);
55
-
56
- // 2. 调用后端服务
48
+
49
+ // 2. Call backend service
57
50
  const topicId = await topicService.createTopic(params);
58
51
  get().internal_updateTopicLoading(tmpId, false);
59
-
60
- // 3. 刷新数据确保一致性
52
+
53
+ // 3. Refresh data to ensure consistency
61
54
  get().internal_updateTopicLoading(topicId, true);
62
55
  await get().refreshTopic();
63
56
  get().internal_updateTopicLoading(topicId, false);
64
-
57
+
65
58
  return topicId;
66
59
  },
67
60
  ```
68
61
 
69
62
  ### 3. Dispatch Methods (`internal_dispatch*`)
70
- 专门处理状态更新的方法:
71
- - 命名:`internal_dispatch` + 实体名(`internal_dispatchTopic`, `internal_dispatchMessage`)
72
- - 职责:调用 reducer、更新 Zustand store、处理状态对比
63
+
64
+ Methods dedicated to handling state updates:
65
+
66
+ - Naming: `internal_dispatch` + entity name (`internal_dispatchTopic`, `internal_dispatchMessage`)
67
+ - Responsibilities: Calling reducers, updating Zustand store, handling state comparison
73
68
 
74
69
  ```typescript
75
- // Dispatch Method 示例
70
+ // Dispatch Method example
76
71
  internal_dispatchTopic: (payload, action) => {
77
72
  const nextTopics = topicReducer(topicSelectors.currentTopics(get()), payload);
78
73
  const nextMap = { ...get().topicMaps, [get().activeId]: nextTopics };
79
74
 
80
75
  if (isEqual(nextMap, get().topicMaps)) return;
81
-
76
+
82
77
  set({ topicMaps: nextMap }, false, action ?? n(`dispatchTopic/${payload.type}`));
83
78
  },
84
79
  ```
85
80
 
86
- ## 何时使用 Reducer 模式 vs. 简单 `set`
81
+ ## When to Use Reducer Pattern vs. Simple `set`
82
+
83
+ ### Use Reducer Pattern When
87
84
 
88
- ### 使用 Reducer 模式的场景
85
+ Suitable for complex data structure management, especially:
89
86
 
90
- 适用于复杂的数据结构管理,特别是:
91
- - 管理对象列表或映射(如 `messagesMap`, `topicMaps`)
92
- - 需要乐观更新的场景
93
- - 状态转换逻辑复杂
94
- - 需要类型安全的 action payload
87
+ - Managing object lists or maps (e.g., `messagesMap`, `topicMaps`)
88
+ - Scenarios requiring optimistic updates
89
+ - Complex state transition logic
90
+ - Type-safe action payloads needed
95
91
 
96
92
  ```typescript
97
- // Reducer 模式示例 - 复杂消息状态管理
93
+ // Reducer pattern example - Complex message state management
98
94
  export const messagesReducer = (state: ChatMessage[], payload: MessageDispatch): ChatMessage[] => {
99
95
  switch (payload.type) {
100
96
  case 'updateMessage': {
101
97
  return produce(state, (draftState) => {
102
98
  const index = draftState.findIndex((i) => i.id === payload.id);
103
99
  if (index < 0) return;
104
- draftState[index] = merge(draftState[index], {
105
- ...payload.value,
106
- updatedAt: Date.now()
100
+ draftState[index] = merge(draftState[index], {
101
+ ...payload.value,
102
+ updatedAt: Date.now(),
107
103
  });
108
104
  });
109
105
  }
110
106
  case 'createMessage': {
111
- return produce(state, (draftState) => {
112
- draftState.push({
113
- ...payload.value,
114
- id: payload.id,
115
- createdAt: Date.now(),
116
- updatedAt: Date.now(),
117
- meta: {}
118
- });
119
- });
107
+ // ...
120
108
  }
121
- // ...其他复杂状态转换
109
+ // ...other complex state transitions
122
110
  }
123
111
  };
124
112
  ```
125
113
 
126
- ### 使用简单 `set` 的场景
114
+ ### Use Simple `set` When
115
+
116
+ Suitable for simple state updates:
127
117
 
128
- 适用于简单状态更新:
129
- - 切换布尔值
130
- - 更新简单字符串/数字
131
- - 设置单一状态字段
118
+ - Toggling boolean values
119
+ - Updating simple strings/numbers
120
+ - Setting single state fields
132
121
 
133
122
  ```typescript
134
- // 简单 set 示例
123
+ // Simple set example
135
124
  updateInputMessage: (message) => {
136
125
  if (isEqual(message, get().inputMessage)) return;
137
126
  set({ inputMessage: message }, false, n('updateInputMessage'));
@@ -142,45 +131,45 @@ togglePortal: (open?: boolean) => {
142
131
  },
143
132
  ```
144
133
 
145
- ## 乐观更新实现模式
134
+ ## Optimistic Update Implementation Patterns
146
135
 
147
- 乐观更新是 LobeChat 中的核心模式,用于提供流畅的用户体验:
136
+ Optimistic updates are a core pattern in LobeChat for providing smooth user experience:
148
137
 
149
- ### 标准乐观更新流程
138
+ ### Standard Optimistic Update Flow
150
139
 
151
140
  ```typescript
152
- // 完整的乐观更新示例
141
+ // Complete optimistic update example
153
142
  internal_updateMessageContent: async (id, content, extra) => {
154
143
  const { internal_dispatchMessage, refreshMessages } = get();
155
144
 
156
- // 1. 立即更新前端状态(乐观更新)
145
+ // 1. Immediately update frontend state (optimistic update)
157
146
  internal_dispatchMessage({
158
147
  id,
159
148
  type: 'updateMessage',
160
149
  value: { content },
161
150
  });
162
151
 
163
- // 2. 调用后端服务
152
+ // 2. Call backend service
164
153
  await messageService.updateMessage(id, {
165
154
  content,
166
155
  tools: extra?.toolCalls ? internal_transformToolCalls(extra.toolCalls) : undefined,
167
- // ...其他字段
156
+ // ...other fields
168
157
  });
169
158
 
170
- // 3. 刷新确保数据一致性
159
+ // 3. Refresh to ensure data consistency
171
160
  await refreshMessages();
172
161
  },
173
162
  ```
174
163
 
175
- ### 创建操作的乐观更新
164
+ ### Optimistic Update for Create Operations
176
165
 
177
166
  ```typescript
178
167
  internal_createMessage: async (message, context) => {
179
168
  const { internal_createTmpMessage, refreshMessages, internal_toggleMessageLoading } = get();
180
-
169
+
181
170
  let tempId = context?.tempMessageId;
182
171
  if (!tempId) {
183
- // 创建临时消息用于乐观更新
172
+ // Create temporary message for optimistic update
184
173
  tempId = internal_createTmpMessage(message);
185
174
  internal_toggleMessageLoading(true, tempId);
186
175
  }
@@ -194,7 +183,7 @@ internal_createMessage: async (message, context) => {
194
183
  return id;
195
184
  } catch (e) {
196
185
  internal_toggleMessageLoading(false, tempId);
197
- // 错误处理:更新消息错误状态
186
+ // Error handling: update message error state
198
187
  internal_dispatchMessage({
199
188
  id: tempId,
200
189
  type: 'updateMessage',
@@ -204,96 +193,77 @@ internal_createMessage: async (message, context) => {
204
193
  },
205
194
  ```
206
195
 
207
- ### 删除操作模式(不使用乐观更新)
196
+ ### Delete Operation Pattern (No Optimistic Update)
208
197
 
209
- 删除操作通常不适合乐观更新,因为:
210
- - 删除是破坏性操作,错误恢复复杂
211
- - 用户对删除操作的即时反馈期望较低
212
- - 删除失败时恢复原状态会造成困惑
198
+ Delete operations typically don't suit optimistic updates because:
199
+
200
+ - Deletion is destructive; error recovery is complex
201
+ - Users have lower expectations for immediate feedback on deletions
202
+ - Restoring state on deletion failure causes confusion
213
203
 
214
204
  ```typescript
215
- // 删除操作的标准模式 - 无乐观更新
205
+ // Standard delete operation pattern - No optimistic update
216
206
  removeGenerationTopic: async (id: string) => {
217
207
  const { internal_removeGenerationTopic } = get();
218
208
  await internal_removeGenerationTopic(id);
219
209
  },
220
210
 
221
211
  internal_removeGenerationTopic: async (id: string) => {
222
- // 1. 显示加载状态
212
+ // 1. Show loading state
223
213
  get().internal_updateGenerationTopicLoading(id, true);
224
-
214
+
225
215
  try {
226
- // 2. 直接调用后端服务
216
+ // 2. Directly call backend service
227
217
  await generationTopicService.deleteTopic(id);
228
-
229
- // 3. 刷新数据获取最新状态
218
+
219
+ // 3. Refresh data to get latest state
230
220
  await get().refreshGenerationTopics();
231
221
  } finally {
232
- // 4. 确保清除加载状态(无论成功或失败)
222
+ // 4. Ensure loading state is cleared (whether success or failure)
233
223
  get().internal_updateGenerationTopicLoading(id, false);
234
224
  }
235
225
  },
236
226
  ```
237
227
 
238
- 删除操作的特点:
239
- - 直接调用服务,不预先更新状态
240
- - 依赖 loading 状态提供用户反馈
241
- - 操作完成后刷新整个列表确保一致性
242
- - 使用 `try/finally` 确保 loading 状态总是被清理
228
+ Delete operation characteristics:
229
+
230
+ - Directly call service without pre-updating state
231
+ - Rely on loading state for user feedback
232
+ - Refresh entire list after operation to ensure consistency
233
+ - Use `try/finally` to ensure loading state is always cleaned up
243
234
 
244
- ## 加载状态管理模式
235
+ ## Loading State Management Pattern
245
236
 
246
- LobeChat 使用统一的加载状态管理模式:
237
+ LobeChat uses a unified loading state management pattern:
247
238
 
248
- ### 数组式加载状态
239
+ ### Array-based Loading State
249
240
 
250
241
  ```typescript
251
- // initialState.ts 中定义
242
+ // Define in initialState.ts
252
243
  export interface ChatMessageState {
253
- messageLoadingIds: string[]; // 消息加载状态
254
- messageEditingIds: string[]; // 消息编辑状态
255
- chatLoadingIds: string[]; // 对话生成状态
244
+ messageEditingIds: string[]; // Message editing state
256
245
  }
257
246
 
258
- // action 中管理
259
- internal_toggleMessageLoading: (loading, id) => {
260
- set({
261
- messageLoadingIds: toggleBooleanList(get().messageLoadingIds, id, loading),
262
- }, false, `internal_toggleMessageLoading/${loading ? 'start' : 'end'}`);
263
- },
264
- ```
265
-
266
- ### 统一的加载状态工具
267
-
268
- ```typescript
269
- // 通用的加载状态切换工具
270
- internal_toggleLoadingArrays: (key, loading, id, action) => {
271
- const abortControllerKey = `${key}AbortController`;
272
-
273
- if (loading) {
274
- const abortController = new AbortController();
275
- set({
276
- [abortControllerKey]: abortController,
277
- [key]: toggleBooleanList(get()[key] as string[], id!, loading),
278
- }, false, action);
279
- return abortController;
280
- } else {
281
- set({
282
- [abortControllerKey]: undefined,
283
- [key]: id ? toggleBooleanList(get()[key] as string[], id, loading) : [],
284
- }, false, action);
285
- }
286
- },
247
+ // Manage in action
248
+ {
249
+ toggleMessageEditing: (id, editing) => {
250
+ set(
251
+ { messageEditingIds: toggleBooleanList(get().messageEditingIds, id, editing) },
252
+ false,
253
+ 'toggleMessageEditing',
254
+ );
255
+ };
256
+ }
287
257
  ```
288
258
 
289
- ## SWR 集成模式
259
+ ## SWR Integration Pattern
290
260
 
291
- LobeChat 使用 SWR 进行数据获取和缓存管理:
261
+ LobeChat uses SWR for data fetching and cache management:
292
262
 
293
- ### Hook 式数据获取
263
+ ### Hook-based Data Fetching
294
264
 
295
265
  ```typescript
296
- // action.ts 中定义 SWR hook
266
+ // Define SWR hook in action.ts
297
267
  useFetchMessages: (enable, sessionId, activeTopicId) =>
298
268
  useClientDataSWR<ChatMessage[]>(
299
269
  enable ? [SWR_USE_FETCH_MESSAGES, sessionId, activeTopicId] : null,
@@ -304,57 +274,55 @@ useFetchMessages: (enable, sessionId, activeTopicId) =>
304
274
  ...get().messagesMap,
305
275
  [messageMapKey(sessionId, activeTopicId)]: messages,
306
276
  };
307
-
277
+
308
278
  if (get().messagesInit && isEqual(nextMap, get().messagesMap)) return;
309
-
279
+
310
280
  set({ messagesInit: true, messagesMap: nextMap }, false, n('useFetchMessages'));
311
281
  },
312
282
  },
313
283
  ),
314
284
  ```
315
285
 
316
- ### 缓存失效和刷新
286
+ ### Cache Invalidation and Refresh
317
287
 
318
288
  ```typescript
319
- // 刷新数据的标准模式
289
+ // Standard data refresh pattern
320
290
  refreshMessages: async () => {
321
291
  await mutate([SWR_USE_FETCH_MESSAGES, get().activeId, get().activeTopicId]);
322
- },
323
-
324
- refreshTopic: async () => {
325
- return mutate([SWR_USE_FETCH_TOPIC, get().activeId]);
326
- },
292
+ };
327
293
  ```
328
294
 
329
- ## 命名规范总结
295
+ ## Naming Convention Summary
330
296
 
331
- ### Action 命名模式
332
- - Public Actions: 动词形式,描述用户意图
297
+ ### Action Naming Patterns
298
+
299
+ - Public Actions: Verb form, describing user intent
333
300
  - `createTopic`, `sendMessage`, `regenerateMessage`
334
- - Internal Actions: `internal_` + 动词,描述内部操作
301
+ - Internal Actions: `internal_` + verb, describing internal operation
335
302
  - `internal_createTopic`, `internal_updateMessageContent`
336
- - Dispatch Methods: `internal_dispatch` + 实体名
303
+ - Dispatch Methods: `internal_dispatch` + entity name
337
304
  - `internal_dispatchTopic`, `internal_dispatchMessage`
338
- - Toggle Methods: `internal_toggle` + 状态名
305
+ - Toggle Methods: `internal_toggle` + state name
339
306
  - `internal_toggleMessageLoading`, `internal_toggleChatLoading`
340
307
 
341
- ### 状态命名模式
342
- - ID 数组: `[entity]LoadingIds`, `[entity]EditingIds`
343
- - 映射结构: `[entity]Maps`, `[entity]Map`
344
- - 当前激活: `active[Entity]Id`
345
- - 初始化标记: `[entity]sInit`
346
-
347
- ## 最佳实践
348
-
349
- 1. 合理使用乐观更新:
350
- - 适用:创建、更新操作(用户交互频繁)
351
- - 避免:删除操作(破坏性操作,错误恢复复杂)
352
- 2. 加载状态管理:使用统一的加载状态数组管理并发操作
353
- 3. 类型安全:为所有 action payload 定义 TypeScript 接口
354
- 4. SWR 集成:使用 SWR 管理数据获取和缓存失效
355
- 5. AbortController:为长时间运行的操作提供取消能力
356
- 6. 操作模式选择:
357
- - 创建/更新:乐观更新 + 最终一致性
358
- - 删除:加载状态 + 服务调用 + 数据刷新
359
-
360
- 这套 Action 组织模式确保了代码的一致性、可维护性,并提供了优秀的用户体验。
308
+ ### State Naming Patterns
309
+
310
+ - ID arrays: `[entity]LoadingIds`, `[entity]EditingIds`
311
+ - Map structures: `[entity]Maps`, `[entity]Map`
312
+ - Currently active: `active[Entity]Id`
313
+ - Initialization flags: `[entity]sInit`
314
+
315
+ ## Best Practices
316
+
317
+ 1. Use optimistic updates appropriately:
318
+ - Suitable: Create, update operations (frequent user interaction)
319
+ - ❌ Avoid: Delete operations (destructive, complex error recovery)
320
+ 2. Loading state management: Use unified loading state arrays to manage concurrent operations
321
+ 3. Type safety: Define TypeScript interfaces for all action payloads
322
+ 4. SWR integration: Use SWR to manage data fetching and cache invalidation
323
+ 5. AbortController: Provide cancellation capability for long-running operations
324
+ 6. Operation mode selection:
325
+ - Create/Update: Optimistic update + eventual consistency
326
+ - Delete: Loading state + service call + data refresh
327
+
328
+ This Action organization pattern ensures code consistency, maintainability, and provides excellent user experience.
@@ -1,8 +1,9 @@
1
1
  ---
2
- description:
2
+ description:
3
3
  globs: src/store/**
4
4
  alwaysApply: false
5
5
  ---
6
+
6
7
  # LobeChat Zustand Store Slice 组织架构
7
8
 
8
9
  本文档描述了 LobeChat 项目中 Zustand Store 的模块化 Slice 组织方式,展示如何通过分片架构管理复杂的应用状态。
@@ -69,7 +70,7 @@ export const useChatStore = createWithEqualityFn<ChatStore>()(
69
70
 
70
71
  每个 slice 位于 `src/store/chat/slices/[sliceName]/` 目录下:
71
72
 
72
- ```
73
+ ```plaintext
73
74
  src/store/chat/slices/
74
75
  └── [sliceName]/ # 例如 message, topic, aiChat, builtinTool
75
76
  ├── action.ts # 定义 actions (或者是一个 actions/ 目录)
@@ -159,15 +160,16 @@ export const topicReducer = (state: ChatTopic[] = [], payload: ChatTopicDispatch
159
160
  // 典型的 selectors.ts 结构
160
161
  import { ChatStoreState } from '../../initialState';
161
162
 
162
- const currentTopics = (s: ChatStoreState): ChatTopic[] | undefined =>
163
- s.topicMaps[s.activeId];
163
+ const currentTopics = (s: ChatStoreState): ChatTopic[] | undefined => s.topicMaps[s.activeId];
164
164
 
165
165
  const currentActiveTopic = (s: ChatStoreState): ChatTopic | undefined => {
166
166
  return currentTopics(s)?.find((topic) => topic.id === s.activeTopicId);
167
167
  };
168
168
 
169
- const getTopicById = (id: string) => (s: ChatStoreState): ChatTopic | undefined =>
170
- currentTopics(s)?.find((topic) => topic.id === id);
169
+ const getTopicById =
170
+ (id: string) =>
171
+ (s: ChatStoreState): ChatTopic | undefined =>
172
+ currentTopics(s)?.find((topic) => topic.id === id);
171
173
 
172
174
  // 核心模式:使用 xxxSelectors 聚合导出
173
175
  export const topicSelectors = {
@@ -219,13 +221,15 @@ src/store/chat/slices/builtinTool/
219
221
  ## 状态设计模式
220
222
 
221
223
  ### 1. Map 结构用于关联数据
224
+
222
225
  ```typescript
223
226
  // 以 sessionId 为 key,管理多个会话的数据
224
- topicMaps: Record<string, ChatTopic[]>
225
- messagesMap: Record<string, ChatMessage[]>
227
+ topicMaps: Record<string, ChatTopic[]>;
228
+ messagesMap: Record<string, ChatMessage[]>;
226
229
  ```
227
230
 
228
231
  ### 2. 数组用于加载状态管理
232
+
229
233
  ```typescript
230
234
  // 管理多个并发操作的加载状态
231
235
  messageLoadingIds: string[]
@@ -234,6 +238,7 @@ chatLoadingIds: string[]
234
238
  ```
235
239
 
236
240
  ### 3. 可选字段用于当前活动项
241
+
237
242
  ```typescript
238
243
  // 当前激活的实体 ID
239
244
  activeId: string
@@ -244,6 +249,7 @@ activeThreadId?: string
244
249
  ## Slice 集成到顶层 Store
245
250
 
246
251
  ### 1. 状态聚合
252
+
247
253
  ```typescript
248
254
  // 在 initialState.ts 中
249
255
  export type ChatStoreState = ChatTopicState &
@@ -253,6 +259,7 @@ export type ChatStoreState = ChatTopicState &
253
259
  ```
254
260
 
255
261
  ### 2. Action 接口聚合
262
+
256
263
  ```typescript
257
264
  // 在 store.ts 中
258
265
  export interface ChatStoreAction
@@ -263,6 +270,7 @@ export interface ChatStoreAction
263
270
  ```
264
271
 
265
272
  ### 3. Selector 统一导出
273
+
266
274
  ```typescript
267
275
  // 在 selectors.ts 中 - 统一聚合 selectors
268
276
  export { chatSelectors } from './slices/message/selectors';
package/.husky/pre-commit CHANGED
@@ -1,2 +1,2 @@
1
- npm run typecheck
1
+ npm run type-check
2
2
  npx --no-install lint-staged
package/.i18nrc.js CHANGED
@@ -30,7 +30,9 @@ module.exports = defineConfig({
30
30
  jsonMode: true,
31
31
  },
32
32
  markdown: {
33
- reference: '你需要保持 mdx 的组件格式,输出文本不需要在最外层包裹任何代码块语法',
33
+ reference:
34
+ '你需要保持 mdx 的组件格式,输出文本不需要在最外层包裹任何代码块语法。以下是一些词汇的固定翻译:\n' +
35
+ JSON.stringify(require('./glossary.json'), null, 2),
34
36
  entry: ['./README.zh-CN.md', './contributing/**/*.zh-CN.md', './docs/**/*.zh-CN.mdx'],
35
37
  entryLocale: 'zh-CN',
36
38
  outputLocales: ['en-US'],
package/AGENTS.md CHANGED
@@ -26,6 +26,7 @@ The project follows a well-organized monorepo structure:
26
26
  - `src/` - Main source code
27
27
  - `docs/` - Documentation
28
28
  - `.cursor/rules/` - Development rules and guidelines
29
+ - PR titles starting with `✨ feat/` or `🐛 fix` will trigger the release workflow upon merge. Only use these prefixes for significant user-facing feature changes or bug fixes
29
30
 
30
31
  ## Development Workflow
31
32
 
@@ -65,7 +66,7 @@ The project follows a well-organized monorepo structure:
65
66
 
66
67
  ### Type Checking
67
68
 
68
- - Use `bun run typecheck` to check for type errors
69
+ - Use `bun run type-check` to check for type errors
69
70
 
70
71
  ### i18n
71
72
 
@@ -83,7 +84,7 @@ All following rules are saved under `.cursor/rules/` directory:
83
84
 
84
85
  ### Frontend
85
86
 
86
- - `react-component.mdc` – React component style guide and conventions
87
+ - `react.mdc` – React component style guide and conventions
87
88
  - `i18n.mdc` – Internationalization guide using react-i18next
88
89
  - `typescript.mdc` – TypeScript code style guide
89
90
  - `packages/react-layout-kit.mdc` – Usage guide for react-layout-kit
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.174](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.173...v2.0.0-next.174)
6
+
7
+ <sup>Released on **2025-12-20**</sup>
8
+
9
+ #### ♻ Code Refactoring
10
+
11
+ - **misc**: Refactor database schema.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### Code refactoring
19
+
20
+ - **misc**: Refactor database schema, closes [#10860](https://github.com/lobehub/lobe-chat/issues/10860) ([5c489bc](https://github.com/lobehub/lobe-chat/commit/5c489bc))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ## [Version 2.0.0-next.173](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.172...v2.0.0-next.173)
31
+
32
+ <sup>Released on **2025-12-16**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Request to gpt5 series should not with `top_p`, temperature when reasoning effort is not none.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Request to gpt5 series should not with `top_p`, temperature when reasoning effort is not none, closes [#10800](https://github.com/lobehub/lobe-chat/issues/10800) ([b4ad470](https://github.com/lobehub/lobe-chat/commit/b4ad470))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ## [Version 2.0.0-next.172](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.171...v2.0.0-next.172)
6
56
 
7
57
  <sup>Released on **2025-12-15**</sup>