@@ -22,12 +22,16 @@ import {
2222 logConversationResponse ,
2323 logTokenUsage ,
2424 logApiRequest ,
25+ logApiResponse ,
26+ logApiError ,
2527} from '../telemetry/loggers.js' ;
2628import {
2729 ConversationRequestEvent ,
2830 ConversationResponseEvent ,
2931 TokenUsageEvent ,
3032 ApiRequestEvent ,
33+ ApiResponseEvent ,
34+ ApiErrorEvent ,
3135} from '../telemetry/types.js' ;
3236import { getConversationFileWriter } from '../storage/ConversationFileWriter.js' ;
3337import { ProviderPerformanceTracker } from './logging/ProviderPerformanceTracker.js' ;
@@ -613,13 +617,25 @@ export class LoggingProviderWrapper implements IProvider {
613617
614618 // Always process stream to extract token metrics
615619 // If logging not enabled, process for metrics only
620+ // Resolve the model name for telemetry - use resolved model, not provider default
621+ const resolvedModelName =
622+ normalizedOptions . resolved ?. model || this . wrapped . getDefaultModel ( ) ;
616623 if ( ! activeConfig ?. getConversationLoggingEnabled ( ) ) {
617- yield * this . processStreamForMetrics ( activeConfig , stream ) ;
624+ yield * this . processStreamForMetrics (
625+ activeConfig ,
626+ stream ,
627+ resolvedModelName ,
628+ ) ;
618629 return ;
619630 }
620631
621632 // Log the response stream (which also processes metrics)
622- yield * this . logResponseStream ( activeConfig , stream , promptId ) ;
633+ yield * this . logResponseStream (
634+ activeConfig ,
635+ stream ,
636+ promptId ,
637+ resolvedModelName ,
638+ ) ;
623639 }
624640
625641 private async logRequest (
@@ -670,10 +686,12 @@ export class LoggingProviderWrapper implements IProvider {
670686 /**
671687 * Process stream to extract token metrics without logging
672688 * @plan PLAN-20250909-TOKTRACK
689+ * @issue #684 - Fixed: Now logs API response telemetry for /stats model
673690 */
674691 private async * processStreamForMetrics (
675692 config : Config | undefined ,
676693 stream : AsyncIterableIterator < IContent > ,
694+ modelName : string ,
677695 ) : AsyncIterableIterator < IContent > {
678696 const startTime = performance . now ( ) ;
679697 let latestTokenUsage : UsageStats | undefined ;
@@ -692,11 +710,39 @@ export class LoggingProviderWrapper implements IProvider {
692710 }
693711
694712 // Process metrics if we have token usage
695- if ( latestTokenUsage ) {
696- const duration = performance . now ( ) - startTime ;
697- const tokenCounts =
698- this . extractTokenCountsFromTokenUsage ( latestTokenUsage ) ;
713+ const duration = performance . now ( ) - startTime ;
714+ const tokenCounts = latestTokenUsage
715+ ? this . extractTokenCountsFromTokenUsage ( latestTokenUsage )
716+ : {
717+ input_token_count : 0 ,
718+ output_token_count : 0 ,
719+ cached_content_token_count : 0 ,
720+ thoughts_token_count : 0 ,
721+ tool_token_count : 0 ,
722+ cache_read_input_tokens : 0 ,
723+ cache_creation_input_tokens : null ,
724+ } ;
725+
726+ // Issue #684: Log API response telemetry for /stats model tracking
727+ if ( config ) {
728+ // Create event and set token counts directly since constructor doesn't support raw counts
729+ const event = new ApiResponseEvent (
730+ modelName ,
731+ duration ,
732+ '' , // promptId - not available in metrics-only path
733+ ) ;
734+ event . input_token_count = tokenCounts . input_token_count ;
735+ event . output_token_count = tokenCounts . output_token_count ;
736+ event . cached_content_token_count =
737+ tokenCounts . cached_content_token_count ;
738+ event . thoughts_token_count = tokenCounts . thoughts_token_count ;
739+ event . tool_token_count = tokenCounts . tool_token_count ;
740+ event . total_token_count =
741+ tokenCounts . input_token_count + tokenCounts . output_token_count ;
742+ logApiResponse ( config , event ) ;
743+ }
699744
745+ if ( latestTokenUsage ) {
700746 // Accumulate token usage for session tracking
701747 this . accumulateTokenUsage ( tokenCounts , config ) ;
702748
@@ -713,6 +759,24 @@ export class LoggingProviderWrapper implements IProvider {
713759 // Record error in performance tracker
714760 const duration = performance . now ( ) - startTime ;
715761 this . performanceTracker . recordError ( duration , String ( error ) ) ;
762+
763+ // Issue #684: Log API error telemetry
764+ if ( config ) {
765+ const errorMessage =
766+ error instanceof Error ? error . message : String ( error ) ;
767+ logApiError (
768+ config ,
769+ new ApiErrorEvent (
770+ modelName ,
771+ errorMessage ,
772+ duration ,
773+ '' , // promptId
774+ undefined , // auth_type
775+ 'stream_error' , // error_type
776+ undefined , // status_code
777+ ) ,
778+ ) ;
779+ }
716780 throw error ;
717781 }
718782 }
@@ -721,6 +785,7 @@ export class LoggingProviderWrapper implements IProvider {
721785 config : Config ,
722786 stream : AsyncIterableIterator < IContent > ,
723787 promptId : string ,
788+ modelName : string ,
724789 ) : AsyncIterableIterator < IContent > {
725790 const startTime = performance . now ( ) ;
726791 let responseContent = '' ;
@@ -756,6 +821,7 @@ export class LoggingProviderWrapper implements IProvider {
756821 false ,
757822 error ,
758823 latestTokenUsage ,
824+ modelName ,
759825 ) ;
760826 throw error ;
761827 }
@@ -770,6 +836,7 @@ export class LoggingProviderWrapper implements IProvider {
770836 true ,
771837 undefined ,
772838 latestTokenUsage ,
839+ modelName ,
773840 ) ;
774841 }
775842 }
@@ -804,6 +871,7 @@ export class LoggingProviderWrapper implements IProvider {
804871 success : boolean ,
805872 error ?: unknown ,
806873 tokenUsage ?: UsageStats ,
874+ modelName ?: string ,
807875 ) : Promise < void > {
808876 try {
809877 const redactedContent = this . redactor
@@ -845,6 +913,25 @@ export class LoggingProviderWrapper implements IProvider {
845913 ) ,
846914 ) ;
847915
916+ // Issue #684: Log API response telemetry for /stats model tracking
917+ const resolvedModelName = modelName ?? this . wrapped . getDefaultModel ( ) ;
918+ const apiResponseEvent = new ApiResponseEvent (
919+ resolvedModelName ,
920+ duration ,
921+ promptId ,
922+ ) ;
923+ apiResponseEvent . input_token_count = tokenCounts . input_token_count ;
924+ apiResponseEvent . output_token_count = tokenCounts . output_token_count ;
925+ apiResponseEvent . cached_content_token_count =
926+ tokenCounts . cached_content_token_count ;
927+ apiResponseEvent . thoughts_token_count = tokenCounts . thoughts_token_count ;
928+ apiResponseEvent . tool_token_count = tokenCounts . tool_token_count ;
929+ apiResponseEvent . total_token_count = totalTokens ;
930+ if ( ! success && error ) {
931+ apiResponseEvent . error = String ( error ) ;
932+ }
933+ logApiResponse ( config , apiResponseEvent ) ;
934+
848935 const event = new ConversationResponseEvent (
849936 this . wrapped . name ,
850937 this . conversationId ,
0 commit comments