diff --git a/api/chat_model_handler.go b/api/chat_model_handler.go index 3edd50b4..b64aeeb2 100644 --- a/api/chat_model_handler.go +++ b/api/chat_model_handler.go @@ -141,6 +141,7 @@ func (h *ChatModelHandler) UpdateChatModel(w http.ResponseWriter, r *http.Reques DefaultToken int32 MaxToken int32 HttpTimeOut int32 + IsEnable bool } err = json.NewDecoder(r.Body).Decode(&input) if err != nil { @@ -148,6 +149,7 @@ func (h *ChatModelHandler) UpdateChatModel(w http.ResponseWriter, r *http.Reques return } + ChatModel, err := h.db.UpdateChatModel(r.Context(), sqlc_queries.UpdateChatModelParams{ ID: int32(id), Name: input.Name, @@ -162,6 +164,7 @@ func (h *ChatModelHandler) UpdateChatModel(w http.ResponseWriter, r *http.Reques DefaultToken: input.DefaultToken, MaxToken: input.MaxToken, HttpTimeOut: input.HttpTimeOut, + IsEnable: input.IsEnable, }) if err != nil { diff --git a/api/chat_model_handler_test.go b/api/chat_model_handler_test.go index feb7a74f..721c798c 100644 --- a/api/chat_model_handler_test.go +++ b/api/chat_model_handler_test.go @@ -155,7 +155,7 @@ func checkGetModels(t *testing.T, router *mux.Router, expectedResults []sqlc_que t.Errorf("error parsing response body: %s", err.Error()) } assert.Equal(t, len(results), 2) - assert.DeepEqual(t, lo.Reverse(expectedResults), results, cmpopts.IgnoreFields(sqlc_queries.ChatModel{}, "ID")) + assert.DeepEqual(t, lo.Reverse(expectedResults), results, cmpopts.IgnoreFields(sqlc_queries.ChatModel{}, "ID", "IsEnable")) return results } diff --git a/api/main.go b/api/main.go index 654dbba5..2a2d5c83 100644 --- a/api/main.go +++ b/api/main.go @@ -185,8 +185,6 @@ func main() { apiRouter.HandleFunc("/tts", handleTTSRequest) - - // Embed static/* directory fs := http.FileServer(http.FS(static.StaticFiles)) diff --git a/api/sqlc/queries/chat_model.sql b/api/sqlc/queries/chat_model.sql index 307eaea9..b79e5be4 100644 --- a/api/sqlc/queries/chat_model.sql +++ b/api/sqlc/queries/chat_model.sql @@ -19,7 +19,7 @@ RETURNING *; -- name: UpdateChatModel :one UPDATE chat_model SET name = $2, label = $3, is_default = $4, url = $5, api_auth_header = $6, api_auth_key = $7, enable_per_mode_ratelimit = $9, -max_token = $10, default_token = $11, order_number = $12, http_time_out = $13 +max_token = $10, default_token = $11, order_number = $12, http_time_out = $13, is_enable = $14 WHERE id = $1 and user_id = $8 RETURNING *; diff --git a/api/sqlc/schema.sql b/api/sqlc/schema.sql index 17680947..c3a3d524 100644 --- a/api/sqlc/schema.sql +++ b/api/sqlc/schema.sql @@ -36,6 +36,7 @@ ALTER TABLE chat_model ADD COLUMN IF NOT EXISTS max_token INTEGER NOT NULL defau ALTER TABLE chat_model ADD COLUMN IF NOT EXISTS default_token INTEGER NOT NULL default 2048; ALTER TABLE chat_model ADD COLUMN IF NOT EXISTS order_number INTEGER NOT NULL default 1; ALTER TABLE chat_model ADD COLUMN IF NOT EXISTS http_time_out INTEGER NOT NULL default 120; +ALTER TABLE chat_model ADD COLUMN IF NOT EXISTS is_enable BOOLEAN DEFAULT true NOT NULL; INSERT INTO chat_model(name, label, is_default, url, api_auth_header, api_auth_key, max_token, default_token, order_number) diff --git a/api/sqlc_queries/chat_model.sql.go b/api/sqlc_queries/chat_model.sql.go index 3adc788a..4051e702 100644 --- a/api/sqlc_queries/chat_model.sql.go +++ b/api/sqlc_queries/chat_model.sql.go @@ -10,7 +10,7 @@ import ( ) const chatModelByID = `-- name: ChatModelByID :one -SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out FROM chat_model WHERE id = $1 +SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable FROM chat_model WHERE id = $1 ` func (q *Queries) ChatModelByID(ctx context.Context, id int32) (ChatModel, error) { @@ -30,12 +30,13 @@ func (q *Queries) ChatModelByID(ctx context.Context, id int32) (ChatModel, error &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } const chatModelByName = `-- name: ChatModelByName :one -SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out FROM chat_model WHERE name = $1 +SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable FROM chat_model WHERE name = $1 ` func (q *Queries) ChatModelByName(ctx context.Context, name string) (ChatModel, error) { @@ -55,6 +56,7 @@ func (q *Queries) ChatModelByName(ctx context.Context, name string) (ChatModel, &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } @@ -62,7 +64,7 @@ func (q *Queries) ChatModelByName(ctx context.Context, name string) (ChatModel, const createChatModel = `-- name: CreateChatModel :one INSERT INTO chat_model (name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) -RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out +RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable ` type CreateChatModelParams struct { @@ -110,6 +112,7 @@ func (q *Queries) CreateChatModel(ctx context.Context, arg CreateChatModelParams &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } @@ -129,7 +132,7 @@ func (q *Queries) DeleteChatModel(ctx context.Context, arg DeleteChatModelParams } const getDefaultChatModel = `-- name: GetDefaultChatModel :one -SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out FROM chat_model WHERE is_default = true +SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable FROM chat_model WHERE is_default = true and user_id in (select id from auth_user where is_superuser = true) ` @@ -150,12 +153,13 @@ func (q *Queries) GetDefaultChatModel(ctx context.Context) (ChatModel, error) { &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } const listChatModels = `-- name: ListChatModels :many -SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out FROM chat_model ORDER BY order_number +SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable FROM chat_model ORDER BY order_number ` func (q *Queries) ListChatModels(ctx context.Context) ([]ChatModel, error) { @@ -181,6 +185,7 @@ func (q *Queries) ListChatModels(ctx context.Context) ([]ChatModel, error) { &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ); err != nil { return nil, err } @@ -196,7 +201,7 @@ func (q *Queries) ListChatModels(ctx context.Context) ([]ChatModel, error) { } const listSystemChatModels = `-- name: ListSystemChatModels :many -SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out FROM chat_model +SELECT id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable FROM chat_model where user_id in (select id from auth_user where is_superuser = true) ORDER BY order_number, id desc ` @@ -224,6 +229,7 @@ func (q *Queries) ListSystemChatModels(ctx context.Context) ([]ChatModel, error) &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ); err != nil { return nil, err } @@ -240,9 +246,9 @@ func (q *Queries) ListSystemChatModels(ctx context.Context) ([]ChatModel, error) const updateChatModel = `-- name: UpdateChatModel :one UPDATE chat_model SET name = $2, label = $3, is_default = $4, url = $5, api_auth_header = $6, api_auth_key = $7, enable_per_mode_ratelimit = $9, -max_token = $10, default_token = $11, order_number = $12, http_time_out = $13 +max_token = $10, default_token = $11, order_number = $12, http_time_out = $13, is_enable = $14 WHERE id = $1 and user_id = $8 -RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out +RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable ` type UpdateChatModelParams struct { @@ -259,6 +265,7 @@ type UpdateChatModelParams struct { DefaultToken int32 `json:"defaultToken"` OrderNumber int32 `json:"orderNumber"` HttpTimeOut int32 `json:"httpTimeOut"` + IsEnable bool `json:"isEnable"` } func (q *Queries) UpdateChatModel(ctx context.Context, arg UpdateChatModelParams) (ChatModel, error) { @@ -276,6 +283,7 @@ func (q *Queries) UpdateChatModel(ctx context.Context, arg UpdateChatModelParams arg.DefaultToken, arg.OrderNumber, arg.HttpTimeOut, + arg.IsEnable, ) var i ChatModel err := row.Scan( @@ -292,6 +300,7 @@ func (q *Queries) UpdateChatModel(ctx context.Context, arg UpdateChatModelParams &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } @@ -299,7 +308,7 @@ func (q *Queries) UpdateChatModel(ctx context.Context, arg UpdateChatModelParams const updateChatModelKey = `-- name: UpdateChatModelKey :one UPDATE chat_model SET api_auth_key = $2 WHERE id = $1 -RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out +RETURNING id, name, label, is_default, url, api_auth_header, api_auth_key, user_id, enable_per_mode_ratelimit, max_token, default_token, order_number, http_time_out, is_enable ` type UpdateChatModelKeyParams struct { @@ -324,6 +333,7 @@ func (q *Queries) UpdateChatModelKey(ctx context.Context, arg UpdateChatModelKey &i.DefaultToken, &i.OrderNumber, &i.HttpTimeOut, + &i.IsEnable, ) return i, err } diff --git a/api/sqlc_queries/models.go b/api/sqlc_queries/models.go index 0d1a7d6e..6d16d778 100644 --- a/api/sqlc_queries/models.go +++ b/api/sqlc_queries/models.go @@ -82,6 +82,7 @@ type ChatModel struct { DefaultToken int32 `json:"defaultToken"` OrderNumber int32 `json:"orderNumber"` HttpTimeOut int32 `json:"httpTimeOut"` + IsEnable bool `json:"isEnable"` } type ChatPrompt struct { diff --git a/web/src/locales/en-US.json b/web/src/locales/en-US.json index be398d9c..bf56dc79 100644 --- a/web/src/locales/en-US.json +++ b/web/src/locales/en-US.json @@ -2,18 +2,14 @@ "admin": { "add_user_model_rate_limit": "Add User Session Count", "chat_model": { - "EnablePerModeRatelimit": "Separate Throttling", "actions": "Actions", "apiAuthHeader": "Auth Header key", "apiAuthKey": "API KEY corresponding to the environment variable", - "api_auth_header": "Auth Header key", - "api_auth_key": "Environment variable corresponding to API KEY", "defaultToken": "Default token number", "deleteModel": "Delete", "deleteModelConfirm": "Confirm deletion", - "enable_per_model_rate_limit": "Enable per-model rate limit", + "enablePerModelRateLimit": "Enable per-model rate limit", "isDefault": "Default?", - "is_default": "Default?", "label": "Model name", "maxToken": "Maximum token number", "name": "ID", diff --git a/web/src/locales/zh-CN.json b/web/src/locales/zh-CN.json index 9197a0d0..d44ebf28 100644 --- a/web/src/locales/zh-CN.json +++ b/web/src/locales/zh-CN.json @@ -124,16 +124,13 @@ "deleteModelConfirm": "确认删除", "name": "ID", "label": "模型名称", - "is_default": "默认?", "isDefault": "默认?", - "api_auth_header": "Auth Header key", "apiAuthHeader": "Auth Header key", - "api_auth_key": "API KEY对应的环境变量", "apiAuthKey": "API KEY对应的环境变量", "actions": "操作", "url": "访问接口(with full url path)", - "enable_per_model_rate_limit": "是否单独流控", - "EnablePerModeRatelimit": "是否单独流控", + "enablePerModeRatelimit": "是否单独流控", + "isEnable": "是否启用", "orderNumber": "次序", "maxToken": "最大token数量", "defaultToken": "默认token数量" diff --git a/web/src/locales/zh-TW.json b/web/src/locales/zh-TW.json index 5e16d6d3..c363e39e 100644 --- a/web/src/locales/zh-TW.json +++ b/web/src/locales/zh-TW.json @@ -2,18 +2,14 @@ "admin": { "add_user_model_rate_limit": "添加用戶會話數量", "chat_model": { - "EnablePerModeRatelimit": "是否單獨流控", "actions": "操作", "apiAuthHeader": "Auth Header 鍵", "apiAuthKey": "API KEY對應的環境變量", - "api_auth_header": "Auth Header 鍵", - "api_auth_key": "API KEY對應的環境變數", "defaultToken": "默認token數量", "deleteModel": "刪除", "deleteModelConfirm": "確認刪除", - "enable_per_model_rate_limit": "是否單獨流控", + "enablePerModelRateLimit": "是否單獨流控", "isDefault": "默認?", - "is_default": "默認?", "label": "模型名稱", "maxToken": "最大token數量", "name": "身分識別號", diff --git a/web/src/typings/chat.d.ts b/web/src/typings/chat.d.ts index f3131f98..bfee207f 100644 --- a/web/src/typings/chat.d.ts +++ b/web/src/typings/chat.d.ts @@ -63,6 +63,7 @@ declare namespace Chat { name: string url: string enablePerModeRatelimit: boolean, + isEnable: boolean, maxToken?: string, defaultToken?: string, orderNumber?: string, diff --git a/web/src/views/admin/model/AddModelForm.vue b/web/src/views/admin/model/AddModelForm.vue index d6b40276..4e49090f 100644 --- a/web/src/views/admin/model/AddModelForm.vue +++ b/web/src/views/admin/model/AddModelForm.vue @@ -16,6 +16,7 @@ const formData = ref({ apiAuthHeader: '', apiAuthKey: '', enablePerModeRatelimit: false, + isEnable: true, }) interface Emit { @@ -50,16 +51,16 @@ async function addRow() { - + - + - + - + diff --git a/web/src/views/admin/model/index.vue b/web/src/views/admin/model/index.vue index a0df2faa..a8819e87 100644 --- a/web/src/views/admin/model/index.vue +++ b/web/src/views/admin/model/index.vue @@ -48,7 +48,7 @@ const deteteModelMutation = useMutation({ const UpdateRow = (row: Chat.ChatModel) => { if (row.id) { - chatModelMutation.mutate({ + const newRow = { id: row.id, data: { ...row, @@ -56,7 +56,9 @@ const UpdateRow = (row: Chat.ChatModel) => { defaultToken: parseInt(row.defaultToken || '0'), maxToken: parseInt(row.maxToken || '0'), }, - }) + } + console.log(newRow) + chatModelMutation.mutate(newRow) } } @@ -213,7 +215,7 @@ function createColumns(): DataTableColumns { }, } const perModelLimit = { - title: t('admin.chat_model.EnablePerModeRatelimit'), + title: t('admin.chat_model.enablePerModeRatelimit'), key: 'enablePerModeRatelimit', render(row: Chat.ChatModel, index: number) { return h(NSwitch, { @@ -227,6 +229,21 @@ function createColumns(): DataTableColumns { }, } + const isEnableColumn = { + title: t('admin.chat_model.isEnable'), + key: 'isEnable', + render(row: Chat.ChatModel, index: number) { + return h(NSwitch, { + value: row.isEnable, + onUpdateValue(v: boolean) { + // Assuming `data` is an array of FormData objects + data.value[index].isEnable = v + UpdateRow(data.value[index]) + }, + }) + }, + } + const actionField = { title: t('admin.chat_model.actions'), key: 'actions', @@ -257,6 +274,7 @@ function createColumns(): DataTableColumns { apiAuthHeaderField, isDefaultField, perModelLimit, + isEnableColumn, defaultToken, maxToken, orderNumber, diff --git a/web/src/views/chat/components/ModelSelector.vue b/web/src/views/chat/components/ModelSelector.vue index eba50b8f..2f8b641d 100644 --- a/web/src/views/chat/components/ModelSelector.vue +++ b/web/src/views/chat/components/ModelSelector.vue @@ -31,7 +31,7 @@ const optionFromModel = (model: any) => { } } const chatModelOptions = computed(() => - data?.value ? data.value.map(optionFromModel) : [] + data?.value ? data.value.filter((x: any) => x.isEnable).map(optionFromModel) : [] ) diff --git a/web/src/views/chat/components/Session/SessionConfig.vue b/web/src/views/chat/components/Session/SessionConfig.vue index ea25050d..0d5e3106 100644 --- a/web/src/views/chat/components/Session/SessionConfig.vue +++ b/web/src/views/chat/components/Session/SessionConfig.vue @@ -27,7 +27,7 @@ const { data, isLoading } = useQuery({ }) const chatModelOptions = computed(() => - data?.value ? data.value.map(optionFromModel) : [] + data?.value ? data.value.filter((x: any) => x.isEnable).map(optionFromModel) : [] ) const chatStore = useChatStore()