@@ -245,4 +245,149 @@ describe("activity endpoint", () => {
245245 const res = await app . request ( "/activity?days=7" ) ;
246246 expect ( res . status ) . toBe ( 401 ) ;
247247 } ) ;
248+
249+ test ( "GET /activity should correctly aggregate token counts" , async ( ) => {
250+ // Clear existing logs and insert test data with known values
251+ await db . delete ( tables . log ) ;
252+
253+ const today = new Date ( ) ;
254+ const yesterday = new Date ( today ) ;
255+ yesterday . setDate ( yesterday . getDate ( ) - 1 ) ;
256+
257+ await db . insert ( tables . log ) . values ( [
258+ {
259+ id : "token-test-1" ,
260+ requestId : "token-test-1" ,
261+ createdAt : today ,
262+ updatedAt : today ,
263+ organizationId : "test-org-id" ,
264+ projectId : "test-project-id" ,
265+ apiKeyId : "test-api-key-id" ,
266+ duration : 1000 ,
267+ requestedModel : "gpt-4" ,
268+ requestedProvider : "openai" ,
269+ usedModel : "gpt-4" ,
270+ usedProvider : "openai" ,
271+ responseSize : 1000 ,
272+ promptTokens : "100" ,
273+ completionTokens : "200" ,
274+ totalTokens : "300" ,
275+ cost : 0.1 ,
276+ inputCost : 0.05 ,
277+ outputCost : 0.05 ,
278+ requestCost : 0 ,
279+ messages : JSON . stringify ( [ { role : "user" , content : "Test" } ] ) ,
280+ mode : "api-keys" ,
281+ usedMode : "api-keys" ,
282+ } ,
283+ {
284+ id : "token-test-2" ,
285+ requestId : "token-test-2" ,
286+ createdAt : today ,
287+ updatedAt : today ,
288+ organizationId : "test-org-id" ,
289+ projectId : "test-project-id" ,
290+ apiKeyId : "test-api-key-id" ,
291+ duration : 1500 ,
292+ requestedModel : "gpt-4" ,
293+ requestedProvider : "openai" ,
294+ usedModel : "gpt-4" ,
295+ usedProvider : "openai" ,
296+ responseSize : 1500 ,
297+ promptTokens : "150" ,
298+ completionTokens : "250" ,
299+ totalTokens : "400" ,
300+ cost : 0.15 ,
301+ inputCost : 0.07 ,
302+ outputCost : 0.08 ,
303+ requestCost : 0 ,
304+ messages : JSON . stringify ( [ { role : "user" , content : "Test2" } ] ) ,
305+ mode : "api-keys" ,
306+ usedMode : "api-keys" ,
307+ } ,
308+ {
309+ id : "token-test-3" ,
310+ requestId : "token-test-3" ,
311+ createdAt : yesterday ,
312+ updatedAt : yesterday ,
313+ organizationId : "test-org-id" ,
314+ projectId : "test-project-id" ,
315+ apiKeyId : "test-api-key-id" ,
316+ duration : 2000 ,
317+ requestedModel : "claude-3-sonnet" ,
318+ requestedProvider : "anthropic" ,
319+ usedModel : "claude-3-sonnet" ,
320+ usedProvider : "anthropic" ,
321+ responseSize : 2000 ,
322+ promptTokens : "300" ,
323+ completionTokens : "500" ,
324+ totalTokens : "800" ,
325+ cost : 0.25 ,
326+ inputCost : 0.1 ,
327+ outputCost : 0.15 ,
328+ requestCost : 0 ,
329+ messages : JSON . stringify ( [ { role : "user" , content : "Test3" } ] ) ,
330+ mode : "api-keys" ,
331+ usedMode : "api-keys" ,
332+ } ,
333+ ] ) ;
334+
335+ const res = await app . request ( "/activity?days=7" , {
336+ headers : {
337+ Cookie : token ,
338+ } ,
339+ } ) ;
340+
341+ expect ( res . status ) . toBe ( 200 ) ;
342+ const data = await res . json ( ) ;
343+
344+ // Verify the response structure
345+ expect ( Array . isArray ( data . activity ) ) . toBe ( true ) ;
346+ expect ( data . activity . length ) . toBeGreaterThan ( 0 ) ;
347+
348+ // Calculate totals from the response
349+ const totalRequests = data . activity . reduce (
350+ ( sum : number , day : any ) => sum + day . requestCount ,
351+ 0 ,
352+ ) ;
353+ const totalTokens = data . activity . reduce (
354+ ( sum : number , day : any ) => sum + day . totalTokens ,
355+ 0 ,
356+ ) ;
357+ const totalInputTokens = data . activity . reduce (
358+ ( sum : number , day : any ) => sum + day . inputTokens ,
359+ 0 ,
360+ ) ;
361+ const totalOutputTokens = data . activity . reduce (
362+ ( sum : number , day : any ) => sum + day . outputTokens ,
363+ 0 ,
364+ ) ;
365+ const totalCost = data . activity . reduce (
366+ ( sum : number , day : any ) => sum + day . cost ,
367+ 0 ,
368+ ) ;
369+
370+ // Verify correct aggregation
371+ expect ( totalRequests ) . toBe ( 3 ) ;
372+ expect ( totalTokens ) . toBe ( 1500 ) ; // 300 + 400 + 800
373+ expect ( totalInputTokens ) . toBe ( 550 ) ; // 100 + 150 + 300
374+ expect ( totalOutputTokens ) . toBe ( 950 ) ; // 200 + 250 + 500
375+ expect ( totalCost ) . toBeCloseTo ( 0.5 , 2 ) ; // 0.10 + 0.15 + 0.25
376+
377+ // Verify individual days
378+ const todayData = data . activity . find ( ( day : any ) => day . requestCount === 2 ) ;
379+ const yesterdayData = data . activity . find (
380+ ( day : any ) => day . requestCount === 1 ,
381+ ) ;
382+
383+ expect ( todayData ) . toBeDefined ( ) ;
384+ expect ( todayData . totalTokens ) . toBe ( 700 ) ; // 300 + 400
385+ expect ( todayData . inputTokens ) . toBe ( 250 ) ; // 100 + 150
386+ expect ( todayData . outputTokens ) . toBe ( 450 ) ; // 200 + 250
387+
388+ expect ( yesterdayData ) . toBeDefined ( ) ;
389+ expect ( yesterdayData . totalTokens ) . toBe ( 800 ) ;
390+ expect ( yesterdayData . inputTokens ) . toBe ( 300 ) ;
391+ expect ( yesterdayData . outputTokens ) . toBe ( 500 ) ;
392+ } ) ;
248393} ) ;
0 commit comments