UNPKG

pulse-ai-utils

Version:

Utility functions and helpers for AI-powered applications

142 lines 5.48 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const openai_1 = __importDefault(require("openai")); const llm_base_1 = require("./llm-base"); const env_loader_1 = require("../config/env-loader"); const firebase_config_1 = require("../config/firebase-config"); /** * OpenAI Helper - Uses only OpenAI API and models * Supports: GPT-4, GPT-3.5, etc. */ class OpenAIHelper extends llm_base_1.LLMBase { constructor(apiKey, openaiInstance, model = 'gpt-4o') { const config = { model, apiKey: apiKey || (0, env_loader_1.getEnvVar)('OPENAI_API_KEY'), baseURL: 'https://api.openai.com/v1' }; super(config, openaiInstance); } /** * Create OpenAI helper with model from remote config * Falls back to env vars and defaults if remote config fails */ static async createWithRemoteConfig(apiKey, openaiInstance) { try { const remoteModel = await (0, firebase_config_1.getOpenAIModel)(); return new OpenAIHelper(apiKey, openaiInstance, remoteModel); } catch (error) { console.warn('Failed to fetch model from remote config, using defaults:', error); return new OpenAIHelper(apiKey, openaiInstance); } } /** * Update the model from remote config * Useful for long-running instances that need to pick up config changes */ async updateModelFromRemoteConfig() { try { const remoteModel = await (0, firebase_config_1.getOpenAIModel)(); this.defaultModel = remoteModel; } catch (error) { console.warn('Failed to update model from remote config:', error); } } createOpenAIInstance(config) { if (!config.apiKey) { config.apiKey = this.getApiKey(); } return new openai_1.default({ apiKey: config.apiKey, baseURL: config.baseURL }); } getApiKey() { if (this.isTestMode()) { return 'dummy-key-for-tests'; } const apiKey = (0, env_loader_1.getEnvVar)('OPENAI_API_KEY'); if (!apiKey) { throw new Error('OpenAI API key is required. Set OPENAI_API_KEY environment variable in your project root .env file.'); } // Additional validation for API key format if (apiKey.includes(' ') || apiKey.includes('\n') || apiKey.includes('\t')) { console.error('Invalid OpenAI API key format detected:', { length: apiKey.length, hasSpaces: apiKey.includes(' '), hasNewlines: apiKey.includes('\n'), hasTabs: apiKey.includes('\t'), first20chars: apiKey.substring(0, 20) }); throw new Error('OpenAI API key contains invalid characters (spaces, newlines, or tabs). Please check your Secret Manager configuration.'); } return apiKey; } getProviderName() { return 'openai'; } // OpenAI-specific methods can be added here async getAvailableModels() { if (this.isTestMode()) { return ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo']; } try { const models = await this.openai.models.list(); return models.data .filter(model => model.id.startsWith('gpt')) .map(model => model.id); } catch (error) { console.warn('Could not fetch OpenAI models:', error); return ['gpt-4o', 'gpt-4', 'gpt-3.5-turbo']; } } /** * Generate embedding using OpenAI's text-embedding models * This is used for vector search functionality */ async generateEmbedding(text, model = 'text-embedding-3-small') { if (this.isTestMode()) { // Return a mock embedding for tests return new Array(1536).fill(0).map(() => Math.random()); } try { const response = await this.openai.embeddings.create({ model: model, // 'text-embedding-3-small', 'text-embedding-3-large', or 'text-embedding-ada-002' input: text, }); return response.data[0].embedding; } catch (error) { console.error('Error generating embedding:', error); throw new Error(`Failed to generate embedding: ${error instanceof Error ? error.message : 'Unknown error'}`); } } /** * Generate embeddings for multiple texts in one request * More efficient for batch processing */ async generateEmbeddings(texts, model = 'text-embedding-3-small') { if (this.isTestMode()) { return texts.map(() => new Array(1536).fill(0).map(() => Math.random())); } try { const response = await this.openai.embeddings.create({ model: model, input: texts, }); return response.data.map(item => item.embedding); } catch (error) { console.error('Error generating embeddings:', error); throw new Error(`Failed to generate embeddings: ${error instanceof Error ? error.message : 'Unknown error'}`); } } } exports.default = OpenAIHelper; //# sourceMappingURL=openai-helper.js.map