feat(#309): Add LLM usage tracking and analytics
Implements comprehensive LLM usage tracking with analytics endpoints. Implementation: - Added LlmUsageLog model to Prisma schema - Created llm-usage module with service, controller, and DTOs - Added tracking for token usage, costs, and durations - Implemented analytics aggregation by provider, model, and task type - Added filtering by workspace, provider, model, user, and date range Testing: - 20 unit tests with 90.8% coverage (exceeds 85% requirement) - Tests for service and controller with full error handling - Tests use Vitest following project conventions API Endpoints: - GET /api/llm-usage/analytics - Aggregated usage analytics - GET /api/llm-usage/by-workspace/:workspaceId - Workspace usage logs - GET /api/llm-usage/by-workspace/:workspaceId/provider/:provider - Provider logs - GET /api/llm-usage/by-workspace/:workspaceId/model/:model - Model logs Database: - LlmUsageLog table with indexes for efficient queries - Relations to User, Workspace, and LlmProviderInstance - Ready for migration with: pnpm prisma migrate dev Refs #309 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
2
apps/api/src/llm-usage/dto/index.ts
Normal file
2
apps/api/src/llm-usage/dto/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export * from "./track-usage.dto";
|
||||
export * from "./usage-analytics.dto";
|
||||
49
apps/api/src/llm-usage/dto/track-usage.dto.ts
Normal file
49
apps/api/src/llm-usage/dto/track-usage.dto.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { IsString, IsInt, IsOptional, IsNumber, Min, IsUUID } from "class-validator";
|
||||
|
||||
export class TrackUsageDto {
|
||||
@IsUUID()
|
||||
workspaceId!: string;
|
||||
|
||||
@IsUUID()
|
||||
userId!: string;
|
||||
|
||||
@IsString()
|
||||
provider!: string;
|
||||
|
||||
@IsString()
|
||||
model!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
providerInstanceId?: string;
|
||||
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
promptTokens!: number;
|
||||
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
completionTokens!: number;
|
||||
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
totalTokens!: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
costCents?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
taskType?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
conversationId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
@Min(0)
|
||||
durationMs?: number;
|
||||
}
|
||||
69
apps/api/src/llm-usage/dto/usage-analytics.dto.ts
Normal file
69
apps/api/src/llm-usage/dto/usage-analytics.dto.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { IsOptional, IsDateString, IsUUID, IsString } from "class-validator";
|
||||
|
||||
export class UsageAnalyticsQueryDto {
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
workspaceId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
provider?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
model?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsUUID()
|
||||
userId?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
startDate?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsDateString()
|
||||
endDate?: string;
|
||||
}
|
||||
|
||||
export interface UsageAnalyticsResponseDto {
|
||||
totalCalls: number;
|
||||
totalPromptTokens: number;
|
||||
totalCompletionTokens: number;
|
||||
totalTokens: number;
|
||||
totalCostCents: number;
|
||||
averageDurationMs: number;
|
||||
byProvider: ProviderUsageDto[];
|
||||
byModel: ModelUsageDto[];
|
||||
byTaskType: TaskTypeUsageDto[];
|
||||
}
|
||||
|
||||
export interface ProviderUsageDto {
|
||||
provider: string;
|
||||
calls: number;
|
||||
promptTokens: number;
|
||||
completionTokens: number;
|
||||
totalTokens: number;
|
||||
costCents: number;
|
||||
averageDurationMs: number;
|
||||
}
|
||||
|
||||
export interface ModelUsageDto {
|
||||
model: string;
|
||||
calls: number;
|
||||
promptTokens: number;
|
||||
completionTokens: number;
|
||||
totalTokens: number;
|
||||
costCents: number;
|
||||
averageDurationMs: number;
|
||||
}
|
||||
|
||||
export interface TaskTypeUsageDto {
|
||||
taskType: string;
|
||||
calls: number;
|
||||
promptTokens: number;
|
||||
completionTokens: number;
|
||||
totalTokens: number;
|
||||
costCents: number;
|
||||
averageDurationMs: number;
|
||||
}
|
||||
Reference in New Issue
Block a user