Spaces:
Sleeping
Sleeping
Dhudean
commited on
Commit
·
cbcb0fb
1
Parent(s):
0d39baf
update
Browse files- check/check.go +19 -19
- common/config/config.go +7 -0
- common/constants.go +4 -4
- controller/chat.go +103 -37
- main.go +1 -2
- model/openai.go +27 -0
check/check.go
CHANGED
|
@@ -44,25 +44,25 @@ func CheckEnvVariable() {
|
|
| 44 |
}
|
| 45 |
}
|
| 46 |
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
|
| 67 |
logger.SysLog("environment variable check passed.")
|
| 68 |
}
|
|
|
|
| 44 |
}
|
| 45 |
}
|
| 46 |
|
| 47 |
+
if config.SessionImageChatMapStr != "" {
|
| 48 |
+
pattern := `^([a-zA-Z0-9\-\/]+=([a-zA-Z0-9\-\.]+))(,[a-zA-Z0-9\-\/]+=([a-zA-Z0-9\-\.]+))*`
|
| 49 |
+
match, _ := regexp.MatchString(pattern, config.SessionImageChatMapStr)
|
| 50 |
+
if !match {
|
| 51 |
+
logger.FatalLog("环境变量 SESSION_IMAGE_CHAT_MAP 设置有误")
|
| 52 |
+
} else {
|
| 53 |
+
sessionImageChatMap := make(map[string]string)
|
| 54 |
+
pairs := strings.Split(config.SessionImageChatMapStr, ",")
|
| 55 |
+
|
| 56 |
+
for _, pair := range pairs {
|
| 57 |
+
kv := strings.Split(pair, "=")
|
| 58 |
+
sessionImageChatMap["session_id="+kv[0]] = kv[1]
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
config.SessionImageChatMap = sessionImageChatMap
|
| 62 |
+
}
|
| 63 |
+
} else {
|
| 64 |
+
logger.SysLog("环境变量 SESSION_IMAGE_CHAT_MAP 未设置,生图可能会异常")
|
| 65 |
+
}
|
| 66 |
|
| 67 |
logger.SysLog("environment variable check passed.")
|
| 68 |
}
|
common/config/config.go
CHANGED
|
@@ -27,6 +27,12 @@ var AutoModelChatMapType = env.Int("AUTO_MODEL_CHAT_MAP_TYPE", 1)
|
|
| 27 |
var YesCaptchaClientKey = env.String("YES_CAPTCHA_CLIENT_KEY", "")
|
| 28 |
var CheatUrl = env.String("CHEAT_URL", "https://gs-cheat.aytsao.cn/genspark/create/req/body")
|
| 29 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
var RateLimitCookieLockDuration = env.Int("RATE_LIMIT_COOKIE_LOCK_DURATION", 10*60)
|
| 31 |
|
| 32 |
// 路由前缀
|
|
@@ -35,6 +41,7 @@ var ModelChatMapStr = env.String("MODEL_CHAT_MAP", "")
|
|
| 35 |
var ModelChatMap = make(map[string]string)
|
| 36 |
var SessionImageChatMap = make(map[string]string)
|
| 37 |
var GlobalSessionManager *SessionManager
|
|
|
|
| 38 |
var SessionImageChatMapStr = env.String("SESSION_IMAGE_CHAT_MAP", "")
|
| 39 |
var YescaptchaClient *yescaptcha.Client
|
| 40 |
|
|
|
|
| 27 |
var YesCaptchaClientKey = env.String("YES_CAPTCHA_CLIENT_KEY", "")
|
| 28 |
var CheatUrl = env.String("CHEAT_URL", "https://gs-cheat.aytsao.cn/genspark/create/req/body")
|
| 29 |
|
| 30 |
+
// 隐藏思考过程
|
| 31 |
+
var ReasoningHide = env.Int("REASONING_HIDE", 0)
|
| 32 |
+
|
| 33 |
+
// 前置message
|
| 34 |
+
var PRE_MESSAGES_JSON = env.String("PRE_MESSAGES_JSON", "")
|
| 35 |
+
|
| 36 |
var RateLimitCookieLockDuration = env.Int("RATE_LIMIT_COOKIE_LOCK_DURATION", 10*60)
|
| 37 |
|
| 38 |
// 路由前缀
|
|
|
|
| 41 |
var ModelChatMap = make(map[string]string)
|
| 42 |
var SessionImageChatMap = make(map[string]string)
|
| 43 |
var GlobalSessionManager *SessionManager
|
| 44 |
+
|
| 45 |
var SessionImageChatMapStr = env.String("SESSION_IMAGE_CHAT_MAP", "")
|
| 46 |
var YescaptchaClient *yescaptcha.Client
|
| 47 |
|
common/constants.go
CHANGED
|
@@ -3,13 +3,13 @@ package common
|
|
| 3 |
import "time"
|
| 4 |
|
| 5 |
var StartTime = time.Now().Unix() // unit: second
|
| 6 |
-
var Version = "v1.10.
|
| 7 |
|
| 8 |
var DefaultOpenaiModelList = []string{
|
| 9 |
"gpt-4o",
|
| 10 |
"o1",
|
| 11 |
"o3-mini-high",
|
| 12 |
-
"claude-3-
|
| 13 |
"claude-3-5-haiku",
|
| 14 |
"gemini-2.0-flash",
|
| 15 |
"deep-seek-v3",
|
|
@@ -28,7 +28,7 @@ var TextModelList = []string{
|
|
| 28 |
"gpt-4o",
|
| 29 |
"o1",
|
| 30 |
"o3-mini-high",
|
| 31 |
-
"claude-3-
|
| 32 |
"claude-3-5-haiku",
|
| 33 |
"gemini-2.0-flash",
|
| 34 |
"deep-seek-v3",
|
|
@@ -37,7 +37,7 @@ var TextModelList = []string{
|
|
| 37 |
|
| 38 |
var MixtureModelList = []string{
|
| 39 |
"gpt-4o",
|
| 40 |
-
"claude-3-
|
| 41 |
"gemini-2.0-flash",
|
| 42 |
}
|
| 43 |
|
|
|
|
| 3 |
import "time"
|
| 4 |
|
| 5 |
var StartTime = time.Now().Unix() // unit: second
|
| 6 |
+
var Version = "v1.10.14" // this hard coding will be replaced automatically when building, no need to manually change
|
| 7 |
|
| 8 |
var DefaultOpenaiModelList = []string{
|
| 9 |
"gpt-4o",
|
| 10 |
"o1",
|
| 11 |
"o3-mini-high",
|
| 12 |
+
"claude-3-7-sonnet",
|
| 13 |
"claude-3-5-haiku",
|
| 14 |
"gemini-2.0-flash",
|
| 15 |
"deep-seek-v3",
|
|
|
|
| 28 |
"gpt-4o",
|
| 29 |
"o1",
|
| 30 |
"o3-mini-high",
|
| 31 |
+
"claude-3-7-sonnet",
|
| 32 |
"claude-3-5-haiku",
|
| 33 |
"gemini-2.0-flash",
|
| 34 |
"deep-seek-v3",
|
|
|
|
| 37 |
|
| 38 |
var MixtureModelList = []string{
|
| 39 |
"gpt-4o",
|
| 40 |
+
"claude-3-7-sonnet",
|
| 41 |
"gemini-2.0-flash",
|
| 42 |
}
|
| 43 |
|
controller/chat.go
CHANGED
|
@@ -336,6 +336,12 @@ func fetchImageBytes(url string) ([]byte, error) {
|
|
| 336 |
|
| 337 |
func createRequestBody(c *gin.Context, client cycletls.CycleTLS, cookie string, openAIReq *model.OpenAIChatCompletionRequest) (map[string]interface{}, error) {
|
| 338 |
openAIReq.SystemMessagesProcess(openAIReq.Model)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 339 |
|
| 340 |
// 处理消息中的图像 URL
|
| 341 |
err := processMessages(c, client, cookie, openAIReq.Messages)
|
|
@@ -486,7 +492,7 @@ func createImageRequestBody(c *gin.Context, cookie string, openAIReq *model.Open
|
|
| 486 |
}
|
| 487 |
var currentQueryString string
|
| 488 |
if len(chatId) != 0 {
|
| 489 |
-
currentQueryString = fmt.Sprintf("id=%s&type=%s",
|
| 490 |
} else {
|
| 491 |
currentQueryString = fmt.Sprintf("type=%s", imageType)
|
| 492 |
}
|
|
@@ -563,25 +569,64 @@ func createStreamResponse(responseId, modelName string, jsonData []byte, delta m
|
|
| 563 |
// handleMessageFieldDelta 处理消息字段增量
|
| 564 |
func handleMessageFieldDelta(c *gin.Context, event map[string]interface{}, responseId, modelName string, jsonData []byte) error {
|
| 565 |
fieldName, ok := event["field_name"].(string)
|
| 566 |
-
if !ok
|
| 567 |
-
!strings.Contains(fieldName, "session_state.streaming_detail_answer") &&
|
| 568 |
-
//fieldName != "session_state.reflection" &&
|
| 569 |
-
fieldName != "session_state.streaming_markmap") {
|
| 570 |
return nil
|
| 571 |
}
|
| 572 |
|
| 573 |
-
|
| 574 |
-
|
| 575 |
-
|
| 576 |
-
|
| 577 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 578 |
}
|
| 579 |
-
|
|
|
|
| 580 |
return nil
|
| 581 |
}
|
| 582 |
|
| 583 |
-
|
| 584 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 585 |
}
|
| 586 |
|
| 587 |
type Content struct {
|
|
@@ -863,9 +908,9 @@ func handleStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie string
|
|
| 863 |
case common.IsFreeLimit(data):
|
| 864 |
isRateLimit = true
|
| 865 |
logger.Warnf(ctx, "Cookie free rate limited, switching to next cookie, attempt %d/%d, COOKIE:%s", attempt+1, maxRetries, cookie)
|
| 866 |
-
|
| 867 |
// 删除cookie
|
| 868 |
-
config.RemoveCookie(cookie)
|
| 869 |
break SSELoop // 使用 label 跳出 SSE 循环
|
| 870 |
case common.IsNotLogin(data):
|
| 871 |
isRateLimit = true
|
|
@@ -1100,6 +1145,7 @@ func handleNonStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie str
|
|
| 1100 |
|
| 1101 |
scanner := bufio.NewScanner(strings.NewReader(response.Body))
|
| 1102 |
var content string
|
|
|
|
| 1103 |
var firstLine string
|
| 1104 |
var projectId string
|
| 1105 |
isRateLimit := false
|
|
@@ -1131,9 +1177,9 @@ func handleNonStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie str
|
|
| 1131 |
case common.IsFreeLimit(line):
|
| 1132 |
isRateLimit = true
|
| 1133 |
logger.Warnf(ctx, "Cookie free rate limited, switching to next cookie, attempt %d/%d, COOKIE:%s", attempt+1, maxRetries, cookie)
|
| 1134 |
-
|
| 1135 |
// 删除cookie
|
| 1136 |
-
config.RemoveCookie(cookie)
|
| 1137 |
break
|
| 1138 |
case common.IsNotLogin(line):
|
| 1139 |
isRateLimit = true
|
|
@@ -1159,6 +1205,7 @@ func handleNonStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie str
|
|
| 1159 |
FieldName string `json:"field_name"`
|
| 1160 |
Content string `json:"content"`
|
| 1161 |
Id string `json:"id"`
|
|
|
|
| 1162 |
}
|
| 1163 |
if err := json.Unmarshal([]byte(data), &parsedResponse); err != nil {
|
| 1164 |
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
@@ -1167,6 +1214,25 @@ func handleNonStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie str
|
|
| 1167 |
if parsedResponse.Type == "project_start" {
|
| 1168 |
projectId = parsedResponse.Id
|
| 1169 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1170 |
if parsedResponse.Type == "message_result" {
|
| 1171 |
// 删除临时会话
|
| 1172 |
go func() {
|
|
@@ -1191,7 +1257,7 @@ func handleNonStreamRequest(c *gin.Context, client cycletls.CycleTLS, cookie str
|
|
| 1191 |
}
|
| 1192 |
parsedResponse.Content = content.DetailAnswer
|
| 1193 |
}
|
| 1194 |
-
content = parsedResponse.Content
|
| 1195 |
break
|
| 1196 |
}
|
| 1197 |
}
|
|
@@ -1311,31 +1377,31 @@ func ImageProcess(c *gin.Context, client cycletls.CycleTLS, openAIReq model.Open
|
|
| 1311 |
)
|
| 1312 |
|
| 1313 |
var (
|
| 1314 |
-
|
| 1315 |
-
maxRetries
|
| 1316 |
-
cookie
|
| 1317 |
-
chatId
|
| 1318 |
)
|
| 1319 |
|
| 1320 |
cookieManager := config.NewCookieManager()
|
| 1321 |
-
|
| 1322 |
ctx := c.Request.Context()
|
| 1323 |
|
| 1324 |
// Initialize session manager and get initial cookie
|
| 1325 |
-
|
| 1326 |
-
|
| 1327 |
-
|
| 1328 |
|
| 1329 |
-
|
| 1330 |
-
|
| 1331 |
-
|
| 1332 |
-
|
| 1333 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1334 |
}
|
| 1335 |
-
//} else {
|
| 1336 |
-
// maxRetries = sessionImageChatManager.GetSize()
|
| 1337 |
-
// cookie, chatId, _ = sessionImageChatManager.GetRandomKeyValue()
|
| 1338 |
-
//}
|
| 1339 |
|
| 1340 |
for attempt := 0; attempt < maxRetries; attempt++ {
|
| 1341 |
// Create request body
|
|
@@ -1394,9 +1460,9 @@ func ImageProcess(c *gin.Context, client cycletls.CycleTLS, openAIReq model.Open
|
|
| 1394 |
// }
|
| 1395 |
//} else {
|
| 1396 |
//cookieManager := config.NewCookieManager()
|
| 1397 |
-
|
| 1398 |
// 删除cookie
|
| 1399 |
-
config.RemoveCookie(cookie)
|
| 1400 |
cookie, err = cookieManager.GetNextCookie()
|
| 1401 |
if err != nil {
|
| 1402 |
logger.Errorf(ctx, "No more valid cookies available after attempt %d", attempt+1)
|
|
|
|
| 336 |
|
| 337 |
func createRequestBody(c *gin.Context, client cycletls.CycleTLS, cookie string, openAIReq *model.OpenAIChatCompletionRequest) (map[string]interface{}, error) {
|
| 338 |
openAIReq.SystemMessagesProcess(openAIReq.Model)
|
| 339 |
+
if config.PRE_MESSAGES_JSON != "" {
|
| 340 |
+
err := openAIReq.PrependMessagesFromJSON(config.PRE_MESSAGES_JSON)
|
| 341 |
+
if err != nil {
|
| 342 |
+
return nil, fmt.Errorf("PrependMessagesFromJSON err: %v PrependMessagesFromJSON:", err, config.PRE_MESSAGES_JSON)
|
| 343 |
+
}
|
| 344 |
+
}
|
| 345 |
|
| 346 |
// 处理消息中的图像 URL
|
| 347 |
err := processMessages(c, client, cookie, openAIReq.Messages)
|
|
|
|
| 492 |
}
|
| 493 |
var currentQueryString string
|
| 494 |
if len(chatId) != 0 {
|
| 495 |
+
currentQueryString = fmt.Sprintf("id=%s&type=%s", "90280b44-9ddf-4f4f-ba62-d72d38a82f99", imageType)
|
| 496 |
} else {
|
| 497 |
currentQueryString = fmt.Sprintf("type=%s", imageType)
|
| 498 |
}
|
|
|
|
| 569 |
// handleMessageFieldDelta 处理消息字段增量
|
| 570 |
func handleMessageFieldDelta(c *gin.Context, event map[string]interface{}, responseId, modelName string, jsonData []byte) error {
|
| 571 |
fieldName, ok := event["field_name"].(string)
|
| 572 |
+
if !ok {
|
|
|
|
|
|
|
|
|
|
| 573 |
return nil
|
| 574 |
}
|
| 575 |
|
| 576 |
+
// 基础允许列表(所有配置下都需要处理的字段)
|
| 577 |
+
baseAllowed := fieldName == "session_state.answer" ||
|
| 578 |
+
strings.Contains(fieldName, "session_state.streaming_detail_answer") ||
|
| 579 |
+
fieldName == "session_state.streaming_markmap"
|
| 580 |
+
|
| 581 |
+
// 需要显示思考过程时需要额外处理的字段
|
| 582 |
+
if config.ReasoningHide != 1 {
|
| 583 |
+
baseAllowed = baseAllowed ||
|
| 584 |
+
fieldName == "session_state.answerthink_is_started" ||
|
| 585 |
+
fieldName == "session_state.answerthink" ||
|
| 586 |
+
fieldName == "session_state.answerthink_is_finished"
|
| 587 |
}
|
| 588 |
+
|
| 589 |
+
if !baseAllowed {
|
| 590 |
return nil
|
| 591 |
}
|
| 592 |
|
| 593 |
+
// 获取 delta 内容
|
| 594 |
+
var delta string
|
| 595 |
+
switch {
|
| 596 |
+
case (modelName == "o1" || modelName == "o3-mini-high") && fieldName == "session_state.answer":
|
| 597 |
+
delta, _ = event["field_value"].(string)
|
| 598 |
+
default:
|
| 599 |
+
delta, _ = event["delta"].(string)
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
// 创建基础响应
|
| 603 |
+
createResponse := func(content string) model.OpenAIChatCompletionResponse {
|
| 604 |
+
return createStreamResponse(
|
| 605 |
+
responseId,
|
| 606 |
+
modelName,
|
| 607 |
+
jsonData,
|
| 608 |
+
model.OpenAIDelta{Content: content, Role: "assistant"},
|
| 609 |
+
nil,
|
| 610 |
+
)
|
| 611 |
+
}
|
| 612 |
+
|
| 613 |
+
// 发送基础事件
|
| 614 |
+
var err error
|
| 615 |
+
if err = sendSSEvent(c, createResponse(delta)); err != nil {
|
| 616 |
+
return err
|
| 617 |
+
}
|
| 618 |
+
|
| 619 |
+
// 处理思考过程标记
|
| 620 |
+
if config.ReasoningHide != 1 {
|
| 621 |
+
switch fieldName {
|
| 622 |
+
case "session_state.answerthink_is_started":
|
| 623 |
+
err = sendSSEvent(c, createResponse("<think>\n"))
|
| 624 |
+
case "session_state.answerthink_is_finished":
|
| 625 |
+
err = sendSSEvent(c, createResponse("\n</think>"))
|
| 626 |
+
}
|
| 627 |
+
}
|
| 628 |
+
|
| 629 |
+
return err
|
| 630 |
}
|
| 631 |
|
| 632 |
type Content struct {
|
|
|
|
| 908 |
case common.IsFreeLimit(data):
|
| 909 |
isRateLimit = true
|
| 910 |
logger.Warnf(ctx, "Cookie free rate limited, switching to next cookie, attempt %d/%d, COOKIE:%s", attempt+1, maxRetries, cookie)
|
| 911 |
+
config.AddRateLimitCookie(cookie, time.Now().Add(24*60*60*time.Second))
|
| 912 |
// 删除cookie
|
| 913 |
+
//config.RemoveCookie(cookie)
|
| 914 |
break SSELoop // 使用 label 跳出 SSE 循环
|
| 915 |
case common.IsNotLogin(data):
|
| 916 |
isRateLimit = true
|
|
|
|
| 1145 |
|
| 1146 |
scanner := bufio.NewScanner(strings.NewReader(response.Body))
|
| 1147 |
var content string
|
| 1148 |
+
var answerThink string
|
| 1149 |
var firstLine string
|
| 1150 |
var projectId string
|
| 1151 |
isRateLimit := false
|
|
|
|
| 1177 |
case common.IsFreeLimit(line):
|
| 1178 |
isRateLimit = true
|
| 1179 |
logger.Warnf(ctx, "Cookie free rate limited, switching to next cookie, attempt %d/%d, COOKIE:%s", attempt+1, maxRetries, cookie)
|
| 1180 |
+
config.AddRateLimitCookie(cookie, time.Now().Add(24*60*60*time.Second))
|
| 1181 |
// 删除cookie
|
| 1182 |
+
//config.RemoveCookie(cookie)
|
| 1183 |
break
|
| 1184 |
case common.IsNotLogin(line):
|
| 1185 |
isRateLimit = true
|
|
|
|
| 1205 |
FieldName string `json:"field_name"`
|
| 1206 |
Content string `json:"content"`
|
| 1207 |
Id string `json:"id"`
|
| 1208 |
+
Delta string `json:"delta"`
|
| 1209 |
}
|
| 1210 |
if err := json.Unmarshal([]byte(data), &parsedResponse); err != nil {
|
| 1211 |
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
|
|
| 1214 |
if parsedResponse.Type == "project_start" {
|
| 1215 |
projectId = parsedResponse.Id
|
| 1216 |
}
|
| 1217 |
+
if parsedResponse.Type == "message_field" {
|
| 1218 |
+
// 提取思考过程
|
| 1219 |
+
if config.ReasoningHide != 1 {
|
| 1220 |
+
if parsedResponse.FieldName == "session_state.answerthink_is_started" {
|
| 1221 |
+
answerThink = "<think>\n"
|
| 1222 |
+
}
|
| 1223 |
+
if parsedResponse.FieldName == "session_state.answerthink_is_finished" {
|
| 1224 |
+
answerThink = answerThink + "\n</think>"
|
| 1225 |
+
}
|
| 1226 |
+
}
|
| 1227 |
+
}
|
| 1228 |
+
if parsedResponse.Type == "message_field_delta" {
|
| 1229 |
+
// 提取思考过程
|
| 1230 |
+
if config.ReasoningHide != 1 {
|
| 1231 |
+
if parsedResponse.FieldName == "session_state.answerthink" {
|
| 1232 |
+
answerThink = answerThink + parsedResponse.Delta
|
| 1233 |
+
}
|
| 1234 |
+
}
|
| 1235 |
+
}
|
| 1236 |
if parsedResponse.Type == "message_result" {
|
| 1237 |
// 删除临时会话
|
| 1238 |
go func() {
|
|
|
|
| 1257 |
}
|
| 1258 |
parsedResponse.Content = content.DetailAnswer
|
| 1259 |
}
|
| 1260 |
+
content = strings.TrimSpace(answerThink + parsedResponse.Content)
|
| 1261 |
break
|
| 1262 |
}
|
| 1263 |
}
|
|
|
|
| 1377 |
)
|
| 1378 |
|
| 1379 |
var (
|
| 1380 |
+
sessionImageChatManager *config.SessionMapManager
|
| 1381 |
+
maxRetries int
|
| 1382 |
+
cookie string
|
| 1383 |
+
chatId string
|
| 1384 |
)
|
| 1385 |
|
| 1386 |
cookieManager := config.NewCookieManager()
|
| 1387 |
+
sessionImageChatManager = config.NewSessionMapManager()
|
| 1388 |
ctx := c.Request.Context()
|
| 1389 |
|
| 1390 |
// Initialize session manager and get initial cookie
|
| 1391 |
+
if len(config.SessionImageChatMap) == 0 {
|
| 1392 |
+
logger.Warnf(ctx, "未配置环境变量 SESSION_IMAGE_CHAT_MAP, 可能会生图失败!")
|
| 1393 |
+
maxRetries = len(cookieManager.Cookies)
|
| 1394 |
|
| 1395 |
+
var err error
|
| 1396 |
+
cookie, err = cookieManager.GetRandomCookie()
|
| 1397 |
+
if err != nil {
|
| 1398 |
+
logger.Errorf(ctx, "Failed to get initial cookie: %v", err)
|
| 1399 |
+
return nil, fmt.Errorf(errNoValidCookies)
|
| 1400 |
+
}
|
| 1401 |
+
} else {
|
| 1402 |
+
maxRetries = sessionImageChatManager.GetSize()
|
| 1403 |
+
cookie, chatId, _ = sessionImageChatManager.GetRandomKeyValue()
|
| 1404 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1405 |
|
| 1406 |
for attempt := 0; attempt < maxRetries; attempt++ {
|
| 1407 |
// Create request body
|
|
|
|
| 1460 |
// }
|
| 1461 |
//} else {
|
| 1462 |
//cookieManager := config.NewCookieManager()
|
| 1463 |
+
config.AddRateLimitCookie(cookie, time.Now().Add(24*60*60*time.Second))
|
| 1464 |
// 删除cookie
|
| 1465 |
+
//config.RemoveCookie(cookie)
|
| 1466 |
cookie, err = cookieManager.GetNextCookie()
|
| 1467 |
if err != nil {
|
| 1468 |
logger.Errorf(ctx, "No more valid cookies available after attempt %d", attempt+1)
|
main.go
CHANGED
|
@@ -6,7 +6,6 @@ import (
|
|
| 6 |
"genspark2api/common"
|
| 7 |
"genspark2api/common/config"
|
| 8 |
logger "genspark2api/common/loggger"
|
| 9 |
-
"genspark2api/job"
|
| 10 |
"genspark2api/middleware"
|
| 11 |
"genspark2api/router"
|
| 12 |
"genspark2api/yescaptcha"
|
|
@@ -34,7 +33,7 @@ func main() {
|
|
| 34 |
config.GlobalSessionManager = config.NewSessionManager()
|
| 35 |
|
| 36 |
// 定时任务 每天9点整重载GS_COOKIES
|
| 37 |
-
go job.LoadCookieTask()
|
| 38 |
|
| 39 |
server := gin.New()
|
| 40 |
server.Use(gin.Recovery())
|
|
|
|
| 6 |
"genspark2api/common"
|
| 7 |
"genspark2api/common/config"
|
| 8 |
logger "genspark2api/common/loggger"
|
|
|
|
| 9 |
"genspark2api/middleware"
|
| 10 |
"genspark2api/router"
|
| 11 |
"genspark2api/yescaptcha"
|
|
|
|
| 33 |
config.GlobalSessionManager = config.NewSessionManager()
|
| 34 |
|
| 35 |
// 定时任务 每天9点整重载GS_COOKIES
|
| 36 |
+
//go job.LoadCookieTask()
|
| 37 |
|
| 38 |
server := gin.New()
|
| 39 |
server.Use(gin.Recovery())
|
model/openai.go
CHANGED
|
@@ -1,5 +1,7 @@
|
|
| 1 |
package model
|
| 2 |
|
|
|
|
|
|
|
| 3 |
type OpenAIChatCompletionRequest struct {
|
| 4 |
Model string `json:"model"`
|
| 5 |
Stream bool `json:"stream"`
|
|
@@ -24,6 +26,31 @@ type OpenAIChatMessage struct {
|
|
| 24 |
SessionState *SessionState `json:"session_state"`
|
| 25 |
}
|
| 26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 27 |
func (r *OpenAIChatCompletionRequest) SystemMessagesProcess(model string) {
|
| 28 |
if r.Messages == nil {
|
| 29 |
return
|
|
|
|
| 1 |
package model
|
| 2 |
|
| 3 |
+
import "encoding/json"
|
| 4 |
+
|
| 5 |
type OpenAIChatCompletionRequest struct {
|
| 6 |
Model string `json:"model"`
|
| 7 |
Stream bool `json:"stream"`
|
|
|
|
| 26 |
SessionState *SessionState `json:"session_state"`
|
| 27 |
}
|
| 28 |
|
| 29 |
+
func (r *OpenAIChatCompletionRequest) AddMessage(message OpenAIChatMessage) {
|
| 30 |
+
r.Messages = append([]OpenAIChatMessage{message}, r.Messages...)
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
func (r *OpenAIChatCompletionRequest) PrependMessagesFromJSON(jsonString string) error {
|
| 34 |
+
var newMessages []OpenAIChatMessage
|
| 35 |
+
err := json.Unmarshal([]byte(jsonString), &newMessages)
|
| 36 |
+
if err != nil {
|
| 37 |
+
return err
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
// 查找最后一个 system role 的索引
|
| 41 |
+
var insertIndex int
|
| 42 |
+
for i := len(r.Messages) - 1; i >= 0; i-- {
|
| 43 |
+
if r.Messages[i].Role == "system" {
|
| 44 |
+
insertIndex = i + 1
|
| 45 |
+
break
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
|
| 49 |
+
// 将 newMessages 插入到找到的索引后面
|
| 50 |
+
r.Messages = append(r.Messages[:insertIndex], append(newMessages, r.Messages[insertIndex:]...)...)
|
| 51 |
+
return nil
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
func (r *OpenAIChatCompletionRequest) SystemMessagesProcess(model string) {
|
| 55 |
if r.Messages == nil {
|
| 56 |
return
|