/**
* Shared constants — single source of truth for model IDs, thresholds, and limits.
*/
export type ModelProvider = "anthropic" | "bedrock" | "gemini" | "openai";
export const MODELS = {
// Anthropic (direct API)
OPUS: "claude-opus-4-6",
SONNET: "claude-sonnet-4-20250514",
HAIKU: "claude-haiku-4-5-20251001",
// Bedrock (Claude on AWS)
BEDROCK_SONNET: "us.anthropic.claude-sonnet-4-20250514-v1:0",
BEDROCK_SONNET_45: "us.anthropic.claude-sonnet-4-5-20250929-v1:0",
BEDROCK_HAIKU: "us.anthropic.claude-haiku-4-5-20251001-v1:0",
// Google Gemini
GEMINI_3_PRO: "gemini-3-pro-preview",
GEMINI_3_FLASH: "gemini-3-flash-preview",
GEMINI_25_PRO: "gemini-2.5-pro",
GEMINI_25_FLASH: "gemini-2.5-flash",
GEMINI_25_FLASH_LITE: "gemini-2.5-flash-lite",
// OpenAI
GPT_5: "gpt-5",
GPT_5_MINI: "gpt-5-mini",
GPT_5_NANO: "gpt-5-nano",
O3: "o3",
O4_MINI: "o4-mini",
GPT_4O: "gpt-4o",
} as const;
/** Maps short model aliases to full model IDs */
export const MODEL_MAP: Record<string, string> = {
// Auto-routing (resolved at runtime by model-router)
auto: "auto",
// Anthropic
opus: MODELS.OPUS,
sonnet: MODELS.SONNET,
haiku: MODELS.HAIKU,
// Bedrock
"bedrock-sonnet": MODELS.BEDROCK_SONNET,
"bedrock-sonnet-4.5": MODELS.BEDROCK_SONNET_45,
"bedrock-haiku": MODELS.BEDROCK_HAIKU,
// Gemini
"gemini-3-pro": MODELS.GEMINI_3_PRO,
"gemini-3-flash": MODELS.GEMINI_3_FLASH,
"gemini-pro": MODELS.GEMINI_25_PRO,
"gemini-flash": MODELS.GEMINI_25_FLASH,
"gemini-flash-lite": MODELS.GEMINI_25_FLASH_LITE,
// OpenAI
"gpt-5": MODELS.GPT_5,
"5": MODELS.GPT_5,
"gpt-5-mini": MODELS.GPT_5_MINI,
"5-mini": MODELS.GPT_5_MINI,
"gpt-5-nano": MODELS.GPT_5_NANO,
"5-nano": MODELS.GPT_5_NANO,
"o3": MODELS.O3,
"o4-mini": MODELS.O4_MINI,
"gpt-4o": MODELS.GPT_4O,
"4o": MODELS.GPT_4O,
};
/** Allowed model IDs for server validation */
export const ALLOWED_MODELS = [...Object.values(MODELS), "auto"] as string[];
/** Detect provider from full model ID */
export function getProvider(modelId: string): ModelProvider {
if (modelId === "auto") return "anthropic"; // auto resolves to Claude models
if (modelId.includes(".anthropic.")) return "bedrock";
if (modelId.startsWith("gemini-")) return "gemini";
if (modelId.startsWith("gpt-") || /^o\d/.test(modelId)) return "openai";
return "anthropic";
}
/** Check if an OpenAI model is a reasoning model (o-series) */
export function isOpenAIReasoningModel(modelId: string): boolean {
return /^o\d/.test(modelId);
}