Просмотр исходного кода

fix: clamp reasoning tokens in session usage

Jack 3 месяцев назад
Родитель
Сommit
cfa7ca14ac

+ 6 - 3
packages/opencode/src/session/session.ts

@@ -356,8 +356,11 @@ export const getUsage = (input: { model: Provider.Model; usage: LanguageModelUsa
     return value
   }
   const inputTokens = safe(input.usage.inputTokens ?? 0)
-  const outputTokens = safe(input.usage.outputTokens ?? 0)
-  const reasoningTokens = safe(input.usage.outputTokenDetails?.reasoningTokens ?? input.usage.reasoningTokens ?? 0)
+  const outputTokens = Math.max(0, safe(input.usage.outputTokens ?? 0))
+  const reasoningTokens = Math.min(
+    Math.max(0, safe(input.usage.outputTokenDetails?.reasoningTokens ?? input.usage.reasoningTokens ?? 0)),
+    outputTokens,
+  )
 
   const cacheReadInputTokens = safe(
     input.usage.inputTokenDetails?.cacheReadTokens ?? input.usage.cachedInputTokens ?? 0,
@@ -387,7 +390,7 @@ export const getUsage = (input: { model: Provider.Model; usage: LanguageModelUsa
   const tokens = {
     total,
     input: adjustedInputTokens,
-    output: safe(outputTokens - reasoningTokens),
+    output: outputTokens - reasoningTokens,
     reasoning: reasoningTokens,
     cache: {
       write: cacheWriteInputTokens,

+ 24 - 0
packages/opencode/test/session/compaction.test.ts

@@ -2011,6 +2011,30 @@ describe("SessionNs.getUsage", () => {
     expect(result.tokens.total).toBe(1500)
   })
 
+  test("clamps reasoning tokens to completion tokens", () => {
+    const model = createModel({ context: 100_000, output: 32_000 })
+    const result = SessionNs.getUsage({
+      model,
+      usage: {
+        inputTokens: 1000,
+        outputTokens: 45,
+        totalTokens: 1045,
+        inputTokenDetails: {
+          noCacheTokens: undefined,
+          cacheReadTokens: undefined,
+          cacheWriteTokens: undefined,
+        },
+        outputTokenDetails: {
+          textTokens: undefined,
+          reasoningTokens: 47,
+        },
+      },
+    })
+
+    expect(result.tokens.output).toBe(0)
+    expect(result.tokens.reasoning).toBe(45)
+  })
+
   test("does not double count reasoning tokens in cost", () => {
     const model = createModel({
       context: 100_000,