fix: restore Claude file conversion and preserve stream status
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package claude
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/QuantumNous/new-api/common"
|
||||
"github.com/QuantumNous/new-api/constant"
|
||||
@@ -35,6 +37,21 @@ func stopReasonClaude2OpenAI(reason string) string {
|
||||
return reasonmap.ClaudeStopReasonToOpenAIFinishReason(reason)
|
||||
}
|
||||
|
||||
func inferClaudeFileMimeType(file *dto.MessageFile) string {
|
||||
if file == nil || file.FileName == "" {
|
||||
return ""
|
||||
}
|
||||
dot := strings.LastIndex(file.FileName, ".")
|
||||
if dot == -1 || dot+1 >= len(file.FileName) {
|
||||
return ""
|
||||
}
|
||||
mimeType := service.GetMimeTypeByExtension(file.FileName[dot+1:])
|
||||
if mimeType == "application/octet-stream" {
|
||||
return ""
|
||||
}
|
||||
return mimeType
|
||||
}
|
||||
|
||||
func maybeMarkClaudeRefusal(c *gin.Context, stopReason string) {
|
||||
if c == nil {
|
||||
return
|
||||
@@ -365,31 +382,59 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
|
||||
text = "..."
|
||||
}
|
||||
claudeMessage.Content = text
|
||||
} else {
|
||||
claudeMediaMessages := make([]dto.ClaudeMediaMessage, 0)
|
||||
for _, mediaMessage := range message.ParseContent() {
|
||||
switch mediaMessage.Type {
|
||||
case "text":
|
||||
} else {
|
||||
claudeMediaMessages := make([]dto.ClaudeMediaMessage, 0)
|
||||
for _, mediaMessage := range message.ParseContent() {
|
||||
switch mediaMessage.Type {
|
||||
case "text":
|
||||
if mediaMessage.Text != "" {
|
||||
claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{
|
||||
Type: "text",
|
||||
Text: common.GetPointer[string](mediaMessage.Text),
|
||||
})
|
||||
}
|
||||
default:
|
||||
source := mediaMessage.ToFileSource()
|
||||
if source == nil {
|
||||
continue
|
||||
}
|
||||
base64Data, mimeType, err := service.GetBase64Data(c, source, "formatting image for Claude")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get file data failed: %s", err.Error())
|
||||
}
|
||||
claudeMediaMessage := dto.ClaudeMediaMessage{
|
||||
Source: &dto.ClaudeMessageSource{
|
||||
Type: "base64",
|
||||
},
|
||||
}
|
||||
default:
|
||||
var source types.FileSource
|
||||
if mediaMessage.Type == dto.ContentTypeFile {
|
||||
file := mediaMessage.GetFile()
|
||||
if file == nil || file.FileData == "" {
|
||||
continue
|
||||
}
|
||||
source = types.NewFileSourceFromData(file.FileData, inferClaudeFileMimeType(file))
|
||||
} else {
|
||||
source = mediaMessage.ToFileSource()
|
||||
}
|
||||
if source == nil {
|
||||
continue
|
||||
}
|
||||
base64Data, mimeType, err := service.GetBase64Data(c, source, "formatting image for Claude")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get file data failed: %s", err.Error())
|
||||
}
|
||||
if mimeType == "text/plain" {
|
||||
decoded, err := base64.StdEncoding.DecodeString(base64Data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decode text file data failed: %s", err.Error())
|
||||
}
|
||||
if utf8.Valid(decoded) {
|
||||
text := string(decoded)
|
||||
if text != "" {
|
||||
claudeMediaMessages = append(claudeMediaMessages, dto.ClaudeMediaMessage{
|
||||
Type: "text",
|
||||
Text: common.GetPointer[string](text),
|
||||
})
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
if mimeType == "" || mimeType == "application/octet-stream" {
|
||||
continue
|
||||
}
|
||||
claudeMediaMessage := dto.ClaudeMediaMessage{
|
||||
Source: &dto.ClaudeMessageSource{
|
||||
Type: "base64",
|
||||
},
|
||||
}
|
||||
if strings.HasPrefix(mimeType, "application/pdf") {
|
||||
claudeMediaMessage.Type = "document"
|
||||
} else {
|
||||
|
||||
@@ -40,8 +40,10 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
|
||||
return
|
||||
}
|
||||
|
||||
// 无条件新建 StreamStatus
|
||||
info.StreamStatus = relaycommon.NewStreamStatus()
|
||||
// 保留调用方预先注入的 StreamStatus,避免覆盖已有错误/状态。
|
||||
if info.StreamStatus == nil {
|
||||
info.StreamStatus = relaycommon.NewStreamStatus()
|
||||
}
|
||||
|
||||
// 确保响应体总是被关闭
|
||||
defer func() {
|
||||
|
||||
Reference in New Issue
Block a user