The MemberJunction AI Vectors Core package provides the foundational abstractions and base classes for working with vector embeddings, vector databases, and vector operations within the MemberJunction ecosystem.
This package serves as the core foundation for vector-related operations in MemberJunction, providing:
npm install @memberjunction/ai-vectors
The package defines several key interfaces for vector operations:
Interface for text embedding generation:
interface IEmbedding {
createEmbedding(text: string, options?: any): any;
createBatchEmbedding(text: string[], options?: any): any;
}
Interface for vector database management:
interface IVectorDatabase {
listIndexes(options?: any): any;
createIndex(options: any): any;
deleteIndex(indexID: any, options?: any): any;
editIndex(indexID: any, options?: any): any;
}
Interface for vector index operations:
interface IVectorIndex {
createRecord(record: any, options?: any): any;
createRecords(records: any[], options?: any): any;
getRecord(recordID: any, options?: any): any;
getRecords(recordIDs: any[], options?: any): any;
updateRecord(record: any, options?: any): any;
updateRecords(records: any[], options?: any): any;
deleteRecord(recordID: any, options?: any): any;
deleteRecords(recordIDs: any[], options?: any): any;
}
The VectorBase class serves as the foundation for vector operations, providing:
GetRecordsByEntityID(entityID: string, recordIDs?: CompositeKey[]): Promise<BaseEntity[]> - Retrieve entity records with optional filteringPageRecordsByEntityID<T>(params: PageRecordsParams): Promise<T[]> - Paginated entity record retrievalGetAIModel(id?: string): AIModelEntityExtended - Access configured embedding modelsGetVectorDatabase(id?: string): VectorDatabaseEntity - Access configured vector databasesRunViewForSingleValue<T>(entityName: string, extraFilter: string): Promise<T | null> - Query for single entity recordsSaveEntity(entity: BaseEntity): Promise<boolean> - Save entities with proper user contextType definition for paginated record retrieval:
type PageRecordsParams = {
EntityID: string | number; // The ID of the entity to get records from
PageNumber: number; // Page number (1-based)
PageSize: number; // Number of records per page
ResultType: "entity_object" | "simple" | "count_only"; // Type of result
Filter?: string; // Optional SQL filter
}
Create specialized vector operation classes by extending VectorBase:
import { VectorBase, PageRecordsParams } from '@memberjunction/ai-vectors';
import { BaseEntity } from '@memberjunction/core';
export class MyVectorProcessor extends VectorBase {
async processEntityRecords(entityId: string): Promise<void> {
// Get all entity records
const records = await this.GetRecordsByEntityID(entityId);
// Process each record
for (const record of records) {
// Your vector processing logic here
console.log(`Processing ${record.EntityInfo.Name} record ${record.ID}`);
}
}
async paginatedProcess(entityId: string): Promise<void> {
// Process records page by page
const params: PageRecordsParams = {
EntityID: entityId,
PageNumber: 1,
PageSize: 100,
ResultType: 'entity_object' as const
};
const records = await this.PageRecordsByEntityID<BaseEntity>(params);
// Process paged records
console.log(`Retrieved ${records.length} records`);
}
}
Implement the interfaces to create specific provider implementations:
import { IEmbedding } from '@memberjunction/ai-vectors';
export class OpenAIEmbedding implements IEmbedding {
constructor(private apiKey: string) {}
async createEmbedding(text: string): Promise<number[]> {
// Implementation using OpenAI's embedding API
}
async createBatchEmbedding(texts: string[]): Promise<number[][]> {
// Batch implementation
}
}
The package provides utilities for working with MemberJunction entities:
import { VectorBase, PageRecordsParams } from '@memberjunction/ai-vectors';
import { BaseEntity } from '@memberjunction/core';
import { AIModelEntityExtended, VectorDatabaseEntity } from '@memberjunction/core-entities';
class EntityVectorizer extends VectorBase {
async vectorizeEntities(entityId: string): Promise<void> {
// Get AI model for embeddings (defaults to first embedding model if no ID provided)
const embeddingModel: AIModelEntityExtended = this.GetAIModel();
console.log(`Using embedding model: ${embeddingModel.Name}`);
// Get vector database (defaults to first configured vector DB)
const vectorDb: VectorDatabaseEntity = this.GetVectorDatabase();
console.log(`Using vector database: ${vectorDb.Name}`);
// Process records in pages for memory efficiency
let pageNumber = 1;
let hasMoreRecords = true;
while (hasMoreRecords) {
const params: PageRecordsParams = {
EntityID: entityId,
PageNumber: pageNumber,
PageSize: 50,
ResultType: 'entity_object' as const,
Filter: "IsActive = 1" // Optional: add custom filtering
};
const records = await this.PageRecordsByEntityID<BaseEntity>(params);
hasMoreRecords = records.length === params.PageSize;
pageNumber++;
// Process the current page of records
for (const record of records) {
// Your vectorization logic here
// Example: Generate embeddings for record content
}
}
}
async saveVectorizedEntity(entity: BaseEntity): Promise<boolean> {
// SaveEntity automatically adds user context
return await this.SaveEntity(entity);
}
}
Use composite keys for complex filtering scenarios:
import { VectorBase } from '@memberjunction/ai-vectors';
import { CompositeKey } from '@memberjunction/core';
class AdvancedVectorProcessor extends VectorBase {
async getSpecificRecords(entityId: string): Promise<void> {
// Build composite keys for specific records
const compositeKeys: CompositeKey[] = [
{
KeyValuePairs: [
{ FieldName: 'Status', Value: 'Active' },
{ FieldName: 'CategoryID', Value: '123' }
]
},
{
KeyValuePairs: [
{ FieldName: 'Status', Value: 'Pending' },
{ FieldName: 'CategoryID', Value: '456' }
]
}
];
// This will generate: (Status = 'Active' AND CategoryID = '123') OR (Status = 'Pending' AND CategoryID = '456')
const records = await this.GetRecordsByEntityID(entityId, compositeKeys);
console.log(`Found ${records.length} matching records`);
}
}
This package works in harmony with other MemberJunction packages:
import { VectorBase } from '@memberjunction/ai-vectors';
import { AIEngine } from '@memberjunction/aiengine';
import { Metadata, RunView } from '@memberjunction/core';
// Your vector processing will have access to:
// - Entity metadata
// - AI models configuration
// - Vector database configuration
// - User context
This core package serves as the foundation for a suite of vector-related packages:
@memberjunction/ai-vectors - Core abstractions (this package)@memberjunction/ai-vectordb - Vector database interface@memberjunction/ai-vectors-memory - In-memory vector similarity search@memberjunction/ai-vectors-sync - Entity synchronization with vector databases@memberjunction/ai-vectors-pinecone - Pinecone vector database implementation@memberjunction/ai-vectors-dupe - Duplicate detection using vector similarityThe package automatically integrates with MemberJunction's configuration system:
AIEngine.InstancePageRecordsByEntityID, specify the expected typeThe package provides clear error messages for common scenarios:
try {
const model = this.GetAIModel('specific-model-id');
} catch (error) {
// Will throw if no embedding model is configured
console.error('No AI Model Entity found');
}
try {
const records = await this.GetRecordsByEntityID('invalid-id');
} catch (error) {
// Will throw if entity ID doesn't exist
console.error(`Entity with ID invalid-id not found.`);
}
@memberjunction/core: ^2.43.0 - Core MemberJunction functionality@memberjunction/global: ^2.43.0 - Global utilities@memberjunction/core-entities: ^2.43.0 - Entity definitions@memberjunction/aiengine: ^2.43.0 - AI engine integration@memberjunction/ai: ^2.43.0 - AI abstractions@memberjunction/ai-vectordb: ^2.43.0 - Vector database interfacesopenai: ^4.28.4 - OpenAI SDK (for embedding implementations)dotenv: ^16.4.1 - Environment configurationnpm run build
npm run start
When contributing to this package:
ISC