@lobehub/lobehub 2.0.0-next.50 → 2.0.0-next.52

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 (171) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +25 -5
  3. package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +242 -0
  4. package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +4 -1
  5. package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +499 -0
  6. package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +357 -0
  7. package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +30 -22
  8. package/changelog/v1.json +18 -0
  9. package/locales/ar/chat.json +20 -0
  10. package/locales/ar/common.json +1 -0
  11. package/locales/ar/components.json +6 -0
  12. package/locales/ar/models.json +119 -126
  13. package/locales/ar/plugin.json +2 -1
  14. package/locales/bg-BG/chat.json +20 -0
  15. package/locales/bg-BG/common.json +1 -0
  16. package/locales/bg-BG/components.json +6 -0
  17. package/locales/bg-BG/models.json +104 -132
  18. package/locales/bg-BG/plugin.json +2 -1
  19. package/locales/de-DE/chat.json +20 -0
  20. package/locales/de-DE/common.json +1 -0
  21. package/locales/de-DE/components.json +6 -0
  22. package/locales/de-DE/models.json +119 -126
  23. package/locales/de-DE/plugin.json +2 -1
  24. package/locales/en-US/chat.json +20 -0
  25. package/locales/en-US/common.json +1 -0
  26. package/locales/en-US/components.json +6 -0
  27. package/locales/en-US/models.json +167 -126
  28. package/locales/en-US/plugin.json +2 -1
  29. package/locales/es-ES/chat.json +20 -0
  30. package/locales/es-ES/common.json +1 -0
  31. package/locales/es-ES/components.json +6 -0
  32. package/locales/es-ES/models.json +119 -126
  33. package/locales/es-ES/plugin.json +2 -1
  34. package/locales/fa-IR/chat.json +20 -0
  35. package/locales/fa-IR/common.json +1 -0
  36. package/locales/fa-IR/components.json +6 -0
  37. package/locales/fa-IR/models.json +119 -126
  38. package/locales/fa-IR/plugin.json +2 -1
  39. package/locales/fr-FR/chat.json +20 -0
  40. package/locales/fr-FR/common.json +1 -0
  41. package/locales/fr-FR/components.json +6 -0
  42. package/locales/fr-FR/models.json +119 -126
  43. package/locales/fr-FR/plugin.json +2 -1
  44. package/locales/it-IT/chat.json +20 -0
  45. package/locales/it-IT/common.json +1 -0
  46. package/locales/it-IT/components.json +6 -0
  47. package/locales/it-IT/models.json +119 -126
  48. package/locales/it-IT/plugin.json +2 -1
  49. package/locales/ja-JP/chat.json +20 -0
  50. package/locales/ja-JP/common.json +1 -0
  51. package/locales/ja-JP/components.json +6 -0
  52. package/locales/ja-JP/models.json +119 -126
  53. package/locales/ja-JP/plugin.json +2 -1
  54. package/locales/ko-KR/chat.json +20 -0
  55. package/locales/ko-KR/common.json +1 -0
  56. package/locales/ko-KR/components.json +6 -0
  57. package/locales/ko-KR/models.json +119 -126
  58. package/locales/ko-KR/plugin.json +2 -1
  59. package/locales/nl-NL/chat.json +20 -0
  60. package/locales/nl-NL/common.json +1 -0
  61. package/locales/nl-NL/components.json +6 -0
  62. package/locales/nl-NL/models.json +119 -126
  63. package/locales/nl-NL/plugin.json +2 -1
  64. package/locales/pl-PL/chat.json +20 -0
  65. package/locales/pl-PL/common.json +1 -0
  66. package/locales/pl-PL/components.json +6 -0
  67. package/locales/pl-PL/models.json +119 -126
  68. package/locales/pl-PL/plugin.json +2 -1
  69. package/locales/pt-BR/chat.json +20 -0
  70. package/locales/pt-BR/common.json +1 -0
  71. package/locales/pt-BR/components.json +6 -0
  72. package/locales/pt-BR/models.json +119 -126
  73. package/locales/pt-BR/plugin.json +2 -1
  74. package/locales/ru-RU/chat.json +20 -0
  75. package/locales/ru-RU/common.json +1 -0
  76. package/locales/ru-RU/components.json +6 -0
  77. package/locales/ru-RU/models.json +119 -126
  78. package/locales/ru-RU/plugin.json +2 -1
  79. package/locales/tr-TR/chat.json +20 -0
  80. package/locales/tr-TR/common.json +1 -0
  81. package/locales/tr-TR/components.json +6 -0
  82. package/locales/tr-TR/models.json +119 -126
  83. package/locales/tr-TR/plugin.json +2 -1
  84. package/locales/vi-VN/chat.json +20 -0
  85. package/locales/vi-VN/common.json +1 -0
  86. package/locales/vi-VN/components.json +6 -0
  87. package/locales/vi-VN/models.json +119 -126
  88. package/locales/vi-VN/plugin.json +2 -1
  89. package/locales/zh-CN/chat.json +20 -0
  90. package/locales/zh-CN/common.json +1 -0
  91. package/locales/zh-CN/components.json +6 -0
  92. package/locales/zh-CN/models.json +173 -80
  93. package/locales/zh-CN/plugin.json +2 -1
  94. package/locales/zh-TW/chat.json +20 -0
  95. package/locales/zh-TW/common.json +1 -0
  96. package/locales/zh-TW/components.json +6 -0
  97. package/locales/zh-TW/models.json +119 -126
  98. package/locales/zh-TW/plugin.json +2 -1
  99. package/package.json +1 -1
  100. package/packages/agent-runtime/src/core/InterventionChecker.ts +1 -1
  101. package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +23 -23
  102. package/packages/agent-runtime/src/types/state.ts +7 -1
  103. package/packages/const/src/settings/tool.ts +1 -5
  104. package/packages/electron-client-ipc/src/types/localSystem.ts +26 -2
  105. package/packages/file-loaders/src/loaders/docx/index.ts +1 -1
  106. package/packages/model-bank/src/aiModels/wenxin.ts +1348 -291
  107. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +58 -0
  108. package/packages/model-runtime/src/core/contextBuilders/openai.ts +24 -10
  109. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +3 -2
  110. package/packages/model-runtime/src/providers/openai/index.test.ts +44 -0
  111. package/packages/model-runtime/src/providers/wenxin/index.ts +22 -1
  112. package/packages/model-runtime/src/utils/modelParse.ts +6 -0
  113. package/packages/types/src/tool/builtin.ts +15 -4
  114. package/packages/types/src/tool/intervention.ts +32 -2
  115. package/packages/types/src/user/settings/tool.ts +3 -27
  116. package/src/config/modelProviders/wenxin.ts +2 -3
  117. package/src/features/Conversation/MarkdownElements/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +133 -0
  118. package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +48 -0
  119. package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +2 -1
  120. package/src/features/Conversation/Messages/Assistant/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
  121. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/Fallback.tsx +98 -0
  122. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ModeSelector.tsx +5 -6
  123. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +40 -36
  124. package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
  125. package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +25 -18
  126. package/src/features/LocalFile/LocalFile.tsx +55 -5
  127. package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +10 -4
  128. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +2 -2
  129. package/src/locales/default/components.ts +6 -0
  130. package/src/locales/default/plugin.ts +2 -1
  131. package/src/services/chat/chat.test.ts +1 -0
  132. package/src/services/electron/localFileService.ts +4 -0
  133. package/src/store/aiInfra/slices/aiProvider/__tests__/selectors.test.ts +62 -0
  134. package/src/store/aiInfra/slices/aiProvider/selectors.ts +1 -1
  135. package/src/store/chat/agents/GeneralChatAgent.ts +26 -1
  136. package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +173 -0
  137. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +8 -40
  138. package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +91 -34
  139. package/src/store/user/selectors.ts +1 -0
  140. package/src/store/user/slices/settings/action.ts +12 -0
  141. package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +0 -7
  142. package/src/store/user/slices/settings/selectors/index.ts +1 -0
  143. package/src/store/user/slices/settings/selectors/settings.test.ts +0 -37
  144. package/src/store/user/slices/settings/selectors/settings.ts +0 -5
  145. package/src/store/user/slices/settings/selectors/toolIntervention.ts +17 -0
  146. package/src/tools/code-interpreter/Render/index.tsx +1 -1
  147. package/src/tools/interventions.ts +32 -0
  148. package/src/tools/local-system/Intervention/RunCommand/index.tsx +56 -0
  149. package/src/tools/local-system/Placeholder/ListFiles.tsx +3 -5
  150. package/src/tools/local-system/Placeholder/SearchFiles.tsx +2 -5
  151. package/src/tools/local-system/Render/ListFiles/index.tsx +16 -21
  152. package/src/tools/local-system/Render/RenameLocalFile/index.tsx +15 -20
  153. package/src/tools/local-system/Render/RunCommand/index.tsx +103 -27
  154. package/src/tools/local-system/Render/SearchFiles/SearchQuery/index.tsx +0 -1
  155. package/src/tools/local-system/Render/SearchFiles/index.tsx +15 -20
  156. package/src/tools/local-system/Render/WriteFile/index.tsx +2 -8
  157. package/src/tools/local-system/index.ts +184 -4
  158. package/src/tools/local-system/systemRole.ts +62 -8
  159. package/src/tools/placeholders.ts +39 -8
  160. package/src/tools/renders.ts +56 -9
  161. package/src/tools/web-browsing/Placeholder/{PageContent.tsx → CrawlMultiPages.tsx} +4 -1
  162. package/src/tools/web-browsing/Placeholder/CrawlSinglePage.tsx +12 -0
  163. package/src/tools/web-browsing/Placeholder/Search.tsx +4 -4
  164. package/src/tools/web-browsing/Render/CrawlMultiPages.tsx +15 -0
  165. package/src/tools/web-browsing/Render/CrawlSinglePage.tsx +15 -0
  166. package/src/tools/web-browsing/Render/Search/index.tsx +39 -44
  167. package/packages/database/migrations/0044_add_tool_intervention.sql +0 -1
  168. package/src/tools/local-system/Placeholder/index.tsx +0 -25
  169. package/src/tools/local-system/Render/index.tsx +0 -40
  170. package/src/tools/web-browsing/Placeholder/index.tsx +0 -40
  171. package/src/tools/web-browsing/Render/index.tsx +0 -57
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 2.0.0-next.52](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.51...v2.0.0-next.52)
6
+
7
+ <sup>Released on **2025-11-13**</sup>
8
+
9
+ #### 🐛 Bug Fixes
10
+
11
+ - **misc**: Filter out reasoning fields from messages in ChatCompletion API.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's fixed
19
+
20
+ - **misc**: Filter out reasoning fields from messages in ChatCompletion API, closes [#10203](https://github.com/lobehub/lobe-chat/issues/10203) [#10193](https://github.com/lobehub/lobe-chat/issues/10193) ([5f28b2c](https://github.com/lobehub/lobe-chat/commit/5f28b2c))
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.51](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.50...v2.0.0-next.51)
31
+
32
+ <sup>Released on **2025-11-13**</sup>
33
+
34
+ #### 💄 Styles
35
+
36
+ - **misc**: Update ERNIE-5.0-Thinking-Preview model.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Styles
44
+
45
+ - **misc**: Update ERNIE-5.0-Thinking-Preview model, closes [#10196](https://github.com/lobehub/lobe-chat/issues/10196) ([89f3eed](https://github.com/lobehub/lobe-chat/commit/89f3eed))
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.50](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.49...v2.0.0-next.50)
6
56
 
7
57
  <sup>Released on **2025-11-13**</sup>
@@ -467,15 +467,35 @@ export default class LocalFileCtr extends ControllerModule {
467
467
  */
468
468
  @ipcClientEvent('searchLocalFiles')
469
469
  async handleLocalFilesSearch(params: LocalSearchFilesParams): Promise<FileResult[]> {
470
- logger.debug('Received file search request:', { keywords: params.keywords });
470
+ logger.debug('Received file search request:', {
471
+ directory: params.directory,
472
+ keywords: params.keywords,
473
+ });
471
474
 
472
- const options: Omit<SearchOptions, 'keywords'> = {
473
- limit: 30,
475
+ // Build search options from params, mapping directory to onlyIn
476
+ const options: SearchOptions = {
477
+ contentContains: params.contentContains,
478
+ createdAfter: params.createdAfter ? new Date(params.createdAfter) : undefined,
479
+ createdBefore: params.createdBefore ? new Date(params.createdBefore) : undefined,
480
+ detailed: params.detailed,
481
+ exclude: params.exclude,
482
+ fileTypes: params.fileTypes,
483
+ keywords: params.keywords,
484
+ limit: params.limit || 30,
485
+ liveUpdate: params.liveUpdate,
486
+ modifiedAfter: params.modifiedAfter ? new Date(params.modifiedAfter) : undefined,
487
+ modifiedBefore: params.modifiedBefore ? new Date(params.modifiedBefore) : undefined,
488
+ onlyIn: params.directory, // Map directory param to onlyIn option
489
+ sortBy: params.sortBy,
490
+ sortDirection: params.sortDirection,
474
491
  };
475
492
 
476
493
  try {
477
- const results = await this.searchService.search(params.keywords, options);
478
- logger.debug('File search completed', { count: results.length });
494
+ const results = await this.searchService.search(options.keywords, options);
495
+ logger.debug('File search completed', {
496
+ count: results.length,
497
+ directory: params.directory,
498
+ });
479
499
  return results;
480
500
  } catch (error) {
481
501
  logger.error('File search failed:', error);
@@ -0,0 +1,242 @@
1
+ import {
2
+ GetCommandOutputParams,
3
+ GetCommandOutputResult,
4
+ KillCommandParams,
5
+ KillCommandResult,
6
+ RunCommandParams,
7
+ RunCommandResult,
8
+ } from '@lobechat/electron-client-ipc';
9
+ import { ChildProcess, spawn } from 'node:child_process';
10
+ import { randomUUID } from 'node:crypto';
11
+
12
+ import { createLogger } from '@/utils/logger';
13
+
14
+ import { ControllerModule, ipcClientEvent } from './index';
15
+
16
+ const logger = createLogger('controllers:ShellCommandCtr');
17
+
18
+ interface ShellProcess {
19
+ lastReadStderr: number;
20
+ lastReadStdout: number;
21
+ process: ChildProcess;
22
+ stderr: string[];
23
+ stdout: string[];
24
+ }
25
+
26
+ export default class ShellCommandCtr extends ControllerModule {
27
+ // Shell process management
28
+ private shellProcesses = new Map<string, ShellProcess>();
29
+
30
+ @ipcClientEvent('runCommand')
31
+ async handleRunCommand({
32
+ command,
33
+ description,
34
+ run_in_background,
35
+ timeout = 120_000,
36
+ }: RunCommandParams): Promise<RunCommandResult> {
37
+ const logPrefix = `[runCommand: ${description || command.slice(0, 50)}]`;
38
+ logger.debug(`${logPrefix} Starting command execution`, {
39
+ background: run_in_background,
40
+ timeout,
41
+ });
42
+
43
+ // Validate timeout
44
+ const effectiveTimeout = Math.min(Math.max(timeout, 1000), 600_000);
45
+
46
+ // Cross-platform shell selection
47
+ const shellConfig =
48
+ process.platform === 'win32'
49
+ ? { args: ['/c', command], cmd: 'cmd.exe' }
50
+ : { args: ['-c', command], cmd: '/bin/sh' };
51
+
52
+ try {
53
+ if (run_in_background) {
54
+ // Background execution
55
+ const shellId = randomUUID();
56
+ const childProcess = spawn(shellConfig.cmd, shellConfig.args, {
57
+ env: process.env,
58
+ shell: false,
59
+ });
60
+
61
+ const shellProcess: ShellProcess = {
62
+ lastReadStderr: 0,
63
+ lastReadStdout: 0,
64
+ process: childProcess,
65
+ stderr: [],
66
+ stdout: [],
67
+ };
68
+
69
+ // Capture output
70
+ childProcess.stdout?.on('data', (data) => {
71
+ shellProcess.stdout.push(data.toString());
72
+ });
73
+
74
+ childProcess.stderr?.on('data', (data) => {
75
+ shellProcess.stderr.push(data.toString());
76
+ });
77
+
78
+ childProcess.on('exit', (code) => {
79
+ logger.debug(`${logPrefix} Background process exited`, { code, shellId });
80
+ });
81
+
82
+ this.shellProcesses.set(shellId, shellProcess);
83
+
84
+ logger.info(`${logPrefix} Started background execution`, { shellId });
85
+ return {
86
+ shell_id: shellId,
87
+ success: true,
88
+ };
89
+ } else {
90
+ // Synchronous execution with timeout
91
+ return new Promise((resolve) => {
92
+ const childProcess = spawn(shellConfig.cmd, shellConfig.args, {
93
+ env: process.env,
94
+ shell: false,
95
+ });
96
+
97
+ let stdout = '';
98
+ let stderr = '';
99
+ let killed = false;
100
+
101
+ const timeoutHandle = setTimeout(() => {
102
+ killed = true;
103
+ childProcess.kill();
104
+ resolve({
105
+ error: `Command timed out after ${effectiveTimeout}ms`,
106
+ stderr,
107
+ stdout,
108
+ success: false,
109
+ });
110
+ }, effectiveTimeout);
111
+
112
+ childProcess.stdout?.on('data', (data) => {
113
+ stdout += data.toString();
114
+ });
115
+
116
+ childProcess.stderr?.on('data', (data) => {
117
+ stderr += data.toString();
118
+ });
119
+
120
+ childProcess.on('exit', (code) => {
121
+ if (!killed) {
122
+ clearTimeout(timeoutHandle);
123
+ const success = code === 0;
124
+ logger.info(`${logPrefix} Command completed`, { code, success });
125
+ resolve({
126
+ exit_code: code || 0,
127
+ output: stdout + stderr,
128
+ stderr,
129
+ stdout,
130
+ success,
131
+ });
132
+ }
133
+ });
134
+
135
+ childProcess.on('error', (error) => {
136
+ clearTimeout(timeoutHandle);
137
+ logger.error(`${logPrefix} Command failed:`, error);
138
+ resolve({
139
+ error: error.message,
140
+ stderr,
141
+ stdout,
142
+ success: false,
143
+ });
144
+ });
145
+ });
146
+ }
147
+ } catch (error) {
148
+ logger.error(`${logPrefix} Failed to execute command:`, error);
149
+ return {
150
+ error: (error as Error).message,
151
+ success: false,
152
+ };
153
+ }
154
+ }
155
+
156
+ @ipcClientEvent('getCommandOutput')
157
+ async handleGetCommandOutput({
158
+ filter,
159
+ shell_id,
160
+ }: GetCommandOutputParams): Promise<GetCommandOutputResult> {
161
+ const logPrefix = `[getCommandOutput: ${shell_id}]`;
162
+ logger.debug(`${logPrefix} Retrieving output`);
163
+
164
+ const shellProcess = this.shellProcesses.get(shell_id);
165
+ if (!shellProcess) {
166
+ logger.error(`${logPrefix} Shell process not found`);
167
+ return {
168
+ error: `Shell ID ${shell_id} not found`,
169
+ output: '',
170
+ running: false,
171
+ stderr: '',
172
+ stdout: '',
173
+ success: false,
174
+ };
175
+ }
176
+
177
+ const { lastReadStderr, lastReadStdout, process: childProcess, stderr, stdout } = shellProcess;
178
+
179
+ // Get new output since last read
180
+ const newStdout = stdout.slice(lastReadStdout).join('');
181
+ const newStderr = stderr.slice(lastReadStderr).join('');
182
+ let output = newStdout + newStderr;
183
+
184
+ // Apply filter if provided
185
+ if (filter) {
186
+ try {
187
+ const regex = new RegExp(filter, 'gm');
188
+ const lines = output.split('\n');
189
+ output = lines.filter((line) => regex.test(line)).join('\n');
190
+ } catch (error) {
191
+ logger.error(`${logPrefix} Invalid filter regex:`, error);
192
+ }
193
+ }
194
+
195
+ // Update last read positions separately
196
+ shellProcess.lastReadStdout = stdout.length;
197
+ shellProcess.lastReadStderr = stderr.length;
198
+
199
+ const running = childProcess.exitCode === null;
200
+
201
+ logger.debug(`${logPrefix} Output retrieved`, {
202
+ outputLength: output.length,
203
+ running,
204
+ });
205
+
206
+ return {
207
+ output,
208
+ running,
209
+ stderr: newStderr,
210
+ stdout: newStdout,
211
+ success: true,
212
+ };
213
+ }
214
+
215
+ @ipcClientEvent('killCommand')
216
+ async handleKillCommand({ shell_id }: KillCommandParams): Promise<KillCommandResult> {
217
+ const logPrefix = `[killCommand: ${shell_id}]`;
218
+ logger.debug(`${logPrefix} Attempting to kill shell`);
219
+
220
+ const shellProcess = this.shellProcesses.get(shell_id);
221
+ if (!shellProcess) {
222
+ logger.error(`${logPrefix} Shell process not found`);
223
+ return {
224
+ error: `Shell ID ${shell_id} not found`,
225
+ success: false,
226
+ };
227
+ }
228
+
229
+ try {
230
+ shellProcess.process.kill();
231
+ this.shellProcesses.delete(shell_id);
232
+ logger.info(`${logPrefix} Shell killed successfully`);
233
+ return { success: true };
234
+ } catch (error) {
235
+ logger.error(`${logPrefix} Failed to kill shell:`, error);
236
+ return {
237
+ error: (error as Error).message,
238
+ success: false,
239
+ };
240
+ }
241
+ }
242
+ }
@@ -345,7 +345,10 @@ describe('LocalFileCtr', () => {
345
345
  const result = await localFileCtr.handleLocalFilesSearch({ keywords: 'test' });
346
346
 
347
347
  expect(result).toEqual(mockResults);
348
- expect(mockSearchService.search).toHaveBeenCalledWith('test', { limit: 30 });
348
+ expect(mockSearchService.search).toHaveBeenCalledWith('test', {
349
+ keywords: 'test',
350
+ limit: 30,
351
+ });
349
352
  });
350
353
 
351
354
  it('should return empty array on search error', async () => {