@lobehub/lobehub 2.0.0-next.51 → 2.0.0-next.53

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 (107) hide show
  1. package/CHANGELOG.md +58 -0
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/apps/desktop/package.json +1 -1
  5. package/apps/desktop/src/main/controllers/LocalFileCtr.ts +25 -5
  6. package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +4 -1
  7. package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +357 -0
  8. package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +30 -22
  9. package/changelog/v1.json +21 -0
  10. package/locales/ar/models.json +119 -126
  11. package/locales/ar/plugin.json +1 -1
  12. package/locales/bg-BG/models.json +104 -132
  13. package/locales/bg-BG/plugin.json +1 -1
  14. package/locales/de-DE/models.json +119 -126
  15. package/locales/de-DE/plugin.json +1 -1
  16. package/locales/en-US/models.json +167 -126
  17. package/locales/en-US/plugin.json +1 -1
  18. package/locales/es-ES/models.json +119 -126
  19. package/locales/es-ES/plugin.json +1 -1
  20. package/locales/fa-IR/models.json +119 -126
  21. package/locales/fa-IR/plugin.json +1 -1
  22. package/locales/fr-FR/models.json +119 -126
  23. package/locales/fr-FR/plugin.json +1 -1
  24. package/locales/it-IT/models.json +119 -126
  25. package/locales/it-IT/plugin.json +1 -1
  26. package/locales/ja-JP/models.json +119 -126
  27. package/locales/ja-JP/plugin.json +1 -1
  28. package/locales/ko-KR/models.json +119 -126
  29. package/locales/ko-KR/plugin.json +1 -1
  30. package/locales/nl-NL/models.json +119 -126
  31. package/locales/nl-NL/plugin.json +1 -1
  32. package/locales/pl-PL/models.json +119 -126
  33. package/locales/pl-PL/plugin.json +1 -1
  34. package/locales/pt-BR/models.json +119 -126
  35. package/locales/pt-BR/plugin.json +1 -1
  36. package/locales/ru-RU/models.json +119 -126
  37. package/locales/ru-RU/plugin.json +1 -1
  38. package/locales/tr-TR/models.json +119 -126
  39. package/locales/tr-TR/plugin.json +1 -1
  40. package/locales/vi-VN/models.json +119 -126
  41. package/locales/vi-VN/plugin.json +1 -1
  42. package/locales/zh-CN/models.json +173 -80
  43. package/locales/zh-CN/plugin.json +1 -1
  44. package/locales/zh-TW/models.json +119 -126
  45. package/locales/zh-TW/plugin.json +1 -1
  46. package/package.json +2 -2
  47. package/packages/const/src/models.ts +2 -0
  48. package/packages/electron-client-ipc/src/types/localSystem.ts +26 -2
  49. package/packages/electron-server-ipc/src/ipcClient.ts +31 -31
  50. package/packages/electron-server-ipc/src/ipcServer.ts +15 -15
  51. package/packages/model-bank/src/aiModels/aihubmix.ts +106 -2
  52. package/packages/model-bank/src/aiModels/openai.ts +107 -3
  53. package/packages/model-bank/src/aiModels/qwen.ts +76 -7
  54. package/packages/model-bank/src/types/aiModel.ts +1 -0
  55. package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +58 -0
  56. package/packages/model-runtime/src/core/contextBuilders/openai.ts +24 -10
  57. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +3 -2
  58. package/packages/model-runtime/src/providers/openai/index.test.ts +44 -0
  59. package/packages/types/src/agent/chatConfig.ts +9 -0
  60. package/packages/types/src/tool/builtin.ts +6 -4
  61. package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +32 -23
  62. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +12 -0
  63. package/src/features/ChatInput/ActionBar/Model/GPT51ReasoningEffortSlider.tsx +58 -0
  64. package/src/features/ChatItem/components/MessageContent.tsx +3 -1
  65. package/src/features/Conversation/Messages/Assistant/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
  66. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ApprovalActions.tsx +34 -13
  67. package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +2 -2
  68. package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
  69. package/src/features/Conversation/Messages/User/index.tsx +11 -1
  70. package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +10 -4
  71. package/src/features/PluginsUI/Render/BuiltinType/index.tsx +2 -2
  72. package/src/libs/mcp/__tests__/__snapshots__/index.test.ts.snap +0 -6
  73. package/src/locales/default/chat.ts +2 -0
  74. package/src/locales/default/plugin.ts +1 -1
  75. package/src/services/chat/chat.test.ts +1 -0
  76. package/src/services/chat/index.ts +7 -0
  77. package/src/store/aiInfra/slices/aiProvider/__tests__/selectors.test.ts +62 -0
  78. package/src/store/aiInfra/slices/aiProvider/selectors.ts +1 -1
  79. package/src/store/chat/slices/aiChat/actions/conversationControl.ts +42 -0
  80. package/src/tools/code-interpreter/Render/index.tsx +1 -1
  81. package/src/tools/interventions.ts +28 -4
  82. package/src/tools/local-system/Intervention/RunCommand/index.tsx +4 -5
  83. package/src/tools/local-system/Placeholder/ListFiles.tsx +3 -5
  84. package/src/tools/local-system/Placeholder/SearchFiles.tsx +2 -5
  85. package/src/tools/local-system/Render/ListFiles/index.tsx +16 -21
  86. package/src/tools/local-system/Render/ReadLocalFile/ReadFileView.tsx +2 -1
  87. package/src/tools/local-system/Render/RenameLocalFile/index.tsx +15 -20
  88. package/src/tools/local-system/Render/RunCommand/index.tsx +67 -70
  89. package/src/tools/local-system/Render/SearchFiles/SearchQuery/index.tsx +0 -1
  90. package/src/tools/local-system/Render/SearchFiles/index.tsx +15 -20
  91. package/src/tools/local-system/Render/WriteFile/index.tsx +2 -8
  92. package/src/tools/local-system/index.ts +5 -4
  93. package/src/tools/local-system/systemRole.ts +1 -1
  94. package/src/tools/placeholders.ts +39 -8
  95. package/src/tools/renders.ts +56 -9
  96. package/src/tools/web-browsing/Placeholder/{PageContent.tsx → CrawlMultiPages.tsx} +4 -1
  97. package/src/tools/web-browsing/Placeholder/CrawlSinglePage.tsx +12 -0
  98. package/src/tools/web-browsing/Placeholder/Search.tsx +4 -4
  99. package/src/tools/web-browsing/Render/CrawlMultiPages.tsx +15 -0
  100. package/src/tools/web-browsing/Render/CrawlSinglePage.tsx +15 -0
  101. package/src/tools/web-browsing/Render/Search/index.tsx +39 -44
  102. package/packages/database/migrations/0044_add_tool_intervention.sql +0 -1
  103. package/src/tools/local-system/Intervention/index.tsx +0 -17
  104. package/src/tools/local-system/Placeholder/index.tsx +0 -25
  105. package/src/tools/local-system/Render/index.tsx +0 -42
  106. package/src/tools/web-browsing/Placeholder/index.tsx +0 -40
  107. package/src/tools/web-browsing/Render/index.tsx +0 -57
@@ -5,7 +5,7 @@ import { Flexbox } from 'react-layout-kit';
5
5
  import { useChatStore } from '@/store/chat';
6
6
  import { useUserStore } from '@/store/user';
7
7
  import { toolInterventionSelectors } from '@/store/user/selectors';
8
- import { BuiltinToolInterventions } from '@/tools/interventions';
8
+ import { getBuiltinIntervention } from '@/tools/interventions';
9
9
 
10
10
  import Arguments from '../Arguments';
11
11
  import ApprovalActions from './ApprovalActions';
@@ -52,7 +52,7 @@ const Intervention = memo<InterventionProps>(
52
52
  },
53
53
  [requestArgs, id],
54
54
  );
55
- const BuiltinToolInterventionRender = BuiltinToolInterventions[identifier];
55
+ const BuiltinToolInterventionRender = getBuiltinIntervention(identifier, apiName);
56
56
 
57
57
  if (BuiltinToolInterventionRender) {
58
58
  if (isEditing)
@@ -1,7 +1,7 @@
1
1
  import { safeParseJSON } from '@lobechat/utils';
2
2
  import { memo } from 'react';
3
3
 
4
- import { BuiltinToolPlaceholders } from '@/tools/placeholders';
4
+ import { getBuiltinPlaceholder } from '@/tools/placeholders';
5
5
 
6
6
  import Arguments from '../Arguments';
7
7
 
@@ -14,9 +14,9 @@ interface LoadingPlaceholderProps {
14
14
 
15
15
  const LoadingPlaceholder = memo<LoadingPlaceholderProps>(
16
16
  ({ identifier, requestArgs, apiName, loading }) => {
17
- const Render = BuiltinToolPlaceholders[identifier || ''];
17
+ const Render = getBuiltinPlaceholder(identifier, apiName);
18
18
 
19
- if (identifier && Render) {
19
+ if (Render) {
20
20
  return (
21
21
  <Render apiName={apiName} args={safeParseJSON(requestArgs) || {}} identifier={identifier} />
22
22
  );
@@ -1,6 +1,6 @@
1
1
  import { UIChatMessage } from '@lobechat/types';
2
2
  import { Tag } from '@lobehub/ui';
3
- import { useResponsive } from 'antd-style';
3
+ import { createStyles, useResponsive } from 'antd-style';
4
4
  import isEqual from 'fast-deep-equal';
5
5
  import { ReactNode, memo, useCallback, useMemo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
@@ -45,6 +45,13 @@ const remarkPlugins = markdownElements
45
45
  .map((element) => element.remarkPlugin)
46
46
  .filter(Boolean);
47
47
 
48
+ const useUserStyles = createStyles(({ css, token }) => ({
49
+ messageContainer: css`
50
+ border: none;
51
+ background: ${token.colorFillTertiary};
52
+ `,
53
+ }));
54
+
48
55
  const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
49
56
  const item = useChatStore(
50
57
  displayMessageSelectors.getDisplayMessageById(id),
@@ -56,6 +63,8 @@ const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
56
63
  const { t } = useTranslation('chat');
57
64
  const { mobile } = useResponsive();
58
65
  const avatar = useUserAvatar();
66
+ const { styles: userStyles } = useUserStyles();
67
+
59
68
  const title = useUserStore(userProfileSelectors.displayUserName);
60
69
 
61
70
  const displayMode = useAgentStore(agentChatConfigSelectors.displayMode);
@@ -165,6 +174,7 @@ const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
165
174
  >
166
175
  <Flexbox flex={1} style={{ maxWidth: '100%', minWidth: 0 }}>
167
176
  <MessageContent
177
+ className={userStyles.messageContainer}
168
178
  editing={editing}
169
179
  id={id}
170
180
  markdownProps={markdownProps}
@@ -4,11 +4,17 @@ import { describe, expect, it, vi } from 'vitest';
4
4
  import BuiltinType from './index';
5
5
 
6
6
  // Mock renders module
7
+ const mockWebBrowsingRender = vi.fn(({ content }) => <div>WebBrowsingRender: {content}</div>);
8
+ const mockCodeInterpreterRender = vi.fn(({ content }) => (
9
+ <div>CodeInterpreterRender: {content}</div>
10
+ ));
11
+
7
12
  vi.mock('@/tools/renders', () => ({
8
- BuiltinToolsRenders: {
9
- 'lobe-web-browsing': vi.fn(({ content }) => <div>WebBrowsingRender: {content}</div>),
10
- 'lobe-code-interpreter': vi.fn(({ content }) => <div>CodeInterpreterRender: {content}</div>),
11
- },
13
+ getBuiltinRender: vi.fn((identifier, apiName) => {
14
+ if (identifier === 'lobe-web-browsing') return mockWebBrowsingRender;
15
+ if (identifier === 'lobe-code-interpreter') return mockCodeInterpreterRender;
16
+ return undefined;
17
+ }),
12
18
  }));
13
19
 
14
20
  // Mock useParseContent hook
@@ -1,7 +1,7 @@
1
1
  import { safeParseJSON } from '@lobechat/utils';
2
2
  import { memo } from 'react';
3
3
 
4
- import { BuiltinToolsRenders } from '@/tools/renders';
4
+ import { getBuiltinRender } from '@/tools/renders';
5
5
 
6
6
  import { useParseContent } from '../useParseContent';
7
7
 
@@ -28,7 +28,7 @@ const BuiltinType = memo<BuiltinTypeProps>(
28
28
  }) => {
29
29
  const { data } = useParseContent(content);
30
30
 
31
- const Render = BuiltinToolsRenders[identifier || ''];
31
+ const Render = getBuiltinRender(identifier, apiName);
32
32
 
33
33
  if (!Render) return;
34
34
 
@@ -5,8 +5,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
5
5
  {
6
6
  "description": "Echoes back a message with 'Hello' prefix",
7
7
  "inputSchema": {
8
- "$schema": "http://json-schema.org/draft-07/schema#",
9
- "additionalProperties": false,
10
8
  "properties": {
11
9
  "message": {
12
10
  "description": "The message to echo",
@@ -23,8 +21,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
23
21
  {
24
22
  "description": "Lists all available tools and methods",
25
23
  "inputSchema": {
26
- "$schema": "http://json-schema.org/draft-07/schema#",
27
- "additionalProperties": false,
28
24
  "properties": {},
29
25
  "type": "object",
30
26
  },
@@ -33,8 +29,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
33
29
  {
34
30
  "description": "Adds two numbers",
35
31
  "inputSchema": {
36
- "$schema": "http://json-schema.org/draft-07/schema#",
37
- "additionalProperties": false,
38
32
  "properties": {
39
33
  "a": {
40
34
  "description": "The first number",
@@ -414,6 +414,8 @@ export default {
414
414
  manualDesc: '每次调用都需要手动批准',
415
415
  },
416
416
  reject: '拒绝',
417
+ rejectAndContinue: '拒绝后重试执行',
418
+ rejectOnly: '拒绝',
417
419
  rejectReasonPlaceholder: '输入拒绝原因将帮助 Agent 理解并优化后续行动',
418
420
  rejectTitle: '拒绝本次工具调用',
419
421
  rejectedWithReason: '本次工具调用被主动拒绝:{{reason}}',
@@ -260,7 +260,7 @@ export default {
260
260
  searchLocalFiles: '搜索文件',
261
261
  writeLocalFile: '写入文件',
262
262
  },
263
- title: '本地文件',
263
+ title: '本地系统',
264
264
  },
265
265
  mcpInstall: {
266
266
  CHECKING_INSTALLATION: '检查安装环境...',
@@ -1004,6 +1004,7 @@ describe('ChatService', () => {
1004
1004
  stream: true,
1005
1005
  ...DEFAULT_AGENT_CONFIG.params,
1006
1006
  ...params,
1007
+ apiMode: 'responses',
1007
1008
  };
1008
1009
 
1009
1010
  await chatService.getChatCompletion(params, options);
@@ -174,6 +174,13 @@ class ChatService {
174
174
  extendParams.reasoning_effort = chatConfig.gpt5ReasoningEffort;
175
175
  }
176
176
 
177
+ if (
178
+ modelExtendParams!.includes('gpt5_1ReasoningEffort') &&
179
+ chatConfig.gpt5_1ReasoningEffort
180
+ ) {
181
+ extendParams.reasoning_effort = chatConfig.gpt5_1ReasoningEffort;
182
+ }
183
+
177
184
  if (modelExtendParams!.includes('textVerbosity') && chatConfig.textVerbosity) {
178
185
  extendParams.verbosity = chatConfig.textVerbosity;
179
186
  }
@@ -246,4 +246,66 @@ describe('aiProviderSelectors', () => {
246
246
  );
247
247
  });
248
248
  });
249
+
250
+ describe('isProviderEnableResponseApi', () => {
251
+ it('should return true when config explicitly sets enableResponseApi to true', () => {
252
+ const state = {
253
+ ...mockState,
254
+ aiProviderRuntimeConfig: {
255
+ test: {
256
+ config: { enableResponseApi: true },
257
+ keyVaults: {},
258
+ settings: {},
259
+ },
260
+ },
261
+ };
262
+ expect(aiProviderSelectors.isProviderEnableResponseApi('test')(state)).toBe(true);
263
+ });
264
+
265
+ it('should return false when config explicitly sets enableResponseApi to false', () => {
266
+ const state = {
267
+ ...mockState,
268
+ aiProviderRuntimeConfig: {
269
+ test: {
270
+ config: { enableResponseApi: false },
271
+ keyVaults: {},
272
+ settings: {},
273
+ },
274
+ },
275
+ };
276
+ expect(aiProviderSelectors.isProviderEnableResponseApi('test')(state)).toBe(false);
277
+ });
278
+
279
+ it('should return true by default for openai provider', () => {
280
+ const state = {
281
+ ...mockState,
282
+ aiProviderRuntimeConfig: {
283
+ openai: {
284
+ keyVaults: {},
285
+ settings: {},
286
+ },
287
+ },
288
+ };
289
+ expect(aiProviderSelectors.isProviderEnableResponseApi('openai')(state)).toBe(true);
290
+ });
291
+
292
+ it('should return false by default for non-openai provider', () => {
293
+ const state = {
294
+ ...mockState,
295
+ aiProviderRuntimeConfig: {
296
+ anthropic: {
297
+ keyVaults: {},
298
+ settings: {},
299
+ },
300
+ },
301
+ };
302
+ expect(aiProviderSelectors.isProviderEnableResponseApi('anthropic')(state)).toBe(false);
303
+ });
304
+
305
+ it('should return false for provider without config', () => {
306
+ expect(aiProviderSelectors.isProviderEnableResponseApi('non-existing')(mockState)).toBe(
307
+ false,
308
+ );
309
+ });
310
+ });
249
311
  });
@@ -108,7 +108,7 @@ const isProviderEnableResponseApi = (id: string) => (s: AIProviderStoreState) =>
108
108
 
109
109
  if (typeof enableResponseApi === 'boolean') return enableResponseApi;
110
110
 
111
- return false;
111
+ return id === 'openai';
112
112
  };
113
113
 
114
114
  const isInitAiProviderRuntimeState = (s: AIProviderStoreState) => !!s.isInitAiProviderRuntimeState;
@@ -43,6 +43,10 @@ export interface ConversationControlAction {
43
43
  * Reject tool intervention
44
44
  */
45
45
  rejectToolCalling: (messageId: string, reason?: string) => Promise<void>;
46
+ /**
47
+ * Reject tool intervention and continue
48
+ */
49
+ rejectAndContinueToolCalling: (messageId: string, reason?: string) => Promise<void>;
46
50
  /**
47
51
  * Toggle sendMessage operation state
48
52
  */
@@ -206,6 +210,44 @@ export const conversationControl: StateCreator<
206
210
  await get().optimisticUpdateMessageContent(messageId, toolContent);
207
211
  },
208
212
 
213
+ rejectAndContinueToolCalling: async (messageId, reason) => {
214
+ await get().rejectToolCalling(messageId, reason);
215
+
216
+ const toolMessage = dbMessageSelectors.getDbMessageById(messageId)(get());
217
+ if (!toolMessage) return;
218
+
219
+ // Get current messages for state construction
220
+ const currentMessages = displayMessageSelectors.mainAIChats(get());
221
+ const { activeThreadId, internal_execAgentRuntime } = get();
222
+
223
+ // Create agent state and context to continue from rejected tool message
224
+ const { state, context: initialContext } = get().internal_createAgentState({
225
+ messages: currentMessages,
226
+ parentMessageId: messageId,
227
+ threadId: activeThreadId,
228
+ });
229
+
230
+ // Override context with 'userInput' phase to continue as if user provided feedback
231
+ const context: AgentRuntimeContext = {
232
+ ...initialContext,
233
+ phase: 'user_input',
234
+ };
235
+
236
+ // Execute agent runtime from rejected tool message position to continue
237
+ try {
238
+ await internal_execAgentRuntime({
239
+ messages: currentMessages,
240
+ parentMessageId: messageId,
241
+ parentMessageType: 'tool',
242
+ threadId: activeThreadId,
243
+ initialState: state,
244
+ initialContext: context,
245
+ });
246
+ } catch (error) {
247
+ console.error('[rejectAndContinueToolCalling] Error executing agent runtime:', error);
248
+ }
249
+ },
250
+
209
251
  internal_updateSendMessageOperation: (key, value, actionName) => {
210
252
  const operationKey = typeof key === 'string' ? key : messageMapKey(key.sessionId, key.topicId);
211
253
 
@@ -17,7 +17,7 @@ import { chatToolSelectors } from '@/store/chat/slices/builtinTool/selectors';
17
17
  import ResultFileGallery from './components/ResultFileGallery';
18
18
 
19
19
  const CodeInterpreter = memo<
20
- BuiltinRenderProps<CodeInterpreterResponse, CodeInterpreterParams, CodeInterpreterState>
20
+ BuiltinRenderProps<CodeInterpreterParams, CodeInterpreterState, CodeInterpreterResponse>
21
21
  >(({ content, args, pluginState, messageId, apiName }) => {
22
22
  const { t } = useTranslation('tool');
23
23
  const theme = useTheme();
@@ -1,8 +1,32 @@
1
1
  import { BuiltinIntervention } from '@lobechat/types';
2
2
 
3
- import { LocalSystemManifest } from './local-system';
4
- import LocalSystem from './local-system/Intervention';
3
+ import { LocalSystemApiName, LocalSystemManifest } from './local-system';
4
+ import RunCommand from './local-system/Intervention/RunCommand';
5
5
 
6
- export const BuiltinToolInterventions: Record<string, BuiltinIntervention> = {
7
- [LocalSystemManifest.identifier]: LocalSystem as BuiltinIntervention,
6
+ /**
7
+ * Builtin tools interventions registry
8
+ * Organized by toolset (identifier) -> API name
9
+ * Only register APIs that have custom intervention UI
10
+ */
11
+ export const BuiltinToolInterventions: Record<string, Record<string, any>> = {
12
+ [LocalSystemManifest.identifier]: {
13
+ [LocalSystemApiName.runCommand]: RunCommand,
14
+ },
15
+ };
16
+
17
+ /**
18
+ * Get builtin intervention component for a specific API
19
+ * @param identifier - Tool identifier (e.g., 'lobe-local-system')
20
+ * @param apiName - API name (e.g., 'runCommand')
21
+ */
22
+ export const getBuiltinIntervention = (
23
+ identifier?: string,
24
+ apiName?: string,
25
+ ): BuiltinIntervention | undefined => {
26
+ if (!identifier || !apiName) return undefined;
27
+
28
+ const toolset = BuiltinToolInterventions[identifier];
29
+ if (!toolset) return undefined;
30
+
31
+ return toolset[apiName];
8
32
  };
@@ -3,6 +3,8 @@ import { Highlighter, Text } from '@lobehub/ui';
3
3
  import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
6
+ import { BuiltinInterventionProps } from '@/types/tool';
7
+
6
8
  const formatTimeout = (ms?: number) => {
7
9
  if (!ms) return null;
8
10
 
@@ -23,11 +25,8 @@ const formatTimeout = (ms?: number) => {
23
25
  return `${ms}ms`;
24
26
  };
25
27
 
26
- interface RunCommandProps extends RunCommandParams {
27
- messageId: string;
28
- }
29
-
30
- const RunCommand = memo<RunCommandProps>(({ description, command, timeout }) => {
28
+ const RunCommand = memo<BuiltinInterventionProps<RunCommandParams>>(({ args }) => {
29
+ const { description, command, timeout } = args;
31
30
  return (
32
31
  <Flexbox gap={8}>
33
32
  <Flexbox horizontal justify={'space-between'}>
@@ -1,17 +1,15 @@
1
1
  import { ListLocalFileParams } from '@lobechat/electron-client-ipc';
2
+ import { BuiltinPlaceholderProps } from '@lobechat/types';
2
3
  import { Skeleton } from 'antd';
3
4
  import React, { memo } from 'react';
4
5
  import { Center, Flexbox } from 'react-layout-kit';
5
6
 
6
7
  import { LocalFolder } from '@/features/LocalFile';
7
8
 
8
- interface ListFilesProps {
9
- args: ListLocalFileParams;
10
- }
11
- export const ListFiles = memo<ListFilesProps>(({ args }) => {
9
+ export const ListFiles = memo<BuiltinPlaceholderProps<ListLocalFileParams>>(({ args }) => {
12
10
  return (
13
11
  <Flexbox gap={12}>
14
- <LocalFolder path={args.path} />
12
+ {args?.path && <LocalFolder path={args.path} />}
15
13
  <Center height={140}>
16
14
  <Flexbox gap={4} width={'90%'}>
17
15
  <Skeleton.Button active block style={{ height: 16 }} />
@@ -1,4 +1,5 @@
1
1
  import { LocalSearchFilesParams } from '@lobechat/electron-client-ipc';
2
+ import { BuiltinPlaceholderProps } from '@lobechat/types';
2
3
  import { Icon } from '@lobehub/ui';
3
4
  import { Skeleton } from 'antd';
4
5
  import { createStyles } from 'antd-style';
@@ -21,11 +22,7 @@ const useStyles = createStyles(({ css, token, cx }) => ({
21
22
  `),
22
23
  }));
23
24
 
24
- interface SearchFilesProps {
25
- args: LocalSearchFilesParams;
26
- }
27
-
28
- const SearchFiles = memo<SearchFilesProps>(({ args }) => {
25
+ const SearchFiles = memo<BuiltinPlaceholderProps<LocalSearchFilesParams>>(({ args = {} }) => {
29
26
  const { styles } = useStyles();
30
27
 
31
28
  return (
@@ -1,31 +1,26 @@
1
1
  import { ListLocalFileParams } from '@lobechat/electron-client-ipc';
2
- import { ChatMessagePluginError } from '@lobechat/types';
2
+ import { BuiltinRenderProps } from '@lobechat/types';
3
3
  import React, { memo } from 'react';
4
4
 
5
5
  import { LocalFolder } from '@/features/LocalFile';
6
- import { LocalFileListState } from '@/tools/local-system/type';
7
6
 
7
+ import { LocalFileListState } from '../../type';
8
8
  import SearchResult from './Result';
9
9
 
10
- interface ListFilesProps {
11
- args: ListLocalFileParams;
12
- messageId: string;
13
- pluginError: ChatMessagePluginError;
14
- pluginState?: LocalFileListState;
15
- }
16
-
17
- const ListFiles = memo<ListFilesProps>(({ messageId, pluginError, args, pluginState }) => {
18
- return (
19
- <>
20
- <LocalFolder path={args.path} />
21
- <SearchResult
22
- listResults={pluginState?.listResults}
23
- messageId={messageId}
24
- pluginError={pluginError}
25
- />
26
- </>
27
- );
28
- });
10
+ const ListFiles = memo<BuiltinRenderProps<ListLocalFileParams, LocalFileListState>>(
11
+ ({ messageId, pluginError, args, pluginState }) => {
12
+ return (
13
+ <>
14
+ <LocalFolder path={args.path} />
15
+ <SearchResult
16
+ listResults={pluginState?.listResults}
17
+ messageId={messageId}
18
+ pluginError={pluginError}
19
+ />
20
+ </>
21
+ );
22
+ },
23
+ );
29
24
 
30
25
  ListFiles.displayName = 'ListFiles';
31
26
 
@@ -26,9 +26,10 @@ const useStyles = createStyles(({ css, token, cx }) => ({
26
26
 
27
27
  height: 64px;
28
28
  padding: 8px;
29
- border: 1px solid ${token.colorBorderSecondary};
30
29
  border-radius: ${token.borderRadiusLG}px;
31
30
 
31
+ background: ${token.colorFillQuaternary};
32
+
32
33
  transition: all 0.2s ${token.motionEaseInOut};
33
34
 
34
35
  .local-file-actions {
@@ -1,5 +1,5 @@
1
1
  import { RenameLocalFileParams } from '@lobechat/electron-client-ipc';
2
- import { ChatMessagePluginError } from '@lobechat/types';
2
+ import { BuiltinRenderProps } from '@lobechat/types';
3
3
  import { Icon } from '@lobehub/ui';
4
4
  import { createStyles } from 'antd-style';
5
5
  import { ArrowRightIcon } from 'lucide-react';
@@ -19,27 +19,22 @@ const useStyles = createStyles(({ css, token }) => ({
19
19
  `,
20
20
  }));
21
21
 
22
- interface RenameLocalFileProps {
23
- args: RenameLocalFileParams;
24
- messageId: string;
25
- pluginError: ChatMessagePluginError;
26
- pluginState: LocalReadFileState;
27
- }
22
+ const RenameLocalFile = memo<BuiltinRenderProps<RenameLocalFileParams, LocalReadFileState>>(
23
+ ({ args }) => {
24
+ const { styles } = useStyles();
28
25
 
29
- const RenameLocalFile = memo<RenameLocalFileProps>(({ args }) => {
30
- const { styles } = useStyles();
26
+ const { base: oldFileName, dir } = path.parse(args.path);
31
27
 
32
- const { base: oldFileName, dir } = path.parse(args.path);
33
-
34
- return (
35
- <Flexbox align={'center'} className={styles.container} gap={8} horizontal paddingInline={12}>
36
- <Flexbox>{oldFileName}</Flexbox>
37
- <Flexbox>
38
- <Icon icon={ArrowRightIcon} />
28
+ return (
29
+ <Flexbox align={'center'} className={styles.container} gap={8} horizontal paddingInline={12}>
30
+ <Flexbox>{oldFileName}</Flexbox>
31
+ <Flexbox>
32
+ <Icon icon={ArrowRightIcon} />
33
+ </Flexbox>
34
+ <LocalFile name={args.newName} path={path.join(dir, args.newName)} />
39
35
  </Flexbox>
40
- <LocalFile name={args.newName} path={path.join(dir, args.newName)} />
41
- </Flexbox>
42
- );
43
- });
36
+ );
37
+ },
38
+ );
44
39
 
45
40
  export default RenameLocalFile;