From 969ecca53e1edb552c6f17999b510c247545064e Mon Sep 17 00:00:00 2001 From: feitianbubu Date: Wed, 1 Jul 2026 08:22:49 +0800 Subject: [PATCH 1/2] feat: pass video task usage via header for relay token billing --- relay/relay_task.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/relay/relay_task.go b/relay/relay_task.go index 098e23828b6c..b9571acde59b 100644 --- a/relay/relay_task.go +++ b/relay/relay_task.go @@ -397,6 +397,15 @@ func videoFetchByIDRespBodyBuilder(c *gin.Context) (respBody []byte, taskResp *d taskResp = service.TaskErrorWrapper(err, "convert_to_openai_video_failed", http.StatusInternalServerError) return } + // 计量经 header 透传给下游(中转套娃),保持 body 为纯 OpenAI 标准结构 + if ti, perr := adaptor.ParseTaskResult(originTask.Data); perr == nil && ti != nil && ti.TotalTokens > 0 { + if usageJSON, merr := common.Marshal(map[string]int{ + "completion_tokens": ti.CompletionTokens, + "total_tokens": ti.TotalTokens, + }); merr == nil { + c.Header("X-New-Api-Usage", string(usageJSON)) + } + } respBody = openAIVideoData return } From 9a8459ba0a70ac8b9e891a6276d2f276a3f64ddd Mon Sep 17 00:00:00 2001 From: feitianbubu Date: Wed, 1 Jul 2026 15:08:06 +0800 Subject: [PATCH 2/2] feat: return billed seconds in openai video response --- model/task.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/model/task.go b/model/task.go index 9c0cb6dd7bd5..393792891e31 100644 --- a/model/task.go +++ b/model/task.go @@ -4,6 +4,7 @@ import ( "bytes" "database/sql/driver" "encoding/json" + "strconv" "time" "github.com/QuantumNous/new-api/common" @@ -531,5 +532,11 @@ func (t *Task) ToOpenAIVideo() *dto.OpenAIVideo { openAIVideo.CreatedAt = t.CreatedAt openAIVideo.CompletedAt = t.UpdatedAt openAIVideo.SetMetadata("url", t.GetResultURL()) + // 按秒计费的时长(OtherRatios["seconds"])统一带出,供下游按秒计费 + if bc := t.PrivateData.BillingContext; bc != nil { + if s, ok := bc.OtherRatios["seconds"]; ok && s > 0 { + openAIVideo.Seconds = strconv.Itoa(int(s)) + } + } return openAIVideo }