@memberjunction/ai 2.43.0 → 2.45.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.
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { BaseParams, BaseResult, ModelUsage } from "./baseModel";
2
3
  export declare const ChatMessageRole: {
3
4
  readonly system: "system";
@@ -35,6 +36,7 @@ export declare class ChatParams extends BaseParams {
35
36
  effortLevel?: string;
36
37
  enableCaching?: boolean;
37
38
  includeLogProbs?: boolean;
39
+ cancellationToken?: AbortSignal;
38
40
  }
39
41
  export declare function GetUserMessageFromChatParams(p: ChatParams): ChatMessageContent | undefined;
40
42
  export declare function GetSystemPromptFromChatParams(p: ChatParams): ChatMessageContent | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"chat.types.d.ts","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAOhE,eAAO,MAAM,eAAe;;;;CAIlB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,OAAO,eAAe,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAOnF,MAAM,MAAM,uBAAuB,GAAG;IAKlC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,UAAU,CAAC;IAMpE,OAAO,EAAE,MAAM,CAAC;CACnB,CAAA;AAKD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,uBAAuB,EAAE,CAAC;AAKpE,MAAM,MAAM,WAAW,GAAG;IAItB,IAAI,EAAE,eAAe,CAAC;IAItB,OAAO,EAAE,kBAAkB,CAAC;CAC/B,CAAA;AAKD,MAAM,MAAM,qBAAqB,GAAG;IAIhC,IAAI,EAAE,WAAW,CAAC;IAKlB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAA;AAKD,MAAM,WAAW,sBAAsB;IAMnC,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,CAAC;IAMzD,UAAU,CAAC,EAAE,CAAC,aAAa,EAAE,UAAU,KAAK,IAAI,CAAC;IAMjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;CAClC;AAKD,MAAM,WAAW,gCAAgC;IAM7C,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAO7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAM9C,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,IAAI,CAAC;CACtD;AAED,qBAAa,UAAW,SAAQ,UAAU;IAItC,QAAQ,EAAE,WAAW,EAAE,CAAM;IAO7B,SAAS,CAAC,EAAE,OAAO,CAAS;IAM5B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;IAK5C,WAAW,CAAC,EAAE,MAAM,CAAC;IAWrB,aAAa,CAAC,EAAE,OAAO,CAAQ;IAQ/B,eAAe,CAAC,EAAE,OAAO,CAAS;CACrC;AAMD,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAE1F;AAMD,wBAAgB,6BAA6B,CAAC,CAAC,EAAE,UAAU,GAAG,kBAAkB,GAAG,SAAS,CAE3F;AAKD,MAAM,MAAM,uBAAuB,GAAG;IAMlC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;IAK5B,OAAO,EAAE,MAAM,CAAA;IAKf,KAAK,EAAE,MAAM,CAAA;IAKb,YAAY,EAAE,KAAK,CAAC;QAIhB,KAAK,EAAE,MAAM,CAAA;QAIb,OAAO,EAAE,MAAM,CAAA;QAMf,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC;KAC/B,CAAC,GAAG,IAAI,CAAC;CACb,CAAA;AAKD,MAAM,MAAM,kBAAkB,GAAG;IAI7B,OAAO,EAAE,KAAK,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC;IAI/C,OAAO,EAAE,KAAK,CAAC,uBAAuB,CAAC,GAAG,IAAI,CAAC;CAClD,CAAA;AAKD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,OAAO,EAAE,qBAAqB,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;CACvC,CAAA;AAKD,MAAM,MAAM,cAAc,GAAG;IAIzB,OAAO,EAAE,gBAAgB,EAAE,CAAA;IAI3B,KAAK,CAAC,EAAE,MAAM,CAAA;IAId,KAAK,CAAC,EAAE,UAAU,CAAA;CACrB,CAAA;AAKD,MAAM,WAAW,aAAa;IAI1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IAKnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,qBAAa,UAAW,SAAQ,UAAU;IACtC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IAKnB,SAAS,CAAC,EAAE,aAAa,CAAC;CAC7B"}
1
+ {"version":3,"file":"chat.types.d.ts","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"chat.types.js","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAOnD,QAAA,eAAe,GAAG;IAC3B,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;CAChB,CAAC;AA0GX,MAAa,UAAW,SAAQ,sBAAU;IAA1C;;QAII,aAAQ,GAAkB,EAAE,CAAC;QAO7B,cAAS,GAAa,KAAK,CAAC;QAsB5B,kBAAa,GAAa,IAAI,CAAC;QAQ/B,oBAAe,GAAa,KAAK,CAAC;IACtC,CAAC;CAAA;AA1CD,gCA0CC;AAMD,SAAgB,4BAA4B,CAAC,CAAa;IACtD,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;AAC1E,CAAC;AAFD,oEAEC;AAMD,SAAgB,6BAA6B,CAAC,CAAa;IACvD,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAe,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;AAC5E,CAAC;AAFD,sEAEC;AAqGD,MAAa,UAAW,SAAQ,sBAAU;CASzC;AATD,gCASC"}
1
+ {"version":3,"file":"chat.types.js","sourceRoot":"","sources":["../../src/generic/chat.types.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAOnD,QAAA,eAAe,GAAG;IAC3B,MAAM,EAAE,QAAQ;IAChB,IAAI,EAAE,MAAM;IACZ,SAAS,EAAE,WAAW;CAChB,CAAC;AA0GX,MAAa,UAAW,SAAQ,sBAAU;IAA1C;;QAII,aAAQ,GAAkB,EAAE,CAAC;QAO7B,cAAS,GAAa,KAAK,CAAC;QAsB5B,kBAAa,GAAa,IAAI,CAAC;QAQ/B,oBAAe,GAAa,KAAK,CAAC;IAQtC,CAAC;CAAA;AAjDD,gCAiDC;AAMD,SAAgB,4BAA4B,CAAC,CAAa;IACtD,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;AAC1E,CAAC;AAFD,oEAEC;AAMD,SAAgB,6BAA6B,CAAC,CAAa;IACvD,OAAO,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,uBAAe,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;AAC5E,CAAC;AAFD,sEAEC;AAqGD,MAAa,UAAW,SAAQ,sBAAU;CASzC;AATD,gCASC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memberjunction/ai",
3
- "version": "2.43.0",
3
+ "version": "2.45.0",
4
4
  "description": "MemberJunction: AI Module - LLMs and other AI services wrapped and abstracted for use in MemberJunction",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -15,7 +15,7 @@
15
15
  "author": "MemberJunction.com",
16
16
  "license": "ISC",
17
17
  "dependencies": {
18
- "@memberjunction/global": "2.43.0",
18
+ "@memberjunction/global": "2.45.0",
19
19
  "dotenv": "^16.4.1",
20
20
  "rxjs": "^7.8.1",
21
21
  "typeorm": "^0.3.20"
package/readme.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
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.
4
4
 
5
+ ## Overview
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.
8
+
5
9
  ## Standalone Usage
6
10
 
7
11
  **IMPORTANT**: This package can be used completely independently from the rest of the MemberJunction framework:
@@ -17,12 +21,16 @@ The `@memberjunction/ai` package and all provider packages in `@memberjunction/a
17
21
 
18
22
  - **Provider Abstraction**: Work with AI models without tightly coupling to specific vendor APIs
19
23
  - **Runtime Optionality**: Switch between AI providers at runtime based on configuration
20
- - **Base Classes**: Abstract base classes for different AI model types (LLMs, embedding models, etc.)
24
+ - **Base Classes**: Abstract base classes for different AI model types (LLMs, embedding models, audio, video, etc.)
21
25
  - **Standard Interfaces**: Consistent interfaces for common AI operations like chat, summarization, and classification
22
26
  - **Streaming Support**: Stream responses from supported LLM providers for real-time UIs
27
+ - **Parallel Processing**: Execute multiple chat completions in parallel with progress callbacks
28
+ - **Multi-modal Support**: Handle text, images, videos, audio, and files in chat messages
23
29
  - **Type Definitions**: Comprehensive TypeScript type definitions for all AI operations
24
30
  - **Error Handling**: Standardized error handling and reporting across all providers
25
31
  - **Token Usage Tracking**: Consistent tracking of token usage across providers
32
+ - **Response Format Control**: Specify output formats (Text, Markdown, JSON, or provider-specific)
33
+ - **Additional Settings**: Provider-specific configuration through a flexible settings system
26
34
 
27
35
  ## Installation
28
36
 
@@ -124,12 +132,45 @@ console.log(result.data.choices[0].message.content);
124
132
 
125
133
  ### Base Models
126
134
 
127
- - `BaseModel`: The foundational abstract class for all AI models
128
- - `BaseLLM`: Abstract class for text generation models like GPT, Claude, etc.
129
- - `BaseEmbedding`: Abstract class for text embedding models
130
- - `BaseDiffusion`: Abstract class for image generation models
131
- - `BaseAudio`: Abstract class for speech and audio processing models
132
- - `BaseVideo`: Abstract class for video generation models
135
+ #### BaseModel
136
+ The foundational abstract class for all AI models. Provides:
137
+ - Protected API key management
138
+ - Base parameter and result types
139
+ - Model usage tracking
140
+
141
+ #### BaseLLM
142
+ Abstract class for text generation models. Features:
143
+ - Standard and streaming chat completions
144
+ - Parallel chat completions with callbacks
145
+ - Text summarization
146
+ - Text classification
147
+ - Additional provider-specific settings management
148
+ - Response format control (Any, Text, Markdown, JSON, ModelSpecific)
149
+ - Support for reasoning budget tokens (for reasoning models)
150
+
151
+ #### BaseEmbeddings
152
+ Abstract class for text embedding models. Provides:
153
+ - Single text embedding generation
154
+ - Batch text embedding generation
155
+ - Model listing capabilities
156
+ - Additional settings management
157
+
158
+ #### BaseAudioGenerator
159
+ Abstract class for audio processing models. Supports:
160
+ - Text-to-speech generation
161
+ - Speech-to-text transcription
162
+ - Voice listing and management
163
+ - Model and pronunciation dictionary queries
164
+ - Configurable voice settings (stability, similarity, speed, etc.)
165
+
166
+ #### BaseVideoGenerator
167
+ Abstract class for video generation models. Enables:
168
+ - Avatar-based video creation
169
+ - Video translation capabilities
170
+ - Avatar management and listing
171
+
172
+ #### BaseDiffusion
173
+ Abstract class for image generation models (placeholder for future implementation)
133
174
 
134
175
  ## LLM Operations
135
176
 
@@ -200,6 +241,187 @@ const params: ChatParams = {
200
241
  await llm.ChatCompletion(params);
201
242
  ```
202
243
 
244
+ ### Cancellable Operations with AbortSignal
245
+
246
+ 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.
247
+
248
+ #### Understanding the AbortSignal Pattern
249
+
250
+ The `AbortSignal` pattern uses a **separation of concerns** approach:
251
+
252
+ - **Controller (Caller)**: Creates the `AbortController` and decides **when** to cancel
253
+ - **Worker (AI Operations)**: Receives the `AbortSignal` token and handles **how** to cancel
254
+
255
+ #### Basic Cancellation Example
256
+
257
+ ```typescript
258
+ import { ChatParams, BaseLLM } from '@memberjunction/ai';
259
+
260
+ async function cancellableAIChat() {
261
+ // Create the cancellation controller (the "boss")
262
+ const controller = new AbortController();
263
+
264
+ // Set up automatic timeout cancellation
265
+ const timeout = setTimeout(() => {
266
+ controller.abort(); // Cancel after 30 seconds
267
+ }, 30000);
268
+
269
+ try {
270
+ const params: ChatParams = {
271
+ model: 'gpt-4',
272
+ messages: [
273
+ { role: 'user', content: 'Write a very long story...' }
274
+ ],
275
+ cancellationToken: controller.signal // Pass the signal token
276
+ };
277
+
278
+ const result = await llm.ChatCompletion(params);
279
+ clearTimeout(timeout); // Clear timeout if completed successfully
280
+ return result;
281
+
282
+ } catch (error) {
283
+ if (error.message.includes('cancelled')) {
284
+ console.log('Operation was cancelled');
285
+ } else {
286
+ console.error('Operation failed:', error);
287
+ }
288
+ }
289
+ }
290
+ ```
291
+
292
+ #### User-Initiated Cancellation
293
+
294
+ Perfect for UI applications where users can cancel operations:
295
+
296
+ ```typescript
297
+ class AIInterface {
298
+ private currentController: AbortController | null = null;
299
+
300
+ async startAIConversation() {
301
+ // Create new controller for this conversation
302
+ this.currentController = new AbortController();
303
+
304
+ try {
305
+ const result = await llm.ChatCompletion({
306
+ model: 'gpt-4',
307
+ messages: [{ role: 'user', content: 'Generate a detailed report...' }],
308
+ cancellationToken: this.currentController.signal
309
+ });
310
+
311
+ console.log('AI Response:', result.data.choices[0].message.content);
312
+ } catch (error) {
313
+ if (error.message.includes('cancelled')) {
314
+ console.log('User cancelled the conversation');
315
+ }
316
+ } finally {
317
+ this.currentController = null;
318
+ }
319
+ }
320
+
321
+ // Called when user clicks "Cancel" button
322
+ cancelConversation() {
323
+ if (this.currentController) {
324
+ this.currentController.abort(); // Instant cancellation
325
+ }
326
+ }
327
+ }
328
+ ```
329
+
330
+ #### Multiple Cancellation Sources
331
+
332
+ One signal can be cancelled from multiple sources:
333
+
334
+ ```typescript
335
+ async function smartAIExecution() {
336
+ const controller = new AbortController();
337
+ const signal = controller.signal;
338
+
339
+ // 1. User cancel button
340
+ document.getElementById('cancel')?.addEventListener('click', () => {
341
+ controller.abort(); // User cancellation
342
+ });
343
+
344
+ // 2. Resource limit cancellation
345
+ if (await checkMemoryUsage() > MAX_MEMORY) {
346
+ controller.abort(); // Resource limit cancellation
347
+ }
348
+
349
+ // 3. Window unload cancellation
350
+ window.addEventListener('beforeunload', () => {
351
+ controller.abort(); // Page closing cancellation
352
+ });
353
+
354
+ // 4. Timeout cancellation
355
+ setTimeout(() => controller.abort(), 60000); // 1 minute timeout
356
+
357
+ try {
358
+ const result = await llm.ChatCompletion({
359
+ model: 'gpt-4',
360
+ messages: [{ role: 'user', content: 'Complex analysis task...' }],
361
+ cancellationToken: signal // One token, many cancel sources!
362
+ });
363
+
364
+ return result;
365
+ } catch (error) {
366
+ // The AI operation doesn't know WHY it was cancelled - just that it should stop
367
+ console.log('AI operation was cancelled:', error.message);
368
+ }
369
+ }
370
+ ```
371
+
372
+ #### How It Works Internally
373
+
374
+ The AI Core package implements cancellation at multiple levels:
375
+
376
+ 1. **BaseLLM Level**: Checks cancellation token before and during operations
377
+ 2. **Provider Level**: Native cancellation support where available (e.g., fetch API)
378
+ 3. **Fallback Pattern**: Promise.race for providers without native cancellation
379
+
380
+ ```typescript
381
+ // Internal implementation example (simplified)
382
+ async ChatCompletion(params: ChatParams): Promise<ChatResult> {
383
+ // Check if already cancelled before starting
384
+ if (params.cancellationToken?.aborted) {
385
+ throw new Error('Operation was cancelled');
386
+ }
387
+
388
+ // For providers with native cancellation support
389
+ if (this.hasNativeCancellation) {
390
+ return await this.callProviderAPI({
391
+ ...params,
392
+ signal: params.cancellationToken // Native fetch cancellation
393
+ });
394
+ }
395
+
396
+ // Fallback: Promise.race pattern for other providers
397
+ const promises = [
398
+ this.callProviderAPI(params) // The actual AI call
399
+ ];
400
+
401
+ if (params.cancellationToken) {
402
+ promises.push(
403
+ new Promise<never>((_, reject) => {
404
+ params.cancellationToken!.addEventListener('abort', () => {
405
+ reject(new Error('Operation was cancelled'));
406
+ });
407
+ })
408
+ );
409
+ }
410
+
411
+ return await Promise.race(promises);
412
+ }
413
+ ```
414
+
415
+ #### Key Benefits
416
+
417
+ 1. **🎯 Responsive UX**: Users can cancel long-running AI operations instantly
418
+ 2. **💾 Resource Management**: Prevent runaway operations from consuming resources
419
+ 3. **🔄 Composable**: Easy to combine user actions, timeouts, and resource limits
420
+ 4. **📱 Standard API**: Uses native JavaScript AbortSignal - no custom patterns
421
+ 5. **🧹 Clean Cleanup**: Automatic resource cleanup when operations are cancelled
422
+
423
+ The cancellation token pattern provides a **robust, standardized way** to make AI operations responsive and resource-efficient!
424
+
203
425
  ### Text Summarization
204
426
 
205
427
  For summarizing longer text content:
@@ -321,5 +543,166 @@ This architecture allows for a clean separation between common streaming logic a
321
543
  - `@memberjunction/global` - MemberJunction global utilities including class factory
322
544
  - `rxjs` - Reactive extensions for JavaScript
323
545
 
546
+ ## API Reference
547
+
548
+ ### Result Types
549
+
550
+ #### BaseResult
551
+ All operations return results extending `BaseResult`:
552
+ ```typescript
553
+ class BaseResult {
554
+ success: boolean;
555
+ startTime: Date;
556
+ endTime: Date;
557
+ errorMessage: string;
558
+ exception: any;
559
+ timeElapsed: number; // Computed getter
560
+ }
561
+ ```
562
+
563
+ #### ChatResult
564
+ Extends `BaseResult` with chat-specific data:
565
+ ```typescript
566
+ class ChatResult extends BaseResult {
567
+ data: {
568
+ choices: Array<{
569
+ message: ChatCompletionMessage;
570
+ index: number;
571
+ finishReason?: string;
572
+ }>;
573
+ usage: ModelUsage;
574
+ };
575
+ statusText?: string;
576
+ }
577
+ ```
578
+
579
+ ### Chat Message Types
580
+
581
+ #### ChatMessage
582
+ Supports multi-modal content:
583
+ ```typescript
584
+ type ChatMessage = {
585
+ role: 'system' | 'user' | 'assistant';
586
+ content: string | ChatMessageContentBlock[];
587
+ }
588
+
589
+ type ChatMessageContentBlock = {
590
+ type: 'text' | 'image_url' | 'video_url' | 'audio_url' | 'file_url';
591
+ content: string; // URL or base64 encoded content
592
+ }
593
+ ```
594
+
595
+ ### Streaming Callbacks
596
+
597
+ ```typescript
598
+ interface StreamingChatCallbacks {
599
+ OnContent?: (chunk: string, isComplete: boolean) => void;
600
+ OnComplete?: (finalResponse: ChatResult) => void;
601
+ OnError?: (error: any) => void;
602
+ }
603
+
604
+ interface ParallelChatCompletionsCallbacks {
605
+ OnCompletion?: (response: ChatResult, index: number) => void;
606
+ OnError?: (error: any, index: number) => void;
607
+ OnAllCompleted?: (responses: ChatResult[]) => void;
608
+ }
609
+ ```
610
+
611
+ ## Configuration
612
+
613
+ ### API Key Management
614
+
615
+ The package includes a flexible API key management system through the `AIAPIKeys` class:
616
+
617
+ ```typescript
618
+ import { GetAIAPIKey } from '@memberjunction/ai';
619
+
620
+ // Get API key for a specific provider
621
+ const apiKey = GetAIAPIKey('OpenAI');
622
+ ```
623
+
624
+ By default, it looks for environment variables with the pattern: `AI_VENDOR_API_KEY__[PROVIDER_NAME]`
625
+
626
+ Example:
627
+ ```bash
628
+ AI_VENDOR_API_KEY__OPENAI=your-api-key
629
+ AI_VENDOR_API_KEY__ANTHROPIC=your-api-key
630
+ AI_VENDOR_API_KEY__MISTRAL=your-api-key
631
+ ```
632
+
633
+ You can extend the `AIAPIKeys` class to implement custom API key retrieval logic.
634
+
635
+ ### Provider-Specific Settings
636
+
637
+ Many providers support additional configuration beyond the API key:
638
+
639
+ ```typescript
640
+ const llm = new SomeLLM('api-key');
641
+ llm.SetAdditionalSettings({
642
+ baseURL: 'https://custom-endpoint.com',
643
+ organization: 'my-org',
644
+ // Provider-specific settings
645
+ });
646
+ ```
647
+
648
+ ## Integration with MemberJunction
649
+
650
+ While this package can be used standalone, it integrates seamlessly with the MemberJunction framework:
651
+
652
+ - Uses `@memberjunction/global` for class factory pattern and registration
653
+ - Compatible with MemberJunction's metadata system
654
+ - Can leverage MemberJunction's configuration management when available
655
+
656
+ ## Dependencies
657
+
658
+ - `@memberjunction/global` (^2.43.0) - MemberJunction global utilities including class factory
659
+ - `rxjs` (^7.8.1) - Reactive extensions for JavaScript (used in streaming implementations)
660
+ - `dotenv` (^16.4.1) - Environment variable management
661
+ - `typeorm` (^0.3.20) - ORM functionality (optional, only if using with full MemberJunction)
662
+
663
+ ## Development
664
+
665
+ ### Building
666
+
667
+ ```bash
668
+ cd packages/AI/Core
669
+ npm run build
670
+ ```
671
+
672
+ ### TypeScript Configuration
673
+
674
+ The package is configured with TypeScript strict mode and targets ES2022. See `tsconfig.json` for full compiler options.
675
+
676
+ ## Best Practices
677
+
678
+ 1. **Always use the class factory pattern** for maximum flexibility
679
+ 2. **Handle errors gracefully** - check `result.success` before accessing data
680
+ 3. **Monitor token usage** to manage costs and stay within limits
681
+ 4. **Use streaming for long responses** to improve user experience
682
+ 5. **Leverage parallel completions** for comparison or reliability
683
+ 6. **Cache API keys** using the built-in caching mechanism
684
+ 7. **Specify response formats** when you need structured output
685
+
686
+ ## Troubleshooting
687
+
688
+ ### Common Issues
689
+
690
+ 1. **"API key cannot be empty" error**
691
+ - Ensure you're passing a valid API key to the constructor
692
+ - Check environment variables are properly set
693
+
694
+ 2. **Provider not found when using class factory**
695
+ - Make sure to import and call the provider's Load function
696
+ - Verify the provider class name matches exactly
697
+
698
+ 3. **Streaming not working**
699
+ - Check if the provider supports streaming (`llm.SupportsStreaming`)
700
+ - Ensure streaming callbacks are properly defined
701
+
702
+ 4. **Type errors with content blocks**
703
+ - Use the provided type guards and interfaces
704
+ - Ensure content format matches the expected structure
705
+
324
706
  ## License
707
+
325
708
  See the [repository root](../../../LICENSE) for license information.