Skip to main content
Glama
config.ts3.44 kB
import { existsSync, readFileSync } from "node:fs"; import { join } from "node:path"; import { type Config, ConfigSchema, DEFAULT_CONFIG } from "./types"; const CONFIG_FILE = ".doclea/config.json"; // Service endpoints for auto-detection const QDRANT_DEFAULT_URL = "http://localhost:6333"; const TEI_DEFAULT_ENDPOINT = "http://localhost:8080"; const DETECTION_TIMEOUT_MS = 500; /** * Check if a service is running at the given URL * Uses a quick health check with short timeout */ async function isServiceRunning(url: string): Promise<boolean> { try { const controller = new AbortController(); const timeoutId = setTimeout( () => controller.abort(), DETECTION_TIMEOUT_MS, ); const response = await fetch(url, { method: "GET", signal: controller.signal, }); clearTimeout(timeoutId); return response.ok || response.status === 200; } catch { return false; } } /** * Auto-detect available backends and return optimized configuration * Priority: Docker services (if running) > Embedded backends (default) */ export async function detectConfig(): Promise<Config> { const [qdrantRunning, teiRunning] = await Promise.all([ isServiceRunning(`${QDRANT_DEFAULT_URL}/health`), isServiceRunning(`${TEI_DEFAULT_ENDPOINT}/health`), ]); const config: Config = { ...DEFAULT_CONFIG }; // Use Qdrant if running, otherwise sqlite-vec if (qdrantRunning) { config.vector = { provider: "qdrant", url: QDRANT_DEFAULT_URL, collectionName: "doclea-memories", }; } // Use TEI if running, otherwise transformers.js if (teiRunning) { config.embedding = { provider: "local", endpoint: TEI_DEFAULT_ENDPOINT, }; } return config; } /** * Load configuration from file or auto-detect * File config takes precedence over auto-detection */ export function loadConfig(projectPath: string = process.cwd()): Config { const configPath = join(projectPath, CONFIG_FILE); if (!existsSync(configPath)) { return DEFAULT_CONFIG; } try { const rawConfig = JSON.parse(readFileSync(configPath, "utf-8")); return ConfigSchema.parse(rawConfig); } catch (error) { if (error instanceof Error) { throw new Error( `Failed to load config from ${configPath}: ${error.message}`, ); } throw error; } } /** * Load configuration with auto-detection * 1. If config file exists, use it * 2. Otherwise, auto-detect available backends */ export async function loadConfigWithAutoDetect( projectPath: string = process.cwd(), ): Promise<Config> { const configPath = join(projectPath, CONFIG_FILE); // If config file exists, use it if (existsSync(configPath)) { try { const rawConfig = JSON.parse(readFileSync(configPath, "utf-8")); return ConfigSchema.parse(rawConfig); } catch (error) { if (error instanceof Error) { throw new Error( `Failed to load config from ${configPath}: ${error.message}`, ); } throw error; } } // Otherwise, auto-detect return detectConfig(); } export function getConfigPath(projectPath: string = process.cwd()): string { return join(projectPath, CONFIG_FILE); } export function getDbPath( config: Config, projectPath: string = process.cwd(), ): string { return join(projectPath, config.storage.dbPath); } export function getProjectPath(): string { return process.cwd(); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/docleaai/doclea-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server