Merge branch 'main' into dall-e-image-creation
This commit is contained in:
commit
f4cc40c868
@ -6,12 +6,13 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"one-api/common"
|
"one-api/common"
|
||||||
"one-api/model"
|
"one-api/model"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func relayTextHelper(c *gin.Context, relayMode int) *OpenAIErrorWithStatusCode {
|
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 == "" {
|
if relayMode == RelayModeModerations && textRequest.Model == "" {
|
||||||
textRequest.Model = "text-moderation-latest"
|
textRequest.Model = "text-moderation-latest"
|
||||||
}
|
}
|
||||||
|
if relayMode == RelayModeEmbeddings && textRequest.Model == "" {
|
||||||
|
textRequest.Model = c.Param("model")
|
||||||
|
}
|
||||||
// request validation
|
// request validation
|
||||||
if textRequest.Model == "" {
|
if textRequest.Model == "" {
|
||||||
return errorWrapper(errors.New("model is required"), "required_field_missing", http.StatusBadRequest)
|
return errorWrapper(errors.New("model is required"), "required_field_missing", http.StatusBadRequest)
|
||||||
|
@ -115,6 +115,8 @@ func Relay(c *gin.Context) {
|
|||||||
relayMode = RelayModeCompletions
|
relayMode = RelayModeCompletions
|
||||||
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/embeddings") {
|
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/embeddings") {
|
||||||
relayMode = RelayModeEmbeddings
|
relayMode = RelayModeEmbeddings
|
||||||
|
} else if strings.HasSuffix(c.Request.URL.Path, "embeddings") {
|
||||||
|
relayMode = RelayModeEmbeddings
|
||||||
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/moderations") {
|
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/moderations") {
|
||||||
relayMode = RelayModeModerations
|
relayMode = RelayModeModerations
|
||||||
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
|
} else if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
|
||||||
@ -139,7 +141,7 @@ func Relay(c *gin.Context) {
|
|||||||
channelId := c.GetInt("channel_id")
|
channelId := c.GetInt("channel_id")
|
||||||
common.SysError(fmt.Sprintf("relay error (channel #%d): %s", channelId, err.Message))
|
common.SysError(fmt.Sprintf("relay error (channel #%d): %s", channelId, err.Message))
|
||||||
// https://platform.openai.com/docs/guides/error-codes/api-errors
|
// 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")
|
channelId := c.GetInt("channel_id")
|
||||||
channelName := c.GetString("channel_name")
|
channelName := c.GetString("channel_name")
|
||||||
disableChannel(channelId, channelName, err.Message)
|
disableChannel(channelId, channelName, err.Message)
|
||||||
|
47
i18n/en.json
47
i18n/en.json
@ -107,6 +107,11 @@
|
|||||||
"已禁用": "Disabled",
|
"已禁用": "Disabled",
|
||||||
"未知状态": "Unknown status",
|
"未知状态": "Unknown status",
|
||||||
" 秒": "s",
|
" 秒": "s",
|
||||||
|
" 分钟 ": " m ",
|
||||||
|
" 小时 ": " h ",
|
||||||
|
" 天 ": " d ",
|
||||||
|
" 个月 ": " M ",
|
||||||
|
" 年 ": " y ",
|
||||||
"未测试": "Not tested",
|
"未测试": "Not tested",
|
||||||
"通道 ${name} 测试成功,耗时 ${time.toFixed(2)} 秒。": "Channel ${name} test succeeded, time consumed ${time.toFixed(2)} s.",
|
"通道 ${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.",
|
"已成功开始测试所有已启用通道,请刷新页面查看结果。": "All enabled channels have been successfully tested, please refresh the page to view the results.",
|
||||||
@ -458,5 +463,45 @@
|
|||||||
"消耗额度": "Used Quota",
|
"消耗额度": "Used Quota",
|
||||||
"可选值": "Optional Values",
|
"可选值": "Optional Values",
|
||||||
"渠道不存在:%d": "Channel does not exist: %d",
|
"渠道不存在:%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"
|
||||||
}
|
}
|
||||||
|
@ -74,6 +74,11 @@ func Distribute() func(c *gin.Context) {
|
|||||||
modelRequest.Model = "text-moderation-stable"
|
modelRequest.Model = "text-moderation-stable"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if strings.HasSuffix(c.Request.URL.Path, "embeddings") {
|
||||||
|
if modelRequest.Model == "" {
|
||||||
|
modelRequest.Model = c.Param("model")
|
||||||
|
}
|
||||||
|
}
|
||||||
if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
|
if strings.HasPrefix(c.Request.URL.Path, "/v1/images/generations") {
|
||||||
if modelRequest.Model == "" {
|
if modelRequest.Model == "" {
|
||||||
modelRequest.Model = "dall-e"
|
modelRequest.Model = "dall-e"
|
||||||
|
@ -25,6 +25,7 @@ func SetRelayRouter(router *gin.Engine) {
|
|||||||
relayV1Router.POST("/images/edits", controller.RelayNotImplemented)
|
relayV1Router.POST("/images/edits", controller.RelayNotImplemented)
|
||||||
relayV1Router.POST("/images/variations", controller.RelayNotImplemented)
|
relayV1Router.POST("/images/variations", controller.RelayNotImplemented)
|
||||||
relayV1Router.POST("/embeddings", controller.Relay)
|
relayV1Router.POST("/embeddings", controller.Relay)
|
||||||
|
relayV1Router.POST("/engines/:model/embeddings", controller.Relay)
|
||||||
relayV1Router.POST("/audio/transcriptions", controller.RelayNotImplemented)
|
relayV1Router.POST("/audio/transcriptions", controller.RelayNotImplemented)
|
||||||
relayV1Router.POST("/audio/translations", controller.RelayNotImplemented)
|
relayV1Router.POST("/audio/translations", controller.RelayNotImplemented)
|
||||||
relayV1Router.GET("/files", controller.RelayNotImplemented)
|
relayV1Router.GET("/files", controller.RelayNotImplemented)
|
||||||
|
@ -226,6 +226,7 @@ const UsersTable = () => {
|
|||||||
<Popup
|
<Popup
|
||||||
content={user.email ? user.email : '未绑定邮箱地址'}
|
content={user.email ? user.email : '未绑定邮箱地址'}
|
||||||
key={user.username}
|
key={user.username}
|
||||||
|
header={user.display_name ? user.display_name : user.username}
|
||||||
trigger={<span>{renderText(user.username, 10)}</span>}
|
trigger={<span>{renderText(user.username, 10)}</span>}
|
||||||
hoverable
|
hoverable
|
||||||
/>
|
/>
|
||||||
|
Loading…
Reference in New Issue
Block a user