usage_conversion_test.go 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package model_test
  2. import (
  3. "testing"
  4. "github.com/labring/aiproxy/core/relay/model"
  5. "github.com/stretchr/testify/assert"
  6. )
  7. func TestChatUsageConversions(t *testing.T) {
  8. chatUsage := model.ChatUsage{
  9. PromptTokens: 100,
  10. CompletionTokens: 50,
  11. TotalTokens: 150,
  12. PromptTokensDetails: &model.PromptTokensDetails{
  13. CachedTokens: 20,
  14. CacheCreationTokens: 10,
  15. },
  16. CompletionTokensDetails: &model.CompletionTokensDetails{
  17. ReasoningTokens: 30,
  18. },
  19. }
  20. t.Run("ChatUsage to ResponseUsage", func(t *testing.T) {
  21. responseUsage := chatUsage.ToResponseUsage()
  22. assert.Equal(t, int64(100), responseUsage.InputTokens)
  23. assert.Equal(t, int64(50), responseUsage.OutputTokens)
  24. assert.Equal(t, int64(150), responseUsage.TotalTokens)
  25. assert.NotNil(t, responseUsage.InputTokensDetails)
  26. assert.Equal(t, int64(20), responseUsage.InputTokensDetails.CachedTokens)
  27. assert.NotNil(t, responseUsage.OutputTokensDetails)
  28. assert.Equal(t, int64(30), responseUsage.OutputTokensDetails.ReasoningTokens)
  29. })
  30. t.Run("ChatUsage to ClaudeUsage", func(t *testing.T) {
  31. claudeUsage := chatUsage.ToClaudeUsage()
  32. assert.Equal(t, int64(100), claudeUsage.InputTokens)
  33. assert.Equal(t, int64(50), claudeUsage.OutputTokens)
  34. assert.Equal(t, int64(10), claudeUsage.CacheCreationInputTokens)
  35. assert.Equal(t, int64(20), claudeUsage.CacheReadInputTokens)
  36. })
  37. t.Run("ChatUsage to GeminiUsage", func(t *testing.T) {
  38. geminiUsage := chatUsage.ToGeminiUsage()
  39. assert.Equal(t, int64(100), geminiUsage.PromptTokenCount)
  40. assert.Equal(t, int64(50), geminiUsage.CandidatesTokenCount)
  41. assert.Equal(t, int64(150), geminiUsage.TotalTokenCount)
  42. assert.Equal(t, int64(20), geminiUsage.CachedContentTokenCount)
  43. assert.Equal(t, int64(30), geminiUsage.ThoughtsTokenCount)
  44. })
  45. }
  46. func TestResponseUsageConversions(t *testing.T) {
  47. responseUsage := model.ResponseUsage{
  48. InputTokens: 100,
  49. OutputTokens: 50,
  50. TotalTokens: 150,
  51. InputTokensDetails: &model.ResponseUsageDetails{
  52. CachedTokens: 20,
  53. },
  54. OutputTokensDetails: &model.ResponseUsageDetails{
  55. ReasoningTokens: 30,
  56. },
  57. }
  58. t.Run("ResponseUsage to ChatUsage", func(t *testing.T) {
  59. chatUsage := responseUsage.ToChatUsage()
  60. assert.Equal(t, int64(100), chatUsage.PromptTokens)
  61. assert.Equal(t, int64(50), chatUsage.CompletionTokens)
  62. assert.Equal(t, int64(150), chatUsage.TotalTokens)
  63. assert.NotNil(t, chatUsage.PromptTokensDetails)
  64. assert.Equal(t, int64(20), chatUsage.PromptTokensDetails.CachedTokens)
  65. assert.NotNil(t, chatUsage.CompletionTokensDetails)
  66. assert.Equal(t, int64(30), chatUsage.CompletionTokensDetails.ReasoningTokens)
  67. })
  68. t.Run("ResponseUsage to ClaudeUsage", func(t *testing.T) {
  69. claudeUsage := responseUsage.ToClaudeUsage()
  70. assert.Equal(t, int64(100), claudeUsage.InputTokens)
  71. assert.Equal(t, int64(50), claudeUsage.OutputTokens)
  72. assert.Equal(t, int64(20), claudeUsage.CacheReadInputTokens)
  73. })
  74. t.Run("ResponseUsage to GeminiUsage", func(t *testing.T) {
  75. geminiUsage := responseUsage.ToGeminiUsage()
  76. assert.Equal(t, int64(100), geminiUsage.PromptTokenCount)
  77. assert.Equal(t, int64(50), geminiUsage.CandidatesTokenCount)
  78. assert.Equal(t, int64(150), geminiUsage.TotalTokenCount)
  79. assert.Equal(t, int64(20), geminiUsage.CachedContentTokenCount)
  80. assert.Equal(t, int64(30), geminiUsage.ThoughtsTokenCount)
  81. })
  82. }
  83. func TestClaudeUsageConversions(t *testing.T) {
  84. claudeUsage := model.ClaudeUsage{
  85. InputTokens: 100,
  86. OutputTokens: 50,
  87. CacheCreationInputTokens: 10,
  88. CacheReadInputTokens: 20,
  89. }
  90. t.Run("ClaudeUsage to ChatUsage", func(t *testing.T) {
  91. chatUsage := claudeUsage.ToOpenAIUsage()
  92. assert.Equal(t, int64(130), chatUsage.PromptTokens) // 100 + 10 + 20
  93. assert.Equal(t, int64(50), chatUsage.CompletionTokens)
  94. assert.Equal(t, int64(180), chatUsage.TotalTokens)
  95. assert.NotNil(t, chatUsage.PromptTokensDetails)
  96. assert.Equal(t, int64(20), chatUsage.PromptTokensDetails.CachedTokens)
  97. assert.Equal(t, int64(10), chatUsage.PromptTokensDetails.CacheCreationTokens)
  98. })
  99. t.Run("ClaudeUsage to ResponseUsage", func(t *testing.T) {
  100. responseUsage := claudeUsage.ToResponseUsage()
  101. assert.Equal(t, int64(130), responseUsage.InputTokens) // 100 + 10 + 20
  102. assert.Equal(t, int64(50), responseUsage.OutputTokens)
  103. assert.Equal(t, int64(180), responseUsage.TotalTokens)
  104. assert.NotNil(t, responseUsage.InputTokensDetails)
  105. assert.Equal(t, int64(20), responseUsage.InputTokensDetails.CachedTokens)
  106. })
  107. t.Run("ClaudeUsage to GeminiUsage", func(t *testing.T) {
  108. geminiUsage := claudeUsage.ToGeminiUsage()
  109. assert.Equal(t, int64(130), geminiUsage.PromptTokenCount) // 100 + 10 + 20
  110. assert.Equal(t, int64(50), geminiUsage.CandidatesTokenCount)
  111. assert.Equal(t, int64(180), geminiUsage.TotalTokenCount)
  112. assert.Equal(t, int64(20), geminiUsage.CachedContentTokenCount)
  113. })
  114. }
  115. func TestGeminiUsageConversions(t *testing.T) {
  116. geminiUsage := model.GeminiUsageMetadata{
  117. PromptTokenCount: 100,
  118. CandidatesTokenCount: 50,
  119. TotalTokenCount: 150,
  120. ThoughtsTokenCount: 30,
  121. CachedContentTokenCount: 20,
  122. }
  123. t.Run("GeminiUsage to ChatUsage", func(t *testing.T) {
  124. chatUsage := geminiUsage.ToUsage()
  125. assert.Equal(t, int64(100), chatUsage.PromptTokens)
  126. assert.Equal(t, int64(80), chatUsage.CompletionTokens) // 50 + 30
  127. assert.Equal(t, int64(150), chatUsage.TotalTokens)
  128. assert.NotNil(t, chatUsage.PromptTokensDetails)
  129. assert.Equal(t, int64(20), chatUsage.PromptTokensDetails.CachedTokens)
  130. assert.NotNil(t, chatUsage.CompletionTokensDetails)
  131. assert.Equal(t, int64(30), chatUsage.CompletionTokensDetails.ReasoningTokens)
  132. })
  133. t.Run("GeminiUsage to ResponseUsage", func(t *testing.T) {
  134. responseUsage := geminiUsage.ToResponseUsage()
  135. assert.Equal(t, int64(100), responseUsage.InputTokens)
  136. assert.Equal(t, int64(50), responseUsage.OutputTokens)
  137. assert.Equal(t, int64(150), responseUsage.TotalTokens)
  138. assert.NotNil(t, responseUsage.InputTokensDetails)
  139. assert.Equal(t, int64(20), responseUsage.InputTokensDetails.CachedTokens)
  140. assert.NotNil(t, responseUsage.OutputTokensDetails)
  141. assert.Equal(t, int64(30), responseUsage.OutputTokensDetails.ReasoningTokens)
  142. })
  143. t.Run("GeminiUsage to ClaudeUsage", func(t *testing.T) {
  144. claudeUsage := geminiUsage.ToClaudeUsage()
  145. assert.Equal(t, int64(100), claudeUsage.InputTokens)
  146. assert.Equal(t, int64(50), claudeUsage.OutputTokens)
  147. assert.Equal(t, int64(20), claudeUsage.CacheReadInputTokens)
  148. })
  149. }
  150. func TestRoundTripConversions(t *testing.T) {
  151. t.Run("ChatUsage -> ResponseUsage -> ChatUsage", func(t *testing.T) {
  152. original := model.ChatUsage{
  153. PromptTokens: 100,
  154. CompletionTokens: 50,
  155. TotalTokens: 150,
  156. PromptTokensDetails: &model.PromptTokensDetails{
  157. CachedTokens: 20,
  158. },
  159. CompletionTokensDetails: &model.CompletionTokensDetails{
  160. ReasoningTokens: 30,
  161. },
  162. }
  163. responseUsage := original.ToResponseUsage()
  164. converted := responseUsage.ToChatUsage()
  165. assert.Equal(t, original.PromptTokens, converted.PromptTokens)
  166. assert.Equal(t, original.CompletionTokens, converted.CompletionTokens)
  167. assert.Equal(t, original.TotalTokens, converted.TotalTokens)
  168. assert.Equal(
  169. t,
  170. original.PromptTokensDetails.CachedTokens,
  171. converted.PromptTokensDetails.CachedTokens,
  172. )
  173. assert.Equal(
  174. t,
  175. original.CompletionTokensDetails.ReasoningTokens,
  176. converted.CompletionTokensDetails.ReasoningTokens,
  177. )
  178. })
  179. t.Run("ResponseUsage -> GeminiUsage -> ResponseUsage", func(t *testing.T) {
  180. original := model.ResponseUsage{
  181. InputTokens: 100,
  182. OutputTokens: 50,
  183. TotalTokens: 150,
  184. InputTokensDetails: &model.ResponseUsageDetails{
  185. CachedTokens: 20,
  186. },
  187. OutputTokensDetails: &model.ResponseUsageDetails{
  188. ReasoningTokens: 30,
  189. },
  190. }
  191. geminiUsage := original.ToGeminiUsage()
  192. converted := geminiUsage.ToResponseUsage()
  193. assert.Equal(t, original.InputTokens, converted.InputTokens)
  194. assert.Equal(t, original.OutputTokens, converted.OutputTokens)
  195. assert.Equal(t, original.TotalTokens, converted.TotalTokens)
  196. assert.Equal(
  197. t,
  198. original.InputTokensDetails.CachedTokens,
  199. converted.InputTokensDetails.CachedTokens,
  200. )
  201. assert.Equal(
  202. t,
  203. original.OutputTokensDetails.ReasoningTokens,
  204. converted.OutputTokensDetails.ReasoningTokens,
  205. )
  206. })
  207. }