@lobehub/lobehub 2.0.0-next.186 → 2.0.0-next.188

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 (140) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/changelog/v1.json +18 -0
  3. package/locales/ar/models.json +89 -5
  4. package/locales/ar/plugin.json +5 -0
  5. package/locales/ar/providers.json +1 -0
  6. package/locales/bg-BG/models.json +68 -0
  7. package/locales/bg-BG/plugin.json +5 -0
  8. package/locales/bg-BG/providers.json +1 -0
  9. package/locales/de-DE/models.json +85 -0
  10. package/locales/de-DE/plugin.json +5 -0
  11. package/locales/de-DE/providers.json +1 -0
  12. package/locales/en-US/models.json +11 -10
  13. package/locales/en-US/plugin.json +5 -0
  14. package/locales/en-US/providers.json +1 -0
  15. package/locales/es-ES/models.json +72 -0
  16. package/locales/es-ES/plugin.json +5 -0
  17. package/locales/es-ES/providers.json +1 -0
  18. package/locales/fa-IR/models.json +86 -0
  19. package/locales/fa-IR/plugin.json +5 -0
  20. package/locales/fa-IR/providers.json +1 -0
  21. package/locales/fr-FR/models.json +49 -0
  22. package/locales/fr-FR/plugin.json +5 -0
  23. package/locales/fr-FR/providers.json +1 -0
  24. package/locales/it-IT/models.json +82 -0
  25. package/locales/it-IT/plugin.json +5 -0
  26. package/locales/it-IT/providers.json +1 -0
  27. package/locales/ja-JP/models.json +42 -5
  28. package/locales/ja-JP/plugin.json +5 -0
  29. package/locales/ja-JP/providers.json +1 -0
  30. package/locales/ko-KR/models.json +54 -0
  31. package/locales/ko-KR/plugin.json +5 -0
  32. package/locales/ko-KR/providers.json +1 -0
  33. package/locales/nl-NL/models.json +12 -1
  34. package/locales/nl-NL/plugin.json +5 -0
  35. package/locales/nl-NL/providers.json +1 -0
  36. package/locales/pl-PL/models.json +46 -0
  37. package/locales/pl-PL/plugin.json +5 -0
  38. package/locales/pl-PL/providers.json +1 -0
  39. package/locales/pt-BR/models.json +59 -0
  40. package/locales/pt-BR/plugin.json +5 -0
  41. package/locales/pt-BR/providers.json +1 -0
  42. package/locales/ru-RU/models.json +85 -0
  43. package/locales/ru-RU/plugin.json +5 -0
  44. package/locales/ru-RU/providers.json +1 -0
  45. package/locales/tr-TR/models.json +81 -0
  46. package/locales/tr-TR/plugin.json +5 -0
  47. package/locales/tr-TR/providers.json +1 -0
  48. package/locales/vi-VN/models.json +54 -0
  49. package/locales/vi-VN/plugin.json +5 -0
  50. package/locales/vi-VN/providers.json +1 -0
  51. package/locales/zh-CN/models.json +42 -5
  52. package/locales/zh-CN/plugin.json +5 -0
  53. package/locales/zh-CN/providers.json +1 -0
  54. package/locales/zh-TW/models.json +85 -0
  55. package/locales/zh-TW/plugin.json +5 -0
  56. package/locales/zh-TW/providers.json +1 -0
  57. package/package.json +1 -1
  58. package/packages/builtin-tool-gtd/src/manifest.ts +13 -8
  59. package/packages/builtin-tool-gtd/src/systemRole.ts +54 -19
  60. package/packages/builtin-tool-knowledge-base/package.json +1 -0
  61. package/packages/builtin-tool-knowledge-base/src/client/Inspector/ReadKnowledge/index.tsx +97 -0
  62. package/packages/builtin-tool-knowledge-base/src/client/Inspector/SearchKnowledgeBase/index.tsx +75 -0
  63. package/packages/builtin-tool-knowledge-base/src/client/Inspector/index.ts +11 -0
  64. package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/FileCard.tsx +12 -12
  65. package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/index.tsx +16 -25
  66. package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx +21 -47
  67. package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/index.tsx +19 -31
  68. package/packages/builtin-tool-knowledge-base/src/client/Render/index.ts +0 -5
  69. package/packages/builtin-tool-knowledge-base/src/client/index.ts +5 -1
  70. package/packages/builtin-tool-knowledge-base/src/executor/index.ts +119 -0
  71. package/packages/builtin-tool-local-system/package.json +1 -0
  72. package/packages/builtin-tool-local-system/src/client/Inspector/EditLocalFile/index.tsx +44 -29
  73. package/packages/builtin-tool-local-system/src/client/Inspector/GrepContent/index.tsx +20 -18
  74. package/packages/builtin-tool-local-system/src/client/Inspector/ListLocalFiles/index.tsx +76 -0
  75. package/packages/builtin-tool-local-system/src/client/Inspector/ReadLocalFile/index.tsx +8 -32
  76. package/packages/builtin-tool-local-system/src/client/Inspector/RenameLocalFile/index.tsx +62 -0
  77. package/packages/builtin-tool-local-system/src/client/Inspector/SearchLocalFiles/index.tsx +17 -11
  78. package/packages/builtin-tool-local-system/src/client/Inspector/WriteLocalFile/index.tsx +61 -0
  79. package/packages/builtin-tool-local-system/src/client/Inspector/index.ts +6 -0
  80. package/packages/builtin-tool-local-system/src/client/Render/EditLocalFile/index.tsx +6 -1
  81. package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/SearchView.tsx +19 -31
  82. package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/index.tsx +2 -42
  83. package/packages/builtin-tool-local-system/src/client/Render/index.ts +0 -2
  84. package/packages/builtin-tool-local-system/src/client/components/FilePathDisplay.tsx +56 -0
  85. package/packages/builtin-tool-local-system/src/client/components/index.ts +2 -0
  86. package/packages/builtin-tool-local-system/src/executor/index.ts +435 -0
  87. package/packages/builtin-tool-web-browsing/src/client/Inspector/Search/index.tsx +32 -5
  88. package/packages/fetch-sse/src/__tests__/request.test.ts +608 -0
  89. package/packages/model-bank/src/aiModels/aihubmix.ts +44 -8
  90. package/packages/model-bank/src/aiModels/google.ts +49 -17
  91. package/packages/model-bank/src/aiModels/hunyuan.ts +20 -0
  92. package/packages/model-bank/src/aiModels/infiniai.ts +48 -7
  93. package/packages/model-bank/src/aiModels/lobehub.ts +13 -11
  94. package/packages/model-bank/src/aiModels/minimax.ts +46 -2
  95. package/packages/model-bank/src/aiModels/ollamacloud.ts +40 -5
  96. package/packages/model-bank/src/aiModels/openai.ts +6 -3
  97. package/packages/model-bank/src/aiModels/qwen.ts +1 -1
  98. package/packages/model-bank/src/aiModels/siliconcloud.ts +60 -0
  99. package/packages/model-bank/src/aiModels/vertexai.ts +77 -44
  100. package/packages/model-bank/src/aiModels/volcengine.ts +111 -2
  101. package/packages/model-bank/src/aiModels/zenmux.ts +19 -13
  102. package/packages/model-bank/src/aiModels/zhipu.ts +64 -2
  103. package/packages/model-bank/src/types/aiModel.ts +3 -0
  104. package/packages/model-runtime/src/core/contextBuilders/google.test.ts +84 -0
  105. package/packages/model-runtime/src/core/contextBuilders/google.ts +37 -1
  106. package/packages/model-runtime/src/providers/volcengine/index.ts +2 -1
  107. package/packages/model-runtime/src/providers/zhipu/index.test.ts +0 -27
  108. package/packages/model-runtime/src/providers/zhipu/index.ts +1 -1
  109. package/packages/model-runtime/src/utils/modelParse.ts +26 -21
  110. package/packages/types/src/agent/chatConfig.ts +6 -2
  111. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +40 -1
  112. package/src/features/ChatInput/ActionBar/Model/GPT52ProReasoningEffortSlider.tsx +59 -0
  113. package/src/features/ChatInput/ActionBar/Model/GPT52ReasoningEffortSlider.tsx +61 -0
  114. package/src/features/ChatInput/ActionBar/Model/TextVerbositySlider.tsx +1 -1
  115. package/src/features/ChatInput/ActionBar/Model/ThinkingLevel2Slider.tsx +58 -0
  116. package/src/features/ChatInput/ActionBar/Model/ThinkingLevelSlider.tsx +10 -8
  117. package/src/helpers/toolEngineering/index.ts +1 -1
  118. package/src/locales/default/plugin.ts +6 -0
  119. package/src/server/modules/Mecha/AgentToolsEngine/__tests__/index.test.ts +1 -1
  120. package/src/server/modules/Mecha/AgentToolsEngine/index.ts +1 -1
  121. package/src/services/chat/mecha/modelParamsResolver.ts +11 -0
  122. package/src/store/chat/slices/builtinTool/actions/index.ts +1 -11
  123. package/src/store/tool/slices/builtin/executors/index.ts +4 -0
  124. package/src/styles/text.ts +1 -1
  125. package/src/tools/executionRuntimes.ts +3 -8
  126. package/src/tools/identifiers.ts +1 -1
  127. package/src/tools/index.ts +1 -1
  128. package/src/tools/inspectors.ts +5 -0
  129. package/src/tools/renders.ts +6 -12
  130. package/packages/builtin-tool-local-system/src/client/Render/RenameLocalFile/index.tsx +0 -37
  131. package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +0 -201
  132. package/src/store/chat/slices/builtinTool/actions/knowledgeBase.ts +0 -163
  133. package/src/store/chat/slices/builtinTool/actions/localSystem.ts +0 -241
  134. package/src/tools/knowledge-base/ExecutionRuntime/index.ts +0 -25
  135. package/src/tools/knowledge-base/Render/ReadKnowledge/index.tsx +0 -29
  136. package/src/tools/knowledge-base/Render/SearchKnowledgeBase/index.tsx +0 -29
  137. package/src/tools/knowledge-base/Render/index.ts +0 -7
  138. package/src/tools/knowledge-base/index.ts +0 -12
  139. package/src/tools/local-system/ExecutionRuntime/index.ts +0 -9
  140. package/src/tools/local-system/systemRole.ts +0 -1
@@ -0,0 +1,435 @@
1
+ import type {
2
+ EditLocalFileParams,
3
+ EditLocalFileResult,
4
+ GetCommandOutputParams,
5
+ GetCommandOutputResult,
6
+ GlobFilesParams,
7
+ GlobFilesResult,
8
+ GrepContentParams,
9
+ GrepContentResult,
10
+ KillCommandParams,
11
+ KillCommandResult,
12
+ ListLocalFileParams,
13
+ LocalFileItem,
14
+ LocalMoveFilesResultItem,
15
+ LocalReadFileParams,
16
+ LocalReadFileResult,
17
+ LocalReadFilesParams,
18
+ LocalSearchFilesParams,
19
+ MoveLocalFilesParams,
20
+ RenameLocalFileParams,
21
+ RenameLocalFileResult,
22
+ RunCommandParams,
23
+ RunCommandResult,
24
+ WriteLocalFileParams,
25
+ } from '@lobechat/electron-client-ipc';
26
+ import { BaseExecutor, type BuiltinToolResult } from '@lobechat/types';
27
+
28
+ import { localFileService } from '@/services/electron/localFileService';
29
+
30
+ import {
31
+ type EditLocalFileState,
32
+ type GetCommandOutputState,
33
+ type GlobFilesState,
34
+ type GrepContentState,
35
+ type KillCommandState,
36
+ type LocalFileListState,
37
+ type LocalFileSearchState,
38
+ type LocalMoveFilesState,
39
+ type LocalReadFileState,
40
+ type LocalReadFilesState,
41
+ type LocalRenameFileState,
42
+ LocalSystemIdentifier,
43
+ type RunCommandState,
44
+ } from '../types';
45
+
46
+ const LocalSystemApiEnum = {
47
+ editLocalFile: 'editLocalFile' as const,
48
+ getCommandOutput: 'getCommandOutput' as const,
49
+ globLocalFiles: 'globLocalFiles' as const,
50
+ grepContent: 'grepContent' as const,
51
+ killCommand: 'killCommand' as const,
52
+ listLocalFiles: 'listLocalFiles' as const,
53
+ moveLocalFiles: 'moveLocalFiles' as const,
54
+ readLocalFile: 'readLocalFile' as const,
55
+ readLocalFiles: 'readLocalFiles' as const,
56
+ renameLocalFile: 'renameLocalFile' as const,
57
+ runCommand: 'runCommand' as const,
58
+ searchLocalFiles: 'searchLocalFiles' as const,
59
+ writeLocalFile: 'writeLocalFile' as const,
60
+ };
61
+
62
+ /**
63
+ * Local System Tool Executor
64
+ *
65
+ * Handles all local file system operations including file CRUD, shell commands, and search.
66
+ */
67
+ class LocalSystemExecutor extends BaseExecutor<typeof LocalSystemApiEnum> {
68
+ readonly identifier = LocalSystemIdentifier;
69
+ protected readonly apiEnum = LocalSystemApiEnum;
70
+
71
+ // ==================== File Operations ====================
72
+
73
+ listLocalFiles = async (params: ListLocalFileParams): Promise<BuiltinToolResult> => {
74
+ try {
75
+ const result: LocalFileItem[] = await localFileService.listLocalFiles(params);
76
+
77
+ const state: LocalFileListState = { listResults: result };
78
+
79
+ return {
80
+ content: JSON.stringify(result),
81
+ state,
82
+ success: true,
83
+ };
84
+ } catch (error) {
85
+ return {
86
+ content: (error as Error).message,
87
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
88
+ success: false,
89
+ };
90
+ }
91
+ };
92
+
93
+ readLocalFile = async (params: LocalReadFileParams): Promise<BuiltinToolResult> => {
94
+ try {
95
+ const result: LocalReadFileResult = await localFileService.readLocalFile(params);
96
+
97
+ const state: LocalReadFileState = { fileContent: result };
98
+
99
+ return {
100
+ content: JSON.stringify(result),
101
+ state,
102
+ success: true,
103
+ };
104
+ } catch (error) {
105
+ return {
106
+ content: (error as Error).message,
107
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
108
+ success: false,
109
+ };
110
+ }
111
+ };
112
+
113
+ readLocalFiles = async (params: LocalReadFilesParams): Promise<BuiltinToolResult> => {
114
+ try {
115
+ const results: LocalReadFileResult[] = await localFileService.readLocalFiles(params);
116
+
117
+ const state: LocalReadFilesState = { filesContent: results };
118
+
119
+ return {
120
+ content: JSON.stringify(results),
121
+ state,
122
+ success: true,
123
+ };
124
+ } catch (error) {
125
+ return {
126
+ content: (error as Error).message,
127
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
128
+ success: false,
129
+ };
130
+ }
131
+ };
132
+
133
+ searchLocalFiles = async (params: LocalSearchFilesParams): Promise<BuiltinToolResult> => {
134
+ try {
135
+ const result: LocalFileItem[] = await localFileService.searchLocalFiles(params);
136
+
137
+ const state: LocalFileSearchState = { searchResults: result };
138
+
139
+ return {
140
+ content: JSON.stringify(result),
141
+ state,
142
+ success: true,
143
+ };
144
+ } catch (error) {
145
+ return {
146
+ content: (error as Error).message,
147
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
148
+ success: false,
149
+ };
150
+ }
151
+ };
152
+
153
+ moveLocalFiles = async (params: MoveLocalFilesParams): Promise<BuiltinToolResult> => {
154
+ try {
155
+ const results: LocalMoveFilesResultItem[] = await localFileService.moveLocalFiles(params);
156
+
157
+ const allSucceeded = results.every((r) => r.success);
158
+ const someFailed = results.some((r) => !r.success);
159
+ const successCount = results.filter((r) => r.success).length;
160
+ const failedCount = results.length - successCount;
161
+
162
+ let message = '';
163
+
164
+ if (allSucceeded) {
165
+ message = `Successfully moved ${results.length} item(s).`;
166
+ } else if (someFailed) {
167
+ message = `Moved ${successCount} item(s) successfully. Failed to move ${failedCount} item(s).`;
168
+ } else {
169
+ message = `Failed to move all ${results.length} item(s).`;
170
+ }
171
+
172
+ const state: LocalMoveFilesState = {
173
+ results,
174
+ successCount,
175
+ totalCount: results.length,
176
+ };
177
+
178
+ return {
179
+ content: JSON.stringify({ message, results }),
180
+ state,
181
+ success: true,
182
+ };
183
+ } catch (error) {
184
+ return {
185
+ content: (error as Error).message,
186
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
187
+ success: false,
188
+ };
189
+ }
190
+ };
191
+
192
+ renameLocalFile = async (params: RenameLocalFileParams): Promise<BuiltinToolResult> => {
193
+ try {
194
+ const result: RenameLocalFileResult = await localFileService.renameLocalFile(params);
195
+
196
+ if (!result.success) {
197
+ const state: LocalRenameFileState = {
198
+ error: result.error,
199
+ newPath: '',
200
+ oldPath: params.path,
201
+ success: false,
202
+ };
203
+
204
+ return {
205
+ content: JSON.stringify({ message: result.error, success: false }),
206
+ state,
207
+ success: false,
208
+ };
209
+ }
210
+
211
+ const state: LocalRenameFileState = {
212
+ newPath: result.newPath!,
213
+ oldPath: params.path,
214
+ success: true,
215
+ };
216
+
217
+ return {
218
+ content: JSON.stringify({
219
+ message: `Successfully renamed file ${params.path} to ${params.newName}.`,
220
+ success: true,
221
+ }),
222
+ state,
223
+ success: true,
224
+ };
225
+ } catch (error) {
226
+ return {
227
+ content: (error as Error).message,
228
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
229
+ success: false,
230
+ };
231
+ }
232
+ };
233
+
234
+ writeLocalFile = async (params: WriteLocalFileParams): Promise<BuiltinToolResult> => {
235
+ try {
236
+ const result = await localFileService.writeFile(params);
237
+
238
+ if (!result.success) {
239
+ return {
240
+ content: JSON.stringify({
241
+ message: result.error || 'Failed to write file',
242
+ success: false,
243
+ }),
244
+ error: { message: result.error || 'Failed to write file', type: 'PluginServerError' },
245
+ success: false,
246
+ };
247
+ }
248
+
249
+ return {
250
+ content: JSON.stringify({
251
+ message: `Successfully wrote file ${params.path}`,
252
+ success: true,
253
+ }),
254
+ success: true,
255
+ };
256
+ } catch (error) {
257
+ return {
258
+ content: (error as Error).message,
259
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
260
+ success: false,
261
+ };
262
+ }
263
+ };
264
+
265
+ editLocalFile = async (params: EditLocalFileParams): Promise<BuiltinToolResult> => {
266
+ try {
267
+ const result: EditLocalFileResult = await localFileService.editLocalFile(params);
268
+
269
+ if (!result.success) {
270
+ return {
271
+ content: `Edit failed: ${result.error}`,
272
+ success: false,
273
+ };
274
+ }
275
+
276
+ const statsText =
277
+ result.linesAdded || result.linesDeleted
278
+ ? ` (+${result.linesAdded || 0} -${result.linesDeleted || 0})`
279
+ : '';
280
+ const message = `Successfully replaced ${result.replacements} occurrence(s) in ${params.file_path}${statsText}`;
281
+
282
+ const state: EditLocalFileState = {
283
+ diffText: result.diffText,
284
+ linesAdded: result.linesAdded,
285
+ linesDeleted: result.linesDeleted,
286
+ replacements: result.replacements,
287
+ };
288
+
289
+ return {
290
+ content: message,
291
+ state,
292
+ success: true,
293
+ };
294
+ } catch (error) {
295
+ return {
296
+ content: (error as Error).message,
297
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
298
+ success: false,
299
+ };
300
+ }
301
+ };
302
+
303
+ // ==================== Shell Commands ====================
304
+
305
+ runCommand = async (params: RunCommandParams): Promise<BuiltinToolResult> => {
306
+ try {
307
+ const result: RunCommandResult = await localFileService.runCommand(params);
308
+
309
+ let message: string;
310
+
311
+ if (result.success) {
312
+ if (result.shell_id) {
313
+ message = `Command started in background with shell_id: ${result.shell_id}`;
314
+ } else {
315
+ message = `Command completed successfully.`;
316
+ }
317
+ } else {
318
+ message = `Command failed: ${result.error}`;
319
+ }
320
+
321
+ const state: RunCommandState = { message, result };
322
+
323
+ return {
324
+ content: JSON.stringify(result),
325
+ state,
326
+ success: result.success,
327
+ };
328
+ } catch (error) {
329
+ return {
330
+ content: (error as Error).message,
331
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
332
+ success: false,
333
+ };
334
+ }
335
+ };
336
+
337
+ getCommandOutput = async (params: GetCommandOutputParams): Promise<BuiltinToolResult> => {
338
+ try {
339
+ const result: GetCommandOutputResult = await localFileService.getCommandOutput(params);
340
+
341
+ const message = result.success
342
+ ? `Output retrieved. Running: ${result.running}`
343
+ : `Failed: ${result.error}`;
344
+
345
+ const state: GetCommandOutputState = { message, result };
346
+
347
+ return {
348
+ content: JSON.stringify(result),
349
+ state,
350
+ success: result.success,
351
+ };
352
+ } catch (error) {
353
+ return {
354
+ content: (error as Error).message,
355
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
356
+ success: false,
357
+ };
358
+ }
359
+ };
360
+
361
+ killCommand = async (params: KillCommandParams): Promise<BuiltinToolResult> => {
362
+ try {
363
+ const result: KillCommandResult = await localFileService.killCommand(params);
364
+
365
+ const message = result.success
366
+ ? `Successfully killed shell: ${params.shell_id}`
367
+ : `Failed to kill shell: ${result.error}`;
368
+
369
+ const state: KillCommandState = { message, result };
370
+
371
+ return {
372
+ content: JSON.stringify(result),
373
+ state,
374
+ success: result.success,
375
+ };
376
+ } catch (error) {
377
+ return {
378
+ content: (error as Error).message,
379
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
380
+ success: false,
381
+ };
382
+ }
383
+ };
384
+
385
+ // ==================== Search & Find ====================
386
+
387
+ grepContent = async (params: GrepContentParams): Promise<BuiltinToolResult> => {
388
+ try {
389
+ const result: GrepContentResult = await localFileService.grepContent(params);
390
+
391
+ const message = result.success
392
+ ? `Found ${result.total_matches} matches in ${result.matches.length} locations`
393
+ : 'Search failed';
394
+
395
+ const state: GrepContentState = { message, result };
396
+
397
+ return {
398
+ content: JSON.stringify(result),
399
+ state,
400
+ success: result.success,
401
+ };
402
+ } catch (error) {
403
+ return {
404
+ content: (error as Error).message,
405
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
406
+ success: false,
407
+ };
408
+ }
409
+ };
410
+
411
+ globLocalFiles = async (params: GlobFilesParams): Promise<BuiltinToolResult> => {
412
+ try {
413
+ const result: GlobFilesResult = await localFileService.globFiles(params);
414
+
415
+ const message = result.success ? `Found ${result.total_files} files` : 'Glob search failed';
416
+
417
+ const state: GlobFilesState = { message, result };
418
+
419
+ return {
420
+ content: JSON.stringify(result),
421
+ state,
422
+ success: result.success,
423
+ };
424
+ } catch (error) {
425
+ return {
426
+ content: (error as Error).message,
427
+ error: { body: error, message: (error as Error).message, type: 'PluginServerError' },
428
+ success: false,
429
+ };
430
+ }
431
+ };
432
+ }
433
+
434
+ // Export the executor instance for registration
435
+ export const localSystemExecutor = new LocalSystemExecutor();
@@ -1,7 +1,12 @@
1
1
  'use client';
2
2
 
3
- import { type BuiltinInspectorProps, type SearchQuery } from '@lobechat/types';
4
- import { createStaticStyles, cx } from 'antd-style';
3
+ import {
4
+ type BuiltinInspectorProps,
5
+ type SearchQuery,
6
+ type UniformSearchResponse,
7
+ } from '@lobechat/types';
8
+ import { Text } from '@lobehub/ui';
9
+ import { createStaticStyles, cssVar, cx } from 'antd-style';
5
10
  import { memo } from 'react';
6
11
  import { useTranslation } from 'react-i18next';
7
12
 
@@ -18,11 +23,13 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
18
23
  `,
19
24
  }));
20
25
 
21
- export const SearchInspector = memo<BuiltinInspectorProps<SearchQuery>>(
22
- ({ args, partialArgs, isArgumentsStreaming }) => {
26
+ export const SearchInspector = memo<BuiltinInspectorProps<SearchQuery, UniformSearchResponse>>(
27
+ ({ args, partialArgs, isArgumentsStreaming, isLoading, pluginState }) => {
23
28
  const { t } = useTranslation('plugin');
24
29
 
25
30
  const query = args?.query || partialArgs?.query || '';
31
+ const resultCount = pluginState?.results?.length ?? 0;
32
+ const hasResults = resultCount > 0;
26
33
 
27
34
  if (isArgumentsStreaming && !query) {
28
35
  return (
@@ -33,9 +40,29 @@ export const SearchInspector = memo<BuiltinInspectorProps<SearchQuery>>(
33
40
  }
34
41
 
35
42
  return (
36
- <div className={cx(styles.root, isArgumentsStreaming && shinyTextStyles.shinyText)}>
43
+ <div
44
+ className={cx(
45
+ styles.root,
46
+ (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText,
47
+ )}
48
+ >
37
49
  <span>{t('builtins.lobe-web-browsing.apiName.search')}: </span>
38
50
  {query && <span className={highlightTextStyles.gold}>{query}</span>}
51
+ {!isLoading &&
52
+ !isArgumentsStreaming &&
53
+ pluginState?.results &&
54
+ (hasResults ? (
55
+ <span style={{ marginInlineStart: 4 }}>({resultCount})</span>
56
+ ) : (
57
+ <Text
58
+ as={'span'}
59
+ color={cssVar.colorTextDescription}
60
+ fontSize={12}
61
+ style={{ marginInlineStart: 4 }}
62
+ >
63
+ ({t('builtins.lobe-web-browsing.inspector.noResults')})
64
+ </Text>
65
+ ))}
39
66
  </div>
40
67
  );
41
68
  },