@@ -980,6 +980,182 @@ describe("callModel E2E Tests", () => {
980980 } ) ;
981981 } ) ;
982982
983+ describe ( "response.getResponse - Full response with usage" , ( ) => {
984+ it ( "should return full response with correct shape" , async ( ) => {
985+ const response = client . callModel ( {
986+ model : "meta-llama/llama-3.2-1b-instruct" ,
987+ input : [
988+ {
989+ role : "user" ,
990+ content : "Say 'hello'." ,
991+ } ,
992+ ] ,
993+ } ) ;
994+
995+ const fullResponse = await response . getResponse ( ) ;
996+
997+ // Verify top-level response shape
998+ expect ( fullResponse ) . toBeDefined ( ) ;
999+ expect ( typeof fullResponse . id ) . toBe ( "string" ) ;
1000+ expect ( fullResponse . id . length ) . toBeGreaterThan ( 0 ) ;
1001+ expect ( fullResponse . object ) . toBe ( "response" ) ;
1002+ expect ( typeof fullResponse . createdAt ) . toBe ( "number" ) ;
1003+ expect ( typeof fullResponse . model ) . toBe ( "string" ) ;
1004+ expect ( Array . isArray ( fullResponse . output ) ) . toBe ( true ) ;
1005+ expect ( fullResponse . output . length ) . toBeGreaterThan ( 0 ) ;
1006+
1007+ // Verify output items have correct shape
1008+ for ( const item of fullResponse . output ) {
1009+ expect ( item ) . toHaveProperty ( "type" ) ;
1010+ expect ( typeof ( item as any ) . type ) . toBe ( "string" ) ;
1011+ }
1012+
1013+ // Verify temperature and topP are present (can be null)
1014+ expect ( "temperature" in fullResponse ) . toBe ( true ) ;
1015+ expect ( "topP" in fullResponse ) . toBe ( true ) ;
1016+
1017+ // Verify metadata shape
1018+ expect ( "metadata" in fullResponse ) . toBe ( true ) ;
1019+
1020+ // Verify tools array exists
1021+ expect ( Array . isArray ( fullResponse . tools ) ) . toBe ( true ) ;
1022+
1023+ // Verify toolChoice exists
1024+ expect ( "toolChoice" in fullResponse ) . toBe ( true ) ;
1025+
1026+ // Verify parallelToolCalls is boolean
1027+ expect ( typeof fullResponse . parallelToolCalls ) . toBe ( "boolean" ) ;
1028+ } ) ;
1029+
1030+ it ( "should return usage with correct shape including all token details" , async ( ) => {
1031+ const response = client . callModel ( {
1032+ model : "meta-llama/llama-3.2-1b-instruct" ,
1033+ input : [
1034+ {
1035+ role : "user" ,
1036+ content : "Say 'hello'." ,
1037+ } ,
1038+ ] ,
1039+ } ) ;
1040+
1041+ const fullResponse = await response . getResponse ( ) ;
1042+
1043+ // Verify usage exists and has correct shape
1044+ expect ( fullResponse . usage ) . toBeDefined ( ) ;
1045+ const usage = fullResponse . usage ! ;
1046+
1047+ // Verify top-level usage fields
1048+ expect ( typeof usage . inputTokens ) . toBe ( "number" ) ;
1049+ expect ( usage . inputTokens ) . toBeGreaterThan ( 0 ) ;
1050+ expect ( typeof usage . outputTokens ) . toBe ( "number" ) ;
1051+ expect ( usage . outputTokens ) . toBeGreaterThan ( 0 ) ;
1052+ expect ( typeof usage . totalTokens ) . toBe ( "number" ) ;
1053+ expect ( usage . totalTokens ) . toBe ( usage . inputTokens + usage . outputTokens ) ;
1054+
1055+ // Verify inputTokensDetails shape with cachedTokens
1056+ expect ( usage . inputTokensDetails ) . toBeDefined ( ) ;
1057+ expect ( typeof usage . inputTokensDetails . cachedTokens ) . toBe ( "number" ) ;
1058+ expect ( usage . inputTokensDetails . cachedTokens ) . toBeGreaterThanOrEqual ( 0 ) ;
1059+
1060+ // Verify outputTokensDetails shape with reasoningTokens
1061+ expect ( usage . outputTokensDetails ) . toBeDefined ( ) ;
1062+ expect ( typeof usage . outputTokensDetails . reasoningTokens ) . toBe ( "number" ) ;
1063+ expect ( usage . outputTokensDetails . reasoningTokens ) . toBeGreaterThanOrEqual ( 0 ) ;
1064+
1065+ // Verify optional cost fields if present
1066+ if ( usage . cost !== undefined && usage . cost !== null ) {
1067+ expect ( typeof usage . cost ) . toBe ( "number" ) ;
1068+ }
1069+
1070+ if ( usage . isByok !== undefined ) {
1071+ expect ( typeof usage . isByok ) . toBe ( "boolean" ) ;
1072+ }
1073+
1074+ if ( usage . costDetails !== undefined ) {
1075+ expect ( typeof usage . costDetails . upstreamInferenceInputCost ) . toBe ( "number" ) ;
1076+ expect ( typeof usage . costDetails . upstreamInferenceOutputCost ) . toBe ( "number" ) ;
1077+ if ( usage . costDetails . upstreamInferenceCost !== undefined && usage . costDetails . upstreamInferenceCost !== null ) {
1078+ expect ( typeof usage . costDetails . upstreamInferenceCost ) . toBe ( "number" ) ;
1079+ }
1080+ }
1081+ } ) ;
1082+
1083+ it ( "should return error and incompleteDetails fields with correct shape" , async ( ) => {
1084+ const response = client . callModel ( {
1085+ model : "meta-llama/llama-3.2-1b-instruct" ,
1086+ input : [
1087+ {
1088+ role : "user" ,
1089+ content : "Say 'test'." ,
1090+ } ,
1091+ ] ,
1092+ } ) ;
1093+
1094+ const fullResponse = await response . getResponse ( ) ;
1095+
1096+ // error can be null or an object
1097+ expect ( "error" in fullResponse ) . toBe ( true ) ;
1098+ if ( fullResponse . error !== null ) {
1099+ expect ( typeof fullResponse . error ) . toBe ( "object" ) ;
1100+ }
1101+
1102+ // incompleteDetails can be null or an object
1103+ expect ( "incompleteDetails" in fullResponse ) . toBe ( true ) ;
1104+ if ( fullResponse . incompleteDetails !== null ) {
1105+ expect ( typeof fullResponse . incompleteDetails ) . toBe ( "object" ) ;
1106+ }
1107+ } ) ;
1108+
1109+ it ( "should allow concurrent access with other methods" , async ( ) => {
1110+ const response = client . callModel ( {
1111+ model : "meta-llama/llama-3.2-1b-instruct" ,
1112+ input : [
1113+ {
1114+ role : "user" ,
1115+ content : "Say 'test'." ,
1116+ } ,
1117+ ] ,
1118+ } ) ;
1119+
1120+ // Get both text and full response concurrently
1121+ const [ text , fullResponse ] = await Promise . all ( [
1122+ response . getText ( ) ,
1123+ response . getResponse ( ) ,
1124+ ] ) ;
1125+
1126+ expect ( text ) . toBeDefined ( ) ;
1127+ expect ( typeof text ) . toBe ( "string" ) ;
1128+ expect ( fullResponse ) . toBeDefined ( ) ;
1129+ expect ( fullResponse . usage ) . toBeDefined ( ) ;
1130+
1131+ // Text should match outputText
1132+ if ( fullResponse . outputText ) {
1133+ expect ( text ) . toBe ( fullResponse . outputText ) ;
1134+ }
1135+ } ) ;
1136+
1137+ it ( "should return consistent results on multiple calls" , async ( ) => {
1138+ const response = client . callModel ( {
1139+ model : "meta-llama/llama-3.2-1b-instruct" ,
1140+ input : [
1141+ {
1142+ role : "user" ,
1143+ content : "Say 'consistent'." ,
1144+ } ,
1145+ ] ,
1146+ } ) ;
1147+
1148+ const firstCall = await response . getResponse ( ) ;
1149+ const secondCall = await response . getResponse ( ) ;
1150+
1151+ // Should return the same response object
1152+ expect ( firstCall . id ) . toBe ( secondCall . id ) ;
1153+ expect ( firstCall . usage ?. inputTokens ) . toBe ( secondCall . usage ?. inputTokens ) ;
1154+ expect ( firstCall . usage ?. outputTokens ) . toBe ( secondCall . usage ?. outputTokens ) ;
1155+ expect ( firstCall . usage ?. inputTokensDetails ?. cachedTokens ) . toBe ( secondCall . usage ?. inputTokensDetails ?. cachedTokens ) ;
1156+ } ) ;
1157+ } ) ;
1158+
9831159 describe ( "Response parameters" , ( ) => {
9841160 it ( "should respect maxOutputTokens parameter" , async ( ) => {
9851161 const response = client . callModel ( {
@@ -1019,5 +1195,90 @@ describe("callModel E2E Tests", () => {
10191195 expect ( text . length ) . toBeGreaterThan ( 0 ) ;
10201196 // Just verify instructions parameter is accepted, not that model follows it perfectly
10211197 } ) ;
1198+
1199+ it ( "should support provider parameter with correct shape" , async ( ) => {
1200+ const response = client . callModel ( {
1201+ model : "meta-llama/llama-3.2-1b-instruct" ,
1202+ input : [
1203+ {
1204+ role : "user" ,
1205+ content : "Say 'provider test'." ,
1206+ } ,
1207+ ] ,
1208+ provider : {
1209+ allowFallbacks : true ,
1210+ requireParameters : false ,
1211+ } ,
1212+ } ) ;
1213+
1214+ const fullResponse = await response . getResponse ( ) ;
1215+
1216+ expect ( fullResponse ) . toBeDefined ( ) ;
1217+ expect ( fullResponse . usage ) . toBeDefined ( ) ;
1218+ expect ( fullResponse . usage ?. inputTokens ) . toBeGreaterThan ( 0 ) ;
1219+ } ) ;
1220+
1221+ it ( "should support provider with order preference" , async ( ) => {
1222+ const response = client . callModel ( {
1223+ model : "meta-llama/llama-3.2-1b-instruct" ,
1224+ input : [
1225+ {
1226+ role : "user" ,
1227+ content : "Say 'ordered provider'." ,
1228+ } ,
1229+ ] ,
1230+ provider : {
1231+ order : [ "Together" , "Fireworks" ] ,
1232+ allowFallbacks : true ,
1233+ } ,
1234+ } ) ;
1235+
1236+ const text = await response . getText ( ) ;
1237+
1238+ expect ( text ) . toBeDefined ( ) ;
1239+ expect ( typeof text ) . toBe ( "string" ) ;
1240+ expect ( text . length ) . toBeGreaterThan ( 0 ) ;
1241+ } ) ;
1242+
1243+ it ( "should support provider with ignore list" , async ( ) => {
1244+ const response = client . callModel ( {
1245+ model : "meta-llama/llama-3.2-1b-instruct" ,
1246+ input : [
1247+ {
1248+ role : "user" ,
1249+ content : "Say 'ignore test'." ,
1250+ } ,
1251+ ] ,
1252+ provider : {
1253+ ignore : [ "SomeProvider" ] ,
1254+ allowFallbacks : true ,
1255+ } ,
1256+ } ) ;
1257+
1258+ const text = await response . getText ( ) ;
1259+
1260+ expect ( text ) . toBeDefined ( ) ;
1261+ expect ( typeof text ) . toBe ( "string" ) ;
1262+ } ) ;
1263+
1264+ it ( "should support provider with quantizations filter" , async ( ) => {
1265+ const response = client . callModel ( {
1266+ model : "meta-llama/llama-3.2-1b-instruct" ,
1267+ input : [
1268+ {
1269+ role : "user" ,
1270+ content : "Say 'quantization test'." ,
1271+ } ,
1272+ ] ,
1273+ provider : {
1274+ allowFallbacks : true ,
1275+ } ,
1276+ } ) ;
1277+
1278+ const fullResponse = await response . getResponse ( ) ;
1279+
1280+ expect ( fullResponse ) . toBeDefined ( ) ;
1281+ expect ( fullResponse . model ) . toBeDefined ( ) ;
1282+ } ) ;
10221283 } ) ;
10231284} ) ;
0 commit comments