crewai-ts
Version:
TypeScript port of crewAI for agent-based workflows
126 lines (125 loc) • 4.06 kB
JavaScript
/**
* OpenAI Embedder Implementation
*
* Optimized embedder using OpenAI's text embedding models
* with performance enhancements for production use
*/
import { BaseEmbedder } from './BaseEmbedder.js';
import OpenAI from 'openai';
/**
* OpenAI Embedder Implementation
*
* Uses OpenAI's powerful embedding models with optimized performance
*/
export class OpenAIEmbedder extends BaseEmbedder {
/**
* API key for OpenAI
*/
apiKey;
/**
* API URL
*/
apiUrl;
/**
* OpenAI Organization ID
*/
organization;
/**
* Request timeout
*/
timeout;
/**
* OpenAI client
*/
client = {};
/**
* Constructor for OpenAIEmbedder
*/
constructor(options = {}) {
// Set provider to OpenAI
super({
...options,
// Default model if not specified
model: options.model || 'text-embedding-ada-002',
// Dimensions based on model
dimensions: options.dimensions || 1536
});
// Get API key from options or environment
this.apiKey = options.apiKey || process.env.OPENAI_API_KEY || '';
if (!this.apiKey) {
throw new Error('OpenAI API key is required. Provide it in options or set OPENAI_API_KEY environment variable.');
}
// Set organization if provided
this.organization = options.organization || process.env.OPENAI_ORGANIZATION;
// Set API URL
this.apiUrl = options.apiUrl || 'https://api.openai.com/v1/embeddings';
// Set timeout
this.timeout = options.timeout || 30000;
// Initialize OpenAI client
this.client = new OpenAI({
apiKey: this.apiKey,
organization: this.organization,
baseURL: this.apiUrl,
timeout: this.timeout
});
}
/**
* Embed text using OpenAI's embedding API
* @param text Text to embed
* @returns Promise resolving to Float32Array of embeddings
*/
async embed(text) {
if (!this.client) {
throw new Error('OpenAI client not initialized');
}
try {
const response = await this.client.embeddings.create({
model: this.options.model || 'text-embedding-3-small',
input: text,
});
if (!response.data[0]?.embedding) {
throw new Error('Invalid response from OpenAI API');
}
return new Float32Array(response.data[0].embedding);
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to embed text: ${errorMessage}`);
}
}
/**
* Embed batch of texts using OpenAI's embedding API
* @param texts Texts to embed
* @returns Promise resolving to Float32Array[] of embeddings
*/
async embedBatch(texts) {
if (!this.client) {
throw new Error('OpenAI client not initialized');
}
try {
const response = await this.client.embeddings.create({
model: this.options.model || 'text-embedding-3-small',
input: texts,
});
if (!response.data) {
throw new Error('Invalid response from OpenAI API');
}
return response.data.map((d) => {
if (!d.embedding) {
throw new Error('Invalid embedding data');
}
return new Float32Array(d.embedding);
});
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
throw new Error(`Failed to embed batch: ${errorMessage}`);
}
}
async executeWithRetry(operation, maxRetries, initialBackoff, maxBackoff) {
return await operation();
}
async executeBatchWithRetry(operation, maxRetries, initialBackoff, maxBackoff) {
return await operation();
}
}