@lobehub/chat 0.63.2 → 0.64.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 +62 -0
- package/package.json +1 -1
- package/src/components/EmojiPicker/index.tsx +13 -5
- package/src/const/url.ts +1 -1
- package/src/features/AgentSetting/AgentMeta/index.tsx +1 -1
- package/src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx +72 -0
- package/src/features/AgentSetting/AgentPlugin/MarketList.tsx +160 -0
- package/src/features/AgentSetting/AgentPlugin/PluginSettings.tsx +76 -0
- package/src/features/AgentSetting/AgentPlugin/index.tsx +8 -143
- package/src/features/PluginDevModal/ManifestForm.tsx +96 -0
- package/src/features/PluginDevModal/MetaForm.tsx +90 -0
- package/src/features/PluginDevModal/PluginPreview.tsx +36 -0
- package/src/features/PluginDevModal/index.tsx +153 -0
- package/src/locales/default/error.ts +2 -0
- package/src/locales/default/plugin.ts +79 -3
- package/src/locales/default/setting.ts +3 -0
- package/src/pages/chat/features/Conversation/ChatList/Error/index.tsx +2 -1
- package/src/pages/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +7 -4
- package/src/pages/chat/features/Conversation/ChatList/Plugins/PluginMessage.tsx +27 -33
- package/src/services/plugin.ts +6 -3
- package/src/store/plugin/action.ts +23 -2
- package/src/store/plugin/initialState.ts +17 -1
- package/src/store/plugin/reducers/devPluginList.ts +56 -0
- package/src/store/plugin/selectors.ts +9 -2
- package/src/store/plugin/store.ts +5 -1
|
@@ -14,6 +14,8 @@ import { pluginSelectors } from '@/store/plugin/selectors';
|
|
|
14
14
|
import { LobeSessions } from '@/types/session';
|
|
15
15
|
import { setNamespace } from '@/utils/storeDebug';
|
|
16
16
|
|
|
17
|
+
import { DevPlugin, defaultDevPlugin } from './initialState';
|
|
18
|
+
import { DevListDispatch, devPluginListReducer } from './reducers/devPluginList';
|
|
17
19
|
import { PluginDispatch, pluginManifestReducer } from './reducers/manifest';
|
|
18
20
|
import { PluginStore } from './store';
|
|
19
21
|
|
|
@@ -24,9 +26,12 @@ const t = setNamespace('plugin');
|
|
|
24
26
|
*/
|
|
25
27
|
export interface PluginAction {
|
|
26
28
|
checkLocalEnabledPlugins: (sessions: LobeSessions) => void;
|
|
29
|
+
dispatchDevPluginList: (payload: DevListDispatch) => void;
|
|
27
30
|
dispatchPluginManifest: (payload: PluginDispatch) => void;
|
|
28
31
|
fetchPluginManifest: (name: string) => Promise<void>;
|
|
32
|
+
saveToDevList: (value: DevPlugin) => void;
|
|
29
33
|
updateManifestLoadingState: (key: string, value: boolean | undefined) => void;
|
|
34
|
+
updateNewDevPlugin: (value: Partial<DevPlugin>) => void;
|
|
30
35
|
updatePluginSettings: <T>(id: string, settings: Partial<T>) => void;
|
|
31
36
|
useFetchPluginList: () => SWRResponse<LobeChatPluginsMarketIndex>;
|
|
32
37
|
}
|
|
@@ -55,13 +60,18 @@ export const createPluginSlice: StateCreator<
|
|
|
55
60
|
|
|
56
61
|
set({ manifestPrepared: true }, false, t('checkLocalEnabledPlugins'));
|
|
57
62
|
},
|
|
63
|
+
dispatchDevPluginList: (payload) => {
|
|
64
|
+
const { devPluginList } = get();
|
|
65
|
+
|
|
66
|
+
const nextList = devPluginListReducer(devPluginList, payload);
|
|
67
|
+
set({ devPluginList: nextList }, false, t('dispatchDevList', payload));
|
|
68
|
+
},
|
|
58
69
|
dispatchPluginManifest: (payload) => {
|
|
59
70
|
const { pluginManifestMap } = get();
|
|
60
71
|
const nextManifest = pluginManifestReducer(pluginManifestMap, payload);
|
|
61
72
|
|
|
62
73
|
set({ pluginManifestMap: nextManifest }, false, t('dispatchPluginManifest', payload));
|
|
63
74
|
},
|
|
64
|
-
|
|
65
75
|
fetchPluginManifest: async (name) => {
|
|
66
76
|
const plugin = pluginSelectors.getPluginMetaById(name)(get());
|
|
67
77
|
// 1. 校验文件
|
|
@@ -103,6 +113,10 @@ export const createPluginSlice: StateCreator<
|
|
|
103
113
|
// 4. 存储 manifest 信息
|
|
104
114
|
get().dispatchPluginManifest({ id: plugin.identifier, plugin: data, type: 'addManifest' });
|
|
105
115
|
},
|
|
116
|
+
saveToDevList: (value) => {
|
|
117
|
+
get().dispatchDevPluginList({ plugin: value, type: 'addItem' });
|
|
118
|
+
set({ newDevPlugin: defaultDevPlugin }, false, t('saveToDevList'));
|
|
119
|
+
},
|
|
106
120
|
|
|
107
121
|
updateManifestLoadingState: (key, value) => {
|
|
108
122
|
set(
|
|
@@ -113,7 +127,13 @@ export const createPluginSlice: StateCreator<
|
|
|
113
127
|
t('updateManifestLoadingState'),
|
|
114
128
|
);
|
|
115
129
|
},
|
|
116
|
-
|
|
130
|
+
updateNewDevPlugin: (newDevPlugin) => {
|
|
131
|
+
set(
|
|
132
|
+
{ newDevPlugin: merge({}, get().newDevPlugin, newDevPlugin) },
|
|
133
|
+
false,
|
|
134
|
+
t('updateNewDevPlugin'),
|
|
135
|
+
);
|
|
136
|
+
},
|
|
117
137
|
updatePluginSettings: (id, settings) => {
|
|
118
138
|
set(
|
|
119
139
|
produce((draft) => {
|
|
@@ -123,6 +143,7 @@ export const createPluginSlice: StateCreator<
|
|
|
123
143
|
t('updatePluginSettings'),
|
|
124
144
|
);
|
|
125
145
|
},
|
|
146
|
+
|
|
126
147
|
useFetchPluginList: () =>
|
|
127
148
|
useSWR<LobeChatPluginsMarketIndex>('fetchPluginList', getPluginList, {
|
|
128
149
|
onSuccess: (pluginMarketIndex) => {
|
|
@@ -1,20 +1,36 @@
|
|
|
1
|
-
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
1
|
+
import { LobeChatPluginManifest, LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
|
|
3
3
|
import { PluginManifestMap } from '@/types/plugin';
|
|
4
4
|
|
|
5
5
|
export type PluginManifestLoadingState = Record<string, boolean>;
|
|
6
6
|
export type PluginsSettings = Record<string, any>;
|
|
7
7
|
|
|
8
|
+
export interface DevPlugin extends LobeChatPluginMeta {
|
|
9
|
+
apiMode: 'openapi' | 'simple';
|
|
10
|
+
enableSettings: boolean;
|
|
11
|
+
manifestConfig?: LobeChatPluginManifest;
|
|
12
|
+
manifestMode: 'local' | 'url';
|
|
13
|
+
}
|
|
14
|
+
|
|
8
15
|
export interface PluginStoreState {
|
|
16
|
+
devPluginList: DevPlugin[];
|
|
9
17
|
manifestPrepared: boolean;
|
|
18
|
+
newDevPlugin: Partial<DevPlugin>;
|
|
10
19
|
pluginList: LobeChatPluginMeta[];
|
|
11
20
|
pluginManifestLoading: PluginManifestLoadingState;
|
|
12
21
|
pluginManifestMap: PluginManifestMap;
|
|
13
22
|
pluginsSettings: PluginsSettings;
|
|
14
23
|
}
|
|
24
|
+
export const defaultDevPlugin: Partial<DevPlugin> = {
|
|
25
|
+
apiMode: 'simple',
|
|
26
|
+
enableSettings: false,
|
|
27
|
+
manifestMode: 'url',
|
|
28
|
+
};
|
|
15
29
|
|
|
16
30
|
export const initialState: PluginStoreState = {
|
|
31
|
+
devPluginList: [],
|
|
17
32
|
manifestPrepared: false,
|
|
33
|
+
newDevPlugin: defaultDevPlugin,
|
|
18
34
|
pluginList: [],
|
|
19
35
|
pluginManifestLoading: {},
|
|
20
36
|
pluginManifestMap: {},
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { produce } from 'immer';
|
|
2
|
+
|
|
3
|
+
import { DevPlugin } from '../initialState';
|
|
4
|
+
|
|
5
|
+
export type DevListState = DevPlugin[];
|
|
6
|
+
|
|
7
|
+
export type AddPluginAction = {
|
|
8
|
+
plugin: DevPlugin;
|
|
9
|
+
type: 'addItem';
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type DeletePluginAction = {
|
|
13
|
+
id: string;
|
|
14
|
+
type: 'deleteItem';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type UpdatePluginAction = {
|
|
18
|
+
id: string;
|
|
19
|
+
plugin: DevPlugin;
|
|
20
|
+
type: 'updateItem';
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export type DevListDispatch = AddPluginAction | DeletePluginAction | UpdatePluginAction;
|
|
24
|
+
|
|
25
|
+
export const devPluginListReducer = (
|
|
26
|
+
state: DevListState,
|
|
27
|
+
payload: DevListDispatch,
|
|
28
|
+
): DevListState => {
|
|
29
|
+
switch (payload.type) {
|
|
30
|
+
case 'addItem': {
|
|
31
|
+
return [...state, payload.plugin];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
case 'deleteItem': {
|
|
35
|
+
return produce(state, (draftState) => {
|
|
36
|
+
const deleteIndex = state.findIndex((plugin) => plugin.identifier === payload.id);
|
|
37
|
+
if (deleteIndex !== -1) {
|
|
38
|
+
draftState.splice(deleteIndex, 1);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
case 'updateItem': {
|
|
44
|
+
return produce(state, (draftState) => {
|
|
45
|
+
const updateIndex = state.findIndex((plugin) => plugin.identifier === payload.id);
|
|
46
|
+
if (updateIndex !== -1) {
|
|
47
|
+
draftState[updateIndex] = payload.plugin;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
default: {
|
|
53
|
+
return state;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
};
|
|
@@ -23,8 +23,13 @@ const enabledSchema =
|
|
|
23
23
|
);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
const pluginList = (s: PluginStoreState) => [...s.pluginList, ...s.devPluginList];
|
|
27
|
+
|
|
26
28
|
const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
|
|
27
|
-
pluginHelpers.getPluginFormList(s
|
|
29
|
+
pluginHelpers.getPluginFormList(pluginList(s), id);
|
|
30
|
+
|
|
31
|
+
const getDevPluginById = (id: string) => (s: PluginStoreState) =>
|
|
32
|
+
s.devPluginList.find((i) => i.identifier === id);
|
|
28
33
|
|
|
29
34
|
const getPluginManifestById = (id: string) => (s: PluginStoreState) => s.pluginManifestMap[id];
|
|
30
35
|
const getPluginSettingsById = (id: string) => (s: PluginStoreState) => s.pluginsSettings[id];
|
|
@@ -41,7 +46,7 @@ const getPluginManifestLoadingStatus = (id: string) => (s: PluginStoreState) =>
|
|
|
41
46
|
};
|
|
42
47
|
|
|
43
48
|
const displayPluginList = (s: PluginStoreState) =>
|
|
44
|
-
s.
|
|
49
|
+
pluginList(s).map((p) => ({
|
|
45
50
|
author: p.author,
|
|
46
51
|
avatar: p.meta?.avatar,
|
|
47
52
|
createAt: p.createAt,
|
|
@@ -54,8 +59,10 @@ const displayPluginList = (s: PluginStoreState) =>
|
|
|
54
59
|
export const pluginSelectors = {
|
|
55
60
|
displayPluginList,
|
|
56
61
|
enabledSchema,
|
|
62
|
+
getDevPluginById,
|
|
57
63
|
getPluginManifestById,
|
|
58
64
|
getPluginManifestLoadingStatus,
|
|
59
65
|
getPluginMetaById,
|
|
60
66
|
getPluginSettingsById,
|
|
67
|
+
pluginList,
|
|
61
68
|
};
|
|
@@ -19,7 +19,10 @@ const createStore: StateCreator<PluginStore, [['zustand/devtools', never]]> = (.
|
|
|
19
19
|
|
|
20
20
|
// =============== persist 本地缓存中间件配置 ============ //
|
|
21
21
|
|
|
22
|
-
type SessionPersist = Pick<
|
|
22
|
+
type SessionPersist = Pick<
|
|
23
|
+
PluginStore,
|
|
24
|
+
'pluginList' | 'pluginManifestMap' | 'pluginsSettings' | 'devPluginList'
|
|
25
|
+
>;
|
|
23
26
|
|
|
24
27
|
const storeName = 'LOBE_PLUGIN';
|
|
25
28
|
|
|
@@ -27,6 +30,7 @@ const persistOptions: PersistOptions<PluginStore, SessionPersist> = {
|
|
|
27
30
|
name: storeName,
|
|
28
31
|
|
|
29
32
|
partialize: (s) => ({
|
|
33
|
+
devPluginList: s.devPluginList,
|
|
30
34
|
pluginList: s.pluginList,
|
|
31
35
|
pluginManifestMap: s.pluginManifestMap,
|
|
32
36
|
pluginsSettings: s.pluginsSettings,
|