Skip to main content
Glama
utils.tsβ€’6.72 kB
/** * Embedding Utilities * * Utility functions for working with embedding configuration and * environment variables. Provides convenient access to environment-based * configuration for the embedding system. * * @module embedding/utils */ import { env } from '../../env.js'; import { type OpenAIEmbeddingConfig } from './backend/types.js'; import { DEFAULTS } from './constants.js'; /** * Get embedding configuration from environment variables * * Uses the centralized env configuration to build embedding config. * Falls back to sensible defaults when environment variables are not set. * * @returns OpenAI embedding configuration or null if no API key * * @example * ```typescript * const config = getEmbeddingConfigFromEnv(); * if (config) { * const embedder = await createEmbedder(config); * } * ``` */ export function getEmbeddingConfigFromEnv(): OpenAIEmbeddingConfig | null { // Check if we have a required API key if (!env.OPENAI_API_KEY) { return null; } const config: OpenAIEmbeddingConfig = { type: 'openai', apiKey: env.OPENAI_API_KEY!, model: (env.EMBEDDING_MODEL as any) || DEFAULTS.OPENAI_MODEL, baseUrl: env.OPENAI_BASE_URL || DEFAULTS.OPENAI_BASE_URL, timeout: env.EMBEDDING_TIMEOUT || DEFAULTS.TIMEOUT, maxRetries: env.EMBEDDING_MAX_RETRIES || DEFAULTS.MAX_RETRIES, organization: env.OPENAI_ORG_ID || '', }; return config; } /** * Check if embedding configuration is available in environment * * @returns True if embedding can be configured from environment variables * * @example * ```typescript * if (isEmbeddingConfigAvailable()) { * const embedder = await createEmbedderFromEnv(); * } else { * console.log('Please set OPENAI_API_KEY environment variable'); * } * ``` */ export function isEmbeddingConfigAvailable(): boolean { return !!env.OPENAI_API_KEY; } /** * Get embedding configuration summary for logging/debugging * * Returns safe configuration info without exposing sensitive data. * * @returns Configuration summary object * * @example * ```typescript * const summary = getEmbeddingConfigSummary(); * console.log('Embedding config:', summary); * // Output: { hasApiKey: true, model: 'text-embedding-3-small', ... } * ``` */ export function getEmbeddingConfigSummary(): { hasApiKey: boolean; model?: string; baseUrl?: string; timeout?: number; maxRetries?: number; hasOrganization: boolean; } { return { hasApiKey: !!env.OPENAI_API_KEY, model: env.EMBEDDING_MODEL || DEFAULTS.OPENAI_MODEL, baseUrl: env.OPENAI_BASE_URL || DEFAULTS.OPENAI_BASE_URL, timeout: env.EMBEDDING_TIMEOUT || DEFAULTS.TIMEOUT, maxRetries: env.EMBEDDING_MAX_RETRIES || DEFAULTS.MAX_RETRIES, hasOrganization: !!env.OPENAI_ORG_ID, }; } /** * Validate that required environment variables are set for embeddings * * @returns Validation result with details * * @example * ```typescript * const validation = validateEmbeddingEnv(); * if (!validation.valid) { * console.error('Embedding setup issues:', validation.issues); * } * ``` */ export function validateEmbeddingEnv(): { valid: boolean; issues: string[]; } { const issues: string[] = []; // Check required variables if (!env.OPENAI_API_KEY) { // Check if other LLM providers are configured const hasOtherProviders = env.ANTHROPIC_API_KEY || env.OPENROUTER_API_KEY; if (hasOtherProviders) { issues.push( 'OPENAI_API_KEY is required for embedding functionality, even when using Anthropic or OpenRouter for LLM services' ); } else { issues.push('OPENAI_API_KEY is required for embedding functionality'); } } // Check API key format if (env.OPENAI_API_KEY && !env.OPENAI_API_KEY.startsWith('sk-')) { issues.push('OPENAI_API_KEY should start with "sk-"'); } // Check numeric values if (env.EMBEDDING_TIMEOUT && env.EMBEDDING_TIMEOUT <= 0) { issues.push('EMBEDDING_TIMEOUT must be a positive number'); } if (env.EMBEDDING_MAX_RETRIES && env.EMBEDDING_MAX_RETRIES < 0) { issues.push('EMBEDDING_MAX_RETRIES must be a non-negative number'); } // Check URL format if (env.OPENAI_BASE_URL) { try { new URL(env.OPENAI_BASE_URL); } catch { issues.push('OPENAI_BASE_URL must be a valid URL'); } } return { valid: issues.length === 0, issues, }; } /** * Check for mixed provider configuration and provide helpful guidance * * @returns Configuration analysis with recommendations * * @example * ```typescript * const analysis = analyzeProviderConfiguration(); * if (analysis.warnings.length > 0) { * console.warn('Configuration warnings:', analysis.warnings); * } * ``` */ export function analyzeProviderConfiguration(): { usingMixedProviders: boolean; llmProvider: 'openai' | 'anthropic' | 'openrouter' | 'none' | 'multiple'; embeddingProvider: 'openai' | 'none'; warnings: string[]; recommendations: string[]; } { const warnings: string[] = []; const recommendations: string[] = []; // Detect which LLM providers are configured const hasOpenAI = !!env.OPENAI_API_KEY; const hasAnthropic = !!env.ANTHROPIC_API_KEY; const hasOpenRouter = !!env.OPENROUTER_API_KEY; let llmProvider: 'openai' | 'anthropic' | 'openrouter' | 'none' | 'multiple'; const configuredProviders = [ hasOpenAI && 'openai', hasAnthropic && 'anthropic', hasOpenRouter && 'openrouter', ].filter(Boolean); if (configuredProviders.length === 0) { llmProvider = 'none'; warnings.push('No LLM provider API keys configured'); } else if (configuredProviders.length === 1) { llmProvider = configuredProviders[0] as 'openai' | 'anthropic' | 'openrouter'; } else { llmProvider = 'multiple'; recommendations.push( 'Multiple LLM provider API keys detected. The system will use the configured provider in your LLM service setup.' ); } // Embedding provider analysis const embeddingProvider = hasOpenAI ? 'openai' : 'none'; const usingMixedProviders = (hasAnthropic || hasOpenRouter) && hasOpenAI; // Generate specific warnings and recommendations if (!hasOpenAI && (hasAnthropic || hasOpenRouter)) { warnings.push('Embedding functionality will not work without OPENAI_API_KEY'); recommendations.push( 'Add OPENAI_API_KEY to enable embedding features, even when using Anthropic or OpenRouter for LLM' ); } if (usingMixedProviders) { recommendations.push( 'You are using a mixed provider setup (non-OpenAI for LLM + OpenAI for embeddings). This is a valid configuration.' ); } if (hasOpenAI && !hasAnthropic && !hasOpenRouter) { recommendations.push( 'Using OpenAI for both LLM and embeddings - this is the simplest configuration.' ); } return { usingMixedProviders, llmProvider, embeddingProvider, warnings, recommendations, }; }

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/campfirein/cipher'

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