import { Controller, Get, Query, UseGuards, BadRequestException } from "@nestjs/common"; import { AuthGuard } from "../auth/guards/auth.guard"; import { PredictionService } from "./prediction.service"; import { TaskType, Complexity, Provider, type PredictionResponse, } from "@mosaicstack/telemetry-client"; /** * Valid values for query parameter validation. */ const VALID_TASK_TYPES = new Set(Object.values(TaskType)); const VALID_COMPLEXITIES = new Set(Object.values(Complexity)); const VALID_PROVIDERS = new Set(Object.values(Provider)); /** * Response DTO for the estimate endpoint. */ interface EstimateResponseDto { data: PredictionResponse | null; } /** * Mosaic Telemetry Controller * * Provides API endpoints for accessing telemetry prediction data. * All endpoints require authentication via AuthGuard. * * This controller is intentionally lightweight - it delegates to PredictionService * for the actual prediction logic and returns results directly to the frontend. */ @Controller("telemetry") @UseGuards(AuthGuard) export class MosaicTelemetryController { constructor(private readonly predictionService: PredictionService) {} /** * GET /api/telemetry/estimate * * Get a cost/token estimate for a given task configuration. * Returns prediction data including confidence level, or null if * no prediction is available. * * @param taskType - Task type enum value (e.g. "implementation", "planning") * @param model - Model name (e.g. "claude-sonnet-4-5") * @param provider - Provider enum value (e.g. "anthropic", "openai") * @param complexity - Complexity level (e.g. "low", "medium", "high") * @returns Prediction response with estimates and confidence */ @Get("estimate") getEstimate( @Query("taskType") taskType: string, @Query("model") model: string, @Query("provider") provider: string, @Query("complexity") complexity: string ): EstimateResponseDto { if (!taskType || !model || !provider || !complexity) { throw new BadRequestException( "Missing query parameters. Required: taskType, model, provider, complexity" ); } if (!VALID_TASK_TYPES.has(taskType)) { throw new BadRequestException( `Invalid taskType "${taskType}". Valid values: ${[...VALID_TASK_TYPES].join(", ")}` ); } if (!VALID_PROVIDERS.has(provider)) { throw new BadRequestException( `Invalid provider "${provider}". Valid values: ${[...VALID_PROVIDERS].join(", ")}` ); } if (!VALID_COMPLEXITIES.has(complexity)) { throw new BadRequestException( `Invalid complexity "${complexity}". Valid values: ${[...VALID_COMPLEXITIES].join(", ")}` ); } const prediction = this.predictionService.getEstimate( taskType as TaskType, model, provider as Provider, complexity as Complexity ); return { data: prediction }; } }