export type AiRuntimeConfig = { baseUrl: string; apiKey: string; chatModel: string; requestTimeoutMs: number; maxTokens: number; maxRetries: number; }; export type AiRuntimeConfigResult = | { success: true; config: AiRuntimeConfig } | { success: false; reason: string }; const DEFAULT_CHAT_MODEL = "gpt-4.1-mini"; const DEFAULT_REQUEST_TIMEOUT_MS = 20_000; const DEFAULT_MAX_TOKENS = 1_000; const DEFAULT_MAX_RETRIES = 0; function readOptionalEnv(name: string): string { return process.env[name]?.trim() ?? ""; } function readBoundedIntegerEnv(name: string, fallback: number, min: number, max: number): number { const rawValue = readOptionalEnv(name); if (!rawValue) { return fallback; } const value = Number(rawValue); if (!Number.isInteger(value) || value < min || value > max) { return fallback; } return value; } export function getAiRuntimeConfig(): AiRuntimeConfigResult { const apiKey = readOptionalEnv("AI_API_KEY"); if (!apiKey) { return { success: false, reason: "AI_API_KEY 未配置" }; } return { success: true, config: { baseUrl: readOptionalEnv("AI_BASE_URL"), apiKey, chatModel: readOptionalEnv("AI_CHAT_MODEL") || DEFAULT_CHAT_MODEL, requestTimeoutMs: readBoundedIntegerEnv("AI_REQUEST_TIMEOUT_MS", DEFAULT_REQUEST_TIMEOUT_MS, 1_000, 120_000), maxTokens: readBoundedIntegerEnv("AI_MAX_TOKENS", DEFAULT_MAX_TOKENS, 256, 2_000), maxRetries: readBoundedIntegerEnv("AI_MAX_RETRIES", DEFAULT_MAX_RETRIES, 0, 5), }, }; }