@@ -4,7 +4,8 @@ import type { ToolContext } from "./types"
44import { ensureSessionInitialized } from "../state"
55import { saveSessionState } from "../state/persistence"
66import { loadPrompt } from "../prompts"
7- import { getCurrentParams , getTotalToolTokens , countMessageTextTokens } from "../strategies/utils"
7+ import { getCurrentParams , countAllMessageTokens , countTokens } from "../strategies/utils"
8+ import type { AssistantMessage } from "@opencode-ai/sdk/v2"
89import { findStringInMessages , collectToolIdsInRange , collectMessageIdsInRange } from "./utils"
910import { sendCompressNotification } from "../ui/notification"
1011import { prune as applyPruneTransforms } from "../messages/prune"
@@ -330,26 +331,42 @@ export function createCompressTool(ctx: ToolContext): ReturnType<typeof tool> {
330331 } ,
331332 } )
332333
333- let textTokens = 0
334+ let estimatedCompressedTokens = 0
334335 for ( const msgId of compressedMessageIds ) {
335336 const msg = messages . find ( ( m ) => m . info . id === msgId )
336337 if ( msg ) {
337- const tokens = countMessageTextTokens ( msg )
338- textTokens += tokens
338+ const tokens = countAllMessageTokens ( msg )
339+ estimatedCompressedTokens += tokens
339340 state . prune . messages . set ( msgId , tokens )
340341 }
341342 }
342- const toolTokens = getTotalToolTokens ( state , compressedToolIds )
343343 for ( const id of compressedToolIds ) {
344344 const entry = state . toolParameters . get ( id )
345345 state . prune . tools . set ( id , entry ?. tokenCount ?? 0 )
346346 }
347- const estimatedCompressedTokens = textTokens + toolTokens
347+
348+ // Use API-reported tokens from last assistant message (matches OpenCode UI)
349+ let totalSessionTokens = 0
350+ for ( let i = messages . length - 1 ; i >= 0 ; i -- ) {
351+ if ( messages [ i ] . info . role === "assistant" ) {
352+ const info = messages [ i ] . info as AssistantMessage
353+ if ( info . tokens ?. output > 0 ) {
354+ totalSessionTokens =
355+ ( info . tokens ?. input || 0 ) +
356+ ( info . tokens ?. output || 0 ) +
357+ ( info . tokens ?. reasoning || 0 ) +
358+ ( info . tokens ?. cache ?. read || 0 ) +
359+ ( info . tokens ?. cache ?. write || 0 )
360+ break
361+ }
362+ }
363+ }
348364
349365 clog . info ( C . COMPRESS , `Token Accounting` , {
350- text : textTokens ,
351- tools : toolTokens ,
352- total : estimatedCompressedTokens ,
366+ totalSessionTokens,
367+ estimatedCompressedTokens,
368+ compressedMessages : compressedMessageIds . length ,
369+ compressedTools : compressedToolIds . length ,
353370 pruneState : {
354371 tools : state . prune . tools . size ,
355372 messages : state . prune . messages . size ,
@@ -369,6 +386,21 @@ export function createCompressTool(ctx: ToolContext): ReturnType<typeof tool> {
369386 }
370387
371388 const currentParams = getCurrentParams ( state , messages , logger )
389+ const summaryTokens = countTokens ( args . content . summary )
390+
391+ clog . info ( C . COMPRESS , `Notification Values` , {
392+ totalSessionTokens,
393+ estimatedCompressedTokens,
394+ summaryTokens,
395+ reductionPercent :
396+ totalSessionTokens > 0
397+ ? `-${ Math . round ( ( estimatedCompressedTokens / totalSessionTokens ) * 100 ) } %`
398+ : "N/A" ,
399+ messageCount : messages . length ,
400+ compressedMessageIds : compressedMessageIds . length ,
401+ compressedToolIds : compressedToolIds . length ,
402+ } )
403+
372404 await sendCompressNotification (
373405 client ,
374406 logger ,
@@ -379,6 +411,9 @@ export function createCompressTool(ctx: ToolContext): ReturnType<typeof tool> {
379411 compressedMessageIds ,
380412 topic ,
381413 summary ,
414+ summaryTokens ,
415+ totalSessionTokens ,
416+ estimatedCompressedTokens ,
382417 rawStartResult ,
383418 rawEndResult ,
384419 messages . length ,
@@ -398,7 +433,7 @@ export function createCompressTool(ctx: ToolContext): ReturnType<typeof tool> {
398433 clog . error ( C . STATE , `✗ State Persistence Failed` , { error : err . message } )
399434 } )
400435
401- const result = `Compressed ${ compressedMessageIds . length } messages (${ compressedToolIds . length } tool calls) into summary. The content will be replaced with your summary.`
436+ const result = `Compressed ${ compressedMessageIds . length } messages (${ compressedToolIds . length } tool calls) into summary ( ${ summaryTokens } tokens) . The content will be replaced with your summary.`
402437 clog . info (
403438 C . COMPRESS ,
404439 `${ separator } \n✓ COMPRESS INVOCATION SUCCESS\nID: ${ invocationId } \n\n${ result } \n${ separator } ` ,
0 commit comments