@mate-academy/llm-gateway 1.3.0 → 1.3.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 +485 -22
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,9 +16,12 @@ npm install @mate-academy/llm-gateway
|
|
|
16
16
|
|
|
17
17
|
- Support for multiple LLM providers (OpenAI, Google Generative AI)
|
|
18
18
|
- Standardized completion service interface
|
|
19
|
-
- Standardized assistance service interface
|
|
19
|
+
- Standardized assistance service interface with file handling
|
|
20
|
+
- Speech-to-text transcription capabilities
|
|
21
|
+
- Text-to-speech generation capabilities
|
|
20
22
|
- Factory pattern for easy provider selection
|
|
21
23
|
- Consistent logging across all providers
|
|
24
|
+
- Comprehensive testing suite with integration tests
|
|
22
25
|
|
|
23
26
|
## Usage
|
|
24
27
|
|
|
@@ -29,7 +32,9 @@ import {
|
|
|
29
32
|
LLMProviders,
|
|
30
33
|
LLMServiceFactory,
|
|
31
34
|
LLMCompletionService,
|
|
32
|
-
LLMAssistanceService
|
|
35
|
+
LLMAssistanceService,
|
|
36
|
+
LLMSpeechToTextService,
|
|
37
|
+
LLMTextToSpeechService,
|
|
33
38
|
} from '@mate-academy/llm-gateway';
|
|
34
39
|
|
|
35
40
|
// Define provider options
|
|
@@ -60,6 +65,20 @@ const assistanceService = LLMServiceFactory.getAssistanceService(
|
|
|
60
65
|
logger, // your logger instance
|
|
61
66
|
llmProviderOptions,
|
|
62
67
|
);
|
|
68
|
+
|
|
69
|
+
// Get speech-to-text service
|
|
70
|
+
const speechToTextService = LLMServiceFactory.getSpeechToTextService(
|
|
71
|
+
LLMProviders.OpenAI,
|
|
72
|
+
logger, // your logger instance
|
|
73
|
+
llmProviderOptions,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Get text-to-speech service
|
|
77
|
+
const textToSpeechService = LLMServiceFactory.getTextToSpeechService(
|
|
78
|
+
LLMProviders.OpenAI,
|
|
79
|
+
logger, // your logger instance
|
|
80
|
+
llmProviderOptions,
|
|
81
|
+
);
|
|
63
82
|
```
|
|
64
83
|
|
|
65
84
|
### Real-world Example
|
|
@@ -72,11 +91,15 @@ import {
|
|
|
72
91
|
LLMServiceFactory,
|
|
73
92
|
LLMCompletionService,
|
|
74
93
|
LLMAssistanceService,
|
|
94
|
+
LLMSpeechToTextService,
|
|
95
|
+
LLMTextToSpeechService,
|
|
75
96
|
} from '@mate-academy/llm-gateway';
|
|
76
97
|
|
|
77
98
|
class MyUseCase {
|
|
78
99
|
private llmCompletionService: LLMCompletionService<LLMProviders>;
|
|
79
100
|
private llmAssistanceService: LLMAssistanceService<LLMProviders>;
|
|
101
|
+
private llmSpeechToTextService: LLMSpeechToTextService<LLMProviders>;
|
|
102
|
+
private llmTextToSpeechService: LLMTextToSpeechService<LLMProviders>;
|
|
80
103
|
|
|
81
104
|
constructor(logger, config) {
|
|
82
105
|
const llmProviderOptions = LLMServiceFactory.resolveProviderOptions(
|
|
@@ -104,18 +127,136 @@ class MyUseCase {
|
|
|
104
127
|
logger,
|
|
105
128
|
llmProviderOptions,
|
|
106
129
|
);
|
|
130
|
+
|
|
131
|
+
this.llmSpeechToTextService = LLMServiceFactory.getSpeechToTextService(
|
|
132
|
+
config.llmProvider,
|
|
133
|
+
logger,
|
|
134
|
+
llmProviderOptions,
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
this.llmTextToSpeechService = LLMServiceFactory.getTextToSpeechService(
|
|
138
|
+
config.llmProvider,
|
|
139
|
+
logger,
|
|
140
|
+
llmProviderOptions,
|
|
141
|
+
);
|
|
107
142
|
}
|
|
108
143
|
|
|
109
144
|
async processRequest(prompt) {
|
|
110
145
|
// Use completion service
|
|
111
|
-
const completion = await this.llmCompletionService.
|
|
112
|
-
|
|
113
|
-
|
|
146
|
+
const completion = await this.llmCompletionService.sendMessage({
|
|
147
|
+
message: {
|
|
148
|
+
role: 'user',
|
|
149
|
+
content: { type: 'text', text: prompt }
|
|
150
|
+
},
|
|
151
|
+
model: this.getPreferredModel(),
|
|
114
152
|
});
|
|
115
153
|
|
|
116
154
|
return completion;
|
|
117
155
|
}
|
|
156
|
+
|
|
157
|
+
async transcribeAudio(audioPath) {
|
|
158
|
+
// Use speech-to-text service
|
|
159
|
+
const transcription = await this.llmSpeechToTextService.transcribe({
|
|
160
|
+
pathToAudio: audioPath,
|
|
161
|
+
model: this.getPreferredModel(),
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
return transcription;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async generateSpeech(text) {
|
|
168
|
+
// Use text-to-speech service
|
|
169
|
+
const speech = await this.llmTextToSpeechService.createSpeech({
|
|
170
|
+
input: text,
|
|
171
|
+
model: this.getPreferredModel(),
|
|
172
|
+
voice: 'alloy', // OpenAI voice option
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
return speech;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
private getPreferredModel() {
|
|
179
|
+
// Get the appropriate model from the service's available models
|
|
180
|
+
const models = Object.values(this.llmCompletionService.models);
|
|
181
|
+
return models[0]; // Use the first available model
|
|
182
|
+
}
|
|
118
183
|
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
this.llmAssistanceService = LLMServiceFactory.getAssistanceService(
|
|
187
|
+
config.llmProvider,
|
|
188
|
+
logger,
|
|
189
|
+
llmProviderOptions,
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
### Usage Examples
|
|
194
|
+
|
|
195
|
+
#### Basic Text Completion
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
const result = await completionService.sendMessage({
|
|
199
|
+
message: {
|
|
200
|
+
role: 'user',
|
|
201
|
+
content: { type: 'text', text: 'Hello, how are you?' }
|
|
202
|
+
},
|
|
203
|
+
model: preferredModel,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
console.log(result.text); // AI response
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### File-based Assistance
|
|
210
|
+
|
|
211
|
+
```typescript
|
|
212
|
+
// Upload files for context
|
|
213
|
+
const uploadedFile = await assistanceService.uploadFile({
|
|
214
|
+
filename: 'document.pdf',
|
|
215
|
+
content: fileBuffer,
|
|
216
|
+
mimeType: 'application/pdf',
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Create file storage
|
|
220
|
+
const storage = await assistanceService.createFileStorage({
|
|
221
|
+
uploadedFiles: [uploadedFile],
|
|
222
|
+
model: preferredModel,
|
|
223
|
+
instructions: 'Help me analyze this document',
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
// Create chat with file context
|
|
227
|
+
const chat = await assistanceService.createChat({
|
|
228
|
+
storageId: storage.storageId,
|
|
229
|
+
model: preferredModel,
|
|
230
|
+
history: [],
|
|
231
|
+
files: [uploadedFile],
|
|
232
|
+
instructions: 'Answer questions about the uploaded document',
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
#### Speech-to-Text Transcription
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
const transcription = await speechToTextService.transcribe({
|
|
240
|
+
pathToAudio: '/path/to/audio.mp3',
|
|
241
|
+
model: preferredModel,
|
|
242
|
+
language: 'en', // optional
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
console.log(transcription.text); // Transcribed text
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
#### Text-to-Speech Generation
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
const speech = await textToSpeechService.createSpeech({
|
|
252
|
+
input: 'Hello, this will be converted to speech',
|
|
253
|
+
model: preferredModel,
|
|
254
|
+
voice: 'alloy', // OpenAI voice option
|
|
255
|
+
response_format: 'mp3',
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
// Save audio buffer to file
|
|
259
|
+
fs.writeFileSync('output.mp3', speech.audioBuffer);
|
|
119
260
|
```
|
|
120
261
|
|
|
121
262
|
## API Reference
|
|
@@ -126,12 +267,25 @@ Enum of supported LLM providers:
|
|
|
126
267
|
|
|
127
268
|
```typescript
|
|
128
269
|
enum LLMProviders {
|
|
129
|
-
OpenAI = '
|
|
130
|
-
GoogleGenerativeAI = '
|
|
270
|
+
OpenAI = 'OpenAI',
|
|
271
|
+
GoogleGenerativeAI = 'GoogleGenerativeAI',
|
|
131
272
|
// other providers may be added in the future
|
|
132
273
|
}
|
|
133
274
|
```
|
|
134
275
|
|
|
276
|
+
### LLMPurposes
|
|
277
|
+
|
|
278
|
+
Enum of supported service purposes:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
enum LLMPurposes {
|
|
282
|
+
Completion = 'completion',
|
|
283
|
+
Assistance = 'assistance',
|
|
284
|
+
SpeechToText = 'speech_to_text',
|
|
285
|
+
TextToSpeech = 'text_to_speech',
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
135
289
|
### LLMServiceFactory
|
|
136
290
|
|
|
137
291
|
Factory class for creating LLM service instances.
|
|
@@ -141,6 +295,8 @@ Factory class for creating LLM service instances.
|
|
|
141
295
|
- `resolveProviderOptions(provider, optionsMap)`: Resolves the options for the specified provider
|
|
142
296
|
- `getCompletionService(provider, logger, options)`: Creates a completion service instance
|
|
143
297
|
- `getAssistanceService(provider, logger, options)`: Creates an assistance service instance
|
|
298
|
+
- `getSpeechToTextService(provider, logger, options)`: Creates a speech-to-text service instance
|
|
299
|
+
- `getTextToSpeechService(provider, logger, options)`: Creates a text-to-speech service instance
|
|
144
300
|
|
|
145
301
|
### LLMCompletionService
|
|
146
302
|
|
|
@@ -148,30 +304,188 @@ Interface for text completion services.
|
|
|
148
304
|
|
|
149
305
|
#### Methods
|
|
150
306
|
|
|
151
|
-
- `
|
|
307
|
+
- `sendMessage(options)`: Send a message to the LLM and get a completion response
|
|
152
308
|
|
|
153
309
|
### LLMAssistanceService
|
|
154
310
|
|
|
155
|
-
Interface for chat/assistance services.
|
|
311
|
+
Interface for chat/assistance services with file handling capabilities.
|
|
156
312
|
|
|
157
313
|
#### Methods
|
|
158
314
|
|
|
159
|
-
- `
|
|
160
|
-
- `
|
|
161
|
-
- `
|
|
162
|
-
- `
|
|
163
|
-
|
|
164
|
-
|
|
315
|
+
- `uploadFile(file)`: Upload a file to the LLM service
|
|
316
|
+
- `createFileStorage(options)`: Create a file storage for organizing files
|
|
317
|
+
- `createChat(options)`: Create a new chat/conversation
|
|
318
|
+
- `assistInChat(options)`: Send a message in an existing chat and get an assistant response
|
|
319
|
+
|
|
320
|
+
### LLMSpeechToTextService
|
|
321
|
+
|
|
322
|
+
Interface for converting speech audio to text.
|
|
323
|
+
|
|
324
|
+
#### Methods
|
|
325
|
+
|
|
326
|
+
- `transcribe(options)`: Convert audio file to text transcription
|
|
327
|
+
|
|
328
|
+
### LLMTextToSpeechService
|
|
329
|
+
|
|
330
|
+
Interface for converting text to speech audio.
|
|
331
|
+
|
|
332
|
+
#### Methods
|
|
333
|
+
|
|
334
|
+
- `createSpeech(options)`: Convert text to speech audio file
|
|
165
335
|
|
|
166
336
|
## Supported Providers
|
|
167
337
|
|
|
168
338
|
### OpenAI
|
|
169
339
|
|
|
170
|
-
Supports
|
|
340
|
+
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).
|
|
341
|
+
|
|
342
|
+
**Available Models:**
|
|
343
|
+
- GPT-4 models for completion and assistance
|
|
344
|
+
- TTS models for text-to-speech
|
|
171
345
|
|
|
172
346
|
### Google Generative AI
|
|
173
347
|
|
|
174
|
-
Supports completion
|
|
348
|
+
Supports completion and assistance APIs through Google's Generative AI models. For more information, see [Google Generative AI documentation](https://ai.google.dev/docs).
|
|
349
|
+
|
|
350
|
+
**Available Models:**
|
|
351
|
+
- Gemini models for completion, assistance and speech-to-text
|
|
352
|
+
|
|
353
|
+
## Testing
|
|
354
|
+
|
|
355
|
+
The LLM Gateway includes a comprehensive testing suite with both unit and integration tests.
|
|
356
|
+
|
|
357
|
+
### Test Structure
|
|
358
|
+
|
|
359
|
+
The package includes:
|
|
360
|
+
- **Integration tests** for all service types (`src/tests/integration/`)
|
|
361
|
+
- **Test helpers** for common testing utilities (`src/tests/helpers.ts`)
|
|
362
|
+
- **Mock implementations** for testing environments
|
|
363
|
+
- **Audio test files** for speech-to-text testing
|
|
364
|
+
|
|
365
|
+
### Running Tests
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Run all tests with logging
|
|
369
|
+
npm test
|
|
370
|
+
|
|
371
|
+
# Run tests silently (without logs)
|
|
372
|
+
npm run test:silent
|
|
373
|
+
|
|
374
|
+
# Run with specific environment variables
|
|
375
|
+
ENABLE_LOGGING=true npm test
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### Test Configuration
|
|
379
|
+
|
|
380
|
+
Integration tests require API keys for the respective providers:
|
|
381
|
+
|
|
382
|
+
```bash
|
|
383
|
+
# Required environment variables for OpenAI tests
|
|
384
|
+
OPENAI_SECRET_API_KEY=your_openai_api_key
|
|
385
|
+
OPENAI_ORG_ID=your_organization_id # optional
|
|
386
|
+
OPENAI_BASE_URL=https://api.openai.com/v1 # optional
|
|
387
|
+
|
|
388
|
+
# Required environment variables for Google AI tests
|
|
389
|
+
GOOGLE_GENERATIVE_AI_API_KEY=your_google_ai_api_key
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Test Coverage
|
|
393
|
+
|
|
394
|
+
The integration tests cover:
|
|
395
|
+
|
|
396
|
+
1. **Completion Service Tests:**
|
|
397
|
+
- Basic message sending and responses
|
|
398
|
+
- Message history handling
|
|
399
|
+
- Error handling for invalid inputs
|
|
400
|
+
- Model-specific functionality
|
|
401
|
+
|
|
402
|
+
2. **Assistance Service Tests:**
|
|
403
|
+
- File upload and storage creation
|
|
404
|
+
- Chat creation and management
|
|
405
|
+
- Assistant interactions
|
|
406
|
+
- File-based conversations
|
|
407
|
+
|
|
408
|
+
3. **Speech-to-Text Service Tests:**
|
|
409
|
+
- Audio file transcription
|
|
410
|
+
- Multiple audio format support
|
|
411
|
+
- Error handling for invalid files
|
|
412
|
+
- Model-specific transcription quality
|
|
413
|
+
|
|
414
|
+
4. **Text-to-Speech Service Tests:**
|
|
415
|
+
- Text-to-audio conversion
|
|
416
|
+
- Voice selection options
|
|
417
|
+
- Audio format configuration
|
|
418
|
+
- Error handling
|
|
419
|
+
|
|
420
|
+
### Test Helpers
|
|
421
|
+
|
|
422
|
+
The package provides several test utilities:
|
|
423
|
+
|
|
424
|
+
```typescript
|
|
425
|
+
import {
|
|
426
|
+
mockLogger,
|
|
427
|
+
resolveTestConfig,
|
|
428
|
+
hasText,
|
|
429
|
+
hasError,
|
|
430
|
+
} from '@mate-academy/llm-gateway/tests/helpers';
|
|
431
|
+
|
|
432
|
+
// Mock logger for testing
|
|
433
|
+
const logger = mockLogger;
|
|
434
|
+
|
|
435
|
+
// Get test configuration for specific service purpose
|
|
436
|
+
const testConfig = resolveTestConfig(LLMPurposes.Completion);
|
|
437
|
+
|
|
438
|
+
// Type guards for test assertions
|
|
439
|
+
if (hasText(result)) {
|
|
440
|
+
expect(result.text).toContain('expected content');
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (hasError(result)) {
|
|
444
|
+
expect(result.error).toBeDefined();
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
### Writing Custom Tests
|
|
449
|
+
|
|
450
|
+
Example of writing a custom integration test:
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
import {
|
|
454
|
+
describe,
|
|
455
|
+
it,
|
|
456
|
+
expect,
|
|
457
|
+
beforeAll,
|
|
458
|
+
} from '@jest/globals';
|
|
459
|
+
import {
|
|
460
|
+
LLMServiceFactory,
|
|
461
|
+
LLMProviders,
|
|
462
|
+
LLMPurposes,
|
|
463
|
+
} from '@mate-academy/llm-gateway';
|
|
464
|
+
import { mockLogger, resolveTestConfig } from '@mate-academy/llm-gateway/tests/helpers';
|
|
465
|
+
|
|
466
|
+
describe('Custom LLM Integration Test', () => {
|
|
467
|
+
const testConfig = resolveTestConfig(LLMPurposes.Completion);
|
|
468
|
+
|
|
469
|
+
Object.values(testConfig).forEach(({ provider, clientOptions, requireCredentials }) => {
|
|
470
|
+
describe(`${provider} Provider`, () => {
|
|
471
|
+
let service;
|
|
472
|
+
|
|
473
|
+
beforeAll(() => {
|
|
474
|
+
requireCredentials();
|
|
475
|
+
service = LLMServiceFactory.getCompletionService(
|
|
476
|
+
provider,
|
|
477
|
+
mockLogger,
|
|
478
|
+
clientOptions
|
|
479
|
+
);
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
it('should process custom request', async () => {
|
|
483
|
+
// Your custom test logic here
|
|
484
|
+
});
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
});
|
|
488
|
+
```
|
|
175
489
|
|
|
176
490
|
## Developer Guide: Adding a New Provider
|
|
177
491
|
|
|
@@ -325,6 +639,18 @@ export const YOUR_PROVIDER_MODELS: LLMProviderModelsByPurpose<
|
|
|
325
639
|
YourProviderModelNames.MODEL_TWO, // Only MODEL_TWO supports assistance
|
|
326
640
|
],
|
|
327
641
|
),
|
|
642
|
+
[LLMPurposes.SpeechToText]: pick(
|
|
643
|
+
YOUR_PROVIDER_AVAILABLE_MODELS,
|
|
644
|
+
[
|
|
645
|
+
YourProviderModelNames.MODEL_ONE, // Speech-to-text capable model
|
|
646
|
+
],
|
|
647
|
+
),
|
|
648
|
+
[LLMPurposes.TextToSpeech]: pick(
|
|
649
|
+
YOUR_PROVIDER_AVAILABLE_MODELS,
|
|
650
|
+
[
|
|
651
|
+
YourProviderModelNames.MODEL_ONE, // Text-to-speech capable model
|
|
652
|
+
],
|
|
653
|
+
),
|
|
328
654
|
};
|
|
329
655
|
|
|
330
656
|
// Define service builders for each LLM purpose
|
|
@@ -339,6 +665,12 @@ export const YOUR_PROVIDER_SERVICE_BUILDERS: {
|
|
|
339
665
|
[LLMPurposes.Assistance]: (logger, options) => (
|
|
340
666
|
new YourProviderAssistanceService(logger, options)
|
|
341
667
|
),
|
|
668
|
+
[LLMPurposes.SpeechToText]: (logger, options) => (
|
|
669
|
+
new YourProviderSpeechToTextService(logger, options)
|
|
670
|
+
),
|
|
671
|
+
[LLMPurposes.TextToSpeech]: (logger, options) => (
|
|
672
|
+
new YourProviderTextToSpeechService(logger, options)
|
|
673
|
+
),
|
|
342
674
|
};
|
|
343
675
|
```
|
|
344
676
|
|
|
@@ -396,9 +728,8 @@ export class YourProviderCompletionService extends LLMCompletionService<LLMProvi
|
|
|
396
728
|
import { Logger } from '../../../LLMService.typedefs';
|
|
397
729
|
import { LLMAssistanceService } from '../../../services/LLMAssistanceService.abstract';
|
|
398
730
|
import {
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
MessageParams,
|
|
731
|
+
LLMAssistanceOptions,
|
|
732
|
+
LLMAssistanceResult,
|
|
402
733
|
LLMProviders
|
|
403
734
|
} from '../../../LLMService.typedefs';
|
|
404
735
|
import { YourProviderEntity } from '../YourProvider.entity';
|
|
@@ -412,6 +743,94 @@ export class YourProviderAssistanceService extends LLMAssistanceService<LLMProvi
|
|
|
412
743
|
}
|
|
413
744
|
|
|
414
745
|
// Implement required assistance methods
|
|
746
|
+
async uploadFile(file: LLMUploadFile): Promise<LLMUploadFileResult> {
|
|
747
|
+
// Implementation for file upload
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
async createFileStorage(options: LLMCreateFileStorageOptions): Promise<LLMCreateFileStorageResult> {
|
|
751
|
+
// Implementation for file storage creation
|
|
752
|
+
}
|
|
753
|
+
|
|
754
|
+
async createChat(options: LLMCreateChatOptions): Promise<LLMCreateChatResult> {
|
|
755
|
+
// Implementation for chat creation
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
async assistInChat(options: LLMAssistanceOptions): Promise<LLMAssistanceResult> {
|
|
759
|
+
// Implementation for chat assistance
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
```
|
|
763
|
+
|
|
764
|
+
**SpeechToTextService (if applicable)**:
|
|
765
|
+
|
|
766
|
+
```typescript
|
|
767
|
+
import { Logger } from '../../../LLMService.typedefs';
|
|
768
|
+
import { LLMSpeechToTextService } from '../../../services/LLMSpeechToTextService.abstract';
|
|
769
|
+
import {
|
|
770
|
+
LLMTranscribeOptions,
|
|
771
|
+
LLMTranscribeResult,
|
|
772
|
+
LLMProviders
|
|
773
|
+
} from '../../../LLMService.typedefs';
|
|
774
|
+
import { YourProviderEntity } from '../YourProvider.entity';
|
|
775
|
+
|
|
776
|
+
export class YourProviderSpeechToTextService extends LLMSpeechToTextService<LLMProviders.YourProvider> {
|
|
777
|
+
constructor(
|
|
778
|
+
logger: Logger,
|
|
779
|
+
private readonly providerEntity: YourProviderEntity,
|
|
780
|
+
) {
|
|
781
|
+
super(logger);
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
async transcribe(options: LLMTranscribeOptions<typeof this.provider>): Promise<LLMTranscribeResult> {
|
|
785
|
+
this.logger.info('Starting transcription with YourProvider', { options });
|
|
786
|
+
|
|
787
|
+
try {
|
|
788
|
+
// Implement provider-specific transcription logic
|
|
789
|
+
return {
|
|
790
|
+
text: 'Transcribed text from audio',
|
|
791
|
+
};
|
|
792
|
+
} catch (error) {
|
|
793
|
+
this.logger.error('Error in YourProvider transcription', { error });
|
|
794
|
+
throw error;
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
**TextToSpeechService (if applicable)**:
|
|
801
|
+
|
|
802
|
+
```typescript
|
|
803
|
+
import { Logger } from '../../../LLMService.typedefs';
|
|
804
|
+
import { LLMTextToSpeechService } from '../../../services/LLMTextToSpeechService.abstract';
|
|
805
|
+
import {
|
|
806
|
+
LLMCreateSpeechOptions,
|
|
807
|
+
LLMCreateSpeechResult,
|
|
808
|
+
LLMProviders
|
|
809
|
+
} from '../../../LLMService.typedefs';
|
|
810
|
+
import { YourProviderEntity } from '../YourProvider.entity';
|
|
811
|
+
|
|
812
|
+
export class YourProviderTextToSpeechService extends LLMTextToSpeechService<LLMProviders.YourProvider> {
|
|
813
|
+
constructor(
|
|
814
|
+
logger: Logger,
|
|
815
|
+
private readonly providerEntity: YourProviderEntity,
|
|
816
|
+
) {
|
|
817
|
+
super(logger);
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
async createSpeech(options: LLMCreateSpeechOptions<typeof this.provider>): Promise<LLMCreateSpeechResult> {
|
|
821
|
+
this.logger.info('Starting speech creation with YourProvider', { options });
|
|
822
|
+
|
|
823
|
+
try {
|
|
824
|
+
// Implement provider-specific speech creation logic
|
|
825
|
+
return {
|
|
826
|
+
audioBuffer: Buffer.from('audio data'),
|
|
827
|
+
format: 'mp3',
|
|
828
|
+
};
|
|
829
|
+
} catch (error) {
|
|
830
|
+
this.logger.error('Error in YourProvider speech creation', { error });
|
|
831
|
+
throw error;
|
|
832
|
+
}
|
|
833
|
+
}
|
|
415
834
|
}
|
|
416
835
|
```
|
|
417
836
|
|
|
@@ -528,7 +947,11 @@ export class LLMServiceFactory {
|
|
|
528
947
|
switch (provider) {
|
|
529
948
|
// ... other providers
|
|
530
949
|
case LLMProviders.YourProvider:
|
|
531
|
-
return YourProviderServiceFactory.
|
|
950
|
+
return YourProviderServiceFactory.createService(
|
|
951
|
+
LLMPurposes.Completion,
|
|
952
|
+
logger,
|
|
953
|
+
options
|
|
954
|
+
);
|
|
532
955
|
default:
|
|
533
956
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
534
957
|
}
|
|
@@ -542,7 +965,47 @@ export class LLMServiceFactory {
|
|
|
542
965
|
switch (provider) {
|
|
543
966
|
// ... other providers
|
|
544
967
|
case LLMProviders.YourProvider:
|
|
545
|
-
return YourProviderServiceFactory.
|
|
968
|
+
return YourProviderServiceFactory.createService(
|
|
969
|
+
LLMPurposes.Assistance,
|
|
970
|
+
logger,
|
|
971
|
+
options
|
|
972
|
+
);
|
|
973
|
+
default:
|
|
974
|
+
throw new Error(`Unsupported provider: ${provider}`);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
static getSpeechToTextService<T extends LLMProviders>(
|
|
979
|
+
provider: T,
|
|
980
|
+
logger: Logger,
|
|
981
|
+
options: any,
|
|
982
|
+
) {
|
|
983
|
+
switch (provider) {
|
|
984
|
+
// ... other providers
|
|
985
|
+
case LLMProviders.YourProvider:
|
|
986
|
+
return YourProviderServiceFactory.createService(
|
|
987
|
+
LLMPurposes.SpeechToText,
|
|
988
|
+
logger,
|
|
989
|
+
options
|
|
990
|
+
);
|
|
991
|
+
default:
|
|
992
|
+
throw new Error(`Unsupported provider: ${provider}`);
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
static getTextToSpeechService<T extends LLMProviders>(
|
|
997
|
+
provider: T,
|
|
998
|
+
logger: Logger,
|
|
999
|
+
options: any,
|
|
1000
|
+
) {
|
|
1001
|
+
switch (provider) {
|
|
1002
|
+
// ... other providers
|
|
1003
|
+
case LLMProviders.YourProvider:
|
|
1004
|
+
return YourProviderServiceFactory.createService(
|
|
1005
|
+
LLMPurposes.TextToSpeech,
|
|
1006
|
+
logger,
|
|
1007
|
+
options
|
|
1008
|
+
);
|
|
546
1009
|
default:
|
|
547
1010
|
throw new Error(`Unsupported provider: ${provider}`);
|
|
548
1011
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mate-academy/llm-gateway",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "A gateway package for LLM services.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"axios": "^1.9.0",
|
|
66
66
|
"js-tiktoken": "^1.0.20",
|
|
67
67
|
"mime-types": "^3.0.1",
|
|
68
|
-
"openai": "^5.
|
|
68
|
+
"openai": "^5.2.0",
|
|
69
69
|
"uuid": "^11.1.0"
|
|
70
70
|
}
|
|
71
71
|
}
|