mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-24 16:05:44 +08:00
fix(apicompat): Responses↔Anthropic 转换补齐 cache_creation_input_tokens
Fixes #3935
This commit is contained in:
@@ -102,9 +102,10 @@ func AnthropicToResponsesResponse(resp *AnthropicResponse) *ResponsesResponse {
|
||||
resp.Usage.CacheReadInputTokens +
|
||||
resp.Usage.CacheCreationInputTokens
|
||||
out.Usage = &ResponsesUsage{
|
||||
InputTokens: totalInputTokens,
|
||||
OutputTokens: resp.Usage.OutputTokens,
|
||||
TotalTokens: totalInputTokens + resp.Usage.OutputTokens,
|
||||
InputTokens: totalInputTokens,
|
||||
OutputTokens: resp.Usage.OutputTokens,
|
||||
TotalTokens: totalInputTokens + resp.Usage.OutputTokens,
|
||||
CacheCreationInputTokens: resp.Usage.CacheCreationInputTokens,
|
||||
}
|
||||
if resp.Usage.CacheReadInputTokens > 0 {
|
||||
out.Usage.InputTokensDetails = &ResponsesInputTokensDetails{
|
||||
@@ -497,9 +498,10 @@ func makeResponsesCompletedEvent(
|
||||
// back to match OpenAI Responses semantics where input_tokens is the total.
|
||||
totalInputTokens := state.InputTokens + state.CacheReadInputTokens + state.CacheCreationInputTokens
|
||||
usage := &ResponsesUsage{
|
||||
InputTokens: totalInputTokens,
|
||||
OutputTokens: state.OutputTokens,
|
||||
TotalTokens: totalInputTokens + state.OutputTokens,
|
||||
InputTokens: totalInputTokens,
|
||||
OutputTokens: state.OutputTokens,
|
||||
TotalTokens: totalInputTokens + state.OutputTokens,
|
||||
CacheCreationInputTokens: state.CacheCreationInputTokens,
|
||||
}
|
||||
if state.CacheReadInputTokens > 0 {
|
||||
usage.InputTokensDetails = &ResponsesInputTokensDetails{
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
package apicompat
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestAnthropicUsageFromResponsesUsage_CacheCreation(t *testing.T) {
|
||||
usage := &ResponsesUsage{
|
||||
InputTokens: 20,
|
||||
OutputTokens: 5,
|
||||
CacheCreationInputTokens: 6,
|
||||
InputTokensDetails: &ResponsesInputTokensDetails{
|
||||
CachedTokens: 4,
|
||||
},
|
||||
}
|
||||
|
||||
got := anthropicUsageFromResponsesUsage(usage)
|
||||
|
||||
assert.Equal(t, 10, got.InputTokens, "input = total(20) - cache_read(4) - cache_creation(6)")
|
||||
assert.Equal(t, 5, got.OutputTokens)
|
||||
assert.Equal(t, 4, got.CacheReadInputTokens)
|
||||
assert.Equal(t, 6, got.CacheCreationInputTokens, "cache creation must be preserved")
|
||||
}
|
||||
|
||||
func TestAnthropicUsageFromResponsesUsage_NoCacheCreation(t *testing.T) {
|
||||
usage := &ResponsesUsage{
|
||||
InputTokens: 10,
|
||||
OutputTokens: 5,
|
||||
InputTokensDetails: &ResponsesInputTokensDetails{
|
||||
CachedTokens: 3,
|
||||
},
|
||||
}
|
||||
|
||||
got := anthropicUsageFromResponsesUsage(usage)
|
||||
|
||||
assert.Equal(t, 7, got.InputTokens)
|
||||
assert.Equal(t, 3, got.CacheReadInputTokens)
|
||||
assert.Equal(t, 0, got.CacheCreationInputTokens)
|
||||
}
|
||||
|
||||
func TestAnthropicToResponsesResponse_CacheCreation(t *testing.T) {
|
||||
resp := AnthropicResponse{
|
||||
ID: "msg_test",
|
||||
Type: "message",
|
||||
Role: "assistant",
|
||||
Model: "claude-opus-4-6",
|
||||
Usage: AnthropicUsage{
|
||||
InputTokens: 10,
|
||||
OutputTokens: 5,
|
||||
CacheReadInputTokens: 4,
|
||||
CacheCreationInputTokens: 6,
|
||||
},
|
||||
StopReason: "end_turn",
|
||||
}
|
||||
|
||||
out := AnthropicToResponsesResponse(&resp)
|
||||
|
||||
require.NotNil(t, out.Usage)
|
||||
assert.Equal(t, 20, out.Usage.InputTokens, "total = input(10) + cache_read(4) + cache_creation(6)")
|
||||
assert.Equal(t, 6, out.Usage.CacheCreationInputTokens, "cache creation must round-trip")
|
||||
}
|
||||
@@ -100,15 +100,16 @@ func anthropicUsageFromResponsesUsage(usage *ResponsesUsage) AnthropicUsage {
|
||||
cachedTokens = usage.InputTokensDetails.CachedTokens
|
||||
}
|
||||
|
||||
inputTokens := usage.InputTokens - cachedTokens
|
||||
inputTokens := usage.InputTokens - cachedTokens - usage.CacheCreationInputTokens
|
||||
if inputTokens < 0 {
|
||||
inputTokens = 0
|
||||
}
|
||||
|
||||
return AnthropicUsage{
|
||||
InputTokens: inputTokens,
|
||||
OutputTokens: usage.OutputTokens,
|
||||
CacheReadInputTokens: cachedTokens,
|
||||
InputTokens: inputTokens,
|
||||
OutputTokens: usage.OutputTokens,
|
||||
CacheReadInputTokens: cachedTokens,
|
||||
CacheCreationInputTokens: usage.CacheCreationInputTokens,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user