feat: 支持开关指定内置插件

This commit is contained in:
Hk-Gosuto
2023-09-04 21:59:42 +08:00
parent c5cc16ca09
commit c9c5ab2a9b
17 changed files with 909 additions and 8 deletions

View File

@@ -18,6 +18,7 @@ import { ChatControllerPool } from "../client/controller";
import { prettyObject } from "../utils/format";
import { estimateTokenLength } from "../utils/token";
import { nanoid } from "nanoid";
import { Plugin, usePluginStore } from "../store/plugin";
export interface ChatToolMessage {
toolName: string;
@@ -313,6 +314,10 @@ export const useChatStore = create<ChatStore>()(
const config = useAppConfig.getState();
const pluginConfig = useAppConfig.getState().pluginConfig;
const pluginStore = usePluginStore.getState();
const allPlugins = pluginStore
.getAll()
.filter((m) => (!getLang() || m.lang === getLang()) && m.enable);
// save user's and bot's message
get().updateCurrentSession((session) => {
@@ -324,12 +329,17 @@ export const useChatStore = create<ChatStore>()(
session.messages.push(botMessage);
});
if (config.pluginConfig.enable && session.mask.usePlugins) {
if (
config.pluginConfig.enable &&
session.mask.usePlugins &&
allPlugins.length > 0
) {
console.log("[ToolAgent] start");
const pluginToolNames = allPlugins.map((m) => m.toolName);
api.llm.toolAgentChat({
messages: sendMessages,
config: { ...modelConfig, stream: true },
agentConfig: { ...pluginConfig },
agentConfig: { ...pluginConfig, useTools: pluginToolNames },
onUpdate(message) {
botMessage.streaming = true;
if (message) {

137
app/store/plugin.ts Normal file
View File

@@ -0,0 +1,137 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
import { BUILTIN_PLUGIN_STORE, BUILTIN_PLUGINS } from "../plugins";
import { getLang, Lang } from "../locales";
import { DEFAULT_TOPIC, ChatMessage } from "./chat";
import { ModelConfig, useAppConfig } from "./config";
import { StoreKey } from "../constant";
import { nanoid } from "nanoid";
export type Plugin = {
id: string;
createdAt: number;
name: string;
toolName?: string;
lang: string;
description: string;
builtin: boolean;
enable: boolean;
};
export const DEFAULT_PLUGIN_STATE = {
plugins: {} as Record<string, Plugin>,
pluginStatuses: {} as Record<string, boolean>,
};
export type PluginState = typeof DEFAULT_PLUGIN_STATE;
type PluginStore = PluginState & {
create: (plugin?: Partial<Plugin>) => Plugin;
update: (id: string, updater: (plugin: Plugin) => void) => void;
enable: (id: string) => void;
disable: (id: string) => void;
delete: (id: string) => void;
search: (text: string) => Plugin[];
get: (id?: string) => Plugin | null;
getAll: () => Plugin[];
};
export const createEmptyPlugin = () =>
({
id: nanoid(),
name: DEFAULT_TOPIC,
lang: getLang(),
builtin: false,
createdAt: Date.now(),
enable: true,
}) as Plugin;
export const usePluginStore = create<PluginStore>()(
persist(
(set, get) => ({
...DEFAULT_PLUGIN_STATE,
create(plugin) {
const plugins = get().plugins;
const id = nanoid();
plugins[id] = {
...createEmptyPlugin(),
...plugin,
id,
builtin: false,
};
set(() => ({ plugins }));
return plugins[id];
},
update(id, updater) {
const plugins = get().plugins;
const plugin = plugins[id];
if (!plugin) return;
const updatePlugin = { ...plugin };
updater(updatePlugin);
plugins[id] = updatePlugin;
set(() => ({ plugins }));
},
delete(id) {
const plugins = get().plugins;
delete plugins[id];
set(() => ({ plugins }));
},
enable(id) {
const pluginStatuses = get().pluginStatuses;
pluginStatuses[id] = true;
set(() => ({ pluginStatuses }));
},
disable(id) {
const pluginStatuses = get().pluginStatuses;
pluginStatuses[id] = false;
set(() => ({ pluginStatuses }));
},
get(id) {
return get().plugins[id ?? 1145141919810];
},
getAll() {
const userPlugins = Object.values(get().plugins).sort(
(a, b) => b.createdAt - a.createdAt,
);
const buildinPlugins = BUILTIN_PLUGINS.map(
(m) =>
({
...m,
}) as Plugin,
);
const pluginStatuses = get().pluginStatuses;
return userPlugins.concat(buildinPlugins).map((e) => {
e.enable = pluginStatuses[e.id] ?? true;
return e;
});
},
search(text) {
return Object.values(get().plugins);
},
}),
{
name: StoreKey.Plugin,
version: 3.1,
migrate(state, version) {
const newState = JSON.parse(JSON.stringify(state)) as PluginState;
if (version < 3) {
Object.values(newState.plugins).forEach((m) => (m.id = nanoid()));
}
if (version < 3.1) {
const updatedPlugins: Record<string, Plugin> = {};
Object.values(newState.plugins).forEach((m) => {
updatedPlugins[m.id] = m;
});
newState.plugins = updatedPlugins;
}
return newState as any;
},
},
),
);