@lobehub/chat 1.104.0 → 1.104.2

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 (25) hide show
  1. package/.cursor/rules/code-review.mdc +2 -0
  2. package/.cursor/rules/typescript.mdc +3 -1
  3. package/CHANGELOG.md +50 -0
  4. package/apps/desktop/src/main/core/ui/ShortcutManager.ts +61 -6
  5. package/apps/desktop/src/main/core/ui/__tests__/ShortcutManager.test.ts +539 -0
  6. package/changelog/v1.json +18 -0
  7. package/package.json +1 -1
  8. package/src/app/[variants]/(main)/image/features/GenerationFeed/BatchItem.tsx +6 -1
  9. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/ErrorState.tsx +3 -2
  10. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/LoadingState.tsx +27 -24
  11. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/SuccessState.tsx +14 -3
  12. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/index.tsx +4 -7
  13. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/types.ts +3 -0
  14. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/utils.test.ts +600 -0
  15. package/src/app/[variants]/(main)/image/features/GenerationFeed/GenerationItem/utils.ts +126 -7
  16. package/src/const/imageGeneration.ts +18 -0
  17. package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.test.ts +3 -0
  18. package/src/libs/model-runtime/utils/openaiCompatibleFactory/index.ts +7 -5
  19. package/src/libs/model-runtime/utils/streams/openai/openai.ts +8 -4
  20. package/src/libs/model-runtime/utils/usageConverter.test.ts +45 -1
  21. package/src/libs/model-runtime/utils/usageConverter.ts +6 -2
  22. package/src/server/services/generation/index.test.ts +848 -0
  23. package/src/server/services/generation/index.ts +90 -69
  24. package/src/utils/number.test.ts +101 -1
  25. package/src/utils/number.ts +42 -0
@@ -26,6 +26,8 @@ Gather the modified code and context. Please strictly follow the process below:
26
26
 
27
27
  ### Code Style
28
28
 
29
+ read [typescript.mdc](mdc:.cursor/rules/typescript.mdc) to learn the project's code style.
30
+
29
31
  - Ensure JSDoc comments accurately reflect the implementation; update them when needed.
30
32
  - Look for opportunities to simplify or modernize code with the latest JavaScript/TypeScript features.
31
33
  - Prefer `async`/`await` over callbacks or chained `.then` promises.
@@ -16,4 +16,6 @@ TypeScript Code Style Guide:
16
16
  - Always refactor repeated logic into a reusable function
17
17
  - Don't remove meaningful code comments, be sure to keep original comments when providing applied code
18
18
  - Update the code comments when needed after you modify the related code
19
- - Please respect my prettier preferences when you provide code
19
+ - Please respect my prettier preferences when you provide code
20
+ - Prefer object destructuring when accessing and using properties
21
+ - Prefer async version api than sync version, eg: use readFile from 'fs/promises' instead of 'fs'
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.104.2](https://github.com/lobehub/lobe-chat/compare/v1.104.1...v1.104.2)
6
+
7
+ <sup>Released on **2025-07-26**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Fix update hotkey invalid when input mod in desktop.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Fix update hotkey invalid when input mod in desktop, closes [#8572](https://github.com/lobehub/lobe-chat/issues/8572) ([07f3e6a](https://github.com/lobehub/lobe-chat/commit/07f3e6a))
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 1.104.1](https://github.com/lobehub/lobe-chat/compare/v1.104.0...v1.104.1)
31
+
32
+ <sup>Released on **2025-07-25**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Update convertUsage to handle XAI provider and adjust OpenAIStream to pass provider.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Update convertUsage to handle XAI provider and adjust OpenAIStream to pass provider, closes [#8557](https://github.com/lobehub/lobe-chat/issues/8557) ([d1e4a54](https://github.com/lobehub/lobe-chat/commit/d1e4a54))
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 1.104.0](https://github.com/lobehub/lobe-chat/compare/v1.103.2...v1.104.0)
6
56
 
7
57
  <sup>Released on **2025-07-24**</sup>
@@ -33,6 +33,28 @@ export class ShortcutManager {
33
33
  });
34
34
  }
35
35
 
36
+ /**
37
+ * Convert react-hotkey format to Electron accelerator format
38
+ * @param accelerator The accelerator string from frontend
39
+ * @returns Converted accelerator string for Electron
40
+ */
41
+ private convertAcceleratorFormat(accelerator: string): string {
42
+ return accelerator
43
+ .split('+')
44
+ .map((key) => {
45
+ const trimmedKey = key.trim().toLowerCase();
46
+
47
+ // Convert react-hotkey 'mod' to Electron 'CommandOrControl'
48
+ if (trimmedKey === 'mod') {
49
+ return 'CommandOrControl';
50
+ }
51
+
52
+ // Keep other keys as is, but preserve proper casing
53
+ return key.trim().length === 1 ? key.trim().toUpperCase() : key.trim();
54
+ })
55
+ .join('+');
56
+ }
57
+
36
58
  initialize() {
37
59
  logger.info('Initializing global shortcuts');
38
60
  // Load shortcuts configuration from storage
@@ -67,7 +89,11 @@ export class ShortcutManager {
67
89
  return { errorType: 'INVALID_FORMAT', success: false };
68
90
  }
69
91
 
70
- const cleanAccelerator = accelerator.trim().toLowerCase();
92
+ // 转换前端格式到 Electron 格式
93
+ const convertedAccelerator = this.convertAcceleratorFormat(accelerator.trim());
94
+ const cleanAccelerator = convertedAccelerator.toLowerCase();
95
+
96
+ logger.debug(`Converted accelerator from ${accelerator} to ${convertedAccelerator}`);
71
97
 
72
98
  // 3. 检查是否包含 + 号(修饰键格式)
73
99
  if (!cleanAccelerator.includes('+')) {
@@ -100,17 +126,19 @@ export class ShortcutManager {
100
126
  }
101
127
 
102
128
  // 6. 尝试注册测试(检查是否被系统占用)
103
- const testSuccess = globalShortcut.register(cleanAccelerator, () => {});
129
+ const testSuccess = globalShortcut.register(convertedAccelerator, () => {});
104
130
  if (!testSuccess) {
105
- logger.error(`Shortcut ${cleanAccelerator} is already registered by system or other app`);
131
+ logger.error(
132
+ `Shortcut ${convertedAccelerator} is already registered by system or other app`,
133
+ );
106
134
  return { errorType: 'SYSTEM_OCCUPIED', success: false };
107
135
  } else {
108
136
  // 测试成功,立即取消注册
109
- globalShortcut.unregister(cleanAccelerator);
137
+ globalShortcut.unregister(convertedAccelerator);
110
138
  }
111
139
 
112
140
  // 7. 更新配置
113
- this.shortcutsConfig[id] = cleanAccelerator;
141
+ this.shortcutsConfig[id] = convertedAccelerator;
114
142
 
115
143
  this.saveShortcutsConfig();
116
144
  this.registerConfiguredShortcuts();
@@ -196,7 +224,34 @@ export class ShortcutManager {
196
224
  this.shortcutsConfig = DEFAULT_SHORTCUTS_CONFIG;
197
225
  this.saveShortcutsConfig();
198
226
  } else {
199
- this.shortcutsConfig = config;
227
+ // Filter out invalid shortcuts that are not in DEFAULT_SHORTCUTS_CONFIG
228
+ const filteredConfig: Record<string, string> = {};
229
+ let hasInvalidKeys = false;
230
+
231
+ Object.entries(config).forEach(([id, accelerator]) => {
232
+ if (DEFAULT_SHORTCUTS_CONFIG[id]) {
233
+ filteredConfig[id] = accelerator;
234
+ } else {
235
+ hasInvalidKeys = true;
236
+ logger.debug(`Filtering out invalid shortcut ID: ${id}`);
237
+ }
238
+ });
239
+
240
+ // Ensure all default shortcuts are present
241
+ Object.entries(DEFAULT_SHORTCUTS_CONFIG).forEach(([id, defaultAccelerator]) => {
242
+ if (!(id in filteredConfig)) {
243
+ filteredConfig[id] = defaultAccelerator;
244
+ logger.debug(`Adding missing default shortcut: ${id} = ${defaultAccelerator}`);
245
+ }
246
+ });
247
+
248
+ this.shortcutsConfig = filteredConfig;
249
+
250
+ // Save the filtered configuration back to storage if we removed invalid keys
251
+ if (hasInvalidKeys) {
252
+ logger.debug('Saving filtered shortcuts config to remove invalid keys');
253
+ this.saveShortcutsConfig();
254
+ }
200
255
  }
201
256
 
202
257
  logger.debug('Loaded shortcuts config:', this.shortcutsConfig);