From ea73201b6f10116306cba14716dc23d6f752572a Mon Sep 17 00:00:00 2001 From: mrhaoji Date: Wed, 12 Jul 2023 22:43:54 +0800 Subject: [PATCH 1/4] fix: restore display_name/username that deleted before (#268) which happend in commit # 3bab5b4 --- web/src/components/UsersTable.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/src/components/UsersTable.js b/web/src/components/UsersTable.js index a4f744da..08ba961a 100644 --- a/web/src/components/UsersTable.js +++ b/web/src/components/UsersTable.js @@ -226,6 +226,7 @@ const UsersTable = () => { {renderText(user.username, 10)}} hoverable /> From 2b17bb8dd721dc9f2e8909d9ffa91f609834434f Mon Sep 17 00:00:00 2001 From: ckt <65409152+ckt1031@users.noreply.github.com> Date: Wed, 12 Jul 2023 22:50:02 +0800 Subject: [PATCH 2/4] chore: update i18n (#262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: 优化翻译 * Update en.json --- i18n/en.json | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/i18n/en.json b/i18n/en.json index 41e4448e..3ef1b010 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -107,6 +107,11 @@ "已禁用": "Disabled", "未知状态": "Unknown status", " 秒": "s", + " 分钟 ": " m ", + " 小时 ": " h ", + " 天 ": " d ", + " 个月 ": " M ", + " 年 ": " y ", "未测试": "Not tested", "通道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。": "Channel ${name} test succeeded, time consumed ${time.toFixed(2)} s.", "已成功开始测试所有已启用通道,请刷新页面查看结果。": "All enabled channels have been successfully tested, please refresh the page to view the results.", @@ -458,5 +463,45 @@ "消耗额度": "Used Quota", "可选值": "Optional Values", "渠道不存在:%d": "Channel does not exist: %d", - "数据库一致性已被破坏,请联系管理员": "Database consistency has been broken, please contact the administrator" + "数据库一致性已被破坏,请联系管理员": "Database consistency has been broken, please contact the administrator", + "使用近似的方式估算 token 数以减少计算量": "Estimate the number of tokens in an approximate way to reduce computational load", + "请填写ChannelName和ChannelKey!": "Please fill in the ChannelName and ChannelKey!", + "请至少选择一个Model!": "Please select at least one Model!", + "加载首页内容失败": "Failed to load the homepage content", + "加载关于内容失败": "Failed to load the About content", + "兑换码更新成功!": "Redemption code updated successfully!", + "兑换码创建成功!": "Redemption code created successfully!", + "用户账户创建成功!": "User account created successfully!", + "生成数量": "Generate quantity", + "请输入生成数量": "Please enter the quantity to generate", + "创建新用户账户": "Create new user account", + "渠道更新成功!": "Channel updated successfully!", + "渠道创建成功!": "Channel created successfully!", + "请选择分组": "Please select a group", + "更新兑换码信息": "Update redemption code information", + "创建新的兑换码": "Create a new redemption code", + "请在系统设置页面编辑分组倍率以添加新的分组:": "Please edit the group ratio in the system settings page to add a new group:", + "未找到所请求的页面": "The requested page was not found", + "过期时间格式错误!": "Expiration time format error!", + "请输入过期时间,格式为 yyyy-MM-dd HH:mm:ss,-1 表示无限制": "Please enter the expiration time, the format is yyyy-MM-dd HH:mm:ss, -1 means no limit", + "此项可选,为一个 JSON 文本,键为用户请求的模型名称,值为要替换的模型名称,例如:": "This is optional, it's a JSON text, the key is the model name requested by the user, and the value is the model name to be replaced, for example:", + "此项可选,输入镜像站地址,格式为:": "This is optional, enter the mirror site address, the format is:", + "模型映射": "Model mapping", + "请输入默认 API 版本,例如:2023-03-15-preview,该配置可以被实际的请求查询参数所覆盖": "Please enter the default API version, for example: 2023-03-15-preview, this configuration can be overridden by the actual request query parameters", + "默认": "Default", + "图片演示": "Image demo", + "参数替换为你的部署名称(模型名称中的点会被剔除)": "Replace the parameter with your deployment name (dots in the model name will be removed)", + "模型映射必须是合法的 JSON 格式!": "Model mapping must be in valid JSON format!", + "取消无限额度": "Cancel unlimited quota", + "请输入新的剩余额度": "Please enter the new remaining quota", + "请输入单个兑换码中包含的额度": "Please enter the quota included in a single redemption code", + "请输入用户名": "Please enter username", + "请输入显示名称": "Please enter display name", + "请输入密码": "Please enter password", + "模型部署名称必须和模型名称保持一致": "The model deployment name must be consistent with the model name", + ",因为 One API 会把请求体中的 model": ", because One API will take the model in the request body", + "请输入 AZURE_OPENAI_ENDPOINT": "Please enter AZURE_OPENAI_ENDPOINT", + "请输入自定义渠道的 Base URL": "Please enter the Base URL of the custom channel", + "Homepage URL 填": "Fill in the Homepage URL", + "Authorization callback URL 填": "Fill in the Authorization callback URL" } From abc53cb208aac5546be811d6953c8ff6cad3035c Mon Sep 17 00:00:00 2001 From: JustSong Date: Sat, 15 Jul 2023 11:49:58 +0800 Subject: [PATCH 3/4] feat: disable channel when account_deactivated received (close #271) --- controller/relay.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/relay.go b/controller/relay.go index 42aa0c0f..c8bd929c 100644 --- a/controller/relay.go +++ b/controller/relay.go @@ -124,7 +124,7 @@ func Relay(c *gin.Context) { channelId := c.GetInt("channel_id") common.SysError(fmt.Sprintf("relay error (channel #%d): %s", channelId, err.Message)) // https://platform.openai.com/docs/guides/error-codes/api-errors - if common.AutomaticDisableChannelEnabled && (err.Type == "insufficient_quota" || err.Code == "invalid_api_key") { + if common.AutomaticDisableChannelEnabled && (err.Type == "insufficient_quota" || err.Code == "invalid_api_key" || err.Code == "account_deactivated") { channelId := c.GetInt("channel_id") channelName := c.GetString("channel_name") disableChannel(channelId, channelName, err.Message) From 81c5901123b74553cfb004388d51779936c1afdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=A9=E7=89=9B=E7=89=9B?= Date: Sat, 15 Jul 2023 12:03:23 +0800 Subject: [PATCH 4/4] feat: add support for /v1/engines/text-embedding-ada-002/embeddings (#224, close #222) --- controller/relay-text.go | 6 +++++- controller/relay.go | 5 ++++- middleware/distributor.go | 8 +++++++- router/relay-router.go | 4 +++- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/controller/relay-text.go b/controller/relay-text.go index eab71a95..a26355e3 100644 --- a/controller/relay-text.go +++ b/controller/relay-text.go @@ -6,12 +6,13 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gin-gonic/gin" "io" "net/http" "one-api/common" "one-api/model" "strings" + + "github.com/gin-gonic/gin" ) func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { @@ -30,6 +31,9 @@ func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode { if relayMode == RelayModeModerations && textRequest.Model == "" { textRequest.Model = "text-moderation-latest" } + if relayMode == RelayModeEmbeddings && textRequest.Model == "" { + textRequest.Model = c.Param("model") + } // request validation if textRequest.Model == "" { return errorWrapper(errors.New("model is required"), "required_field_missing", http.StatusBadRequest) diff --git a/controller/relay.go b/controller/relay.go index c8bd929c..2f562799 100644 --- a/controller/relay.go +++ b/controller/relay.go @@ -2,10 +2,11 @@ package controller import ( "fmt" - "github.com/gin-gonic/gin" "net/http" "one-api/common" "strings" + + "github.com/gin-gonic/gin" ) type Message struct { @@ -100,6 +101,8 @@ func Relay(c *gin.Context) { relayMode = RelayModeCompletions } else if strings.HasPrefix(c.Request.URL.Path, "/v1/embeddings") { relayMode = RelayModeEmbeddings + } else if strings.HasSuffix(c.Request.URL.Path, "embeddings") { + relayMode = RelayModeEmbeddings } else if strings.HasPrefix(c.Request.URL.Path, "/v1/moderations") { relayMode = RelayModeModerations } else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") { diff --git a/middleware/distributor.go b/middleware/distributor.go index 314677c7..cb419d6d 100644 --- a/middleware/distributor.go +++ b/middleware/distributor.go @@ -2,12 +2,13 @@ package middleware import ( "fmt" - "github.com/gin-gonic/gin" "net/http" "one-api/common" "one-api/model" "strconv" "strings" + + "github.com/gin-gonic/gin" ) type ModelRequest struct { @@ -73,6 +74,11 @@ func Distribute() func(c *gin.Context) { modelRequest.Model = "text-moderation-stable" } } + if strings.HasSuffix(c.Request.URL.Path, "embeddings") { + if modelRequest.Model == "" { + modelRequest.Model = c.Param("model") + } + } channel, err = model.CacheGetRandomSatisfiedChannel(userGroup, modelRequest.Model) if err != nil { message := "无可用渠道" diff --git a/router/relay-router.go b/router/relay-router.go index cbdfef11..cef5c7cc 100644 --- a/router/relay-router.go +++ b/router/relay-router.go @@ -1,9 +1,10 @@ package router import ( - "github.com/gin-gonic/gin" "one-api/controller" "one-api/middleware" + + "github.com/gin-gonic/gin" ) func SetRelayRouter(router *gin.Engine) { @@ -24,6 +25,7 @@ func SetRelayRouter(router *gin.Engine) { relayV1Router.POST("/images/edits", controller.RelayNotImplemented) relayV1Router.POST("/images/variations", controller.RelayNotImplemented) relayV1Router.POST("/embeddings", controller.Relay) + relayV1Router.POST("/engines/:model/embeddings", controller.Relay) relayV1Router.POST("/audio/transcriptions", controller.RelayNotImplemented) relayV1Router.POST("/audio/translations", controller.RelayNotImplemented) relayV1Router.GET("/files", controller.RelayNotImplemented)