@@ -1279,4 +1279,165 @@ describe("AwsBedrockHandler", () => {
12791279 expect ( mockCaptureException ) . toHaveBeenCalled ( )
12801280 } )
12811281 } )
1282+
1283+ describe ( "AI SDK v6 usage field paths" , ( ) => {
1284+ const systemPrompt = "You are a helpful assistant"
1285+ const messages : RooMessage [ ] = [
1286+ {
1287+ role : "user" ,
1288+ content : "Hello" ,
1289+ } ,
1290+ ]
1291+
1292+ function setupStream ( usage : Record < string , unknown > , providerMetadata : Record < string , unknown > = { } ) {
1293+ async function * mockFullStream ( ) {
1294+ yield { type : "text-delta" , text : "reply" }
1295+ }
1296+
1297+ mockStreamText . mockReturnValue ( {
1298+ fullStream : mockFullStream ( ) ,
1299+ usage : Promise . resolve ( usage ) ,
1300+ providerMetadata : Promise . resolve ( providerMetadata ) ,
1301+ } )
1302+ }
1303+
1304+ describe ( "cache tokens" , ( ) => {
1305+ it ( "should read cache tokens from v6 top-level cachedInputTokens" , async ( ) => {
1306+ setupStream ( { inputTokens : 100 , outputTokens : 50 , cachedInputTokens : 30 } )
1307+
1308+ const generator = handler . createMessage ( systemPrompt , messages )
1309+ const chunks : unknown [ ] = [ ]
1310+ for await ( const chunk of generator ) {
1311+ chunks . push ( chunk )
1312+ }
1313+
1314+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1315+ expect ( usageChunk ) . toBeDefined ( )
1316+ expect ( usageChunk . cacheReadTokens ) . toBe ( 30 )
1317+ } )
1318+
1319+ it ( "should read cache tokens from v6 inputTokenDetails.cacheReadTokens" , async ( ) => {
1320+ setupStream ( {
1321+ inputTokens : 100 ,
1322+ outputTokens : 50 ,
1323+ inputTokenDetails : { cacheReadTokens : 25 } ,
1324+ } )
1325+
1326+ const generator = handler . createMessage ( systemPrompt , messages )
1327+ const chunks : unknown [ ] = [ ]
1328+ for await ( const chunk of generator ) {
1329+ chunks . push ( chunk )
1330+ }
1331+
1332+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1333+ expect ( usageChunk ) . toBeDefined ( )
1334+ expect ( usageChunk . cacheReadTokens ) . toBe ( 25 )
1335+ } )
1336+
1337+ it ( "should prefer v6 top-level cachedInputTokens over providerMetadata.bedrock" , async ( ) => {
1338+ setupStream (
1339+ { inputTokens : 100 , outputTokens : 50 , cachedInputTokens : 30 } ,
1340+ { bedrock : { usage : { cacheReadInputTokens : 20 } } } ,
1341+ )
1342+
1343+ const generator = handler . createMessage ( systemPrompt , messages )
1344+ const chunks : unknown [ ] = [ ]
1345+ for await ( const chunk of generator ) {
1346+ chunks . push ( chunk )
1347+ }
1348+
1349+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1350+ expect ( usageChunk ) . toBeDefined ( )
1351+ expect ( usageChunk . cacheReadTokens ) . toBe ( 30 )
1352+ } )
1353+
1354+ it ( "should fall back to providerMetadata.bedrock.usage.cacheReadInputTokens" , async ( ) => {
1355+ setupStream (
1356+ { inputTokens : 100 , outputTokens : 50 } ,
1357+ { bedrock : { usage : { cacheReadInputTokens : 20 } } } ,
1358+ )
1359+
1360+ const generator = handler . createMessage ( systemPrompt , messages )
1361+ const chunks : unknown [ ] = [ ]
1362+ for await ( const chunk of generator ) {
1363+ chunks . push ( chunk )
1364+ }
1365+
1366+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1367+ expect ( usageChunk ) . toBeDefined ( )
1368+ expect ( usageChunk . cacheReadTokens ) . toBe ( 20 )
1369+ } )
1370+
1371+ it ( "should read cacheWriteTokens from v6 inputTokenDetails.cacheWriteTokens" , async ( ) => {
1372+ setupStream ( {
1373+ inputTokens : 100 ,
1374+ outputTokens : 50 ,
1375+ inputTokenDetails : { cacheWriteTokens : 15 } ,
1376+ } )
1377+
1378+ const generator = handler . createMessage ( systemPrompt , messages )
1379+ const chunks : unknown [ ] = [ ]
1380+ for await ( const chunk of generator ) {
1381+ chunks . push ( chunk )
1382+ }
1383+
1384+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1385+ expect ( usageChunk ) . toBeDefined ( )
1386+ expect ( usageChunk . cacheWriteTokens ) . toBe ( 15 )
1387+ } )
1388+ } )
1389+
1390+ describe ( "reasoning tokens" , ( ) => {
1391+ it ( "should read reasoning tokens from v6 top-level reasoningTokens" , async ( ) => {
1392+ setupStream ( { inputTokens : 100 , outputTokens : 50 , reasoningTokens : 40 } )
1393+
1394+ const generator = handler . createMessage ( systemPrompt , messages )
1395+ const chunks : unknown [ ] = [ ]
1396+ for await ( const chunk of generator ) {
1397+ chunks . push ( chunk )
1398+ }
1399+
1400+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1401+ expect ( usageChunk ) . toBeDefined ( )
1402+ expect ( usageChunk . reasoningTokens ) . toBe ( 40 )
1403+ } )
1404+
1405+ it ( "should read reasoning tokens from v6 outputTokenDetails.reasoningTokens" , async ( ) => {
1406+ setupStream ( {
1407+ inputTokens : 100 ,
1408+ outputTokens : 50 ,
1409+ outputTokenDetails : { reasoningTokens : 35 } ,
1410+ } )
1411+
1412+ const generator = handler . createMessage ( systemPrompt , messages )
1413+ const chunks : unknown [ ] = [ ]
1414+ for await ( const chunk of generator ) {
1415+ chunks . push ( chunk )
1416+ }
1417+
1418+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1419+ expect ( usageChunk ) . toBeDefined ( )
1420+ expect ( usageChunk . reasoningTokens ) . toBe ( 35 )
1421+ } )
1422+
1423+ it ( "should prefer v6 top-level reasoningTokens over outputTokenDetails" , async ( ) => {
1424+ setupStream ( {
1425+ inputTokens : 100 ,
1426+ outputTokens : 50 ,
1427+ reasoningTokens : 40 ,
1428+ outputTokenDetails : { reasoningTokens : 15 } ,
1429+ } )
1430+
1431+ const generator = handler . createMessage ( systemPrompt , messages )
1432+ const chunks : unknown [ ] = [ ]
1433+ for await ( const chunk of generator ) {
1434+ chunks . push ( chunk )
1435+ }
1436+
1437+ const usageChunk = chunks . find ( ( c : any ) => c . type === "usage" ) as any
1438+ expect ( usageChunk ) . toBeDefined ( )
1439+ expect ( usageChunk . reasoningTokens ) . toBe ( 40 )
1440+ } )
1441+ } )
1442+ } )
12821443} )
0 commit comments