| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| import { listModels, type ModelInfo } from "../models"; |
| import type { LlmRole } from "./types"; |
|
|
| export const ROLE_TIMEOUT_MS: Record<LlmRole, number> = { |
| judge: 8_000, |
| diagnoser: 15_000, |
| planner: 20_000, |
| "code-mutator": 45_000, |
| }; |
|
|
| |
| |
| |
| |
| |
| const ROLE_PREFERENCE: Record<LlmRole, string[]> = { |
| judge: ["mdl_deepseek-v3", "mdl_qwen-max", "mdl_glm-4_6", "mdl_deepseek-r1"], |
| diagnoser: [ |
| "mdl_deepseek-r1", |
| "mdl_qwen-max", |
| "mdl_glm-4_6", |
| "mdl_deepseek-v3", |
| ], |
| planner: ["mdl_claude-sonnet-4-6", "mdl_gpt-5_2", "mdl_deepseek-r1"], |
| "code-mutator": [ |
| "mdl_claude-sonnet-4-6", |
| "mdl_gpt-5_2", |
| "mdl_deepseek-r1", |
| ], |
| }; |
|
|
| |
| |
| |
| |
| |
| const KNOWN_MODEL_PRICING_USD_PER_1K: Record< |
| string, |
| { input: number; output: number } |
| > = { |
| "mdl_claude-sonnet-4-6": { input: 0.003, output: 0.015 }, |
| "mdl_gpt-5_2": { input: 0.0025, output: 0.01 }, |
| "mdl_gemini-2_5-pro": { input: 0.00125, output: 0.005 }, |
| "mdl_deepseek-r1": { input: 0.00055, output: 0.00219 }, |
| "mdl_deepseek-v3": { input: 0.00027, output: 0.0011 }, |
| "mdl_qwen-max": { input: 0.0004, output: 0.0012 }, |
| "mdl_minimax-m2": { input: 0.0003, output: 0.0012 }, |
| "mdl_kimi-k2": { input: 0.0006, output: 0.0025 }, |
| "mdl_glm-4_6": { input: 0.0005, output: 0.002 }, |
| }; |
|
|
| export interface SelectedModel { |
| modelId: string; |
| modelInfo: ModelInfo; |
| |
| pricing: { input_per_1k: number; output_per_1k: number }; |
| } |
|
|
| |
| export function pickModelForRole(role: LlmRole): SelectedModel | null { |
| const all = listModels(); |
| const preferred = ROLE_PREFERENCE[role]; |
| for (const id of preferred) { |
| const m = all.find((mm) => mm.id === id && mm.available); |
| if (m) return { modelId: m.id, modelInfo: m, pricing: pricingFor(m) }; |
| } |
| |
| const any = all.find((mm) => mm.available); |
| if (any) |
| return { modelId: any.id, modelInfo: any, pricing: pricingFor(any) }; |
| return null; |
| } |
|
|
| function pricingFor(m: ModelInfo): { |
| input_per_1k: number; |
| output_per_1k: number; |
| } { |
| |
| if ( |
| m.pricing && |
| (m.pricing.input_per_1k > 0 || m.pricing.output_per_1k > 0) |
| ) { |
| return { |
| input_per_1k: m.pricing.input_per_1k, |
| output_per_1k: m.pricing.output_per_1k, |
| }; |
| } |
| const known = KNOWN_MODEL_PRICING_USD_PER_1K[m.id]; |
| if (known) { |
| return { input_per_1k: known.input, output_per_1k: known.output }; |
| } |
| return { input_per_1k: 0, output_per_1k: 0 }; |
| } |
|
|
| export function estimateCostUsd( |
| pricing: { input_per_1k: number; output_per_1k: number }, |
| inputTokens: number, |
| outputTokens: number, |
| ): number { |
| return ( |
| (inputTokens / 1000) * pricing.input_per_1k + |
| (outputTokens / 1000) * pricing.output_per_1k |
| ); |
| } |
|
|