@lobehub/chat 0.157.0 → 0.157.1
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/package.json +30 -30
- package/src/app/api/chat/[provider]/route.test.ts +2 -2
- package/src/app/api/chat/[provider]/route.ts +1 -1
- package/src/app/api/chat/models/[provider]/route.ts +1 -1
- package/src/app/api/config.test.ts +1 -51
- package/src/app/api/openai/createBizOpenAI/auth.test.ts +52 -0
- package/src/app/api/openai/createBizOpenAI/index.ts +1 -1
- package/src/app/api/plugin/gateway/route.ts +1 -1
- package/src/app/api/text-to-image/[provider]/route.ts +61 -0
- package/src/components/GalleyGrid/index.tsx +2 -2
- package/src/database/client/schemas/message.ts +2 -0
- package/src/features/Conversation/Actions/Assistant.tsx +3 -2
- package/src/features/Conversation/Actions/Tool.tsx +23 -11
- package/src/features/Conversation/Messages/Assistant/ToolCalls/index.tsx +9 -14
- package/src/features/Conversation/Messages/Assistant/index.tsx +7 -3
- package/src/features/Conversation/Messages/Tool/Inspector/index.tsx +1 -1
- package/src/features/Conversation/Plugins/Render/index.tsx +11 -2
- package/src/hooks/useTokenCount.test.ts +38 -0
- package/src/hooks/useTokenCount.ts +1 -2
- package/src/libs/agent-runtime/AgentRuntime.ts +9 -1
- package/src/libs/agent-runtime/BaseAI.ts +3 -0
- package/src/libs/agent-runtime/types/index.ts +1 -0
- package/src/libs/agent-runtime/types/textToImage.ts +34 -0
- package/src/libs/agent-runtime/utils/createError.ts +1 -0
- package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +51 -0
- package/src/locales/default/tool.ts +1 -0
- package/src/services/_url.ts +1 -1
- package/src/services/{imageGeneration.ts → textToImage.ts} +11 -2
- package/src/store/chat/initialState.ts +1 -1
- package/src/store/chat/selectors.ts +1 -1
- package/src/store/chat/slices/{tool → builtinTool}/action.test.ts +1 -1
- package/src/store/chat/slices/{tool → builtinTool}/action.ts +16 -4
- package/src/store/chat/slices/enchance/action.ts +10 -11
- package/src/store/chat/slices/message/action.ts +30 -92
- package/src/store/chat/slices/message/initialState.ts +5 -0
- package/src/store/chat/slices/message/selectors.ts +8 -0
- package/src/store/chat/slices/plugin/action.test.ts +1 -1
- package/src/store/chat/slices/plugin/action.ts +95 -80
- package/src/store/chat/store.ts +2 -2
- package/src/store/tool/slices/store/action.test.ts +6 -2
- package/src/store/tool/slices/store/action.ts +3 -1
- package/src/tools/dalle/Render/Item/Error.tsx +50 -0
- package/src/tools/dalle/Render/Item/Image.tsx +44 -0
- package/src/tools/dalle/Render/{Item.tsx → Item/index.tsx} +20 -29
- package/src/utils/fetch.test.ts +208 -3
- package/src/utils/fetch.ts +242 -19
- package/src/app/api/openai/images/createImageGeneration.ts +0 -26
- package/src/app/api/openai/images/route.ts +0 -16
- package/src/features/Conversation/Actions/Function.tsx +0 -17
- /package/src/app/api/{chat → middleware}/auth/index.test.ts +0 -0
- /package/src/app/api/{chat → middleware}/auth/index.ts +0 -0
- /package/src/app/api/{chat → middleware}/auth/utils.ts +0 -0
- /package/src/app/api/{auth.ts → openai/createBizOpenAI/auth.ts} +0 -0
- /package/src/store/chat/slices/{tool → builtinTool}/initialState.ts +0 -0
- /package/src/store/chat/slices/{tool → builtinTool}/selectors.ts +0 -0
- /package/src/tools/dalle/Render/{EditMode.tsx → Item/EditMode.tsx} +0 -0
|
@@ -24,15 +24,22 @@ export interface ChatPluginAction {
|
|
|
24
24
|
content: string,
|
|
25
25
|
triggerAiMessage?: boolean,
|
|
26
26
|
) => Promise<void>;
|
|
27
|
+
|
|
28
|
+
internal_callPluginApi: (id: string, payload: ChatToolPayload) => Promise<string | undefined>;
|
|
29
|
+
internal_invokeDifferentTypePlugin: (id: string, payload: ChatToolPayload) => Promise<any>;
|
|
27
30
|
internal_transformToolCalls: (toolCalls: MessageToolCall[]) => ChatToolPayload[];
|
|
31
|
+
internal_updatePluginError: (id: string, error: any) => Promise<void>;
|
|
32
|
+
|
|
28
33
|
invokeBuiltinTool: (id: string, payload: ChatToolPayload) => Promise<void>;
|
|
29
34
|
invokeDefaultTypePlugin: (id: string, payload: any) => Promise<string | undefined>;
|
|
30
35
|
invokeMarkdownTypePlugin: (id: string, payload: ChatToolPayload) => Promise<void>;
|
|
36
|
+
|
|
31
37
|
invokeStandaloneTypePlugin: (id: string, payload: ChatToolPayload) => Promise<void>;
|
|
32
|
-
|
|
38
|
+
|
|
39
|
+
reInvokeToolMessage: (id: string) => Promise<void>;
|
|
33
40
|
triggerAIMessage: (params: { parentId?: string; traceId?: string }) => Promise<void>;
|
|
34
|
-
triggerToolCalls: (id: string) => Promise<void>;
|
|
35
41
|
|
|
42
|
+
triggerToolCalls: (id: string) => Promise<void>;
|
|
36
43
|
updatePluginState: (id: string, key: string, value: any) => Promise<void>;
|
|
37
44
|
}
|
|
38
45
|
|
|
@@ -62,6 +69,70 @@ export const chatPlugin: StateCreator<
|
|
|
62
69
|
|
|
63
70
|
if (triggerAiMessage) await triggerAIMessage({ parentId: id });
|
|
64
71
|
},
|
|
72
|
+
internal_callPluginApi: async (id, payload) => {
|
|
73
|
+
const { internal_updateMessageContent, refreshMessages, internal_toggleChatLoading } = get();
|
|
74
|
+
let data: string;
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
const abortController = internal_toggleChatLoading(
|
|
78
|
+
true,
|
|
79
|
+
id,
|
|
80
|
+
n('fetchPlugin/start') as string,
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
const message = chatSelectors.getMessageById(id)(get());
|
|
84
|
+
|
|
85
|
+
const res = await chatService.runPluginApi(payload, {
|
|
86
|
+
signal: abortController?.signal,
|
|
87
|
+
trace: { observationId: message?.observationId, traceId: message?.traceId },
|
|
88
|
+
});
|
|
89
|
+
data = res.text;
|
|
90
|
+
|
|
91
|
+
// save traceId
|
|
92
|
+
if (res.traceId) {
|
|
93
|
+
await messageService.updateMessage(id, { traceId: res.traceId });
|
|
94
|
+
}
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.log(error);
|
|
97
|
+
const err = error as Error;
|
|
98
|
+
|
|
99
|
+
// ignore the aborted request error
|
|
100
|
+
if (!err.message.includes('The user aborted a request.')) {
|
|
101
|
+
await messageService.updateMessageError(id, error as any);
|
|
102
|
+
await refreshMessages();
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
data = '';
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
internal_toggleChatLoading(false, id, n('fetchPlugin/end') as string);
|
|
109
|
+
// 如果报错则结束了
|
|
110
|
+
if (!data) return;
|
|
111
|
+
|
|
112
|
+
await internal_updateMessageContent(id, data);
|
|
113
|
+
|
|
114
|
+
return data;
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
internal_invokeDifferentTypePlugin: async (id, payload) => {
|
|
118
|
+
switch (payload.type) {
|
|
119
|
+
case 'standalone': {
|
|
120
|
+
return await get().invokeStandaloneTypePlugin(id, payload);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
case 'markdown': {
|
|
124
|
+
return await get().invokeMarkdownTypePlugin(id, payload);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
case 'builtin': {
|
|
128
|
+
return await get().invokeBuiltinTool(id, payload);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
default: {
|
|
132
|
+
return await get().invokeDefaultTypePlugin(id, payload);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
},
|
|
65
136
|
|
|
66
137
|
internal_transformToolCalls: (toolCalls) => {
|
|
67
138
|
return toolCalls
|
|
@@ -98,6 +169,13 @@ export const chatPlugin: StateCreator<
|
|
|
98
169
|
.filter(Boolean) as ChatToolPayload[];
|
|
99
170
|
},
|
|
100
171
|
|
|
172
|
+
internal_updatePluginError: async (id, error) => {
|
|
173
|
+
const { refreshMessages } = get();
|
|
174
|
+
|
|
175
|
+
await messageService.updateMessage(id, { pluginError: error });
|
|
176
|
+
await refreshMessages();
|
|
177
|
+
},
|
|
178
|
+
|
|
101
179
|
invokeBuiltinTool: async (id, payload) => {
|
|
102
180
|
const { internal_toggleChatLoading, internal_updateMessageContent } = get();
|
|
103
181
|
const params = JSON.parse(payload.arguments);
|
|
@@ -131,9 +209,9 @@ export const chatPlugin: StateCreator<
|
|
|
131
209
|
},
|
|
132
210
|
|
|
133
211
|
invokeDefaultTypePlugin: async (id, payload) => {
|
|
134
|
-
const {
|
|
212
|
+
const { internal_callPluginApi } = get();
|
|
135
213
|
|
|
136
|
-
const data = await
|
|
214
|
+
const data = await internal_callPluginApi(id, payload);
|
|
137
215
|
|
|
138
216
|
if (!data) return;
|
|
139
217
|
|
|
@@ -141,9 +219,9 @@ export const chatPlugin: StateCreator<
|
|
|
141
219
|
},
|
|
142
220
|
|
|
143
221
|
invokeMarkdownTypePlugin: async (id, payload) => {
|
|
144
|
-
const {
|
|
222
|
+
const { internal_callPluginApi } = get();
|
|
145
223
|
|
|
146
|
-
await
|
|
224
|
+
await internal_callPluginApi(id, payload);
|
|
147
225
|
},
|
|
148
226
|
|
|
149
227
|
invokeStandaloneTypePlugin: async (id, payload) => {
|
|
@@ -166,49 +244,13 @@ export const chatPlugin: StateCreator<
|
|
|
166
244
|
}
|
|
167
245
|
},
|
|
168
246
|
|
|
169
|
-
|
|
170
|
-
const
|
|
171
|
-
|
|
247
|
+
reInvokeToolMessage: async (id) => {
|
|
248
|
+
const message = chatSelectors.getMessageById(id)(get());
|
|
249
|
+
if (!message || message.role !== 'tool' || !message.plugin) return;
|
|
172
250
|
|
|
173
|
-
|
|
174
|
-
const abortController = internal_toggleChatLoading(
|
|
175
|
-
true,
|
|
176
|
-
id,
|
|
177
|
-
n('fetchPlugin/start') as string,
|
|
178
|
-
);
|
|
251
|
+
const payload: ChatToolPayload = { ...message.plugin, id: message.tool_call_id! };
|
|
179
252
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
const res = await chatService.runPluginApi(payload, {
|
|
183
|
-
signal: abortController?.signal,
|
|
184
|
-
trace: { observationId: message?.observationId, traceId: message?.traceId },
|
|
185
|
-
});
|
|
186
|
-
data = res.text;
|
|
187
|
-
|
|
188
|
-
// save traceId
|
|
189
|
-
if (res.traceId) {
|
|
190
|
-
await messageService.updateMessage(id, { traceId: res.traceId });
|
|
191
|
-
}
|
|
192
|
-
} catch (error) {
|
|
193
|
-
console.log(error);
|
|
194
|
-
const err = error as Error;
|
|
195
|
-
|
|
196
|
-
// ignore the aborted request error
|
|
197
|
-
if (!err.message.includes('The user aborted a request.')) {
|
|
198
|
-
await messageService.updateMessageError(id, error as any);
|
|
199
|
-
await refreshMessages();
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
data = '';
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
internal_toggleChatLoading(false, id, n('fetchPlugin/end') as string);
|
|
206
|
-
// 如果报错则结束了
|
|
207
|
-
if (!data) return;
|
|
208
|
-
|
|
209
|
-
await internal_updateMessageContent(id, data);
|
|
210
|
-
|
|
211
|
-
return data;
|
|
253
|
+
await get().internal_invokeDifferentTypePlugin(id, payload);
|
|
212
254
|
},
|
|
213
255
|
|
|
214
256
|
triggerAIMessage: async ({ parentId, traceId }) => {
|
|
@@ -216,19 +258,10 @@ export const chatPlugin: StateCreator<
|
|
|
216
258
|
const chats = chatSelectors.currentChats(get());
|
|
217
259
|
await internal_coreProcessMessage(chats, parentId ?? chats.at(-1)!.id, { traceId });
|
|
218
260
|
},
|
|
219
|
-
|
|
220
261
|
triggerToolCalls: async (assistantId) => {
|
|
221
262
|
const message = chatSelectors.getMessageById(assistantId)(get());
|
|
222
263
|
if (!message || !message.tools) return;
|
|
223
264
|
|
|
224
|
-
const {
|
|
225
|
-
invokeDefaultTypePlugin,
|
|
226
|
-
invokeMarkdownTypePlugin,
|
|
227
|
-
invokeStandaloneTypePlugin,
|
|
228
|
-
invokeBuiltinTool,
|
|
229
|
-
triggerAIMessage,
|
|
230
|
-
} = get();
|
|
231
|
-
|
|
232
265
|
let shouldCreateMessage = false;
|
|
233
266
|
let latestToolId = '';
|
|
234
267
|
const messagePools = message.tools.map(async (payload) => {
|
|
@@ -244,29 +277,12 @@ export const chatPlugin: StateCreator<
|
|
|
244
277
|
|
|
245
278
|
const id = await get().internal_createMessage(toolMessage);
|
|
246
279
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
await invokeStandaloneTypePlugin(id, payload);
|
|
250
|
-
break;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
case 'markdown': {
|
|
254
|
-
await invokeMarkdownTypePlugin(id, payload);
|
|
255
|
-
break;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
case 'builtin': {
|
|
259
|
-
await invokeBuiltinTool(id, payload);
|
|
260
|
-
break;
|
|
261
|
-
}
|
|
280
|
+
// trigger the plugin call
|
|
281
|
+
const data = await get().internal_invokeDifferentTypePlugin(id, payload);
|
|
262
282
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
shouldCreateMessage = true;
|
|
267
|
-
latestToolId = id;
|
|
268
|
-
}
|
|
269
|
-
}
|
|
283
|
+
if (payload.type === 'default' && data) {
|
|
284
|
+
shouldCreateMessage = true;
|
|
285
|
+
latestToolId = id;
|
|
270
286
|
}
|
|
271
287
|
});
|
|
272
288
|
|
|
@@ -277,9 +293,8 @@ export const chatPlugin: StateCreator<
|
|
|
277
293
|
|
|
278
294
|
const traceId = chatSelectors.getTraceIdByMessageId(latestToolId)(get());
|
|
279
295
|
|
|
280
|
-
await triggerAIMessage({ traceId });
|
|
296
|
+
await get().triggerAIMessage({ traceId });
|
|
281
297
|
},
|
|
282
|
-
|
|
283
298
|
updatePluginState: async (id, key, value) => {
|
|
284
299
|
const { refreshMessages } = get();
|
|
285
300
|
|
package/src/store/chat/store.ts
CHANGED
|
@@ -6,11 +6,11 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
6
6
|
import { isDev } from '@/utils/env';
|
|
7
7
|
|
|
8
8
|
import { ChatStoreState, initialState } from './initialState';
|
|
9
|
+
import { ChatBuiltinToolAction, chatToolSlice } from './slices/builtinTool/action';
|
|
9
10
|
import { ChatEnhanceAction, chatEnhance } from './slices/enchance/action';
|
|
10
11
|
import { ChatMessageAction, chatMessage } from './slices/message/action';
|
|
11
12
|
import { ChatPluginAction, chatPlugin } from './slices/plugin/action';
|
|
12
13
|
import { ShareAction, chatShare } from './slices/share/action';
|
|
13
|
-
import { ChatToolAction, chatToolSlice } from './slices/tool/action';
|
|
14
14
|
import { ChatTopicAction, chatTopic } from './slices/topic/action';
|
|
15
15
|
|
|
16
16
|
export interface ChatStoreAction
|
|
@@ -19,7 +19,7 @@ export interface ChatStoreAction
|
|
|
19
19
|
ShareAction,
|
|
20
20
|
ChatEnhanceAction,
|
|
21
21
|
ChatPluginAction,
|
|
22
|
-
|
|
22
|
+
ChatBuiltinToolAction {}
|
|
23
23
|
|
|
24
24
|
export type ChatStore = ChatStoreAction & ChatStoreState;
|
|
25
25
|
|
|
@@ -156,7 +156,9 @@ describe('useToolStore:pluginStore', () => {
|
|
|
156
156
|
const { result } = renderHook(() => useToolStore.getState().useFetchPluginStore());
|
|
157
157
|
|
|
158
158
|
// Then
|
|
159
|
-
expect(useSWR).toHaveBeenCalledWith('loadPluginStore', expect.any(Function)
|
|
159
|
+
expect(useSWR).toHaveBeenCalledWith('loadPluginStore', expect.any(Function), {
|
|
160
|
+
revalidateOnFocus: false,
|
|
161
|
+
});
|
|
160
162
|
expect(result.current.data).toEqual(pluginListMock);
|
|
161
163
|
expect(result.current.error).toBeNull();
|
|
162
164
|
expect(result.current.isValidating).toBe(false);
|
|
@@ -175,7 +177,9 @@ describe('useToolStore:pluginStore', () => {
|
|
|
175
177
|
const { result } = renderHook(() => useToolStore.getState().useFetchPluginStore());
|
|
176
178
|
|
|
177
179
|
// Then
|
|
178
|
-
expect(useSWR).toHaveBeenCalledWith('loadPluginStore', expect.any(Function)
|
|
180
|
+
expect(useSWR).toHaveBeenCalledWith('loadPluginStore', expect.any(Function), {
|
|
181
|
+
revalidateOnFocus: false,
|
|
182
|
+
});
|
|
179
183
|
expect(result.current.data).toBeNull();
|
|
180
184
|
expect(result.current.error).toEqual(error);
|
|
181
185
|
expect(result.current.isValidating).toBe(false);
|
|
@@ -101,5 +101,7 @@ export const createPluginStoreSlice: StateCreator<
|
|
|
101
101
|
revalidateOnFocus: false,
|
|
102
102
|
}),
|
|
103
103
|
useFetchPluginStore: () =>
|
|
104
|
-
useSWR<LobeChatPluginsMarketIndex>('loadPluginStore', get().loadPluginStore
|
|
104
|
+
useSWR<LobeChatPluginsMarketIndex>('loadPluginStore', get().loadPluginStore, {
|
|
105
|
+
revalidateOnFocus: false,
|
|
106
|
+
}),
|
|
105
107
|
});
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Alert, Highlighter, Icon } from '@lobehub/ui';
|
|
2
|
+
import { Button } from 'antd';
|
|
3
|
+
import { LucideRefreshCw } from 'lucide-react';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
|
+
import { Flexbox } from 'react-layout-kit';
|
|
7
|
+
|
|
8
|
+
import { useChatStore } from '@/store/chat';
|
|
9
|
+
import { chatSelectors } from '@/store/chat/selectors';
|
|
10
|
+
|
|
11
|
+
interface ErrorProps {
|
|
12
|
+
index: number;
|
|
13
|
+
messageId: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const Error = memo<ErrorProps>(({ messageId, index }) => {
|
|
17
|
+
const { t } = useTranslation('error');
|
|
18
|
+
const { t: ct } = useTranslation('common');
|
|
19
|
+
|
|
20
|
+
const error = useChatStore(
|
|
21
|
+
(s) => chatSelectors.getMessageById(messageId)(s)?.pluginState?.['error']?.[index],
|
|
22
|
+
);
|
|
23
|
+
const [reInvokeToolMessage] = useChatStore((s) => [s.reInvokeToolMessage]);
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
error && (
|
|
27
|
+
<Flexbox gap={12}>
|
|
28
|
+
<Alert
|
|
29
|
+
extra={
|
|
30
|
+
<Highlighter copyButtonSize={'small'} language={'json'}>
|
|
31
|
+
{JSON.stringify(error.body, null, 2)}
|
|
32
|
+
</Highlighter>
|
|
33
|
+
}
|
|
34
|
+
extraDefaultExpand
|
|
35
|
+
message={t(`response.${error.errorType}` as any)}
|
|
36
|
+
type={'error'}
|
|
37
|
+
/>
|
|
38
|
+
<Button
|
|
39
|
+
icon={<Icon icon={LucideRefreshCw} />}
|
|
40
|
+
onClick={() => reInvokeToolMessage(messageId)}
|
|
41
|
+
type={'primary'}
|
|
42
|
+
>
|
|
43
|
+
{ct('retry')}
|
|
44
|
+
</Button>
|
|
45
|
+
</Flexbox>
|
|
46
|
+
)
|
|
47
|
+
);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
export default Error;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Icon, Image, Tooltip } from '@lobehub/ui';
|
|
2
|
+
import { Loader2 } from 'lucide-react';
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
|
+
|
|
7
|
+
import ImageFileItem from '@/components/FileList/ImageFileItem';
|
|
8
|
+
|
|
9
|
+
interface ImagePreviewProps {
|
|
10
|
+
imageId?: string;
|
|
11
|
+
previewUrl?: string;
|
|
12
|
+
prompt: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const ImagePreview = memo<ImagePreviewProps>(({ imageId, previewUrl, prompt }) => {
|
|
16
|
+
const { t } = useTranslation('tool');
|
|
17
|
+
|
|
18
|
+
return imageId ? (
|
|
19
|
+
// <Flexbox className={styles.action}>
|
|
20
|
+
// <ActionIconGroup
|
|
21
|
+
// items={[{ icon: LucideEdit, key: 'edit', label: t('edit', { ns: 'common' }) }]}
|
|
22
|
+
// onActionClick={(e) => {
|
|
23
|
+
// if (e.key === 'edit') {
|
|
24
|
+
// setEdit(true);
|
|
25
|
+
// }
|
|
26
|
+
// }}
|
|
27
|
+
// />
|
|
28
|
+
// </Flexbox>
|
|
29
|
+
<ImageFileItem id={imageId} />
|
|
30
|
+
) : (
|
|
31
|
+
previewUrl && (
|
|
32
|
+
<Flexbox style={{ position: 'relative' }}>
|
|
33
|
+
<div style={{ position: 'absolute', right: 8, top: 8, zIndex: 10 }}>
|
|
34
|
+
<Tooltip title={t('dalle.downloading')}>
|
|
35
|
+
<Icon icon={Loader2} size={'large'} spin />
|
|
36
|
+
</Tooltip>
|
|
37
|
+
</div>
|
|
38
|
+
<Image alt={prompt} size={'100%'} src={previewUrl} />
|
|
39
|
+
</Flexbox>
|
|
40
|
+
)
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
export default ImagePreview;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Highlighter, Icon } from '@lobehub/ui';
|
|
2
2
|
import { Spin } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
import { Loader2 } from 'lucide-react';
|
|
@@ -6,12 +6,13 @@ import { memo, useState } from 'react';
|
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
8
|
|
|
9
|
-
import ImageFileItem from '@/components/FileList/ImageFileItem';
|
|
10
9
|
import { useChatStore } from '@/store/chat';
|
|
11
10
|
import { chatToolSelectors } from '@/store/chat/selectors';
|
|
12
11
|
import { DallEImageItem } from '@/types/tool/dalle';
|
|
13
12
|
|
|
14
13
|
import EditMode from './EditMode';
|
|
14
|
+
import Error from './Error';
|
|
15
|
+
import ImagePreview from './Image';
|
|
15
16
|
|
|
16
17
|
const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
|
17
18
|
action: css`
|
|
@@ -32,8 +33,8 @@ const useStyles = createStyles(({ css, token, prefixCls }) => ({
|
|
|
32
33
|
`,
|
|
33
34
|
}));
|
|
34
35
|
|
|
35
|
-
const ImageItem = memo<DallEImageItem & { messageId: string }>(
|
|
36
|
-
({ prompt, messageId, imageId, previewUrl, style, size, quality }) => {
|
|
36
|
+
const ImageItem = memo<DallEImageItem & { index: number; messageId: string }>(
|
|
37
|
+
({ prompt, messageId, imageId, previewUrl, index, style, size, quality }) => {
|
|
37
38
|
const { t } = useTranslation('tool');
|
|
38
39
|
const { styles } = useStyles();
|
|
39
40
|
|
|
@@ -55,30 +56,7 @@ const ImageItem = memo<DallEImageItem & { messageId: string }>(
|
|
|
55
56
|
);
|
|
56
57
|
|
|
57
58
|
if (imageId || previewUrl)
|
|
58
|
-
return imageId
|
|
59
|
-
// <Flexbox className={styles.action}>
|
|
60
|
-
// <ActionIconGroup
|
|
61
|
-
// items={[{ icon: LucideEdit, key: 'edit', label: t('edit', { ns: 'common' }) }]}
|
|
62
|
-
// onActionClick={(e) => {
|
|
63
|
-
// if (e.key === 'edit') {
|
|
64
|
-
// setEdit(true);
|
|
65
|
-
// }
|
|
66
|
-
// }}
|
|
67
|
-
// />
|
|
68
|
-
// </Flexbox>
|
|
69
|
-
<ImageFileItem id={imageId} />
|
|
70
|
-
) : (
|
|
71
|
-
previewUrl && (
|
|
72
|
-
<Flexbox style={{ position: 'relative' }}>
|
|
73
|
-
<div style={{ position: 'absolute', right: 8, top: 8, zIndex: 10 }}>
|
|
74
|
-
<Tooltip title={t('dalle.downloading')}>
|
|
75
|
-
<Icon icon={Loader2} size={'large'} spin />
|
|
76
|
-
</Tooltip>
|
|
77
|
-
</div>
|
|
78
|
-
<Image alt={prompt} size={'100%'} src={previewUrl} />
|
|
79
|
-
</Flexbox>
|
|
80
|
-
)
|
|
81
|
-
);
|
|
59
|
+
return <ImagePreview imageId={imageId} previewUrl={previewUrl} prompt={prompt} />;
|
|
82
60
|
|
|
83
61
|
return (
|
|
84
62
|
<Flexbox className={styles.container} padding={8}>
|
|
@@ -87,7 +65,20 @@ const ImageItem = memo<DallEImageItem & { messageId: string }>(
|
|
|
87
65
|
{prompt}
|
|
88
66
|
</Spin>
|
|
89
67
|
) : (
|
|
90
|
-
|
|
68
|
+
<Flexbox gap={12}>
|
|
69
|
+
<Flexbox>
|
|
70
|
+
<Highlighter
|
|
71
|
+
copyButtonSize={'small'}
|
|
72
|
+
fileName={t('dalle.prompt')}
|
|
73
|
+
fullFeatured
|
|
74
|
+
language={'prompt'}
|
|
75
|
+
showLanguage
|
|
76
|
+
>
|
|
77
|
+
{prompt}
|
|
78
|
+
</Highlighter>
|
|
79
|
+
</Flexbox>
|
|
80
|
+
<Error index={index} messageId={messageId} />
|
|
81
|
+
</Flexbox>
|
|
91
82
|
)}
|
|
92
83
|
</Flexbox>
|
|
93
84
|
);
|