@mate-academy/llm-gateway 2.5.3 → 3.0.1
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.
- package/README.md +411 -117
- package/dist/LLMService.factory.d.ts +10 -19
- package/dist/LLMService.factory.js +22 -22
- package/dist/LLMService.factory.js.map +1 -1
- package/dist/LLMService.typedefs.d.ts +51 -4
- package/dist/LLMService.typedefs.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.d.ts +2 -3
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.js +1 -1
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAI.entity.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.d.ts +3 -4
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.js +2 -1
- package/dist/providers/GoogleGenerativeAI/GoogleGenerativeAIService.factory.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/schemas/GoogleSchemaAdapter.d.ts +12 -0
- package/dist/providers/GoogleGenerativeAI/schemas/GoogleSchemaAdapter.js +72 -0
- package/dist/providers/GoogleGenerativeAI/schemas/GoogleSchemaAdapter.js.map +1 -0
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.d.ts +2 -3
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js +9 -9
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAIAssistance.service.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.d.ts +2 -3
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js +4 -4
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAICompletion.service.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAISpeechToText.service.d.ts +2 -3
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAISpeechToText.service.js +1 -1
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAISpeechToText.service.js.map +1 -1
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAITextToSpeech.service.d.ts +2 -3
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAITextToSpeech.service.js +1 -1
- package/dist/providers/GoogleGenerativeAI/services/GoogleGenerativeAITextToSpeech.service.js.map +1 -1
- package/dist/providers/OpenAI/OpenAI.entity.d.ts +3 -4
- package/dist/providers/OpenAI/OpenAI.entity.js +1 -1
- package/dist/providers/OpenAI/OpenAI.entity.js.map +1 -1
- package/dist/providers/OpenAI/OpenAIService.factory.d.ts +3 -4
- package/dist/providers/OpenAI/OpenAIService.factory.js +2 -1
- package/dist/providers/OpenAI/OpenAIService.factory.js.map +1 -1
- package/dist/providers/OpenAI/schemas/OpenAISchemaAdapter.d.ts +14 -0
- package/dist/providers/OpenAI/schemas/OpenAISchemaAdapter.js +87 -0
- package/dist/providers/OpenAI/schemas/OpenAISchemaAdapter.js.map +1 -0
- package/dist/providers/OpenAI/services/OpenAIAssistance.service.d.ts +2 -3
- package/dist/providers/OpenAI/services/OpenAIAssistance.service.js +8 -8
- package/dist/providers/OpenAI/services/OpenAIAssistance.service.js.map +1 -1
- package/dist/providers/OpenAI/services/OpenAICompletion.service.d.ts +2 -3
- package/dist/providers/OpenAI/services/OpenAICompletion.service.js +4 -4
- package/dist/providers/OpenAI/services/OpenAICompletion.service.js.map +1 -1
- package/dist/providers/OpenAI/services/OpenAISpeechToText.service.d.ts +2 -3
- package/dist/providers/OpenAI/services/OpenAISpeechToText.service.js +1 -1
- package/dist/providers/OpenAI/services/OpenAISpeechToText.service.js.map +1 -1
- package/dist/providers/OpenAI/services/OpenAITextToSpeech.service.d.ts +2 -3
- package/dist/providers/OpenAI/services/OpenAITextToSpeech.service.js +1 -1
- package/dist/providers/OpenAI/services/OpenAITextToSpeech.service.js.map +1 -1
- package/dist/services/LLMAssistanceService.abstract.d.ts +2 -3
- package/dist/services/LLMAssistanceService.abstract.js.map +1 -1
- package/dist/services/LLMBaseService.abstract.d.ts +3 -4
- package/dist/services/LLMBaseService.abstract.js +1 -1
- package/dist/services/LLMBaseService.abstract.js.map +1 -1
- package/dist/services/LLMCompletionService.abstract.d.ts +2 -3
- package/dist/services/LLMCompletionService.abstract.js.map +1 -1
- package/dist/services/LLMServicePurposeFactory.abstract.d.ts +7 -3
- package/dist/services/LLMServicePurposeFactory.abstract.js.map +1 -1
- package/dist/services/LLMSpeechToTextService.abstract.d.ts +2 -3
- package/dist/services/LLMSpeechToTextService.abstract.js.map +1 -1
- package/dist/services/LLMTextToSpeechService.abstract.d.ts +2 -3
- package/dist/services/LLMTextToSpeechService.abstract.js.map +1 -1
- package/dist/utilities/schema/LLMSchema.d.ts +4 -20
- package/dist/utilities/schema/LLMSchema.js +8 -147
- package/dist/utilities/schema/LLMSchema.js.map +1 -1
- package/dist/utilities/schema/LLMSchemaInterface.d.ts +3 -7
- package/dist/utilities/schema/adapters/SchemaAdapterInterface.d.ts +12 -0
- package/dist/utilities/schema/adapters/SchemaAdapterInterface.js +3 -0
- package/dist/utilities/schema/adapters/SchemaAdapterInterface.js.map +1 -0
- package/dist/utilities/schema/adapters/SchemaAdapterRegistry.d.ts +28 -0
- package/dist/utilities/schema/adapters/SchemaAdapterRegistry.js +36 -0
- package/dist/utilities/schema/adapters/SchemaAdapterRegistry.js.map +1 -0
- package/package.json +8 -9
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@ npm install @mate-academy/llm-gateway
|
|
|
16
16
|
|
|
17
17
|
- Support for multiple LLM providers (OpenAI, Google Generative AI)
|
|
18
18
|
- **Structured Output**: Type-safe JSON responses with schema validation
|
|
19
|
+
- **Extensible Schema Architecture**: Driver pattern with provider-specific adapters
|
|
19
20
|
- Standardized completion service interface
|
|
20
21
|
- Standardized assistance service interface with file handling
|
|
21
22
|
- Speech-to-text transcription capabilities
|
|
@@ -30,6 +31,23 @@ npm install @mate-academy/llm-gateway
|
|
|
30
31
|
|
|
31
32
|
## Usage
|
|
32
33
|
|
|
34
|
+
### Logger Interface
|
|
35
|
+
|
|
36
|
+
The package accepts an optional logger that implements the `LLMLogger` interface. Most logging libraries are compatible (`@mate-academy/logger`, winston, pino, etc.). If no logger is provided, no logging will occur.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// Using @mate-academy/logger (recommended)
|
|
40
|
+
import { logger } from '@mate-academy/logger';
|
|
41
|
+
|
|
42
|
+
// Or simple console logger
|
|
43
|
+
const logger = {
|
|
44
|
+
info: (msg, meta) => console.log(msg, meta),
|
|
45
|
+
error: (msg, meta) => console.error(msg, meta),
|
|
46
|
+
warn: (msg, meta) => console.warn(msg, meta),
|
|
47
|
+
child: (context) => logger,
|
|
48
|
+
};
|
|
49
|
+
```
|
|
50
|
+
|
|
33
51
|
### Basic Setup
|
|
34
52
|
|
|
35
53
|
```typescript
|
|
@@ -47,6 +65,7 @@ import {
|
|
|
47
65
|
LLMModel,
|
|
48
66
|
LLMSchema,
|
|
49
67
|
createPromptTemplate,
|
|
68
|
+
LLMLogger,
|
|
50
69
|
} from '@mate-academy/llm-gateway';
|
|
51
70
|
|
|
52
71
|
// Define provider options
|
|
@@ -65,32 +84,32 @@ const llmProviderOptions = LLMServiceFactory.resolveProviderOptions(
|
|
|
65
84
|
);
|
|
66
85
|
|
|
67
86
|
// Get completion service
|
|
68
|
-
const completionService = LLMServiceFactory.getCompletionService(
|
|
69
|
-
LLMProviders.OpenAI,
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
);
|
|
87
|
+
const completionService = LLMServiceFactory.getCompletionService({
|
|
88
|
+
provider: LLMProviders.OpenAI,
|
|
89
|
+
options: llmProviderOptions,
|
|
90
|
+
logger, // optional - omit for no logging
|
|
91
|
+
});
|
|
73
92
|
|
|
74
93
|
// Get assistance service
|
|
75
|
-
const assistanceService = LLMServiceFactory.getAssistanceService(
|
|
76
|
-
LLMProviders.OpenAI,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
);
|
|
94
|
+
const assistanceService = LLMServiceFactory.getAssistanceService({
|
|
95
|
+
provider: LLMProviders.OpenAI,
|
|
96
|
+
options: llmProviderOptions,
|
|
97
|
+
logger, // optional - omit for no logging
|
|
98
|
+
});
|
|
80
99
|
|
|
81
100
|
// Get speech-to-text service
|
|
82
|
-
const speechToTextService = LLMServiceFactory.getSpeechToTextService(
|
|
83
|
-
LLMProviders.OpenAI,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
);
|
|
101
|
+
const speechToTextService = LLMServiceFactory.getSpeechToTextService({
|
|
102
|
+
provider: LLMProviders.OpenAI,
|
|
103
|
+
options: llmProviderOptions,
|
|
104
|
+
logger, // optional - omit for no logging
|
|
105
|
+
});
|
|
87
106
|
|
|
88
107
|
// Get text-to-speech service
|
|
89
|
-
const textToSpeechService = LLMServiceFactory.getTextToSpeechService(
|
|
90
|
-
LLMProviders.OpenAI,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
);
|
|
108
|
+
const textToSpeechService = LLMServiceFactory.getTextToSpeechService({
|
|
109
|
+
provider: LLMProviders.OpenAI,
|
|
110
|
+
options: llmProviderOptions,
|
|
111
|
+
logger, // optional - omit for no logging
|
|
112
|
+
});
|
|
94
113
|
```
|
|
95
114
|
|
|
96
115
|
### Real-world Example
|
|
@@ -128,29 +147,29 @@ class MyUseCase {
|
|
|
128
147
|
},
|
|
129
148
|
);
|
|
130
149
|
|
|
131
|
-
this.llmCompletionService = LLMServiceFactory.getCompletionService(
|
|
132
|
-
config.llmProvider,
|
|
150
|
+
this.llmCompletionService = LLMServiceFactory.getCompletionService({
|
|
151
|
+
provider: config.llmProvider,
|
|
152
|
+
options: llmProviderOptions,
|
|
133
153
|
logger,
|
|
134
|
-
|
|
135
|
-
);
|
|
154
|
+
});
|
|
136
155
|
|
|
137
|
-
this.llmAssistanceService = LLMServiceFactory.getAssistanceService(
|
|
138
|
-
config.llmProvider,
|
|
156
|
+
this.llmAssistanceService = LLMServiceFactory.getAssistanceService({
|
|
157
|
+
provider: config.llmProvider,
|
|
158
|
+
options: llmProviderOptions,
|
|
139
159
|
logger,
|
|
140
|
-
|
|
141
|
-
);
|
|
160
|
+
});
|
|
142
161
|
|
|
143
|
-
this.llmSpeechToTextService = LLMServiceFactory.getSpeechToTextService(
|
|
144
|
-
config.llmProvider,
|
|
162
|
+
this.llmSpeechToTextService = LLMServiceFactory.getSpeechToTextService({
|
|
163
|
+
provider: config.llmProvider,
|
|
164
|
+
options: llmProviderOptions,
|
|
145
165
|
logger,
|
|
146
|
-
|
|
147
|
-
);
|
|
166
|
+
});
|
|
148
167
|
|
|
149
|
-
this.llmTextToSpeechService = LLMServiceFactory.getTextToSpeechService(
|
|
150
|
-
config.llmProvider,
|
|
168
|
+
this.llmTextToSpeechService = LLMServiceFactory.getTextToSpeechService({
|
|
169
|
+
provider: config.llmProvider,
|
|
170
|
+
options: llmProviderOptions,
|
|
151
171
|
logger,
|
|
152
|
-
|
|
153
|
-
);
|
|
172
|
+
});
|
|
154
173
|
}
|
|
155
174
|
|
|
156
175
|
async processRequest(prompt) {
|
|
@@ -257,7 +276,7 @@ const result = await completionService.sendMessage({
|
|
|
257
276
|
// Type-safe access to structured data
|
|
258
277
|
if (result.data) {
|
|
259
278
|
console.log(result.data.name); // string
|
|
260
|
-
console.log(result.data.age); // number
|
|
279
|
+
console.log(result.data.age); // number
|
|
261
280
|
console.log(result.data.email); // string
|
|
262
281
|
console.log(result.data.isActive); // boolean
|
|
263
282
|
}
|
|
@@ -380,6 +399,65 @@ if (result.data) {
|
|
|
380
399
|
- Use `.min()` and `.max()` instead of `.positive()`, `.negative()`
|
|
381
400
|
- Test schemas with both providers if cross-compatibility is important
|
|
382
401
|
|
|
402
|
+
#### Schema Architecture
|
|
403
|
+
|
|
404
|
+
The package uses a **driver pattern** for schema conversion, automatically adapting schemas to each provider's specific format while maintaining a unified API.
|
|
405
|
+
|
|
406
|
+
Schema adapters are automatically registered when providers are imported, so no manual configuration is needed. For detailed architecture information and extending with new providers, see the [Developer Guide](#developer-guide).
|
|
407
|
+
|
|
408
|
+
### Model Configuration
|
|
409
|
+
|
|
410
|
+
Each model comes with default configuration values that can be customized for your specific needs.
|
|
411
|
+
|
|
412
|
+
#### Accessing and Customizing Models
|
|
413
|
+
|
|
414
|
+
```typescript
|
|
415
|
+
// Get available models from the service
|
|
416
|
+
const models = completionService.models;
|
|
417
|
+
|
|
418
|
+
// Get a specific model
|
|
419
|
+
const model = models[OpenAIModelNames.GPT_4_OMNI];
|
|
420
|
+
|
|
421
|
+
// Customize model configuration
|
|
422
|
+
const customModel = {
|
|
423
|
+
...model,
|
|
424
|
+
config: {
|
|
425
|
+
...model.config,
|
|
426
|
+
temperature: 0.8, // Override temperature (0-2, controls randomness)
|
|
427
|
+
top_p: 0.9, // Override top_p (nucleus sampling)
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
|
|
431
|
+
// Use customized model in requests
|
|
432
|
+
const result = await completionService.sendMessage({
|
|
433
|
+
message: {
|
|
434
|
+
role: LLMRoles.User,
|
|
435
|
+
content: [{ type: LLMMessageContentType.TEXT, text: 'Hello!' }]
|
|
436
|
+
},
|
|
437
|
+
model: customModel,
|
|
438
|
+
});
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
#### Model-Specific Configuration
|
|
442
|
+
|
|
443
|
+
**GPT-5 Models** have special configuration options:
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
const gpt5Model = models[OpenAIModelNames.GPT_5];
|
|
447
|
+
|
|
448
|
+
const customGPT5Model = {
|
|
449
|
+
...gpt5Model,
|
|
450
|
+
config: {
|
|
451
|
+
...gpt5Model.config,
|
|
452
|
+
temperature: 1, // Note: GPT-5 only supports temperature=1
|
|
453
|
+
reasoning_effort: 'high', // 'minimal' | 'medium' | 'high'
|
|
454
|
+
verbosity: 'low', // 'low' | 'medium' | 'high'
|
|
455
|
+
}
|
|
456
|
+
};
|
|
457
|
+
```
|
|
458
|
+
|
|
459
|
+
**Note:** GPT-5 models require `temperature: 1` and cannot be changed. GPT-5-MINI only supports the default temperature.
|
|
460
|
+
|
|
383
461
|
#### File-based Assistance
|
|
384
462
|
|
|
385
463
|
```typescript
|
|
@@ -390,11 +468,11 @@ const uploadedFile = await assistanceService.uploadFile({
|
|
|
390
468
|
mimeType: LLMUploadFileMimeTypes.PLAIN_TEXT,
|
|
391
469
|
});
|
|
392
470
|
|
|
393
|
-
// Create file storage
|
|
471
|
+
// Create file storage with instructions
|
|
394
472
|
const storage = await assistanceService.createFileStorage({
|
|
395
473
|
uploadedFiles: [uploadedFile],
|
|
396
474
|
model: preferredModel,
|
|
397
|
-
instructions: 'Help me analyze this document',
|
|
475
|
+
instructions: 'Help me analyze this document', // Optional context for the storage
|
|
398
476
|
});
|
|
399
477
|
|
|
400
478
|
// Create chat with file context
|
|
@@ -403,7 +481,7 @@ const chat = await assistanceService.createChat({
|
|
|
403
481
|
model: preferredModel,
|
|
404
482
|
history: [],
|
|
405
483
|
files: [uploadedFile],
|
|
406
|
-
instructions: 'Answer questions about the uploaded document',
|
|
484
|
+
instructions: 'Answer questions about the uploaded document', // Initial assistant instructions
|
|
407
485
|
});
|
|
408
486
|
```
|
|
409
487
|
|
|
@@ -414,7 +492,7 @@ const transcription = await speechToTextService.transcribe({
|
|
|
414
492
|
pathToAudio: '/path/to/audio.mp3',
|
|
415
493
|
mimeType: LLMUploadFileMimeTypes.AUDIO_MP3, // Optional, but recommended
|
|
416
494
|
model: preferredModel,
|
|
417
|
-
instructions: 'Transcribe the audio file', // Optional
|
|
495
|
+
instructions: 'Transcribe the audio file', // Optional: custom prompt for transcription context
|
|
418
496
|
});
|
|
419
497
|
|
|
420
498
|
console.log(transcription.text); // Transcribed text
|
|
@@ -563,6 +641,12 @@ Interface for text completion services.
|
|
|
563
641
|
#### Methods
|
|
564
642
|
|
|
565
643
|
- `sendMessage(options)`: Send a message to the LLM and get a completion response
|
|
644
|
+
- `message`: The message to send
|
|
645
|
+
- `model`: The LLM model to use (with optional config overrides)
|
|
646
|
+
- `history`: Optional conversation history
|
|
647
|
+
- `instructions`: Optional system instructions to guide the model's behavior
|
|
648
|
+
- `schema`: Optional schema for structured output
|
|
649
|
+
- `abortSignal`: Optional abort signal for cancellation
|
|
566
650
|
|
|
567
651
|
### LLMAssistanceService
|
|
568
652
|
|
|
@@ -573,10 +657,22 @@ Interface for chat/assistance services with file handling capabilities.
|
|
|
573
657
|
- `uploadFile(fileOptions)`: Upload a file to the LLM service
|
|
574
658
|
- `deleteFile(fileId)`: Delete a file from the LLM service
|
|
575
659
|
- `createFileStorage(options)`: Create a file storage for organizing files
|
|
660
|
+
- `uploadedFiles`: Array of previously uploaded files
|
|
661
|
+
- `model`: The LLM model to use
|
|
662
|
+
- `instructions`: Optional instructions for how to use the stored files
|
|
576
663
|
- `deleteFileStorage(fileStorageId)`: Delete a file storage
|
|
577
664
|
- `createAssistant(options)`: Create an AI assistant with specific instructions
|
|
665
|
+
- `model`: The LLM model to use
|
|
666
|
+
- `instructions`: Optional instructions defining the assistant's behavior
|
|
667
|
+
- `storageIds`: Optional array of storage IDs to give the assistant access to
|
|
668
|
+
- `name`: Optional name for the assistant
|
|
578
669
|
- `deleteAssistant(assistantId)`: Delete an assistant
|
|
579
670
|
- `createChat(options)`: Create a new chat/conversation
|
|
671
|
+
- `model`: The LLM model to use
|
|
672
|
+
- `instructions`: Optional initial instructions for the conversation
|
|
673
|
+
- `history`: Optional conversation history
|
|
674
|
+
- `files`: Optional array of uploaded files
|
|
675
|
+
- `storageId`: Optional storage ID to use
|
|
580
676
|
- `deleteChat(chatId)`: Delete a chat
|
|
581
677
|
- `assistInChat(options)`: Send a message in an existing chat and get an assistant response
|
|
582
678
|
- `countTokens(messages, model)`: Count tokens in messages for context management
|
|
@@ -588,6 +684,10 @@ Interface for converting speech audio to text.
|
|
|
588
684
|
#### Methods
|
|
589
685
|
|
|
590
686
|
- `transcribe(options)`: Convert audio file to text transcription
|
|
687
|
+
- `pathToAudio`: Path to the audio file
|
|
688
|
+
- `mimeType`: Optional MIME type of the audio file
|
|
689
|
+
- `model`: The LLM model to use
|
|
690
|
+
- `instructions`: Optional custom transcription prompt or context
|
|
591
691
|
|
|
592
692
|
### LLMTextToSpeechService
|
|
593
693
|
|
|
@@ -665,6 +765,7 @@ const fullLesson = coursePrompt({
|
|
|
665
765
|
const basicLesson = coursePrompt({
|
|
666
766
|
topicTitle: 'React Hooks',
|
|
667
767
|
hasPrerequisites: false,
|
|
768
|
+
prerequisites: '',
|
|
668
769
|
includeExercises: false,
|
|
669
770
|
difficultyLevel: 'beginner'
|
|
670
771
|
});
|
|
@@ -733,7 +834,7 @@ const reviewInstruction = codeReviewPrompt({
|
|
|
733
834
|
outputFormat: 'structured',
|
|
734
835
|
includeCode: true,
|
|
735
836
|
codeSnippet: 'function example() { /* code here */ }',
|
|
736
|
-
provideExamples: false
|
|
837
|
+
provideExamples: false,
|
|
737
838
|
});
|
|
738
839
|
```
|
|
739
840
|
|
|
@@ -887,15 +988,33 @@ Creates a prompt template function from a template string.
|
|
|
887
988
|
Supports all service types: completion, assistance, speech-to-text, and text-to-speech APIs. For more information, see [OpenAI API documentation](https://platform.openai.com/docs/api-reference).
|
|
888
989
|
|
|
889
990
|
**Available Models:**
|
|
890
|
-
|
|
891
|
-
|
|
991
|
+
|
|
992
|
+
| Model | Purpose | Max Input | Max Output | Notes |
|
|
993
|
+
|-------|---------|-----------|------------|-------|
|
|
994
|
+
| gpt-4o | Completion, Assistance | 128K | 16K | General purpose, balanced |
|
|
995
|
+
| gpt-4o-mini | Completion, Assistance | 128K | 16K | Faster, cost-effective |
|
|
996
|
+
| gpt-4.1 | Completion, Assistance | 1M+ | 32K | Extended context window |
|
|
997
|
+
| gpt-5 | Completion, Assistance | 400K | 128K | Advanced reasoning, requires temperature=1 |
|
|
998
|
+
| gpt-5-mini | Completion, Assistance | 400K | 128K | Smaller GPT-5 variant |
|
|
999
|
+
| gpt-4o-transcribe | Speech-to-Text | 16K | 2K | Optimized for transcription |
|
|
1000
|
+
| gpt-4o-mini-transcribe | Speech-to-Text | 16K | 2K | Cost-effective transcription |
|
|
1001
|
+
| tts-1 | Text-to-Speech | - | - | Standard TTS model |
|
|
1002
|
+
| gpt-4o-mini-tts | Text-to-Speech | - | - | Alternative TTS model |
|
|
892
1003
|
|
|
893
1004
|
### Google Generative AI
|
|
894
1005
|
|
|
895
|
-
Supports completion and
|
|
1006
|
+
Supports completion, assistance, speech-to-text, and text-to-speech APIs through Google's Generative AI models. For more information, see [Google Generative AI documentation](https://ai.google.dev/docs).
|
|
896
1007
|
|
|
897
1008
|
**Available Models:**
|
|
898
|
-
|
|
1009
|
+
|
|
1010
|
+
| Model | Purpose | Max Input | Max Output | Notes |
|
|
1011
|
+
|-------|---------|-----------|------------|-------|
|
|
1012
|
+
| gemini-2.5-flash | Completion, Assistance, Speech-to-Text | 1M+ | 65K | Fast, cost-effective, supports caching for long context |
|
|
1013
|
+
| gemini-2.5-pro | Completion, Assistance, Speech-to-Text | 1M+ | 65K | Advanced reasoning, supports caching for long context |
|
|
1014
|
+
| gemini-2.5-flash-preview-tts | Text-to-Speech | 8K | 16K | Preview TTS model with flash performance |
|
|
1015
|
+
| gemini-2.5-pro-preview-tts | Text-to-Speech | 8K | 16K | Preview TTS model with pro capabilities |
|
|
1016
|
+
|
|
1017
|
+
**Note:** Google Generative AI models support context caching for content longer than 32,768 tokens, which can significantly reduce costs for repeated queries on the same large context.
|
|
899
1018
|
|
|
900
1019
|
## Testing
|
|
901
1020
|
|
|
@@ -968,33 +1087,84 @@ The integration tests cover:
|
|
|
968
1087
|
|
|
969
1088
|
The package provides several test utilities:
|
|
970
1089
|
|
|
971
|
-
|
|
972
|
-
import {
|
|
973
|
-
mockLogger,
|
|
974
|
-
resolveTestConfig,
|
|
975
|
-
hasText,
|
|
976
|
-
hasError,
|
|
977
|
-
} from '@mate-academy/llm-gateway/tests/helpers';
|
|
1090
|
+
#### resolveTestConfig Function
|
|
978
1091
|
|
|
979
|
-
|
|
980
|
-
|
|
1092
|
+
The `resolveTestConfig` function creates standardized test configurations for all supported providers based on the service purpose:
|
|
1093
|
+
|
|
1094
|
+
```typescript
|
|
1095
|
+
import { resolveTestConfig } from '@mate-academy/llm-gateway/tests/helpers';
|
|
981
1096
|
|
|
982
|
-
// Get test
|
|
1097
|
+
// Get test config for completion services
|
|
983
1098
|
const testConfig = resolveTestConfig(LLMPurposes.Completion);
|
|
984
1099
|
|
|
1100
|
+
// testConfig contains configuration for all providers:
|
|
1101
|
+
// {
|
|
1102
|
+
// [LLMProviders.OpenAI]: {
|
|
1103
|
+
// provider: LLMProviders.OpenAI,
|
|
1104
|
+
// availableModels: {...}, // Models available for completion
|
|
1105
|
+
// clientOptions: { apiKey: process.env.OPENAI_SECRET_API_KEY, ... },
|
|
1106
|
+
// requireCredentials: () => void, // Throws if credentials missing
|
|
1107
|
+
// isEnabled: true
|
|
1108
|
+
// },
|
|
1109
|
+
// [LLMProviders.GoogleGenerativeAI]: {
|
|
1110
|
+
// provider: LLMProviders.GoogleGenerativeAI,
|
|
1111
|
+
// availableModels: {...}, // Models available for completion
|
|
1112
|
+
// clientOptions: { apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY },
|
|
1113
|
+
// requireCredentials: () => void, // Throws if credentials missing
|
|
1114
|
+
// isEnabled: true
|
|
1115
|
+
// }
|
|
1116
|
+
// }
|
|
1117
|
+
|
|
1118
|
+
// Use in tests to iterate over all providers
|
|
1119
|
+
Object.values(testConfig).forEach((config) => {
|
|
1120
|
+
const { provider, clientOptions, availableModels, requireCredentials } = config;
|
|
1121
|
+
|
|
1122
|
+
describe(`${provider} Provider`, () => {
|
|
1123
|
+
beforeAll(() => {
|
|
1124
|
+
requireCredentials(); // Ensures API keys are present
|
|
1125
|
+
});
|
|
1126
|
+
|
|
1127
|
+
it('should create service', () => {
|
|
1128
|
+
const service = LLMServiceFactory.getCompletionService({
|
|
1129
|
+
provider,
|
|
1130
|
+
options: clientOptions,
|
|
1131
|
+
logger: mockLogger, // Optional
|
|
1132
|
+
});
|
|
1133
|
+
expect(service).toBeDefined();
|
|
1134
|
+
});
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
#### Mock Logger
|
|
1140
|
+
|
|
1141
|
+
```typescript
|
|
1142
|
+
// Note: Test helpers are for internal use only
|
|
1143
|
+
// When testing your integration, create your own mock logger:
|
|
1144
|
+
const mockLogger = {
|
|
1145
|
+
info: jest.fn(),
|
|
1146
|
+
error: jest.fn(),
|
|
1147
|
+
warn: jest.fn(),
|
|
1148
|
+
child: jest.fn(() => mockLogger),
|
|
1149
|
+
};
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
#### Type Guards
|
|
1153
|
+
|
|
1154
|
+
```typescript
|
|
985
1155
|
// Type guards for test assertions
|
|
986
|
-
if (
|
|
1156
|
+
if ('text' in result && result.text) {
|
|
987
1157
|
expect(result.text).toContain('expected content');
|
|
988
1158
|
}
|
|
989
1159
|
|
|
990
|
-
if (
|
|
1160
|
+
if ('error' in result && result.error) {
|
|
991
1161
|
expect(result.error).toBeDefined();
|
|
992
1162
|
}
|
|
993
1163
|
```
|
|
994
1164
|
|
|
995
1165
|
### Writing Custom Tests
|
|
996
1166
|
|
|
997
|
-
Example of writing a custom integration test
|
|
1167
|
+
Example of writing a custom integration test using `resolveTestConfig`:
|
|
998
1168
|
|
|
999
1169
|
```typescript
|
|
1000
1170
|
import {
|
|
@@ -1007,34 +1177,109 @@ import {
|
|
|
1007
1177
|
LLMServiceFactory,
|
|
1008
1178
|
LLMProviders,
|
|
1009
1179
|
LLMPurposes,
|
|
1180
|
+
resolveTestConfig,
|
|
1010
1181
|
} from '@mate-academy/llm-gateway';
|
|
1011
|
-
|
|
1182
|
+
|
|
1183
|
+
// Create your own mock logger
|
|
1184
|
+
const mockLogger = {
|
|
1185
|
+
info: jest.fn(),
|
|
1186
|
+
error: jest.fn(),
|
|
1187
|
+
warn: jest.fn(),
|
|
1188
|
+
child: jest.fn(() => mockLogger),
|
|
1189
|
+
};
|
|
1012
1190
|
|
|
1013
1191
|
describe('Custom LLM Integration Test', () => {
|
|
1192
|
+
// Use resolveTestConfig for consistent test configuration
|
|
1014
1193
|
const testConfig = resolveTestConfig(LLMPurposes.Completion);
|
|
1015
1194
|
|
|
1016
|
-
|
|
1195
|
+
// Test all enabled providers
|
|
1196
|
+
Object.values(testConfig).forEach((config) => {
|
|
1197
|
+
const { provider, clientOptions, requireCredentials } = config;
|
|
1198
|
+
|
|
1017
1199
|
describe(`${provider} Provider`, () => {
|
|
1018
1200
|
let service;
|
|
1019
1201
|
|
|
1020
1202
|
beforeAll(() => {
|
|
1021
|
-
requireCredentials();
|
|
1022
|
-
|
|
1203
|
+
requireCredentials(); // Validates API keys are present
|
|
1204
|
+
|
|
1205
|
+
service = LLMServiceFactory.getCompletionService({
|
|
1023
1206
|
provider,
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
);
|
|
1207
|
+
options: clientOptions,
|
|
1208
|
+
logger: mockLogger, // Optional - can be omitted
|
|
1209
|
+
});
|
|
1027
1210
|
});
|
|
1028
1211
|
|
|
1029
1212
|
it('should process custom request', async () => {
|
|
1030
1213
|
// Your custom test logic here
|
|
1214
|
+
const result = await service.sendMessage({
|
|
1215
|
+
message: {
|
|
1216
|
+
role: LLMRoles.User,
|
|
1217
|
+
content: [{ type: LLMMessageContentType.TEXT, text: 'Test message' }],
|
|
1218
|
+
},
|
|
1219
|
+
model: Object.values(config.availableModels)[0], // Use first available model
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
// Use type guards for assertions
|
|
1223
|
+
if ('text' in result && result.text) {
|
|
1224
|
+
expect(result.text).toBeDefined();
|
|
1225
|
+
expect(typeof result.text).toBe('string');
|
|
1226
|
+
} else if ('error' in result && result.error) {
|
|
1227
|
+
throw result.error;
|
|
1228
|
+
}
|
|
1031
1229
|
});
|
|
1032
1230
|
});
|
|
1033
1231
|
});
|
|
1034
1232
|
});
|
|
1035
1233
|
```
|
|
1036
1234
|
|
|
1037
|
-
## Developer Guide
|
|
1235
|
+
## Developer Guide
|
|
1236
|
+
|
|
1237
|
+
### Schema Architecture Overview
|
|
1238
|
+
|
|
1239
|
+
The LLM Gateway uses a **driver pattern** for schema conversion, providing clean separation between core schema logic and provider-specific implementations.
|
|
1240
|
+
|
|
1241
|
+
**Core Components:**
|
|
1242
|
+
|
|
1243
|
+
- **`LLMSchema`**: Core schema builder with unified API
|
|
1244
|
+
- **`SchemaAdapterInterface`**: Simple contract for provider-specific schema converters
|
|
1245
|
+
- **`SCHEMA_ADAPTER_REGISTRY`**: Type-safe registry ensuring all providers are handled
|
|
1246
|
+
- **Provider Adapters**: Convert generic JSON Schema to provider-specific formats
|
|
1247
|
+
|
|
1248
|
+
**How It Works:**
|
|
1249
|
+
|
|
1250
|
+
```typescript
|
|
1251
|
+
// The schema uses a unified API regardless of provider
|
|
1252
|
+
const schema = LLMSchema.object({
|
|
1253
|
+
name: LLMSchema.string(),
|
|
1254
|
+
age: LLMSchema.number().min(1),
|
|
1255
|
+
});
|
|
1256
|
+
|
|
1257
|
+
// Internally, services call _toProviderSchema() which automatically
|
|
1258
|
+
// converts to the correct provider-specific format:
|
|
1259
|
+
schema._toProviderSchema(LLMProviders.OpenAI); // → OpenAI JSON Schema format
|
|
1260
|
+
schema._toProviderSchema(LLMProviders.GoogleGenerativeAI); // → Google Type-based format
|
|
1261
|
+
```
|
|
1262
|
+
|
|
1263
|
+
**Provider Schema Adapters:**
|
|
1264
|
+
|
|
1265
|
+
Each provider has its own schema adapter located in `src/providers/{Provider}/schemas/`:
|
|
1266
|
+
|
|
1267
|
+
- **`OpenAISchemaAdapter`**: Converts to OpenAI's JSON Schema format, handles strict mode requirements
|
|
1268
|
+
- **`GoogleSchemaAdapter`**: Converts to Google's Type-based schema format using their `Type` enum
|
|
1269
|
+
|
|
1270
|
+
**Type-Safe Registry:**
|
|
1271
|
+
|
|
1272
|
+
Schema adapters are managed through a centralized, type-safe registry that ensures compile-time safety:
|
|
1273
|
+
|
|
1274
|
+
```typescript
|
|
1275
|
+
// src/utilities/schema/adapters/SchemaAdapterRegistry.ts
|
|
1276
|
+
export const SCHEMA_ADAPTER_REGISTRY = {
|
|
1277
|
+
OpenAI: new OpenAISchemaAdapter(),
|
|
1278
|
+
GoogleGenerativeAI: new GoogleSchemaAdapter(),
|
|
1279
|
+
} as const satisfies Record<LLMProviders, SchemaAdapterInterface | null>;
|
|
1280
|
+
```
|
|
1281
|
+
|
|
1282
|
+
### Adding a New Provider
|
|
1038
1283
|
|
|
1039
1284
|
To add support for a new LLM provider, follow these steps:
|
|
1040
1285
|
|
|
@@ -1049,6 +1294,8 @@ src/providers/YourProvider/
|
|
|
1049
1294
|
├── YourProvider.entity.ts # Provider-specific entity
|
|
1050
1295
|
├── YourProvider.typedefs.ts # TypeScript definitions
|
|
1051
1296
|
├── YourProviderService.factory.ts # Factory for your provider's services
|
|
1297
|
+
├── schemas/ # Schema conversion adapters
|
|
1298
|
+
│ └── YourProviderSchemaAdapter.ts
|
|
1052
1299
|
└── services/ # Provider service implementations
|
|
1053
1300
|
├── index.ts
|
|
1054
1301
|
├── YourProviderCompletionService.ts
|
|
@@ -1123,7 +1370,60 @@ export type LLMModelName = {
|
|
|
1123
1370
|
};
|
|
1124
1371
|
```
|
|
1125
1372
|
|
|
1126
|
-
### 4.
|
|
1373
|
+
### 4. Create Schema Adapter
|
|
1374
|
+
|
|
1375
|
+
Implement a schema adapter in `src/providers/YourProvider/schemas/YourProviderSchemaAdapter.ts`:
|
|
1376
|
+
|
|
1377
|
+
```typescript
|
|
1378
|
+
import { LLMProviders } from '@/LLMService.typedefs';
|
|
1379
|
+
import type { SchemaAdapterInterface } from '@/utilities/schema/adapters/SchemaAdapterInterface';
|
|
1380
|
+
|
|
1381
|
+
export class YourProviderSchemaAdapter implements SchemaAdapterInterface {
|
|
1382
|
+
convertSchema(jsonSchema: any): any {
|
|
1383
|
+
// Convert JSON Schema to your provider's specific format
|
|
1384
|
+
// Example: transform to provider-specific schema structure
|
|
1385
|
+
return this.transformToYourProviderFormat(jsonSchema);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
private transformToYourProviderFormat(jsonSchema: any): any {
|
|
1389
|
+
// Implement provider-specific schema transformation logic
|
|
1390
|
+
// Handle objects, arrays, strings, numbers, etc.
|
|
1391
|
+
// Return the schema in your provider's expected format
|
|
1392
|
+
|
|
1393
|
+
if (jsonSchema.type === 'object') {
|
|
1394
|
+
// Handle object schemas
|
|
1395
|
+
return {
|
|
1396
|
+
// Your provider's object schema format
|
|
1397
|
+
};
|
|
1398
|
+
}
|
|
1399
|
+
|
|
1400
|
+
// Handle other schema types...
|
|
1401
|
+
return jsonSchema;
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
```
|
|
1405
|
+
|
|
1406
|
+
### 5. Add Adapter to Schema Registry
|
|
1407
|
+
|
|
1408
|
+
Update the schema adapter registry in `src/utilities/schema/adapters/SchemaAdapterRegistry.ts`:
|
|
1409
|
+
|
|
1410
|
+
```typescript
|
|
1411
|
+
import { YourProviderSchemaAdapter } from '@/providers/YourProvider/schemas/YourProviderSchemaAdapter';
|
|
1412
|
+
|
|
1413
|
+
export const SCHEMA_ADAPTER_REGISTRY = {
|
|
1414
|
+
OpenAI: new OpenAISchemaAdapter(),
|
|
1415
|
+
GoogleGenerativeAI: new GoogleSchemaAdapter(),
|
|
1416
|
+
YourProvider: new YourProviderSchemaAdapter(), // Add your adapter here
|
|
1417
|
+
// TypeScript will enforce that ALL providers have adapters
|
|
1418
|
+
} as const satisfies Record<LLMProviders, SchemaAdapterInterface | null>;
|
|
1419
|
+
```
|
|
1420
|
+
|
|
1421
|
+
If your provider doesn't support structured output, set it to `null`:
|
|
1422
|
+
```typescript
|
|
1423
|
+
YourProvider: null, // Provider doesn't support structured output
|
|
1424
|
+
```
|
|
1425
|
+
|
|
1426
|
+
### 6. Implement Provider Constants
|
|
1127
1427
|
|
|
1128
1428
|
Define constants in `src/providers/YourProvider/YourProvider.constants.ts`:
|
|
1129
1429
|
|
|
@@ -1221,7 +1521,7 @@ export const YOUR_PROVIDER_SERVICE_BUILDERS: {
|
|
|
1221
1521
|
};
|
|
1222
1522
|
```
|
|
1223
1523
|
|
|
1224
|
-
###
|
|
1524
|
+
### 6. Implement Provider Entity (if needed)
|
|
1225
1525
|
|
|
1226
1526
|
Create the entity class in `src/providers/YourProvider/YourProvider.entity.ts`:
|
|
1227
1527
|
|
|
@@ -1231,28 +1531,28 @@ export class YourProviderEntity {
|
|
|
1231
1531
|
}
|
|
1232
1532
|
```
|
|
1233
1533
|
|
|
1234
|
-
###
|
|
1534
|
+
### 7. Implement Service Classes
|
|
1235
1535
|
|
|
1236
1536
|
Create service implementations in the `services` directory:
|
|
1237
1537
|
|
|
1238
1538
|
**CompletionService (src/providers/YourProvider/services/YourProviderCompletionService.ts)**:
|
|
1239
1539
|
|
|
1240
1540
|
```typescript
|
|
1241
|
-
import {
|
|
1541
|
+
import { LLMLogger } from '../../../LLMService.typedefs';
|
|
1242
1542
|
import { LLMCompletionService } from '../../../services/LLMCompletionService.abstract';
|
|
1243
1543
|
import { CompletionParams, CompletionResult, LLMProviders } from '../../../LLMService.typedefs';
|
|
1244
1544
|
import { YourProviderEntity } from '../YourProvider.entity';
|
|
1245
1545
|
|
|
1246
1546
|
export class YourProviderCompletionService extends LLMCompletionService<LLMProviders.YourProvider> {
|
|
1247
1547
|
constructor(
|
|
1248
|
-
logger:
|
|
1548
|
+
logger: LLMLogger | undefined,
|
|
1249
1549
|
private readonly providerEntity: YourProviderEntity,
|
|
1250
1550
|
) {
|
|
1251
1551
|
super(logger);
|
|
1252
1552
|
}
|
|
1253
1553
|
|
|
1254
1554
|
async complete(params: CompletionParams): Promise<CompletionResult> {
|
|
1255
|
-
this.logger
|
|
1555
|
+
this.logger?.info('Starting completion with YourProvider', { params });
|
|
1256
1556
|
|
|
1257
1557
|
try {
|
|
1258
1558
|
// Implement provider-specific completion logic
|
|
@@ -1262,7 +1562,7 @@ export class YourProviderCompletionService extends LLMCompletionService<LLMProvi
|
|
|
1262
1562
|
// Include other required fields
|
|
1263
1563
|
};
|
|
1264
1564
|
} catch (error) {
|
|
1265
|
-
this.logger
|
|
1565
|
+
this.logger?.error('Error in YourProvider completion', { error });
|
|
1266
1566
|
throw error;
|
|
1267
1567
|
}
|
|
1268
1568
|
}
|
|
@@ -1272,7 +1572,7 @@ export class YourProviderCompletionService extends LLMCompletionService<LLMProvi
|
|
|
1272
1572
|
**AssistanceService (if applicable)**:
|
|
1273
1573
|
|
|
1274
1574
|
```typescript
|
|
1275
|
-
import {
|
|
1575
|
+
import { LLMLogger } from '../../../LLMService.typedefs';
|
|
1276
1576
|
import { LLMAssistanceService } from '../../../services/LLMAssistanceService.abstract';
|
|
1277
1577
|
import {
|
|
1278
1578
|
LLMAssistanceOptions,
|
|
@@ -1283,7 +1583,7 @@ import { YourProviderEntity } from '../YourProvider.entity';
|
|
|
1283
1583
|
|
|
1284
1584
|
export class YourProviderAssistanceService extends LLMAssistanceService<LLMProviders.YourProvider> {
|
|
1285
1585
|
constructor(
|
|
1286
|
-
logger:
|
|
1586
|
+
logger: LLMLogger,
|
|
1287
1587
|
private readonly providerEntity: YourProviderEntity,
|
|
1288
1588
|
) {
|
|
1289
1589
|
super(logger);
|
|
@@ -1311,7 +1611,7 @@ export class YourProviderAssistanceService extends LLMAssistanceService<LLMProvi
|
|
|
1311
1611
|
**SpeechToTextService (if applicable)**:
|
|
1312
1612
|
|
|
1313
1613
|
```typescript
|
|
1314
|
-
import {
|
|
1614
|
+
import { LLMLogger } from '../../../LLMService.typedefs';
|
|
1315
1615
|
import { LLMSpeechToTextService } from '../../../services/LLMSpeechToTextService.abstract';
|
|
1316
1616
|
import {
|
|
1317
1617
|
LLMTranscribeOptions,
|
|
@@ -1322,14 +1622,14 @@ import { YourProviderEntity } from '../YourProvider.entity';
|
|
|
1322
1622
|
|
|
1323
1623
|
export class YourProviderSpeechToTextService extends LLMSpeechToTextService<LLMProviders.YourProvider> {
|
|
1324
1624
|
constructor(
|
|
1325
|
-
logger:
|
|
1625
|
+
logger: LLMLogger | undefined,
|
|
1326
1626
|
private readonly providerEntity: YourProviderEntity,
|
|
1327
1627
|
) {
|
|
1328
1628
|
super(logger);
|
|
1329
1629
|
}
|
|
1330
1630
|
|
|
1331
1631
|
async transcribe(options: LLMTranscribeOptions<typeof this.provider>): Promise<LLMTranscribeResult> {
|
|
1332
|
-
this.logger
|
|
1632
|
+
this.logger?.info('Starting transcription with YourProvider', { options });
|
|
1333
1633
|
|
|
1334
1634
|
try {
|
|
1335
1635
|
// Implement provider-specific transcription logic
|
|
@@ -1337,7 +1637,7 @@ export class YourProviderSpeechToTextService extends LLMSpeechToTextService<LLMP
|
|
|
1337
1637
|
text: 'Transcribed text from audio',
|
|
1338
1638
|
};
|
|
1339
1639
|
} catch (error) {
|
|
1340
|
-
this.logger
|
|
1640
|
+
this.logger?.error('Error in YourProvider transcription', { error });
|
|
1341
1641
|
throw error;
|
|
1342
1642
|
}
|
|
1343
1643
|
}
|
|
@@ -1347,7 +1647,7 @@ export class YourProviderSpeechToTextService extends LLMSpeechToTextService<LLMP
|
|
|
1347
1647
|
**TextToSpeechService (if applicable)**:
|
|
1348
1648
|
|
|
1349
1649
|
```typescript
|
|
1350
|
-
import {
|
|
1650
|
+
import { LLMLogger } from '../../../LLMService.typedefs';
|
|
1351
1651
|
import { LLMTextToSpeechService } from '../../../services/LLMTextToSpeechService.abstract';
|
|
1352
1652
|
import {
|
|
1353
1653
|
LLMCreateSpeechOptions,
|
|
@@ -1358,14 +1658,14 @@ import { YourProviderEntity } from '../YourProvider.entity';
|
|
|
1358
1658
|
|
|
1359
1659
|
export class YourProviderTextToSpeechService extends LLMTextToSpeechService<LLMProviders.YourProvider> {
|
|
1360
1660
|
constructor(
|
|
1361
|
-
logger:
|
|
1661
|
+
logger: LLMLogger | undefined,
|
|
1362
1662
|
private readonly providerEntity: YourProviderEntity,
|
|
1363
1663
|
) {
|
|
1364
1664
|
super(logger);
|
|
1365
1665
|
}
|
|
1366
1666
|
|
|
1367
1667
|
async createSpeech(options: LLMCreateSpeechOptions<typeof this.provider>): Promise<LLMCreateSpeechResult> {
|
|
1368
|
-
this.logger
|
|
1668
|
+
this.logger?.info('Starting speech creation with YourProvider', { options });
|
|
1369
1669
|
|
|
1370
1670
|
try {
|
|
1371
1671
|
// Implement provider-specific speech creation logic
|
|
@@ -1374,14 +1674,14 @@ export class YourProviderTextToSpeechService extends LLMTextToSpeechService<LLMP
|
|
|
1374
1674
|
mimeType: 'audio/mp3',
|
|
1375
1675
|
};
|
|
1376
1676
|
} catch (error) {
|
|
1377
|
-
this.logger
|
|
1677
|
+
this.logger?.error('Error in YourProvider speech creation', { error });
|
|
1378
1678
|
throw error;
|
|
1379
1679
|
}
|
|
1380
1680
|
}
|
|
1381
1681
|
}
|
|
1382
1682
|
```
|
|
1383
1683
|
|
|
1384
|
-
###
|
|
1684
|
+
### 8. Create Service Factory
|
|
1385
1685
|
|
|
1386
1686
|
First, define service builders in `src/providers/YourProvider/YourProvider.constants.ts`:
|
|
1387
1687
|
|
|
@@ -1412,14 +1712,13 @@ export const YOUR_PROVIDER_SERVICE_BUILDERS: {
|
|
|
1412
1712
|
Then, implement the service factory in `src/providers/YourProvider/YourProviderService.factory.ts`:
|
|
1413
1713
|
|
|
1414
1714
|
```typescript
|
|
1415
|
-
import { type Logger } from '@mate-academy/core';
|
|
1416
1715
|
import {
|
|
1417
1716
|
type LLMInstanceOptions,
|
|
1418
1717
|
LLMProviders,
|
|
1419
1718
|
type LLMPurposes,
|
|
1420
1719
|
type LLMServiceByPurpose,
|
|
1421
1720
|
} from '../../LLMService.typedefs';
|
|
1422
|
-
import { LLMServicePurposeFactory } from '../../services';
|
|
1721
|
+
import { LLMServicePurposeFactory, type LLMCreateServiceOptions } from '../../services';
|
|
1423
1722
|
import { YOUR_PROVIDER_SERVICE_BUILDERS } from './YourProvider.constants';
|
|
1424
1723
|
|
|
1425
1724
|
export class YourProviderServiceFactory extends LLMServicePurposeFactory<
|
|
@@ -1428,10 +1727,9 @@ export class YourProviderServiceFactory extends LLMServicePurposeFactory<
|
|
|
1428
1727
|
createService<
|
|
1429
1728
|
Purpose extends LLMPurposes
|
|
1430
1729
|
>(
|
|
1431
|
-
|
|
1432
|
-
logger: Logger,
|
|
1433
|
-
options: LLMInstanceOptions[LLMProviders.YourProvider],
|
|
1730
|
+
serviceOptions: LLMCreateServiceOptions<LLMProviders.YourProvider, Purpose>,
|
|
1434
1731
|
): LLMServiceByPurpose<LLMProviders.YourProvider>[Purpose] {
|
|
1732
|
+
const { purpose, logger, options } = serviceOptions;
|
|
1435
1733
|
const serviceBuilder = YOUR_PROVIDER_SERVICE_BUILDERS[purpose];
|
|
1436
1734
|
|
|
1437
1735
|
if (!serviceBuilder) {
|
|
@@ -1443,7 +1741,7 @@ export class YourProviderServiceFactory extends LLMServicePurposeFactory<
|
|
|
1443
1741
|
}
|
|
1444
1742
|
```
|
|
1445
1743
|
|
|
1446
|
-
###
|
|
1744
|
+
### 9. Update Entry Point Files
|
|
1447
1745
|
|
|
1448
1746
|
Update the provider's `index.ts`:
|
|
1449
1747
|
|
|
@@ -1462,14 +1760,14 @@ Update the main providers `index.ts` at `src/providers/index.ts`:
|
|
|
1462
1760
|
export * from './YourProvider';
|
|
1463
1761
|
```
|
|
1464
1762
|
|
|
1465
|
-
###
|
|
1763
|
+
### 10. Update LLM Service Factory
|
|
1466
1764
|
|
|
1467
1765
|
Modify `src/LLMService.factory.ts` to include your new provider:
|
|
1468
1766
|
|
|
1469
1767
|
```typescript
|
|
1470
1768
|
import {
|
|
1471
1769
|
LLMProviders,
|
|
1472
|
-
|
|
1770
|
+
LLMServiceOptions,
|
|
1473
1771
|
YourProviderOptions,
|
|
1474
1772
|
} from './LLMService.typedefs';
|
|
1475
1773
|
import { YourProviderServiceFactory } from './providers/YourProvider';
|
|
@@ -1487,72 +1785,68 @@ export class LLMServiceFactory {
|
|
|
1487
1785
|
}
|
|
1488
1786
|
|
|
1489
1787
|
static getCompletionService<T extends LLMProviders>(
|
|
1490
|
-
|
|
1491
|
-
logger: Logger,
|
|
1492
|
-
options: any,
|
|
1788
|
+
serviceOptions: LLMServiceOptions<T>,
|
|
1493
1789
|
) {
|
|
1790
|
+
const { provider, options, logger } = serviceOptions;
|
|
1494
1791
|
switch (provider) {
|
|
1495
1792
|
// ... other providers
|
|
1496
1793
|
case LLMProviders.YourProvider:
|
|
1497
|
-
return YourProviderServiceFactory.createService(
|
|
1498
|
-
LLMPurposes.Completion,
|
|
1794
|
+
return YourProviderServiceFactory.createService({
|
|
1795
|
+
purpose: LLMPurposes.Completion,
|
|
1499
1796
|
logger,
|
|
1500
1797
|
options
|
|
1501
|
-
);
|
|
1798
|
+
});
|
|
1502
1799
|
default:
|
|
1503
1800
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
1504
1801
|
}
|
|
1505
1802
|
}
|
|
1506
1803
|
|
|
1507
1804
|
static getAssistanceService<T extends LLMProviders>(
|
|
1508
|
-
|
|
1509
|
-
logger: Logger,
|
|
1510
|
-
options: any,
|
|
1805
|
+
serviceOptions: LLMServiceOptions<T>,
|
|
1511
1806
|
) {
|
|
1807
|
+
const { provider, options, logger } = serviceOptions;
|
|
1512
1808
|
switch (provider) {
|
|
1513
1809
|
// ... other providers
|
|
1514
1810
|
case LLMProviders.YourProvider:
|
|
1515
|
-
return YourProviderServiceFactory.createService(
|
|
1516
|
-
LLMPurposes.Assistance,
|
|
1811
|
+
return YourProviderServiceFactory.createService({
|
|
1812
|
+
purpose: LLMPurposes.Assistance,
|
|
1517
1813
|
logger,
|
|
1518
1814
|
options
|
|
1519
|
-
);
|
|
1815
|
+
});
|
|
1520
1816
|
default:
|
|
1521
1817
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
1522
1818
|
}
|
|
1523
1819
|
}
|
|
1524
1820
|
|
|
1525
1821
|
static getSpeechToTextService<T extends LLMProviders>(
|
|
1526
|
-
|
|
1527
|
-
logger: Logger,
|
|
1528
|
-
options: any,
|
|
1822
|
+
serviceOptions: LLMServiceOptions<T>,
|
|
1529
1823
|
) {
|
|
1824
|
+
const { provider, options, logger } = serviceOptions;
|
|
1530
1825
|
switch (provider) {
|
|
1531
1826
|
// ... other providers
|
|
1532
1827
|
case LLMProviders.YourProvider:
|
|
1533
|
-
return YourProviderServiceFactory.createService(
|
|
1534
|
-
LLMPurposes.SpeechToText,
|
|
1828
|
+
return YourProviderServiceFactory.createService({
|
|
1829
|
+
purpose: LLMPurposes.SpeechToText,
|
|
1535
1830
|
logger,
|
|
1536
1831
|
options
|
|
1537
|
-
);
|
|
1832
|
+
});
|
|
1538
1833
|
default:
|
|
1539
1834
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
1540
1835
|
}
|
|
1541
1836
|
}
|
|
1542
1837
|
|
|
1543
1838
|
static getTextToSpeechService<T extends LLMProviders>(
|
|
1544
|
-
|
|
1545
|
-
logger: Logger,
|
|
1546
|
-
options: any,
|
|
1839
|
+
serviceOptions: LLMServiceOptions<T>,
|
|
1547
1840
|
) {
|
|
1841
|
+
const { provider, options, logger } = serviceOptions;
|
|
1548
1842
|
switch (provider) {
|
|
1549
1843
|
// ... other providers
|
|
1550
1844
|
case LLMProviders.YourProvider:
|
|
1551
|
-
return YourProviderServiceFactory.createService(
|
|
1552
|
-
LLMPurposes.TextToSpeech,
|
|
1845
|
+
return YourProviderServiceFactory.createService({
|
|
1846
|
+
purpose: LLMPurposes.TextToSpeech,
|
|
1553
1847
|
logger,
|
|
1554
1848
|
options
|
|
1555
|
-
);
|
|
1849
|
+
});
|
|
1556
1850
|
default:
|
|
1557
1851
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
1558
1852
|
}
|