feat(#373): prediction integration for cost estimation
- Create PredictionService for pre-task cost/token estimates - Refresh common predictions on startup - Integrate predictions into LLM telemetry tracker - Add GET /api/telemetry/estimate endpoint - Graceful degradation when no prediction data available - Add unit tests for prediction service Refs #373 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
92
apps/api/src/mosaic-telemetry/mosaic-telemetry.controller.ts
Normal file
92
apps/api/src/mosaic-telemetry/mosaic-telemetry.controller.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
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<string>(Object.values(TaskType));
|
||||
const VALID_COMPLEXITIES = new Set<string>(Object.values(Complexity));
|
||||
const VALID_PROVIDERS = new Set<string>(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 };
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user