feat: publish sanitized custom.97 source

This commit is contained in:
cneicy committed 2026-10-27 20:43:39 +08:00
1 parent 8e6ed0317b
commit 86c0276156
1022 files changed
+69903 -19207

No files matched your search

+45 -11
View File
@@ -62,7 +62,7 @@ func handleClaudeFormat(c *gin.Context, data string, info *relaycommon.RelayInfo
func handleGeminiFormat(c *gin.Context, data string, info *relaycommon.RelayInfo) error {
var streamResponse dto.ChatCompletionsStreamResponse
if err := common.Unmarshal(common.StringToByteSlice(data), &streamResponse); err != nil {
logger.LogError(c, "failed to unmarshal stream response: "+err.Error())
logger.LogError(c, common.LogText("failed to unmarshal stream response: %s", err.Error()))
return err
}
@@ -111,7 +111,7 @@ func sendGeminiStreamResults(c *gin.Context, results []relayconvert.ResponseResu
}
data, err := common.Marshal(geminiResponse)
if err != nil {
logger.LogError(c, "failed to marshal gemini response: "+err.Error())
logger.LogError(c, common.LogText("failed to marshal gemini response: %s", err.Error()))
return err
}
c.Render(-1, common.CustomEvent{Data: "data: " + string(data)})
@@ -206,7 +206,7 @@ func HandleFinalResponse(c *gin.Context, info *relaycommon.RelayInfo, lastStream
case types.RelayFormatClaude:
var streamResponse dto.ChatCompletionsStreamResponse
if err := common.Unmarshal(common.StringToByteSlice(lastStreamData), &streamResponse); err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
common.SysLog(common.LogText("error unmarshalling stream response: %s", err.Error()))
return
}
@@ -214,12 +214,12 @@ func HandleFinalResponse(c *gin.Context, info *relaycommon.RelayInfo, lastStream
result, err := service.ConvertStreamResponse(c, info, types.RelayFormatClaude, &streamResponse)
if err != nil {
common.SysLog("error converting Claude stream response: " + err.Error())
common.SysLog(common.LogText("error converting Claude stream response: %s", err.Error()))
return
}
claudeResponses, ok := result.Value.([]*dto.ClaudeResponse)
if !ok {
common.SysLog(fmt.Sprintf("expected Claude stream responses, got %T", result.Value))
common.SysLog(common.LogText("expected Claude stream responses, got %T", result.Value))
return
}
for _, resp := range claudeResponses {
@@ -230,34 +230,34 @@ func HandleFinalResponse(c *gin.Context, info *relaycommon.RelayInfo, lastStream
case types.RelayFormatGemini:
var streamResponse dto.ChatCompletionsStreamResponse
if err := common.Unmarshal(common.StringToByteSlice(lastStreamData), &streamResponse); err != nil {
common.SysLog("error unmarshalling stream response: " + err.Error())
common.SysLog(common.LogText("error unmarshalling stream response: %s", err.Error()))
return
}
state, err := chatToGeminiStreamState(info, &streamResponse)
if err != nil {
common.SysLog("error creating Gemini stream state: " + err.Error())
common.SysLog(common.LogText("error creating Gemini stream state: %s", err.Error()))
return
}
state.SetUsage(usage)
results, err := service.ConvertStreamResponseChunk(c, info, state, &streamResponse)
if err != nil {
common.SysLog("error converting final Gemini stream response: " + err.Error())
common.SysLog(common.LogText("error converting final Gemini stream response: %s", err.Error()))
return
}
if err := sendGeminiStreamResults(c, results); err != nil {
common.SysLog("error sending final Gemini stream response: " + err.Error())
common.SysLog(common.LogText("error sending final Gemini stream response: %s", err.Error()))
return
}
results, err = service.FinalizeStreamResponse(c, info, state)
if err != nil {
common.SysLog("error finalizing Gemini stream response: " + err.Error())
common.SysLog(common.LogText("error finalizing Gemini stream response: %s", err.Error()))
return
}
if err := sendGeminiStreamResults(c, results); err != nil {
common.SysLog("error sending finalized Gemini stream response: " + err.Error())
common.SysLog(common.LogText("error sending finalized Gemini stream response: %s", err.Error()))
}
}
}
@@ -266,5 +266,39 @@ func sendResponsesStreamData(c *gin.Context, streamResponse dto.ResponsesStreamR
if data == "" {
return
}
if streamResponse.Type == "error" || streamResponse.Type == "response.error" || streamResponse.Type == "response.failed" {
// Stream events bypass the controller's HTTP error projection. Keep
// diagnostics server-side and emit only protocol fields to the client.
var original map[string]any
if common.UnmarshalJsonStr(data, &original) != nil {
return
}
diagnostic := map[string]any{"type": streamResponse.Type, "code": original["code"], "message": original["message"], "error": original["error"]}
if response, ok := original["response"].(map[string]any); ok {
diagnostic["response_error"] = response["error"]
}
detail, _ := common.Marshal(diagnostic)
logger.LogError(c, "upstream Responses stream failure: "+string(detail))
message := common.MessageWithRequestId("The model service is temporarily unavailable. Please try again later.", c.GetString(common.RequestIdKey))
publicError := map[string]any{"type": "api_error", "code": "model_service_error", "message": message}
safe := map[string]any{"type": streamResponse.Type, "code": "model_service_error", "message": message, "error": publicError}
if sequence, ok := original["sequence_number"]; ok {
safe["sequence_number"] = sequence
}
if response, ok := original["response"].(map[string]any); ok {
publicResponse := map[string]any{"status": "failed", "error": publicError}
for _, field := range []string{"id", "object", "created_at", "model", "usage"} {
if value, exists := response[field]; exists {
publicResponse[field] = value
}
}
safe["response"] = publicResponse
}
encoded, err := common.Marshal(safe)
if err != nil {
return
}
data = string(encoded)
}
_ = helper.ResponseChunkData(c, streamResponse, data)
}