/**
* 配置管理模块
*/
import type { Config } from '../types/index.js';
function getEnv(key: string, defaultValue?: string): string {
const value = process.env[key];
if (!value && defaultValue === undefined) {
throw new Error(`Missing required environment variable: ${key}`);
}
return value || defaultValue || '';
}
function getEnvNumber(key: string, defaultValue: number): number {
const value = process.env[key];
if (!value) return defaultValue;
const num = parseInt(value, 10);
return isNaN(num) ? defaultValue : num;
}
function getEnvBoolean(key: string, defaultValue: boolean): boolean {
const value = process.env[key];
if (!value) return defaultValue;
return value.toLowerCase() === 'true';
}
export function loadConfig(): Config {
// 解析域名列表
function parseDomainList(value: string): string[] {
if (!value) return [];
return value
.split(',')
.map(d => d.trim())
.filter(d => d.length > 0);
}
return {
// SearXNG 配置(必需)
searxng: {
baseUrl: getEnv('SEARXNG_BASE_URL'),
timeout: getEnvNumber('SEARXNG_TIMEOUT', 10000),
},
// Creeper 配置(必需)
creeper: {
path: getEnv('CREEPER_PATH'),
pythonPath: getEnv('CREEPER_PYTHON', 'python'),
concurrency: getEnvNumber('CREEPER_CONCURRENCY', 5),
timeout: getEnvNumber('CREEPER_TIMEOUT', 60000),
},
// 过滤器配置
filter: {
maxResults: getEnvNumber('FILTER_MAX_RESULTS', 8),
domainBlacklist: parseDomainList(getEnv('DOMAIN_BLACKLIST', '')),
domainWhitelist: parseDomainList(getEnv('DOMAIN_WHITELIST', '')),
},
// LLM 过滤配置
filterLlm: {
enabled: getEnvBoolean('FILTER_LLM_ENABLED', false),
apiKey: getEnv('FILTER_LLM_API_KEY', ''),
baseUrl: getEnv('FILTER_LLM_BASE_URL', 'https://api.deepseek.com'),
model: getEnv('FILTER_LLM_MODEL', 'deepseek-chat'),
timeout: getEnvNumber('FILTER_LLM_TIMEOUT', 30000),
},
// Map-Reduce 配置
mapReduce: {
chunkSize: getEnvNumber('MAP_REDUCE_CHUNK_SIZE', 30000),
maxConcurrency: getEnvNumber('MAP_REDUCE_MAX_CONCURRENCY', 5),
threshold: getEnvNumber('MAP_REDUCE_THRESHOLD', 50000),
},
// LLM 总结配置
summary: {
apiKey: getEnv('SUMMARY_API_KEY'),
baseUrl: getEnv('SUMMARY_BASE_URL', 'https://api.deepseek.com'),
model: getEnv('SUMMARY_MODEL', 'deepseek-chat'),
maxTokens: getEnvNumber('SUMMARY_MAX_TOKENS', 4096),
timeout: getEnvNumber('SUMMARY_TIMEOUT', 120000),
maxRetries: getEnvNumber('SUMMARY_MAX_RETRIES', 2),
},
// 服务配置
service: {
maxContentLength: getEnvNumber('MAX_CONTENT_LENGTH', 50000),
cacheTtl: getEnvNumber('CACHE_TTL', 3600),
logLevel: getEnv('LOG_LEVEL', 'info'),
},
// 文件保存配置
fileSave: {
enabled: getEnvBoolean('SAVE_CONTENT_ENABLED', false),
saveDir: getEnv('SAVE_CONTENT_DIR', 'temp'),
organization: getEnv('SAVE_CONTENT_ORGANIZATION', 'date') as 'date' | 'flat',
},
};
}
// 延迟加载配置,允许在运行时设置环境变量
let cachedConfig: Config | null = null;
export function getConfig(): Config {
if (!cachedConfig) {
cachedConfig = loadConfig();
}
return cachedConfig;
}
export function resetConfig(): void {
cachedConfig = null;
}