11import { LDClient , LDContext } from '@launchdarkly/node-server-sdk' ;
22
33import {
4- BedrockTokenUsage ,
54 createBedrockTokenUsage ,
65 FeedbackKind ,
76 OpenAITokenUsage ,
7+ TokenMetrics ,
88 TokenUsage ,
99 UnderscoreTokenUsage ,
1010} from './api/metrics' ;
@@ -33,7 +33,7 @@ export class LDAIConfigTracker {
3333 this . ldClient . track ( '$ld:ai:duration:total' , this . context , this . getTrackData ( ) , duration ) ;
3434 }
3535
36- async trackDurationOf ( func : Function , ...args : any [ ] ) : Promise < any > {
36+ async trackDurationOf ( func : ( ... args : any [ ] ) => Promise < any > , ...args : any [ ] ) : Promise < any > {
3737 const startTime = Date . now ( ) ;
3838 const result = await func ( ...args ) ;
3939 const endTime = Date . now ( ) ;
@@ -58,7 +58,7 @@ export class LDAIConfigTracker {
5858 this . ldClient . track ( '$ld:ai:generation' , this . context , this . getTrackData ( ) , generation ) ;
5959 }
6060
61- async trackOpenAI ( func : Function , ...args : any [ ] ) : Promise < any > {
61+ async trackOpenAI ( func : ( ... args : any [ ] ) => Promise < any > , ...args : any [ ] ) : Promise < any > {
6262 const result = await this . trackDurationOf ( func , ...args ) ;
6363 this . trackGeneration ( 1 ) ;
6464 if ( result . usage ) {
@@ -90,8 +90,8 @@ export class LDAIConfigTracker {
9090 return res ;
9191 }
9292
93- trackTokens ( tokens : TokenUsage | UnderscoreTokenUsage | BedrockTokenUsage ) : void {
94- const tokenMetrics = tokens . toMetrics ( ) ;
93+ trackTokens ( tokens : TokenUsage | UnderscoreTokenUsage | { totalTokens : number ; inputTokens : number ; outputTokens : number } ) : void {
94+ const tokenMetrics = toMetrics ( tokens ) ;
9595 if ( tokenMetrics . total > 0 ) {
9696 this . ldClient . track (
9797 '$ld:ai:tokens:total' ,
@@ -118,3 +118,27 @@ export class LDAIConfigTracker {
118118 }
119119 }
120120}
121+
122+ function toMetrics (
123+ usage : TokenUsage | UnderscoreTokenUsage | { totalTokens : number ; inputTokens : number ; outputTokens : number } ,
124+ ) : TokenMetrics {
125+ if ( 'inputTokens' in usage && 'outputTokens' in usage ) {
126+ // Bedrock usage
127+ return {
128+ total : usage . totalTokens ,
129+ input : usage . inputTokens ,
130+ output : usage . outputTokens ,
131+ } ;
132+ }
133+
134+ // OpenAI usage (both camelCase and snake_case)
135+ return {
136+ total : 'total_tokens' in usage ? usage . total_tokens ! : ( usage as TokenUsage ) . totalTokens ?? 0 ,
137+ input :
138+ 'prompt_tokens' in usage ? usage . prompt_tokens ! : ( usage as TokenUsage ) . promptTokens ?? 0 ,
139+ output :
140+ 'completion_tokens' in usage
141+ ? usage . completion_tokens !
142+ : ( usage as TokenUsage ) . completionTokens ?? 0 ,
143+ } ;
144+ }
0 commit comments