@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.
- package/CHANGELOG.md +50 -0
- package/apps/desktop/src/main/controllers/LocalFileCtr.ts +25 -5
- package/apps/desktop/src/main/controllers/ShellCommandCtr.ts +242 -0
- package/apps/desktop/src/main/controllers/__tests__/LocalFileCtr.test.ts +4 -1
- package/apps/desktop/src/main/controllers/__tests__/ShellCommandCtr.test.ts +499 -0
- package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +357 -0
- package/apps/desktop/src/main/modules/fileSearch/impl/macOS.ts +30 -22
- package/changelog/v1.json +18 -0
- package/locales/ar/chat.json +20 -0
- package/locales/ar/common.json +1 -0
- package/locales/ar/components.json +6 -0
- package/locales/ar/models.json +119 -126
- package/locales/ar/plugin.json +2 -1
- package/locales/bg-BG/chat.json +20 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/components.json +6 -0
- package/locales/bg-BG/models.json +104 -132
- package/locales/bg-BG/plugin.json +2 -1
- package/locales/de-DE/chat.json +20 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/components.json +6 -0
- package/locales/de-DE/models.json +119 -126
- package/locales/de-DE/plugin.json +2 -1
- package/locales/en-US/chat.json +20 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/components.json +6 -0
- package/locales/en-US/models.json +167 -126
- package/locales/en-US/plugin.json +2 -1
- package/locales/es-ES/chat.json +20 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/components.json +6 -0
- package/locales/es-ES/models.json +119 -126
- package/locales/es-ES/plugin.json +2 -1
- package/locales/fa-IR/chat.json +20 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/components.json +6 -0
- package/locales/fa-IR/models.json +119 -126
- package/locales/fa-IR/plugin.json +2 -1
- package/locales/fr-FR/chat.json +20 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/components.json +6 -0
- package/locales/fr-FR/models.json +119 -126
- package/locales/fr-FR/plugin.json +2 -1
- package/locales/it-IT/chat.json +20 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/components.json +6 -0
- package/locales/it-IT/models.json +119 -126
- package/locales/it-IT/plugin.json +2 -1
- package/locales/ja-JP/chat.json +20 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/components.json +6 -0
- package/locales/ja-JP/models.json +119 -126
- package/locales/ja-JP/plugin.json +2 -1
- package/locales/ko-KR/chat.json +20 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/components.json +6 -0
- package/locales/ko-KR/models.json +119 -126
- package/locales/ko-KR/plugin.json +2 -1
- package/locales/nl-NL/chat.json +20 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/components.json +6 -0
- package/locales/nl-NL/models.json +119 -126
- package/locales/nl-NL/plugin.json +2 -1
- package/locales/pl-PL/chat.json +20 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/components.json +6 -0
- package/locales/pl-PL/models.json +119 -126
- package/locales/pl-PL/plugin.json +2 -1
- package/locales/pt-BR/chat.json +20 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/components.json +6 -0
- package/locales/pt-BR/models.json +119 -126
- package/locales/pt-BR/plugin.json +2 -1
- package/locales/ru-RU/chat.json +20 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/components.json +6 -0
- package/locales/ru-RU/models.json +119 -126
- package/locales/ru-RU/plugin.json +2 -1
- package/locales/tr-TR/chat.json +20 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/components.json +6 -0
- package/locales/tr-TR/models.json +119 -126
- package/locales/tr-TR/plugin.json +2 -1
- package/locales/vi-VN/chat.json +20 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/components.json +6 -0
- package/locales/vi-VN/models.json +119 -126
- package/locales/vi-VN/plugin.json +2 -1
- package/locales/zh-CN/chat.json +20 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/components.json +6 -0
- package/locales/zh-CN/models.json +173 -80
- package/locales/zh-CN/plugin.json +2 -1
- package/locales/zh-TW/chat.json +20 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/components.json +6 -0
- package/locales/zh-TW/models.json +119 -126
- package/locales/zh-TW/plugin.json +2 -1
- package/package.json +1 -1
- package/packages/agent-runtime/src/core/InterventionChecker.ts +1 -1
- package/packages/agent-runtime/src/core/__tests__/InterventionChecker.test.ts +23 -23
- package/packages/agent-runtime/src/types/state.ts +7 -1
- package/packages/const/src/settings/tool.ts +1 -5
- package/packages/electron-client-ipc/src/types/localSystem.ts +26 -2
- package/packages/file-loaders/src/loaders/docx/index.ts +1 -1
- package/packages/model-bank/src/aiModels/wenxin.ts +1348 -291
- package/packages/model-runtime/src/core/contextBuilders/openai.test.ts +58 -0
- package/packages/model-runtime/src/core/contextBuilders/openai.ts +24 -10
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +3 -2
- package/packages/model-runtime/src/providers/openai/index.test.ts +44 -0
- package/packages/model-runtime/src/providers/wenxin/index.ts +22 -1
- package/packages/model-runtime/src/utils/modelParse.ts +6 -0
- package/packages/types/src/tool/builtin.ts +15 -4
- package/packages/types/src/tool/intervention.ts +32 -2
- package/packages/types/src/user/settings/tool.ts +3 -27
- package/src/config/modelProviders/wenxin.ts +2 -3
- package/src/features/Conversation/MarkdownElements/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +133 -0
- package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +48 -0
- package/src/features/Conversation/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +2 -1
- package/src/features/Conversation/Messages/Assistant/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/Fallback.tsx +98 -0
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ModeSelector.tsx +5 -6
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/index.tsx +40 -36
- package/src/features/Conversation/Messages/Group/Tool/Render/LoadingPlaceholder/index.tsx +3 -3
- package/src/features/Conversation/Messages/Group/Tool/Render/index.tsx +25 -18
- package/src/features/LocalFile/LocalFile.tsx +55 -5
- package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +10 -4
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +2 -2
- package/src/locales/default/components.ts +6 -0
- package/src/locales/default/plugin.ts +2 -1
- package/src/services/chat/chat.test.ts +1 -0
- package/src/services/electron/localFileService.ts +4 -0
- package/src/store/aiInfra/slices/aiProvider/__tests__/selectors.test.ts +62 -0
- package/src/store/aiInfra/slices/aiProvider/selectors.ts +1 -1
- package/src/store/chat/agents/GeneralChatAgent.ts +26 -1
- package/src/store/chat/agents/__tests__/GeneralChatAgent.test.ts +173 -0
- package/src/store/chat/slices/aiChat/actions/conversationControl.ts +8 -40
- package/src/store/chat/slices/aiChat/actions/streamingExecutor.ts +91 -34
- package/src/store/user/selectors.ts +1 -0
- package/src/store/user/slices/settings/action.ts +12 -0
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +0 -7
- package/src/store/user/slices/settings/selectors/index.ts +1 -0
- package/src/store/user/slices/settings/selectors/settings.test.ts +0 -37
- package/src/store/user/slices/settings/selectors/settings.ts +0 -5
- package/src/store/user/slices/settings/selectors/toolIntervention.ts +17 -0
- package/src/tools/code-interpreter/Render/index.tsx +1 -1
- package/src/tools/interventions.ts +32 -0
- package/src/tools/local-system/Intervention/RunCommand/index.tsx +56 -0
- package/src/tools/local-system/Placeholder/ListFiles.tsx +3 -5
- package/src/tools/local-system/Placeholder/SearchFiles.tsx +2 -5
- package/src/tools/local-system/Render/ListFiles/index.tsx +16 -21
- package/src/tools/local-system/Render/RenameLocalFile/index.tsx +15 -20
- package/src/tools/local-system/Render/RunCommand/index.tsx +103 -27
- package/src/tools/local-system/Render/SearchFiles/SearchQuery/index.tsx +0 -1
- package/src/tools/local-system/Render/SearchFiles/index.tsx +15 -20
- package/src/tools/local-system/Render/WriteFile/index.tsx +2 -8
- package/src/tools/local-system/index.ts +184 -4
- package/src/tools/local-system/systemRole.ts +62 -8
- package/src/tools/placeholders.ts +39 -8
- package/src/tools/renders.ts +56 -9
- package/src/tools/web-browsing/Placeholder/{PageContent.tsx → CrawlMultiPages.tsx} +4 -1
- package/src/tools/web-browsing/Placeholder/CrawlSinglePage.tsx +12 -0
- package/src/tools/web-browsing/Placeholder/Search.tsx +4 -4
- package/src/tools/web-browsing/Render/CrawlMultiPages.tsx +15 -0
- package/src/tools/web-browsing/Render/CrawlSinglePage.tsx +15 -0
- package/src/tools/web-browsing/Render/Search/index.tsx +39 -44
- package/packages/database/migrations/0044_add_tool_intervention.sql +0 -1
- package/src/tools/local-system/Placeholder/index.tsx +0 -25
- package/src/tools/local-system/Render/index.tsx +0 -40
- package/src/tools/web-browsing/Placeholder/index.tsx +0 -40
- package/src/tools/web-browsing/Render/index.tsx +0 -57
|
@@ -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
|
-
|
|
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 {
|
|
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
|
-
|
|
11
|
-
args
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RenameLocalFileParams } from '@lobechat/electron-client-ipc';
|
|
2
|
-
import {
|
|
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
|
-
|
|
23
|
-
args
|
|
24
|
-
|
|
25
|
-
pluginError: ChatMessagePluginError;
|
|
26
|
-
pluginState: LocalReadFileState;
|
|
27
|
-
}
|
|
22
|
+
const RenameLocalFile = memo<BuiltinRenderProps<RenameLocalFileParams, LocalReadFileState>>(
|
|
23
|
+
({ args }) => {
|
|
24
|
+
const { styles } = useStyles();
|
|
28
25
|
|
|
29
|
-
const
|
|
30
|
-
const { styles } = useStyles();
|
|
26
|
+
const { base: oldFileName, dir } = path.parse(args.path);
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<
|
|
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
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
36
|
+
);
|
|
37
|
+
},
|
|
38
|
+
);
|
|
44
39
|
|
|
45
40
|
export default RenameLocalFile;
|
|
@@ -1,35 +1,111 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import '@
|
|
5
|
-
import {
|
|
1
|
+
import { CheckCircleFilled, CloseCircleFilled } from '@ant-design/icons';
|
|
2
|
+
import { RunCommandParams, RunCommandResult } from '@lobechat/electron-client-ipc';
|
|
3
|
+
import { BuiltinRenderProps } from '@lobechat/types';
|
|
4
|
+
import { ActionIcon, Block, Highlighter, Text } from '@lobehub/ui';
|
|
5
|
+
import { createStyles } from 'antd-style';
|
|
6
|
+
import { ChevronDown, ChevronUp } from 'lucide-react';
|
|
7
|
+
import { memo, useState } from 'react';
|
|
8
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
9
|
|
|
7
|
-
|
|
10
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
11
|
+
container: css`
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
padding-inline: 8px 0;
|
|
14
|
+
`,
|
|
15
|
+
head: css`
|
|
16
|
+
font-family: ${token.fontFamilyCode};
|
|
17
|
+
font-size: 12px;
|
|
18
|
+
`,
|
|
19
|
+
header: css`
|
|
20
|
+
.action-icon {
|
|
21
|
+
opacity: 0;
|
|
22
|
+
transition: opacity 0.2s ease;
|
|
23
|
+
}
|
|
8
24
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
25
|
+
&:hover {
|
|
26
|
+
.action-icon {
|
|
27
|
+
opacity: 1;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
statusIcon: css`
|
|
32
|
+
font-size: 12px;
|
|
33
|
+
`,
|
|
34
|
+
}));
|
|
18
35
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
36
|
+
interface RunCommandState {
|
|
37
|
+
message: string;
|
|
38
|
+
result: RunCommandResult;
|
|
39
|
+
}
|
|
23
40
|
|
|
24
|
-
|
|
25
|
-
|
|
41
|
+
const RunCommand = memo<BuiltinRenderProps<RunCommandParams, RunCommandState>>(
|
|
42
|
+
({ args, pluginState }) => {
|
|
43
|
+
const { styles, theme } = useStyles();
|
|
44
|
+
const { result, message } = pluginState || {};
|
|
45
|
+
const isSuccess = result?.success;
|
|
46
|
+
const [expanded, setExpanded] = useState(false);
|
|
26
47
|
|
|
27
|
-
return (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
48
|
+
return (
|
|
49
|
+
<Flexbox className={styles.container} gap={8}>
|
|
50
|
+
{/* Header: Description + Status */}
|
|
51
|
+
<Flexbox align={'center'} className={styles.header} horizontal justify={'space-between'}>
|
|
52
|
+
<Flexbox gap={8} horizontal>
|
|
53
|
+
<Flexbox gap={4} horizontal>
|
|
54
|
+
{!result ? null : isSuccess ? (
|
|
55
|
+
<CheckCircleFilled
|
|
56
|
+
className={styles.statusIcon}
|
|
57
|
+
style={{ color: theme.colorSuccess }}
|
|
58
|
+
/>
|
|
59
|
+
) : (
|
|
60
|
+
<CloseCircleFilled
|
|
61
|
+
className={styles.statusIcon}
|
|
62
|
+
style={{ color: theme.colorError }}
|
|
63
|
+
/>
|
|
64
|
+
)}
|
|
65
|
+
{args.description && <Text className={styles.head}>{args.description}</Text>}
|
|
66
|
+
</Flexbox>
|
|
67
|
+
{message && (
|
|
68
|
+
<Flexbox align={'center'} gap={4} horizontal>
|
|
69
|
+
<Text className={styles.head} type={'secondary'}>
|
|
70
|
+
{message}
|
|
71
|
+
</Text>
|
|
72
|
+
</Flexbox>
|
|
73
|
+
)}
|
|
74
|
+
</Flexbox>
|
|
75
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
76
|
+
<ActionIcon
|
|
77
|
+
className={`action-icon`}
|
|
78
|
+
icon={expanded ? ChevronUp : ChevronDown}
|
|
79
|
+
onClick={() => setExpanded(!expanded)}
|
|
80
|
+
size={'small'}
|
|
81
|
+
style={{ opacity: expanded ? 1 : undefined }}
|
|
82
|
+
title={expanded ? 'Collapse' : 'Expand'}
|
|
83
|
+
/>
|
|
84
|
+
</Flexbox>
|
|
85
|
+
</Flexbox>
|
|
31
86
|
|
|
32
|
-
|
|
33
|
-
|
|
87
|
+
{/* Command & Output */}
|
|
88
|
+
{expanded && (
|
|
89
|
+
<Block gap={8} padding={8} variant={'outlined'}>
|
|
90
|
+
<Highlighter
|
|
91
|
+
language={'sh'}
|
|
92
|
+
showLanguage={false}
|
|
93
|
+
style={{ paddingInline: 8 }}
|
|
94
|
+
variant={'borderless'}
|
|
95
|
+
wrap
|
|
96
|
+
>
|
|
97
|
+
{args.command}
|
|
98
|
+
</Highlighter>
|
|
99
|
+
{result?.output && (
|
|
100
|
+
<Highlighter language={'text'} showLanguage={false} variant={'filled'} wrap>
|
|
101
|
+
{result.output}
|
|
102
|
+
</Highlighter>
|
|
103
|
+
)}
|
|
104
|
+
</Block>
|
|
105
|
+
)}
|
|
106
|
+
</Flexbox>
|
|
107
|
+
);
|
|
108
|
+
},
|
|
109
|
+
);
|
|
34
110
|
|
|
35
111
|
export default RunCommand;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LocalSearchFilesParams } from '@lobechat/electron-client-ipc';
|
|
2
|
-
import {
|
|
2
|
+
import { BuiltinRenderProps } from '@lobechat/types';
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
import { Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
|
@@ -8,25 +8,20 @@ import { LocalFileSearchState } from '@/tools/local-system/type';
|
|
|
8
8
|
import SearchResult from './Result';
|
|
9
9
|
import SearchQuery from './SearchQuery';
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
args
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
searchResults={pluginState?.searchResults}
|
|
26
|
-
/>
|
|
27
|
-
</Flexbox>
|
|
28
|
-
);
|
|
29
|
-
});
|
|
11
|
+
const SearchFiles = memo<BuiltinRenderProps<LocalSearchFilesParams, LocalFileSearchState>>(
|
|
12
|
+
({ messageId, pluginError, args, pluginState }) => {
|
|
13
|
+
return (
|
|
14
|
+
<Flexbox gap={4}>
|
|
15
|
+
<SearchQuery args={args} messageId={messageId} pluginState={pluginState} />
|
|
16
|
+
<SearchResult
|
|
17
|
+
messageId={messageId}
|
|
18
|
+
pluginError={pluginError}
|
|
19
|
+
searchResults={pluginState?.searchResults}
|
|
20
|
+
/>
|
|
21
|
+
</Flexbox>
|
|
22
|
+
);
|
|
23
|
+
},
|
|
24
|
+
);
|
|
30
25
|
|
|
31
26
|
SearchFiles.displayName = 'SearchFiles';
|
|
32
27
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { WriteLocalFileParams } from '@lobechat/electron-client-ipc';
|
|
2
|
-
import {
|
|
2
|
+
import { BuiltinRenderProps } from '@lobechat/types';
|
|
3
3
|
import { Icon } from '@lobehub/ui';
|
|
4
4
|
import { Skeleton } from 'antd';
|
|
5
5
|
import { ChevronRight } from 'lucide-react';
|
|
@@ -9,13 +9,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
9
9
|
|
|
10
10
|
import { LocalFile, LocalFolder } from '@/features/LocalFile';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
args: WriteLocalFileParams;
|
|
14
|
-
messageId: string;
|
|
15
|
-
pluginError: ChatMessagePluginError;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const WriteFile = memo<WriteFileProps>(({ args }) => {
|
|
12
|
+
const WriteFile = memo<BuiltinRenderProps<WriteLocalFileParams>>(({ args }) => {
|
|
19
13
|
if (!args) return <Skeleton active />;
|
|
20
14
|
|
|
21
15
|
const { base, dir } = path.parse(args.path);
|
|
@@ -3,10 +3,16 @@ import { BuiltinToolManifest } from '@lobechat/types';
|
|
|
3
3
|
import { systemPrompt } from './systemRole';
|
|
4
4
|
|
|
5
5
|
export const LocalSystemApiName = {
|
|
6
|
+
editLocalFile: 'editLocalFile',
|
|
7
|
+
getCommandOutput: 'getCommandOutput',
|
|
8
|
+
globLocalFiles: 'globLocalFiles',
|
|
9
|
+
grepContent: 'grepContent',
|
|
10
|
+
killCommand: 'killCommand',
|
|
6
11
|
listLocalFiles: 'listLocalFiles',
|
|
7
12
|
moveLocalFiles: 'moveLocalFiles',
|
|
8
13
|
readLocalFile: 'readLocalFile',
|
|
9
14
|
renameLocalFile: 'renameLocalFile',
|
|
15
|
+
runCommand: 'runCommand',
|
|
10
16
|
searchLocalFiles: 'searchLocalFiles',
|
|
11
17
|
writeLocalFile: 'writeLocalFile',
|
|
12
18
|
};
|
|
@@ -72,6 +78,10 @@ export const LocalSystemManifest: BuiltinToolManifest = {
|
|
|
72
78
|
format: 'date-time',
|
|
73
79
|
type: 'string',
|
|
74
80
|
},
|
|
81
|
+
directory: {
|
|
82
|
+
description: 'Limit the search to this specific directory path',
|
|
83
|
+
type: 'string',
|
|
84
|
+
},
|
|
75
85
|
exclude: {
|
|
76
86
|
description: 'Array of file or directory paths to exclude',
|
|
77
87
|
items: {
|
|
@@ -108,10 +118,6 @@ export const LocalSystemManifest: BuiltinToolManifest = {
|
|
|
108
118
|
format: 'date-time',
|
|
109
119
|
type: 'string',
|
|
110
120
|
},
|
|
111
|
-
onlyIn: {
|
|
112
|
-
description: 'Limit the search to this specific directory path',
|
|
113
|
-
type: 'string',
|
|
114
|
-
},
|
|
115
121
|
sortBy: {
|
|
116
122
|
description: 'Sort results by',
|
|
117
123
|
enum: ['name', 'date', 'size'],
|
|
@@ -130,6 +136,7 @@ export const LocalSystemManifest: BuiltinToolManifest = {
|
|
|
130
136
|
{
|
|
131
137
|
description:
|
|
132
138
|
'Moves or renames multiple files/directories. Input is an array of objects, each containing an oldPath and a newPath.',
|
|
139
|
+
humanIntervention: 'required',
|
|
133
140
|
name: LocalSystemApiName.moveLocalFiles,
|
|
134
141
|
parameters: {
|
|
135
142
|
properties: {
|
|
@@ -195,6 +202,179 @@ export const LocalSystemManifest: BuiltinToolManifest = {
|
|
|
195
202
|
type: 'object',
|
|
196
203
|
},
|
|
197
204
|
},
|
|
205
|
+
{
|
|
206
|
+
description:
|
|
207
|
+
'Execute a shell command and return its output. Supports both synchronous and background execution with timeout control.',
|
|
208
|
+
humanIntervention: 'required',
|
|
209
|
+
name: LocalSystemApiName.runCommand,
|
|
210
|
+
parameters: {
|
|
211
|
+
properties: {
|
|
212
|
+
command: {
|
|
213
|
+
description: 'The shell command to execute',
|
|
214
|
+
type: 'string',
|
|
215
|
+
},
|
|
216
|
+
description: {
|
|
217
|
+
description:
|
|
218
|
+
'Clear description of what this command does (5-10 words, in active voice). Use the same language as the user input.',
|
|
219
|
+
type: 'string',
|
|
220
|
+
},
|
|
221
|
+
run_in_background: {
|
|
222
|
+
description: 'Set to true to run command in background and return shell_id',
|
|
223
|
+
type: 'boolean',
|
|
224
|
+
},
|
|
225
|
+
timeout: {
|
|
226
|
+
description: 'Timeout in milliseconds (default: 120000ms, max: 600000ms)',
|
|
227
|
+
type: 'number',
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
required: ['command'],
|
|
231
|
+
type: 'object',
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
description:
|
|
236
|
+
'Retrieve output from a running or completed background shell command. Returns only new output since the last check.',
|
|
237
|
+
name: LocalSystemApiName.getCommandOutput,
|
|
238
|
+
parameters: {
|
|
239
|
+
properties: {
|
|
240
|
+
filter: {
|
|
241
|
+
description:
|
|
242
|
+
'Optional regex pattern to filter output lines. Only matching lines are returned.',
|
|
243
|
+
type: 'string',
|
|
244
|
+
},
|
|
245
|
+
shell_id: {
|
|
246
|
+
description: 'The ID of the background shell to retrieve output from',
|
|
247
|
+
type: 'string',
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
required: ['shell_id'],
|
|
251
|
+
type: 'object',
|
|
252
|
+
},
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
description: 'Kill a running background shell command by its ID.',
|
|
256
|
+
name: LocalSystemApiName.killCommand,
|
|
257
|
+
parameters: {
|
|
258
|
+
properties: {
|
|
259
|
+
shell_id: {
|
|
260
|
+
description: 'The ID of the background shell to kill',
|
|
261
|
+
type: 'string',
|
|
262
|
+
},
|
|
263
|
+
},
|
|
264
|
+
required: ['shell_id'],
|
|
265
|
+
type: 'object',
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
description:
|
|
270
|
+
'Search for content within files using regex patterns. Supports various output modes and filtering options.',
|
|
271
|
+
name: LocalSystemApiName.grepContent,
|
|
272
|
+
parameters: {
|
|
273
|
+
properties: {
|
|
274
|
+
'-A': {
|
|
275
|
+
description:
|
|
276
|
+
'Number of lines to show after each match (requires output_mode: "content")',
|
|
277
|
+
type: 'number',
|
|
278
|
+
},
|
|
279
|
+
'-B': {
|
|
280
|
+
description:
|
|
281
|
+
'Number of lines to show before each match (requires output_mode: "content")',
|
|
282
|
+
type: 'number',
|
|
283
|
+
},
|
|
284
|
+
'-C': {
|
|
285
|
+
description:
|
|
286
|
+
'Number of lines to show before and after each match (requires output_mode: "content")',
|
|
287
|
+
type: 'number',
|
|
288
|
+
},
|
|
289
|
+
'-i': {
|
|
290
|
+
description: 'Case insensitive search',
|
|
291
|
+
type: 'boolean',
|
|
292
|
+
},
|
|
293
|
+
'-n': {
|
|
294
|
+
description: 'Show line numbers in output (requires output_mode: "content")',
|
|
295
|
+
type: 'boolean',
|
|
296
|
+
},
|
|
297
|
+
'glob': {
|
|
298
|
+
description: 'Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}")',
|
|
299
|
+
type: 'string',
|
|
300
|
+
},
|
|
301
|
+
'head_limit': {
|
|
302
|
+
description: 'Limit output to first N results',
|
|
303
|
+
type: 'number',
|
|
304
|
+
},
|
|
305
|
+
'multiline': {
|
|
306
|
+
description: 'Enable multiline mode where . matches newlines',
|
|
307
|
+
type: 'boolean',
|
|
308
|
+
},
|
|
309
|
+
'output_mode': {
|
|
310
|
+
description:
|
|
311
|
+
'Output mode: "content" (matching lines), "files_with_matches" (file paths), "count" (match counts)',
|
|
312
|
+
enum: ['content', 'files_with_matches', 'count'],
|
|
313
|
+
type: 'string',
|
|
314
|
+
},
|
|
315
|
+
'path': {
|
|
316
|
+
description: 'File or directory to search in (defaults to current working directory)',
|
|
317
|
+
type: 'string',
|
|
318
|
+
},
|
|
319
|
+
'pattern': {
|
|
320
|
+
description: 'The regular expression pattern to search for',
|
|
321
|
+
type: 'string',
|
|
322
|
+
},
|
|
323
|
+
'type': {
|
|
324
|
+
description: 'File type to search (e.g. "js", "py", "rust")',
|
|
325
|
+
type: 'string',
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
required: ['pattern'],
|
|
329
|
+
type: 'object',
|
|
330
|
+
},
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
description:
|
|
334
|
+
'Find files matching glob patterns. Supports standard glob syntax like "**/*.js" or "src/**/*.ts".',
|
|
335
|
+
name: LocalSystemApiName.globLocalFiles,
|
|
336
|
+
parameters: {
|
|
337
|
+
properties: {
|
|
338
|
+
path: {
|
|
339
|
+
description: 'The directory to search in (defaults to current working directory)',
|
|
340
|
+
type: 'string',
|
|
341
|
+
},
|
|
342
|
+
pattern: {
|
|
343
|
+
description: 'The glob pattern to match files against (e.g. "**/*.js", "*.{ts,tsx}")',
|
|
344
|
+
type: 'string',
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
required: ['pattern'],
|
|
348
|
+
type: 'object',
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
description:
|
|
353
|
+
'Perform exact string replacements in files. Must read the file first before editing.',
|
|
354
|
+
name: LocalSystemApiName.editLocalFile,
|
|
355
|
+
parameters: {
|
|
356
|
+
properties: {
|
|
357
|
+
file_path: {
|
|
358
|
+
description: 'The absolute path to the file to modify',
|
|
359
|
+
type: 'string',
|
|
360
|
+
},
|
|
361
|
+
new_string: {
|
|
362
|
+
description: 'The text to replace with (must differ from old_string)',
|
|
363
|
+
type: 'string',
|
|
364
|
+
},
|
|
365
|
+
old_string: {
|
|
366
|
+
description: 'The exact text to replace',
|
|
367
|
+
type: 'string',
|
|
368
|
+
},
|
|
369
|
+
replace_all: {
|
|
370
|
+
description: 'Replace all occurrences of old_string (default: false)',
|
|
371
|
+
type: 'boolean',
|
|
372
|
+
},
|
|
373
|
+
},
|
|
374
|
+
required: ['file_path', 'old_string', 'new_string'],
|
|
375
|
+
type: 'object',
|
|
376
|
+
},
|
|
377
|
+
},
|
|
198
378
|
],
|
|
199
379
|
identifier: 'lobe-local-system',
|
|
200
380
|
meta: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const systemPrompt = `You have a Local System tool with capabilities to interact with the user's local
|
|
1
|
+
export const systemPrompt = `You have a Local System tool with capabilities to interact with the user's local system. You can list directories, read file contents, search for files, move, and rename files/directories.
|
|
2
2
|
|
|
3
3
|
<user_context>
|
|
4
4
|
Here are some known locations and system details on the user's system. User is using the Operating System: {{platform}}({{arch}}). Use these paths when the user refers to these common locations by name (e.g., "my desktop", "downloads folder").
|
|
@@ -15,19 +15,33 @@ Here are some known locations and system details on the user's system. User is u
|
|
|
15
15
|
<core_capabilities>
|
|
16
16
|
You have access to a set of tools to interact with the user's local file system:
|
|
17
17
|
|
|
18
|
+
**File Operations:**
|
|
18
19
|
1. **listLocalFiles**: Lists files and directories in a specified path.
|
|
19
20
|
2. **readLocalFile**: Reads the content of a specified file, optionally within a line range. You can read file types such as Word, Excel, PowerPoint, PDF, and plain text files.
|
|
20
|
-
3. **
|
|
21
|
-
4. **searchLocalFiles**: Searches for files based on keywords and other criteria. Use this tool to find files if the user is unsure about the exact path.
|
|
21
|
+
3. **writeLocalFile**: Write content to a specific file, only support plain text file like \`.text\` or \`.md\`
|
|
22
|
+
4. **searchLocalFiles**: Searches for files based on keywords and other criteria using Spotlight (macOS) or native search. Use this tool to find files if the user is unsure about the exact path.
|
|
22
23
|
5. **renameLocalFile**: Renames a single file or directory in its current location.
|
|
23
24
|
6. **moveLocalFiles**: Moves multiple files or directories. Can be used for renaming during the move.
|
|
25
|
+
7. **editLocalFile**: Performs exact string replacements in files. Must read the file first before editing.
|
|
26
|
+
|
|
27
|
+
**Shell Commands:**
|
|
28
|
+
8. **runCommand**: Execute shell commands with timeout control. Supports both synchronous and background execution. When providing a description, always use the same language as the user's input.
|
|
29
|
+
9. **getCommandOutput**: Retrieve output from running background commands. Returns only new output since last check.
|
|
30
|
+
10. **killCommand**: Terminate a running background shell command by its ID.
|
|
31
|
+
|
|
32
|
+
**Search & Find:**
|
|
33
|
+
11. **grepContent**: Search for content within files using regex patterns. Supports various output modes, filtering, and context lines.
|
|
34
|
+
12. **globLocalFiles**: Find files matching glob patterns (e.g., "**/*.js", "*.{ts,tsx}").
|
|
24
35
|
</core_capabilities>
|
|
25
36
|
|
|
26
37
|
<workflow>
|
|
27
|
-
1. Understand the user's request regarding local
|
|
28
|
-
2. Select the appropriate tool
|
|
29
|
-
|
|
30
|
-
|
|
38
|
+
1. Understand the user's request regarding local operations (files, commands, searches).
|
|
39
|
+
2. Select the appropriate tool:
|
|
40
|
+
- File operations: listLocalFiles, readLocalFile, writeLocalFile, editLocalFile, searchLocalFiles, renameLocalFile, moveLocalFiles
|
|
41
|
+
- Shell commands: runCommand, getCommandOutput, killCommand
|
|
42
|
+
- Search/Find: grepContent, globLocalFiles
|
|
43
|
+
3. Execute the operation. **If the user mentions a common location (like Desktop, Documents, Downloads, etc.) without providing a full path, use the corresponding path from the <user_context> section.**
|
|
44
|
+
4. Present the results or confirmation.
|
|
31
45
|
</workflow>
|
|
32
46
|
|
|
33
47
|
<tool_usage_guidelines>
|
|
@@ -54,7 +68,37 @@ You have access to a set of tools to interact with the user's local file system:
|
|
|
54
68
|
- 'oldPath': The current absolute path of the file/directory to move or rename.
|
|
55
69
|
- 'newPath': The target absolute path for the file/directory (can include a new name).
|
|
56
70
|
Example: items: [{ oldPath: "/path/to/file1.txt", newPath: "/new/path/to/fileA.txt" }, { oldPath: "/path/to/folderB", newPath: "/archive/folderB_renamed" }]
|
|
57
|
-
- For writing to a file: Use '
|
|
71
|
+
- For writing to a file: Use 'writeLocalFile' with the file path and the content to be written. Be cautious as this might overwrite existing files.
|
|
72
|
+
- For editing a file: Use 'editLocalFile'. Provide the following parameters:
|
|
73
|
+
- 'file_path': The absolute path to the file to modify.
|
|
74
|
+
- 'old_string': The exact text to replace.
|
|
75
|
+
- 'new_string': The text to replace with.
|
|
76
|
+
- 'replace_all' (Optional): Set to true to replace all occurrences (default: false, replaces only first occurrence).
|
|
77
|
+
Note: You MUST read the file first using 'readLocalFile' before editing to verify the content.
|
|
78
|
+
- For executing shell commands: Use 'runCommand'. Provide the following parameters:
|
|
79
|
+
- 'command': The shell command to execute.
|
|
80
|
+
- 'description' (Optional but recommended): A clear, concise description of what the command does (5-10 words, in active voice). **IMPORTANT: Always use the same language as the user's input.** If the user speaks Chinese, write the description in Chinese; if English, use English, etc.
|
|
81
|
+
- 'run_in_background' (Optional): Set to true to run in background and get a shell_id for later checking output.
|
|
82
|
+
- 'timeout' (Optional): Timeout in milliseconds (default: 120000ms, max: 600000ms).
|
|
83
|
+
The command runs in cmd.exe on Windows or /bin/sh on macOS/Linux.
|
|
84
|
+
- For retrieving output from background commands: Use 'getCommandOutput'. Provide:
|
|
85
|
+
- 'shell_id': The ID returned from runCommand when run_in_background was true.
|
|
86
|
+
- 'filter' (Optional): A regex pattern to filter output lines.
|
|
87
|
+
Returns only new output since the last check.
|
|
88
|
+
- For killing background commands: Use 'killCommand' with 'shell_id'.
|
|
89
|
+
- For searching content in files: Use 'grepContent'. Provide:
|
|
90
|
+
- 'pattern': The regex pattern to search for.
|
|
91
|
+
- 'path' (Optional): File or directory to search (defaults to current working directory).
|
|
92
|
+
- 'output_mode' (Optional): "content" (matching lines), "files_with_matches" (file paths, default), "count" (match counts).
|
|
93
|
+
- 'glob' (Optional): Glob pattern to filter files (e.g., "*.js", "*.{ts,tsx}").
|
|
94
|
+
- '-i' (Optional): Case insensitive search.
|
|
95
|
+
- '-n' (Optional): Show line numbers (requires output_mode: "content").
|
|
96
|
+
- '-A/-B/-C' (Optional): Show N lines after/before/around matches (requires output_mode: "content").
|
|
97
|
+
- 'head_limit' (Optional): Limit results to first N matches.
|
|
98
|
+
- For finding files by pattern: Use 'globLocalFiles'. Provide:
|
|
99
|
+
- 'pattern': Glob pattern (e.g., "**/*.js", "src/**/*.ts").
|
|
100
|
+
- 'path' (Optional): Directory to search in (defaults to current working directory).
|
|
101
|
+
Returns files sorted by modification time (most recent first).
|
|
58
102
|
</tool_usage_guidelines>
|
|
59
103
|
|
|
60
104
|
<security_considerations>
|
|
@@ -62,6 +106,16 @@ You have access to a set of tools to interact with the user's local file system:
|
|
|
62
106
|
- Confirm with the user before moving files to significantly different locations or when renaming might cause confusion or potential data loss if the target exists (though the tool should handle this).
|
|
63
107
|
- Do not attempt to access files outside the user's designated workspace or allowed directories unless explicitly permitted.
|
|
64
108
|
- Handle file paths carefully to avoid unintended access or errors.
|
|
109
|
+
- When running shell commands:
|
|
110
|
+
- Never execute commands that could harm the system or delete important data without explicit user confirmation.
|
|
111
|
+
- Be cautious with commands that have side effects (e.g., rm, sudo, format).
|
|
112
|
+
- Always describe what a command will do before running it, especially for non-trivial operations.
|
|
113
|
+
- Always provide a clear 'description' parameter in the user's language to help them understand what the command does.
|
|
114
|
+
- Use appropriate timeouts to prevent commands from running indefinitely.
|
|
115
|
+
- When editing files:
|
|
116
|
+
- Always read the file first to verify its current content.
|
|
117
|
+
- Ensure old_string exactly matches the text to be replaced to avoid unintended changes.
|
|
118
|
+
- Be cautious when using replace_all option.
|
|
65
119
|
</security_considerations>
|
|
66
120
|
|
|
67
121
|
<response_format>
|