@drax/ai-back 3.41.0 → 3.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/dist/agents/DraxAgent.js +3 -1
  2. package/dist/config/ElevenLabsTTSConfig.js +10 -0
  3. package/dist/controllers/AICrudController.js +1 -1
  4. package/dist/controllers/AIGenericController.js +23 -1
  5. package/dist/controllers/DraxAgentController.js +22 -0
  6. package/dist/controllers/TTSGenericController.js +61 -0
  7. package/dist/factory/ElevenLabsTTSProviderFactory.js +13 -0
  8. package/dist/factory/TTSProviderFactory.js +27 -0
  9. package/dist/factory/ai/AiProviderFactory.js +30 -0
  10. package/dist/factory/ai/DeepSeekAiProviderFactory.js +14 -0
  11. package/dist/factory/ai/GoogleAiProviderFactory.js +14 -0
  12. package/dist/factory/ai/OllamaAiProviderFactory.js +14 -0
  13. package/dist/factory/ai/OpenAiProviderFactory.js +14 -0
  14. package/dist/factory/tts/ElevenLabsTTSProviderFactory.js +13 -0
  15. package/dist/factory/tts/TTSProviderFactory.js +27 -0
  16. package/dist/index.js +23 -13
  17. package/dist/interfaces/ITTSProvider.js +1 -0
  18. package/dist/permissions/TTSPermissions.js +6 -0
  19. package/dist/providers/ElevenLabsTTSProvider.js +108 -0
  20. package/dist/providers/ai/DeepSeekAiProvider.js +34 -0
  21. package/dist/providers/ai/GoogleAiProvider.js +370 -0
  22. package/dist/providers/ai/OllamaAiProvider.js +345 -0
  23. package/dist/providers/ai/OpenAiProvider.js +305 -0
  24. package/dist/providers/tts/ElevenLabsTTSProvider.js +108 -0
  25. package/dist/routes/TTSRoutes.js +8 -0
  26. package/dist/schemas/TTSRequestSchema.js +24 -0
  27. package/dist/services/PromptAudioService.js +68 -0
  28. package/dist/services/TTSGenericService.js +21 -0
  29. package/package.json +3 -3
  30. package/src/agents/DraxAgent.ts +3 -1
  31. package/src/config/ElevenLabsTTSConfig.ts +13 -0
  32. package/src/controllers/AICrudController.ts +1 -1
  33. package/src/controllers/AIGenericController.ts +25 -1
  34. package/src/controllers/DraxAgentController.ts +24 -0
  35. package/src/controllers/TTSGenericController.ts +70 -0
  36. package/src/factory/{AiProviderFactory.ts → ai/AiProviderFactory.ts} +3 -3
  37. package/src/factory/ai/DeepSeekAiProviderFactory.ts +27 -0
  38. package/src/factory/{GoogleAiProviderFactory.ts → ai/GoogleAiProviderFactory.ts} +4 -4
  39. package/src/factory/{OllamaAiProviderFactory.ts → ai/OllamaAiProviderFactory.ts} +4 -4
  40. package/src/factory/{OpenAiProviderFactory.ts → ai/OpenAiProviderFactory.ts} +4 -4
  41. package/src/factory/tts/ElevenLabsTTSProviderFactory.ts +26 -0
  42. package/src/factory/tts/TTSProviderFactory.ts +42 -0
  43. package/src/index.ts +60 -11
  44. package/src/interfaces/IAIProvider.ts +38 -1
  45. package/src/interfaces/IDraxAgent.ts +4 -0
  46. package/src/interfaces/ITTSProvider.ts +47 -0
  47. package/src/permissions/AIPermissions.ts +0 -1
  48. package/src/permissions/TTSPermissions.ts +8 -0
  49. package/src/providers/{DeepSeekProvider.ts → ai/DeepSeekAiProvider.ts} +5 -5
  50. package/src/providers/{GoogleAiProvider.ts → ai/GoogleAiProvider.ts} +6 -3
  51. package/src/providers/{OllamaAiProvider.ts → ai/OllamaAiProvider.ts} +6 -3
  52. package/src/providers/{OpenAiProvider.ts → ai/OpenAiProvider.ts} +6 -3
  53. package/src/providers/tts/ElevenLabsTTSProvider.ts +132 -0
  54. package/src/routes/TTSRoutes.ts +13 -0
  55. package/src/schemas/TTSRequestSchema.ts +38 -0
  56. package/src/services/PromptAudioService.ts +87 -0
  57. package/src/services/TTSGenericService.ts +41 -0
  58. package/test/DeepSeekProvider.test.ts +4 -4
  59. package/test/DraxAgent.test.ts +64 -0
  60. package/test/PromptAudioService.test.ts +115 -0
  61. package/tsconfig.tsbuildinfo +1 -1
  62. package/types/agents/DraxAgent.d.ts.map +1 -1
  63. package/types/config/ElevenLabsTTSConfig.d.ts +10 -0
  64. package/types/config/ElevenLabsTTSConfig.d.ts.map +1 -0
  65. package/types/controllers/AIGenericController.d.ts.map +1 -1
  66. package/types/controllers/DraxAgentController.d.ts.map +1 -1
  67. package/types/controllers/TTSGenericController.d.ts +11 -0
  68. package/types/controllers/TTSGenericController.d.ts.map +1 -0
  69. package/types/factory/ElevenLabsTTSProviderFactory.d.ts +8 -0
  70. package/types/factory/ElevenLabsTTSProviderFactory.d.ts.map +1 -0
  71. package/types/factory/TTSProviderFactory.d.ts +15 -0
  72. package/types/factory/TTSProviderFactory.d.ts.map +1 -0
  73. package/types/factory/ai/AiProviderFactory.d.ts +8 -0
  74. package/types/factory/ai/AiProviderFactory.d.ts.map +1 -0
  75. package/types/factory/ai/DeepSeekAiProviderFactory.d.ts +8 -0
  76. package/types/factory/ai/DeepSeekAiProviderFactory.d.ts.map +1 -0
  77. package/types/factory/ai/GoogleAiProviderFactory.d.ts +8 -0
  78. package/types/factory/ai/GoogleAiProviderFactory.d.ts.map +1 -0
  79. package/types/factory/ai/OllamaAiProviderFactory.d.ts +8 -0
  80. package/types/factory/ai/OllamaAiProviderFactory.d.ts.map +1 -0
  81. package/types/factory/ai/OpenAiProviderFactory.d.ts +8 -0
  82. package/types/factory/ai/OpenAiProviderFactory.d.ts.map +1 -0
  83. package/types/factory/tts/ElevenLabsTTSProviderFactory.d.ts +8 -0
  84. package/types/factory/tts/ElevenLabsTTSProviderFactory.d.ts.map +1 -0
  85. package/types/factory/tts/TTSProviderFactory.d.ts +15 -0
  86. package/types/factory/tts/TTSProviderFactory.d.ts.map +1 -0
  87. package/types/index.d.ts +26 -12
  88. package/types/index.d.ts.map +1 -1
  89. package/types/interfaces/IAIProvider.d.ts +32 -1
  90. package/types/interfaces/IAIProvider.d.ts.map +1 -1
  91. package/types/interfaces/IDraxAgent.d.ts +3 -1
  92. package/types/interfaces/IDraxAgent.d.ts.map +1 -1
  93. package/types/interfaces/ITTSProvider.d.ts +39 -0
  94. package/types/interfaces/ITTSProvider.d.ts.map +1 -0
  95. package/types/permissions/TTSPermissions.d.ts +6 -0
  96. package/types/permissions/TTSPermissions.d.ts.map +1 -0
  97. package/types/providers/ElevenLabsTTSProvider.d.ts +38 -0
  98. package/types/providers/ElevenLabsTTSProvider.d.ts.map +1 -0
  99. package/types/providers/ai/DeepSeekAiProvider.d.ts +24 -0
  100. package/types/providers/ai/DeepSeekAiProvider.d.ts.map +1 -0
  101. package/types/providers/ai/GoogleAiProvider.d.ts +63 -0
  102. package/types/providers/ai/GoogleAiProvider.d.ts.map +1 -0
  103. package/types/providers/ai/OllamaAiProvider.d.ts +78 -0
  104. package/types/providers/ai/OllamaAiProvider.d.ts.map +1 -0
  105. package/types/providers/ai/OpenAiProvider.d.ts +97 -0
  106. package/types/providers/ai/OpenAiProvider.d.ts.map +1 -0
  107. package/types/providers/tts/ElevenLabsTTSProvider.d.ts +38 -0
  108. package/types/providers/tts/ElevenLabsTTSProvider.d.ts.map +1 -0
  109. package/types/routes/TTSRoutes.d.ts +4 -0
  110. package/types/routes/TTSRoutes.d.ts.map +1 -0
  111. package/types/schemas/TTSRequestSchema.d.ts +37 -0
  112. package/types/schemas/TTSRequestSchema.d.ts.map +1 -0
  113. package/types/services/PromptAudioService.d.ts +9 -0
  114. package/types/services/PromptAudioService.d.ts.map +1 -0
  115. package/types/services/TTSGenericService.d.ts +17 -0
  116. package/types/services/TTSGenericService.d.ts.map +1 -0
  117. package/src/factory/DeepSeekProviderFactory.ts +0 -27
@@ -1,5 +1,5 @@
1
1
  import { randomUUID } from "node:crypto";
2
- import AiProviderFactory from "../factory/AiProviderFactory.js";
2
+ import AiProviderFactory from "../factory/ai/AiProviderFactory.js";
3
3
  import AgentSessionServiceFactory from "../factory/services/AgentSessionServiceFactory.js";
4
4
  class DraxAgent {
5
5
  constructor(identifier = "default", description = "") {
@@ -78,6 +78,7 @@ class DraxAgent {
78
78
  userAgent: input.userAgent,
79
79
  tenant: input.tenantId ?? session.tenantId ?? null,
80
80
  user: input.userId ?? session.userId ?? null,
81
+ audioResponse: input.audioResponse,
81
82
  });
82
83
  const assistantMessage = this.normalizeOutput(response.output);
83
84
  const now = new Date();
@@ -100,6 +101,7 @@ class DraxAgent {
100
101
  inputTokens: response.inputTokens,
101
102
  outputTokens: response.outputTokens,
102
103
  time: response.time,
104
+ ...(response.audio ? { audio: response.audio } : {}),
103
105
  };
104
106
  }
105
107
  async createSession(input = {}) {
@@ -0,0 +1,10 @@
1
+ var ElevenLabsTTSConfig;
2
+ (function (ElevenLabsTTSConfig) {
3
+ ElevenLabsTTSConfig["ElevenLabsApiKey"] = "ELEVENLABS_API_KEY";
4
+ ElevenLabsTTSConfig["ElevenLabsBaseUrl"] = "ELEVENLABS_BASE_URL";
5
+ ElevenLabsTTSConfig["ElevenLabsModel"] = "ELEVENLABS_MODEL";
6
+ ElevenLabsTTSConfig["ElevenLabsVoiceId"] = "ELEVENLABS_VOICE_ID";
7
+ ElevenLabsTTSConfig["ElevenLabsOutputFormat"] = "ELEVENLABS_OUTPUT_FORMAT";
8
+ })(ElevenLabsTTSConfig || (ElevenLabsTTSConfig = {}));
9
+ export default ElevenLabsTTSConfig;
10
+ export { ElevenLabsTTSConfig };
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { CommonController } from "@drax/common-back";
3
- import AiProviderFactory from "../factory/AiProviderFactory.js";
3
+ import AiProviderFactory from "../factory/ai/AiProviderFactory.js";
4
4
  import AIPermissions from "../permissions/AIPermissions.js";
5
5
  const CrudAiFieldSchema = z.lazy(() => z.object({
6
6
  name: z.string(),
@@ -1,6 +1,6 @@
1
1
  import { z } from "zod";
2
2
  import { CommonController } from "@drax/common-back";
3
- import AiProviderFactory from "../factory/AiProviderFactory.js";
3
+ import AiProviderFactory from "../factory/ai/AiProviderFactory.js";
4
4
  import AIPermissions from "../permissions/AIPermissions.js";
5
5
  const PromptImageSchema = z.object({
6
6
  url: z.string().min(1),
@@ -35,6 +35,27 @@ const PromptInputFileSchema = z.object({
35
35
  mimetype: z.string().optional(),
36
36
  url: z.string().optional(),
37
37
  });
38
+ const PromptAudioVoiceSettingsSchema = z.object({
39
+ stability: z.number().min(0).max(1).optional(),
40
+ similarityBoost: z.number().min(0).max(1).optional(),
41
+ style: z.number().min(0).max(1).optional(),
42
+ useSpeakerBoost: z.boolean().optional(),
43
+ speed: z.number().positive().optional(),
44
+ });
45
+ const PromptAudioParamsSchema = z.object({
46
+ enabled: z.boolean().optional(),
47
+ provider: z.string().optional(),
48
+ voiceId: z.string().optional(),
49
+ model: z.string().optional(),
50
+ outputFormat: z.string().optional(),
51
+ voiceSettings: PromptAudioVoiceSettingsSchema.optional(),
52
+ previousText: z.string().optional(),
53
+ nextText: z.string().optional(),
54
+ languageCode: z.string().optional(),
55
+ seed: z.number().int().optional(),
56
+ operationTitle: z.string().optional(),
57
+ operationGroup: z.string().optional(),
58
+ });
38
59
  const GenericPromptRequestSchema = z.object({
39
60
  systemPrompt: z.string().min(1),
40
61
  userInput: z.string().optional(),
@@ -50,6 +71,7 @@ const GenericPromptRequestSchema = z.object({
50
71
  model: z.string().optional(),
51
72
  operationTitle: z.string().optional(),
52
73
  operationGroup: z.string().optional(),
74
+ audioResponse: z.union([z.boolean(), PromptAudioParamsSchema]).optional(),
53
75
  });
54
76
  class AIGenericController extends CommonController {
55
77
  async prompt(request, reply) {
@@ -28,6 +28,27 @@ const PromptInputFileSchema = z.object({
28
28
  mimetype: z.string().optional(),
29
29
  url: z.string().optional(),
30
30
  });
31
+ const PromptAudioVoiceSettingsSchema = z.object({
32
+ stability: z.number().min(0).max(1).optional(),
33
+ similarityBoost: z.number().min(0).max(1).optional(),
34
+ style: z.number().min(0).max(1).optional(),
35
+ useSpeakerBoost: z.boolean().optional(),
36
+ speed: z.number().positive().optional(),
37
+ });
38
+ const PromptAudioParamsSchema = z.object({
39
+ enabled: z.boolean().optional(),
40
+ provider: z.string().optional(),
41
+ voiceId: z.string().optional(),
42
+ model: z.string().optional(),
43
+ outputFormat: z.string().optional(),
44
+ voiceSettings: PromptAudioVoiceSettingsSchema.optional(),
45
+ previousText: z.string().optional(),
46
+ nextText: z.string().optional(),
47
+ languageCode: z.string().optional(),
48
+ seed: z.number().int().optional(),
49
+ operationTitle: z.string().optional(),
50
+ operationGroup: z.string().optional(),
51
+ });
31
52
  const AgentSessionRequestSchema = z.object({
32
53
  identifier: z.string().min(1).optional(),
33
54
  sessionId: z.string().optional(),
@@ -47,6 +68,7 @@ const AgentMessageRequestSchema = AgentSessionRequestSchema.extend({
47
68
  toolMaxIterations: z.number().optional(),
48
69
  operationTitle: z.string().optional(),
49
70
  operationGroup: z.string().optional(),
71
+ audioResponse: z.union([z.boolean(), PromptAudioParamsSchema]).optional(),
50
72
  });
51
73
  class DraxAgentController extends CommonController {
52
74
  constructor(options = {}) {
@@ -0,0 +1,61 @@
1
+ import { CommonController } from "@drax/common-back";
2
+ import TTSPermissions from "../permissions/TTSPermissions.js";
3
+ import { TTSRequestSchema } from "../schemas/TTSRequestSchema.js";
4
+ import TTSGenericService from "../services/TTSGenericService.js";
5
+ class TTSGenericController extends CommonController {
6
+ constructor(service = new TTSGenericService()) {
7
+ super();
8
+ this.service = service;
9
+ }
10
+ async availableProviders(request, reply) {
11
+ try {
12
+ request.rbac.assertPermission(TTSPermissions.TextToSpeech);
13
+ return reply.send({
14
+ providers: this.service.availableProviders(),
15
+ });
16
+ }
17
+ catch (e) {
18
+ this.handleError(e, reply);
19
+ }
20
+ }
21
+ async textToSpeech(request, reply) {
22
+ try {
23
+ request.rbac.assertPermission(TTSPermissions.TextToSpeech);
24
+ const input = TTSRequestSchema.parse(request.body ?? {});
25
+ const response = await this.service.textToSpeech(input, {
26
+ ip: request.ip,
27
+ userAgent: request.headers["user-agent"],
28
+ tenant: request.rbac?.tenantId ?? null,
29
+ user: request.rbac?.userId ?? null,
30
+ });
31
+ if (input.responseFormat === "base64") {
32
+ return reply.send({
33
+ audio: response.audio.toString("base64"),
34
+ contentType: response.contentType,
35
+ meta: {
36
+ provider: response.provider,
37
+ model: response.model,
38
+ voiceId: response.voiceId,
39
+ outputFormat: response.outputFormat,
40
+ size: response.size,
41
+ time: response.time,
42
+ },
43
+ });
44
+ }
45
+ return reply
46
+ .header("Content-Type", response.contentType)
47
+ .header("Content-Length", response.size)
48
+ .send(response.audio);
49
+ }
50
+ catch (e) {
51
+ if (e?.name === "ZodError") {
52
+ return reply.status(400).send({
53
+ message: e?.message || "TTS validation error",
54
+ });
55
+ }
56
+ this.handleError(e, reply);
57
+ }
58
+ }
59
+ }
60
+ export default TTSGenericController;
61
+ export { TTSGenericController };
@@ -0,0 +1,13 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import ElevenLabsTTSConfig from "../config/ElevenLabsTTSConfig.js";
3
+ import ElevenLabsTTSProvider from "../providers/ElevenLabsTTSProvider.js";
4
+ class ElevenLabsTTSProviderFactory {
5
+ static instance() {
6
+ if (!ElevenLabsTTSProviderFactory.singleton) {
7
+ ElevenLabsTTSProviderFactory.singleton = new ElevenLabsTTSProvider(DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsApiKey), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsModel, "string", "eleven_multilingual_v2"), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsVoiceId), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsBaseUrl, "string", "https://api.elevenlabs.io"), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsOutputFormat, "string", "mp3_44100_128"));
8
+ }
9
+ return ElevenLabsTTSProviderFactory.singleton;
10
+ }
11
+ }
12
+ export default ElevenLabsTTSProviderFactory;
13
+ export { ElevenLabsTTSProviderFactory };
@@ -0,0 +1,27 @@
1
+ import ElevenLabsTTSProviderFactory from "./ElevenLabsTTSProviderFactory.js";
2
+ class TTSProviderFactory {
3
+ static availableProviders() {
4
+ return TTSProviderFactory.providers;
5
+ }
6
+ static instance(provider = "ElevenLabs") {
7
+ if (!TTSProviderFactory.singletons[provider]) {
8
+ switch (provider) {
9
+ case "ElevenLabs":
10
+ TTSProviderFactory.singletons[provider] = ElevenLabsTTSProviderFactory.instance();
11
+ break;
12
+ default:
13
+ throw new Error(`Unsupported TTS provider: ${provider}`);
14
+ }
15
+ }
16
+ return TTSProviderFactory.singletons[provider];
17
+ }
18
+ }
19
+ TTSProviderFactory.singletons = {};
20
+ TTSProviderFactory.providers = [
21
+ {
22
+ name: "ElevenLabs",
23
+ label: "ElevenLabs",
24
+ },
25
+ ];
26
+ export default TTSProviderFactory;
27
+ export { TTSProviderFactory };
@@ -0,0 +1,30 @@
1
+ import OpenAiProviderFactory from "./OpenAiProviderFactory.js";
2
+ import GoogleAiProviderFactory from "./GoogleAiProviderFactory.js";
3
+ import OllamaAiProviderFactory from "./OllamaAiProviderFactory.js";
4
+ import DeepSeekAiProviderFactory from "./DeepSeekAiProviderFactory.js";
5
+ class AiProviderFactory {
6
+ static instance(provider = 'OpenAi') {
7
+ if (!AiProviderFactory.singletons[provider]) {
8
+ switch (provider) {
9
+ case 'OpenAi':
10
+ AiProviderFactory.singletons[provider] = OpenAiProviderFactory.instance();
11
+ break;
12
+ case 'GoogleAi':
13
+ AiProviderFactory.singletons[provider] = GoogleAiProviderFactory.instance();
14
+ break;
15
+ case 'OllamaAi':
16
+ AiProviderFactory.singletons[provider] = OllamaAiProviderFactory.instance();
17
+ break;
18
+ case 'DeepSeek':
19
+ AiProviderFactory.singletons[provider] = DeepSeekAiProviderFactory.instance();
20
+ break;
21
+ default:
22
+ throw new Error(`Unsupported AI provider: ${provider}`);
23
+ }
24
+ }
25
+ return AiProviderFactory.singletons[provider];
26
+ }
27
+ }
28
+ AiProviderFactory.singletons = {};
29
+ export default AiProviderFactory;
30
+ export { AiProviderFactory };
@@ -0,0 +1,14 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import DeepSeekConfig from "../../config/DeepSeekConfig.js";
3
+ import DeepSeekAiProvider from "../../providers/ai/DeepSeekAiProvider.js";
4
+ import AILogServiceFactory from "../services/AILogServiceFactory.js";
5
+ class DeepSeekAiProviderFactory {
6
+ static instance() {
7
+ if (!DeepSeekAiProviderFactory.singleton) {
8
+ DeepSeekAiProviderFactory.singleton = new DeepSeekAiProvider(DraxConfig.getOrLoad(DeepSeekConfig.DeepSeekApiKey), DraxConfig.getOrLoad(DeepSeekConfig.DeepSeekModel), DraxConfig.getOrLoad(DeepSeekConfig.DeepSeekBaseUrl, "string", "https://api.deepseek.com"), DraxConfig.getOrLoad(DeepSeekConfig.DeepSeekVisionModel), AILogServiceFactory.instance);
9
+ }
10
+ return DeepSeekAiProviderFactory.singleton;
11
+ }
12
+ }
13
+ export default DeepSeekAiProviderFactory;
14
+ export { DeepSeekAiProviderFactory };
@@ -0,0 +1,14 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import GoogleAiConfig from "../../config/GoogleAiConfig.js";
3
+ import GoogleAiProvider from "../../providers/ai/GoogleAiProvider.js";
4
+ import AILogServiceFactory from "../services/AILogServiceFactory.js";
5
+ class GoogleAiProviderFactory {
6
+ static instance() {
7
+ if (!GoogleAiProviderFactory.singleton) {
8
+ GoogleAiProviderFactory.singleton = new GoogleAiProvider(DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiApiKey), DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiModel), DraxConfig.getOrLoad(GoogleAiConfig.GoogleAiVisionModel), AILogServiceFactory.instance);
9
+ }
10
+ return GoogleAiProviderFactory.singleton;
11
+ }
12
+ }
13
+ export default GoogleAiProviderFactory;
14
+ export { GoogleAiProviderFactory };
@@ -0,0 +1,14 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import OllamaAiConfig from "../../config/OllamaAiConfig.js";
3
+ import OllamaAiProvider from "../../providers/ai/OllamaAiProvider.js";
4
+ import AILogServiceFactory from "../services/AILogServiceFactory.js";
5
+ class OllamaAiProviderFactory {
6
+ static instance() {
7
+ if (!OllamaAiProviderFactory.singleton) {
8
+ OllamaAiProviderFactory.singleton = new OllamaAiProvider(DraxConfig.getOrLoad(OllamaAiConfig.OllamaAiBaseUrl, "string", "http://localhost:11434"), DraxConfig.getOrLoad(OllamaAiConfig.OllamaAiModel), DraxConfig.getOrLoad(OllamaAiConfig.OllamaAiVisionModel), DraxConfig.getOrLoad(OllamaAiConfig.OllamaAiEmbeddingModel), AILogServiceFactory.instance);
9
+ }
10
+ return OllamaAiProviderFactory.singleton;
11
+ }
12
+ }
13
+ export default OllamaAiProviderFactory;
14
+ export { OllamaAiProviderFactory };
@@ -0,0 +1,14 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import OpenAiConfig from "../../config/OpenAiConfig.js";
3
+ import OpenAiProvider from "../../providers/ai/OpenAiProvider.js";
4
+ import AILogServiceFactory from "../services/AILogServiceFactory.js";
5
+ class OpenAiProviderFactory {
6
+ static instance() {
7
+ if (!OpenAiProviderFactory.singleton) {
8
+ OpenAiProviderFactory.singleton = new OpenAiProvider(DraxConfig.getOrLoad(OpenAiConfig.OpenAiApiKey), DraxConfig.getOrLoad(OpenAiConfig.OpenAiModel), DraxConfig.getOrLoad(OpenAiConfig.OpenAiVisionModel), AILogServiceFactory.instance);
9
+ }
10
+ return OpenAiProviderFactory.singleton;
11
+ }
12
+ }
13
+ export default OpenAiProviderFactory;
14
+ export { OpenAiProviderFactory };
@@ -0,0 +1,13 @@
1
+ import { DraxConfig } from "@drax/common-back";
2
+ import ElevenLabsTTSConfig from "../../config/ElevenLabsTTSConfig.js";
3
+ import ElevenLabsTTSProvider from "../../providers/tts/ElevenLabsTTSProvider.js";
4
+ class ElevenLabsTTSProviderFactory {
5
+ static instance() {
6
+ if (!ElevenLabsTTSProviderFactory.singleton) {
7
+ ElevenLabsTTSProviderFactory.singleton = new ElevenLabsTTSProvider(DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsApiKey), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsModel, "string", "eleven_multilingual_v2"), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsVoiceId), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsBaseUrl, "string", "https://api.elevenlabs.io"), DraxConfig.getOrLoad(ElevenLabsTTSConfig.ElevenLabsOutputFormat, "string", "mp3_44100_128"));
8
+ }
9
+ return ElevenLabsTTSProviderFactory.singleton;
10
+ }
11
+ }
12
+ export default ElevenLabsTTSProviderFactory;
13
+ export { ElevenLabsTTSProviderFactory };
@@ -0,0 +1,27 @@
1
+ import ElevenLabsTTSProviderFactory from "./ElevenLabsTTSProviderFactory.js";
2
+ class TTSProviderFactory {
3
+ static availableProviders() {
4
+ return TTSProviderFactory.providers;
5
+ }
6
+ static instance(provider = "ElevenLabs") {
7
+ if (!TTSProviderFactory.singletons[provider]) {
8
+ switch (provider) {
9
+ case "ElevenLabs":
10
+ TTSProviderFactory.singletons[provider] = ElevenLabsTTSProviderFactory.instance();
11
+ break;
12
+ default:
13
+ throw new Error(`Unsupported TTS provider: ${provider}`);
14
+ }
15
+ }
16
+ return TTSProviderFactory.singletons[provider];
17
+ }
18
+ }
19
+ TTSProviderFactory.singletons = {};
20
+ TTSProviderFactory.providers = [
21
+ {
22
+ name: "ElevenLabs",
23
+ label: "ElevenLabs",
24
+ },
25
+ ];
26
+ export default TTSProviderFactory;
27
+ export { TTSProviderFactory };
package/dist/index.js CHANGED
@@ -2,42 +2,52 @@ import { OpenAiConfig } from "./config/OpenAiConfig.js";
2
2
  import { GoogleAiConfig } from "./config/GoogleAiConfig.js";
3
3
  import { OllamaAiConfig } from "./config/OllamaAiConfig.js";
4
4
  import { DeepSeekConfig } from "./config/DeepSeekConfig.js";
5
+ import { ElevenLabsTTSConfig } from "./config/ElevenLabsTTSConfig.js";
5
6
  import { AILogSchema, AILogBaseSchema } from "./schemas/AILogSchema.js";
7
+ import { TTSRequestSchema, TTSVoiceSettingsSchema } from "./schemas/TTSRequestSchema.js";
6
8
  import AILogModel from "./models/AILogModel.js";
7
9
  import AILogMongoRepository from "./repository/mongo/AILogMongoRepository.js";
8
10
  import AILogSqliteRepository from "./repository/sqlite/AILogSqliteRepository.js";
9
- import { OpenAiProviderFactory } from "./factory/OpenAiProviderFactory.js";
10
- import { GoogleAiProviderFactory } from "./factory/GoogleAiProviderFactory.js";
11
- import { OllamaAiProviderFactory } from "./factory/OllamaAiProviderFactory.js";
12
- import { DeepSeekProviderFactory } from "./factory/DeepSeekProviderFactory.js";
13
- import { AiProviderFactory } from "./factory/AiProviderFactory.js";
11
+ import { OpenAiProviderFactory } from "./factory/ai/OpenAiProviderFactory.js";
12
+ import { GoogleAiProviderFactory } from "./factory/ai/GoogleAiProviderFactory.js";
13
+ import { OllamaAiProviderFactory } from "./factory/ai/OllamaAiProviderFactory.js";
14
+ import { DeepSeekAiProviderFactory } from "./factory/ai/DeepSeekAiProviderFactory.js";
15
+ import { AiProviderFactory } from "./factory/ai/AiProviderFactory.js";
16
+ import { ElevenLabsTTSProviderFactory } from "./factory/tts/ElevenLabsTTSProviderFactory.js";
17
+ import { TTSProviderFactory } from "./factory/tts/TTSProviderFactory.js";
14
18
  import { DraxAgentFactory } from "./factory/DraxAgentFactory.js";
15
19
  import AILogServiceFactory from "./factory/services/AILogServiceFactory.js";
16
- import { OpenAiProvider } from "./providers/OpenAiProvider.js";
17
- import { GoogleAiProvider } from "./providers/GoogleAiProvider.js";
18
- import { OllamaAiProvider } from "./providers/OllamaAiProvider.js";
19
- import { DeepSeekProvider } from "./providers/DeepSeekProvider.js";
20
+ import { OpenAiProvider } from "./providers/ai/OpenAiProvider.js";
21
+ import { GoogleAiProvider } from "./providers/ai/GoogleAiProvider.js";
22
+ import { OllamaAiProvider } from "./providers/ai/OllamaAiProvider.js";
23
+ import { DeepSeekAiProvider } from "./providers/ai/DeepSeekAiProvider.js";
24
+ import { ElevenLabsTTSProvider } from "./providers/tts/ElevenLabsTTSProvider.js";
20
25
  import { BuilderTool } from "./tools/BuilderTool.js";
21
26
  import { KnowledgeService } from "./services/KnowledgeService.js";
22
27
  import { AILogService } from "./services/AILogService.js";
28
+ import { TTSGenericService } from "./services/TTSGenericService.js";
29
+ import { PromptAudioService } from "./services/PromptAudioService.js";
23
30
  import AILogPermissions from "./permissions/AILogPermissions.js";
24
31
  import AgentPermissions from "./permissions/AgentPermissions.js";
25
32
  import AgentSessionPermissions from "./permissions/AgentSessionPermissions.js";
26
33
  import AIPermissions from "./permissions/AIPermissions.js";
34
+ import TTSPermissions from "./permissions/TTSPermissions.js";
27
35
  import AILogController from "./controllers/AILogController.js";
28
36
  import AICrudController from "./controllers/AICrudController.js";
29
37
  import AIGenericController from "./controllers/AIGenericController.js";
38
+ import TTSGenericController from "./controllers/TTSGenericController.js";
30
39
  import DraxAgentController from "./controllers/DraxAgentController.js";
31
40
  import AgentSessionController from "./controllers/AgentSessionController.js";
32
41
  import AILogRoutes from "./routes/AILogRoutes.js";
33
42
  import AIRoutes from "./routes/AIRoutes.js";
43
+ import TTSRoutes from "./routes/TTSRoutes.js";
34
44
  import DraxAgentRoutes from "./routes/DraxAgentRoutes.js";
35
45
  import AgentSessionRoutes from "./routes/AgentSessionRoutes.js";
36
46
  import { DraxAgent } from "./agents/DraxAgent.js";
37
- export { OpenAiConfig, GoogleAiConfig, OllamaAiConfig, DeepSeekConfig, AILogSchema, AILogBaseSchema, AILogModel, AILogMongoRepository, AILogSqliteRepository, OpenAiProviderFactory, GoogleAiProviderFactory, OllamaAiProviderFactory, DeepSeekProviderFactory, AiProviderFactory, DraxAgentFactory, AILogServiceFactory, OpenAiProvider, GoogleAiProvider, OllamaAiProvider, DeepSeekProvider, BuilderTool,
47
+ export { OpenAiConfig, GoogleAiConfig, OllamaAiConfig, DeepSeekConfig, ElevenLabsTTSConfig, AILogSchema, AILogBaseSchema, TTSRequestSchema, TTSVoiceSettingsSchema, AILogModel, AILogMongoRepository, AILogSqliteRepository, OpenAiProviderFactory, GoogleAiProviderFactory, OllamaAiProviderFactory, DeepSeekAiProviderFactory, AiProviderFactory, ElevenLabsTTSProviderFactory, TTSProviderFactory, DraxAgentFactory, AILogServiceFactory, OpenAiProvider, GoogleAiProvider, OllamaAiProvider, DeepSeekAiProvider, ElevenLabsTTSProvider, BuilderTool,
38
48
  //Service
39
- KnowledgeService, AILogService,
49
+ KnowledgeService, AILogService, TTSGenericService, PromptAudioService,
40
50
  //Permissions
41
- AILogPermissions, AgentPermissions, AIPermissions, AgentSessionPermissions,
51
+ AILogPermissions, AgentPermissions, AIPermissions, TTSPermissions, AgentSessionPermissions,
42
52
  //Controllers
43
- AILogController, AICrudController, AIGenericController, DraxAgentController, AgentSessionController, DraxAgent, AILogRoutes, AIRoutes, DraxAgentRoutes, AgentSessionRoutes };
53
+ AILogController, AICrudController, AIGenericController, TTSGenericController, DraxAgentController, AgentSessionController, DraxAgent, AILogRoutes, AIRoutes, TTSRoutes, DraxAgentRoutes, AgentSessionRoutes };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ var TTSPermissions;
2
+ (function (TTSPermissions) {
3
+ TTSPermissions["TextToSpeech"] = "tts:textToSpeech";
4
+ })(TTSPermissions || (TTSPermissions = {}));
5
+ export { TTSPermissions };
6
+ export default TTSPermissions;
@@ -0,0 +1,108 @@
1
+ class ElevenLabsTTSProvider {
2
+ constructor(apiKey, model, voiceId, baseUrl = "https://api.elevenlabs.io", outputFormat) {
3
+ if (!apiKey) {
4
+ throw new Error("ElevenLabs apiKey required");
5
+ }
6
+ if (!model) {
7
+ throw new Error("ElevenLabs model required");
8
+ }
9
+ if (!voiceId) {
10
+ throw new Error("ElevenLabs voiceId required");
11
+ }
12
+ this._apiKey = apiKey;
13
+ this._model = model;
14
+ this._voiceId = voiceId;
15
+ this._baseUrl = baseUrl.replace(/\/+$/, "");
16
+ this._outputFormat = outputFormat;
17
+ }
18
+ get model() {
19
+ if (!this._model) {
20
+ throw new Error("ElevenLabs model not found");
21
+ }
22
+ return this._model;
23
+ }
24
+ get voiceId() {
25
+ if (!this._voiceId) {
26
+ throw new Error("ElevenLabs voiceId not found");
27
+ }
28
+ return this._voiceId;
29
+ }
30
+ mapContentType(outputFormat) {
31
+ if (!outputFormat) {
32
+ return "audio/mpeg";
33
+ }
34
+ if (outputFormat.startsWith("mp3")) {
35
+ return "audio/mpeg";
36
+ }
37
+ if (outputFormat.startsWith("opus")) {
38
+ return "audio/ogg";
39
+ }
40
+ if (outputFormat.startsWith("pcm")) {
41
+ return "audio/wav";
42
+ }
43
+ if (outputFormat.startsWith("ulaw") || outputFormat.startsWith("alaw")) {
44
+ return "audio/basic";
45
+ }
46
+ return "application/octet-stream";
47
+ }
48
+ mapVoiceSettings(voiceSettings) {
49
+ if (!voiceSettings) {
50
+ return undefined;
51
+ }
52
+ return {
53
+ stability: voiceSettings.stability,
54
+ similarity_boost: voiceSettings.similarityBoost,
55
+ style: voiceSettings.style,
56
+ use_speaker_boost: voiceSettings.useSpeakerBoost,
57
+ speed: voiceSettings.speed,
58
+ };
59
+ }
60
+ buildBody(input, model) {
61
+ return {
62
+ text: input.text,
63
+ model_id: model,
64
+ ...(input.voiceSettings ? { voice_settings: this.mapVoiceSettings(input.voiceSettings) } : {}),
65
+ ...(input.previousText ? { previous_text: input.previousText } : {}),
66
+ ...(input.nextText ? { next_text: input.nextText } : {}),
67
+ ...(input.languageCode ? { language_code: input.languageCode } : {}),
68
+ ...(input.seed !== undefined ? { seed: input.seed } : {}),
69
+ };
70
+ }
71
+ async textToSpeech(input) {
72
+ const startedAt = Date.now();
73
+ const model = input.model ?? this.model;
74
+ const voiceId = input.voiceId ?? this.voiceId;
75
+ const outputFormat = input.outputFormat ?? this._outputFormat;
76
+ const url = new URL(`${this._baseUrl}/v1/text-to-speech/${encodeURIComponent(voiceId)}`);
77
+ if (outputFormat) {
78
+ url.searchParams.set("output_format", outputFormat);
79
+ }
80
+ const response = await fetch(url, {
81
+ method: "POST",
82
+ headers: {
83
+ "Accept": this.mapContentType(outputFormat),
84
+ "Content-Type": "application/json",
85
+ "xi-api-key": this._apiKey,
86
+ },
87
+ body: JSON.stringify(this.buildBody(input, model)),
88
+ });
89
+ if (!response.ok) {
90
+ const errorText = await response.text();
91
+ throw new Error(`ElevenLabs TTS request failed (${response.status}): ${errorText}`);
92
+ }
93
+ const audio = Buffer.from(await response.arrayBuffer());
94
+ const contentType = response.headers.get("content-type") ?? this.mapContentType(outputFormat);
95
+ return {
96
+ audio,
97
+ contentType,
98
+ size: audio.byteLength,
99
+ time: Date.now() - startedAt,
100
+ provider: "elevenlabs",
101
+ model,
102
+ voiceId,
103
+ outputFormat,
104
+ };
105
+ }
106
+ }
107
+ export default ElevenLabsTTSProvider;
108
+ export { ElevenLabsTTSProvider };
@@ -0,0 +1,34 @@
1
+ import OpenAI from "openai";
2
+ import OpenAiProvider from "./OpenAiProvider.js";
3
+ class DeepSeekAiProvider extends OpenAiProvider {
4
+ constructor(apiKey, model, baseUrl = "https://api.deepseek.com", visionModel, aiLogService) {
5
+ if (!apiKey) {
6
+ throw new Error("DeepSeek apiKey required");
7
+ }
8
+ if (!model) {
9
+ throw new Error("DeepSeek model required");
10
+ }
11
+ super(apiKey, model, visionModel, aiLogService);
12
+ if (!baseUrl) {
13
+ throw new Error("DeepSeek baseUrl required");
14
+ }
15
+ this._baseUrl = baseUrl;
16
+ }
17
+ get client() {
18
+ if (!this._client) {
19
+ this._client = new OpenAI({
20
+ apiKey: this._apiKey,
21
+ baseURL: this._baseUrl,
22
+ });
23
+ }
24
+ return this._client;
25
+ }
26
+ buildLogPayload(input, params) {
27
+ return {
28
+ ...super.buildLogPayload(input, params),
29
+ provider: "deepseek",
30
+ };
31
+ }
32
+ }
33
+ export default DeepSeekAiProvider;
34
+ export { DeepSeekAiProvider };