summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/utils/computeStats.test.ts
diff options
context:
space:
mode:
authorAbhi <[email protected]>2025-06-29 20:44:33 -0400
committerGitHub <[email protected]>2025-06-30 00:44:33 +0000
commit770f862832dfef477705bee69bd2a84397d105a8 (patch)
tree8cb647cf789f05458ff491b461aa531a6932ad3d /packages/cli/src/ui/utils/computeStats.test.ts
parent0fd602eb43eea7abca980dc2ae3fd7bf2ba76a2a (diff)
feat: Change /stats to include more detailed breakdowns (#2615)
Diffstat (limited to 'packages/cli/src/ui/utils/computeStats.test.ts')
-rw-r--r--packages/cli/src/ui/utils/computeStats.test.ts247
1 files changed, 247 insertions, 0 deletions
diff --git a/packages/cli/src/ui/utils/computeStats.test.ts b/packages/cli/src/ui/utils/computeStats.test.ts
new file mode 100644
index 00000000..0e32ffe2
--- /dev/null
+++ b/packages/cli/src/ui/utils/computeStats.test.ts
@@ -0,0 +1,247 @@
+/**
+ * @license
+ * Copyright 2025 Google LLC
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { describe, it, expect } from 'vitest';
+import {
+ calculateAverageLatency,
+ calculateCacheHitRate,
+ calculateErrorRate,
+ computeSessionStats,
+} from './computeStats.js';
+import { ModelMetrics, SessionMetrics } from '../contexts/SessionContext.js';
+
+describe('calculateErrorRate', () => {
+ it('should return 0 if totalRequests is 0', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 0, totalErrors: 0, totalLatencyMs: 0 },
+ tokens: {
+ prompt: 0,
+ candidates: 0,
+ total: 0,
+ cached: 0,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateErrorRate(metrics)).toBe(0);
+ });
+
+ it('should calculate the error rate correctly', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 10, totalErrors: 2, totalLatencyMs: 0 },
+ tokens: {
+ prompt: 0,
+ candidates: 0,
+ total: 0,
+ cached: 0,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateErrorRate(metrics)).toBe(20);
+ });
+});
+
+describe('calculateAverageLatency', () => {
+ it('should return 0 if totalRequests is 0', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 0, totalErrors: 0, totalLatencyMs: 1000 },
+ tokens: {
+ prompt: 0,
+ candidates: 0,
+ total: 0,
+ cached: 0,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateAverageLatency(metrics)).toBe(0);
+ });
+
+ it('should calculate the average latency correctly', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 10, totalErrors: 0, totalLatencyMs: 1500 },
+ tokens: {
+ prompt: 0,
+ candidates: 0,
+ total: 0,
+ cached: 0,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateAverageLatency(metrics)).toBe(150);
+ });
+});
+
+describe('calculateCacheHitRate', () => {
+ it('should return 0 if prompt tokens is 0', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 0, totalErrors: 0, totalLatencyMs: 0 },
+ tokens: {
+ prompt: 0,
+ candidates: 0,
+ total: 0,
+ cached: 100,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateCacheHitRate(metrics)).toBe(0);
+ });
+
+ it('should calculate the cache hit rate correctly', () => {
+ const metrics: ModelMetrics = {
+ api: { totalRequests: 0, totalErrors: 0, totalLatencyMs: 0 },
+ tokens: {
+ prompt: 200,
+ candidates: 0,
+ total: 0,
+ cached: 50,
+ thoughts: 0,
+ tool: 0,
+ },
+ };
+ expect(calculateCacheHitRate(metrics)).toBe(25);
+ });
+});
+
+describe('computeSessionStats', () => {
+ it('should return all zeros for initial empty metrics', () => {
+ const metrics: SessionMetrics = {
+ models: {},
+ tools: {
+ totalCalls: 0,
+ totalSuccess: 0,
+ totalFail: 0,
+ totalDurationMs: 0,
+ totalDecisions: { accept: 0, reject: 0, modify: 0 },
+ byName: {},
+ },
+ };
+
+ const result = computeSessionStats(metrics);
+
+ expect(result).toEqual({
+ totalApiTime: 0,
+ totalToolTime: 0,
+ agentActiveTime: 0,
+ apiTimePercent: 0,
+ toolTimePercent: 0,
+ cacheEfficiency: 0,
+ totalDecisions: 0,
+ successRate: 0,
+ agreementRate: 0,
+ totalPromptTokens: 0,
+ totalCachedTokens: 0,
+ });
+ });
+
+ it('should correctly calculate API and tool time percentages', () => {
+ const metrics: SessionMetrics = {
+ models: {
+ 'gemini-pro': {
+ api: { totalRequests: 1, totalErrors: 0, totalLatencyMs: 750 },
+ tokens: {
+ prompt: 10,
+ candidates: 10,
+ total: 20,
+ cached: 0,
+ thoughts: 0,
+ tool: 0,
+ },
+ },
+ },
+ tools: {
+ totalCalls: 1,
+ totalSuccess: 1,
+ totalFail: 0,
+ totalDurationMs: 250,
+ totalDecisions: { accept: 0, reject: 0, modify: 0 },
+ byName: {},
+ },
+ };
+
+ const result = computeSessionStats(metrics);
+
+ expect(result.totalApiTime).toBe(750);
+ expect(result.totalToolTime).toBe(250);
+ expect(result.agentActiveTime).toBe(1000);
+ expect(result.apiTimePercent).toBe(75);
+ expect(result.toolTimePercent).toBe(25);
+ });
+
+ it('should correctly calculate cache efficiency', () => {
+ const metrics: SessionMetrics = {
+ models: {
+ 'gemini-pro': {
+ api: { totalRequests: 2, totalErrors: 0, totalLatencyMs: 1000 },
+ tokens: {
+ prompt: 150,
+ candidates: 10,
+ total: 160,
+ cached: 50,
+ thoughts: 0,
+ tool: 0,
+ },
+ },
+ },
+ tools: {
+ totalCalls: 0,
+ totalSuccess: 0,
+ totalFail: 0,
+ totalDurationMs: 0,
+ totalDecisions: { accept: 0, reject: 0, modify: 0 },
+ byName: {},
+ },
+ };
+
+ const result = computeSessionStats(metrics);
+
+ expect(result.cacheEfficiency).toBeCloseTo(33.33); // 50 / 150
+ });
+
+ it('should correctly calculate success and agreement rates', () => {
+ const metrics: SessionMetrics = {
+ models: {},
+ tools: {
+ totalCalls: 10,
+ totalSuccess: 8,
+ totalFail: 2,
+ totalDurationMs: 1000,
+ totalDecisions: { accept: 6, reject: 2, modify: 2 },
+ byName: {},
+ },
+ };
+
+ const result = computeSessionStats(metrics);
+
+ expect(result.successRate).toBe(80); // 8 / 10
+ expect(result.agreementRate).toBe(60); // 6 / 10
+ });
+
+ it('should handle division by zero gracefully', () => {
+ const metrics: SessionMetrics = {
+ models: {},
+ tools: {
+ totalCalls: 0,
+ totalSuccess: 0,
+ totalFail: 0,
+ totalDurationMs: 0,
+ totalDecisions: { accept: 0, reject: 0, modify: 0 },
+ byName: {},
+ },
+ };
+
+ const result = computeSessionStats(metrics);
+
+ expect(result.apiTimePercent).toBe(0);
+ expect(result.toolTimePercent).toBe(0);
+ expect(result.cacheEfficiency).toBe(0);
+ expect(result.successRate).toBe(0);
+ expect(result.agreementRate).toBe(0);
+ });
+});