fix(openai): preserve usage path precedence

This commit is contained in:
SamizuHM
2026-08-11 22:01:47 +08:00
parent 04dc540b23
commit a163742fc9
2 changed files with 23 additions and 2 deletions
@@ -981,15 +981,15 @@ func extractOpenAIUsageFromJSONBytes(body []byte) (OpenAIUsage, bool) {
}
// 部分 OpenAI 兼容上游(例如 Cline API)会将标准响应包在 data 字段中:
// {"data":{"choices": [...], "usage": {...}}, "success":true}。
// 按优先级尝试原生 OpenAI Responses、兼容层 data 包装和 Responses 包装,
// 按优先级先保留原有路径,再尝试兼容层 data 包装,
// 避免同步请求能正常返回但用量被静默记录为 0。
candidates := []struct {
usagePath string
imageUsagePath string
}{
{usagePath: "usage", imageUsagePath: "tool_usage.image_gen"},
{usagePath: "data.usage", imageUsagePath: "data.tool_usage.image_gen"},
{usagePath: "response.usage", imageUsagePath: "response.tool_usage.image_gen"},
{usagePath: "data.usage", imageUsagePath: "data.tool_usage.image_gen"},
{usagePath: "data.response.usage", imageUsagePath: "data.response.tool_usage.image_gen"},
}
for _, candidate := range candidates {
@@ -483,6 +483,27 @@ func TestExtractOpenAIUsage_ReadsClineDataEnvelope(t *testing.T) {
require.Equal(t, 4, usage.CacheReadInputTokens)
}
func TestExtractOpenAIUsage_ReadsWrappedResponsesDataEnvelope(t *testing.T) {
body := []byte(`{"data":{"response":{"usage":{"input_tokens":11,"output_tokens":5,"total_tokens":16,"input_tokens_details":{"cached_tokens":2}}}}}`)
usage, ok := extractOpenAIUsageFromJSONBytes(body)
require.True(t, ok)
require.Equal(t, 11, usage.InputTokens)
require.Equal(t, 5, usage.OutputTokens)
require.Equal(t, 2, usage.CacheReadInputTokens)
}
func TestExtractOpenAIUsage_PreservesResponseUsagePriority(t *testing.T) {
body := []byte(`{"data":{"usage":{"prompt_tokens":100,"completion_tokens":50}},"response":{"usage":{"input_tokens":11,"output_tokens":5}}}`)
usage, ok := extractOpenAIUsageFromJSONBytes(body)
require.True(t, ok)
require.Equal(t, 11, usage.InputTokens)
require.Equal(t, 5, usage.OutputTokens)
}
func TestOpenAIGatewayService_BindHTTPResponseAccount(t *testing.T) {
gin.SetMode(gin.TestMode)
rec := httptest.NewRecorder()