@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;
|
|
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;
|
|
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.
|
|
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.
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
-
|
|
132
|
-
|
|
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.
|