Merge remote-tracking branch 'upstream/main'

This commit is contained in:
wozulong 2024-05-10 14:08:43 +08:00
commit 0ed6600437
14 changed files with 99 additions and 28 deletions

View File

@ -16,7 +16,22 @@ func SafeGoroutine(f func()) {
}() }()
} }
func SafeSend(ch chan bool, value bool) (closed bool) { func SafeSendBool(ch chan bool, value bool) (closed bool) {
defer func() {
// Recover from panic if one occured. A panic would mean the channel was closed.
if recover() != nil {
closed = true
}
}()
// This will panic if the channel is closed.
ch <- value
// If the code reaches here, then the channel was not closed.
return false
}
func SafeSendString(ch chan string, value string) (closed bool) {
defer func() { defer func() {
// Recover from panic if one occured. A panic would mean the channel was closed. // Recover from panic if one occured. A panic would mean the channel was closed.
if recover() != nil { if recover() != nil {

View File

@ -112,6 +112,8 @@ var DefaultModelRatio = map[string]float64{
"command-light-nightly": 0.5, "command-light-nightly": 0.5,
"command-r": 0.25, "command-r": 0.25,
"command-r-plus ": 1.5, "command-r-plus ": 1.5,
"deepseek-chat": 0.07,
"deepseek-coder": 0.07,
} }
var DefaultModelPrice = map[string]float64{ var DefaultModelPrice = map[string]float64{
@ -243,6 +245,9 @@ func GetCompletionRatio(name string) float64 {
return 2 return 2
} }
} }
if strings.HasPrefix(name, "deepseek") {
return 2
}
switch name { switch name {
case "llama2-70b-4096": case "llama2-70b-4096":
return 0.8 / 0.7 return 0.8 / 0.7

View File

@ -1,6 +1,7 @@
package constant package constant
var MjNotifyEnabled = false var MjNotifyEnabled = false
var MjAccountFilterEnabled = false
var MjModeClearEnabled = false var MjModeClearEnabled = false
var MjForwardUrlEnabled = true var MjForwardUrlEnabled = true

View File

@ -86,7 +86,7 @@ func UpdateMidjourneyTaskBulk() {
continue continue
} }
// 设置超时时间 // 设置超时时间
timeout := time.Second * 5 timeout := time.Second * 15
ctx, cancel := context.WithTimeout(context.Background(), timeout) ctx, cancel := context.WithTimeout(context.Background(), timeout)
// 使用带有超时的 context 创建新的请求 // 使用带有超时的 context 创建新的请求
req = req.WithContext(ctx) req = req.WithContext(ctx)

View File

@ -97,6 +97,7 @@ func InitOptionMap() {
common.OptionMap["DataExportDefaultTime"] = common.DataExportDefaultTime common.OptionMap["DataExportDefaultTime"] = common.DataExportDefaultTime
common.OptionMap["DefaultCollapseSidebar"] = strconv.FormatBool(common.DefaultCollapseSidebar) common.OptionMap["DefaultCollapseSidebar"] = strconv.FormatBool(common.DefaultCollapseSidebar)
common.OptionMap["MjNotifyEnabled"] = strconv.FormatBool(constant.MjNotifyEnabled) common.OptionMap["MjNotifyEnabled"] = strconv.FormatBool(constant.MjNotifyEnabled)
common.OptionMap["MjAccountFilterEnabled"] = strconv.FormatBool(constant.MjAccountFilterEnabled)
common.OptionMap["MjModeClearEnabled"] = strconv.FormatBool(constant.MjModeClearEnabled) common.OptionMap["MjModeClearEnabled"] = strconv.FormatBool(constant.MjModeClearEnabled)
common.OptionMap["MjForwardUrlEnabled"] = strconv.FormatBool(constant.MjForwardUrlEnabled) common.OptionMap["MjForwardUrlEnabled"] = strconv.FormatBool(constant.MjForwardUrlEnabled)
common.OptionMap["CheckSensitiveEnabled"] = strconv.FormatBool(constant.CheckSensitiveEnabled) common.OptionMap["CheckSensitiveEnabled"] = strconv.FormatBool(constant.CheckSensitiveEnabled)
@ -206,6 +207,8 @@ func updateOptionMap(key string, value string) (err error) {
common.DefaultCollapseSidebar = boolValue common.DefaultCollapseSidebar = boolValue
case "MjNotifyEnabled": case "MjNotifyEnabled":
constant.MjNotifyEnabled = boolValue constant.MjNotifyEnabled = boolValue
case "MjAccountFilterEnabled":
constant.MjAccountFilterEnabled = boolValue
case "MjModeClearEnabled": case "MjModeClearEnabled":
constant.MjModeClearEnabled = boolValue constant.MjModeClearEnabled = boolValue
case "MjForwardUrlEnabled": case "MjForwardUrlEnabled":

View File

@ -270,14 +270,17 @@ func (user *User) Edit(updatePassword bool) error {
} }
} }
newUser := *user newUser := *user
DB.First(&user, user.Id) updates := map[string]interface{}{
err = DB.Model(user).Updates(map[string]interface{}{
"username": newUser.Username, "username": newUser.Username,
"password": newUser.Password,
"display_name": newUser.DisplayName, "display_name": newUser.DisplayName,
"group": newUser.Group, "group": newUser.Group,
"quota": newUser.Quota, "quota": newUser.Quota,
}).Error }
if updatePassword {
updates["password"] = newUser.Password
}
DB.First(&user, user.Id)
err = DB.Model(user).Updates(updates).Error
if err == nil { if err == nil {
if common.RedisEnabled { if common.RedisEnabled {
_ = common.RedisSet(fmt.Sprintf("user_group:%d", user.Id), user.Group, time.Duration(UserId2GroupCacheSeconds)*time.Second) _ = common.RedisSet(fmt.Sprintf("user_group:%d", user.Id), user.Group, time.Duration(UserId2GroupCacheSeconds)*time.Second)

View File

@ -5,6 +5,7 @@ import "one-api/relay/channel/claude"
type AwsClaudeRequest struct { type AwsClaudeRequest struct {
// AnthropicVersion should be "bedrock-2023-05-31" // AnthropicVersion should be "bedrock-2023-05-31"
AnthropicVersion string `json:"anthropic_version"` AnthropicVersion string `json:"anthropic_version"`
System string `json:"system"`
Messages []claude.ClaudeMessage `json:"messages"` Messages []claude.ClaudeMessage `json:"messages"`
MaxTokens int `json:"max_tokens,omitempty"` MaxTokens int `json:"max_tokens,omitempty"`
Temperature float64 `json:"temperature,omitempty"` Temperature float64 `json:"temperature,omitempty"`

View File

@ -24,15 +24,16 @@ type ClaudeMessage struct {
} }
type ClaudeRequest struct { type ClaudeRequest struct {
Model string `json:"model"` Model string `json:"model"`
Prompt string `json:"prompt,omitempty"` Prompt string `json:"prompt,omitempty"`
System string `json:"system,omitempty"` System string `json:"system,omitempty"`
Messages []ClaudeMessage `json:"messages,omitempty"` Messages []ClaudeMessage `json:"messages,omitempty"`
MaxTokens uint `json:"max_tokens,omitempty"` MaxTokens uint `json:"max_tokens,omitempty"`
StopSequences []string `json:"stop_sequences,omitempty"` MaxTokensToSample uint `json:"max_tokens_to_sample,omitempty"`
Temperature float64 `json:"temperature,omitempty"` StopSequences []string `json:"stop_sequences,omitempty"`
TopP float64 `json:"top_p,omitempty"` Temperature float64 `json:"temperature,omitempty"`
TopK int `json:"top_k,omitempty"` TopP float64 `json:"top_p,omitempty"`
TopK int `json:"top_k,omitempty"`
//ClaudeMetadata `json:"metadata,omitempty"` //ClaudeMetadata `json:"metadata,omitempty"`
Stream bool `json:"stream,omitempty"` Stream bool `json:"stream,omitempty"`
} }

View File

@ -30,15 +30,14 @@ func RequestOpenAI2ClaudeComplete(textRequest dto.GeneralOpenAIRequest) *ClaudeR
claudeRequest := ClaudeRequest{ claudeRequest := ClaudeRequest{
Model: textRequest.Model, Model: textRequest.Model,
Prompt: "", Prompt: "",
MaxTokens: textRequest.MaxTokens,
StopSequences: nil, StopSequences: nil,
Temperature: textRequest.Temperature, Temperature: textRequest.Temperature,
TopP: textRequest.TopP, TopP: textRequest.TopP,
TopK: textRequest.TopK, TopK: textRequest.TopK,
Stream: textRequest.Stream, Stream: textRequest.Stream,
} }
if claudeRequest.MaxTokens == 0 { if claudeRequest.MaxTokensToSample == 0 {
claudeRequest.MaxTokens = 4096 claudeRequest.MaxTokensToSample = 4096
} }
prompt := "" prompt := ""
for _, message := range textRequest.Messages { for _, message := range textRequest.Messages {

View File

@ -50,7 +50,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
if data[:6] != "data: " && data[:6] != "[DONE]" { if data[:6] != "data: " && data[:6] != "[DONE]" {
continue continue
} }
dataChan <- data common.SafeSendString(dataChan, data)
data = data[6:] data = data[6:]
if !strings.HasPrefix(data, "[DONE]") { if !strings.HasPrefix(data, "[DONE]") {
streamItems = append(streamItems, data) streamItems = append(streamItems, data)
@ -123,7 +123,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
// wait data out // wait data out
time.Sleep(2 * time.Second) time.Sleep(2 * time.Second)
} }
common.SafeSend(stopChan, true) common.SafeSendBool(stopChan, true)
}() }()
service.SetEventStreamHeaders(c) service.SetEventStreamHeaders(c)
c.Stream(func(w io.Writer) bool { c.Stream(func(w io.Writer) bool {

View File

@ -264,10 +264,10 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
completionTokens := usage.CompletionTokens completionTokens := usage.CompletionTokens
tokenName := ctx.GetString("token_name") tokenName := ctx.GetString("token_name")
completionRatio := common.GetCompletionRatio(textRequest.Model)
quota := 0 quota := 0
if modelPrice == -1 { if modelPrice == -1 {
completionRatio := common.GetCompletionRatio(textRequest.Model)
quota = promptTokens + int(float64(completionTokens)*completionRatio) quota = promptTokens + int(float64(completionTokens)*completionRatio)
quota = int(float64(quota) * ratio) quota = int(float64(quota) * ratio)
if ratio != 0 && quota <= 0 { if ratio != 0 && quota <= 0 {
@ -279,7 +279,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
totalTokens := promptTokens + completionTokens totalTokens := promptTokens + completionTokens
var logContent string var logContent string
if modelPrice == -1 { if modelPrice == -1 {
logContent = fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio) logContent = fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f,补全倍率 %.2f", modelRatio, groupRatio, completionRatio)
} else { } else {
logContent = fmt.Sprintf("模型价格 %.2f,分组倍率 %.2f", modelPrice, groupRatio) logContent = fmt.Sprintf("模型价格 %.2f,分组倍率 %.2f", modelPrice, groupRatio)
} }

View File

@ -165,7 +165,9 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
if err != nil { if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_request_body_failed", http.StatusInternalServerError), nullBytes, err return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_request_body_failed", http.StatusInternalServerError), nullBytes, err
} }
delete(mapResult, "accountFilter") if !constant.MjAccountFilterEnabled {
delete(mapResult, "accountFilter")
}
if !constant.MjNotifyEnabled { if !constant.MjNotifyEnabled {
delete(mapResult, "notifyHook") delete(mapResult, "notifyHook")
} }
@ -174,11 +176,11 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
} }
if constant.MjModeClearEnabled { if constant.MjModeClearEnabled {
if prompt, ok := mapResult["prompt"].(string); ok { if prompt, ok := mapResult["prompt"].(string); ok {
prompt = strings.Replace(prompt, "--fast", "", -1) prompt = strings.Replace(prompt, "--fast", "", -1)
prompt = strings.Replace(prompt, "--relax", "", -1) prompt = strings.Replace(prompt, "--relax", "", -1)
prompt = strings.Replace(prompt, "--turbo", "", -1) prompt = strings.Replace(prompt, "--turbo", "", -1)
mapResult["prompt"] = prompt mapResult["prompt"] = prompt
} }
} }
reqBody, err := json.Marshal(mapResult) reqBody, err := json.Marshal(mapResult)

View File

@ -236,6 +236,31 @@ const renderTimestamp = (timestampInSeconds) => {
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; // 格式化输出 return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; // 格式化输出
}; };
// 修改renderDuration函数以包含颜色逻辑
function renderDuration(submit_time, finishTime) {
// 确保startTime和finishTime都是有效的时间戳
if (!submit_time || !finishTime) return 'N/A';
// 将时间戳转换为Date对象
const start = new Date(submit_time);
const finish = new Date(finishTime);
// 计算时间差(毫秒)
const durationMs = finish - start;
// 将时间差转换为秒,并保留一位小数
const durationSec = (durationMs / 1000).toFixed(1);
// 设置颜色大于60秒则为红色小于等于60秒则为绿色
const color = durationSec > 60 ? 'red' : 'green';
// 返回带有样式的颜色标签
return (
<Tag color={color} size="large">
{durationSec}
</Tag>
);
}
const LogsTable = () => { const LogsTable = () => {
const [isModalOpen, setIsModalOpen] = useState(false); const [isModalOpen, setIsModalOpen] = useState(false);
@ -248,6 +273,15 @@ const LogsTable = () => {
return <div>{renderTimestamp(text / 1000)}</div>; return <div>{renderTimestamp(text / 1000)}</div>;
}, },
}, },
{
title: '花费时间',
dataIndex: 'finish_time', // 以finish_time作为dataIndex
key: 'finish_time',
render: (finish, record) => {
// 假设record.start_time是存在的并且finish是完成时间的时间戳
return renderDuration(record.submit_time, finish);
},
},
{ {
title: '渠道', title: '渠道',
dataIndex: 'channel_id', dataIndex: 'channel_id',

View File

@ -38,6 +38,7 @@ const OperationSetting = () => {
StopOnSensitiveEnabled: '', StopOnSensitiveEnabled: '',
SensitiveWords: '', SensitiveWords: '',
MjNotifyEnabled: '', MjNotifyEnabled: '',
MjAccountFilterEnabled: '',
MjModeClearEnabled: '', MjModeClearEnabled: '',
MjForwardUrlEnabled: '', MjForwardUrlEnabled: '',
DrawingEnabled: '', DrawingEnabled: '',
@ -323,6 +324,12 @@ const OperationSetting = () => {
name='MjNotifyEnabled' name='MjNotifyEnabled'
onChange={handleInputChange} onChange={handleInputChange}
/> />
<Form.Checkbox
checked={inputs.MjAccountFilterEnabled === 'true'}
label='允许AccountFilter参数'
name='MjAccountFilterEnabled'
onChange={handleInputChange}
/>
<Form.Checkbox <Form.Checkbox
checked={inputs.MjForwardUrlEnabled === 'true'} checked={inputs.MjForwardUrlEnabled === 'true'}
label='开启之后将上游地址替换为服务器地址' label='开启之后将上游地址替换为服务器地址'