@lobehub/lobehub 2.0.0-next.295 → 2.0.0-next.296
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/en-US/plugin.json +4 -0
- package/locales/zh-CN/plugin.json +4 -0
- package/package.json +1 -1
- package/packages/agent-runtime/src/core/__tests__/runtime.test.ts +5 -5
- package/packages/agent-runtime/src/utils/stepContextComputer.test.ts +5 -5
- package/packages/builtin-tool-gtd/src/client/Inspector/index.ts +0 -4
- package/packages/builtin-tool-gtd/src/client/Intervention/AddTodo.tsx +1 -1
- package/packages/builtin-tool-gtd/src/client/Render/TodoList/index.tsx +39 -10
- package/packages/builtin-tool-gtd/src/client/Render/index.ts +0 -2
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/TodoItemRow.tsx +26 -12
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/actions.ts +5 -5
- package/packages/builtin-tool-gtd/src/client/components/SortableTodoList/store/store.test.ts +14 -8
- package/packages/builtin-tool-gtd/src/executor/index.test.ts +48 -227
- package/packages/builtin-tool-gtd/src/executor/index.ts +15 -158
- package/packages/builtin-tool-gtd/src/manifest.ts +12 -42
- package/packages/builtin-tool-gtd/src/systemRole.ts +14 -8
- package/packages/builtin-tool-gtd/src/types.ts +47 -41
- package/packages/builtin-tool-memory/package.json +8 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddContextMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddExperienceMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/AddPreferenceMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/RemoveIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/SearchUserMemory/index.tsx +67 -0
- package/packages/builtin-tool-memory/src/client/Inspector/UpdateIdentityMemory/index.tsx +60 -0
- package/packages/builtin-tool-memory/src/client/Inspector/index.ts +35 -0
- package/packages/builtin-tool-memory/src/client/Intervention/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Intervention/index.ts +13 -0
- package/packages/builtin-tool-memory/src/client/Render/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Render/SearchUserMemory/index.tsx +217 -0
- package/packages/builtin-tool-memory/src/client/Render/index.ts +15 -0
- package/packages/builtin-tool-memory/src/client/Streaming/AddExperienceMemory/index.tsx +17 -0
- package/packages/builtin-tool-memory/src/client/Streaming/index.ts +18 -0
- package/packages/builtin-tool-memory/src/client/components/ExperienceMemoryCard.tsx +231 -0
- package/packages/builtin-tool-memory/src/client/components/index.ts +1 -0
- package/packages/builtin-tool-memory/src/client/index.ts +27 -0
- package/packages/builtin-tool-memory/src/executor/index.ts +9 -1
- package/packages/builtin-tool-memory/src/types.ts +61 -0
- package/packages/context-engine/src/providers/GTDTodoInjector.ts +15 -7
- package/packages/conversation-flow/src/__tests__/fixtures/outputs/assistantGroup/tools-with-branches.json +4 -0
- package/packages/conversation-flow/src/transformation/FlatListBuilder.ts +1 -0
- package/packages/prompts/src/prompts/gtd/index.test.ts +32 -16
- package/packages/prompts/src/prompts/gtd/index.ts +9 -5
- package/packages/types/src/stepContext.ts +4 -1
- package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -2
- package/src/app/[variants]/(main)/community/features/Search.tsx +1 -1
- package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +4 -2
- package/src/app/[variants]/(main)/resource/library/_layout/Header/LibraryHead.tsx +30 -35
- package/src/app/[variants]/(main)/resource/library/_layout/Header/index.tsx +9 -11
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/index.tsx +11 -17
- package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/LoadingPlaceholder/index.tsx +13 -3
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/CustomRender.tsx +43 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/FallbacktArgumentRender.tsx +59 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Detail/Render/index.tsx +46 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/index.tsx +13 -19
- package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +17 -17
- package/src/features/Conversation/Messages/Tool/Tool/index.tsx +10 -9
- package/src/features/Conversation/TodoProgress/index.tsx +56 -23
- package/src/features/PluginsUI/Render/MCPType/index.tsx +1 -1
- package/src/features/ResourceManager/components/Explorer/Header/index.tsx +57 -4
- package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +6 -4
- package/src/features/ResourceManager/components/Explorer/ListView/index.tsx +16 -5
- package/src/features/ResourceManager/components/LibraryHierarchy/styles.ts +5 -4
- package/src/hooks/useActiveTabKey.ts +1 -2
- package/src/locales/default/plugin.ts +1 -0
- package/src/store/chat/slices/message/selectors/dbMessage.test.ts +11 -11
- package/src/store/file/slices/resource/action.ts +4 -2
- package/src/tools/inspectors.ts +2 -0
- package/src/tools/interventions.ts +2 -0
- package/src/tools/renders.ts +3 -1
- package/src/tools/streamings.ts +2 -0
- package/packages/builtin-tool-gtd/src/client/Inspector/CompleteTodos/index.tsx +0 -52
- package/packages/builtin-tool-gtd/src/client/Inspector/RemoveTodos/index.tsx +0 -52
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Render/CustomRender.tsx +0 -113
- package/src/features/Conversation/Messages/Tool/Tool/Render.tsx +0 -47
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/AbortResponse.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Arguments/index.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/ErrorResponse.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ApprovalActions.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/Fallback.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/KeyValueEditor.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/ModeSelector.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/Intervention/index.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/PluginSettings.tsx +0 -0
- /package/src/features/Conversation/Messages/AssistantGroup/Tool/{Render → Detail}/RejectedResponse.tsx +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type ChatPluginPayload } from '@/types/index';
|
|
2
|
+
import { Flexbox } from '@lobehub/ui';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import PluginRender from '@/features/PluginsUI/Render';
|
|
6
|
+
|
|
7
|
+
interface CustomRenderProps {
|
|
8
|
+
content: string;
|
|
9
|
+
/**
|
|
10
|
+
* The real message ID (tool message ID)
|
|
11
|
+
*/
|
|
12
|
+
messageId?: string;
|
|
13
|
+
plugin?: ChatPluginPayload;
|
|
14
|
+
pluginState?: any;
|
|
15
|
+
/**
|
|
16
|
+
* The tool call ID from the assistant message
|
|
17
|
+
*/
|
|
18
|
+
toolCallId: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const CustomRender = memo<CustomRenderProps>(
|
|
22
|
+
({ toolCallId, messageId, content, pluginState, plugin }) => {
|
|
23
|
+
return (
|
|
24
|
+
<Flexbox gap={12} id={toolCallId} width={'100%'}>
|
|
25
|
+
<PluginRender
|
|
26
|
+
arguments={plugin?.arguments}
|
|
27
|
+
content={content}
|
|
28
|
+
identifier={plugin?.identifier}
|
|
29
|
+
loading={false}
|
|
30
|
+
messageId={messageId}
|
|
31
|
+
payload={plugin}
|
|
32
|
+
pluginState={pluginState}
|
|
33
|
+
toolCallId={toolCallId}
|
|
34
|
+
type={plugin?.type}
|
|
35
|
+
/>
|
|
36
|
+
</Flexbox>
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
CustomRender.displayName = 'GroupCustomRender';
|
|
42
|
+
|
|
43
|
+
export default CustomRender;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Block, Flexbox, Highlighter, Text } from '@lobehub/ui';
|
|
2
|
+
import { Divider } from 'antd';
|
|
3
|
+
import { memo, useMemo } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
|
|
6
|
+
import Arguments from '../Arguments';
|
|
7
|
+
|
|
8
|
+
interface FallbackArgumentRenderProps {
|
|
9
|
+
content: string;
|
|
10
|
+
requestArgs?: string;
|
|
11
|
+
toolCallId: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const FallbackArgumentRender = memo<FallbackArgumentRenderProps>(
|
|
15
|
+
({ toolCallId, content, requestArgs }) => {
|
|
16
|
+
const { t } = useTranslation('plugin');
|
|
17
|
+
|
|
18
|
+
// Parse and display result content
|
|
19
|
+
const { data, language } = useMemo(() => {
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(content || '');
|
|
22
|
+
// If parsed result is a string, return it directly
|
|
23
|
+
if (typeof parsed === 'string') {
|
|
24
|
+
return { data: parsed, language: 'plaintext' };
|
|
25
|
+
}
|
|
26
|
+
return { data: JSON.stringify(parsed, null, 2), language: 'json' };
|
|
27
|
+
} catch {
|
|
28
|
+
return { data: content || '', language: 'plaintext' };
|
|
29
|
+
}
|
|
30
|
+
}, [content]);
|
|
31
|
+
|
|
32
|
+
// Default render: show arguments and result
|
|
33
|
+
return (
|
|
34
|
+
<Block id={toolCallId} variant={'outlined'} width={'100%'}>
|
|
35
|
+
<Arguments arguments={requestArgs} />
|
|
36
|
+
{content && (
|
|
37
|
+
<>
|
|
38
|
+
<Divider style={{ marginBlock: 0 }} />
|
|
39
|
+
<Flexbox paddingBlock={'8px 0'} paddingInline={16}>
|
|
40
|
+
<Text>{t('debug.response')}</Text>
|
|
41
|
+
</Flexbox>
|
|
42
|
+
<Highlighter
|
|
43
|
+
language={language}
|
|
44
|
+
style={{
|
|
45
|
+
background: 'transparent',
|
|
46
|
+
borderRadius: 0,
|
|
47
|
+
maxHeight: 300,
|
|
48
|
+
overflow: 'auto',
|
|
49
|
+
}}
|
|
50
|
+
variant={'filled'}
|
|
51
|
+
>
|
|
52
|
+
{data}
|
|
53
|
+
</Highlighter>
|
|
54
|
+
</>
|
|
55
|
+
)}
|
|
56
|
+
</Block>
|
|
57
|
+
);
|
|
58
|
+
},
|
|
59
|
+
);
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { type ChatPluginPayload } from '@lobechat/types';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { getBuiltinRender } from '@/tools/renders';
|
|
5
|
+
|
|
6
|
+
import CustomRender from './CustomRender';
|
|
7
|
+
import { FallbackArgumentRender } from './FallbacktArgumentRender';
|
|
8
|
+
|
|
9
|
+
interface ToolRenderProps {
|
|
10
|
+
content: string;
|
|
11
|
+
messageId?: string;
|
|
12
|
+
plugin?: ChatPluginPayload;
|
|
13
|
+
pluginState?: any;
|
|
14
|
+
showCustomToolRender?: boolean;
|
|
15
|
+
toolCallId: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const ToolRender = memo<ToolRenderProps>(
|
|
19
|
+
({ showCustomToolRender, content, messageId, plugin, pluginState, toolCallId }) => {
|
|
20
|
+
const hasCustomRender = !!getBuiltinRender(plugin?.identifier, plugin?.apiName);
|
|
21
|
+
|
|
22
|
+
if (hasCustomRender && showCustomToolRender) {
|
|
23
|
+
return (
|
|
24
|
+
<CustomRender
|
|
25
|
+
content={content}
|
|
26
|
+
messageId={messageId}
|
|
27
|
+
plugin={plugin}
|
|
28
|
+
pluginState={pluginState}
|
|
29
|
+
toolCallId={toolCallId}
|
|
30
|
+
/>
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<FallbackArgumentRender
|
|
36
|
+
content={content}
|
|
37
|
+
requestArgs={plugin?.arguments}
|
|
38
|
+
toolCallId={toolCallId}
|
|
39
|
+
/>
|
|
40
|
+
);
|
|
41
|
+
},
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
ToolRender.displayName = 'ToolResultRender';
|
|
45
|
+
|
|
46
|
+
export default ToolRender;
|
|
@@ -6,12 +6,12 @@ import { Suspense, memo } from 'react';
|
|
|
6
6
|
import { getBuiltinStreaming } from '@/tools/streamings';
|
|
7
7
|
|
|
8
8
|
import AbortResponse from './AbortResponse';
|
|
9
|
-
import CustomRender from './CustomRender';
|
|
10
9
|
import ErrorResponse from './ErrorResponse';
|
|
11
10
|
import Intervention from './Intervention';
|
|
12
11
|
import ModeSelector from './Intervention/ModeSelector';
|
|
13
12
|
import LoadingPlaceholder from './LoadingPlaceholder';
|
|
14
13
|
import RejectedResponse from './RejectedResponse';
|
|
14
|
+
import ToolRender from './Render';
|
|
15
15
|
|
|
16
16
|
interface RenderProps {
|
|
17
17
|
apiName: string;
|
|
@@ -26,8 +26,7 @@ interface RenderProps {
|
|
|
26
26
|
*/
|
|
27
27
|
messageId: string;
|
|
28
28
|
result?: ChatToolResult;
|
|
29
|
-
|
|
30
|
-
showPluginRender: boolean;
|
|
29
|
+
showCustomToolRender?: boolean;
|
|
31
30
|
toolCallId: string;
|
|
32
31
|
toolMessageId?: string;
|
|
33
32
|
type?: string;
|
|
@@ -45,8 +44,6 @@ const Render = memo<RenderProps>(
|
|
|
45
44
|
messageId,
|
|
46
45
|
arguments: requestArgs,
|
|
47
46
|
disableEditing,
|
|
48
|
-
showPluginRender,
|
|
49
|
-
setShowPluginRender,
|
|
50
47
|
identifier,
|
|
51
48
|
apiName,
|
|
52
49
|
result,
|
|
@@ -55,6 +52,7 @@ const Render = memo<RenderProps>(
|
|
|
55
52
|
toolMessageId,
|
|
56
53
|
isArgumentsStreaming,
|
|
57
54
|
isToolCalling,
|
|
55
|
+
showCustomToolRender,
|
|
58
56
|
}) => {
|
|
59
57
|
if (toolMessageId && intervention?.status === 'pending' && !disableEditing) {
|
|
60
58
|
return (
|
|
@@ -124,7 +122,9 @@ const Render = memo<RenderProps>(
|
|
|
124
122
|
apiName={apiName}
|
|
125
123
|
identifier={identifier}
|
|
126
124
|
loading
|
|
125
|
+
messageId={messageId}
|
|
127
126
|
requestArgs={requestArgs}
|
|
127
|
+
toolCallId={toolCallId}
|
|
128
128
|
/>
|
|
129
129
|
);
|
|
130
130
|
|
|
@@ -133,23 +133,17 @@ const Render = memo<RenderProps>(
|
|
|
133
133
|
return (
|
|
134
134
|
<Suspense fallback={placeholder}>
|
|
135
135
|
<Flexbox gap={8}>
|
|
136
|
-
<
|
|
136
|
+
<ToolRender
|
|
137
137
|
content={result.content || ''}
|
|
138
138
|
messageId={toolMessageId}
|
|
139
|
-
plugin={
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
type,
|
|
146
|
-
} as any)
|
|
147
|
-
: undefined
|
|
148
|
-
}
|
|
139
|
+
plugin={{
|
|
140
|
+
apiName,
|
|
141
|
+
arguments: requestArgs || '',
|
|
142
|
+
identifier,
|
|
143
|
+
type: type as any,
|
|
144
|
+
}}
|
|
149
145
|
pluginState={result.state}
|
|
150
|
-
|
|
151
|
-
setShowPluginRender={setShowPluginRender}
|
|
152
|
-
showPluginRender={showPluginRender}
|
|
146
|
+
showCustomToolRender={showCustomToolRender}
|
|
153
147
|
toolCallId={toolCallId}
|
|
154
148
|
/>
|
|
155
149
|
{!disableEditing && (
|
|
@@ -21,7 +21,7 @@ const Debug = dynamic(() => import('./Debug'), {
|
|
|
21
21
|
ssr: false,
|
|
22
22
|
});
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const Detail = dynamic(() => import('./Detail'), {
|
|
25
25
|
loading: () => <Skeleton.Block active height={120} width={'100%'} />,
|
|
26
26
|
ssr: false,
|
|
27
27
|
});
|
|
@@ -57,7 +57,9 @@ const Tool = memo<GroupToolProps>(
|
|
|
57
57
|
toolSelectors.getRenderDisplayControl(identifier, apiName),
|
|
58
58
|
);
|
|
59
59
|
const [showDebug, setShowDebug] = useState(false);
|
|
60
|
-
const [
|
|
60
|
+
const [showToolRender, setShowToolRender] = useState(false);
|
|
61
|
+
// Controls switching between custom render and fallback ArgumentRender
|
|
62
|
+
const [showCustomToolRender, setShowCustomToolRender] = useState(true);
|
|
61
63
|
|
|
62
64
|
const isPending = intervention?.status === 'pending';
|
|
63
65
|
const isReject = intervention?.status === 'rejected';
|
|
@@ -65,8 +67,6 @@ const Tool = memo<GroupToolProps>(
|
|
|
65
67
|
const needExpand = renderDisplayControl !== 'collapsed' || isPending;
|
|
66
68
|
const isAlwaysExpand = renderDisplayControl === 'alwaysExpand';
|
|
67
69
|
|
|
68
|
-
const showCustomPluginRender = !isPending && !isReject && !isAbort;
|
|
69
|
-
|
|
70
70
|
let isArgumentsStreaming = false;
|
|
71
71
|
try {
|
|
72
72
|
JSON.parse(requestArgs || '{}');
|
|
@@ -88,14 +88,16 @@ const Tool = memo<GroupToolProps>(
|
|
|
88
88
|
const isToolCalling = isToolCallingFromOperation || isToolCallingFallback;
|
|
89
89
|
|
|
90
90
|
const hasCustomRender = !!getBuiltinRender(identifier, apiName);
|
|
91
|
+
// Only allow toggle when has custom render and not in pending/reject/abort state
|
|
92
|
+
const canToggleCustomToolRender = hasCustomRender && !isPending && !isReject && !isAbort;
|
|
91
93
|
|
|
92
|
-
// Handle expand state changes
|
|
94
|
+
// Handle expand state changes
|
|
93
95
|
const handleExpand = (expand?: boolean) => {
|
|
94
96
|
// Block collapse action when alwaysExpand is set
|
|
95
97
|
if (isAlwaysExpand && expand === false) {
|
|
96
98
|
return;
|
|
97
99
|
}
|
|
98
|
-
|
|
100
|
+
setShowToolRender(!!expand);
|
|
99
101
|
};
|
|
100
102
|
|
|
101
103
|
useEffect(() => {
|
|
@@ -104,27 +106,26 @@ const Tool = memo<GroupToolProps>(
|
|
|
104
106
|
}
|
|
105
107
|
}, [needExpand]);
|
|
106
108
|
|
|
107
|
-
const
|
|
109
|
+
const isToolDetailExpand = forceShowStreamingRender || showToolRender || showDebug;
|
|
110
|
+
|
|
108
111
|
return (
|
|
109
112
|
<AccordionItem
|
|
110
113
|
action={
|
|
111
114
|
!disableEditing && (
|
|
112
115
|
<Actions
|
|
113
116
|
assistantMessageId={assistantMessageId}
|
|
114
|
-
|
|
117
|
+
canToggleCustomToolRender={canToggleCustomToolRender}
|
|
115
118
|
identifier={identifier}
|
|
119
|
+
setShowCustomToolRender={setShowCustomToolRender}
|
|
116
120
|
setShowDebug={setShowDebug}
|
|
117
|
-
|
|
118
|
-
showCustomPluginRender={showCustomPluginRender}
|
|
121
|
+
showCustomToolRender={showCustomToolRender}
|
|
119
122
|
showDebug={showDebug}
|
|
120
|
-
showPluginRender={showPluginRender}
|
|
121
123
|
/>
|
|
122
124
|
)
|
|
123
125
|
}
|
|
124
|
-
|
|
125
|
-
expand={isToolRenderExpand}
|
|
126
|
+
expand={isToolDetailExpand}
|
|
126
127
|
itemKey={id}
|
|
127
|
-
onExpandChange={
|
|
128
|
+
onExpandChange={handleExpand}
|
|
128
129
|
paddingBlock={4}
|
|
129
130
|
paddingInline={4}
|
|
130
131
|
title={
|
|
@@ -151,7 +152,7 @@ const Tool = memo<GroupToolProps>(
|
|
|
151
152
|
/>
|
|
152
153
|
)}
|
|
153
154
|
<ToolErrorBoundary apiName={apiName} identifier={identifier}>
|
|
154
|
-
<
|
|
155
|
+
<Detail
|
|
155
156
|
apiName={apiName}
|
|
156
157
|
arguments={requestArgs}
|
|
157
158
|
disableEditing={disableEditing}
|
|
@@ -161,8 +162,7 @@ const Tool = memo<GroupToolProps>(
|
|
|
161
162
|
isToolCalling={isToolCalling}
|
|
162
163
|
messageId={assistantMessageId}
|
|
163
164
|
result={result}
|
|
164
|
-
|
|
165
|
-
showPluginRender={showPluginRender}
|
|
165
|
+
showCustomToolRender={showCustomToolRender}
|
|
166
166
|
toolCallId={id}
|
|
167
167
|
toolMessageId={toolMessageId}
|
|
168
168
|
type={type}
|
|
@@ -3,6 +3,7 @@ import { type CSSProperties, memo, useState } from 'react';
|
|
|
3
3
|
|
|
4
4
|
import Actions from '@/features/Conversation/Messages/AssistantGroup/Tool/Actions';
|
|
5
5
|
import dynamic from '@/libs/next/dynamic';
|
|
6
|
+
import { getBuiltinRender } from '@/tools/renders';
|
|
6
7
|
|
|
7
8
|
import { dataSelectors, messageStateSelectors, useConversationStore } from '../../../store';
|
|
8
9
|
import Inspectors from '../../AssistantGroup/Tool/Inspector';
|
|
@@ -12,7 +13,7 @@ const Debug = dynamic(() => import('../../AssistantGroup/Tool/Debug'), {
|
|
|
12
13
|
ssr: false,
|
|
13
14
|
});
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
+
const Detail = dynamic(() => import('../../AssistantGroup/Tool/Detail'), {
|
|
16
17
|
loading: () => <Skeleton.Block active height={120} width={'100%'} />,
|
|
17
18
|
ssr: false,
|
|
18
19
|
});
|
|
@@ -44,7 +45,7 @@ const Tool = memo<InspectorProps>(
|
|
|
44
45
|
type,
|
|
45
46
|
}) => {
|
|
46
47
|
const [showDebug, setShowDebug] = useState(false);
|
|
47
|
-
const [
|
|
48
|
+
const [showCustomToolRender, setShowCustomToolRender] = useState(true);
|
|
48
49
|
const [expand, setExpand] = useState(true);
|
|
49
50
|
|
|
50
51
|
// Fetch tool message from store
|
|
@@ -68,6 +69,8 @@ const Tool = memo<InspectorProps>(
|
|
|
68
69
|
// Don't render if still loading and no message yet
|
|
69
70
|
if (loading && !toolMessage) return null;
|
|
70
71
|
|
|
72
|
+
const hasCustomRender = !!getBuiltinRender(identifier, apiName);
|
|
73
|
+
|
|
71
74
|
return (
|
|
72
75
|
<Accordion
|
|
73
76
|
expandedKeys={expand ? ['tool'] : []}
|
|
@@ -79,13 +82,12 @@ const Tool = memo<InspectorProps>(
|
|
|
79
82
|
!disableEditing && (
|
|
80
83
|
<Actions
|
|
81
84
|
assistantMessageId={messageId}
|
|
82
|
-
|
|
85
|
+
canToggleCustomToolRender={hasCustomRender}
|
|
83
86
|
identifier={identifier}
|
|
87
|
+
setShowCustomToolRender={setShowCustomToolRender}
|
|
84
88
|
setShowDebug={setShowDebug}
|
|
85
|
-
|
|
86
|
-
showCustomPluginRender={false}
|
|
89
|
+
showCustomToolRender={showCustomToolRender}
|
|
87
90
|
showDebug={showDebug}
|
|
88
|
-
showPluginRender={showPluginRender}
|
|
89
91
|
/>
|
|
90
92
|
)
|
|
91
93
|
}
|
|
@@ -105,15 +107,14 @@ const Tool = memo<InspectorProps>(
|
|
|
105
107
|
type={type}
|
|
106
108
|
/>
|
|
107
109
|
)}
|
|
108
|
-
<
|
|
110
|
+
<Detail
|
|
109
111
|
apiName={apiName}
|
|
110
112
|
arguments={requestArgs}
|
|
111
113
|
disableEditing={disableEditing}
|
|
112
114
|
identifier={identifier}
|
|
113
115
|
messageId={messageId}
|
|
114
116
|
result={result}
|
|
115
|
-
|
|
116
|
-
showPluginRender={showPluginRender}
|
|
117
|
+
showCustomToolRender={showCustomToolRender}
|
|
117
118
|
toolCallId={toolCallId}
|
|
118
119
|
type={type}
|
|
119
120
|
/>
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { type StepContextTodos } from '@lobechat/types';
|
|
4
4
|
import { Checkbox, Flexbox, Icon, Tag } from '@lobehub/ui';
|
|
5
5
|
import { createStaticStyles, cssVar, cx } from 'antd-style';
|
|
6
|
-
import { ChevronDown, ChevronUp, ListTodo } from 'lucide-react';
|
|
6
|
+
import { ChevronDown, ChevronUp, CircleArrowRight, ListTodo } from 'lucide-react';
|
|
7
7
|
import { memo, useMemo, useState } from 'react';
|
|
8
8
|
import { useTranslation } from 'react-i18next';
|
|
9
9
|
|
|
@@ -73,6 +73,11 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
73
73
|
opacity 0.2s ${cssVar.motionEaseInOut},
|
|
74
74
|
padding 0.2s ${cssVar.motionEaseInOut};
|
|
75
75
|
`,
|
|
76
|
+
processingRow: css`
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 6px;
|
|
79
|
+
align-items: center;
|
|
80
|
+
`,
|
|
76
81
|
progress: css`
|
|
77
82
|
flex: 1;
|
|
78
83
|
height: 4px;
|
|
@@ -85,10 +90,16 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
85
90
|
background: ${cssVar.colorSuccess};
|
|
86
91
|
transition: width 0.3s ${cssVar.motionEaseInOut};
|
|
87
92
|
`,
|
|
88
|
-
|
|
93
|
+
textCompleted: css`
|
|
89
94
|
color: ${cssVar.colorTextQuaternary};
|
|
90
95
|
text-decoration: line-through;
|
|
91
96
|
`,
|
|
97
|
+
textProcessing: css`
|
|
98
|
+
color: ${cssVar.colorText};
|
|
99
|
+
`,
|
|
100
|
+
textTodo: css`
|
|
101
|
+
color: ${cssVar.colorTextSecondary};
|
|
102
|
+
`,
|
|
92
103
|
}));
|
|
93
104
|
|
|
94
105
|
interface TodoProgressProps {
|
|
@@ -112,11 +123,13 @@ const TodoProgress = memo<TodoProgressProps>(({ className }) => {
|
|
|
112
123
|
// Calculate progress
|
|
113
124
|
const items = todos?.items || [];
|
|
114
125
|
const total = items.length;
|
|
115
|
-
const completed = items.filter((item) => item.completed).length;
|
|
126
|
+
const completed = items.filter((item) => item.status === 'completed').length;
|
|
116
127
|
const progressPercent = total > 0 ? (completed / total) * 100 : 0;
|
|
117
128
|
|
|
118
|
-
// Find current pending task (first
|
|
119
|
-
const currentPendingTask =
|
|
129
|
+
// Find current pending task (first non-completed item, prioritize processing)
|
|
130
|
+
const currentPendingTask =
|
|
131
|
+
items.find((item) => item.status === 'processing') ||
|
|
132
|
+
items.find((item) => item.status === 'todo');
|
|
120
133
|
|
|
121
134
|
// Don't render if no todos
|
|
122
135
|
if (total === 0) return null;
|
|
@@ -156,24 +169,44 @@ const TodoProgress = memo<TodoProgressProps>(({ className }) => {
|
|
|
156
169
|
|
|
157
170
|
{/* Expandable Todo List */}
|
|
158
171
|
<div className={cx(styles.listContainer, expanded ? styles.expanded : styles.collapsed)}>
|
|
159
|
-
{items.map((item, index) =>
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
172
|
+
{items.map((item, index) => {
|
|
173
|
+
const isCompleted = item.status === 'completed';
|
|
174
|
+
const isProcessing = item.status === 'processing';
|
|
175
|
+
|
|
176
|
+
// Processing state uses CircleArrowRight icon
|
|
177
|
+
if (isProcessing) {
|
|
178
|
+
return (
|
|
179
|
+
<div className={cx(styles.itemRow, styles.processingRow)} key={index}>
|
|
180
|
+
<Icon
|
|
181
|
+
icon={CircleArrowRight}
|
|
182
|
+
size={17}
|
|
183
|
+
style={{ color: cssVar.colorTextSecondary }}
|
|
184
|
+
/>
|
|
185
|
+
<span className={styles.textProcessing}>{item.text}</span>
|
|
186
|
+
</div>
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Todo and completed states use Checkbox
|
|
191
|
+
return (
|
|
192
|
+
<Checkbox
|
|
193
|
+
backgroundColor={cssVar.colorSuccess}
|
|
194
|
+
checked={isCompleted}
|
|
195
|
+
classNames={{
|
|
196
|
+
text: cx(styles.textTodo, isCompleted && styles.textCompleted),
|
|
197
|
+
wrapper: styles.itemRow,
|
|
198
|
+
}}
|
|
199
|
+
key={index}
|
|
200
|
+
shape="circle"
|
|
201
|
+
style={{ borderWidth: 1.5, cursor: 'default', pointerEvents: 'none' }}
|
|
202
|
+
textProps={{
|
|
203
|
+
type: isCompleted ? 'secondary' : undefined,
|
|
204
|
+
}}
|
|
205
|
+
>
|
|
206
|
+
{item.text}
|
|
207
|
+
</Checkbox>
|
|
208
|
+
);
|
|
209
|
+
})}
|
|
177
210
|
</div>
|
|
178
211
|
</div>
|
|
179
212
|
</WideScreenContainer>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Flexbox, Image, Markdown } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
-
import Arguments from '@/features/Conversation/Messages/AssistantGroup/Tool/
|
|
4
|
+
import Arguments from '@/features/Conversation/Messages/AssistantGroup/Tool/Detail/Arguments';
|
|
5
5
|
import { type ToolCallResult } from '@/libs/mcp';
|
|
6
6
|
|
|
7
7
|
export interface MCPTypeProps {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { ActionIcon, Flexbox } from '@lobehub/ui';
|
|
4
|
+
import { App } from 'antd';
|
|
4
5
|
import { cssVar } from 'antd-style';
|
|
5
|
-
import { SearchIcon } from 'lucide-react';
|
|
6
|
+
import { BookMinusIcon, FileBoxIcon, SearchIcon, Trash2Icon } from 'lucide-react';
|
|
6
7
|
import { memo } from 'react';
|
|
7
8
|
import { useTranslation } from 'react-i18next';
|
|
8
9
|
|
|
@@ -18,7 +19,8 @@ import ViewSwitcher from '../ToolBar/ViewSwitcher';
|
|
|
18
19
|
import Breadcrumb from './Breadcrumb';
|
|
19
20
|
|
|
20
21
|
const Header = memo(() => {
|
|
21
|
-
const { t } = useTranslation('file');
|
|
22
|
+
const { t } = useTranslation(['components', 'common', 'file', 'knowledgeBase']);
|
|
23
|
+
const { modal, message } = App.useApp();
|
|
22
24
|
|
|
23
25
|
// Get state and actions from store
|
|
24
26
|
const [libraryId, category, onActionClick, selectFileIds] = useResourceManagerStore((s) => [
|
|
@@ -29,8 +31,59 @@ const Header = memo(() => {
|
|
|
29
31
|
]);
|
|
30
32
|
const toggleCommandMenu = useGlobalStore((s) => s.toggleCommandMenu);
|
|
31
33
|
|
|
34
|
+
const selectCount = selectFileIds.length;
|
|
35
|
+
const isMultiSelected = selectCount > 1;
|
|
36
|
+
|
|
32
37
|
// If no libraryId, show category name or "Resource" for All
|
|
33
|
-
const leftContent =
|
|
38
|
+
const leftContent = isMultiSelected ? (
|
|
39
|
+
<Flexbox align={'center'} gap={8} horizontal style={{ marginLeft: 0 }}>
|
|
40
|
+
{libraryId ? (
|
|
41
|
+
<ActionIcon
|
|
42
|
+
icon={BookMinusIcon}
|
|
43
|
+
onClick={() => {
|
|
44
|
+
modal.confirm({
|
|
45
|
+
okButtonProps: {
|
|
46
|
+
danger: true,
|
|
47
|
+
},
|
|
48
|
+
onOk: async () => {
|
|
49
|
+
await onActionClick('removeFromKnowledgeBase');
|
|
50
|
+
message.success(t('FileManager.actions.removeFromKnowledgeBaseSuccess'));
|
|
51
|
+
},
|
|
52
|
+
title: t('FileManager.actions.confirmRemoveFromKnowledgeBase', {
|
|
53
|
+
count: selectCount,
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
}}
|
|
57
|
+
title={t('FileManager.actions.removeFromKnowledgeBase')}
|
|
58
|
+
/>
|
|
59
|
+
) : null}
|
|
60
|
+
|
|
61
|
+
<ActionIcon
|
|
62
|
+
icon={FileBoxIcon}
|
|
63
|
+
onClick={async () => {
|
|
64
|
+
await onActionClick('batchChunking');
|
|
65
|
+
}}
|
|
66
|
+
title={t('FileManager.actions.batchChunking')}
|
|
67
|
+
/>
|
|
68
|
+
|
|
69
|
+
<ActionIcon
|
|
70
|
+
icon={Trash2Icon}
|
|
71
|
+
onClick={() => {
|
|
72
|
+
modal.confirm({
|
|
73
|
+
okButtonProps: {
|
|
74
|
+
danger: true,
|
|
75
|
+
},
|
|
76
|
+
onOk: async () => {
|
|
77
|
+
await onActionClick('delete');
|
|
78
|
+
message.success(t('FileManager.actions.deleteSuccess'));
|
|
79
|
+
},
|
|
80
|
+
title: t('FileManager.actions.confirmDeleteMultiFiles', { count: selectCount }),
|
|
81
|
+
});
|
|
82
|
+
}}
|
|
83
|
+
title={t('delete', { ns: 'common' })}
|
|
84
|
+
/>
|
|
85
|
+
</Flexbox>
|
|
86
|
+
) : !libraryId ? (
|
|
34
87
|
<Flexbox style={{ marginLeft: 8 }}>
|
|
35
88
|
{category === FilesTabs.All
|
|
36
89
|
? t('resource', { defaultValue: 'Resource' })
|
|
@@ -49,7 +102,7 @@ const Header = memo(() => {
|
|
|
49
102
|
<>
|
|
50
103
|
<ActionIcon icon={SearchIcon} onClick={() => toggleCommandMenu(true)} />
|
|
51
104
|
<SortDropdown />
|
|
52
|
-
<BatchActionsDropdown onActionClick={onActionClick} selectCount={
|
|
105
|
+
<BatchActionsDropdown onActionClick={onActionClick} selectCount={selectCount} />
|
|
53
106
|
<ViewSwitcher />
|
|
54
107
|
<Flexbox style={{ marginLeft: 8 }}>
|
|
55
108
|
<AddButton />
|
|
@@ -48,11 +48,12 @@ const styles = createStaticStyles(({ css }) => {
|
|
|
48
48
|
`,
|
|
49
49
|
|
|
50
50
|
dragOver: css`
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
outline: 1px dashed ${cssVar.colorPrimaryBorder};
|
|
52
|
+
outline-offset: -2px;
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
&,
|
|
55
|
+
&:hover {
|
|
56
|
+
background: ${cssVar.colorPrimaryBg};
|
|
56
57
|
}
|
|
57
58
|
`,
|
|
58
59
|
|
|
@@ -510,6 +511,7 @@ const FileListItem = memo<FileListItemProps>(
|
|
|
510
511
|
e.stopPropagation();
|
|
511
512
|
}}
|
|
512
513
|
onPointerDown={(e) => e.stopPropagation()}
|
|
514
|
+
paddingInline={8}
|
|
513
515
|
>
|
|
514
516
|
{!isFolder &&
|
|
515
517
|
!isPage &&
|