update context length settings and admin pages

This commit is contained in:
Zhang Minghan 2023-11-29 10:58:59 +08:00
parent e79c29e24a
commit 7e7798d213
13 changed files with 101 additions and 58 deletions

View File

@ -7,7 +7,7 @@ import (
) )
func UsingWebSegment(instance *conversation.Conversation) []globals.Message { func UsingWebSegment(instance *conversation.Conversation) []globals.Message {
segment := conversation.CopyMessage(instance.GetMessageSegment(12)) segment := conversation.CopyMessage(instance.GetChatMessage())
if instance.IsEnableWeb() { if instance.IsEnableWeb() {
segment = ChatWithWeb(func(message []globals.Message, token int) (string, error) { segment = ChatWithWeb(func(message []globals.Message, token int) (string, error) {

View File

@ -4,6 +4,7 @@ import { getMemory } from "@/utils/memory.ts";
export const endpoint = `${ws_api}/chat`; export const endpoint = `${ws_api}/chat`;
export type StreamMessage = { export type StreamMessage = {
conversation?: number;
keyword?: string; keyword?: string;
quota?: number; quota?: number;
message: string; message: string;
@ -97,6 +98,9 @@ export class Connection {
} }
protected triggerCallback(message: StreamMessage): void { protected triggerCallback(message: StreamMessage): void {
if (this.id === -1 && message.conversation) {
this.setId(message.conversation);
}
this.callback && this.callback(message); this.callback && this.callback(message);
} }

View File

@ -1,7 +1,7 @@
import { useDispatch, useSelector } from "react-redux"; import { useDispatch, useSelector } from "react-redux";
import { closeMenu, selectMenu } from "@/store/menu.ts"; import { closeMenu, selectMenu } from "@/store/menu.ts";
import React, { useMemo } from "react"; import React, { useMemo } from "react";
import { LayoutDashboard, Radio, Settings, Users } from "lucide-react"; import {CandlestickChart, LayoutDashboard, Radio, Settings, Users} from "lucide-react";
import router from "@/router.tsx"; import router from "@/router.tsx";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
@ -53,9 +53,14 @@ function MenuBar() {
path={"/broadcast"} path={"/broadcast"}
/> />
<MenuItem <MenuItem
title={t("admin.settings")} title={t("admin.channel")}
icon={<Settings />} icon={<Settings />}
path={"/settings"} path={"/channel"}
/>
<MenuItem
title={t("admin.prize")}
icon={<CandlestickChart />}
path={"/prize"}
/> />
</div> </div>
); );

View File

@ -92,7 +92,7 @@ function OperationMenu({ id }: OperationMenuProps) {
}} }}
/> />
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger> <DropdownMenuTrigger asChild>
<Button variant={`outline`} size={`icon`}> <Button variant={`outline`} size={`icon`}>
<MoreHorizontal className={`h-4 w-4`} /> <MoreHorizontal className={`h-4 w-4`} />
</Button> </Button>

View File

@ -34,6 +34,7 @@ import {
SelectValue, SelectValue,
} from "@/components/ui/select.tsx"; } from "@/components/ui/select.tsx";
import { langs, setLanguage } from "@/i18n.ts"; import { langs, setLanguage } from "@/i18n.ts";
import {cn} from "@/components/ui/lib/utils.ts";
function SettingsDialog() { function SettingsDialog() {
const { t, i18n } = useTranslation(); const { t, i18n } = useTranslation();
@ -140,7 +141,7 @@ function SettingsDialog() {
<div className={`name`}>{t("settings.history")}</div> <div className={`name`}>{t("settings.history")}</div>
<div className={`grow`} /> <div className={`grow`} />
<NumberInput <NumberInput
className={`value`} className={cn(`value`, history === 0 && `text-red-500`)}
value={history} value={history}
acceptNaN={false} acceptNaN={false}
min={0} min={0}

View File

@ -127,9 +127,9 @@ const resources = {
go: "前往实名认证", go: "前往实名认证",
cert: "实名认证礼包", cert: "实名认证礼包",
"cert-desc": "实名认证后可获得 50 点数 (价值 5 元)", "cert-desc": "实名认证后可获得 50 点数 (价值 5 元)",
teen: "未成年人福利", teen: "学生福利",
"teen-desc": "teen-desc":
"实名认证后未成年人18 周岁及以下)可额外获得 150 点数 (价值 15 元),并且获得每天 100 次免费使用 Claude 100k 模型额度", "实名认证后未成年人18 周岁及以下)可额外获得 150 点数 (价值 15 元)",
close: "关闭", close: "关闭",
state: { state: {
true: "已领取", true: "已领取",
@ -308,7 +308,8 @@ const resources = {
dashboard: "仪表盘", dashboard: "仪表盘",
users: "用户管理", users: "用户管理",
broadcast: "公告管理", broadcast: "公告管理",
settings: "设置", channel: "渠道设置",
prize: "价格设定",
"billing-today": "今日入账", "billing-today": "今日入账",
"billing-month": "本月入账", "billing-month": "本月入账",
"subscription-users": "订阅用户", "subscription-users": "订阅用户",
@ -491,9 +492,9 @@ const resources = {
cert: "Certification Package", cert: "Certification Package",
"cert-desc": "cert-desc":
"After real-name certification, you can get 50 points (worth 5 CNY)", "After real-name certification, you can get 50 points (worth 5 CNY)",
teen: "Teenager Package", teen: "Student Package",
"teen-desc": "teen-desc":
"After real-name certification, teenagers (18 years old and below) can get an additional 150 points (worth 15 CNY) and 100 times of free use of Claude 100k model per day", "After real-name certification, teenagers (18 years old and under) can get an additional 150 points (worth 15 CNY)",
close: "Close", close: "Close",
state: { state: {
true: "Received", true: "Received",
@ -681,7 +682,8 @@ const resources = {
dashboard: "Dashboard", dashboard: "Dashboard",
users: "User Management", users: "User Management",
broadcast: "Broadcast Management", broadcast: "Broadcast Management",
settings: "Settings", channel: "Channel Settings",
prize: "Price Settings",
"billing-today": "Billing Today", "billing-today": "Billing Today",
"billing-month": "Billing Month", "billing-month": "Billing Month",
"subscription-users": "Subscription Users", "subscription-users": "Subscription Users",
@ -870,7 +872,7 @@ const resources = {
"После сертификации подлинности вы можете получить 100 очков (стоимостью 5 CNY)", "После сертификации подлинности вы можете получить 100 очков (стоимостью 5 CNY)",
teen: "Подростковый пакет", teen: "Подростковый пакет",
"teen-desc": "teen-desc":
"После сертификации подлинности подростки (до 18 лет) могут получить дополнительно 150 очков (стоимостью 15 CNY) и 100 раз бесплатно использовать модель Claude 100k в день", "После сертификации подлинности подростки (до 18 лет) могут получить дополнительно 150 очков (стоимостью 15 CNY)",
close: "Закрыть", close: "Закрыть",
state: { state: {
true: "Получено", true: "Получено",
@ -1057,7 +1059,8 @@ const resources = {
dashboard: "Панель управления", dashboard: "Панель управления",
users: "Управление пользователями", users: "Управление пользователями",
broadcast: "Управление объявлениями", broadcast: "Управление объявлениями",
settings: "Настройки", channel: "Настройки канала",
prize: "Настройки цен",
"billing-today": "Сегодняшний доход", "billing-today": "Сегодняшний доход",
"billing-month": "Доход за месяц", "billing-month": "Доход за месяц",
"subscription-users": "Подписчики", "subscription-users": "Подписчики",

View File

@ -10,7 +10,8 @@ const Article = lazy(() => import("@/routes/Article.tsx"));
const Admin = lazy(() => import("@/routes/Admin.tsx")); const Admin = lazy(() => import("@/routes/Admin.tsx"));
const Dashboard = lazy(() => import("@/routes/admin/DashBoard.tsx")); const Dashboard = lazy(() => import("@/routes/admin/DashBoard.tsx"));
const Settings = lazy(() => import("@/routes/admin/Settings.tsx")); const Channel = lazy(() => import("@/routes/admin/Channel.tsx"));
const Prize = lazy(() => import("@/routes/admin/Prize.tsx"));
const Users = lazy(() => import("@/routes/admin/Users.tsx")); const Users = lazy(() => import("@/routes/admin/Users.tsx"));
const Broadcast = lazy(() => import("@/routes/admin/Broadcast.tsx")); const Broadcast = lazy(() => import("@/routes/admin/Broadcast.tsx"));
@ -85,11 +86,20 @@ const router = createBrowserRouter([
), ),
}, },
{ {
id: "admin-settings", id: "admin-channel",
path: "settings", path: "channel",
element: ( element: (
<Suspense> <Suspense>
<Settings /> <Channel />
</Suspense>
),
},
{
id: "admin-prize",
path: "prize",
element: (
<Suspense>
<Prize />
</Suspense> </Suspense>
), ),
}, },

View File

@ -0,0 +1,5 @@
function Channel() {
return <></>;
}
export default Channel;

View File

@ -0,0 +1,5 @@
function Prize() {
return <></>;
}
export default Prize;

View File

@ -1,5 +0,0 @@
function Settings() {
return <></>;
}
export default Settings;

View File

@ -9,11 +9,12 @@ type Message struct {
} }
type ChatSegmentResponse struct { type ChatSegmentResponse struct {
Quota float32 `json:"quota"` Conversation int64 `json:"conversation"`
Keyword string `json:"keyword"` Quota float32 `json:"quota"`
Message string `json:"message"` Keyword string `json:"keyword"`
End bool `json:"end"` Message string `json:"message"`
Plan bool `json:"plan"` End bool `json:"end"`
Plan bool `json:"plan"`
} }
type GenerationSegmentResponse struct { type GenerationSegmentResponse struct {

View File

@ -63,6 +63,9 @@ func ChatHandler(conn *Connection, user *auth.User, instance *conversation.Conve
db := conn.GetDB() db := conn.GetDB()
cache := conn.GetCache() cache := conn.GetCache()
check, plan := auth.CanEnableModelWithSubscription(db, cache, user, model) check, plan := auth.CanEnableModelWithSubscription(db, cache, user, model)
conn.Send(globals.ChatSegmentResponse{
Conversation: instance.GetId(),
})
if !check { if !check {
conn.Send(globals.ChatSegmentResponse{ conn.Send(globals.ChatSegmentResponse{

View File

@ -10,17 +10,18 @@ import (
) )
const defaultConversationName = "new chat" const defaultConversationName = "new chat"
const defaultConversationContext = 8
type Conversation struct { type Conversation struct {
Auth bool `json:"auth"` Auth bool `json:"auth"`
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
Id int64 `json:"id"` Id int64 `json:"id"`
Name string `json:"name"` Name string `json:"name"`
Message []globals.Message `json:"message"` Message []globals.Message `json:"message"`
Model string `json:"model"` Model string `json:"model"`
EnableWeb bool `json:"enable_web"` EnableWeb bool `json:"enable_web"`
Shared bool `json:"shared"` Shared bool `json:"shared"`
IgnoreContext bool `json:"ignore_context"` Context int `json:"context"`
} }
type FormMessage struct { type FormMessage struct {
@ -29,17 +30,18 @@ type FormMessage struct {
Web bool `json:"web"` Web bool `json:"web"`
Model string `json:"model"` Model string `json:"model"`
IgnoreContext bool `json:"ignore_context"` IgnoreContext bool `json:"ignore_context"`
Context int `json:"context"`
} }
func NewAnonymousConversation() *Conversation { func NewAnonymousConversation() *Conversation {
return &Conversation{ return &Conversation{
Auth: false, Auth: false,
UserID: -1, UserID: -1,
Id: -1, Id: -1,
Name: defaultConversationName, Name: defaultConversationName,
Message: []globals.Message{}, Message: []globals.Message{},
Model: globals.GPT3Turbo, Model: globals.GPT3Turbo,
IgnoreContext: false, Context: defaultConversationContext,
} }
} }
@ -89,8 +91,8 @@ func (c *Conversation) IsEnableWeb() bool {
return c.EnableWeb return c.EnableWeb
} }
func (c *Conversation) IsIgnoreContext() bool { func (c *Conversation) GetContextLength() int {
return c.IgnoreContext return c.Context
} }
func (c *Conversation) SetModel(model string) { func (c *Conversation) SetModel(model string) {
@ -104,8 +106,8 @@ func (c *Conversation) SetEnableWeb(enable bool) {
c.EnableWeb = enable c.EnableWeb = enable
} }
func (c *Conversation) SetIgnoreContext(ignore bool) { func (c *Conversation) SetContextLength(context int) {
c.IgnoreContext = ignore c.Context = context
} }
func (c *Conversation) GetName() string { func (c *Conversation) GetName() string {
@ -142,20 +144,16 @@ func (c *Conversation) GetMessageLength() int {
} }
func (c *Conversation) GetMessageSegment(length int) []globals.Message { func (c *Conversation) GetMessageSegment(length int) []globals.Message {
if c.IsIgnoreContext() {
if len(c.Message) >= 1 {
// get latest message
return []globals.Message{c.Message[len(c.Message)-1]}
}
// empty
return []globals.Message{}
}
if length > len(c.Message) { if length > len(c.Message) {
return c.Message return c.Message
} }
return c.Message[len(c.Message)-length:] return c.Message[len(c.Message)-length:]
} }
func (c *Conversation) GetChatMessage() []globals.Message {
return c.GetMessageSegment(c.GetContextLength())
}
func CopyMessage(message []globals.Message) []globals.Message { func CopyMessage(message []globals.Message) []globals.Message {
return utils.DeepCopy[[]globals.Message](message) // deep copy return utils.DeepCopy[[]globals.Message](message) // deep copy
} }
@ -224,7 +222,14 @@ func (c *Conversation) AddMessageFromByte(data []byte) (string, error) {
c.AddMessageFromUser(form.Message) c.AddMessageFromUser(form.Message)
c.SetModel(form.Model) c.SetModel(form.Model)
c.SetEnableWeb(form.Web) c.SetEnableWeb(form.Web)
c.SetIgnoreContext(form.IgnoreContext)
if form.IgnoreContext {
form.Context = 1
} else if form.Context <= 0 {
form.Context = defaultConversationContext
}
c.SetContextLength(form.Context)
return form.Message, nil return form.Message, nil
} }
@ -236,7 +241,13 @@ func (c *Conversation) AddMessageFromForm(form *FormMessage) error {
c.AddMessageFromUser(form.Message) c.AddMessageFromUser(form.Message)
c.SetModel(form.Model) c.SetModel(form.Model)
c.SetEnableWeb(form.Web) c.SetEnableWeb(form.Web)
c.SetIgnoreContext(form.IgnoreContext) if form.IgnoreContext {
form.Context = 1
} else if form.Context <= 0 {
form.Context = defaultConversationContext
}
c.SetContextLength(form.Context)
return nil return nil
} }