diff --git a/common/go-channel.go b/common/go-channel.go
index 4f00dff..8cd49ae 100644
--- a/common/go-channel.go
+++ b/common/go-channel.go
@@ -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() {
// Recover from panic if one occured. A panic would mean the channel was closed.
if recover() != nil {
diff --git a/common/model-ratio.go b/common/model-ratio.go
index bc06de1..b48da29 100644
--- a/common/model-ratio.go
+++ b/common/model-ratio.go
@@ -112,6 +112,8 @@ var DefaultModelRatio = map[string]float64{
"command-light-nightly": 0.5,
"command-r": 0.25,
"command-r-plus ": 1.5,
+ "deepseek-chat": 0.07,
+ "deepseek-coder": 0.07,
}
var DefaultModelPrice = map[string]float64{
@@ -243,6 +245,9 @@ func GetCompletionRatio(name string) float64 {
return 2
}
}
+ if strings.HasPrefix(name, "deepseek") {
+ return 2
+ }
switch name {
case "llama2-70b-4096":
return 0.8 / 0.7
diff --git a/constant/midjourney.go b/constant/midjourney.go
index cd38d5f..a8d0bfe 100644
--- a/constant/midjourney.go
+++ b/constant/midjourney.go
@@ -1,6 +1,7 @@
package constant
var MjNotifyEnabled = false
+var MjAccountFilterEnabled = false
var MjModeClearEnabled = false
var MjForwardUrlEnabled = true
diff --git a/controller/midjourney.go b/controller/midjourney.go
index 3d779c8..2d538f1 100644
--- a/controller/midjourney.go
+++ b/controller/midjourney.go
@@ -86,7 +86,7 @@ func UpdateMidjourneyTaskBulk() {
continue
}
// 设置超时时间
- timeout := time.Second * 5
+ timeout := time.Second * 15
ctx, cancel := context.WithTimeout(context.Background(), timeout)
// 使用带有超时的 context 创建新的请求
req = req.WithContext(ctx)
diff --git a/model/option.go b/model/option.go
index 18082b2..f3081c7 100644
--- a/model/option.go
+++ b/model/option.go
@@ -97,6 +97,7 @@ func InitOptionMap() {
common.OptionMap["DataExportDefaultTime"] = common.DataExportDefaultTime
common.OptionMap["DefaultCollapseSidebar"] = strconv.FormatBool(common.DefaultCollapseSidebar)
common.OptionMap["MjNotifyEnabled"] = strconv.FormatBool(constant.MjNotifyEnabled)
+ common.OptionMap["MjAccountFilterEnabled"] = strconv.FormatBool(constant.MjAccountFilterEnabled)
common.OptionMap["MjModeClearEnabled"] = strconv.FormatBool(constant.MjModeClearEnabled)
common.OptionMap["MjForwardUrlEnabled"] = strconv.FormatBool(constant.MjForwardUrlEnabled)
common.OptionMap["CheckSensitiveEnabled"] = strconv.FormatBool(constant.CheckSensitiveEnabled)
@@ -206,6 +207,8 @@ func updateOptionMap(key string, value string) (err error) {
common.DefaultCollapseSidebar = boolValue
case "MjNotifyEnabled":
constant.MjNotifyEnabled = boolValue
+ case "MjAccountFilterEnabled":
+ constant.MjAccountFilterEnabled = boolValue
case "MjModeClearEnabled":
constant.MjModeClearEnabled = boolValue
case "MjForwardUrlEnabled":
diff --git a/model/user.go b/model/user.go
index 3f75182..e8f2aa4 100644
--- a/model/user.go
+++ b/model/user.go
@@ -270,14 +270,17 @@ func (user *User) Edit(updatePassword bool) error {
}
}
newUser := *user
- DB.First(&user, user.Id)
- err = DB.Model(user).Updates(map[string]interface{}{
+ updates := map[string]interface{}{
"username": newUser.Username,
- "password": newUser.Password,
"display_name": newUser.DisplayName,
"group": newUser.Group,
"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 common.RedisEnabled {
_ = common.RedisSet(fmt.Sprintf("user_group:%d", user.Id), user.Group, time.Duration(UserId2GroupCacheSeconds)*time.Second)
diff --git a/relay/channel/aws/dto.go b/relay/channel/aws/dto.go
index 7450908..7a267b1 100644
--- a/relay/channel/aws/dto.go
+++ b/relay/channel/aws/dto.go
@@ -5,6 +5,7 @@ import "one-api/relay/channel/claude"
type AwsClaudeRequest struct {
// AnthropicVersion should be "bedrock-2023-05-31"
AnthropicVersion string `json:"anthropic_version"`
+ System string `json:"system"`
Messages []claude.ClaudeMessage `json:"messages"`
MaxTokens int `json:"max_tokens,omitempty"`
Temperature float64 `json:"temperature,omitempty"`
diff --git a/relay/channel/claude/dto.go b/relay/channel/claude/dto.go
index 2d13e46..47f0c3b 100644
--- a/relay/channel/claude/dto.go
+++ b/relay/channel/claude/dto.go
@@ -24,15 +24,16 @@ type ClaudeMessage struct {
}
type ClaudeRequest struct {
- Model string `json:"model"`
- Prompt string `json:"prompt,omitempty"`
- System string `json:"system,omitempty"`
- Messages []ClaudeMessage `json:"messages,omitempty"`
- MaxTokens uint `json:"max_tokens,omitempty"`
- StopSequences []string `json:"stop_sequences,omitempty"`
- Temperature float64 `json:"temperature,omitempty"`
- TopP float64 `json:"top_p,omitempty"`
- TopK int `json:"top_k,omitempty"`
+ Model string `json:"model"`
+ Prompt string `json:"prompt,omitempty"`
+ System string `json:"system,omitempty"`
+ Messages []ClaudeMessage `json:"messages,omitempty"`
+ MaxTokens uint `json:"max_tokens,omitempty"`
+ MaxTokensToSample uint `json:"max_tokens_to_sample,omitempty"`
+ StopSequences []string `json:"stop_sequences,omitempty"`
+ Temperature float64 `json:"temperature,omitempty"`
+ TopP float64 `json:"top_p,omitempty"`
+ TopK int `json:"top_k,omitempty"`
//ClaudeMetadata `json:"metadata,omitempty"`
Stream bool `json:"stream,omitempty"`
}
diff --git a/relay/channel/claude/relay-claude.go b/relay/channel/claude/relay-claude.go
index 07767a4..d1d8e6e 100644
--- a/relay/channel/claude/relay-claude.go
+++ b/relay/channel/claude/relay-claude.go
@@ -30,15 +30,14 @@ func RequestOpenAI2ClaudeComplete(textRequest dto.GeneralOpenAIRequest) *ClaudeR
claudeRequest := ClaudeRequest{
Model: textRequest.Model,
Prompt: "",
- MaxTokens: textRequest.MaxTokens,
StopSequences: nil,
Temperature: textRequest.Temperature,
TopP: textRequest.TopP,
TopK: textRequest.TopK,
Stream: textRequest.Stream,
}
- if claudeRequest.MaxTokens == 0 {
- claudeRequest.MaxTokens = 4096
+ if claudeRequest.MaxTokensToSample == 0 {
+ claudeRequest.MaxTokensToSample = 4096
}
prompt := ""
for _, message := range textRequest.Messages {
diff --git a/relay/channel/openai/relay-openai.go b/relay/channel/openai/relay-openai.go
index d627575..6825119 100644
--- a/relay/channel/openai/relay-openai.go
+++ b/relay/channel/openai/relay-openai.go
@@ -50,7 +50,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
if data[:6] != "data: " && data[:6] != "[DONE]" {
continue
}
- dataChan <- data
+ common.SafeSendString(dataChan, data)
data = data[6:]
if !strings.HasPrefix(data, "[DONE]") {
streamItems = append(streamItems, data)
@@ -123,7 +123,7 @@ func OpenaiStreamHandler(c *gin.Context, resp *http.Response, relayMode int) (*d
// wait data out
time.Sleep(2 * time.Second)
}
- common.SafeSend(stopChan, true)
+ common.SafeSendBool(stopChan, true)
}()
service.SetEventStreamHeaders(c)
c.Stream(func(w io.Writer) bool {
diff --git a/relay/relay-text.go b/relay/relay-text.go
index e9aa7bb..7c2720e 100644
--- a/relay/relay-text.go
+++ b/relay/relay-text.go
@@ -264,10 +264,10 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
completionTokens := usage.CompletionTokens
tokenName := ctx.GetString("token_name")
+ completionRatio := common.GetCompletionRatio(textRequest.Model)
quota := 0
if modelPrice == -1 {
- completionRatio := common.GetCompletionRatio(textRequest.Model)
quota = promptTokens + int(float64(completionTokens)*completionRatio)
quota = int(float64(quota) * ratio)
if ratio != 0 && quota <= 0 {
@@ -279,7 +279,7 @@ func postConsumeQuota(ctx *gin.Context, relayInfo *relaycommon.RelayInfo, textRe
totalTokens := promptTokens + completionTokens
var logContent string
if modelPrice == -1 {
- logContent = fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f", modelRatio, groupRatio)
+ logContent = fmt.Sprintf("模型倍率 %.2f,分组倍率 %.2f,补全倍率 %.2f", modelRatio, groupRatio, completionRatio)
} else {
logContent = fmt.Sprintf("模型价格 %.2f,分组倍率 %.2f", modelPrice, groupRatio)
}
diff --git a/service/midjourney.go b/service/midjourney.go
index ccf5141..6bb3a9e 100644
--- a/service/midjourney.go
+++ b/service/midjourney.go
@@ -165,7 +165,9 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
if err != nil {
return MidjourneyErrorWithStatusCodeWrapper(constant.MjErrorUnknown, "read_request_body_failed", http.StatusInternalServerError), nullBytes, err
}
- delete(mapResult, "accountFilter")
+ if !constant.MjAccountFilterEnabled {
+ delete(mapResult, "accountFilter")
+ }
if !constant.MjNotifyEnabled {
delete(mapResult, "notifyHook")
}
@@ -174,11 +176,11 @@ func DoMidjourneyHttpRequest(c *gin.Context, timeout time.Duration, fullRequestU
}
if constant.MjModeClearEnabled {
if prompt, ok := mapResult["prompt"].(string); ok {
- prompt = strings.Replace(prompt, "--fast", "", -1)
- prompt = strings.Replace(prompt, "--relax", "", -1)
- prompt = strings.Replace(prompt, "--turbo", "", -1)
-
- mapResult["prompt"] = prompt
+ prompt = strings.Replace(prompt, "--fast", "", -1)
+ prompt = strings.Replace(prompt, "--relax", "", -1)
+ prompt = strings.Replace(prompt, "--turbo", "", -1)
+
+ mapResult["prompt"] = prompt
}
}
reqBody, err := json.Marshal(mapResult)
diff --git a/web/src/components/MjLogsTable.js b/web/src/components/MjLogsTable.js
index f22ddae..e86ee31 100644
--- a/web/src/components/MjLogsTable.js
+++ b/web/src/components/MjLogsTable.js
@@ -236,6 +236,31 @@ const renderTimestamp = (timestampInSeconds) => {
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 (
+