@lobehub/chat 0.65.1 → 0.67.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 +68 -0
- package/locales/ru_RU/common.json +85 -0
- package/locales/ru_RU/empty.json +6 -0
- package/locales/ru_RU/error.json +41 -0
- package/locales/ru_RU/plugin.json +111 -0
- package/locales/ru_RU/setting.json +175 -0
- package/locales/ru_RU/welcome.json +14 -0
- package/package.json +1 -1
- package/src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx +10 -8
- package/src/features/AgentSetting/AgentPlugin/MarketList.tsx +29 -13
- package/src/features/PluginDevModal/ManifestForm.tsx +150 -86
- package/src/features/PluginDevModal/MetaForm.tsx +16 -17
- package/src/features/PluginDevModal/PluginPreview.tsx +9 -8
- package/src/features/PluginDevModal/index.tsx +26 -23
- package/src/locales/default/plugin.ts +9 -5
- package/src/locales/options.ts +4 -0
- package/src/locales/resources/index.ts +2 -0
- package/src/locales/resources/ru_RU.ts +17 -0
- package/src/store/plugin/initialState.ts +5 -34
- package/src/store/plugin/selectors.ts +2 -2
- package/src/store/plugin/slices/customPlugin/action.ts +64 -0
- package/src/store/plugin/slices/customPlugin/index.ts +3 -0
- package/src/store/plugin/slices/customPlugin/initialState.ts +16 -0
- package/src/store/plugin/{reducers/devPluginList.ts → slices/customPlugin/reducers/customPluginList.ts} +6 -6
- package/src/store/plugin/{action.ts → slices/plugin/action.ts} +13 -25
- package/src/store/plugin/slices/plugin/index.ts +3 -0
- package/src/store/plugin/slices/plugin/initialState.ts +22 -0
- package/src/store/plugin/store.ts +6 -4
- package/src/types/plugin.ts +8 -1
- /package/src/store/plugin/{reducers → slices/plugin/reducers}/manifest.ts +0 -0
|
@@ -1,38 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CustomPluginState, initialCustomPluginState } from './slices/customPlugin';
|
|
2
|
+
import { PluginState, initialPluginState } from './slices/plugin';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export type PluginManifestLoadingState = Record<string, boolean>;
|
|
6
|
-
export type PluginsSettings = Record<string, any>;
|
|
7
|
-
|
|
8
|
-
export interface DevPlugin extends LobeChatPluginMeta {
|
|
9
|
-
apiMode: 'openapi' | 'simple';
|
|
10
|
-
enableSettings: boolean;
|
|
11
|
-
manifestConfig?: LobeChatPluginManifest;
|
|
12
|
-
manifestMode: 'local' | 'url';
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export interface PluginStoreState {
|
|
16
|
-
devPluginList: DevPlugin[];
|
|
17
|
-
manifestPrepared: boolean;
|
|
18
|
-
newDevPlugin: Partial<DevPlugin>;
|
|
19
|
-
pluginList: LobeChatPluginMeta[];
|
|
20
|
-
pluginManifestLoading: PluginManifestLoadingState;
|
|
21
|
-
pluginManifestMap: PluginManifestMap;
|
|
22
|
-
pluginsSettings: PluginsSettings;
|
|
23
|
-
}
|
|
24
|
-
export const defaultDevPlugin: Partial<DevPlugin> = {
|
|
25
|
-
apiMode: 'simple',
|
|
26
|
-
enableSettings: false,
|
|
27
|
-
manifestMode: 'url',
|
|
28
|
-
};
|
|
4
|
+
export type PluginStoreState = PluginState & CustomPluginState;
|
|
29
5
|
|
|
30
6
|
export const initialState: PluginStoreState = {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
newDevPlugin: defaultDevPlugin,
|
|
34
|
-
pluginList: [],
|
|
35
|
-
pluginManifestLoading: {},
|
|
36
|
-
pluginManifestMap: {},
|
|
37
|
-
pluginsSettings: {},
|
|
7
|
+
...initialPluginState,
|
|
8
|
+
...initialCustomPluginState,
|
|
38
9
|
};
|
|
@@ -23,13 +23,13 @@ const enabledSchema =
|
|
|
23
23
|
);
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
-
const pluginList = (s: PluginStoreState) => [...s.pluginList, ...s.
|
|
26
|
+
const pluginList = (s: PluginStoreState) => [...s.pluginList, ...s.customPluginList];
|
|
27
27
|
|
|
28
28
|
const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
|
|
29
29
|
pluginHelpers.getPluginFormList(pluginList(s), id);
|
|
30
30
|
|
|
31
31
|
const getDevPluginById = (id: string) => (s: PluginStoreState) =>
|
|
32
|
-
s.
|
|
32
|
+
s.customPluginList.find((i) => i.identifier === id);
|
|
33
33
|
|
|
34
34
|
const getPluginManifestById = (id: string) => (s: PluginStoreState) => s.pluginManifestMap[id];
|
|
35
35
|
const getPluginSettingsById = (id: string) => (s: PluginStoreState) => s.pluginsSettings[id];
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { merge } from 'lodash-es';
|
|
2
|
+
import { StateCreator } from 'zustand/vanilla';
|
|
3
|
+
|
|
4
|
+
import { CustomPlugin } from '@/types/plugin';
|
|
5
|
+
import { setNamespace } from '@/utils/storeDebug';
|
|
6
|
+
|
|
7
|
+
import { PluginStore } from '../../store';
|
|
8
|
+
import { defaultCustomPlugin } from './initialState';
|
|
9
|
+
import { CustomPluginListDispatch, devPluginListReducer } from './reducers/customPluginList';
|
|
10
|
+
|
|
11
|
+
const t = setNamespace('customPlugin');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 代理行为接口
|
|
15
|
+
*/
|
|
16
|
+
export interface CustomPluginAction {
|
|
17
|
+
deleteCustomPlugin: (id: string) => void;
|
|
18
|
+
dispatchCustomPluginList: (payload: CustomPluginListDispatch) => void;
|
|
19
|
+
saveToCustomPluginList: (value: CustomPlugin) => void;
|
|
20
|
+
updateCustomPlugin: (id: string, value: CustomPlugin) => void;
|
|
21
|
+
updateNewCustomPlugin: (value: Partial<CustomPlugin>) => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createCustomPluginSlice: StateCreator<
|
|
25
|
+
PluginStore,
|
|
26
|
+
[['zustand/devtools', never]],
|
|
27
|
+
[],
|
|
28
|
+
CustomPluginAction
|
|
29
|
+
> = (set, get) => ({
|
|
30
|
+
deleteCustomPlugin: (id) => {
|
|
31
|
+
const { dispatchCustomPluginList, dispatchPluginManifest, deletePluginSettings } = get();
|
|
32
|
+
// 1.删除插件项
|
|
33
|
+
dispatchCustomPluginList({ id, type: 'deleteItem' });
|
|
34
|
+
// 2.删除本地 manifest 记录
|
|
35
|
+
dispatchPluginManifest({ id, type: 'deleteManifest' });
|
|
36
|
+
// 3.删除插件配置
|
|
37
|
+
deletePluginSettings(id);
|
|
38
|
+
},
|
|
39
|
+
dispatchCustomPluginList: (payload) => {
|
|
40
|
+
const { customPluginList } = get();
|
|
41
|
+
|
|
42
|
+
const nextList = devPluginListReducer(customPluginList, payload);
|
|
43
|
+
set({ customPluginList: nextList }, false, t('dispatchCustomPluginList', payload));
|
|
44
|
+
},
|
|
45
|
+
saveToCustomPluginList: (value) => {
|
|
46
|
+
get().dispatchCustomPluginList({ plugin: value, type: 'addItem' });
|
|
47
|
+
set({ newCustomPlugin: defaultCustomPlugin }, false, t('saveToCustomPluginList'));
|
|
48
|
+
},
|
|
49
|
+
updateCustomPlugin: (id, value) => {
|
|
50
|
+
const { dispatchCustomPluginList, fetchPluginManifest } = get();
|
|
51
|
+
// 1. 更新 list 项信息
|
|
52
|
+
dispatchCustomPluginList({ id, plugin: value, type: 'updateItem' });
|
|
53
|
+
// 2. 更新 重新拉取 manifest
|
|
54
|
+
fetchPluginManifest(id);
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
updateNewCustomPlugin: (newCustomPlugin) => {
|
|
58
|
+
set(
|
|
59
|
+
{ newCustomPlugin: merge({}, get().newCustomPlugin, newCustomPlugin) },
|
|
60
|
+
false,
|
|
61
|
+
t('updateNewDevPlugin'),
|
|
62
|
+
);
|
|
63
|
+
},
|
|
64
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CustomPlugin } from '@/types/plugin';
|
|
2
|
+
|
|
3
|
+
export interface CustomPluginState {
|
|
4
|
+
customPluginList: CustomPlugin[];
|
|
5
|
+
newCustomPlugin: Partial<CustomPlugin>;
|
|
6
|
+
}
|
|
7
|
+
export const defaultCustomPlugin: Partial<CustomPlugin> = {
|
|
8
|
+
apiMode: 'simple',
|
|
9
|
+
enableSettings: false,
|
|
10
|
+
manifestMode: 'url',
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const initialCustomPluginState: CustomPluginState = {
|
|
14
|
+
customPluginList: [],
|
|
15
|
+
newCustomPlugin: defaultCustomPlugin,
|
|
16
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { produce } from 'immer';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CustomPlugin } from '@/types/plugin';
|
|
4
4
|
|
|
5
|
-
export type DevListState =
|
|
5
|
+
export type DevListState = CustomPlugin[];
|
|
6
6
|
|
|
7
7
|
export type AddPluginAction = {
|
|
8
|
-
plugin:
|
|
8
|
+
plugin: CustomPlugin;
|
|
9
9
|
type: 'addItem';
|
|
10
10
|
};
|
|
11
11
|
|
|
@@ -16,15 +16,15 @@ export type DeletePluginAction = {
|
|
|
16
16
|
|
|
17
17
|
export type UpdatePluginAction = {
|
|
18
18
|
id: string;
|
|
19
|
-
plugin:
|
|
19
|
+
plugin: CustomPlugin;
|
|
20
20
|
type: 'updateItem';
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export type
|
|
23
|
+
export type CustomPluginListDispatch = AddPluginAction | DeletePluginAction | UpdatePluginAction;
|
|
24
24
|
|
|
25
25
|
export const devPluginListReducer = (
|
|
26
26
|
state: DevListState,
|
|
27
|
-
payload:
|
|
27
|
+
payload: CustomPluginListDispatch,
|
|
28
28
|
): DevListState => {
|
|
29
29
|
switch (payload.type) {
|
|
30
30
|
case 'addItem': {
|
|
@@ -14,10 +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 {
|
|
18
|
-
import { DevListDispatch, devPluginListReducer } from './reducers/devPluginList';
|
|
17
|
+
import { PluginStore } from '../../store';
|
|
19
18
|
import { PluginDispatch, pluginManifestReducer } from './reducers/manifest';
|
|
20
|
-
import { PluginStore } from './store';
|
|
21
19
|
|
|
22
20
|
const t = setNamespace('plugin');
|
|
23
21
|
|
|
@@ -26,12 +24,10 @@ const t = setNamespace('plugin');
|
|
|
26
24
|
*/
|
|
27
25
|
export interface PluginAction {
|
|
28
26
|
checkLocalEnabledPlugins: (sessions: LobeSessions) => void;
|
|
29
|
-
|
|
27
|
+
deletePluginSettings: (id: string) => void;
|
|
30
28
|
dispatchPluginManifest: (payload: PluginDispatch) => void;
|
|
31
|
-
fetchPluginManifest: (
|
|
32
|
-
saveToDevList: (value: DevPlugin) => void;
|
|
29
|
+
fetchPluginManifest: (identifier: string) => Promise<void>;
|
|
33
30
|
updateManifestLoadingState: (key: string, value: boolean | undefined) => void;
|
|
34
|
-
updateNewDevPlugin: (value: Partial<DevPlugin>) => void;
|
|
35
31
|
updatePluginSettings: <T>(id: string, settings: Partial<T>) => void;
|
|
36
32
|
useFetchPluginList: () => SWRResponse<LobeChatPluginsMarketIndex>;
|
|
37
33
|
}
|
|
@@ -56,15 +52,18 @@ export const createPluginSlice: StateCreator<
|
|
|
56
52
|
|
|
57
53
|
const plugins = uniq(enabledPlugins);
|
|
58
54
|
|
|
59
|
-
await Promise.all(plugins.map((
|
|
55
|
+
await Promise.all(plugins.map((identifier) => fetchPluginManifest(identifier)));
|
|
60
56
|
|
|
61
57
|
set({ manifestPrepared: true }, false, t('checkLocalEnabledPlugins'));
|
|
62
58
|
},
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
deletePluginSettings: (id) => {
|
|
60
|
+
set(
|
|
61
|
+
produce((draft) => {
|
|
62
|
+
draft.pluginsSettings[id] = undefined;
|
|
63
|
+
}),
|
|
64
|
+
false,
|
|
65
|
+
t('deletePluginSettings'),
|
|
66
|
+
);
|
|
68
67
|
},
|
|
69
68
|
dispatchPluginManifest: (payload) => {
|
|
70
69
|
const { pluginManifestMap } = get();
|
|
@@ -72,6 +71,7 @@ export const createPluginSlice: StateCreator<
|
|
|
72
71
|
|
|
73
72
|
set({ pluginManifestMap: nextManifest }, false, t('dispatchPluginManifest', payload));
|
|
74
73
|
},
|
|
74
|
+
|
|
75
75
|
fetchPluginManifest: async (name) => {
|
|
76
76
|
const plugin = pluginSelectors.getPluginMetaById(name)(get());
|
|
77
77
|
// 1. 校验文件
|
|
@@ -113,11 +113,6 @@ export const createPluginSlice: StateCreator<
|
|
|
113
113
|
// 4. 存储 manifest 信息
|
|
114
114
|
get().dispatchPluginManifest({ id: plugin.identifier, plugin: data, type: 'addManifest' });
|
|
115
115
|
},
|
|
116
|
-
saveToDevList: (value) => {
|
|
117
|
-
get().dispatchDevPluginList({ plugin: value, type: 'addItem' });
|
|
118
|
-
set({ newDevPlugin: defaultDevPlugin }, false, t('saveToDevList'));
|
|
119
|
-
},
|
|
120
|
-
|
|
121
116
|
updateManifestLoadingState: (key, value) => {
|
|
122
117
|
set(
|
|
123
118
|
produce((draft) => {
|
|
@@ -127,13 +122,6 @@ export const createPluginSlice: StateCreator<
|
|
|
127
122
|
t('updateManifestLoadingState'),
|
|
128
123
|
);
|
|
129
124
|
},
|
|
130
|
-
updateNewDevPlugin: (newDevPlugin) => {
|
|
131
|
-
set(
|
|
132
|
-
{ newDevPlugin: merge({}, get().newDevPlugin, newDevPlugin) },
|
|
133
|
-
false,
|
|
134
|
-
t('updateNewDevPlugin'),
|
|
135
|
-
);
|
|
136
|
-
},
|
|
137
125
|
updatePluginSettings: (id, settings) => {
|
|
138
126
|
set(
|
|
139
127
|
produce((draft) => {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
3
|
+
import { PluginManifestMap } from '@/types/plugin';
|
|
4
|
+
|
|
5
|
+
export type PluginManifestLoadingState = Record<string, boolean>;
|
|
6
|
+
export type PluginsSettings = Record<string, any>;
|
|
7
|
+
|
|
8
|
+
export interface PluginState {
|
|
9
|
+
manifestPrepared: boolean;
|
|
10
|
+
pluginList: LobeChatPluginMeta[];
|
|
11
|
+
pluginManifestLoading: PluginManifestLoadingState;
|
|
12
|
+
pluginManifestMap: PluginManifestMap;
|
|
13
|
+
pluginsSettings: PluginsSettings;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const initialPluginState: PluginState = {
|
|
17
|
+
manifestPrepared: false,
|
|
18
|
+
pluginList: [],
|
|
19
|
+
pluginManifestLoading: {},
|
|
20
|
+
pluginManifestMap: {},
|
|
21
|
+
pluginsSettings: {},
|
|
22
|
+
};
|
|
@@ -5,23 +5,25 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
5
5
|
|
|
6
6
|
import { isDev } from '@/utils/env';
|
|
7
7
|
|
|
8
|
-
import { PluginAction, createPluginSlice } from './action';
|
|
9
8
|
import { PluginStoreState, initialState } from './initialState';
|
|
9
|
+
import { CustomPluginAction, createCustomPluginSlice } from './slices/customPlugin';
|
|
10
|
+
import { PluginAction, createPluginSlice } from './slices/plugin';
|
|
10
11
|
|
|
11
12
|
// =============== 聚合 createStoreFn ============ //
|
|
12
13
|
|
|
13
|
-
export type PluginStore = PluginStoreState & PluginAction;
|
|
14
|
+
export type PluginStore = PluginStoreState & CustomPluginAction & PluginAction;
|
|
14
15
|
|
|
15
16
|
const createStore: StateCreator<PluginStore, [['zustand/devtools', never]]> = (...parameters) => ({
|
|
16
17
|
...initialState,
|
|
17
18
|
...createPluginSlice(...parameters),
|
|
19
|
+
...createCustomPluginSlice(...parameters),
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
// =============== persist 本地缓存中间件配置 ============ //
|
|
21
23
|
|
|
22
24
|
type SessionPersist = Pick<
|
|
23
25
|
PluginStore,
|
|
24
|
-
'pluginList' | 'pluginManifestMap' | 'pluginsSettings' | '
|
|
26
|
+
'pluginList' | 'pluginManifestMap' | 'pluginsSettings' | 'customPluginList'
|
|
25
27
|
>;
|
|
26
28
|
|
|
27
29
|
const storeName = 'LOBE_PLUGIN';
|
|
@@ -30,7 +32,7 @@ const persistOptions: PersistOptions<PluginStore, SessionPersist> = {
|
|
|
30
32
|
name: storeName,
|
|
31
33
|
|
|
32
34
|
partialize: (s) => ({
|
|
33
|
-
|
|
35
|
+
customPluginList: s.customPluginList,
|
|
34
36
|
pluginList: s.pluginList,
|
|
35
37
|
pluginManifestMap: s.pluginManifestMap,
|
|
36
38
|
pluginsSettings: s.pluginsSettings,
|
package/src/types/plugin.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
-
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
1
|
+
import { LobeChatPluginManifest, LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
|
|
3
3
|
export type PluginManifestMap = Record<string, LobeChatPluginManifest>;
|
|
4
|
+
|
|
5
|
+
export interface CustomPlugin extends LobeChatPluginMeta {
|
|
6
|
+
apiMode: 'openapi' | 'simple';
|
|
7
|
+
enableSettings: boolean;
|
|
8
|
+
manifestConfig?: LobeChatPluginManifest;
|
|
9
|
+
manifestMode: 'local' | 'url';
|
|
10
|
+
}
|
|
File without changes
|