
Security News
Ruby's Bundler 4.0.18 Extends Cooldown to bundle lock and bundle cache
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.
@memberjunction/ai
Advanced tools
MemberJunction: AI - core components for abstracting LLMs and other AI model types that are usable anywhere without ANY other MJ dependencies past @memberjunction/global which itself has zero additional dependencies.
Core abstractions and base classes for the MemberJunction AI Framework. This package defines provider-agnostic interfaces for Large Language Models, embeddings, image generation, audio, video, reranking, and more.
Zero MemberJunction dependencies beyond @memberjunction/global (which itself has no transitive dependencies). This package works in any TypeScript or JavaScript project -- no database, no metadata layer, no MJ runtime required.
npm install @memberjunction/ai
Every AI capability is represented by an abstract base class. Provider packages (OpenAI, Anthropic, Gemini, etc.) extend these to implement the actual API calls.
| Class | Purpose | Key Methods |
|---|---|---|
BaseLLM | Chat completions (text generation) | ChatCompletion(), ChatCompletions() (parallel batch) |
BaseEmbeddings | Text-to-vector embeddings | EmbedText(), EmbedTexts() |
BaseImageGenerator | Image generation, editing, variations | GenerateImage(), EditImage(), CreateVariation() |
BaseAudio | Text-to-speech and speech-to-text | TextToSpeech(), SpeechToText() |
BaseVideo | Video generation from text/images | GenerateVideo() |
BaseReranker | Document reranking for retrieval | Rerank() |
All inherit from BaseModel, which manages API key storage and provides the @RegisterClass integration point.
| Type | Description |
|---|---|
ChatParams | Full parameter set for chat requests: messages, model, temperature, topP, topK, streaming, effort level, response format, and more |
ChatResult | Completion result with choices, token usage, cost tracking, and timing |
ChatMessage | Single message with role, content (text or multimodal blocks), and optional metadata |
ChatMessageContentBlock | Multimodal content: text, image (base64/URL), video, audio, or file |
StreamingChatCallbacks | Callbacks for real-time streaming: OnContent, OnComplete, OnError |
ParallelChatCompletionsCallbacks | Callbacks for batch parallel completions |
ChatMessageRole | Enum: system, user, assistant |
| Type | Description |
|---|---|
EmbedTextParams / EmbedTextResult | Single text embedding request and response |
EmbedTextsParams / EmbedTextsResult | Batch text embedding request and response |
| Type | Description |
|---|---|
ImageGenerationParams / ImageGenerationResult | Image generation parameters and results |
SummarizeParams / SummarizeResult | Text summarization |
ClassifyParams / ClassifyResult | Text classification |
RerankParams / RerankResult | Document reranking |
ModelUsage | Token counts and cost tracking (prompt tokens, completion tokens, total cost, currency) |
BaseResult | Common result base with success flag, timing, and error info |
| Export | Description |
|---|---|
AIAPIKeys / GetAIAPIKey() | API key resolution from environment variables (AI_VENDOR_API_KEY__<DRIVER>) with optional runtime overrides |
ErrorAnalyzer | Classifies provider errors into structured types with severity, retry hints, and failover recommendations |
AIErrorInfo / AIErrorType | Structured error types: rate limit, authentication, context length, content filter, etc. |
serializeMessageContent() / deserializeMessageContent() | Content block serialization for database storage |
parseBase64DataUrl() / createBase64DataUrl() | Base64 data URL utilities |
import { ChatParams, ChatMessageRole } from "@memberjunction/ai";
import { OpenAILLM } from "@memberjunction/ai-openai";
const llm = new OpenAILLM("your-api-key");
const result = await llm.ChatCompletion({
model: "gpt-4.1",
messages: [
{ role: ChatMessageRole.system, content: "You are a helpful assistant." },
{ role: ChatMessageRole.user, content: "What is the capital of France?" },
],
temperature: 0.7,
maxOutputTokens: 500,
});
console.log(result.data.choices[0].message.content);
await llm.ChatCompletion({
model: "gpt-4.1",
messages: [{ role: ChatMessageRole.user, content: "Explain quantum computing." }],
streaming: true,
streamingCallbacks: {
OnContent: (chunk, isComplete) => process.stdout.write(chunk),
OnComplete: (result) => console.log("\nDone!"),
OnError: (error) => console.error("Stream error:", error),
},
});
const paramSets = [
{ ...base, temperature: 0.3 },
{ ...base, temperature: 0.7 },
{ ...base, temperature: 1.0 },
];
const results = await llm.ChatCompletions(paramSets, {
OnCompletion: (result, index) => console.log(`Completion ${index} done`),
OnAllCompleted: (results) => console.log(`All ${results.length} complete`),
});
const result = await llm.ChatCompletion({
model: "gpt-4.1",
messages: [{
role: ChatMessageRole.user,
content: [
{ type: "text", content: "What is in this image?" },
{ type: "image_url", content: "data:image/png;base64,..." },
],
}],
});
import { OpenAIEmbedding } from "@memberjunction/ai-openai";
const embedder = new OpenAIEmbedding("your-api-key");
const result = await embedder.EmbedText({
model: "text-embedding-3-small",
text: "Sample text to embed",
});
console.log(`Dimensions: ${result.vector.length}`);
import { GetAIAPIKey } from "@memberjunction/ai";
// Reads AI_VENDOR_API_KEY__OPENAILLM from environment
const key = GetAIAPIKey("OpenAILLM");
// With runtime override
const key2 = GetAIAPIKey("AnthropicLLM", [
{ driverClass: "AnthropicLLM", apiKey: "sk-ant-..." },
]);
Extend the base class for the capability you want to support:
import { BaseLLM, ChatParams, ChatResult, ClassifyParams, ClassifyResult, SummarizeParams, SummarizeResult } from "@memberjunction/ai";
import { RegisterClass } from "@memberjunction/global";
@RegisterClass(BaseLLM, "MyProviderLLM")
export class MyProviderLLM extends BaseLLM {
// Required: implement non-streaming chat
protected async nonStreamingChatCompletion(params: ChatParams): Promise<ChatResult> {
// Your API call here
}
// Optional: implement text classification
public async ClassifyText(params: ClassifyParams): Promise<ClassifyResult> { /* ... */ }
// Optional: implement summarization
public async SummarizeText(params: SummarizeParams): Promise<SummarizeResult> { /* ... */ }
// Optional: enable streaming by overriding these
public get SupportsStreaming(): boolean { return true; }
protected async createStreamingRequest(params: ChatParams): Promise<AsyncIterable<unknown>> { /* ... */ }
protected processStreamingChunk(chunk: unknown): { content: string } { /* ... */ }
protected finalizeStreamingResponse(content: string, lastChunk: unknown, usage: unknown): ChatResult { /* ... */ }
}
See the full provider list for working examples across 25+ implementations.
| Package | Purpose |
|---|---|
@memberjunction/global | Class factory and global utilities (zero transitive dependencies) |
dotenv | Environment variable loading |
rxjs | Reactive extensions (internal use) |
FAQs
MemberJunction: AI - core components for abstracting LLMs and other AI model types that are usable anywhere without ANY other MJ dependencies past @memberjunction/global which itself has zero additional dependencies.
The npm package @memberjunction/ai receives a total of 3,226 weekly downloads. As such, @memberjunction/ai popularity was classified as popular.
We found that @memberjunction/ai demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 11 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.