Skip to content

Commit

Permalink
chore: update admin actions
Browse files Browse the repository at this point in the history
  • Loading branch information
zmh-program committed Jan 19, 2024
1 parent c0568bb commit 8dfb118
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 66 deletions.
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@


## 🔨 模型 | Models
- [x] OpenAI ChatGPT (GPT-3.5, GPT-4, Instruct, DALL-E 2, DALL-E 3, Text-Davincci, ...)
- [x] OpenAI ChatGPT (GPT-3.5, GPT-4, Instruct, DALL-E 2, DALL-E 3, ...)
- [x] Azure OpenAI
- [x] Anthropic Claude (claude-2, claude-instant)
- [x] Slack Claude (deprecated)
Expand All @@ -79,9 +79,7 @@
- [x] Baichuan AI
- [x] Douyin Skylark (lite, plus, pro, chat)
- [x] 360 GPT
- [x] LLaMa 2 (70b, 13b, 7b)
- [x] Code LLaMa (34b, 13b, 7b)
- [ ] RWKV
- [x] LocalAI (RWKV, LLaMa 2, Baichuan 7b, Mixtral, ...) _*requires local deployment_


## 📦 部署 | Deploy
Expand Down
2 changes: 1 addition & 1 deletion app/src/admin/channel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ export const ChannelInfos: Record<string, ChannelInfo> = {
format: "<secret>",
models: ["bing-creative", "bing-balanced", "bing-precise"],
description:
"> Bing 服务需要自行搭建,详情请参考 [chatnio-bing-service](https://github.com/Deeptrain-Community/chatnio-bing-service) (如为 bing2api 可直接使用 OpenAI 格式映射)",
"> Bing 服务需要自行搭建,详情请参考 [chatnio-bing-service](https://github.com/Deeptrain-Community/chatnio-bing-service) \n > bing2api (如 [bingo](https://github.com/weaigc/bingo)) 可直接使用 OpenAI 格式",
},
palm: {
endpoint: "https://generativelanguage.googleapis.com",
Expand Down
10 changes: 10 additions & 0 deletions app/src/assets/admin/channel.less
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
}
}

.channel-editor {
position: relative;

.channel-loader {
position: absolute;
top: 0;
right: 0.25rem;
}
}

.channel-wrapper {
display: flex;
flex-direction: column;
Expand Down
9 changes: 8 additions & 1 deletion app/src/components/admin/assemblies/ChannelEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { Button } from "@/components/ui/button.tsx";
import { useTranslation } from "react-i18next";
import { useMemo, useReducer, useState } from "react";
import Required from "@/components/Require.tsx";
import { Plus, Search, X } from "lucide-react";
import { Loader2, Plus, Search, X } from "lucide-react";
import {
DropdownMenu,
DropdownMenuContent,
Expand Down Expand Up @@ -209,6 +209,8 @@ function ChannelEditor({ display, id, setEnabled }: ChannelEditorProps) {
}, [edit.models]);
const enabled = useMemo(() => validator(edit), [edit]);

const [loading, setLoading] = useState(false);

const unusedGroups = useMemo(() => {
if (!edit.group) return channelGroups;
return channelGroups.filter(
Expand Down Expand Up @@ -237,7 +239,9 @@ function ChannelEditor({ display, id, setEnabled }: ChannelEditorProps) {
useEffectAsync(async () => {
if (id === -1) dispatch({ type: "clear" });
else {
setLoading(true);
const resp = await getChannel(id);
setLoading(false);
toastState(toast, t, resp as CommonResponse);
if (resp.data) dispatch({ type: "set", value: resp.data });
}
Expand All @@ -246,6 +250,9 @@ function ChannelEditor({ display, id, setEnabled }: ChannelEditorProps) {
return (
display && (
<div className={`channel-editor`}>
{loading && (
<Loader2 className={`channel-loader h-4 w-4 animate-spin`} />
)}
<div className={`channel-wrapper w-full h-max`}>
<div className={`channel-row`}>
<div className={`channel-content`}>
Expand Down
5 changes: 5 additions & 0 deletions app/src/components/app/AppProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,14 @@ import { initChatModels } from "@/store/chat.ts";
import { Model } from "@/api/types.ts";
import { ChargeProps, nonBilling } from "@/admin/charge.ts";
import { dispatchSubscriptionData } from "@/store/globals.ts";
import { marketEvent } from "@/events/market.ts";

function AppProvider() {
const dispatch = useDispatch();

useEffectAsync(async () => {
marketEvent.emit(false);

const market = await getApiMarket();
const charge = await getApiCharge();

Expand All @@ -48,6 +51,8 @@ function AppProvider() {
});

dispatchSubscriptionData(dispatch, await getApiPlans());

marketEvent.emit(true);
}, [allModels]);

return (
Expand Down
5 changes: 5 additions & 0 deletions app/src/events/market.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { EventCommitter } from "@/events/struct.ts";

export const marketEvent = new EventCommitter<boolean>({
name: "market",
});
2 changes: 2 additions & 0 deletions app/src/resources/i18n/cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@
"market": {
"title": "模型市场",
"model-name": "模型名称",
"new-model": "新建模型",
"model-name-placeholder": "请输入模型昵称 (如:GPT-4)",
"model-id": "模型 ID",
"model-id-placeholder": "请输入模型 ID (如:gpt-4-0613)",
Expand All @@ -417,6 +418,7 @@
"custom-image": "自定义图片",
"custom-image-placeholder": "请输入图片链接",
"update": "更新",
"migrate": "提交",
"update-success": "更新成功",
"update-success-prompt": "模型市场设置已成功提交更新至服务器。",
"update-failed": "更新失败",
Expand Down
4 changes: 3 additions & 1 deletion app/src/resources/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@
"model-image": "Model Picture",
"custom-image": "Custom Image",
"custom-image-placeholder": "Please enter an image link",
"update": "Update"
"update": "Update",
"new-model": "Create a new model",
"migrate": "Submit"
},
"model-chart-tip": "Token usage",
"subscription": "Subscription Management",
Expand Down
4 changes: 3 additions & 1 deletion app/src/resources/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@
"model-image": "モデル写真",
"custom-image": "カスタム画像",
"custom-image-placeholder": "画像リンクを入力してください",
"update": "更新"
"update": "更新",
"new-model": "新しいモデル",
"migrate": "提出"
},
"model-chart-tip": "トークンの使用状況",
"subscription": "サブスクリプション管理",
Expand Down
4 changes: 3 additions & 1 deletion app/src/resources/i18n/ru.json
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,9 @@
"model-image": "Изображение модели",
"custom-image": "Пользовательское изображение",
"custom-image-placeholder": "Введите ссылку на изображение",
"update": "Обновить"
"update": "Обновить",
"new-model": "Новая модель",
"migrate": "передавать"
},
"model-chart-tip": "Использование токенов",
"subscription": "Управление подписками",
Expand Down
3 changes: 2 additions & 1 deletion app/src/routes/admin/Logger.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import Paragraph from "@/components/Paragraph.tsx";
import { Label } from "@/components/ui/label.tsx";
import { NumberInput } from "@/components/ui/number-input.tsx";
import { Button } from "@/components/ui/button.tsx";
import { cn } from "@/components/ui/lib/utils.ts";

type LoggerItemProps = Logger & {
onUpdate: () => void;
Expand Down Expand Up @@ -104,7 +105,7 @@ function LoggerConsole() {
/>
<div className={`grow`} />
<Button onClick={sync} variant={`outline`} size={`icon`}>
<RotateCcw className={`w-4 h-4`} />
<RotateCcw className={cn("w-4 h-4", loading && "animate-spin")} />
</Button>
</div>
<div className={`logger-console`}>
Expand Down
84 changes: 29 additions & 55 deletions app/src/routes/admin/Market.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@ import {
CardTitle,
} from "@/components/ui/card.tsx";
import { useTranslation } from "react-i18next";
import {
Dispatch,
useEffect,
useMemo,
useReducer,
useRef,
useState,
} from "react";
import { Dispatch, useMemo, useReducer, useState } from "react";
import { Model as RawModel } from "@/api/types.ts";
import { supportModels } from "@/conf";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { Input } from "@/components/ui/input.tsx";
import { GripVertical, HelpCircle, Plus, Trash2 } from "lucide-react";
import { GripVertical, HelpCircle, Loader2, Plus, Trash2 } from "lucide-react";
import { generateRandomChar, isUrl } from "@/utils/base.ts";
import Require from "@/components/Require.tsx";
import { Textarea } from "@/components/ui/textarea.tsx";
Expand All @@ -32,6 +25,7 @@ import { updateMarket } from "@/admin/api/market.ts";
import { Combobox } from "@/components/ui/combo-box.tsx";
import { channelModels } from "@/admin/channel.ts";
import { cn } from "@/components/ui/lib/utils.ts";
import { marketEvent } from "@/events/market.ts";

type Model = RawModel & {
seed?: string;
Expand All @@ -41,21 +35,6 @@ type MarketForm = Model[];

const generateSeed = () => generateRandomChar(8);

const initialState: MarketForm = [
{
id: "",
name: "",
free: false,
auth: false,
description: "",
high_context: false,
default: false,
tag: [],
avatar: modelImages[0],
seed: generateSeed(),
},
];

function reducer(state: MarketForm, action: any): MarketForm {
switch (action.type) {
case "set":
Expand Down Expand Up @@ -324,9 +303,8 @@ function MarketImage({ image, idx, dispatch }: MarketImageProps) {

function Market() {
const { t } = useTranslation();
const [form, dispatch] = useReducer(reducer, initialState);
const timer = useRef<number | null>(null);
const sync = useRef<boolean>(false);
const [form, dispatch] = useReducer(reducer, supportModels);
const [loading, setLoading] = useState<boolean>(false);

const update = async (): Promise<void> => {
const preflight = form.filter(
Expand All @@ -348,32 +326,10 @@ function Market() {
});
};

useEffect(() => {
if (supportModels.length > 0 && !sync.current) {
dispatch({ type: "set", payload: [...supportModels] });
sync.current = true;
}
}, [supportModels]);

useEffect(() => {
if (timer.current) {
clearTimeout(timer.current);
}

timer.current = Number(
setTimeout(async () => {
if (sync.current) {
sync.current = false;
return;
}

console.debug(
`[market] model market migrated, sync to server (models: ${form.length})`,
);
await update();
}, 2000),
);
}, [form]);
marketEvent.addEventListener((state: boolean) => {
setLoading(!state);
!state && dispatch({ type: "set", payload: [...supportModels] });
});

const checked = (index: number) => {
return useMemo((): boolean => {
Expand All @@ -387,15 +343,18 @@ function Market() {
<div className={`market`}>
<Card className={`admin-card market-card`}>
<CardHeader className={`flex flex-row items-center select-none`}>
<CardTitle>{t("admin.market.title")}</CardTitle>
<CardTitle>
{t("admin.market.title")}
{loading && <Loader2 className={`h-4 w-4 ml-2 animate-spin`} />}
</CardTitle>
<Button
loading={true}
className={`ml-auto mt-0 whitespace-nowrap`}
size={`sm`}
style={{ marginTop: 0 }}
onClick={update}
>
{t("admin.market.update")}
{t("admin.market.migrate")}
</Button>
</CardHeader>
<CardContent>
Expand Down Expand Up @@ -592,6 +551,21 @@ function Market() {
)}
</Droppable>
</DragDropContext>
<div className={`market-footer flex flex-row items-center mt-4`}>
<div className={`grow`} />
<Button
size={`sm`}
variant={`outline`}
className={`mr-2`}
onClick={() => dispatch({ type: "new" })}
>
<Plus className={`h-4 w-4 mr-2`} />
{t("admin.market.new-model")}
</Button>
<Button size={`sm`} onClick={update} loading={true}>
{t("admin.market.migrate")}
</Button>
</div>
</CardContent>
</Card>
</div>
Expand Down
10 changes: 9 additions & 1 deletion app/src/routes/admin/System.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
} from "@/components/ui/dialog.tsx";
import { DialogTitle } from "@radix-ui/react-dialog";
import Require from "@/components/Require.tsx";
import { Loader2 } from "lucide-react";

type CompProps<T> = {
data: T;
Expand Down Expand Up @@ -422,14 +423,18 @@ function System() {
initialSystemState,
);

const [loading, setLoading] = useState<boolean>(false);

const doSaving = async (doToast?: boolean) => {
const res = await setConfig(data);

if (doToast !== false) toastState(toast, t, res, true);
};

useEffectAsync(async () => {
setLoading(true);
const res = await getConfig();
setLoading(false);
toastState(toast, t, res);
if (res.status) {
setData({ type: "set", value: res.data });
Expand All @@ -440,7 +445,10 @@ function System() {
<div className={`system`}>
<Card className={`admin-card system-card`}>
<CardHeader className={`select-none`}>
<CardTitle>{t("admin.settings")}</CardTitle>
<CardTitle>
{t("admin.settings")}
{loading && <Loader2 className={`h-4 w-4 ml-2 inline-block`} />}
</CardTitle>
</CardHeader>
<CardContent className={`flex flex-col gap-1`}>
<General data={data.general} dispatch={setData} onChange={doSaving} />
Expand Down

0 comments on commit 8dfb118

Please sign in to comment.