@lobehub/chat 0.55.1 → 0.56.0
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 +2 -2
- package/src/const/plugin.ts +1 -0
- package/src/features/AgentSetting/AgentPlugin/index.tsx +7 -7
- package/src/hooks/useImportConfig.ts +7 -0
- package/src/locales/default/plugin.ts +1 -1
- package/src/pages/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +62 -58
- package/src/pages/chat/features/Conversation/ChatList/index.tsx +13 -10
- package/src/pages/chat/features/Header/PluginTag.tsx +1 -1
- package/src/store/plugin/action.ts +5 -5
- package/src/store/plugin/reducers/manifest.ts +2 -2
- package/src/store/plugin/selectors.ts +13 -5
- package/src/store/plugin/store.ts +2 -1
- package/src/store/session/slices/chat/actions/message.ts +18 -18
- package/src/store/session/slices/chat/selectors/utils.test.ts +4 -2
- package/src/store/session/slices/chat/selectors/utils.ts +2 -2
- package/src/types/chatMessage.ts +9 -0
- package/src/types/plugin.ts +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,31 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.56.0](https://github.com/lobehub/lobe-chat/compare/v0.55.1...v0.56.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-24**</sup>
|
|
8
|
+
|
|
9
|
+
#### ✨ Features
|
|
10
|
+
|
|
11
|
+
- **misc**: Use new plugin manifest to support plugin’s multi api.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's improved
|
|
19
|
+
|
|
20
|
+
- **misc**: Use new plugin manifest to support plugin’s multi api, closes [#101](https://github.com/lobehub/lobe-chat/issues/101) ([4534598](https://github.com/lobehub/lobe-chat/commit/4534598))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
5
30
|
### [Version 0.55.1](https://github.com/lobehub/lobe-chat/compare/v0.55.0...v0.55.1)
|
|
6
31
|
|
|
7
32
|
<sup>Released on **2023-08-22**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.56.0",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@emoji-mart/react": "^1",
|
|
69
69
|
"@icons-pack/react-simple-icons": "^8",
|
|
70
70
|
"@lobehub/chat-plugin-sdk": "latest",
|
|
71
|
-
"@lobehub/chat-plugins-gateway": "
|
|
71
|
+
"@lobehub/chat-plugins-gateway": "latest",
|
|
72
72
|
"@lobehub/ui": "latest",
|
|
73
73
|
"@vercel/analytics": "^1",
|
|
74
74
|
"ahooks": "^3",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PLUGIN_SCHEMA_SEPARATOR = '--__--';
|
|
@@ -75,23 +75,23 @@ const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
|
|
|
75
75
|
<Switch
|
|
76
76
|
checked={
|
|
77
77
|
// 如果在加载中,说明激活了
|
|
78
|
-
pluginManifestLoading[item.
|
|
78
|
+
pluginManifestLoading[item.identifier] || !config.plugins
|
|
79
79
|
? false
|
|
80
|
-
: config.plugins.includes(item.
|
|
80
|
+
: config.plugins.includes(item.identifier)
|
|
81
81
|
}
|
|
82
|
-
loading={pluginManifestLoading[item.
|
|
82
|
+
loading={pluginManifestLoading[item.identifier]}
|
|
83
83
|
onChange={(checked) => {
|
|
84
|
-
updateConfig(item.
|
|
84
|
+
updateConfig(item.identifier, checked);
|
|
85
85
|
if (checked) {
|
|
86
|
-
fetchPluginManifest(item.
|
|
86
|
+
fetchPluginManifest(item.identifier);
|
|
87
87
|
}
|
|
88
88
|
}}
|
|
89
89
|
/>
|
|
90
90
|
),
|
|
91
91
|
desc: item.meta?.description,
|
|
92
|
-
label: t(`plugins.${item.
|
|
92
|
+
label: t(`plugins.${item.identifier}` as any, { ns: 'plugin' }),
|
|
93
93
|
minWidth: undefined,
|
|
94
|
-
tag: item.
|
|
94
|
+
tag: item.identifier,
|
|
95
95
|
}));
|
|
96
96
|
|
|
97
97
|
return {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useGlobalStore } from '@/store/global';
|
|
4
|
+
import { usePluginStore } from '@/store/plugin';
|
|
4
5
|
import { useSessionStore } from '@/store/session';
|
|
5
6
|
import { importConfigFile } from '@/utils/config';
|
|
6
7
|
|
|
7
8
|
export const useImportConfig = () => {
|
|
8
9
|
const importSessions = useSessionStore((s) => s.importSessions);
|
|
9
10
|
const importAppSettings = useGlobalStore((s) => s.importAppSettings);
|
|
11
|
+
const checkLocalEnabledPlugins = usePluginStore((s) => s.checkLocalEnabledPlugins);
|
|
10
12
|
|
|
11
13
|
const importConfig = (info: any) => {
|
|
12
14
|
importConfigFile(info, (config) => {
|
|
@@ -19,6 +21,9 @@ export const useImportConfig = () => {
|
|
|
19
21
|
case 'sessions':
|
|
20
22
|
case 'agents': {
|
|
21
23
|
importSessions(config.state.sessions);
|
|
24
|
+
|
|
25
|
+
// 检查一下插件开启情况
|
|
26
|
+
checkLocalEnabledPlugins(config.state.sessions);
|
|
22
27
|
break;
|
|
23
28
|
}
|
|
24
29
|
|
|
@@ -26,6 +31,8 @@ export const useImportConfig = () => {
|
|
|
26
31
|
importSessions(config.state.sessions);
|
|
27
32
|
importAppSettings(config.state.settings);
|
|
28
33
|
|
|
34
|
+
// 检查一下插件开启情况
|
|
35
|
+
checkLocalEnabledPlugins(config.state.sessions);
|
|
29
36
|
break;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
@@ -7,77 +7,81 @@ import { useTranslation } from 'react-i18next';
|
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
8
|
|
|
9
9
|
import { pluginSelectors, usePluginStore } from '@/store/plugin';
|
|
10
|
-
import { OpenAIFunctionCall } from '@/types/chatMessage';
|
|
11
10
|
|
|
12
11
|
import PluginResult from './PluginResultRender';
|
|
13
12
|
import { useStyles } from './style';
|
|
14
13
|
|
|
15
14
|
export interface FunctionCallProps {
|
|
15
|
+
arguments?: string;
|
|
16
|
+
command?: any;
|
|
16
17
|
content: string;
|
|
17
|
-
|
|
18
|
+
id?: string;
|
|
18
19
|
loading?: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const FunctionCall = memo<FunctionCallProps>(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const FunctionCall = memo<FunctionCallProps>(
|
|
23
|
+
({ arguments: requestArgs = '{}', command, loading, content, id = 'unknown' }) => {
|
|
24
|
+
const { t } = useTranslation('plugin');
|
|
25
|
+
const { styles } = useStyles();
|
|
26
|
+
const [open, setOpen] = useState(false);
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
<Avatar avatar={item?.meta.avatar} size={32} />
|
|
29
|
-
) : (
|
|
30
|
-
<Icon icon={LucideToyBrick} />
|
|
31
|
-
);
|
|
28
|
+
const item = usePluginStore(pluginSelectors.getPluginMetaById(id));
|
|
32
29
|
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
const avatar = item?.meta.avatar ? (
|
|
31
|
+
<Avatar avatar={item?.meta.avatar} size={32} />
|
|
32
|
+
) : (
|
|
33
|
+
<Icon icon={LucideToyBrick} />
|
|
34
|
+
);
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
36
|
+
const args = JSON.stringify(command, null, 2);
|
|
37
|
+
const params = JSON.stringify(JSON.parse(requestArgs), null, 2);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Flexbox gap={8}>
|
|
41
|
+
<Flexbox
|
|
42
|
+
align={'center'}
|
|
43
|
+
className={styles.container}
|
|
44
|
+
gap={8}
|
|
45
|
+
horizontal
|
|
46
|
+
onClick={() => {
|
|
47
|
+
setOpen(!open);
|
|
48
|
+
}}
|
|
49
|
+
>
|
|
50
|
+
{loading ? (
|
|
51
|
+
<div>
|
|
52
|
+
<LoadingOutlined />
|
|
53
|
+
</div>
|
|
54
|
+
) : (
|
|
55
|
+
avatar
|
|
56
|
+
)}
|
|
57
|
+
{t(`plugins.${id}` as any, { ns: 'plugin' })}
|
|
58
|
+
<Icon icon={open ? LucideChevronUp : LucideChevronDown} />
|
|
59
|
+
</Flexbox>
|
|
60
|
+
{open && (
|
|
61
|
+
<Tabs
|
|
62
|
+
items={[
|
|
63
|
+
{
|
|
64
|
+
children: <Highlighter language={'json'}>{args}</Highlighter>,
|
|
65
|
+
key: 'function_call',
|
|
66
|
+
label: t('debug.function_call'),
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
children: <Highlighter language={'json'}>{params}</Highlighter>,
|
|
70
|
+
key: 'arguments',
|
|
71
|
+
label: t('debug.arguments'),
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
children: <PluginResult content={content} />,
|
|
75
|
+
key: 'response',
|
|
76
|
+
label: t('debug.response'),
|
|
77
|
+
},
|
|
78
|
+
]}
|
|
79
|
+
style={{ maxWidth: 800 }}
|
|
80
|
+
/>
|
|
53
81
|
)}
|
|
54
|
-
{t(`plugins.${function_call?.name}` as any, { ns: 'plugin' })}
|
|
55
|
-
<Icon icon={open ? LucideChevronUp : LucideChevronDown} />
|
|
56
82
|
</Flexbox>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
{
|
|
61
|
-
children: <Highlighter language={'json'}>{args}</Highlighter>,
|
|
62
|
-
key: 'function_call',
|
|
63
|
-
label: t('debug.function_call'),
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
children: <Highlighter language={'json'}>{params}</Highlighter>,
|
|
67
|
-
key: 'arguments',
|
|
68
|
-
label: t('debug.arguments'),
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
children: <PluginResult content={content} />,
|
|
72
|
-
key: 'response',
|
|
73
|
-
label: t('debug.response'),
|
|
74
|
-
},
|
|
75
|
-
]}
|
|
76
|
-
style={{ maxWidth: 800 }}
|
|
77
|
-
/>
|
|
78
|
-
)}
|
|
79
|
-
</Flexbox>
|
|
80
|
-
);
|
|
81
|
-
});
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
);
|
|
82
86
|
|
|
83
87
|
export default FunctionCall;
|
|
@@ -49,25 +49,28 @@ const List = () => {
|
|
|
49
49
|
|
|
50
50
|
const renderMessage: RenderMessage = useCallback(
|
|
51
51
|
(content, message: ChatMessage) => {
|
|
52
|
+
const id = message.plugin?.identifier || message.function_call?.name;
|
|
53
|
+
const command = message.plugin ?? message.function_call;
|
|
54
|
+
const args = command?.arguments;
|
|
55
|
+
const fcProps = {
|
|
56
|
+
arguments: args,
|
|
57
|
+
command,
|
|
58
|
+
content: message.content,
|
|
59
|
+
id,
|
|
60
|
+
loading: message.id === chatLoadingId,
|
|
61
|
+
};
|
|
62
|
+
|
|
52
63
|
if (message.role === 'function')
|
|
53
64
|
return (
|
|
54
65
|
<Flexbox gap={12}>
|
|
55
|
-
<FunctionCall
|
|
56
|
-
content={message.content}
|
|
57
|
-
function_call={message.function_call}
|
|
58
|
-
loading={message.id === chatLoadingId}
|
|
59
|
-
/>
|
|
66
|
+
<FunctionCall {...fcProps} />
|
|
60
67
|
<PluginMessage loading={message.id === chatLoadingId} {...message} />
|
|
61
68
|
</Flexbox>
|
|
62
69
|
);
|
|
63
70
|
|
|
64
71
|
if (message.role === 'assistant') {
|
|
65
72
|
return isFunctionMessage(message.content) || !!message.function_call ? (
|
|
66
|
-
<FunctionCall
|
|
67
|
-
content={message.content}
|
|
68
|
-
function_call={message.function_call}
|
|
69
|
-
loading={message.id === chatLoadingId}
|
|
70
|
-
/>
|
|
73
|
+
<FunctionCall {...fcProps} />
|
|
71
74
|
) : (
|
|
72
75
|
content
|
|
73
76
|
);
|
|
@@ -19,7 +19,7 @@ const PluginTag = memo<PluginTagProps>(({ plugins }) => {
|
|
|
19
19
|
if (plugins.length === 0) return null;
|
|
20
20
|
|
|
21
21
|
const items: MenuProps['items'] = plugins.map((id) => {
|
|
22
|
-
const item = list?.find((p) => p.
|
|
22
|
+
const item = list?.find((p) => p.identifier === id);
|
|
23
23
|
return {
|
|
24
24
|
icon: (
|
|
25
25
|
<Avatar avatar={item?.meta.avatar} size={24} style={{ marginLeft: -6, marginRight: 2 }} />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
LobeChatPluginManifest,
|
|
3
3
|
LobeChatPluginsMarketIndex,
|
|
4
4
|
pluginManifestSchema,
|
|
5
5
|
} from '@lobehub/chat-plugin-sdk';
|
|
@@ -10,6 +10,7 @@ import useSWR, { SWRResponse } from 'swr';
|
|
|
10
10
|
import { StateCreator } from 'zustand/vanilla';
|
|
11
11
|
|
|
12
12
|
import { getPluginList } from '@/services/plugin';
|
|
13
|
+
import { pluginSelectors } from '@/store/plugin/selectors';
|
|
13
14
|
import { LobeSessions } from '@/types/session';
|
|
14
15
|
import { setNamespace } from '@/utils/storeDebug';
|
|
15
16
|
|
|
@@ -51,7 +52,6 @@ export const createPluginSlice: StateCreator<
|
|
|
51
52
|
|
|
52
53
|
await Promise.all(plugins.map((name) => fetchPluginManifest(name)));
|
|
53
54
|
|
|
54
|
-
console.log('fetched');
|
|
55
55
|
set({ manifestPrepared: true }, false, t('checkLocalEnabledPlugins'));
|
|
56
56
|
},
|
|
57
57
|
dispatchPluginManifest: (payload) => {
|
|
@@ -62,7 +62,7 @@ export const createPluginSlice: StateCreator<
|
|
|
62
62
|
},
|
|
63
63
|
|
|
64
64
|
fetchPluginManifest: async (name) => {
|
|
65
|
-
const plugin =
|
|
65
|
+
const plugin = pluginSelectors.getPluginMetaById(name)(get());
|
|
66
66
|
// 1. 校验文件
|
|
67
67
|
|
|
68
68
|
if (!plugin) return;
|
|
@@ -74,7 +74,7 @@ export const createPluginSlice: StateCreator<
|
|
|
74
74
|
|
|
75
75
|
// 2. 发送请求
|
|
76
76
|
get().updateManifestLoadingState(name, true);
|
|
77
|
-
let data:
|
|
77
|
+
let data: LobeChatPluginManifest | null;
|
|
78
78
|
|
|
79
79
|
try {
|
|
80
80
|
const res = await fetch(plugin.manifest);
|
|
@@ -100,7 +100,7 @@ export const createPluginSlice: StateCreator<
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
// 4. 存储 manifest 信息
|
|
103
|
-
get().dispatchPluginManifest({ id: plugin.
|
|
103
|
+
get().dispatchPluginManifest({ id: plugin.identifier, plugin: data, type: 'addManifest' });
|
|
104
104
|
},
|
|
105
105
|
|
|
106
106
|
updateManifestLoadingState: (key, value) => {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
import { produce } from 'immer';
|
|
3
3
|
|
|
4
4
|
import { PluginManifestMap } from '@/types/plugin';
|
|
5
5
|
|
|
6
|
-
type AddManifestDispatch = { id: string; plugin:
|
|
6
|
+
type AddManifestDispatch = { id: string; plugin: LobeChatPluginManifest; type: 'addManifest' };
|
|
7
7
|
type DeleteManifestDispatch = { id: string; type: 'deleteManifest' };
|
|
8
8
|
// type UpdateManifestDispatch = {
|
|
9
9
|
// id: string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
|
|
2
|
+
|
|
1
3
|
import { PluginStoreState } from './initialState';
|
|
2
4
|
|
|
3
5
|
const enabledSchema =
|
|
@@ -9,15 +11,21 @@ const enabledSchema =
|
|
|
9
11
|
if (!enabledPlugins) return false;
|
|
10
12
|
|
|
11
13
|
// 如果存在 enabledPlugins,那么只启用 enabledPlugins 中的插件
|
|
12
|
-
return enabledPlugins.includes(p.
|
|
14
|
+
return enabledPlugins.includes(p.identifier);
|
|
13
15
|
})
|
|
14
|
-
.
|
|
16
|
+
.flatMap((manifest) =>
|
|
17
|
+
manifest.api.map((m) => ({
|
|
18
|
+
...m,
|
|
19
|
+
// 将插件的 identifier 作为前缀,避免重复
|
|
20
|
+
name: manifest.identifier + PLUGIN_SCHEMA_SEPARATOR + m.name,
|
|
21
|
+
})),
|
|
22
|
+
);
|
|
15
23
|
};
|
|
16
24
|
|
|
17
|
-
const
|
|
18
|
-
s.pluginList?.find((p) => p.
|
|
25
|
+
const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
|
|
26
|
+
s.pluginList?.find((p) => p.identifier === id);
|
|
19
27
|
|
|
20
28
|
export const pluginSelectors = {
|
|
21
29
|
enabledSchema,
|
|
22
|
-
|
|
30
|
+
getPluginMetaById,
|
|
23
31
|
};
|
|
@@ -19,7 +19,7 @@ const createStore: StateCreator<PluginStore, [['zustand/devtools', never]]> = (.
|
|
|
19
19
|
|
|
20
20
|
// =============== persist 本地缓存中间件配置 ============ //
|
|
21
21
|
|
|
22
|
-
type SessionPersist = Pick<PluginStore, 'pluginList'>;
|
|
22
|
+
type SessionPersist = Pick<PluginStore, 'pluginList' | 'pluginManifestMap'>;
|
|
23
23
|
|
|
24
24
|
const storeName = 'LOBE_PLUGIN';
|
|
25
25
|
|
|
@@ -28,6 +28,7 @@ const persistOptions: PersistOptions<PluginStore, SessionPersist> = {
|
|
|
28
28
|
|
|
29
29
|
partialize: (s) => ({
|
|
30
30
|
pluginList: s.pluginList,
|
|
31
|
+
pluginManifestMap: s.pluginManifestMap,
|
|
31
32
|
}),
|
|
32
33
|
|
|
33
34
|
// 手动控制 Hydration ,避免 ssr 报错
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
|
|
1
2
|
import { template } from 'lodash-es';
|
|
2
3
|
import { StateCreator } from 'zustand/vanilla';
|
|
3
4
|
|
|
4
5
|
import { LOADING_FLAT } from '@/const/message';
|
|
6
|
+
import { PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
|
|
5
7
|
import { fetchChatModel } from '@/services/chatModel';
|
|
6
8
|
import { fetchPlugin } from '@/services/plugin';
|
|
7
9
|
import { SessionStore } from '@/store/session';
|
|
@@ -319,32 +321,30 @@ export const chatMessage: StateCreator<
|
|
|
319
321
|
const message = session.chats[id];
|
|
320
322
|
if (!message) return;
|
|
321
323
|
|
|
322
|
-
let payload:
|
|
324
|
+
let payload: PluginRequestPayload = { apiName: '', identifier: '' };
|
|
325
|
+
// 识别到内容是 function_call 的情况下
|
|
326
|
+
// 将 function_call 转换为 plugin request payload
|
|
323
327
|
if (message.content) {
|
|
324
|
-
const { function_call } = JSON.parse(message.content)
|
|
325
|
-
|
|
328
|
+
const { function_call } = JSON.parse(message.content) as {
|
|
329
|
+
function_call: OpenAIFunctionCall;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
const [identifier, apiName] = function_call.name.split(PLUGIN_SCHEMA_SEPARATOR);
|
|
333
|
+
payload = { apiName, arguments: function_call.arguments, identifier };
|
|
334
|
+
|
|
335
|
+
dispatchMessage({ id, key: 'plugin', type: 'updateMessage', value: payload });
|
|
326
336
|
dispatchMessage({ id, key: 'content', type: 'updateMessage', value: '' });
|
|
327
|
-
payload = function_call;
|
|
328
337
|
} else {
|
|
329
|
-
if (message.
|
|
330
|
-
payload = message.
|
|
338
|
+
if (message.plugin) {
|
|
339
|
+
payload = message.plugin;
|
|
331
340
|
}
|
|
332
341
|
}
|
|
333
342
|
|
|
334
|
-
if (!payload.
|
|
343
|
+
if (!payload.apiName) return;
|
|
335
344
|
|
|
336
|
-
// const fid = nanoid();
|
|
337
345
|
dispatchMessage({ id, key: 'role', type: 'updateMessage', value: 'function' });
|
|
338
|
-
dispatchMessage({ id, key: 'name', type: 'updateMessage', value: payload.
|
|
339
|
-
dispatchMessage({ id, key: '
|
|
340
|
-
|
|
341
|
-
// dispatchMessage({
|
|
342
|
-
// id: id,
|
|
343
|
-
// message: FUNCTION_LOADING,
|
|
344
|
-
// parentId: message.,
|
|
345
|
-
// role: 'function',
|
|
346
|
-
// type: 'addMessage',
|
|
347
|
-
// });
|
|
346
|
+
dispatchMessage({ id, key: 'name', type: 'updateMessage', value: payload.identifier });
|
|
347
|
+
dispatchMessage({ id, key: 'plugin', type: 'updateMessage', value: payload });
|
|
348
348
|
|
|
349
349
|
const abortController = toggleChatLoading(true, id);
|
|
350
350
|
const data = await fetchPlugin(payload, { signal: abortController?.signal });
|
|
@@ -342,14 +342,16 @@ describe('organizeChats', () => {
|
|
|
342
342
|
...params,
|
|
343
343
|
pluginList: [
|
|
344
344
|
{
|
|
345
|
-
|
|
345
|
+
identifier: 'realtimeWeather',
|
|
346
|
+
author: '123',
|
|
346
347
|
meta: {
|
|
347
348
|
avatar: '🧩',
|
|
349
|
+
title: '天气预报',
|
|
348
350
|
},
|
|
349
351
|
createAt: 'abc',
|
|
350
352
|
manifest: '',
|
|
351
353
|
homepage: '',
|
|
352
|
-
schemaVersion:
|
|
354
|
+
schemaVersion: 1,
|
|
353
355
|
},
|
|
354
356
|
],
|
|
355
357
|
});
|
|
@@ -38,11 +38,11 @@ export const organizeChats = (
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
case 'function': {
|
|
41
|
-
const plugin = (pluginList || []).find((m) => m.
|
|
41
|
+
const plugin = (pluginList || []).find((m) => m.identifier === message.name);
|
|
42
42
|
|
|
43
43
|
return {
|
|
44
44
|
avatar: '🧩',
|
|
45
|
-
title: plugin?.
|
|
45
|
+
title: plugin?.identifier || 'plugin-unknown',
|
|
46
46
|
};
|
|
47
47
|
}
|
|
48
48
|
}
|
package/src/types/chatMessage.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
1
3
|
import { ErrorType } from '@/types/fetch';
|
|
2
4
|
|
|
3
5
|
import { LLMRoleType } from './llm';
|
|
@@ -33,10 +35,17 @@ export interface ChatMessage extends BaseDataModel {
|
|
|
33
35
|
};
|
|
34
36
|
} & Record<string, any>;
|
|
35
37
|
|
|
38
|
+
/**
|
|
39
|
+
* replace with plugin
|
|
40
|
+
* @deprecated
|
|
41
|
+
*/
|
|
36
42
|
function_call?: OpenAIFunctionCall;
|
|
37
43
|
name?: string;
|
|
38
44
|
|
|
39
45
|
parentId?: string;
|
|
46
|
+
|
|
47
|
+
plugin?: PluginRequestPayload;
|
|
48
|
+
|
|
40
49
|
// 引用
|
|
41
50
|
quotaId?: string;
|
|
42
51
|
/**
|
package/src/types/plugin.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
|
|
3
|
-
export type PluginManifestMap = Record<string,
|
|
3
|
+
export type PluginManifestMap = Record<string, LobeChatPluginManifest>;
|