mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 04:19:39 +02:00
New Bun/Hono service on port 3068 that bundles many web-research providers behind a unified interface for side-by-side comparison. All eval runs persist in research.* (mana_platform) so quality can be reviewed later. Providers (Phase 1+2): search: searxng, duckduckgo, brave, tavily, exa, serper extract: readability (via mana-search), jina-reader, firecrawl Endpoints: POST /v1/search, /v1/search/compare — single + fan-out POST /v1/extract, /v1/extract/compare — single + fan-out GET /v1/runs, /v1/runs/:id — history POST /v1/runs/:run/results/:id/rate — manual eval GET /v1/providers, /v1/providers/health — catalog + readiness Auto-routing: when `provider` is omitted, queries are classified via regex (fast path, 0ms) with optional mana-llm fallback, then routed to the first available provider for that query type (news → tavily, academic → exa, semantic → exa, etc.). Credits: server-key calls go through mana-credits reserve → commit/refund so failed provider calls don't charge the user. BYO-keys supported via research.provider_configs (UI arrives in Phase 4). Cache: Redis with graceful degradation (1h TTL for search, 24h for extract). Pay-per-use APIs only — no subscription-gated providers. Docs: docs/plans/mana-research-service.md + docs/reports/web-research-capabilities.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
68 lines
2 KiB
TypeScript
68 lines
2 KiB
TypeScript
/**
|
|
* Application configuration loaded from environment variables.
|
|
*/
|
|
|
|
export interface Config {
|
|
port: number;
|
|
databaseUrl: string;
|
|
redisUrl: string;
|
|
manaAuthUrl: string;
|
|
manaLlmUrl: string;
|
|
manaCreditsUrl: string;
|
|
manaSearchUrl: string;
|
|
serviceKey: string;
|
|
cors: { origins: string[] };
|
|
cacheTtlSeconds: number;
|
|
providerKeys: {
|
|
brave?: string;
|
|
tavily?: string;
|
|
exa?: string;
|
|
serper?: string;
|
|
perplexity?: string;
|
|
anthropic?: string;
|
|
openai?: string;
|
|
googleGenai?: string;
|
|
jina?: string;
|
|
firecrawl?: string;
|
|
scrapingbee?: string;
|
|
};
|
|
}
|
|
|
|
export function loadConfig(): Config {
|
|
const requiredEnv = (key: string, fallback?: string): string => {
|
|
const value = process.env[key] || fallback;
|
|
if (!value) throw new Error(`Missing required env var: ${key}`);
|
|
return value;
|
|
};
|
|
|
|
return {
|
|
port: parseInt(process.env.PORT || '3068', 10),
|
|
databaseUrl: requiredEnv(
|
|
'DATABASE_URL',
|
|
'postgresql://mana:devpassword@localhost:5432/mana_platform'
|
|
),
|
|
redisUrl: process.env.REDIS_URL || 'redis://localhost:6379',
|
|
manaAuthUrl: requiredEnv('MANA_AUTH_URL', 'http://localhost:3001'),
|
|
manaLlmUrl: requiredEnv('MANA_LLM_URL', 'http://localhost:3025'),
|
|
manaCreditsUrl: requiredEnv('MANA_CREDITS_URL', 'http://localhost:3061'),
|
|
manaSearchUrl: requiredEnv('MANA_SEARCH_URL', 'http://localhost:3021'),
|
|
serviceKey: requiredEnv('MANA_SERVICE_KEY', 'dev-service-key'),
|
|
cors: {
|
|
origins: (process.env.CORS_ORIGINS || 'http://localhost:5173').split(','),
|
|
},
|
|
cacheTtlSeconds: parseInt(process.env.CACHE_TTL_SECONDS || '3600', 10),
|
|
providerKeys: {
|
|
brave: process.env.BRAVE_API_KEY,
|
|
tavily: process.env.TAVILY_API_KEY,
|
|
exa: process.env.EXA_API_KEY,
|
|
serper: process.env.SERPER_API_KEY,
|
|
perplexity: process.env.PERPLEXITY_API_KEY,
|
|
anthropic: process.env.ANTHROPIC_API_KEY,
|
|
openai: process.env.OPENAI_API_KEY,
|
|
googleGenai: process.env.GOOGLE_GENAI_API_KEY,
|
|
jina: process.env.JINA_API_KEY,
|
|
firecrawl: process.env.FIRECRAWL_API_KEY,
|
|
scrapingbee: process.env.SCRAPINGBEE_API_KEY,
|
|
},
|
|
};
|
|
}
|