fix: AWS Nova empty content panic + DTO Rule 6 pointer types

- relay/channel/aws/relay-aws.go: add bounds check before accessing
  Content[0] — empty response array caused index-out-of-range panic
- dto/embedding.go: convert Seed, TopK, NumPredict, NumCtx from int
  to *int so explicit zero values survive omitempty marshaling (Rule 6)
- dto/video.go: convert Fps, Seed, N from int to *int (Rule 6)
- dto/suno.go: convert ContinueAt from float64 to *float64 (Rule 6)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-17 23:17:17 +08:00
co-authored by Claude Opus 4.6
parent e31fe390f3
commit 16410270a1
4 changed files with 15 additions and 9 deletions
+4 -4
View File
@@ -9,14 +9,14 @@ import (
) )
type EmbeddingOptions struct { type EmbeddingOptions struct {
Seed int `json:"seed,omitempty"` Seed *int `json:"seed,omitempty"`
Temperature *float64 `json:"temperature,omitempty"` Temperature *float64 `json:"temperature,omitempty"`
TopK int `json:"top_k,omitempty"` TopK *int `json:"top_k,omitempty"`
TopP *float64 `json:"top_p,omitempty"` TopP *float64 `json:"top_p,omitempty"`
FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"` FrequencyPenalty *float64 `json:"frequency_penalty,omitempty"`
PresencePenalty *float64 `json:"presence_penalty,omitempty"` PresencePenalty *float64 `json:"presence_penalty,omitempty"`
NumPredict int `json:"num_predict,omitempty"` NumPredict *int `json:"num_predict,omitempty"`
NumCtx int `json:"num_ctx,omitempty"` NumCtx *int `json:"num_ctx,omitempty"`
} }
type EmbeddingRequest struct { type EmbeddingRequest struct {
+1 -1
View File
@@ -10,7 +10,7 @@ type SunoSubmitReq struct {
Mv string `json:"mv,omitempty"` Mv string `json:"mv,omitempty"`
Title string `json:"title,omitempty"` Title string `json:"title,omitempty"`
Tags string `json:"tags,omitempty"` Tags string `json:"tags,omitempty"`
ContinueAt float64 `json:"continue_at,omitempty"` ContinueAt *float64 `json:"continue_at,omitempty"`
TaskID string `json:"task_id,omitempty"` TaskID string `json:"task_id,omitempty"`
ContinueClipId string `json:"continue_clip_id,omitempty"` ContinueClipId string `json:"continue_clip_id,omitempty"`
MakeInstrumental bool `json:"make_instrumental"` MakeInstrumental bool `json:"make_instrumental"`
+3 -3
View File
@@ -7,9 +7,9 @@ type VideoRequest struct {
Duration float64 `json:"duration" example:"5.0"` // Video duration (seconds) Duration float64 `json:"duration" example:"5.0"` // Video duration (seconds)
Width int `json:"width" example:"512"` // Video width Width int `json:"width" example:"512"` // Video width
Height int `json:"height" example:"512"` // Video height Height int `json:"height" example:"512"` // Video height
Fps int `json:"fps,omitempty" example:"30"` // Video frame rate Fps *int `json:"fps,omitempty" example:"30"` // Video frame rate
Seed int `json:"seed,omitempty" example:"20231234"` // Random seed Seed *int `json:"seed,omitempty" example:"20231234"` // Random seed
N int `json:"n,omitempty" example:"1"` // Number of videos to generate N *int `json:"n,omitempty" example:"1"` // Number of videos to generate
ResponseFormat string `json:"response_format,omitempty" example:"url"` // Response format ResponseFormat string `json:"response_format,omitempty" example:"url"` // Response format
User string `json:"user,omitempty" example:"user-1234"` // User identifier User string `json:"user,omitempty" example:"user-1234"` // User identifier
Metadata map[string]any `json:"metadata,omitempty"` // Vendor-specific/custom params (e.g. negative_prompt, style, quality_level, etc.) Metadata map[string]any `json:"metadata,omitempty"` // Vendor-specific/custom params (e.g. negative_prompt, style, quality_level, etc.)
+7 -1
View File
@@ -326,6 +326,12 @@ func handleNovaRequest(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor)
} }
// 构造OpenAI格式响应 // 构造OpenAI格式响应
var contentText any
if len(novaResp.Output.Message.Content) > 0 {
contentText = novaResp.Output.Message.Content[0].Text
} else {
contentText = ""
}
response := dto.OpenAITextResponse{ response := dto.OpenAITextResponse{
Id: helper.GetResponseID(c), Id: helper.GetResponseID(c),
Object: "chat.completion", Object: "chat.completion",
@@ -335,7 +341,7 @@ func handleNovaRequest(c *gin.Context, info *relaycommon.RelayInfo, a *Adaptor)
Index: 0, Index: 0,
Message: dto.Message{ Message: dto.Message{
Role: "assistant", Role: "assistant",
Content: novaResp.Output.Message.Content[0].Text, Content: contentText,
}, },
FinishReason: "stop", FinishReason: "stop",
}}, }},