@lobehub/chat 1.81.2 → 1.81.4
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 +59 -0
- package/changelog/v1.json +21 -0
- package/locales/ar/common.json +2 -0
- package/locales/ar/electron.json +32 -0
- package/locales/ar/models.json +126 -3
- package/locales/ar/plugin.json +1 -0
- package/locales/ar/tool.json +25 -0
- package/locales/bg-BG/common.json +2 -0
- package/locales/bg-BG/electron.json +32 -0
- package/locales/bg-BG/models.json +126 -3
- package/locales/bg-BG/plugin.json +1 -0
- package/locales/bg-BG/tool.json +25 -0
- package/locales/de-DE/common.json +2 -0
- package/locales/de-DE/electron.json +32 -0
- package/locales/de-DE/models.json +126 -3
- package/locales/de-DE/plugin.json +1 -0
- package/locales/de-DE/tool.json +25 -0
- package/locales/en-US/common.json +2 -0
- package/locales/en-US/electron.json +32 -0
- package/locales/en-US/models.json +126 -3
- package/locales/en-US/plugin.json +1 -0
- package/locales/en-US/tool.json +25 -0
- package/locales/es-ES/common.json +2 -0
- package/locales/es-ES/electron.json +32 -0
- package/locales/es-ES/models.json +126 -3
- package/locales/es-ES/plugin.json +1 -0
- package/locales/es-ES/tool.json +25 -0
- package/locales/fa-IR/common.json +2 -0
- package/locales/fa-IR/electron.json +32 -0
- package/locales/fa-IR/models.json +126 -3
- package/locales/fa-IR/plugin.json +1 -0
- package/locales/fa-IR/tool.json +25 -0
- package/locales/fr-FR/common.json +2 -0
- package/locales/fr-FR/electron.json +32 -0
- package/locales/fr-FR/models.json +126 -3
- package/locales/fr-FR/plugin.json +1 -0
- package/locales/fr-FR/tool.json +25 -0
- package/locales/it-IT/common.json +2 -0
- package/locales/it-IT/electron.json +32 -0
- package/locales/it-IT/models.json +126 -3
- package/locales/it-IT/plugin.json +1 -0
- package/locales/it-IT/tool.json +25 -0
- package/locales/ja-JP/common.json +2 -0
- package/locales/ja-JP/electron.json +32 -0
- package/locales/ja-JP/models.json +126 -3
- package/locales/ja-JP/plugin.json +1 -0
- package/locales/ja-JP/tool.json +25 -0
- package/locales/ko-KR/common.json +2 -0
- package/locales/ko-KR/electron.json +32 -0
- package/locales/ko-KR/models.json +126 -3
- package/locales/ko-KR/plugin.json +1 -0
- package/locales/ko-KR/tool.json +25 -0
- package/locales/nl-NL/common.json +2 -0
- package/locales/nl-NL/electron.json +32 -0
- package/locales/nl-NL/models.json +126 -3
- package/locales/nl-NL/plugin.json +1 -0
- package/locales/nl-NL/tool.json +25 -0
- package/locales/pl-PL/common.json +2 -0
- package/locales/pl-PL/electron.json +32 -0
- package/locales/pl-PL/models.json +126 -3
- package/locales/pl-PL/plugin.json +1 -0
- package/locales/pl-PL/tool.json +25 -0
- package/locales/pt-BR/common.json +2 -0
- package/locales/pt-BR/electron.json +32 -0
- package/locales/pt-BR/models.json +126 -3
- package/locales/pt-BR/plugin.json +1 -0
- package/locales/pt-BR/tool.json +25 -0
- package/locales/ru-RU/common.json +2 -0
- package/locales/ru-RU/electron.json +32 -0
- package/locales/ru-RU/models.json +126 -3
- package/locales/ru-RU/plugin.json +1 -0
- package/locales/ru-RU/tool.json +25 -0
- package/locales/tr-TR/common.json +2 -0
- package/locales/tr-TR/electron.json +32 -0
- package/locales/tr-TR/models.json +126 -3
- package/locales/tr-TR/plugin.json +1 -0
- package/locales/tr-TR/tool.json +25 -0
- package/locales/vi-VN/common.json +2 -0
- package/locales/vi-VN/electron.json +32 -0
- package/locales/vi-VN/models.json +126 -3
- package/locales/vi-VN/plugin.json +1 -0
- package/locales/vi-VN/tool.json +25 -0
- package/locales/zh-CN/common.json +2 -0
- package/locales/zh-CN/electron.json +32 -0
- package/locales/zh-CN/models.json +131 -8
- package/locales/zh-CN/plugin.json +1 -0
- package/locales/zh-CN/tool.json +25 -0
- package/locales/zh-TW/common.json +2 -0
- package/locales/zh-TW/electron.json +32 -0
- package/locales/zh-TW/models.json +126 -3
- package/locales/zh-TW/plugin.json +1 -0
- package/locales/zh-TW/tool.json +25 -0
- package/package.json +3 -2
- package/packages/electron-client-ipc/src/events/index.ts +5 -5
- package/packages/electron-client-ipc/src/events/localFile.ts +22 -0
- package/packages/electron-client-ipc/src/events/{file.ts → upload.ts} +1 -1
- package/packages/electron-client-ipc/src/types/index.ts +2 -1
- package/packages/electron-client-ipc/src/types/localFile.ts +52 -0
- package/scripts/prebuild.mts +5 -1
- package/src/app/(backend)/trpc/desktop/[trpc]/route.ts +26 -0
- package/src/config/aiModels/cloudflare.ts +41 -37
- package/src/config/aiModels/github.ts +90 -0
- package/src/config/aiModels/google.ts +25 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/ObjectEntity.tsx +81 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/ValueCell.tsx +43 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/index.tsx +120 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/CustomRender.tsx +75 -2
- package/src/features/Conversation/Messages/Assistant/Tool/Render/KeyValueEditor.tsx +214 -0
- package/src/features/User/UserPanel/useMenu.tsx +8 -1
- package/src/libs/agent-runtime/google/index.ts +3 -0
- package/src/libs/trpc/client/desktop.ts +14 -0
- package/src/locales/default/common.ts +2 -0
- package/src/locales/default/electron.ts +34 -0
- package/src/locales/default/index.ts +2 -0
- package/src/locales/default/tool.ts +25 -0
- package/src/server/routers/desktop/index.ts +9 -0
- package/src/server/routers/desktop/pgTable.ts +43 -0
- package/src/services/electron/autoUpdate.ts +17 -0
- package/src/services/electron/file.ts +31 -0
- package/src/services/electron/localFileService.ts +39 -0
- package/src/services/electron/remoteServer.ts +40 -0
- package/src/store/chat/index.ts +1 -1
- package/src/store/chat/slices/builtinTool/actions/index.ts +3 -1
- package/src/store/chat/slices/builtinTool/actions/localFile.ts +129 -0
- package/src/store/chat/slices/builtinTool/initialState.ts +2 -0
- package/src/store/chat/slices/builtinTool/selectors.ts +2 -0
- package/src/store/chat/slices/plugin/action.ts +3 -3
- package/src/store/chat/store.ts +2 -0
- package/src/store/electron/actions/sync.ts +117 -0
- package/src/store/electron/index.ts +1 -0
- package/src/store/electron/initialState.ts +18 -0
- package/src/store/electron/selectors/index.ts +1 -0
- package/src/store/electron/selectors/sync.ts +9 -0
- package/src/store/electron/store.ts +29 -0
- package/src/tools/index.ts +8 -0
- package/src/tools/local-files/Render/ListFiles/Result.tsx +42 -0
- package/src/tools/local-files/Render/ListFiles/index.tsx +68 -0
- package/src/tools/local-files/Render/ReadLocalFile/ReadFileSkeleton.tsx +50 -0
- package/src/tools/local-files/Render/ReadLocalFile/ReadFileView.tsx +197 -0
- package/src/tools/local-files/Render/ReadLocalFile/index.tsx +31 -0
- package/src/tools/local-files/Render/ReadLocalFile/style.ts +37 -0
- package/src/tools/local-files/Render/SearchFiles/Result.tsx +42 -0
- package/src/tools/local-files/Render/SearchFiles/SearchQuery/SearchView.tsx +77 -0
- package/src/tools/local-files/Render/SearchFiles/SearchQuery/index.tsx +72 -0
- package/src/tools/local-files/Render/SearchFiles/index.tsx +32 -0
- package/src/tools/local-files/Render/index.tsx +36 -0
- package/src/tools/local-files/components/FileItem.tsx +117 -0
- package/src/tools/local-files/index.ts +149 -0
- package/src/tools/local-files/systemRole.ts +46 -0
- package/src/tools/local-files/type.ts +33 -0
- package/src/tools/renders.ts +3 -0
- package/packages/electron-client-ipc/src/events/search.ts +0 -4
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments.tsx +0 -165
- /package/packages/electron-client-ipc/src/types/{file.ts → upload.ts} +0 -0
@@ -101,6 +101,29 @@ const githubChatModels: AIChatModelCard[] = [
|
|
101
101
|
releasedAt: '2025-04-14',
|
102
102
|
type: 'chat',
|
103
103
|
},
|
104
|
+
{
|
105
|
+
abilities: {
|
106
|
+
functionCall: true,
|
107
|
+
reasoning: true,
|
108
|
+
},
|
109
|
+
contextWindowTokens: 200_000,
|
110
|
+
displayName: 'OpenAI o4-mini',
|
111
|
+
id: 'o4-mini',
|
112
|
+
maxOutput: 100_000,
|
113
|
+
type: 'chat',
|
114
|
+
},
|
115
|
+
{
|
116
|
+
abilities: {
|
117
|
+
functionCall: true,
|
118
|
+
reasoning: true,
|
119
|
+
},
|
120
|
+
contextWindowTokens: 200_000,
|
121
|
+
displayName: 'OpenAI o3',
|
122
|
+
enabled: true,
|
123
|
+
id: 'o3',
|
124
|
+
maxOutput: 100_000,
|
125
|
+
type: 'chat',
|
126
|
+
},
|
104
127
|
{
|
105
128
|
abilities: {
|
106
129
|
functionCall: true,
|
@@ -174,6 +197,39 @@ const githubChatModels: AIChatModelCard[] = [
|
|
174
197
|
releasedAt: '2024-09-12',
|
175
198
|
type: 'chat',
|
176
199
|
},
|
200
|
+
{
|
201
|
+
abilities: {
|
202
|
+
functionCall: true,
|
203
|
+
vision: true,
|
204
|
+
},
|
205
|
+
contextWindowTokens: 1_074_176,
|
206
|
+
displayName: 'OpenAI GPT-4.1',
|
207
|
+
id: 'gpt-4.1',
|
208
|
+
maxOutput: 33_792,
|
209
|
+
type: 'chat',
|
210
|
+
},
|
211
|
+
{
|
212
|
+
abilities: {
|
213
|
+
functionCall: true,
|
214
|
+
vision: true,
|
215
|
+
},
|
216
|
+
contextWindowTokens: 1_074_176,
|
217
|
+
displayName: 'OpenAI GPT-4.1 mini',
|
218
|
+
id: 'gpt-4.1-mini',
|
219
|
+
maxOutput: 33_792,
|
220
|
+
type: 'chat',
|
221
|
+
},
|
222
|
+
{
|
223
|
+
abilities: {
|
224
|
+
functionCall: true,
|
225
|
+
vision: true,
|
226
|
+
},
|
227
|
+
contextWindowTokens: 1_074_176,
|
228
|
+
displayName: 'OpenAI GPT-4.1 nano',
|
229
|
+
id: 'gpt-4.1-nano',
|
230
|
+
maxOutput: 33_792,
|
231
|
+
type: 'chat',
|
232
|
+
},
|
177
233
|
{
|
178
234
|
abilities: {
|
179
235
|
functionCall: true,
|
@@ -198,6 +254,16 @@ const githubChatModels: AIChatModelCard[] = [
|
|
198
254
|
maxOutput: 16_384,
|
199
255
|
type: 'chat',
|
200
256
|
},
|
257
|
+
{
|
258
|
+
abilities: {
|
259
|
+
reasoning: true,
|
260
|
+
},
|
261
|
+
contextWindowTokens: 128_000,
|
262
|
+
displayName: 'MAI DS R1',
|
263
|
+
id: 'MAI-DS-R1',
|
264
|
+
maxOutput: 4096,
|
265
|
+
type: 'chat',
|
266
|
+
},
|
201
267
|
{
|
202
268
|
abilities: {
|
203
269
|
reasoning: true,
|
@@ -208,6 +274,16 @@ const githubChatModels: AIChatModelCard[] = [
|
|
208
274
|
maxOutput: 4096,
|
209
275
|
type: 'chat',
|
210
276
|
},
|
277
|
+
{
|
278
|
+
abilities: {
|
279
|
+
functionCall: true,
|
280
|
+
},
|
281
|
+
contextWindowTokens: 128_000,
|
282
|
+
displayName: 'DeepSeek V3',
|
283
|
+
id: 'DeepSeek-V3-0324',
|
284
|
+
maxOutput: 4096,
|
285
|
+
type: 'chat',
|
286
|
+
},
|
211
287
|
{
|
212
288
|
abilities: {
|
213
289
|
functionCall: true,
|
@@ -315,6 +391,20 @@ const githubChatModels: AIChatModelCard[] = [
|
|
315
391
|
id: 'llama-3.3-70b-instruct',
|
316
392
|
type: 'chat',
|
317
393
|
},
|
394
|
+
{
|
395
|
+
contextWindowTokens: 10_240_000,
|
396
|
+
displayName: 'Meta Llama 4 Scout 17B',
|
397
|
+
id: 'llama-4-Scout-17B-16E-Instruct',
|
398
|
+
maxOutput: 4096,
|
399
|
+
type: 'chat',
|
400
|
+
},
|
401
|
+
{
|
402
|
+
contextWindowTokens: 10_240_000,
|
403
|
+
displayName: 'Meta Llama 4 Maverick 17B',
|
404
|
+
id: 'llama-4-Maverick-17B-128E-Instruct-FP8',
|
405
|
+
maxOutput: 4096,
|
406
|
+
type: 'chat',
|
407
|
+
},
|
318
408
|
{
|
319
409
|
contextWindowTokens: 131_072,
|
320
410
|
description:
|
@@ -1,6 +1,31 @@
|
|
1
1
|
import { AIChatModelCard } from '@/types/aiModel';
|
2
2
|
|
3
3
|
const googleChatModels: AIChatModelCard[] = [
|
4
|
+
{
|
5
|
+
abilities: {
|
6
|
+
functionCall: true,
|
7
|
+
reasoning: true,
|
8
|
+
search: true,
|
9
|
+
vision: true,
|
10
|
+
},
|
11
|
+
contextWindowTokens: 1_048_576 + 65_536,
|
12
|
+
description:
|
13
|
+
'Gemini 2.5 Flash Preview 是 Google 性价比最高的模型,提供全面的功能。',
|
14
|
+
displayName: 'Gemini 2.5 Flash Preview 04-17',
|
15
|
+
enabled: true,
|
16
|
+
id: 'gemini-2.5-flash-preview-04-17',
|
17
|
+
maxOutput: 65_536,
|
18
|
+
pricing: {
|
19
|
+
input: 0.15,
|
20
|
+
output: 3.5, // Thinking
|
21
|
+
},
|
22
|
+
releasedAt: '2025-04-17',
|
23
|
+
settings: {
|
24
|
+
searchImpl: 'params',
|
25
|
+
searchProvider: 'google',
|
26
|
+
},
|
27
|
+
type: 'chat',
|
28
|
+
},
|
4
29
|
{
|
5
30
|
abilities: {
|
6
31
|
functionCall: true,
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import { createStyles } from 'antd-style';
|
2
|
+
import { memo } from 'react';
|
3
|
+
|
4
|
+
import { useIsMobile } from '@/hooks/useIsMobile';
|
5
|
+
import { shinyTextStylish } from '@/styles/loading';
|
6
|
+
|
7
|
+
import ValueCell from './ValueCell';
|
8
|
+
|
9
|
+
const useStyles = createStyles(({ css, token }) => ({
|
10
|
+
arrayRow: css`
|
11
|
+
&:not(:first-child) {
|
12
|
+
border-block-start: 1px dotted ${token.colorBorderSecondary};
|
13
|
+
}
|
14
|
+
`,
|
15
|
+
colon: css`
|
16
|
+
color: ${token.colorTextTertiary};
|
17
|
+
`,
|
18
|
+
key: css`
|
19
|
+
color: ${token.colorTextTertiary};
|
20
|
+
`,
|
21
|
+
row: css`
|
22
|
+
display: flex;
|
23
|
+
align-items: baseline;
|
24
|
+
|
25
|
+
&:not(:first-child) {
|
26
|
+
border-block-start: 1px dotted ${token.colorBorderSecondary};
|
27
|
+
}
|
28
|
+
`,
|
29
|
+
shineText: shinyTextStylish(token),
|
30
|
+
value: css`
|
31
|
+
color: ${token.colorTextSecondary};
|
32
|
+
`,
|
33
|
+
}));
|
34
|
+
|
35
|
+
const formatValue = (value: any): string | string[] => {
|
36
|
+
if (Array.isArray(value)) {
|
37
|
+
return value.map((v) => (typeof v === 'object' ? JSON.stringify(v) : v));
|
38
|
+
}
|
39
|
+
|
40
|
+
if (typeof value === 'object' && value !== null) {
|
41
|
+
return Object.entries(value)
|
42
|
+
.map(([k, v]) => `${k}: ${typeof v === 'object' ? JSON.stringify(v) : v}`)
|
43
|
+
.join(', ');
|
44
|
+
}
|
45
|
+
return String(value);
|
46
|
+
};
|
47
|
+
|
48
|
+
interface ObjectEntityProps {
|
49
|
+
editable?: boolean;
|
50
|
+
hasMinWidth: boolean;
|
51
|
+
objectKey: string;
|
52
|
+
shine?: boolean;
|
53
|
+
value: any;
|
54
|
+
}
|
55
|
+
|
56
|
+
const ObjectEntity = memo<ObjectEntityProps>(({ hasMinWidth, shine, value, objectKey }) => {
|
57
|
+
const { styles, cx } = useStyles();
|
58
|
+
const isMobile = useIsMobile();
|
59
|
+
const formatedValue = formatValue(value);
|
60
|
+
|
61
|
+
return (
|
62
|
+
<div className={styles.row}>
|
63
|
+
<span
|
64
|
+
className={styles.key}
|
65
|
+
style={{ minWidth: hasMinWidth ? (isMobile ? 60 : 140) : undefined }}
|
66
|
+
>
|
67
|
+
{objectKey}
|
68
|
+
</span>
|
69
|
+
<span className={styles.colon}>:</span>
|
70
|
+
<div className={cx(shine ? styles.shineText : styles.value)} style={{ width: '100%' }}>
|
71
|
+
{typeof formatedValue === 'string' ? (
|
72
|
+
<ValueCell value={formatedValue} />
|
73
|
+
) : (
|
74
|
+
formatedValue.map((v, i) => <ValueCell key={i + v} value={v} />)
|
75
|
+
)}
|
76
|
+
</div>
|
77
|
+
</div>
|
78
|
+
);
|
79
|
+
});
|
80
|
+
|
81
|
+
export default ObjectEntity;
|
@@ -0,0 +1,43 @@
|
|
1
|
+
import { copyToClipboard } from '@lobehub/ui';
|
2
|
+
import { App } from 'antd';
|
3
|
+
import { createStyles } from 'antd-style';
|
4
|
+
import { memo } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
|
7
|
+
const useStyles = createStyles(({ css, token }) => ({
|
8
|
+
copyable: css`
|
9
|
+
cursor: pointer;
|
10
|
+
width: 100%;
|
11
|
+
margin-block: 2px;
|
12
|
+
padding: 4px;
|
13
|
+
|
14
|
+
&:hover {
|
15
|
+
border-radius: 6px;
|
16
|
+
background: ${token.colorFillTertiary};
|
17
|
+
}
|
18
|
+
`,
|
19
|
+
}));
|
20
|
+
|
21
|
+
interface ValueCellProps {
|
22
|
+
value: string;
|
23
|
+
}
|
24
|
+
|
25
|
+
const ValueCell = memo<ValueCellProps>(({ value }) => {
|
26
|
+
const { message } = App.useApp();
|
27
|
+
const { t } = useTranslation('common');
|
28
|
+
const { styles } = useStyles();
|
29
|
+
|
30
|
+
return (
|
31
|
+
<div
|
32
|
+
className={styles.copyable}
|
33
|
+
onClick={async () => {
|
34
|
+
await copyToClipboard(value);
|
35
|
+
message.success(t('copySuccess'));
|
36
|
+
}}
|
37
|
+
>
|
38
|
+
{value}
|
39
|
+
</div>
|
40
|
+
);
|
41
|
+
});
|
42
|
+
|
43
|
+
export default ValueCell;
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
2
|
+
import { createStyles } from 'antd-style';
|
3
|
+
import { parse } from 'partial-json';
|
4
|
+
import { ReactNode, memo, useMemo } from 'react';
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
6
|
+
|
7
|
+
import { useYamlArguments } from '@/hooks/useYamlArguments';
|
8
|
+
|
9
|
+
import ObjectEntity from './ObjectEntity';
|
10
|
+
|
11
|
+
const useStyles = createStyles(({ css, token, cx }) => ({
|
12
|
+
button: css`
|
13
|
+
color: ${token.colorTextSecondary};
|
14
|
+
|
15
|
+
&:hover {
|
16
|
+
color: ${token.colorText};
|
17
|
+
}
|
18
|
+
`,
|
19
|
+
container: css`
|
20
|
+
position: relative;
|
21
|
+
|
22
|
+
padding-block: 4px;
|
23
|
+
padding-inline: 12px 64px;
|
24
|
+
border-radius: ${token.borderRadiusLG}px;
|
25
|
+
|
26
|
+
font-family: ${token.fontFamilyCode};
|
27
|
+
font-size: 13px;
|
28
|
+
line-height: 1.5;
|
29
|
+
|
30
|
+
background: ${token.colorFillQuaternary};
|
31
|
+
|
32
|
+
pre {
|
33
|
+
margin: 0 !important;
|
34
|
+
background: none !important;
|
35
|
+
}
|
36
|
+
|
37
|
+
&:hover {
|
38
|
+
.actions {
|
39
|
+
opacity: 1;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
`,
|
43
|
+
editButton: cx(
|
44
|
+
'actions',
|
45
|
+
css`
|
46
|
+
position: absolute;
|
47
|
+
z-index: 10;
|
48
|
+
inset-block-start: 4px;
|
49
|
+
inset-inline-end: 4px;
|
50
|
+
|
51
|
+
opacity: 0;
|
52
|
+
|
53
|
+
transition: opacity 0.2s ${token.motionEaseInOut};
|
54
|
+
`,
|
55
|
+
),
|
56
|
+
}));
|
57
|
+
|
58
|
+
export interface ArgumentsProps {
|
59
|
+
actions?: ReactNode;
|
60
|
+
arguments?: string;
|
61
|
+
shine?: boolean;
|
62
|
+
}
|
63
|
+
|
64
|
+
const Arguments = memo<ArgumentsProps>(({ arguments: args = '', shine, actions }) => {
|
65
|
+
const { styles } = useStyles();
|
66
|
+
|
67
|
+
const displayArgs = useMemo(() => {
|
68
|
+
try {
|
69
|
+
const obj = parse(args);
|
70
|
+
if (Object.keys(obj).length === 0) return {};
|
71
|
+
return obj;
|
72
|
+
} catch {
|
73
|
+
return args;
|
74
|
+
}
|
75
|
+
}, [args]);
|
76
|
+
|
77
|
+
const yaml = useYamlArguments(args);
|
78
|
+
|
79
|
+
const showActions = !!actions;
|
80
|
+
|
81
|
+
if (typeof displayArgs === 'string') {
|
82
|
+
return (
|
83
|
+
!!yaml && (
|
84
|
+
<div className={styles.container}>
|
85
|
+
<Highlighter language={'yaml'} showLanguage={false}>
|
86
|
+
{yaml}
|
87
|
+
</Highlighter>
|
88
|
+
</div>
|
89
|
+
)
|
90
|
+
);
|
91
|
+
}
|
92
|
+
|
93
|
+
const hasMinWidth = Object.keys(displayArgs).length > 1;
|
94
|
+
|
95
|
+
if (Object.keys(displayArgs).length === 0) return null;
|
96
|
+
|
97
|
+
return (
|
98
|
+
<div className={styles.container}>
|
99
|
+
{showActions && (
|
100
|
+
<Flexbox className={styles.editButton} gap={4} horizontal>
|
101
|
+
{actions}
|
102
|
+
</Flexbox>
|
103
|
+
)}
|
104
|
+
{Object.entries(displayArgs).map(([key, value]) => {
|
105
|
+
return (
|
106
|
+
<ObjectEntity
|
107
|
+
editable={false}
|
108
|
+
hasMinWidth={hasMinWidth}
|
109
|
+
key={key}
|
110
|
+
objectKey={key}
|
111
|
+
shine={shine}
|
112
|
+
value={value}
|
113
|
+
/>
|
114
|
+
);
|
115
|
+
})}
|
116
|
+
</div>
|
117
|
+
);
|
118
|
+
});
|
119
|
+
|
120
|
+
export default Arguments;
|
@@ -1,4 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import { ActionIcon } from '@lobehub/ui';
|
2
|
+
import { App } from 'antd';
|
3
|
+
import { Edit3Icon, PlayCircleIcon } from 'lucide-react';
|
4
|
+
import { parse } from 'partial-json';
|
5
|
+
import { memo, useCallback, useEffect, useState } from 'react';
|
6
|
+
import { useTranslation } from 'react-i18next';
|
2
7
|
import { Flexbox } from 'react-layout-kit';
|
3
8
|
|
4
9
|
import PluginRender from '@/features/PluginsUI/Render';
|
@@ -7,6 +12,16 @@ import { chatSelectors } from '@/store/chat/selectors';
|
|
7
12
|
import { ChatMessage } from '@/types/message';
|
8
13
|
|
9
14
|
import Arguments from './Arguments';
|
15
|
+
import KeyValueEditor from './KeyValueEditor';
|
16
|
+
|
17
|
+
const safeParseJson = (str: string): Record<string, any> => {
|
18
|
+
try {
|
19
|
+
const obj = parse(str);
|
20
|
+
return typeof obj === 'object' && obj !== null ? obj : {};
|
21
|
+
} catch {
|
22
|
+
return {};
|
23
|
+
}
|
24
|
+
};
|
10
25
|
|
11
26
|
interface CustomRenderProps extends ChatMessage {
|
12
27
|
requestArgs?: string;
|
@@ -25,7 +40,37 @@ const CustomRender = memo<CustomRenderProps>(
|
|
25
40
|
setShowPluginRender,
|
26
41
|
pluginError,
|
27
42
|
}) => {
|
43
|
+
const { t } = useTranslation(['tool', 'common']);
|
28
44
|
const [loading] = useChatStore((s) => [chatSelectors.isPluginApiInvoking(id)(s)]);
|
45
|
+
const [isEditing, setIsEditing] = useState(false);
|
46
|
+
const { message } = App.useApp();
|
47
|
+
const [updatePluginArguments, reInvokeToolMessage] = useChatStore((s) => [
|
48
|
+
s.updatePluginArguments,
|
49
|
+
s.reInvokeToolMessage,
|
50
|
+
]);
|
51
|
+
const handleCancel = useCallback(() => {
|
52
|
+
setIsEditing(false);
|
53
|
+
}, []);
|
54
|
+
|
55
|
+
const handleFinish = useCallback(
|
56
|
+
async (editedObject: Record<string, any>) => {
|
57
|
+
if (!id) return;
|
58
|
+
|
59
|
+
try {
|
60
|
+
const newArgsString = JSON.stringify(editedObject, null, 2);
|
61
|
+
|
62
|
+
if (newArgsString !== requestArgs) {
|
63
|
+
await updatePluginArguments(id, editedObject, true);
|
64
|
+
await reInvokeToolMessage(id);
|
65
|
+
}
|
66
|
+
setIsEditing(false);
|
67
|
+
} catch (error) {
|
68
|
+
console.error('Error stringifying arguments:', error);
|
69
|
+
message.error(t('updateArgs.stringifyError'));
|
70
|
+
}
|
71
|
+
},
|
72
|
+
[requestArgs, id],
|
73
|
+
);
|
29
74
|
|
30
75
|
useEffect(() => {
|
31
76
|
if (!plugin?.type || loading) return;
|
@@ -49,8 +94,36 @@ const CustomRender = memo<CustomRenderProps>(
|
|
49
94
|
pluginState={pluginState}
|
50
95
|
type={plugin?.type}
|
51
96
|
/>
|
97
|
+
) : isEditing ? (
|
98
|
+
<KeyValueEditor
|
99
|
+
initialValue={safeParseJson(requestArgs || '')}
|
100
|
+
onCancel={handleCancel}
|
101
|
+
onFinish={handleFinish}
|
102
|
+
/>
|
52
103
|
) : (
|
53
|
-
<Arguments
|
104
|
+
<Arguments
|
105
|
+
actions={
|
106
|
+
<>
|
107
|
+
<ActionIcon
|
108
|
+
icon={Edit3Icon}
|
109
|
+
onClick={() => {
|
110
|
+
setIsEditing(true);
|
111
|
+
}}
|
112
|
+
size={'small'}
|
113
|
+
title={t('edit', { ns: 'common' })}
|
114
|
+
/>
|
115
|
+
<ActionIcon
|
116
|
+
icon={PlayCircleIcon}
|
117
|
+
onClick={async () => {
|
118
|
+
await reInvokeToolMessage(id);
|
119
|
+
}}
|
120
|
+
size={'small'}
|
121
|
+
title={t('run', { ns: 'common' })}
|
122
|
+
/>
|
123
|
+
</>
|
124
|
+
}
|
125
|
+
arguments={requestArgs}
|
126
|
+
/>
|
54
127
|
)}
|
55
128
|
</Flexbox>
|
56
129
|
);
|