@lobehub/lobehub 2.0.0-next.187 → 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.
- package/CHANGELOG.md +25 -0
- package/changelog/v1.json +9 -0
- package/locales/ar/models.json +89 -5
- package/locales/ar/plugin.json +5 -0
- package/locales/ar/providers.json +1 -0
- package/locales/bg-BG/models.json +68 -0
- package/locales/bg-BG/plugin.json +5 -0
- package/locales/bg-BG/providers.json +1 -0
- package/locales/de-DE/models.json +85 -0
- package/locales/de-DE/plugin.json +5 -0
- package/locales/de-DE/providers.json +1 -0
- package/locales/en-US/models.json +11 -10
- package/locales/en-US/plugin.json +5 -0
- package/locales/en-US/providers.json +1 -0
- package/locales/es-ES/models.json +72 -0
- package/locales/es-ES/plugin.json +5 -0
- package/locales/es-ES/providers.json +1 -0
- package/locales/fa-IR/models.json +86 -0
- package/locales/fa-IR/plugin.json +5 -0
- package/locales/fa-IR/providers.json +1 -0
- package/locales/fr-FR/models.json +49 -0
- package/locales/fr-FR/plugin.json +5 -0
- package/locales/fr-FR/providers.json +1 -0
- package/locales/it-IT/models.json +82 -0
- package/locales/it-IT/plugin.json +5 -0
- package/locales/it-IT/providers.json +1 -0
- package/locales/ja-JP/models.json +42 -5
- package/locales/ja-JP/plugin.json +5 -0
- package/locales/ja-JP/providers.json +1 -0
- package/locales/ko-KR/models.json +54 -0
- package/locales/ko-KR/plugin.json +5 -0
- package/locales/ko-KR/providers.json +1 -0
- package/locales/nl-NL/models.json +12 -1
- package/locales/nl-NL/plugin.json +5 -0
- package/locales/nl-NL/providers.json +1 -0
- package/locales/pl-PL/models.json +46 -0
- package/locales/pl-PL/plugin.json +5 -0
- package/locales/pl-PL/providers.json +1 -0
- package/locales/pt-BR/models.json +59 -0
- package/locales/pt-BR/plugin.json +5 -0
- package/locales/pt-BR/providers.json +1 -0
- package/locales/ru-RU/models.json +85 -0
- package/locales/ru-RU/plugin.json +5 -0
- package/locales/ru-RU/providers.json +1 -0
- package/locales/tr-TR/models.json +81 -0
- package/locales/tr-TR/plugin.json +5 -0
- package/locales/tr-TR/providers.json +1 -0
- package/locales/vi-VN/models.json +54 -0
- package/locales/vi-VN/plugin.json +5 -0
- package/locales/vi-VN/providers.json +1 -0
- package/locales/zh-CN/models.json +42 -5
- package/locales/zh-CN/plugin.json +5 -0
- package/locales/zh-CN/providers.json +1 -0
- package/locales/zh-TW/models.json +85 -0
- package/locales/zh-TW/plugin.json +5 -0
- package/locales/zh-TW/providers.json +1 -0
- package/package.json +1 -1
- package/packages/builtin-tool-gtd/src/manifest.ts +13 -8
- package/packages/builtin-tool-gtd/src/systemRole.ts +54 -19
- package/packages/builtin-tool-knowledge-base/package.json +1 -0
- package/packages/builtin-tool-knowledge-base/src/client/Inspector/ReadKnowledge/index.tsx +97 -0
- package/packages/builtin-tool-knowledge-base/src/client/Inspector/SearchKnowledgeBase/index.tsx +75 -0
- package/packages/builtin-tool-knowledge-base/src/client/Inspector/index.ts +11 -0
- package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/FileCard.tsx +12 -12
- package/packages/builtin-tool-knowledge-base/src/client/Render/ReadKnowledge/index.tsx +16 -25
- package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/Item/index.tsx +21 -47
- package/packages/builtin-tool-knowledge-base/src/client/Render/SearchKnowledgeBase/index.tsx +19 -31
- package/packages/builtin-tool-knowledge-base/src/client/Render/index.ts +0 -5
- package/packages/builtin-tool-knowledge-base/src/client/index.ts +5 -1
- package/packages/builtin-tool-knowledge-base/src/executor/index.ts +119 -0
- package/packages/builtin-tool-local-system/package.json +1 -0
- package/packages/builtin-tool-local-system/src/client/Inspector/EditLocalFile/index.tsx +44 -29
- package/packages/builtin-tool-local-system/src/client/Inspector/GrepContent/index.tsx +20 -18
- package/packages/builtin-tool-local-system/src/client/Inspector/ListLocalFiles/index.tsx +76 -0
- package/packages/builtin-tool-local-system/src/client/Inspector/ReadLocalFile/index.tsx +8 -32
- package/packages/builtin-tool-local-system/src/client/Inspector/RenameLocalFile/index.tsx +62 -0
- package/packages/builtin-tool-local-system/src/client/Inspector/SearchLocalFiles/index.tsx +17 -11
- package/packages/builtin-tool-local-system/src/client/Inspector/WriteLocalFile/index.tsx +61 -0
- package/packages/builtin-tool-local-system/src/client/Inspector/index.ts +6 -0
- package/packages/builtin-tool-local-system/src/client/Render/EditLocalFile/index.tsx +6 -1
- package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/SearchView.tsx +19 -31
- package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/index.tsx +2 -42
- package/packages/builtin-tool-local-system/src/client/Render/index.ts +0 -2
- package/packages/builtin-tool-local-system/src/client/components/FilePathDisplay.tsx +56 -0
- package/packages/builtin-tool-local-system/src/client/components/index.ts +2 -0
- package/packages/builtin-tool-local-system/src/executor/index.ts +435 -0
- package/packages/builtin-tool-web-browsing/src/client/Inspector/Search/index.tsx +32 -5
- package/packages/model-runtime/src/core/contextBuilders/google.test.ts +84 -0
- package/packages/model-runtime/src/core/contextBuilders/google.ts +37 -1
- package/src/helpers/toolEngineering/index.ts +1 -1
- package/src/locales/default/plugin.ts +6 -0
- package/src/server/modules/Mecha/AgentToolsEngine/__tests__/index.test.ts +1 -1
- package/src/server/modules/Mecha/AgentToolsEngine/index.ts +1 -1
- package/src/store/chat/slices/builtinTool/actions/index.ts +1 -11
- package/src/store/tool/slices/builtin/executors/index.ts +4 -0
- package/src/styles/text.ts +1 -1
- package/src/tools/executionRuntimes.ts +3 -8
- package/src/tools/identifiers.ts +1 -1
- package/src/tools/index.ts +1 -1
- package/src/tools/inspectors.ts +5 -0
- package/src/tools/renders.ts +6 -12
- package/packages/builtin-tool-local-system/src/client/Render/RenameLocalFile/index.tsx +0 -37
- package/src/store/chat/slices/builtinTool/actions/__tests__/localSystem.test.ts +0 -201
- package/src/store/chat/slices/builtinTool/actions/knowledgeBase.ts +0 -163
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +0 -241
- package/src/tools/knowledge-base/ExecutionRuntime/index.ts +0 -25
- package/src/tools/knowledge-base/Render/ReadKnowledge/index.tsx +0 -29
- package/src/tools/knowledge-base/Render/SearchKnowledgeBase/index.tsx +0 -29
- package/src/tools/knowledge-base/Render/index.ts +0 -7
- package/src/tools/knowledge-base/index.ts +0 -12
- package/src/tools/local-system/ExecutionRuntime/index.ts +0 -9
- package/src/tools/local-system/systemRole.ts +0 -1
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { type GrepContentParams } from '@lobechat/electron-client-ipc';
|
|
4
4
|
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
+
import { Text } from '@lobehub/ui';
|
|
5
6
|
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
-
import { Check, X } from 'lucide-react';
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
@@ -20,10 +20,6 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
20
20
|
|
|
21
21
|
color: ${cssVar.colorTextSecondary};
|
|
22
22
|
`,
|
|
23
|
-
statusIcon: css`
|
|
24
|
-
margin-block-end: -2px;
|
|
25
|
-
margin-inline-start: 4px;
|
|
26
|
-
`,
|
|
27
23
|
}));
|
|
28
24
|
|
|
29
25
|
export const GrepContentInspector = memo<
|
|
@@ -50,22 +46,28 @@ export const GrepContentInspector = memo<
|
|
|
50
46
|
);
|
|
51
47
|
}
|
|
52
48
|
|
|
53
|
-
// Check
|
|
54
|
-
const
|
|
49
|
+
// Check result count
|
|
50
|
+
const resultCount = pluginState?.result?.total_matches ?? 0;
|
|
51
|
+
const hasResults = resultCount > 0;
|
|
55
52
|
|
|
56
53
|
return (
|
|
57
54
|
<div className={cx(styles.root, isLoading && shinyTextStyles.shinyText)}>
|
|
58
|
-
<span
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
55
|
+
<span>{t('builtins.lobe-local-system.apiName.grepContent')}: </span>
|
|
56
|
+
{pattern && <span className={highlightTextStyles.primary}>{pattern}</span>}
|
|
57
|
+
{!isLoading &&
|
|
58
|
+
pluginState?.result &&
|
|
59
|
+
(hasResults ? (
|
|
60
|
+
<span style={{ marginInlineStart: 4 }}>({resultCount})</span>
|
|
61
|
+
) : (
|
|
62
|
+
<Text
|
|
63
|
+
as={'span'}
|
|
64
|
+
color={cssVar.colorTextDescription}
|
|
65
|
+
fontSize={12}
|
|
66
|
+
style={{ marginInlineStart: 4 }}
|
|
67
|
+
>
|
|
68
|
+
({t('builtins.lobe-local-system.inspector.noResults')})
|
|
69
|
+
</Text>
|
|
70
|
+
))}
|
|
69
71
|
</div>
|
|
70
72
|
);
|
|
71
73
|
});
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type ListLocalFileParams } from '@lobechat/electron-client-ipc';
|
|
4
|
+
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
+
import { Text } from '@lobehub/ui';
|
|
6
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
7
|
+
import { memo } from 'react';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
9
|
+
|
|
10
|
+
import { shinyTextStyles } from '@/styles';
|
|
11
|
+
|
|
12
|
+
import { type LocalFileListState } from '../../..';
|
|
13
|
+
import { FilePathDisplay } from '../../components/FilePathDisplay';
|
|
14
|
+
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
|
+
root: css`
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
display: -webkit-box;
|
|
19
|
+
-webkit-box-orient: vertical;
|
|
20
|
+
-webkit-line-clamp: 1;
|
|
21
|
+
|
|
22
|
+
color: ${cssVar.colorTextSecondary};
|
|
23
|
+
`,
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
export const ListLocalFilesInspector = memo<
|
|
27
|
+
BuiltinInspectorProps<ListLocalFileParams, LocalFileListState>
|
|
28
|
+
>(({ args, partialArgs, isArgumentsStreaming, pluginState, isLoading }) => {
|
|
29
|
+
const { t } = useTranslation('plugin');
|
|
30
|
+
|
|
31
|
+
const path = args?.path || partialArgs?.path || '';
|
|
32
|
+
|
|
33
|
+
// During argument streaming
|
|
34
|
+
if (isArgumentsStreaming) {
|
|
35
|
+
if (!path)
|
|
36
|
+
return (
|
|
37
|
+
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
38
|
+
<span>{t('builtins.lobe-local-system.apiName.listLocalFiles')}</span>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
44
|
+
<span>{t('builtins.lobe-local-system.apiName.listLocalFiles')}: </span>
|
|
45
|
+
<FilePathDisplay filePath={path} isDirectory />
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Show result count if available
|
|
51
|
+
const resultCount = pluginState?.listResults?.length ?? 0;
|
|
52
|
+
const hasResults = resultCount > 0;
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<div className={cx(styles.root, isLoading && shinyTextStyles.shinyText)}>
|
|
56
|
+
<span>{t('builtins.lobe-local-system.apiName.listLocalFiles')}: </span>
|
|
57
|
+
<FilePathDisplay filePath={path} isDirectory />
|
|
58
|
+
{!isLoading &&
|
|
59
|
+
pluginState?.listResults &&
|
|
60
|
+
(hasResults ? (
|
|
61
|
+
<span style={{ marginInlineStart: 4 }}>({resultCount})</span>
|
|
62
|
+
) : (
|
|
63
|
+
<Text
|
|
64
|
+
as={'span'}
|
|
65
|
+
color={cssVar.colorTextDescription}
|
|
66
|
+
fontSize={12}
|
|
67
|
+
style={{ marginInlineStart: 4 }}
|
|
68
|
+
>
|
|
69
|
+
({t('builtins.lobe-local-system.inspector.noResults')})
|
|
70
|
+
</Text>
|
|
71
|
+
))}
|
|
72
|
+
</div>
|
|
73
|
+
);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
ListLocalFilesInspector.displayName = 'ListLocalFilesInspector';
|
|
@@ -2,15 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
import { type LocalReadFileParams } from '@lobechat/electron-client-ipc';
|
|
4
4
|
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
-
import { createStaticStyles,
|
|
6
|
-
import { Check, X } from 'lucide-react';
|
|
7
|
-
import path from 'path-browserify-esm';
|
|
5
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
8
6
|
import { memo } from 'react';
|
|
9
7
|
import { useTranslation } from 'react-i18next';
|
|
10
8
|
|
|
11
|
-
import {
|
|
9
|
+
import { shinyTextStyles } from '@/styles';
|
|
12
10
|
|
|
13
11
|
import { type LocalReadFileState } from '../../..';
|
|
12
|
+
import { FilePathDisplay } from '../../components/FilePathDisplay';
|
|
14
13
|
|
|
15
14
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
15
|
root: css`
|
|
@@ -21,29 +20,18 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
21
20
|
|
|
22
21
|
color: ${cssVar.colorTextSecondary};
|
|
23
22
|
`,
|
|
24
|
-
statusIcon: css`
|
|
25
|
-
margin-block-end: -2px;
|
|
26
|
-
margin-inline-start: 4px;
|
|
27
|
-
`,
|
|
28
23
|
}));
|
|
29
24
|
|
|
30
25
|
export const ReadLocalFileInspector = memo<
|
|
31
26
|
BuiltinInspectorProps<LocalReadFileParams, LocalReadFileState>
|
|
32
|
-
>(({ args, partialArgs, isArgumentsStreaming,
|
|
27
|
+
>(({ args, partialArgs, isArgumentsStreaming, isLoading }) => {
|
|
33
28
|
const { t } = useTranslation('plugin');
|
|
34
29
|
|
|
35
|
-
// Show filename with parent directory for context
|
|
36
30
|
const filePath = args?.path || partialArgs?.path || '';
|
|
37
|
-
let displayPath = '';
|
|
38
|
-
if (filePath) {
|
|
39
|
-
const { base, dir } = path.parse(filePath);
|
|
40
|
-
const parentDir = path.basename(dir);
|
|
41
|
-
displayPath = parentDir ? `${parentDir}/${base}` : base;
|
|
42
|
-
}
|
|
43
31
|
|
|
44
32
|
// During argument streaming
|
|
45
33
|
if (isArgumentsStreaming) {
|
|
46
|
-
if (!
|
|
34
|
+
if (!filePath)
|
|
47
35
|
return (
|
|
48
36
|
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
49
37
|
<span>{t('builtins.lobe-local-system.apiName.readLocalFile')}</span>
|
|
@@ -53,27 +41,15 @@ export const ReadLocalFileInspector = memo<
|
|
|
53
41
|
return (
|
|
54
42
|
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
55
43
|
<span>{t('builtins.lobe-local-system.apiName.readLocalFile')}: </span>
|
|
56
|
-
<
|
|
44
|
+
<FilePathDisplay filePath={filePath} />
|
|
57
45
|
</div>
|
|
58
46
|
);
|
|
59
47
|
}
|
|
60
48
|
|
|
61
|
-
// Check if file was read successfully (has content)
|
|
62
|
-
const hasContent = !!pluginState?.fileContent;
|
|
63
|
-
|
|
64
49
|
return (
|
|
65
50
|
<div className={cx(styles.root, isLoading && shinyTextStyles.shinyText)}>
|
|
66
|
-
<span
|
|
67
|
-
|
|
68
|
-
{displayPath && <span className={highlightTextStyles.primary}>{displayPath}</span>}
|
|
69
|
-
{isLoading ? null : pluginState ? (
|
|
70
|
-
hasContent ? (
|
|
71
|
-
<Check className={styles.statusIcon} color={cssVar.colorSuccess} size={14} />
|
|
72
|
-
) : (
|
|
73
|
-
<X className={styles.statusIcon} color={cssVar.colorError} size={14} />
|
|
74
|
-
)
|
|
75
|
-
) : null}
|
|
76
|
-
</span>
|
|
51
|
+
<span>{t('builtins.lobe-local-system.apiName.readLocalFile')}: </span>
|
|
52
|
+
<FilePathDisplay filePath={filePath} />
|
|
77
53
|
</div>
|
|
78
54
|
);
|
|
79
55
|
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type RenameLocalFileParams } from '@lobechat/electron-client-ipc';
|
|
4
|
+
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
+
import { MaterialFileTypeIcon } from '@lobehub/ui';
|
|
6
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
7
|
+
import path from 'path-browserify-esm';
|
|
8
|
+
import { memo } from 'react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
10
|
+
|
|
11
|
+
import { highlightTextStyles, shinyTextStyles } from '@/styles';
|
|
12
|
+
|
|
13
|
+
import { type LocalRenameFileState } from '../../..';
|
|
14
|
+
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
|
+
icon: css`
|
|
17
|
+
flex-shrink: 0;
|
|
18
|
+
margin-inline-end: 4px;
|
|
19
|
+
`,
|
|
20
|
+
root: css`
|
|
21
|
+
overflow: hidden;
|
|
22
|
+
display: -webkit-box;
|
|
23
|
+
-webkit-box-orient: vertical;
|
|
24
|
+
-webkit-line-clamp: 1;
|
|
25
|
+
|
|
26
|
+
color: ${cssVar.colorTextSecondary};
|
|
27
|
+
`,
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
export const RenameLocalFileInspector = memo<
|
|
31
|
+
BuiltinInspectorProps<RenameLocalFileParams, LocalRenameFileState>
|
|
32
|
+
>(({ args, partialArgs, isArgumentsStreaming }) => {
|
|
33
|
+
const { t } = useTranslation('plugin');
|
|
34
|
+
|
|
35
|
+
const filePath = args?.path || partialArgs?.path || '';
|
|
36
|
+
const newName = args?.newName || partialArgs?.newName || '';
|
|
37
|
+
|
|
38
|
+
// Get the old filename from path
|
|
39
|
+
const oldName = filePath ? path.basename(filePath) : '';
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div className={cx(styles.root, isArgumentsStreaming && shinyTextStyles.shinyText)}>
|
|
43
|
+
{oldName && newName ? (
|
|
44
|
+
<>
|
|
45
|
+
{t('builtins.lobe-local-system.apiName.renameLocalFile')} {oldName} →{' '}
|
|
46
|
+
<MaterialFileTypeIcon
|
|
47
|
+
className={styles.icon}
|
|
48
|
+
filename={newName}
|
|
49
|
+
size={16}
|
|
50
|
+
type={'file'}
|
|
51
|
+
variant={'raw'}
|
|
52
|
+
/>
|
|
53
|
+
<span className={highlightTextStyles.primary}>{newName}</span>
|
|
54
|
+
</>
|
|
55
|
+
) : (
|
|
56
|
+
<span>{t('builtins.lobe-local-system.apiName.renameLocalFile')}</span>
|
|
57
|
+
)}
|
|
58
|
+
</div>
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
RenameLocalFileInspector.displayName = 'RenameLocalFileInspector';
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { type LocalSearchFilesParams } from '@lobechat/electron-client-ipc';
|
|
4
4
|
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
+
import { Text } from '@lobehub/ui';
|
|
5
6
|
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
-
import { Check } from 'lucide-react';
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
@@ -20,10 +20,6 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
20
20
|
|
|
21
21
|
color: ${cssVar.colorTextSecondary};
|
|
22
22
|
`,
|
|
23
|
-
statusIcon: css`
|
|
24
|
-
margin-block-end: -2px;
|
|
25
|
-
margin-inline-start: 4px;
|
|
26
|
-
`,
|
|
27
23
|
}));
|
|
28
24
|
|
|
29
25
|
export const SearchLocalFilesInspector = memo<
|
|
@@ -51,18 +47,28 @@ export const SearchLocalFilesInspector = memo<
|
|
|
51
47
|
}
|
|
52
48
|
|
|
53
49
|
// Check if search returned results
|
|
54
|
-
const
|
|
50
|
+
const resultCount = pluginState?.searchResults?.length ?? 0;
|
|
51
|
+
const hasResults = resultCount > 0;
|
|
55
52
|
|
|
56
53
|
return (
|
|
57
54
|
<div className={cx(styles.root, isLoading && shinyTextStyles.shinyText)}>
|
|
58
55
|
<span style={{ marginInlineStart: 2 }}>
|
|
59
56
|
<span>{t('builtins.lobe-local-system.apiName.searchLocalFiles')}: </span>
|
|
60
57
|
{keywords && <span className={highlightTextStyles.primary}>{keywords}</span>}
|
|
61
|
-
{isLoading
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
58
|
+
{!isLoading &&
|
|
59
|
+
pluginState?.searchResults &&
|
|
60
|
+
(hasResults ? (
|
|
61
|
+
<span style={{ marginInlineStart: 4 }}>({resultCount})</span>
|
|
62
|
+
) : (
|
|
63
|
+
<Text
|
|
64
|
+
as={'span'}
|
|
65
|
+
color={cssVar.colorTextDescription}
|
|
66
|
+
fontSize={12}
|
|
67
|
+
style={{ marginInlineStart: 4 }}
|
|
68
|
+
>
|
|
69
|
+
({t('builtins.lobe-local-system.inspector.noResults')})
|
|
70
|
+
</Text>
|
|
71
|
+
))}
|
|
66
72
|
</span>
|
|
67
73
|
</div>
|
|
68
74
|
);
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { type WriteLocalFileParams } from '@lobechat/electron-client-ipc';
|
|
4
|
+
import { type BuiltinInspectorProps } from '@lobechat/types';
|
|
5
|
+
import { Icon, Text } from '@lobehub/ui';
|
|
6
|
+
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
7
|
+
import { Plus } from 'lucide-react';
|
|
8
|
+
import { memo } from 'react';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
10
|
+
|
|
11
|
+
import { shinyTextStyles } from '@/styles';
|
|
12
|
+
|
|
13
|
+
import { FilePathDisplay } from '../../components/FilePathDisplay';
|
|
14
|
+
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
|
+
root: css`
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
display: -webkit-box;
|
|
19
|
+
-webkit-box-orient: vertical;
|
|
20
|
+
-webkit-line-clamp: 1;
|
|
21
|
+
|
|
22
|
+
color: ${cssVar.colorTextSecondary};
|
|
23
|
+
`,
|
|
24
|
+
}));
|
|
25
|
+
|
|
26
|
+
export const WriteLocalFileInspector = memo<BuiltinInspectorProps<WriteLocalFileParams>>(
|
|
27
|
+
({ args, partialArgs, isArgumentsStreaming }) => {
|
|
28
|
+
const { t } = useTranslation('plugin');
|
|
29
|
+
|
|
30
|
+
const filePath = args?.path || partialArgs?.path || '';
|
|
31
|
+
const content = args?.content || partialArgs?.content || '';
|
|
32
|
+
|
|
33
|
+
// Calculate lines from content
|
|
34
|
+
const lines = content ? content.split('\n').length : 0;
|
|
35
|
+
|
|
36
|
+
// During argument streaming without path
|
|
37
|
+
if (isArgumentsStreaming && !filePath) {
|
|
38
|
+
return (
|
|
39
|
+
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
40
|
+
<span>{t('builtins.lobe-local-system.apiName.writeLocalFile')}</span>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<div className={cx(styles.root, isArgumentsStreaming && shinyTextStyles.shinyText)}>
|
|
47
|
+
<span>{t('builtins.lobe-local-system.apiName.writeLocalFile')}: </span>
|
|
48
|
+
<FilePathDisplay filePath={filePath} />
|
|
49
|
+
{lines > 0 && (
|
|
50
|
+
<Text as={'span'} code color={cssVar.colorSuccess} fontSize={12}>
|
|
51
|
+
{' '}
|
|
52
|
+
<Icon icon={Plus} size={12} />
|
|
53
|
+
{lines}
|
|
54
|
+
</Text>
|
|
55
|
+
)}
|
|
56
|
+
</div>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
WriteLocalFileInspector.displayName = 'WriteLocalFileInspector';
|
|
@@ -2,9 +2,12 @@ import { LocalSystemApiName } from '../..';
|
|
|
2
2
|
import { EditLocalFileInspector } from './EditLocalFile';
|
|
3
3
|
import { GlobLocalFilesInspector } from './GlobLocalFiles';
|
|
4
4
|
import { GrepContentInspector } from './GrepContent';
|
|
5
|
+
import { ListLocalFilesInspector } from './ListLocalFiles';
|
|
5
6
|
import { ReadLocalFileInspector } from './ReadLocalFile';
|
|
7
|
+
import { RenameLocalFileInspector } from './RenameLocalFile';
|
|
6
8
|
import { RunCommandInspector } from './RunCommand';
|
|
7
9
|
import { SearchLocalFilesInspector } from './SearchLocalFiles';
|
|
10
|
+
import { WriteLocalFileInspector } from './WriteLocalFile';
|
|
8
11
|
|
|
9
12
|
/**
|
|
10
13
|
* Local System Inspector Components Registry
|
|
@@ -13,7 +16,10 @@ export const LocalSystemInspectors = {
|
|
|
13
16
|
[LocalSystemApiName.editLocalFile]: EditLocalFileInspector,
|
|
14
17
|
[LocalSystemApiName.globLocalFiles]: GlobLocalFilesInspector,
|
|
15
18
|
[LocalSystemApiName.grepContent]: GrepContentInspector,
|
|
19
|
+
[LocalSystemApiName.listLocalFiles]: ListLocalFilesInspector,
|
|
16
20
|
[LocalSystemApiName.readLocalFile]: ReadLocalFileInspector,
|
|
21
|
+
[LocalSystemApiName.renameLocalFile]: RenameLocalFileInspector,
|
|
17
22
|
[LocalSystemApiName.runCommand]: RunCommandInspector,
|
|
18
23
|
[LocalSystemApiName.searchLocalFiles]: SearchLocalFilesInspector,
|
|
24
|
+
[LocalSystemApiName.writeLocalFile]: WriteLocalFileInspector,
|
|
19
25
|
};
|
|
@@ -50,7 +50,12 @@ const EditLocalFile = memo<BuiltinRenderProps<EditLocalFileParams, EditLocalFile
|
|
|
50
50
|
<Flexbox data-theme={isDarkMode ? 'dark' : 'light'} gap={12}>
|
|
51
51
|
{files.map((file, index) => (
|
|
52
52
|
<div key={`${file.oldPath}-${index}`} style={{ fontSize: '12px' }}>
|
|
53
|
-
<Diff
|
|
53
|
+
<Diff
|
|
54
|
+
diffType={file.type}
|
|
55
|
+
gutterType="default"
|
|
56
|
+
hunks={file.hunks}
|
|
57
|
+
viewType="unified"
|
|
58
|
+
>
|
|
54
59
|
{(hunks) => hunks.map((hunk) => <Hunk hunk={hunk} key={hunk.content} />)}
|
|
55
60
|
</Diff>
|
|
56
61
|
</div>
|
package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/SearchView.tsx
CHANGED
|
@@ -12,52 +12,40 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
12
12
|
color: ${cssVar.colorTextTertiary};
|
|
13
13
|
`,
|
|
14
14
|
query: css`
|
|
15
|
-
cursor: pointer;
|
|
16
|
-
|
|
17
15
|
padding-block: 4px;
|
|
18
16
|
padding-inline: 8px;
|
|
19
17
|
border-radius: 8px;
|
|
20
18
|
|
|
21
19
|
font-size: 12px;
|
|
22
20
|
color: ${cssVar.colorTextSecondary};
|
|
23
|
-
|
|
24
|
-
&:hover {
|
|
25
|
-
background: ${cssVar.colorFillTertiary};
|
|
26
|
-
}
|
|
27
21
|
`,
|
|
28
22
|
}));
|
|
29
23
|
|
|
30
24
|
interface SearchBarProps {
|
|
31
25
|
defaultQuery: string;
|
|
32
|
-
onEditingChange: (editing: boolean) => void;
|
|
33
26
|
resultsNumber: number;
|
|
34
27
|
searching?: boolean;
|
|
35
28
|
}
|
|
36
29
|
|
|
37
|
-
const SearchBar = memo<SearchBarProps>(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<Flexbox
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
>
|
|
51
|
-
<Icon icon={SearchIcon} />
|
|
52
|
-
{defaultQuery}
|
|
53
|
-
</Flexbox>
|
|
30
|
+
const SearchBar = memo<SearchBarProps>(({ defaultQuery, resultsNumber, searching }) => {
|
|
31
|
+
const { t } = useTranslation('tool');
|
|
32
|
+
return (
|
|
33
|
+
<Flexbox align={'center'} distribution={'space-between'} gap={40} height={26} horizontal>
|
|
34
|
+
<Flexbox
|
|
35
|
+
align={'center'}
|
|
36
|
+
className={cx(styles.query, searching && shinyTextStyles.shinyText)}
|
|
37
|
+
gap={8}
|
|
38
|
+
horizontal
|
|
39
|
+
>
|
|
40
|
+
<Icon icon={SearchIcon} />
|
|
41
|
+
{defaultQuery}
|
|
42
|
+
</Flexbox>
|
|
54
43
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
</Flexbox>
|
|
44
|
+
<Flexbox align={'center'} className={styles.font} horizontal>
|
|
45
|
+
<div>{t('search.searchResult')}</div>
|
|
46
|
+
{resultsNumber}
|
|
59
47
|
</Flexbox>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
);
|
|
48
|
+
</Flexbox>
|
|
49
|
+
);
|
|
50
|
+
});
|
|
63
51
|
export default SearchBar;
|
package/packages/builtin-tool-local-system/src/client/Render/SearchFiles/SearchQuery/index.tsx
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import type { LocalFileSearchState } from '@lobechat/builtin-tool-local-system';
|
|
2
2
|
import { type LocalSearchFilesParams } from '@lobechat/electron-client-ipc';
|
|
3
|
-
import {
|
|
4
|
-
import { SearchIcon, XIcon } from 'lucide-react';
|
|
5
|
-
import { memo, useState } from 'react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { memo } from 'react';
|
|
7
4
|
|
|
8
5
|
import { useChatStore } from '@/store/chat';
|
|
9
6
|
import { chatToolSelectors } from '@/store/chat/selectors';
|
|
@@ -17,49 +14,12 @@ interface SearchQueryViewProps {
|
|
|
17
14
|
}
|
|
18
15
|
|
|
19
16
|
const SearchQueryView = memo<SearchQueryViewProps>(({ messageId, args, pluginState }) => {
|
|
20
|
-
const { t } = useTranslation('tool');
|
|
21
17
|
const loading = useChatStore(chatToolSelectors.isSearchingLocalFiles(messageId));
|
|
22
|
-
const reSearchLocalFiles = useChatStore((s) => s.reSearchLocalFiles);
|
|
23
18
|
const searchResults = pluginState?.searchResults || [];
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
const [query, setQuery] = useState(args.keywords);
|
|
27
|
-
|
|
28
|
-
const updateAndSearch = async () => {
|
|
29
|
-
const data: LocalSearchFilesParams = { keywords: query };
|
|
30
|
-
|
|
31
|
-
await reSearchLocalFiles(messageId, data);
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return editing ? (
|
|
35
|
-
<Flexbox align={'center'} flex={1} gap={8} height={32} horizontal>
|
|
36
|
-
<Flexbox gap={8}>
|
|
37
|
-
<SearchBar
|
|
38
|
-
autoFocus
|
|
39
|
-
onChange={(e) => {
|
|
40
|
-
setQuery(e.target.value);
|
|
41
|
-
}}
|
|
42
|
-
onSearch={updateAndSearch}
|
|
43
|
-
placeholder={t('search.searchBar.placeholder')}
|
|
44
|
-
style={{ minWidth: 400 }}
|
|
45
|
-
value={query}
|
|
46
|
-
variant={'filled'}
|
|
47
|
-
/>
|
|
48
|
-
<Button
|
|
49
|
-
icon={<Icon icon={SearchIcon} />}
|
|
50
|
-
loading={loading}
|
|
51
|
-
onClick={updateAndSearch}
|
|
52
|
-
type={'primary'}
|
|
53
|
-
>
|
|
54
|
-
{t('search.searchBar.button')}
|
|
55
|
-
</Button>
|
|
56
|
-
</Flexbox>
|
|
57
|
-
<ActionIcon icon={XIcon} onClick={() => setEditing(false)} />
|
|
58
|
-
</Flexbox>
|
|
59
|
-
) : (
|
|
20
|
+
return (
|
|
60
21
|
<SearchView
|
|
61
22
|
defaultQuery={args?.keywords}
|
|
62
|
-
onEditingChange={setEditing}
|
|
63
23
|
resultsNumber={searchResults.length}
|
|
64
24
|
searching={loading || !pluginState}
|
|
65
25
|
/>
|
|
@@ -3,7 +3,6 @@ import EditLocalFile from './EditLocalFile';
|
|
|
3
3
|
import ListFiles from './ListFiles';
|
|
4
4
|
import MoveLocalFiles from './MoveLocalFiles';
|
|
5
5
|
import ReadLocalFile from './ReadLocalFile';
|
|
6
|
-
import RenameLocalFile from './RenameLocalFile';
|
|
7
6
|
import RunCommand from './RunCommand';
|
|
8
7
|
import SearchFiles from './SearchFiles';
|
|
9
8
|
import WriteFile from './WriteFile';
|
|
@@ -16,7 +15,6 @@ export const LocalSystemRenders = {
|
|
|
16
15
|
[LocalSystemApiName.listLocalFiles]: ListFiles,
|
|
17
16
|
[LocalSystemApiName.moveLocalFiles]: MoveLocalFiles,
|
|
18
17
|
[LocalSystemApiName.readLocalFile]: ReadLocalFile,
|
|
19
|
-
[LocalSystemApiName.renameLocalFile]: RenameLocalFile,
|
|
20
18
|
[LocalSystemApiName.runCommand]: RunCommand,
|
|
21
19
|
[LocalSystemApiName.searchLocalFiles]: SearchFiles,
|
|
22
20
|
[LocalSystemApiName.writeLocalFile]: WriteFile,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { MaterialFileTypeIcon } from '@lobehub/ui';
|
|
4
|
+
import { createStaticStyles, cssVar } from 'antd-style';
|
|
5
|
+
import path from 'path-browserify-esm';
|
|
6
|
+
import { memo, useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
const styles = createStaticStyles(({ css }) => ({
|
|
9
|
+
icon: css`
|
|
10
|
+
flex-shrink: 0;
|
|
11
|
+
margin-inline-end: 4px;
|
|
12
|
+
`,
|
|
13
|
+
text: css`
|
|
14
|
+
color: ${cssVar.colorText};
|
|
15
|
+
`,
|
|
16
|
+
}));
|
|
17
|
+
|
|
18
|
+
interface FilePathDisplayProps {
|
|
19
|
+
filePath: string;
|
|
20
|
+
isDirectory?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Reusable component for displaying file/folder icon + path in LocalSystem inspectors
|
|
25
|
+
* Used by Read, Write, Edit, Delete, Rename, List inspectors
|
|
26
|
+
*/
|
|
27
|
+
export const FilePathDisplay = memo<FilePathDisplayProps>(({ filePath, isDirectory }) => {
|
|
28
|
+
const { displayPath, name } = useMemo(() => {
|
|
29
|
+
if (!filePath) return { displayPath: '', name: '' };
|
|
30
|
+
const { base, dir } = path.parse(filePath);
|
|
31
|
+
const parentDir = path.basename(dir);
|
|
32
|
+
return {
|
|
33
|
+
displayPath: parentDir ? `${parentDir}/${base}` : base,
|
|
34
|
+
name: base,
|
|
35
|
+
};
|
|
36
|
+
}, [filePath]);
|
|
37
|
+
|
|
38
|
+
if (!filePath) return null;
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<>
|
|
42
|
+
{name && (
|
|
43
|
+
<MaterialFileTypeIcon
|
|
44
|
+
className={styles.icon}
|
|
45
|
+
filename={name}
|
|
46
|
+
size={16}
|
|
47
|
+
type={isDirectory ? 'folder' : 'file'}
|
|
48
|
+
variant={'raw'}
|
|
49
|
+
/>
|
|
50
|
+
)}
|
|
51
|
+
{displayPath && <span className={styles.text}>{displayPath}</span>}
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
FilePathDisplay.displayName = 'FilePathDisplay';
|