pulse-ai-utils
Version:
Utility functions and helpers for AI-powered applications
142 lines • 5.48 kB
JavaScript
;
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