mirror of
https://github.com/linux-do/new-api.git
synced 2025-09-18 00:16:37 +08:00
Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
0ed6600437
@ -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 {
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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":
|
||||||
|
@ -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)
|
||||||
|
@ -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"`
|
||||||
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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',
|
||||||
|
@ -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='开启之后将上游地址替换为服务器地址'
|
||||||
|
Loading…
Reference in New Issue
Block a user