fix: restore Claude file conversion and preserve stream status

This commit is contained in:
Lich-Mac-Mini
2026-04-17 20:28:32 +08:00
parent 06f9bde3c9
commit 198e723b97
2 changed files with 68 additions and 21 deletions
+46 -1
View File
@@ -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
@@ -377,7 +394,16 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
})
}
default:
source := mediaMessage.ToFileSource()
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
}
@@ -385,6 +411,25 @@ func RequestOpenAI2ClaudeMessage(c *gin.Context, textRequest dto.GeneralOpenAIRe
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",
+3 -1
View File
@@ -40,8 +40,10 @@ func StreamScannerHandler(c *gin.Context, resp *http.Response, info *relaycommon
return
}
// 无条件新建 StreamStatus
// 保留调用方预先注入的 StreamStatus,避免覆盖已有错误/状态。
if info.StreamStatus == nil {
info.StreamStatus = relaycommon.NewStreamStatus()
}
// 确保响应体总是被关闭
defer func() {