@memberjunction/ai 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +242 -0
  2. package/package.json +2 -2
  3. package/readme.md +167 -967
package/readme.md CHANGED
@@ -1,1042 +1,242 @@
1
1
  # @memberjunction/ai
2
2
 
3
- The MemberJunction AI Core package provides a comprehensive abstraction layer for working with various AI models (LLMs, Video and Audio Generation, Text-To-Speech (TTS), embedding models, etc.) in a provider-agnostic way, allowing your application to easily switch between different AI providers without refactoring your code.
3
+ Core abstractions and base classes for the MemberJunction AI Framework. This package defines provider-agnostic interfaces for Large Language Models (LLMs), embeddings, image generation, audio, video, reranking, and more. It has **zero MemberJunction dependencies** beyond `@memberjunction/global`, making it suitable for standalone use in any TypeScript/JavaScript project.
4
4
 
5
- ## Overview
5
+ ## Architecture
6
6
 
7
- This package serves as the foundation for all AI capabilities in the MemberJunction ecosystem. It defines abstract base classes and interfaces that are implemented by provider-specific packages, enabling seamless integration with various AI services while maintaining a consistent API.
7
+ ```mermaid
8
+ graph TD
9
+ subgraph "@memberjunction/ai"
10
+ BM["BaseModel"]
11
+ style BM fill:#2d6a9f,stroke:#1a4971,color:#fff
8
12
 
9
- ### Type Organization Update (2025)
13
+ BLLM["BaseLLM"]
14
+ style BLLM fill:#2d6a9f,stroke:#1a4971,color:#fff
10
15
 
11
- As part of a major type reorganization to improve code organization and reduce circular dependencies:
12
- - **Core Package** now contains:
13
- - Base AI model abstractions (`BaseModel`, `BaseLLM`, `BaseEmbeddings`, etc.)
14
- - Core AI result types (`BaseResult`, `ChatResult`, `ModelUsage`, etc.)
15
- - Common interfaces and types used across all AI packages
16
- - **Agent-specific types** have moved to `@memberjunction/ai-agents`
17
- - **Prompt-specific types** remain in `@memberjunction/ai-prompts`
18
- - **Engine-specific types** (like agent type definitions) are in `@memberjunction/aiengine`
16
+ BE["BaseEmbeddings"]
17
+ style BE fill:#2d6a9f,stroke:#1a4971,color:#fff
19
18
 
20
- ## Standalone Usage
19
+ BIG["BaseImageGenerator"]
20
+ style BIG fill:#2d6a9f,stroke:#1a4971,color:#fff
21
21
 
22
- **IMPORTANT**: This package can be used completely independently from the rest of the MemberJunction framework:
22
+ BA["BaseAudio"]
23
+ style BA fill:#2d6a9f,stroke:#1a4971,color:#fff
23
24
 
24
- - **Zero** database setup required
25
- - No environment variables or other settings expected (you are responsible for this and pass in API keys to the constructors)
26
- - Works in any TypeScript environment that can safely make API calls (e.g. don't use in browsers)
27
- - Perfect for server-side applications, backend services, and CLI tools
25
+ BV["BaseVideo"]
26
+ style BV fill:#2d6a9f,stroke:#1a4971,color:#fff
28
27
 
29
- The `@memberjunction/ai` package and all provider packages in `@memberjunction/ai-*` are designed to be lightweight, standalone modules that can be used in any TypeScript project.
28
+ BR["BaseReranker"]
29
+ style BR fill:#2d6a9f,stroke:#1a4971,color:#fff
30
30
 
31
- ## Features
31
+ CT["Chat Types"]
32
+ style CT fill:#7c5295,stroke:#563a6b,color:#fff
32
33
 
33
- - **Provider Abstraction**: Work with AI models without tightly coupling to specific vendor APIs
34
- - **Runtime Optionality**: Switch between AI providers at runtime based on configuration
35
- - **Base Classes**: Abstract base classes for different AI model types (LLMs, embedding models, audio, video, etc.)
36
- - **Standard Interfaces**: Consistent interfaces for common AI operations like chat, summarization, and classification
37
- - **Streaming Support**: Stream responses from supported LLM providers for real-time UIs
38
- - **Parallel Processing**: Execute multiple chat completions in parallel with progress callbacks
39
- - **Multi-modal Support**: Handle text, images, videos, audio, and files in chat messages
40
- - **Type Definitions**: Comprehensive TypeScript type definitions for all AI operations
41
- - **Error Handling**: Standardized error handling and reporting across all providers
42
- - **Token Usage Tracking**: Consistent tracking of token usage across providers
43
- - **Response Format Control**: Specify output formats (Text, Markdown, JSON, or provider-specific)
44
- - **Additional Settings**: Provider-specific configuration through a flexible settings system
34
+ ET["Embed Types"]
35
+ style ET fill:#7c5295,stroke:#563a6b,color:#fff
45
36
 
46
- ## Installation
47
-
48
- ```bash
49
- npm install @memberjunction/ai
50
- ```
51
-
52
- Then install one or more provider packages:
53
-
54
- ```bash
55
- npm install @memberjunction/ai-openai
56
- npm install @memberjunction/ai-anthropic
57
- npm install @memberjunction/ai-mistral
58
- # etc.
59
- ```
37
+ ERR["ErrorAnalyzer"]
38
+ style ERR fill:#b8762f,stroke:#8a5722,color:#fff
60
39
 
61
- ## Usage
62
-
63
- ### Provider-Agnostic Usage (Recommended)
64
-
65
- For maximum flexibility, use the class factory approach to select the provider at runtime:
66
-
67
- ```typescript
68
- import { BaseLLM, ChatParams } from '@memberjunction/ai';
69
- import { MJGlobal } from '@memberjunction/global';
40
+ AK["AIAPIKeys"]
41
+ style AK fill:#2d8659,stroke:#1a5c3a,color:#fff
70
42
 
71
- // Required to stop tree-shaking of the MistralLLM - since there's no static code path to this class when using Class Factory pattern, you need this to prevent some bundlers from tree-shaking optimization on this class.
72
- import { LoadMistralLLM } from '@memberjunction/ai-mistral';
73
- LoadMistralLLM();
43
+ BM --> BLLM
44
+ BM --> BE
45
+ BM --> BIG
46
+ BM --> BA
47
+ BM --> BV
48
+ BM --> BR
49
+ end
74
50
 
75
- // Get an implementation of BaseLLM by provider name
76
- const llm = MJGlobal.Instance.ClassFactory.CreateInstance<BaseLLM>(
77
- BaseLLM,
78
- 'MistralLLM', // Provider class name
79
- 'your-api-key'
80
- );
51
+ P1["OpenAI Provider"]
52
+ style P1 fill:#2d8659,stroke:#1a5c3a,color:#fff
53
+ P2["Anthropic Provider"]
54
+ style P2 fill:#2d8659,stroke:#1a5c3a,color:#fff
55
+ P3["Other Providers"]
56
+ style P3 fill:#2d8659,stroke:#1a5c3a,color:#fff
81
57
 
82
- // Use the abstracted interface
83
- const params: ChatParams = {
84
- model: 'mistral-large-latest',
85
- messages: [
86
- { role: 'system', content: 'You are a helpful assistant.' },
87
- { role: 'user', content: 'What is AI abstraction?' }
88
- ]
89
- };
90
-
91
- const result = await llm.ChatCompletion(params);
58
+ BLLM --> P1
59
+ BLLM --> P2
60
+ BLLM --> P3
92
61
  ```
93
62
 
94
- ### Environment-Based Provider Selection
95
-
96
- Use environment variables or configuration to select the provider:
97
-
98
- ```typescript
99
- import { BaseLLM } from '@memberjunction/ai';
100
- import { MJGlobal } from '@memberjunction/global';
101
- import dotenv from 'dotenv';
102
-
103
- // Required to stop tree-shaking of the OpenAILLM - since there's no static code path to this class when using Class Factory pattern, you need this to prevent some bundlers from tree-shaking optimization on this class.
104
- import { LoadOpenAILLM } from '@memberjunction/ai-openai';
105
- LoadOpenAILLM();
106
-
107
- dotenv.config();
108
-
109
- const providerName = process.env.AI_PROVIDER || 'OpenAILLM';
110
- const apiKey = process.env.AI_API_KEY;
63
+ ## Installation
111
64
 
112
- const llm = MJGlobal.Instance.ClassFactory.CreateInstance<BaseLLM>(
113
- BaseLLM,
114
- providerName,
115
- apiKey
116
- );
65
+ ```bash
66
+ npm install @memberjunction/ai
117
67
  ```
118
68
 
119
- ### Direct Provider Usage
69
+ ## Key Exports
70
+
71
+ ### Base Classes
72
+
73
+ | Class | Purpose |
74
+ |---|---|
75
+ | `BaseModel` | Root base class for all AI model types; manages API key storage |
76
+ | `BaseLLM` | Abstract base for chat completion providers with streaming, parallel execution, and thinking model support |
77
+ | `BaseEmbeddings` | Abstract base for text embedding providers |
78
+ | `BaseImageGenerator` | Abstract base for image generation, editing, and variation providers |
79
+ | `BaseAudio` | Abstract base for text-to-speech and speech-to-text providers |
80
+ | `BaseVideo` | Abstract base for video generation providers |
81
+ | `BaseReranker` | Abstract base for document reranking providers |
82
+
83
+ ### Type Definitions
84
+
85
+ | Type / Class | Purpose |
86
+ |---|---|
87
+ | `ChatParams` | Parameters for chat completion requests (messages, streaming, sampling controls) |
88
+ | `ChatResult` | Result of a chat completion including choices, usage, and cache info |
89
+ | `ChatMessage` | Individual message with role, content (text or multimodal blocks), and optional metadata |
90
+ | `ChatMessageContentBlock` | Multimodal content block (text, image, video, audio, file) |
91
+ | `StreamingChatCallbacks` | Callbacks for real-time streaming responses |
92
+ | `ParallelChatCompletionsCallbacks` | Callbacks for batch parallel completions |
93
+ | `EmbedTextParams` / `EmbedTextResult` | Parameters and results for single text embedding |
94
+ | `EmbedTextsParams` / `EmbedTextsResult` | Parameters and results for batch text embeddings |
95
+ | `ImageGenerationParams` / `ImageGenerationResult` | Image generation parameters and results |
96
+ | `SummarizeParams` / `SummarizeResult` | Text summarization parameters and results |
97
+ | `ClassifyParams` / `ClassifyResult` | Text classification parameters and results |
98
+ | `RerankParams` / `RerankResult` | Document reranking parameters and results |
99
+
100
+ ### Utilities
101
+
102
+ | Export | Purpose |
103
+ |---|---|
104
+ | `BaseResult` | Common result base with success flag, timing, and error info |
105
+ | `ModelUsage` | Token usage and cost tracking (prompt tokens, completion tokens, cost, currency) |
106
+ | `AIAPIKeys` | API key management via environment variables (`AI_VENDOR_API_KEY__<DRIVER>`) |
107
+ | `GetAIAPIKey()` | Helper to resolve API keys with optional runtime overrides |
108
+ | `ErrorAnalyzer` | Standardized error analysis across all providers with severity and failover hints |
109
+ | `AIErrorInfo` / `AIErrorType` | Structured error types (rate limit, authentication, context length, etc.) |
110
+ | `serializeMessageContent()` / `deserializeMessageContent()` | Content block serialization for database storage |
111
+ | `parseBase64DataUrl()` / `createBase64DataUrl()` | Base64 data URL utilities |
120
112
 
121
- When necessary, you can directly use a specific AI provider:
113
+ ## Usage
114
+
115
+ ### Basic Chat Completion
122
116
 
123
117
  ```typescript
118
+ import { ChatParams, ChatMessageRole } from '@memberjunction/ai';
124
119
  import { OpenAILLM } from '@memberjunction/ai-openai';
125
120
 
126
- // Note with direct use of the OpenAILLM class no need for the LoadOpenAILLM call to prevent tree shaking since there is a static code path to the class
127
- // Create an instance with your API key
128
- const llm = new OpenAILLM('your-openai-api-key');
121
+ const llm = new OpenAILLM('your-api-key');
129
122
 
130
- // Use the provider-specific implementation
131
- const result = await llm.ChatCompletion({
132
- model: 'gpt-4',
133
- messages: [
134
- { role: 'system', content: 'You are a helpful assistant.' },
135
- { role: 'user', content: 'What is AI abstraction?' }
136
- ]
137
- });
123
+ const params = new ChatParams();
124
+ params.model = 'gpt-4';
125
+ params.messages = [
126
+ { role: ChatMessageRole.user, content: 'What is the capital of France?' }
127
+ ];
138
128
 
129
+ const result = await llm.ChatCompletion(params);
139
130
  console.log(result.data.choices[0].message.content);
140
131
  ```
141
132
 
142
- ## Core Abstractions
143
-
144
- ### Base Models
145
-
146
- #### BaseModel
147
- The foundational abstract class for all AI models. Provides:
148
- - Protected API key management
149
- - Base parameter and result types
150
- - Model usage tracking
151
-
152
- #### BaseLLM
153
- Abstract class for text generation models. Features:
154
- - Standard and streaming chat completions
155
- - Parallel chat completions with callbacks
156
- - Text summarization
157
- - Text classification
158
- - Additional provider-specific settings management
159
- - Response format control (Any, Text, Markdown, JSON, ModelSpecific)
160
- - Support for reasoning budget tokens (for reasoning models)
161
- - Advanced sampling parameters (see [Parameter Reference](#parameter-reference) below)
162
-
163
- #### BaseEmbeddings
164
- Abstract class for text embedding models. Provides:
165
- - Single text embedding generation
166
- - Batch text embedding generation
167
- - Model listing capabilities
168
- - Additional settings management
169
-
170
- #### BaseAudioGenerator
171
- Abstract class for audio processing models. Supports:
172
- - Text-to-speech generation
173
- - Speech-to-text transcription
174
- - Voice listing and management
175
- - Model and pronunciation dictionary queries
176
- - Configurable voice settings (stability, similarity, speed, etc.)
177
-
178
- #### BaseVideoGenerator
179
- Abstract class for video generation models. Enables:
180
- - Avatar-based video creation
181
- - Video translation capabilities
182
- - Avatar management and listing
183
-
184
- #### BaseDiffusion
185
- Abstract class for image generation models (placeholder for future implementation)
186
-
187
- ## LLM Operations
188
-
189
- ### Standard Chat Completion
190
-
191
- For interactive conversations with AI models:
192
-
193
- ```typescript
194
- import { ChatParams, ChatResult, ChatMessage } from '@memberjunction/ai';
195
-
196
- const params: ChatParams = {
197
- model: 'your-model-name',
198
- messages: [
199
- { role: 'system', content: 'System instruction' },
200
- { role: 'user', content: 'User message' },
201
- { role: 'assistant', content: 'Assistant response' }
202
- ],
203
- temperature: 0.7,
204
- maxOutputTokens: 1000
205
- };
206
-
207
- const result: ChatResult = await llm.ChatCompletion(params);
208
- ```
209
-
210
133
  ### Streaming Chat Completion
211
134
 
212
- For real-time streaming of responses:
213
-
214
135
  ```typescript
215
- import { ChatParams, ChatResult, ChatMessage, StreamingChatCallbacks } from '@memberjunction/ai';
216
-
217
- // Define the streaming callbacks
218
- const callbacks: StreamingChatCallbacks = {
219
- // Called when a new chunk arrives
220
- OnContent: (chunk: string, isComplete: boolean) => {
221
- if (isComplete) {
222
- console.log("\nStream completed!");
223
- } else {
224
- // Print chunks as they arrive (or add to UI)
225
- process.stdout.write(chunk);
226
- }
227
- },
228
-
229
- // Called when the complete response is available
230
- OnComplete: (finalResponse: ChatResult) => {
231
- console.log("\nFull response:", finalResponse.data.choices[0].message.content);
232
- console.log("Total tokens:", finalResponse.data.usage.totalTokens);
233
- },
234
-
235
- // Called if an error occurs during streaming
236
- OnError: (error: any) => {
237
- console.error("Streaming error:", error);
238
- }
239
- };
240
-
241
- // Create streaming chat parameters
242
- const params: ChatParams = {
243
- model: 'gpt-4',
244
- messages: [
245
- { role: 'system', content: 'You are a helpful assistant.' },
246
- { role: 'user', content: 'Write a short poem about AI, one line at a time.' }
247
- ],
248
- streaming: true, // Enable streaming
249
- streamingCallbacks: callbacks
136
+ const params = new ChatParams();
137
+ params.model = 'gpt-4';
138
+ params.streaming = true;
139
+ params.messages = [
140
+ { role: ChatMessageRole.user, content: 'Explain quantum computing' }
141
+ ];
142
+ params.streamingCallbacks = {
143
+ OnContent: (chunk, isComplete) => process.stdout.write(chunk),
144
+ OnComplete: (result) => console.log('\nDone!'),
145
+ OnError: (error) => console.error('Stream error:', error)
250
146
  };
251
147
 
252
- // The ChatCompletion API remains the same, but will stream results
253
148
  await llm.ChatCompletion(params);
254
149
  ```
255
150
 
256
- ### Cancellable Operations with AbortSignal
257
-
258
- The MemberJunction AI Core package supports cancellation of long-running operations using the standard JavaScript `AbortSignal` pattern. This provides a clean, standardized way to cancel AI operations when needed.
259
-
260
- #### Understanding the AbortSignal Pattern
261
-
262
- The `AbortSignal` pattern uses a **separation of concerns** approach:
263
-
264
- - **Controller (Caller)**: Creates the `AbortController` and decides **when** to cancel
265
- - **Worker (AI Operations)**: Receives the `AbortSignal` token and handles **how** to cancel
266
-
267
- #### Basic Cancellation Example
268
-
269
- ```typescript
270
- import { ChatParams, BaseLLM } from '@memberjunction/ai';
271
-
272
- async function cancellableAIChat() {
273
- // Create the cancellation controller (the "boss")
274
- const controller = new AbortController();
275
-
276
- // Set up automatic timeout cancellation
277
- const timeout = setTimeout(() => {
278
- controller.abort(); // Cancel after 30 seconds
279
- }, 30000);
280
-
281
- try {
282
- const params: ChatParams = {
283
- model: 'gpt-4',
284
- messages: [
285
- { role: 'user', content: 'Write a very long story...' }
286
- ],
287
- cancellationToken: controller.signal // Pass the signal token
288
- };
289
-
290
- const result = await llm.ChatCompletion(params);
291
- clearTimeout(timeout); // Clear timeout if completed successfully
292
- return result;
293
-
294
- } catch (error) {
295
- if (error.message.includes('cancelled')) {
296
- console.log('Operation was cancelled');
297
- } else {
298
- console.error('Operation failed:', error);
299
- }
300
- }
301
- }
302
- ```
303
-
304
- #### User-Initiated Cancellation
305
-
306
- Perfect for UI applications where users can cancel operations:
307
-
308
- ```typescript
309
- class AIInterface {
310
- private currentController: AbortController | null = null;
311
-
312
- async startAIConversation() {
313
- // Create new controller for this conversation
314
- this.currentController = new AbortController();
315
-
316
- try {
317
- const result = await llm.ChatCompletion({
318
- model: 'gpt-4',
319
- messages: [{ role: 'user', content: 'Generate a detailed report...' }],
320
- cancellationToken: this.currentController.signal
321
- });
322
-
323
- console.log('AI Response:', result.data.choices[0].message.content);
324
- } catch (error) {
325
- if (error.message.includes('cancelled')) {
326
- console.log('User cancelled the conversation');
327
- }
328
- } finally {
329
- this.currentController = null;
330
- }
331
- }
332
-
333
- // Called when user clicks "Cancel" button
334
- cancelConversation() {
335
- if (this.currentController) {
336
- this.currentController.abort(); // Instant cancellation
337
- }
338
- }
339
- }
340
- ```
341
-
342
- #### Multiple Cancellation Sources
343
-
344
- One signal can be cancelled from multiple sources:
345
-
346
- ```typescript
347
- async function smartAIExecution() {
348
- const controller = new AbortController();
349
- const signal = controller.signal;
350
-
351
- // 1. User cancel button
352
- document.getElementById('cancel')?.addEventListener('click', () => {
353
- controller.abort(); // User cancellation
354
- });
355
-
356
- // 2. Resource limit cancellation
357
- if (await checkMemoryUsage() > MAX_MEMORY) {
358
- controller.abort(); // Resource limit cancellation
359
- }
360
-
361
- // 3. Window unload cancellation
362
- window.addEventListener('beforeunload', () => {
363
- controller.abort(); // Page closing cancellation
364
- });
365
-
366
- // 4. Timeout cancellation
367
- setTimeout(() => controller.abort(), 60000); // 1 minute timeout
368
-
369
- try {
370
- const result = await llm.ChatCompletion({
371
- model: 'gpt-4',
372
- messages: [{ role: 'user', content: 'Complex analysis task...' }],
373
- cancellationToken: signal // One token, many cancel sources!
374
- });
375
-
376
- return result;
377
- } catch (error) {
378
- // The AI operation doesn't know WHY it was cancelled - just that it should stop
379
- console.log('AI operation was cancelled:', error.message);
380
- }
381
- }
382
- ```
383
-
384
- #### How It Works Internally
385
-
386
- The AI Core package implements cancellation at multiple levels:
387
-
388
- 1. **BaseLLM Level**: Checks cancellation token before and during operations
389
- 2. **Provider Level**: Native cancellation support where available (e.g., fetch API)
390
- 3. **Fallback Pattern**: Promise.race for providers without native cancellation
391
-
392
- ```typescript
393
- // Internal implementation example (simplified)
394
- async ChatCompletion(params: ChatParams): Promise<ChatResult> {
395
- // Check if already cancelled before starting
396
- if (params.cancellationToken?.aborted) {
397
- throw new Error('Operation was cancelled');
398
- }
399
-
400
- // For providers with native cancellation support
401
- if (this.hasNativeCancellation) {
402
- return await this.callProviderAPI({
403
- ...params,
404
- signal: params.cancellationToken // Native fetch cancellation
405
- });
406
- }
407
-
408
- // Fallback: Promise.race pattern for other providers
409
- const promises = [
410
- this.callProviderAPI(params) // The actual AI call
411
- ];
412
-
413
- if (params.cancellationToken) {
414
- promises.push(
415
- new Promise<never>((_, reject) => {
416
- params.cancellationToken!.addEventListener('abort', () => {
417
- reject(new Error('Operation was cancelled'));
418
- });
419
- })
420
- );
421
- }
422
-
423
- return await Promise.race(promises);
424
- }
425
- ```
426
-
427
- #### Key Benefits
428
-
429
- 1. **🎯 Responsive UX**: Users can cancel long-running AI operations instantly
430
- 2. **💾 Resource Management**: Prevent runaway operations from consuming resources
431
- 3. **🔄 Composable**: Easy to combine user actions, timeouts, and resource limits
432
- 4. **📱 Standard API**: Uses native JavaScript AbortSignal - no custom patterns
433
- 5. **🧹 Clean Cleanup**: Automatic resource cleanup when operations are cancelled
434
-
435
- The cancellation token pattern provides a **robust, standardized way** to make AI operations responsive and resource-efficient!
436
-
437
- ### Text Summarization
438
-
439
- For summarizing longer text content:
440
-
441
- ```typescript
442
- import { SummarizeParams, SummarizeResult } from '@memberjunction/ai';
443
-
444
- const params: SummarizeParams = {
445
- text: 'Long text to summarize...',
446
- model: 'your-model-name',
447
- maxWords: 100
448
- };
449
-
450
- const result: SummarizeResult = await llm.SummarizeText(params);
451
- console.log(result.summary);
452
- ```
453
-
454
- ### Text Classification
455
-
456
- For categorizing text into predefined classes:
457
-
458
- ```typescript
459
- import { ClassifyParams, ClassifyResult } from '@memberjunction/ai';
460
-
461
- const params: ClassifyParams = {
462
- text: 'Text to classify',
463
- model: 'your-model-name',
464
- classes: ['Category1', 'Category2', 'Category3']
465
- };
466
-
467
- const result: ClassifyResult = await llm.ClassifyText(params);
468
- console.log(result.classification);
469
- ```
470
-
471
- ## Response Format Control
472
-
473
- Control the format of AI responses:
474
-
475
- ```typescript
476
- const params: ChatParams = {
477
- // ...other parameters
478
- responseFormat: 'JSON', // 'Any', 'Text', 'Markdown', 'JSON', or 'ModelSpecific'
479
- };
480
-
481
- // For provider-specific response formats
482
- const customFormatParams: ChatParams = {
483
- // ...other parameters
484
- responseFormat: 'ModelSpecific',
485
- modelSpecificResponseFormat: {
486
- // Provider-specific format options
487
- }
488
- };
489
- ```
490
-
491
- ## Error Handling
492
-
493
- ### Enhanced Error Information (v2.47.0+)
494
-
495
- The MemberJunction AI Core package now provides rich, structured error information to enable intelligent retry logic and provider failover. All operations return results extending `BaseResult` which now includes detailed error information.
496
-
497
- #### Basic Error Handling
498
-
499
- ```typescript
500
- const result = await llm.ChatCompletion(params);
501
-
502
- if (!result.success) {
503
- console.error('Error:', result.errorMessage);
504
- console.error('Status Text:', result.statusText);
505
- console.error('Exception:', result.exception);
506
- console.error('Time Elapsed:', result.timeElapsed, 'ms');
507
- } else {
508
- console.log('Success! Response time:', result.timeElapsed, 'ms');
509
- }
510
- ```
511
-
512
- #### Advanced Error Handling with Error Info
513
-
514
- ```typescript
515
- const result = await llm.ChatCompletion(params);
516
-
517
- if (!result.success && result.errorInfo) {
518
- const { errorInfo } = result;
519
-
520
- console.log(`Error Type: ${errorInfo.errorType}`);
521
- console.log(`HTTP Status: ${errorInfo.httpStatusCode}`);
522
- console.log(`Severity: ${errorInfo.severity}`);
523
- console.log(`Can Failover: ${errorInfo.canFailover}`);
524
-
525
- // Handle based on error type
526
- switch (errorInfo.errorType) {
527
- case 'RateLimit':
528
- // Wait and retry or switch providers
529
- const delay = errorInfo.suggestedRetryDelaySeconds || 30;
530
- console.log(`Rate limited. Retry after ${delay} seconds`);
531
- break;
532
-
533
- case 'Authentication':
534
- // Fatal error - check API keys
535
- console.error('Authentication failed. Check API key configuration.');
536
- break;
537
-
538
- case 'ServiceUnavailable':
539
- // Try another provider
540
- if (errorInfo.canFailover) {
541
- console.log('Service unavailable. Switching to backup provider...');
542
- }
543
- break;
544
- }
545
- }
546
- ```
547
-
548
- ### Error Types
549
-
550
- The package categorizes errors into the following types:
551
-
552
- - **`RateLimit`**: Rate limit exceeded (HTTP 429). Suggests switching providers or waiting
553
- - **`Authentication`**: Auth failure (HTTP 401/403). Usually indicates invalid API key
554
- - **`ServiceUnavailable`**: Service down (HTTP 503). Provider temporarily unavailable
555
- - **`InternalServerError`**: Server error (HTTP 500). Problem on provider's side
556
- - **`NetworkError`**: Connection issues, timeouts, DNS failures
557
- - **`InvalidRequest`**: Bad request format (HTTP 400). Problem with request parameters
558
- - **`ModelError`**: Model-specific issues (not found, overloaded)
559
- - **`Unknown`**: Unclassified errors
560
-
561
- ### Error Severity Levels
562
-
563
- Errors are classified by severity to guide retry strategies:
564
-
565
- - **`Transient`**: Temporary error that may resolve with immediate retry
566
- - **`Retriable`**: Error requiring waiting or provider switching before retry
567
- - **`Fatal`**: Permanent error that won't be resolved by retrying
568
-
569
- ### Error Analysis Utility
570
-
571
- The package includes an `ErrorAnalyzer` utility for providers to use:
572
-
573
- ```typescript
574
- import { ErrorAnalyzer } from '@memberjunction/ai';
575
-
576
- try {
577
- // Provider API call
578
- } catch (error) {
579
- const errorInfo = ErrorAnalyzer.analyzeError(error, 'OpenAI');
580
- // errorInfo now contains structured error details
581
- }
582
- ```
583
-
584
- ### Implementing Intelligent Failover
151
+ ### Parallel Chat Completions
585
152
 
586
153
  ```typescript
587
- import { BaseLLM, ChatParams, AIErrorInfo } from '@memberjunction/ai';
154
+ const paramsArray = [
155
+ { ...baseParams, temperature: 0.3 },
156
+ { ...baseParams, temperature: 0.7 },
157
+ { ...baseParams, temperature: 1.0 }
158
+ ];
588
159
 
589
- class ResilientAIClient {
590
- private providers: Array<{ name: string; llm: BaseLLM }> = [];
591
-
592
- async chatWithFailover(params: ChatParams): Promise<ChatResult> {
593
- for (const provider of this.providers) {
594
- try {
595
- const result = await provider.llm.ChatCompletion(params);
596
-
597
- if (result.success) {
598
- return result;
599
- }
600
-
601
- // Check if we should try another provider
602
- if (result.errorInfo?.canFailover) {
603
- console.log(`Provider ${provider.name} failed. Trying next...`);
604
- continue;
605
- } else {
606
- // Fatal error - don't try other providers
607
- return result;
608
- }
609
-
610
- } catch (error) {
611
- console.error(`Provider ${provider.name} threw exception:`, error);
612
- }
613
- }
614
-
615
- throw new Error('All providers failed');
616
- }
617
- }
160
+ const results = await llm.ChatCompletions(paramsArray, {
161
+ OnCompletion: (result, index) => console.log(`Completion ${index} done`),
162
+ OnAllCompleted: (results) => console.log(`All ${results.length} done`)
163
+ });
618
164
  ```
619
165
 
620
- ### Retry with Backoff
166
+ ### Multimodal Content
621
167
 
622
168
  ```typescript
623
- async function retryWithBackoff(
624
- operation: () => Promise<ChatResult>,
625
- maxRetries: number = 3
626
- ): Promise<ChatResult> {
627
- let lastResult: ChatResult;
628
-
629
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
630
- lastResult = await operation();
631
-
632
- if (lastResult.success) {
633
- return lastResult;
634
- }
635
-
636
- const errorInfo = lastResult.errorInfo;
637
- if (!errorInfo || errorInfo.severity === 'Fatal') {
638
- // Don't retry fatal errors
639
- return lastResult;
169
+ const params = new ChatParams();
170
+ params.model = 'gpt-4o';
171
+ params.messages = [
172
+ {
173
+ role: ChatMessageRole.user,
174
+ content: [
175
+ { type: 'text', content: 'What is in this image?' },
176
+ { type: 'image_url', content: 'data:image/png;base64,...' }
177
+ ]
640
178
  }
641
-
642
- // Calculate delay
643
- const delay = errorInfo.suggestedRetryDelaySeconds ||
644
- Math.pow(2, attempt - 1) * 1000; // Exponential backoff
645
-
646
- console.log(`Retry ${attempt}/${maxRetries} after ${delay}s...`);
647
- await new Promise(resolve => setTimeout(resolve, delay * 1000));
648
- }
649
-
650
- return lastResult!;
651
- }
652
- ```
653
-
654
- ## Token Usage Tracking
655
-
656
- Monitor token usage consistently across different providers:
657
-
658
- ```typescript
659
- const result = await llm.ChatCompletion(params);
660
- console.log('Prompt Tokens:', result.data.usage.promptTokens);
661
- console.log('Completion Tokens:', result.data.usage.completionTokens);
662
- console.log('Total Tokens:', result.data.usage.totalTokens);
663
- ```
664
-
665
- ## Available Providers
666
-
667
- The following provider packages implement the MemberJunction AI abstractions:
668
-
669
- - [`@memberjunction/ai-openai`](../Providers/OpenAI/readme.md) - OpenAI (GPT models)
670
- - [`@memberjunction/ai-anthropic`](../Providers/Anthropic/readme.md) - Anthropic (Claude models)
671
- - [`@memberjunction/ai-mistral`](../Providers/Mistral/readme.md) - Mistral AI
672
- - [`@memberjunction/ai-gemini`](../Providers/Gemini/readme.md) - Google's Gemini models
673
- - [`@memberjunction/ai-vertex`](../Providers/Vertex/readme.md) - Google Vertex AI (various models including Gemini, others)
674
- - [`@memberjunction/ai-bedrock`](../Providers/Bedrock/readme.md) - Amazon Bedrock (Claude, Llama, Titan, etc.)
675
- - [`@memberjunction/ai-groq`](../Providers/Groq/readme.md) - Groq's optimized inference (https://www.groq.com)
676
- - [`@memberjunction/ai-bettybot`](../Providers/BettyBot/readme.md) - Betty AI (https://www.meetbetty.ai)
677
- - [`@memberjunction/ai-azure`](../Providers/Azure/readme.md) - Azure AI Foundry with support for OpenAI, Mistral, Phi, more
678
- - [`@memberjunction/ai-cerebras`](../Providers/Cerebras/readme.md) - Cerebras models
679
- - [`@memberjunction/ai-elevenlabs`](../Providers/ElevenLabs/readme.md) - ElevenLabs audio models
680
- - [`@memberjunction/ai-heygen`](../Providers/HeyGen/readme.md) - HeyGen video models
681
-
682
- Note: Each provider implements the features they support. See individual provider documentation for specific capabilities.
683
-
684
- ## Implementation Details
685
-
686
- ### Streaming Architecture
687
-
688
- The BaseLLM class uses a template method pattern for handling streaming:
689
-
690
- 1. The main `ChatCompletion` method checks if streaming is requested and supported
691
- 2. If streaming is enabled, it calls the template method `handleStreamingChatCompletion`
692
- 3. Provider implementations supply three key methods:
693
- - `createStreamingRequest`: Creates the provider-specific streaming request
694
- - `processStreamingChunk`: Processes individual chunks from the stream
695
- - `finalizeStreamingResponse`: Creates the final response object
696
-
697
- This architecture allows for a clean separation between common streaming logic and provider-specific implementations.
698
-
699
- ## Import Examples
700
-
701
- ```typescript
702
- // Import base model classes
703
- import { BaseLLM, BaseEmbeddings, BaseAudioGenerator } from '@memberjunction/ai';
704
-
705
- // Import result types
706
- import { ChatResult, ModelUsage, BaseResult } from '@memberjunction/ai';
707
-
708
- // Import parameter types
709
- import { ChatParams, ChatMessage, StreamingChatCallbacks } from '@memberjunction/ai';
710
-
711
- // Import utility classes
712
- import { AIAPIKeys, GetAIAPIKey } from '@memberjunction/ai';
713
- ```
714
-
715
- ## Dependencies
716
-
717
- - `@memberjunction/global` - MemberJunction global utilities including class factory
718
- - `rxjs` - Reactive extensions for JavaScript
719
-
720
- ## Type Exports
721
-
722
- The Core package exports fundamental types used throughout the AI ecosystem:
723
-
724
- ### Base Model Classes
725
- - `BaseModel` - Foundation class for all AI models
726
- - `BaseLLM` - Base class for language models
727
- - `BaseEmbeddings` - Base class for embedding models
728
- - `BaseAudioGenerator` - Base class for audio models
729
- - `BaseVideoGenerator` - Base class for video models
730
- - `BaseDiffusion` - Base class for image generation models
731
-
732
- ### Core Result Types
733
- - `BaseResult` - Base result structure for all AI operations
734
- - `ChatResult` - Result from chat completions
735
- - `ModelUsage` - Token/resource usage tracking
736
- - `SummarizeResult` - Text summarization results
737
- - `ClassifyResult` - Text classification results
738
- - `EmbeddingResult` - Embedding generation results
739
-
740
- ### Common Interfaces
741
- - `ChatMessage` - Message structure for conversations
742
- - `ChatParams` - Parameters for chat operations
743
- - `StreamingChatCallbacks` - Callbacks for streaming responses
744
- - `ParallelChatCompletionsCallbacks` - Callbacks for parallel execution
745
-
746
- ## API Reference
747
-
748
- ### Result Types
749
-
750
- #### BaseResult
751
- All operations return results extending `BaseResult`:
752
- ```typescript
753
- class BaseResult {
754
- success: boolean;
755
- startTime: Date;
756
- endTime: Date;
757
- errorMessage: string;
758
- exception: any;
759
- errorInfo?: AIErrorInfo; // Enhanced error details (v2.47.0+)
760
- timeElapsed: number; // Computed getter
761
- }
762
-
763
- // Enhanced error information structure
764
- interface AIErrorInfo {
765
- httpStatusCode?: number; // HTTP status code (429, 500, etc.)
766
- errorType: AIErrorType; // Categorized error type
767
- severity: ErrorSeverity; // Transient, Retriable, or Fatal
768
- suggestedRetryDelaySeconds?: number; // Provider-suggested retry delay
769
- canFailover: boolean; // Whether switching providers might help
770
- providerErrorCode?: string; // Original provider error code
771
- context?: Record<string, any>; // Additional error context
772
- }
773
- ```
774
-
775
- #### ChatResult
776
- Extends `BaseResult` with chat-specific data:
777
- ```typescript
778
- class ChatResult extends BaseResult {
779
- data: {
780
- choices: Array<{
781
- message: ChatCompletionMessage;
782
- index: number;
783
- finishReason?: string;
784
- }>;
785
- usage: ModelUsage;
786
- };
787
- statusText?: string;
788
- }
789
- ```
790
-
791
- ### Chat Message Types
792
-
793
- #### ChatMessage
794
- Supports multi-modal content and optional typed metadata:
795
- ```typescript
796
- type ChatMessage<M = any> = {
797
- role: 'system' | 'user' | 'assistant';
798
- content: string | ChatMessageContentBlock[];
799
- metadata?: M; // Optional typed metadata for extended functionality
800
- }
801
-
802
- type ChatMessageContentBlock = {
803
- type: 'text' | 'image_url' | 'video_url' | 'audio_url' | 'file_url';
804
- content: string; // URL or base64 encoded content
805
- }
179
+ ];
806
180
  ```
807
181
 
808
- **Generic Metadata Parameter**:
809
- The `ChatMessage` type is now generic, allowing you to attach typed metadata to messages:
810
- - The generic parameter defaults to `any` for backward compatibility
811
- - Use `ChatMessage<MyMetadata>` to specify a custom metadata type
812
- - This enables framework extensions (like agents) to add lifecycle metadata without modifying the core type
813
- - Example: Agents use `ChatMessage<AgentChatMessageMetadata>` to track message expiration, compaction, and expansion state
814
-
815
- ### Streaming Callbacks
182
+ ### Text Embeddings
816
183
 
817
184
  ```typescript
818
- interface StreamingChatCallbacks {
819
- OnContent?: (chunk: string, isComplete: boolean) => void;
820
- OnComplete?: (finalResponse: ChatResult) => void;
821
- OnError?: (error: any) => void;
822
- }
185
+ import { EmbedTextParams } from '@memberjunction/ai';
186
+ import { OpenAIEmbeddings } from '@memberjunction/ai-openai';
823
187
 
824
- interface ParallelChatCompletionsCallbacks {
825
- OnCompletion?: (response: ChatResult, index: number) => void;
826
- OnError?: (error: any, index: number) => void;
827
- OnAllCompleted?: (responses: ChatResult[]) => void;
828
- }
188
+ const embedder = new OpenAIEmbeddings('your-api-key');
189
+ const result = await embedder.EmbedText({
190
+ model: 'text-embedding-ada-002',
191
+ text: 'Sample text to embed'
192
+ });
193
+ console.log(result.embedding); // number[]
829
194
  ```
830
195
 
831
- ## Configuration
832
-
833
196
  ### API Key Management
834
197
 
835
- The package includes a flexible API key management system through the `AIAPIKeys` class:
836
-
837
198
  ```typescript
838
199
  import { GetAIAPIKey } from '@memberjunction/ai';
839
200
 
840
- // Get API key for a specific provider
841
- const apiKey = GetAIAPIKey('OpenAI');
842
- ```
843
-
844
- By default, it looks for environment variables with the pattern: `AI_VENDOR_API_KEY__[PROVIDER_NAME]`
201
+ // Reads from environment: AI_VENDOR_API_KEY__OPENAILLM
202
+ const key = GetAIAPIKey('OpenAILLM');
845
203
 
846
- Example:
847
- ```bash
848
- AI_VENDOR_API_KEY__OPENAI=your-api-key
849
- AI_VENDOR_API_KEY__ANTHROPIC=your-api-key
850
- AI_VENDOR_API_KEY__MISTRAL=your-api-key
204
+ // With runtime override
205
+ const key2 = GetAIAPIKey('AnthropicLLM', [
206
+ { driverClass: 'AnthropicLLM', apiKey: 'sk-ant-...' }
207
+ ]);
851
208
  ```
852
209
 
853
- > **Advanced Authentication**: When using the full MemberJunction framework with `@memberjunction/ai-prompts`, you can leverage the Credentials system for encrypted, audited credential management with hierarchical resolution. See the [AI Authentication Guide](../Prompts/AI-AUTHENTICATION.md) for details on:
854
- > - Credential resolution hierarchy (vendor → model → prompt → request)
855
- > - Integration with the encrypted Credentials system
856
- > - Support for complex authentication schemes (Azure, AWS, OAuth)
857
- > - Migration path from environment variables
858
-
859
- #### Custom API Key Management
210
+ ## Provider Implementation
860
211
 
861
- You can extend the `AIAPIKeys` class to implement custom API key retrieval logic:
212
+ To create a new AI provider, extend the appropriate base class:
862
213
 
863
214
  ```typescript
864
- import { AIAPIKeys, RegisterClass } from '@memberjunction/ai';
865
-
866
- @RegisterClass(AIAPIKeys, 'CustomAPIKeys', 2) // Priority 2 overrides default
867
- export class CustomAPIKeys extends AIAPIKeys {
868
- public GetAPIKey(AIDriverName: string): string {
869
- // Your custom logic here
870
- // Could retrieve from database, vault, etc.
871
- return super.GetAPIKey(AIDriverName); // Fallback to default
872
- }
873
- }
874
- ```
875
-
876
- #### Runtime API Key Override
877
-
878
- As of v2.50.0, you can provide API keys at runtime without modifying environment variables or global configuration. This is useful for multi-tenant applications or testing with different API keys.
879
-
880
- ##### Direct Constructor Usage
215
+ import { BaseLLM, ChatParams, ChatResult } from '@memberjunction/ai';
881
216
 
882
- When creating AI model instances directly, pass the API key to the constructor:
883
-
884
- ```typescript
885
- import { OpenAILLM } from '@memberjunction/ai-openai';
886
-
887
- const llm = new OpenAILLM('sk-your-runtime-api-key');
888
- ```
889
-
890
- ##### With Class Factory Pattern
891
-
892
- When using the class factory pattern, the API key is passed as the second parameter:
893
-
894
- ```typescript
895
- import { BaseLLM } from '@memberjunction/ai';
896
- import { MJGlobal } from '@memberjunction/global';
897
-
898
- const llm = MJGlobal.Instance.ClassFactory.CreateInstance<BaseLLM>(
899
- BaseLLM,
900
- 'OpenAILLM',
901
- 'sk-your-runtime-api-key' // Runtime API key
902
- );
903
- ```
217
+ export class MyProviderLLM extends BaseLLM {
218
+ protected async nonStreamingChatCompletion(params: ChatParams): Promise<ChatResult> {
219
+ // Implement provider-specific chat completion
220
+ }
904
221
 
905
- ##### API Key Type Definition
222
+ public async ClassifyText(params: ClassifyParams): Promise<ClassifyResult> {
223
+ // Implement or throw if not supported
224
+ }
906
225
 
907
- The package exports an `AIAPIKey` interface for structured API key configuration:
226
+ public async SummarizeText(params: SummarizeParams): Promise<SummarizeResult> {
227
+ // Implement or throw if not supported
228
+ }
908
229
 
909
- ```typescript
910
- export interface AIAPIKey {
911
- /**
912
- * The driver class name (e.g., 'OpenAILLM', 'AnthropicLLM', 'GroqLLM')
913
- * This should match the exact driver class name used by the AI provider
914
- */
915
- driverClass: string;
916
-
917
- /**
918
- * The API key value for the specified driver class
919
- */
920
- apiKey: string;
230
+ // For streaming support, override these:
231
+ public get SupportsStreaming(): boolean { return true; }
232
+ protected async createStreamingRequest(params: ChatParams): Promise<AsyncIterable<unknown>> { /* ... */ }
233
+ protected processStreamingChunk(chunk: unknown): { content: string } { /* ... */ }
234
+ protected finalizeStreamingResponse(content: string, lastChunk: unknown, usage: unknown): ChatResult { /* ... */ }
921
235
  }
922
236
  ```
923
237
 
924
- ### Provider-Specific Settings
925
-
926
- Many providers support additional configuration beyond the API key:
927
-
928
- ```typescript
929
- const llm = new SomeLLM('api-key');
930
- llm.SetAdditionalSettings({
931
- baseURL: 'https://custom-endpoint.com',
932
- organization: 'my-org',
933
- // Provider-specific settings
934
- });
935
- ```
936
-
937
- ## Integration with MemberJunction
938
-
939
- While this package can be used standalone, it integrates seamlessly with the MemberJunction framework:
940
-
941
- - Uses `@memberjunction/global` for class factory pattern and registration
942
- - Compatible with MemberJunction's metadata system
943
- - Can leverage MemberJunction's configuration management when available
944
-
945
238
  ## Dependencies
946
239
 
947
- - `@memberjunction/global` (^2.43.0) - MemberJunction global utilities including class factory
948
- - `rxjs` (^7.8.1) - Reactive extensions for JavaScript (used in streaming implementations)
949
- - `dotenv` (^16.4.1) - Environment variable management
950
- - `typeorm` (^0.3.20) - ORM functionality (optional, only if using with full MemberJunction)
951
-
952
- ## Development
953
-
954
- ### Building
955
-
956
- ```bash
957
- cd packages/AI/Core
958
- npm run build
959
- ```
960
-
961
- ### TypeScript Configuration
962
-
963
- The package is configured with TypeScript strict mode and targets ES2022. See `tsconfig.json` for full compiler options.
964
-
965
- ## Best Practices
966
-
967
- 1. **Always use the class factory pattern** for maximum flexibility
968
- 2. **Handle errors gracefully** - check `result.success` before accessing data
969
- 3. **Monitor token usage** to manage costs and stay within limits
970
- 4. **Use streaming for long responses** to improve user experience
971
- 5. **Leverage parallel completions** for comparison or reliability
972
- 6. **Cache API keys** using the built-in caching mechanism
973
- 7. **Specify response formats** when you need structured output
974
-
975
- ## Troubleshooting
976
-
977
- ### Common Issues
978
-
979
- 1. **"API key cannot be empty" error**
980
- - Ensure you're passing a valid API key to the constructor
981
- - Check environment variables are properly set
982
-
983
- 2. **Provider not found when using class factory**
984
- - Make sure to import and call the provider's Load function
985
- - Verify the provider class name matches exactly
986
-
987
- 3. **Streaming not working**
988
- - Check if the provider supports streaming (`llm.SupportsStreaming`)
989
- - Ensure streaming callbacks are properly defined
990
-
991
- 4. **Type errors with content blocks**
992
- - Use the provided type guards and interfaces
993
- - Ensure content format matches the expected structure
994
-
995
- ## Parameter Reference
996
-
997
- ### ChatParams Parameters
998
-
999
- The `ChatParams` class supports the following parameters for controlling LLM behavior:
1000
-
1001
- #### Core Parameters (from BaseParams)
1002
- - `model` (required): The model name to use
1003
- - `temperature`: Controls randomness (0.0 = deterministic, 2.0 = very random)
1004
- - `maxOutputTokens`: Maximum tokens to generate in response
1005
- - `responseFormat`: Output format - 'Any', 'Text', 'Markdown', 'JSON', or 'ModelSpecific'
1006
- - `seed`: Random seed for reproducible outputs (provider-dependent)
1007
- - `stopSequences`: Array of sequences that will stop generation
1008
-
1009
- #### Sampling Parameters
1010
- - `topP`: Top-p (nucleus) sampling (0-1). Alternative to temperature, considers cumulative probability
1011
- - `topK`: Top-k sampling. Limits to top K most likely tokens (provider-dependent)
1012
- - `minP`: Minimum probability threshold (0-1). Filters out low-probability tokens
1013
-
1014
- #### Repetition Control
1015
- - `frequencyPenalty`: Reduce token repetition based on frequency (-2.0 to 2.0)
1016
- - `presencePenalty`: Encourage topic diversity (-2.0 to 2.0)
1017
-
1018
- #### Advanced Features
1019
- - `streaming`: Enable streaming responses
1020
- - `includeLogProbs`: Request log probabilities for tokens
1021
- - `topLogProbs`: Number of top log probabilities to return (2-20)
1022
- - `effortLevel`: Model-specific effort/reasoning level
1023
- - `reasoningBudgetTokens`: Token budget for reasoning models
1024
- - `enableCaching`: Enable provider caching features
1025
- - `cancellationToken`: AbortSignal for cancelling operations
1026
-
1027
- ### Provider Support
1028
-
1029
- Not all providers support all parameters. The framework will:
1030
- - Pass supported parameters to the provider
1031
- - Log warnings for unsupported parameters (visible in console)
1032
- - Continue execution without failing
1033
-
1034
- Common support patterns:
1035
- - **OpenAI**: Supports most parameters except topK, minP
1036
- - **Anthropic**: Supports topP, topK, but not frequency/presence penalties
1037
- - **Google/Gemini**: Supports topP, topK, temperature
1038
- - **Others**: Vary by provider - check console warnings
1039
-
1040
- ## License
1041
-
1042
- See the [repository root](../../../LICENSE) for license information.
240
+ - `@memberjunction/global` -- Class factory and global utilities (zero transitive dependencies)
241
+ - `dotenv` -- Environment variable loading
242
+ - `rxjs` -- Reactive extensions (used internally)