@@ -31,6 +31,7 @@ import {
3131 showList ,
3232 type StepResult ,
3333} from 'rover-core' ;
34+ import type { UsageReport } from 'rover-schemas' ;
3435import { ACPClient } from './acp-client.js' ;
3536import { GeminiOrQwenACPClient } from './gemini-or-qwen-acp-client.js' ;
3637import { createAgent } from './agents/index.js' ;
@@ -286,8 +287,7 @@ export class ACPRunner {
286287 ) : Promise < {
287288 stopReason : string ;
288289 response : string ;
289- tokens ?: number ;
290- cost ?: number ;
290+ usage ?: UsageReport ;
291291 } > {
292292 if ( ! this . isConnectionInitialized || ! this . connection ) {
293293 throw new Error (
@@ -380,18 +380,43 @@ export class ACPRunner {
380380 const response = this . client . stopCapturing ( sessionId ) ;
381381
382382 // Extract usage stats from the ACP response
383- const tokens = promptResult . usage
384- ? ( promptResult . usage . inputTokens ?? 0 ) +
385- ( promptResult . usage . outputTokens ?? 0 ) +
386- ( promptResult . usage . cachedReadTokens ?? 0 ) +
387- ( promptResult . usage . cachedWriteTokens ?? 0 )
388- : undefined ;
389-
390- // Get per-prompt cost delta from the client's tracked usage_update events
383+ let usage : UsageReport | undefined ;
384+
385+ const promptUsage = promptResult . usage ;
391386 const promptCost = this . client . getLastPromptCost ( sessionId ) ;
392- const cost = promptCost . amount > 0 ? promptCost . amount : undefined ;
393387
394- return { stopReason : promptResult . stopReason , response, tokens, cost } ;
388+ if ( promptUsage || promptCost . amount > 0 ) {
389+ const inputTokens = promptUsage ?. inputTokens
390+ ? Number ( promptUsage . inputTokens )
391+ : undefined ;
392+ const outputTokens = promptUsage ?. outputTokens
393+ ? Number ( promptUsage . outputTokens )
394+ : undefined ;
395+ const cachedRead = promptUsage ?. cachedReadTokens
396+ ? Number ( promptUsage . cachedReadTokens )
397+ : 0 ;
398+ const cachedWrite = promptUsage ?. cachedWriteTokens
399+ ? Number ( promptUsage . cachedWriteTokens )
400+ : 0 ;
401+
402+ const totalTokens =
403+ inputTokens !== undefined || outputTokens !== undefined
404+ ? ( inputTokens ?? 0 ) +
405+ ( outputTokens ?? 0 ) +
406+ cachedRead +
407+ cachedWrite
408+ : undefined ;
409+
410+ usage = {
411+ inputTokens,
412+ outputTokens,
413+ totalTokens,
414+ cost : promptCost . amount > 0 ? promptCost . amount : undefined ,
415+ currency : promptCost . amount > 0 ? promptCost . currency : undefined ,
416+ } ;
417+ }
418+
419+ return { stopReason : promptResult . stopReason , response, usage } ;
395420 } catch ( error ) {
396421 console . log (
397422 colors . red ( '[ACP] Prompt failed:' ) ,
@@ -547,11 +572,14 @@ export class ACPRunner {
547572 // Send the prompt via ACP session
548573 const promptResult = await this . sendPrompt ( sessionId , prompt ) ;
549574
550- // Track usage stats from ACP response
551- const tokens = promptResult . tokens ;
552- const cost = promptResult . cost ;
553- // Use the model set for this step, or the default model
575+ // Build usage report from ACP response
554576 const model = stepModel || this . defaultModel ;
577+ let usage : UsageReport | undefined = promptResult . usage ;
578+ if ( usage ) {
579+ usage = { ...usage , model } ;
580+ } else if ( model ) {
581+ usage = { model } ;
582+ }
555583
556584 if ( VERBOSE ) {
557585 console . log (
@@ -588,18 +616,19 @@ export class ACPRunner {
588616 stepName : step . name ,
589617 agent : this . tool ,
590618 duration,
591- tokens,
592- cost,
593- model,
619+ tokens : usage ?. totalTokens ,
620+ inputTokens : usage ?. inputTokens ,
621+ outputTokens : usage ?. outputTokens ,
622+ cost : usage ?. cost ,
623+ currency : usage ?. currency ,
624+ model : usage ?. model ,
594625 } ) ;
595626
596627 return {
597628 id : step . id ,
598629 success : true ,
599630 duration,
600- tokens,
601- cost,
602- model,
631+ usage,
603632 outputs,
604633 } ;
605634 } catch ( error ) {
0 commit comments