Spaces:
Configuration error
Configuration error
BOHE
commited on
Commit
·
b44e579
1
Parent(s):
af4375a
测试
Browse files- api/main.go +179 -206
api/main.go
CHANGED
|
@@ -24,7 +24,7 @@ type TokenCount struct {
|
|
| 24 |
}
|
| 25 |
|
| 26 |
const (
|
| 27 |
-
MaxContextTokens =
|
| 28 |
)
|
| 29 |
|
| 30 |
// YouChatResponse 定义了从 You.com API 接收的单个 token 的结构。
|
|
@@ -240,30 +240,80 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 240 |
// 转换 system 消息为 user 消息
|
| 241 |
openAIReq.Messages = convertSystemToUser(openAIReq.Messages)
|
| 242 |
|
| 243 |
-
// 计算最后一条消息的 token 数(使用字符估算方法)
|
| 244 |
-
lastMessage := openAIReq.Messages[len(openAIReq.Messages)-1]
|
| 245 |
-
lastMessageTokens, err := countTokens([]Message{lastMessage})
|
| 246 |
-
if err != nil {
|
| 247 |
-
http.Error(w, "Failed to count tokens", http.StatusInternalServerError)
|
| 248 |
-
return
|
| 249 |
-
}
|
| 250 |
-
|
| 251 |
// 构建 You.com 聊天历史
|
| 252 |
var chatHistory []map[string]interface{}
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
| 261 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 262 |
}
|
| 263 |
-
chatHistory = append(chatHistory, chatMsg)
|
| 264 |
}
|
| 265 |
|
| 266 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 267 |
|
| 268 |
// 创建 You.com API 请求
|
| 269 |
youReq, _ := http.NewRequest("GET", "https://you.com/api/streamingSearch", nil)
|
|
@@ -273,23 +323,48 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 273 |
conversationTurnId := uuid.New().String()
|
| 274 |
traceId := fmt.Sprintf("%s|%s|%s", chatId, conversationTurnId, time.Now().Format(time.RFC3339))
|
| 275 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
// 如果最后一条消息超过限制,使用文件上传
|
| 277 |
if lastMessageTokens > MaxContextTokens {
|
| 278 |
-
//
|
| 279 |
nonceResp, err := getNonce(dsToken)
|
| 280 |
if err != nil {
|
| 281 |
fmt.Printf("获取 nonce 失败: %v\n", err)
|
| 282 |
http.Error(w, "Failed to get nonce", http.StatusInternalServerError)
|
| 283 |
return
|
| 284 |
}
|
| 285 |
-
fmt.Printf("获取到 nonce: %s\n", nonceResp.Uuid)
|
| 286 |
-
|
| 287 |
-
// 4. 修改消息列表,保留历史记录,只将最后一条消息改为文件引用
|
| 288 |
-
lastMsg := openAIReq.Messages[len(openAIReq.Messages)-1]
|
| 289 |
|
| 290 |
-
//
|
| 291 |
tempFile := fmt.Sprintf("temp_%s.txt", nonceResp.Uuid)
|
| 292 |
-
if err := os.WriteFile(tempFile, []byte(
|
| 293 |
fmt.Printf("创建临时文件失败: %v\n", err)
|
| 294 |
http.Error(w, "Failed to create temp file", http.StatusInternalServerError)
|
| 295 |
return
|
|
@@ -305,197 +380,95 @@ func Handler(w http.ResponseWriter, r *http.Request) {
|
|
| 305 |
}
|
| 306 |
|
| 307 |
// 添加文件源信息
|
| 308 |
-
sources
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
},
|
| 315 |
-
}
|
| 316 |
-
sourcesJSON, err := json.Marshal(sources)
|
| 317 |
-
if err != nil {
|
| 318 |
-
fmt.Printf("序列化 sources 失败: %v\n", err)
|
| 319 |
-
http.Error(w, "Failed to marshal sources", http.StatusInternalServerError)
|
| 320 |
-
return
|
| 321 |
-
}
|
| 322 |
-
|
| 323 |
-
// 更新查询参数
|
| 324 |
-
q := youReq.URL.Query()
|
| 325 |
-
|
| 326 |
-
// 如果是第一次聊天(没有历史记录),使用空数组
|
| 327 |
-
chatJSON := "[]"
|
| 328 |
-
pastChatLength := "0"
|
| 329 |
-
if len(chatHistory) > 0 {
|
| 330 |
-
chatJSON = string(chatHistoryJSON)
|
| 331 |
-
pastChatLength = fmt.Sprintf("%d", len(chatHistory))
|
| 332 |
-
}
|
| 333 |
|
| 334 |
-
//
|
| 335 |
-
|
| 336 |
-
q.Add("count", "10")
|
| 337 |
-
q.Add("safeSearch", "Off")
|
| 338 |
-
q.Add("mkt", "en-US")
|
| 339 |
-
q.Add("enable_worklow_generation_ux", "true")
|
| 340 |
-
q.Add("domain", "youchat")
|
| 341 |
-
q.Add("use_personalization_extraction", "true")
|
| 342 |
-
q.Add("queryTraceId", chatId)
|
| 343 |
-
q.Add("chatId", chatId)
|
| 344 |
-
q.Add("conversationTurnId", conversationTurnId)
|
| 345 |
-
q.Add("pastChatLength", pastChatLength)
|
| 346 |
-
q.Add("selectedChatMode", "custom")
|
| 347 |
q.Add("sources", string(sourcesJSON))
|
| 348 |
-
q.Add("selectedAiModel", mapModelName(openAIReq.Model))
|
| 349 |
-
q.Add("enable_agent_clarification_questions", "true")
|
| 350 |
-
q.Add("traceId", traceId)
|
| 351 |
-
q.Add("use_nested_youchat_updates", "true")
|
| 352 |
-
q.Add("q", fmt.Sprintf("Please review the attached file: %s", uploadResp.UserFilename))
|
| 353 |
-
q.Add("chat", chatJSON)
|
| 354 |
|
| 355 |
-
|
| 356 |
-
|
| 357 |
-
|
| 358 |
-
|
| 359 |
-
|
| 360 |
-
|
| 361 |
-
|
| 362 |
-
}
|
| 363 |
-
|
| 364 |
-
// 设置请求头
|
| 365 |
-
youReq.Header = http.Header{
|
| 366 |
-
"sec-ch-ua-platform": {"Windows"},
|
| 367 |
-
"Cache-Control": {"no-cache"},
|
| 368 |
-
"sec-ch-ua": {`"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"`},
|
| 369 |
-
"sec-ch-ua-bitness": {"64"},
|
| 370 |
-
"sec-ch-ua-model": {""},
|
| 371 |
-
"sec-ch-ua-mobile": {"?0"},
|
| 372 |
-
"sec-ch-ua-arch": {"x86"},
|
| 373 |
-
"sec-ch-ua-full-version": {"133.0.3065.39"},
|
| 374 |
-
"Accept": {"text/event-stream"},
|
| 375 |
-
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
| 376 |
-
"sec-ch-ua-platform-version": {"19.0.0"},
|
| 377 |
-
"Sec-Fetch-Site": {"same-origin"},
|
| 378 |
-
"Sec-Fetch-Mode": {"cors"},
|
| 379 |
-
"Sec-Fetch-Dest": {"empty"},
|
| 380 |
-
"Host": {"you.com"},
|
| 381 |
-
}
|
| 382 |
-
|
| 383 |
-
// 设置 Cookie
|
| 384 |
-
cookies := getCookies(dsToken)
|
| 385 |
-
var cookieStrings []string
|
| 386 |
-
for name, value := range cookies {
|
| 387 |
-
cookieStrings = append(cookieStrings, fmt.Sprintf("%s=%s", name, value))
|
| 388 |
-
}
|
| 389 |
-
youReq.Header.Add("Cookie", strings.Join(cookieStrings, ";"))
|
| 390 |
-
fmt.Printf("Cookie: %s\n", strings.Join(cookieStrings, ";"))
|
| 391 |
-
fmt.Printf("===================\n\n")
|
| 392 |
-
|
| 393 |
-
// 发送请求并获取响应
|
| 394 |
-
client := &http.Client{}
|
| 395 |
-
resp, err := client.Do(youReq)
|
| 396 |
-
if err != nil {
|
| 397 |
-
fmt.Printf("发送请求失败: %v\n", err)
|
| 398 |
-
http.Error(w, err.Error(), http.StatusInternalServerError)
|
| 399 |
-
return
|
| 400 |
}
|
| 401 |
-
|
|
|
|
| 402 |
|
| 403 |
-
|
| 404 |
-
|
| 405 |
|
| 406 |
-
|
| 407 |
-
|
| 408 |
-
|
| 409 |
-
|
| 410 |
-
|
| 411 |
-
|
| 412 |
-
}
|
| 413 |
-
|
| 414 |
-
// 根据 OpenAI 请求的 stream 参数选择处理函数
|
| 415 |
-
if !openAIReq.Stream {
|
| 416 |
-
handleNonStreamingResponse(w, youReq) // 处理非流式响应
|
| 417 |
-
return
|
| 418 |
-
}
|
| 419 |
|
| 420 |
-
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
| 424 |
-
|
| 425 |
-
|
| 426 |
-
|
| 427 |
-
|
| 428 |
-
|
| 429 |
-
|
| 430 |
-
|
| 431 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 432 |
|
| 433 |
-
|
| 434 |
-
|
| 435 |
-
|
| 436 |
-
|
| 437 |
-
|
| 438 |
-
|
| 439 |
-
|
| 440 |
-
|
| 441 |
-
|
| 442 |
-
q.Add("chatId", chatId)
|
| 443 |
-
q.Add("conversationTurnId", conversationTurnId)
|
| 444 |
-
q.Add("pastChatLength", pastChatLength)
|
| 445 |
-
q.Add("selectedChatMode", "custom")
|
| 446 |
-
q.Add("selectedAiModel", mapModelName(openAIReq.Model))
|
| 447 |
-
q.Add("enable_agent_clarification_questions", "true")
|
| 448 |
-
q.Add("traceId", traceId)
|
| 449 |
-
q.Add("use_nested_youchat_updates", "true")
|
| 450 |
-
q.Add("q", openAIReq.Messages[len(openAIReq.Messages)-1].Content)
|
| 451 |
-
q.Add("chat", chatJSON)
|
| 452 |
-
|
| 453 |
-
youReq.URL.RawQuery = q.Encode()
|
| 454 |
-
|
| 455 |
-
fmt.Printf("\n=== 完整请求信息 ===\n")
|
| 456 |
-
fmt.Printf("请求 URL: %s\n", youReq.URL.String())
|
| 457 |
-
fmt.Printf("请求头:\n")
|
| 458 |
-
for key, values := range youReq.Header {
|
| 459 |
-
fmt.Printf("%s: %v\n", key, values)
|
| 460 |
-
}
|
| 461 |
|
| 462 |
-
|
| 463 |
-
|
| 464 |
-
|
| 465 |
-
|
| 466 |
-
|
| 467 |
-
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
| 471 |
-
"sec-ch-ua-full-version": {"133.0.3065.39"},
|
| 472 |
-
"Accept": {"text/event-stream"},
|
| 473 |
-
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
| 474 |
-
"sec-ch-ua-platform-version": {"19.0.0"},
|
| 475 |
-
"Sec-Fetch-Site": {"same-origin"},
|
| 476 |
-
"Sec-Fetch-Mode": {"cors"},
|
| 477 |
-
"Sec-Fetch-Dest": {"empty"},
|
| 478 |
-
"Host": {"you.com"},
|
| 479 |
-
}
|
| 480 |
|
| 481 |
-
|
| 482 |
-
|
| 483 |
-
var cookieStrings []string
|
| 484 |
-
for name, value := range cookies {
|
| 485 |
-
cookieStrings = append(cookieStrings, fmt.Sprintf("%s=%s", name, value))
|
| 486 |
-
}
|
| 487 |
-
youReq.Header.Add("Cookie", strings.Join(cookieStrings, ";"))
|
| 488 |
-
fmt.Printf("Cookie: %s\n", strings.Join(cookieStrings, ";"))
|
| 489 |
-
fmt.Printf("===================\n\n")
|
| 490 |
|
| 491 |
-
|
| 492 |
-
|
| 493 |
-
|
| 494 |
-
|
| 495 |
-
|
|
|
|
|
|
|
| 496 |
|
| 497 |
-
|
|
|
|
|
|
|
|
|
|
| 498 |
}
|
|
|
|
|
|
|
| 499 |
}
|
| 500 |
|
| 501 |
// getCookies 根据提供的 DS token 生成所需的 Cookie。
|
|
@@ -707,7 +680,7 @@ func countTokens(messages []Message) (int, error) {
|
|
| 707 |
}
|
| 708 |
|
| 709 |
// 计算 tokens:英文字符 * 0.3 + 中文字符 * 0.6
|
| 710 |
-
tokens := int(float64(englishCount)*0.3 + float64(chineseCount)*
|
| 711 |
|
| 712 |
// 加上角色名的 token(约 2 个)
|
| 713 |
totalTokens += tokens + 2
|
|
|
|
| 24 |
}
|
| 25 |
|
| 26 |
const (
|
| 27 |
+
MaxContextTokens = 2000 // 最大上下文 token 数
|
| 28 |
)
|
| 29 |
|
| 30 |
// YouChatResponse 定义了从 You.com API 接收的单个 token 的结构。
|
|
|
|
| 240 |
// 转换 system 消息为 user 消息
|
| 241 |
openAIReq.Messages = convertSystemToUser(openAIReq.Messages)
|
| 242 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 243 |
// 构建 You.com 聊天历史
|
| 244 |
var chatHistory []map[string]interface{}
|
| 245 |
+
var sources []map[string]interface{}
|
| 246 |
+
var lastAssistantMessage string
|
| 247 |
+
|
| 248 |
+
// 处理历史消息(不包括最后一条)
|
| 249 |
+
for _, msg := range openAIReq.Messages[:len(openAIReq.Messages)-1] {
|
| 250 |
+
if msg.Role == "user" {
|
| 251 |
+
tokens, err := countTokens([]Message{msg})
|
| 252 |
+
if err != nil {
|
| 253 |
+
http.Error(w, "Failed to count tokens", http.StatusInternalServerError)
|
| 254 |
+
return
|
| 255 |
+
}
|
| 256 |
+
|
| 257 |
+
if tokens > MaxContextTokens {
|
| 258 |
+
// 获取 nonce
|
| 259 |
+
nonceResp, err := getNonce(dsToken)
|
| 260 |
+
if err != nil {
|
| 261 |
+
fmt.Printf("获取 nonce 失败: %v\n", err)
|
| 262 |
+
http.Error(w, "Failed to get nonce", http.StatusInternalServerError)
|
| 263 |
+
return
|
| 264 |
+
}
|
| 265 |
+
|
| 266 |
+
// 创建临时文件
|
| 267 |
+
tempFile := fmt.Sprintf("temp_%s.txt", nonceResp.Uuid)
|
| 268 |
+
if err := os.WriteFile(tempFile, []byte(msg.Content), 0644); err != nil {
|
| 269 |
+
fmt.Printf("创建临时文件失败: %v\n", err)
|
| 270 |
+
http.Error(w, "Failed to create temp file", http.StatusInternalServerError)
|
| 271 |
+
return
|
| 272 |
+
}
|
| 273 |
+
defer os.Remove(tempFile)
|
| 274 |
+
|
| 275 |
+
// 上传文件
|
| 276 |
+
uploadResp, err := uploadFile(dsToken, tempFile)
|
| 277 |
+
if err != nil {
|
| 278 |
+
fmt.Printf("上传文件失败: %v\n", err)
|
| 279 |
+
http.Error(w, "Failed to upload file", http.StatusInternalServerError)
|
| 280 |
+
return
|
| 281 |
+
}
|
| 282 |
+
|
| 283 |
+
// 添加文件源信息
|
| 284 |
+
sources = append(sources, map[string]interface{}{
|
| 285 |
+
"source_type": "user_file",
|
| 286 |
+
"filename": uploadResp.Filename,
|
| 287 |
+
"user_filename": uploadResp.UserFilename,
|
| 288 |
+
"size_bytes": len(msg.Content),
|
| 289 |
+
})
|
| 290 |
+
|
| 291 |
+
// 在历史记录中使用文件引用
|
| 292 |
+
chatHistory = append(chatHistory, map[string]interface{}{
|
| 293 |
+
"question": fmt.Sprintf("Please review the attached file: %s", uploadResp.UserFilename),
|
| 294 |
+
"answer": "",
|
| 295 |
+
})
|
| 296 |
+
} else {
|
| 297 |
+
chatHistory = append(chatHistory, map[string]interface{}{
|
| 298 |
+
"question": msg.Content,
|
| 299 |
+
"answer": "",
|
| 300 |
+
})
|
| 301 |
+
}
|
| 302 |
+
} else if msg.Role == "assistant" {
|
| 303 |
+
// 只保存最后一条 assistant 消息
|
| 304 |
+
lastAssistantMessage = msg.Content
|
| 305 |
}
|
|
|
|
| 306 |
}
|
| 307 |
|
| 308 |
+
// 如果有最后一条 assistant 消息,添加到历史记录中
|
| 309 |
+
if lastAssistantMessage != "" {
|
| 310 |
+
chatHistory = append(chatHistory, map[string]interface{}{
|
| 311 |
+
"question": "",
|
| 312 |
+
"answer": lastAssistantMessage,
|
| 313 |
+
})
|
| 314 |
+
}
|
| 315 |
+
|
| 316 |
+
chatHistoryJSON, _ := json.Marshal(chatHistory)
|
| 317 |
|
| 318 |
// 创建 You.com API 请求
|
| 319 |
youReq, _ := http.NewRequest("GET", "https://you.com/api/streamingSearch", nil)
|
|
|
|
| 323 |
conversationTurnId := uuid.New().String()
|
| 324 |
traceId := fmt.Sprintf("%s|%s|%s", chatId, conversationTurnId, time.Now().Format(time.RFC3339))
|
| 325 |
|
| 326 |
+
// 处理最后一条消息
|
| 327 |
+
lastMessage := openAIReq.Messages[len(openAIReq.Messages)-1]
|
| 328 |
+
lastMessageTokens, err := countTokens([]Message{lastMessage})
|
| 329 |
+
if err != nil {
|
| 330 |
+
http.Error(w, "Failed to count tokens", http.StatusInternalServerError)
|
| 331 |
+
return
|
| 332 |
+
}
|
| 333 |
+
|
| 334 |
+
// 构建查询参数
|
| 335 |
+
q := youReq.URL.Query()
|
| 336 |
+
|
| 337 |
+
// 设置基本参数
|
| 338 |
+
q.Add("page", "1")
|
| 339 |
+
q.Add("count", "10")
|
| 340 |
+
q.Add("safeSearch", "Off")
|
| 341 |
+
q.Add("mkt", "en-US")
|
| 342 |
+
q.Add("enable_worklow_generation_ux", "true")
|
| 343 |
+
q.Add("domain", "youchat")
|
| 344 |
+
q.Add("use_personalization_extraction", "true")
|
| 345 |
+
q.Add("queryTraceId", chatId)
|
| 346 |
+
q.Add("chatId", chatId)
|
| 347 |
+
q.Add("conversationTurnId", conversationTurnId)
|
| 348 |
+
q.Add("pastChatLength", fmt.Sprintf("%d", len(chatHistory)))
|
| 349 |
+
q.Add("selectedChatMode", "custom")
|
| 350 |
+
q.Add("selectedAiModel", mapModelName(openAIReq.Model))
|
| 351 |
+
q.Add("enable_agent_clarification_questions", "true")
|
| 352 |
+
q.Add("traceId", traceId)
|
| 353 |
+
q.Add("use_nested_youchat_updates", "true")
|
| 354 |
+
|
| 355 |
// 如果最后一条消息超过限制,使用文件上传
|
| 356 |
if lastMessageTokens > MaxContextTokens {
|
| 357 |
+
// 获取 nonce
|
| 358 |
nonceResp, err := getNonce(dsToken)
|
| 359 |
if err != nil {
|
| 360 |
fmt.Printf("获取 nonce 失败: %v\n", err)
|
| 361 |
http.Error(w, "Failed to get nonce", http.StatusInternalServerError)
|
| 362 |
return
|
| 363 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 364 |
|
| 365 |
+
// 创建临时文件
|
| 366 |
tempFile := fmt.Sprintf("temp_%s.txt", nonceResp.Uuid)
|
| 367 |
+
if err := os.WriteFile(tempFile, []byte(lastMessage.Content), 0644); err != nil {
|
| 368 |
fmt.Printf("创建临时文件失败: %v\n", err)
|
| 369 |
http.Error(w, "Failed to create temp file", http.StatusInternalServerError)
|
| 370 |
return
|
|
|
|
| 380 |
}
|
| 381 |
|
| 382 |
// 添加文件源信息
|
| 383 |
+
sources = append(sources, map[string]interface{}{
|
| 384 |
+
"source_type": "user_file",
|
| 385 |
+
"filename": uploadResp.Filename,
|
| 386 |
+
"user_filename": uploadResp.UserFilename,
|
| 387 |
+
"size_bytes": len(lastMessage.Content),
|
| 388 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 389 |
|
| 390 |
+
// 添加 sources 参数
|
| 391 |
+
sourcesJSON, _ := json.Marshal(sources)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 392 |
q.Add("sources", string(sourcesJSON))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 393 |
|
| 394 |
+
// 使用文件引用作为查询
|
| 395 |
+
q.Add("q", fmt.Sprintf("Please review the attached file: %s", uploadResp.UserFilename))
|
| 396 |
+
} else {
|
| 397 |
+
// 如果有之前上传的文件,添加 sources
|
| 398 |
+
if len(sources) > 0 {
|
| 399 |
+
sourcesJSON, _ := json.Marshal(sources)
|
| 400 |
+
q.Add("sources", string(sourcesJSON))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
}
|
| 402 |
+
q.Add("q", lastMessage.Content)
|
| 403 |
+
}
|
| 404 |
|
| 405 |
+
q.Add("chat", string(chatHistoryJSON))
|
| 406 |
+
youReq.URL.RawQuery = q.Encode()
|
| 407 |
|
| 408 |
+
fmt.Printf("\n=== 完整请求信息 ===\n")
|
| 409 |
+
fmt.Printf("请求 URL: %s\n", youReq.URL.String())
|
| 410 |
+
fmt.Printf("请求头:\n")
|
| 411 |
+
for key, values := range youReq.Header {
|
| 412 |
+
fmt.Printf("%s: %v\n", key, values)
|
| 413 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 414 |
|
| 415 |
+
// 设置请求头
|
| 416 |
+
youReq.Header = http.Header{
|
| 417 |
+
"sec-ch-ua-platform": {"Windows"},
|
| 418 |
+
"Cache-Control": {"no-cache"},
|
| 419 |
+
"sec-ch-ua": {`"Not(A:Brand";v="99", "Microsoft Edge";v="133", "Chromium";v="133"`},
|
| 420 |
+
"sec-ch-ua-bitness": {"64"},
|
| 421 |
+
"sec-ch-ua-model": {""},
|
| 422 |
+
"sec-ch-ua-mobile": {"?0"},
|
| 423 |
+
"sec-ch-ua-arch": {"x86"},
|
| 424 |
+
"sec-ch-ua-full-version": {"133.0.3065.39"},
|
| 425 |
+
"Accept": {"text/event-stream"},
|
| 426 |
+
"User-Agent": {"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36 Edg/133.0.0.0"},
|
| 427 |
+
"sec-ch-ua-platform-version": {"19.0.0"},
|
| 428 |
+
"Sec-Fetch-Site": {"same-origin"},
|
| 429 |
+
"Sec-Fetch-Mode": {"cors"},
|
| 430 |
+
"Sec-Fetch-Dest": {"empty"},
|
| 431 |
+
"Host": {"you.com"},
|
| 432 |
+
}
|
| 433 |
|
| 434 |
+
// 设置 Cookie
|
| 435 |
+
cookies := getCookies(dsToken)
|
| 436 |
+
var cookieStrings []string
|
| 437 |
+
for name, value := range cookies {
|
| 438 |
+
cookieStrings = append(cookieStrings, fmt.Sprintf("%s=%s", name, value))
|
| 439 |
+
}
|
| 440 |
+
youReq.Header.Add("Cookie", strings.Join(cookieStrings, ";"))
|
| 441 |
+
fmt.Printf("Cookie: %s\n", strings.Join(cookieStrings, ";"))
|
| 442 |
+
fmt.Printf("===================\n\n")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 443 |
|
| 444 |
+
// 发送请求并获取响应
|
| 445 |
+
client := &http.Client{}
|
| 446 |
+
resp, err := client.Do(youReq)
|
| 447 |
+
if err != nil {
|
| 448 |
+
fmt.Printf("发送请求失败: %v\n", err)
|
| 449 |
+
http.Error(w, err.Error(), http.StatusInternalServerError)
|
| 450 |
+
return
|
| 451 |
+
}
|
| 452 |
+
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 453 |
|
| 454 |
+
// 打印响应状态码
|
| 455 |
+
fmt.Printf("响应状态码: %d\n", resp.StatusCode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 456 |
|
| 457 |
+
// 如果状态码不是 200,打印响应内容
|
| 458 |
+
if resp.StatusCode != http.StatusOK {
|
| 459 |
+
body, _ := io.ReadAll(resp.Body)
|
| 460 |
+
fmt.Printf("错误响应内容: %s\n", string(body))
|
| 461 |
+
http.Error(w, fmt.Sprintf("API returned status %d", resp.StatusCode), resp.StatusCode)
|
| 462 |
+
return
|
| 463 |
+
}
|
| 464 |
|
| 465 |
+
// 根据 OpenAI 请求的 stream 参数选择处理函数
|
| 466 |
+
if !openAIReq.Stream {
|
| 467 |
+
handleNonStreamingResponse(w, youReq) // 处理非流式响应
|
| 468 |
+
return
|
| 469 |
}
|
| 470 |
+
|
| 471 |
+
handleStreamingResponse(w, youReq) // 处理流式响应
|
| 472 |
}
|
| 473 |
|
| 474 |
// getCookies 根据提供的 DS token 生成所需的 Cookie。
|
|
|
|
| 680 |
}
|
| 681 |
|
| 682 |
// 计算 tokens:英文字符 * 0.3 + 中文字符 * 0.6
|
| 683 |
+
tokens := int(float64(englishCount)*0.3 + float64(chineseCount)*1)
|
| 684 |
|
| 685 |
// 加上角色名的 token(约 2 个)
|
| 686 |
totalTokens += tokens + 2
|