chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
import type { AzureTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const azureTtsTool: ToolConfig<AzureTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_azure',
|
||||
name: 'Azure TTS',
|
||||
description: 'Convert text to speech using Azure Cognitive Services',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Azure Speech Services API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Azure voice identifier (e.g., "en-US-JennyNeural", "en-US-GuyNeural", "en-GB-SoniaNeural")',
|
||||
},
|
||||
region: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Azure region (e.g., eastus, westus, westeurope)',
|
||||
},
|
||||
outputFormat: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Output audio format',
|
||||
},
|
||||
rate: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Speaking rate (e.g., +10%, -20%, 1.5)',
|
||||
},
|
||||
pitch: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Voice pitch (e.g., +5Hz, -2st, low)',
|
||||
},
|
||||
style: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Speaking style (e.g., cheerful, sad, angry - neural voices only)',
|
||||
},
|
||||
styleDegree: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Style intensity (0.01 to 2.0)',
|
||||
},
|
||||
role: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Role (e.g., Girl, Boy, YoungAdultFemale)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: AzureTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'azure',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
voiceId: params.voiceId || 'en-US-JennyNeural',
|
||||
region: params.region || 'eastus',
|
||||
outputFormat: params.outputFormat || 'audio-24khz-96kbitrate-mono-mp3',
|
||||
rate: params.rate,
|
||||
pitch: params.pitch,
|
||||
style: params.style,
|
||||
styleDegree: params.styleDegree,
|
||||
role: params.role,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import type { CartesiaTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const cartesiaTtsTool: ToolConfig<CartesiaTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_cartesia',
|
||||
name: 'Cartesia TTS',
|
||||
description: 'Convert text to speech using Cartesia Sonic (ultra-low latency)',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Cartesia API key',
|
||||
},
|
||||
modelId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cartesia model identifier (e.g., "sonic", "sonic-2", "sonic-3", "sonic-multilingual")',
|
||||
},
|
||||
voice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Cartesia voice identifier or embedding (e.g., "a0e99841-438c-4a64-b679-ae501e7d6091")',
|
||||
},
|
||||
language: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Language code for speech synthesis (e.g., "en", "es", "fr", "de", "it", "pt")',
|
||||
},
|
||||
outputFormat: {
|
||||
type: 'json',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Output format configuration (container, encoding, sampleRate)',
|
||||
},
|
||||
speed: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Speech speed multiplier (e.g., 0.5 for slower, 1.0 for normal, 2.0 for faster)',
|
||||
},
|
||||
emotion: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: "Emotion tags for Sonic-3 (e.g., ['positivity:high'])",
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: CartesiaTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'cartesia',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
modelId: params.modelId || 'sonic-3',
|
||||
voice: params.voice,
|
||||
language: params.language || 'en',
|
||||
outputFormat: params.outputFormat || {
|
||||
container: 'mp3',
|
||||
encoding: 'pcm_f32le',
|
||||
sampleRate: 44100,
|
||||
},
|
||||
speed: params.speed,
|
||||
emotion: params.emotion,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
import type { DeepgramTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const deepgramTtsTool: ToolConfig<DeepgramTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_deepgram',
|
||||
name: 'Deepgram TTS',
|
||||
description: 'Convert text to speech using Deepgram Aura',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Deepgram API key',
|
||||
},
|
||||
model: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Deepgram model/voice identifier (e.g., "aura-asteria-en", "aura-luna-en", "aura-2-luna-en")',
|
||||
},
|
||||
voice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Deepgram voice identifier, alternative to model param (e.g., "aura-asteria-en", "aura-orion-en")',
|
||||
},
|
||||
encoding: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Audio encoding (linear16, mp3, opus, aac, flac)',
|
||||
},
|
||||
sampleRate: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Sample rate (8000, 16000, 24000, 48000)',
|
||||
},
|
||||
bitRate: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Bit rate for compressed formats',
|
||||
},
|
||||
container: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Container format (none, wav, ogg)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: DeepgramTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'deepgram',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
model: params.model || params.voice || 'aura-asteria-en',
|
||||
encoding: params.encoding || 'mp3',
|
||||
sampleRate: params.sampleRate,
|
||||
bitRate: params.bitRate,
|
||||
container: params.container || 'none',
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import type { ElevenLabsTtsUnifiedParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsTtsUnifiedTool: ToolConfig<ElevenLabsTtsUnifiedParams, TtsBlockResponse> = {
|
||||
id: 'tts_elevenlabs',
|
||||
name: 'ElevenLabs TTS',
|
||||
description: 'Convert text to speech using ElevenLabs voices',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'ElevenLabs voice identifier (e.g., "21m00Tcm4TlvDq8ikWAM", "AZnzlk1XvdvUeBnXmlld")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'ElevenLabs API key',
|
||||
},
|
||||
modelId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'ElevenLabs model identifier (e.g., "eleven_turbo_v2_5", "eleven_flash_v2_5", "eleven_multilingual_v2")',
|
||||
},
|
||||
stability: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Voice stability (0.0 to 1.0, default: 0.5)',
|
||||
},
|
||||
similarityBoost: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Similarity boost (0.0 to 1.0, default: 0.8)',
|
||||
},
|
||||
style: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Style exaggeration (0.0 to 1.0)',
|
||||
},
|
||||
useSpeakerBoost: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Use speaker boost (default: true)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: ElevenLabsTtsUnifiedParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'elevenlabs',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
voiceId: params.voiceId,
|
||||
modelId: params.modelId || 'eleven_turbo_v2_5',
|
||||
stability: params.stability ?? 0.5,
|
||||
similarityBoost: params.similarityBoost ?? 0.8,
|
||||
style: params.style,
|
||||
useSpeakerBoost: params.useSpeakerBoost ?? true,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
import type { GoogleTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const googleTtsTool: ToolConfig<GoogleTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_google',
|
||||
name: 'Google Cloud TTS',
|
||||
description: 'Convert text to speech using Google Cloud Text-to-Speech',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Google Cloud API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Google Cloud voice identifier (e.g., "en-US-Neural2-A", "en-US-Wavenet-D", "en-GB-Neural2-B")',
|
||||
},
|
||||
languageCode: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'BCP-47 language code for speech synthesis (e.g., "en-US", "es-ES", "fr-FR", "de-DE")',
|
||||
},
|
||||
gender: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Voice gender (MALE, FEMALE, NEUTRAL)',
|
||||
},
|
||||
audioEncoding: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Audio encoding (LINEAR16, MP3, OGG_OPUS, MULAW, ALAW)',
|
||||
},
|
||||
speakingRate: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Speaking rate multiplier from 0.25 to 2.0 (e.g., 0.5 for slower, 1.0 for normal, 1.5 for faster)',
|
||||
},
|
||||
pitch: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Voice pitch (-20.0 to 20.0, default: 0.0)',
|
||||
},
|
||||
volumeGainDb: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Volume gain in dB (-96.0 to 16.0)',
|
||||
},
|
||||
sampleRateHertz: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Sample rate in Hz',
|
||||
},
|
||||
effectsProfileId: {
|
||||
type: 'array',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: "Effects profile (e.g., ['headphone-class-device'])",
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: GoogleTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'google',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
voiceId: params.voiceId,
|
||||
languageCode: params.languageCode,
|
||||
gender: params.gender,
|
||||
audioEncoding: params.audioEncoding || 'MP3',
|
||||
speakingRate: params.speakingRate ?? 1.0,
|
||||
pitch: params.pitch ?? 0.0,
|
||||
volumeGainDb: params.volumeGainDb,
|
||||
sampleRateHertz: params.sampleRateHertz,
|
||||
effectsProfileId: params.effectsProfileId,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
export { azureTtsTool } from './azure'
|
||||
export { cartesiaTtsTool } from './cartesia'
|
||||
export { deepgramTtsTool } from './deepgram'
|
||||
export { elevenLabsTtsUnifiedTool } from './elevenlabs'
|
||||
export { googleTtsTool } from './google'
|
||||
export { openaiTtsTool } from './openai'
|
||||
export { playhtTtsTool } from './playht'
|
||||
export * from './types'
|
||||
@@ -0,0 +1,109 @@
|
||||
import type { OpenAiTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const openaiTtsTool: ToolConfig<OpenAiTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_openai',
|
||||
name: 'OpenAI TTS',
|
||||
description: 'Convert text to speech using OpenAI TTS models',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'OpenAI API key',
|
||||
},
|
||||
model: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'OpenAI TTS model identifier (e.g., "tts-1", "tts-1-hd", "gpt-4o-mini-tts")',
|
||||
},
|
||||
voice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'OpenAI voice identifier (e.g., "alloy", "ash", "ballad", "coral", "echo", "sage", "shimmer")',
|
||||
},
|
||||
responseFormat: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Audio format (mp3, opus, aac, flac, wav, pcm)',
|
||||
},
|
||||
speed: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Speech speed multiplier from 0.25 to 4.0 (e.g., 0.5 for slower, 1.0 for normal, 2.0 for faster)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: OpenAiTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'openai',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
model: params.model || 'tts-1',
|
||||
voice: params.voice || 'alloy',
|
||||
responseFormat: params.responseFormat || 'mp3',
|
||||
speed: params.speed || 1.0,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import type { PlayHtTtsParams, TtsBlockResponse } from '@/tools/tts/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const playhtTtsTool: ToolConfig<PlayHtTtsParams, TtsBlockResponse> = {
|
||||
id: 'tts_playht',
|
||||
name: 'PlayHT TTS',
|
||||
description: 'Convert text to speech using PlayHT (voice cloning)',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The text content to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PlayHT API key (AUTHORIZATION header)',
|
||||
},
|
||||
userId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'PlayHT user ID (X-USER-ID header)',
|
||||
},
|
||||
voice: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'PlayHT voice identifier or manifest URL (e.g., "s3://voice-cloning-zero-shot/...")',
|
||||
},
|
||||
quality: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Quality level (draft, standard, premium)',
|
||||
},
|
||||
outputFormat: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Output format (mp3, wav, ogg, flac, mulaw)',
|
||||
},
|
||||
speed: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Speech speed multiplier from 0.5 to 2.0 (e.g., 0.5 for slower, 1.0 for normal, 1.5 for faster)',
|
||||
},
|
||||
temperature: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Creativity/randomness (0.0 to 2.0)',
|
||||
},
|
||||
voiceGuidance: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Voice stability (1.0 to 6.0)',
|
||||
},
|
||||
textGuidance: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Text adherence (1.0 to 6.0)',
|
||||
},
|
||||
sampleRate: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-only',
|
||||
description: 'Sample rate (8000, 16000, 22050, 24000, 44100, 48000)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts/unified',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: PlayHtTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
provider: 'playht',
|
||||
text: params.text,
|
||||
apiKey: params.apiKey,
|
||||
userId: params.userId,
|
||||
voice: params.voice,
|
||||
quality: params.quality || 'standard',
|
||||
outputFormat: params.outputFormat || 'mp3',
|
||||
speed: params.speed ?? 1.0,
|
||||
temperature: params.temperature,
|
||||
voiceGuidance: params.voiceGuidance,
|
||||
textGuidance: params.textGuidance,
|
||||
sampleRate: params.sampleRate,
|
||||
workspaceId: params._context?.workspaceId,
|
||||
workflowId: params._context?.workflowId,
|
||||
executionId: params._context?.executionId,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
|
||||
if (!response.ok || data.error) {
|
||||
return {
|
||||
success: false,
|
||||
error: data.error || 'TTS generation failed',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
duration: data.duration,
|
||||
characterCount: data.characterCount,
|
||||
format: data.format,
|
||||
provider: data.provider,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL to the generated audio file' },
|
||||
audioFile: { type: 'file', description: 'Generated audio file object' },
|
||||
duration: { type: 'number', description: 'Audio duration in seconds' },
|
||||
characterCount: { type: 'number', description: 'Number of characters processed' },
|
||||
format: { type: 'string', description: 'Audio format' },
|
||||
provider: { type: 'string', description: 'TTS provider used' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,321 @@
|
||||
import type { UserFile } from '@/executor/types'
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
export type TtsProvider =
|
||||
| 'openai'
|
||||
| 'deepgram'
|
||||
| 'elevenlabs'
|
||||
| 'cartesia'
|
||||
| 'google'
|
||||
| 'azure'
|
||||
| 'playht'
|
||||
|
||||
// OpenAI TTS Types
|
||||
export interface OpenAiTtsParams {
|
||||
text: string
|
||||
model?: 'tts-1' | 'tts-1-hd' | 'gpt-4o-mini-tts'
|
||||
voice?:
|
||||
| 'alloy'
|
||||
| 'ash'
|
||||
| 'ballad'
|
||||
| 'cedar'
|
||||
| 'coral'
|
||||
| 'echo'
|
||||
| 'marin'
|
||||
| 'sage'
|
||||
| 'shimmer'
|
||||
| 'verse'
|
||||
responseFormat?: 'mp3' | 'opus' | 'aac' | 'flac' | 'wav' | 'pcm'
|
||||
speed?: number // 0.25 to 4.0
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// Deepgram TTS Types
|
||||
export interface DeepgramTtsParams {
|
||||
text: string
|
||||
model?: string // e.g., 'aura-2'
|
||||
voice?: string // e.g., 'aura-asteria-en', 'aura-luna-en', etc.
|
||||
encoding?: 'linear16' | 'mp3' | 'opus' | 'aac' | 'flac' | 'mulaw' | 'alaw'
|
||||
sampleRate?: number // 8000, 16000, 24000, 48000
|
||||
bitRate?: number // For compressed formats
|
||||
container?: 'none' | 'wav' | 'ogg'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// ElevenLabs TTS Types
|
||||
export interface ElevenLabsTtsUnifiedParams {
|
||||
text: string
|
||||
voiceId: string
|
||||
modelId?: string
|
||||
stability?: number // 0.0 to 1.0
|
||||
similarityBoost?: number // 0.0 to 1.0
|
||||
style?: number // 0.0 to 1.0
|
||||
useSpeakerBoost?: boolean
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// Cartesia TTS Types
|
||||
export interface CartesiaTtsParams {
|
||||
text: string
|
||||
modelId?: string // e.g., 'sonic-english', 'sonic-multilingual'
|
||||
voice?: string // Voice ID or embedding
|
||||
language?: string // Language code (en, es, fr, de, it, pt, etc.)
|
||||
outputFormat?: {
|
||||
container?: 'raw' | 'wav' | 'mp3' | 'ogg'
|
||||
encoding?: 'pcm_f32le' | 'pcm_s16le' | 'pcm_mulaw' | 'pcm_alaw'
|
||||
sampleRate?: number // 8000, 16000, 22050, 24000, 44100, 48000
|
||||
}
|
||||
speed?: number // Speed multiplier
|
||||
emotion?: string[] // For Sonic-3: e.g., ['positivity:high', 'curiosity:medium']
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// Google Cloud TTS Types
|
||||
export interface GoogleTtsParams {
|
||||
text: string
|
||||
voiceId?: string // e.g., 'en-US-Neural2-A'
|
||||
languageCode?: string // e.g., 'en-US'
|
||||
gender?: 'MALE' | 'FEMALE' | 'NEUTRAL'
|
||||
audioEncoding?: 'LINEAR16' | 'MP3' | 'OGG_OPUS' | 'MULAW' | 'ALAW'
|
||||
speakingRate?: number // 0.25 to 2.0
|
||||
pitch?: number // -20.0 to 20.0
|
||||
volumeGainDb?: number // -96.0 to 16.0
|
||||
sampleRateHertz?: number
|
||||
effectsProfileId?: string[] // e.g., ['headphone-class-device']
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// Azure TTS Types
|
||||
export interface AzureTtsParams {
|
||||
text: string
|
||||
voiceId?: string // e.g., 'en-US-JennyNeural'
|
||||
region?: string // e.g., 'eastus', 'westus'
|
||||
outputFormat?:
|
||||
| 'riff-8khz-16bit-mono-pcm'
|
||||
| 'riff-24khz-16bit-mono-pcm'
|
||||
| 'audio-24khz-48kbitrate-mono-mp3'
|
||||
| 'audio-24khz-96kbitrate-mono-mp3'
|
||||
| 'audio-48khz-96kbitrate-mono-mp3'
|
||||
rate?: string // e.g., '+10%', '-20%', '1.5'
|
||||
pitch?: string // e.g., '+5Hz', '-2st', 'low'
|
||||
style?: string // e.g., 'cheerful', 'sad', 'angry' (neural voices only)
|
||||
styleDegree?: number // 0.01 to 2.0
|
||||
role?: string // e.g., 'Girl', 'Boy', 'YoungAdultFemale'
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
// PlayHT TTS Types
|
||||
export interface PlayHtTtsParams {
|
||||
text: string
|
||||
voice?: string // Voice ID or manifest URL
|
||||
quality?: 'draft' | 'standard' | 'premium'
|
||||
outputFormat?: 'mp3' | 'wav' | 'ogg' | 'flac' | 'mulaw'
|
||||
speed?: number // 0.5 to 2.0
|
||||
temperature?: number // 0.0 to 2.0 (creativity/randomness)
|
||||
voiceGuidance?: number // 1.0 to 6.0 (voice stability)
|
||||
textGuidance?: number // 1.0 to 6.0 (text adherence)
|
||||
sampleRate?: number // 8000, 16000, 22050, 24000, 44100, 48000
|
||||
userId: string // X-USER-ID header
|
||||
apiKey: string // AUTHORIZATION header
|
||||
}
|
||||
|
||||
// Unified Response Type for block outputs
|
||||
export interface TtsBlockResponse extends ToolResponse {
|
||||
output: {
|
||||
audioUrl: string
|
||||
audioFile?: UserFile
|
||||
duration?: number
|
||||
characterCount?: number
|
||||
format?: string
|
||||
provider?: TtsProvider
|
||||
}
|
||||
}
|
||||
|
||||
// API Response type (used internally in proxy route)
|
||||
export interface TtsResponse {
|
||||
audioUrl: string
|
||||
audioFile?: UserFile
|
||||
duration?: number
|
||||
characterCount?: number
|
||||
format?: string
|
||||
provider?: TtsProvider
|
||||
}
|
||||
|
||||
// Voice options for different providers
|
||||
export const OPENAI_VOICES = {
|
||||
// All voices work with all models
|
||||
alloy: 'Alloy (neutral, balanced)',
|
||||
ash: 'Ash (masculine, clear)',
|
||||
ballad: 'Ballad (smooth, melodic)',
|
||||
coral: 'Coral (warm, friendly)',
|
||||
echo: 'Echo (warm, masculine)',
|
||||
marin: 'Marin (soft, gentle)',
|
||||
cedar: 'Cedar (deep, resonant)',
|
||||
sage: 'Sage (calm, wise)',
|
||||
shimmer: 'Shimmer (warm, empathetic)',
|
||||
verse: 'Verse (poetic, expressive)',
|
||||
} as const
|
||||
|
||||
export const DEEPGRAM_VOICES = {
|
||||
// Aura-1 English voices (legacy)
|
||||
'aura-asteria-en': 'Asteria (Aura-1, American, warm female)',
|
||||
'aura-luna-en': 'Luna (Aura-1, American, professional female)',
|
||||
'aura-stella-en': 'Stella (Aura-1, American, energetic female)',
|
||||
'aura-athena-en': 'Athena (Aura-1, British, sophisticated female)',
|
||||
'aura-hera-en': 'Hera (Aura-1, American, mature female)',
|
||||
'aura-orion-en': 'Orion (Aura-1, American, confident male)',
|
||||
'aura-arcas-en': 'Arcas (Aura-1, American, professional male)',
|
||||
'aura-perseus-en': 'Perseus (Aura-1, American, strong male)',
|
||||
'aura-angus-en': 'Angus (Aura-1, Irish, friendly male)',
|
||||
'aura-orpheus-en': 'Orpheus (Aura-1, American, smooth male)',
|
||||
'aura-helios-en': 'Helios (Aura-1, British, authoritative male)',
|
||||
'aura-zeus-en': 'Zeus (Aura-1, American, deep male)',
|
||||
|
||||
// Aura-2 English voices
|
||||
'aura-2-arcas-en': 'Arcas (Aura-2, American male)',
|
||||
'aura-2-asteria-en': 'Asteria (Aura-2, American female)',
|
||||
'aura-2-luna-en': 'Luna (Aura-2, American female)',
|
||||
'aura-2-stella-en': 'Stella (Aura-2, American female)',
|
||||
'aura-2-athena-en': 'Athena (Aura-2, British female)',
|
||||
'aura-2-hera-en': 'Hera (Aura-2, American female)',
|
||||
'aura-2-orion-en': 'Orion (Aura-2, American male)',
|
||||
'aura-2-perseus-en': 'Perseus (Aura-2, American male)',
|
||||
'aura-2-orpheus-en': 'Orpheus (Aura-2, American male)',
|
||||
'aura-2-helios-en': 'Helios (Aura-2, British male)',
|
||||
'aura-2-zeus-en': 'Zeus (Aura-2, American male)',
|
||||
'aura-2-angus-en': 'Angus (Aura-2, Irish male)',
|
||||
'aura-2-sasha-en': 'Sasha (Aura-2, American female)',
|
||||
'aura-2-sophia-en': 'Sophia (Aura-2, American female)',
|
||||
'aura-2-oliver-en': 'Oliver (Aura-2, American male)',
|
||||
'aura-2-emma-en': 'Emma (Aura-2, American female)',
|
||||
'aura-2-jack-en': 'Jack (Aura-2, American male)',
|
||||
'aura-2-lily-en': 'Lily (Aura-2, American female)',
|
||||
'aura-2-noah-en': 'Noah (Aura-2, American male)',
|
||||
'aura-2-mia-en': 'Mia (Aura-2, American female)',
|
||||
'aura-2-william-en': 'William (Aura-2, American male)',
|
||||
'aura-2-emily-en': 'Emily (Aura-2, American female)',
|
||||
'aura-2-james-en': 'James (Aura-2, American male)',
|
||||
'aura-2-ava-en': 'Ava (Aura-2, American female)',
|
||||
'aura-2-benjamin-en': 'Benjamin (Aura-2, American male)',
|
||||
'aura-2-charlotte-en': 'Charlotte (Aura-2, American female)',
|
||||
'aura-2-lucas-en': 'Lucas (Aura-2, American male)',
|
||||
'aura-2-harper-en': 'Harper (Aura-2, American female)',
|
||||
'aura-2-henry-en': 'Henry (Aura-2, American male)',
|
||||
'aura-2-evelyn-en': 'Evelyn (Aura-2, American female)',
|
||||
'aura-2-alexander-en': 'Alexander (Aura-2, American male)',
|
||||
'aura-2-abigail-en': 'Abigail (Aura-2, American female)',
|
||||
'aura-2-michael-en': 'Michael (Aura-2, American male)',
|
||||
'aura-2-sofia-en': 'Sofia (Aura-2, American female)',
|
||||
'aura-2-daniel-en': 'Daniel (Aura-2, American male)',
|
||||
'aura-2-ella-en': 'Ella (Aura-2, American female)',
|
||||
'aura-2-matthew-en': 'Matthew (Aura-2, American male)',
|
||||
'aura-2-grace-en': 'Grace (Aura-2, American female)',
|
||||
'aura-2-jackson-en': 'Jackson (Aura-2, American male)',
|
||||
'aura-2-chloe-en': 'Chloe (Aura-2, American female)',
|
||||
'aura-2-samuel-en': 'Samuel (Aura-2, American male)',
|
||||
'aura-2-madison-en': 'Madison (Aura-2, American female)',
|
||||
|
||||
// Aura-2 Spanish voices
|
||||
'aura-2-maria-es': 'Maria (Aura-2, Spanish female)',
|
||||
'aura-2-carmen-es': 'Carmen (Aura-2, Spanish female)',
|
||||
'aura-2-carlos-es': 'Carlos (Aura-2, Spanish male)',
|
||||
'aura-2-diego-es': 'Diego (Aura-2, Spanish male)',
|
||||
'aura-2-isabel-es': 'Isabel (Aura-2, Spanish female)',
|
||||
'aura-2-juan-es': 'Juan (Aura-2, Spanish male)',
|
||||
'aura-2-lucia-es': 'Lucia (Aura-2, Spanish female)',
|
||||
'aura-2-miguel-es': 'Miguel (Aura-2, Spanish male)',
|
||||
'aura-2-sofia-es': 'Sofia (Aura-2, Spanish female)',
|
||||
'aura-2-antonio-es': 'Antonio (Aura-2, Spanish male)',
|
||||
} as const
|
||||
|
||||
export const ELEVENLABS_MODELS = {
|
||||
// V2 Models
|
||||
eleven_turbo_v2_5: 'Turbo v2.5 (faster, improved)',
|
||||
eleven_flash_v2_5: 'Flash v2.5 (ultra-fast, 75ms latency)',
|
||||
eleven_multilingual_v2: 'Multilingual v2 (32 languages)',
|
||||
eleven_turbo_v2: 'Turbo v2 (fast, good quality)',
|
||||
|
||||
// V1 Models
|
||||
eleven_monolingual_v1: 'Monolingual v1 (English only)',
|
||||
eleven_multilingual_v1: 'Multilingual v1',
|
||||
} as const
|
||||
|
||||
export const CARTESIA_MODELS = {
|
||||
sonic: 'Sonic (English, low latency)',
|
||||
'sonic-2': 'Sonic 2 (English, improved)',
|
||||
'sonic-turbo': 'Sonic Turbo (English, ultra-fast)',
|
||||
'sonic-3': 'Sonic 3 (English, highest quality)',
|
||||
'sonic-multilingual': 'Sonic Multilingual (100+ languages)',
|
||||
} as const
|
||||
|
||||
export const GOOGLE_VOICE_GENDERS = {
|
||||
MALE: 'Male',
|
||||
FEMALE: 'Female',
|
||||
NEUTRAL: 'Neutral',
|
||||
} as const
|
||||
|
||||
export const GOOGLE_AUDIO_ENCODINGS = {
|
||||
LINEAR16: 'LINEAR16 (uncompressed)',
|
||||
MP3: 'MP3 (compressed)',
|
||||
OGG_OPUS: 'OGG Opus (compressed)',
|
||||
MULAW: 'MULAW (8kHz)',
|
||||
ALAW: 'ALAW (8kHz)',
|
||||
} as const
|
||||
|
||||
export const AZURE_OUTPUT_FORMATS = {
|
||||
'riff-8khz-16bit-mono-pcm': 'PCM 8kHz 16-bit',
|
||||
'riff-24khz-16bit-mono-pcm': 'PCM 24kHz 16-bit',
|
||||
'audio-24khz-48kbitrate-mono-mp3': 'MP3 24kHz 48kbps',
|
||||
'audio-24khz-96kbitrate-mono-mp3': 'MP3 24kHz 96kbps',
|
||||
'audio-48khz-96kbitrate-mono-mp3': 'MP3 48kHz 96kbps (high quality)',
|
||||
} as const
|
||||
|
||||
export const PLAYHT_QUALITY_LEVELS = {
|
||||
draft: 'Draft (fastest)',
|
||||
standard: 'Standard (recommended)',
|
||||
premium: 'Premium (best quality)',
|
||||
} as const
|
||||
|
||||
export const PLAYHT_OUTPUT_FORMATS = {
|
||||
mp3: 'MP3',
|
||||
wav: 'WAV',
|
||||
ogg: 'OGG',
|
||||
flac: 'FLAC',
|
||||
mulaw: 'MULAW',
|
||||
} as const
|
||||
|
||||
// Audio format MIME types
|
||||
export const AUDIO_MIME_TYPES: Record<string, string> = {
|
||||
mp3: 'audio/mpeg',
|
||||
opus: 'audio/opus',
|
||||
aac: 'audio/aac',
|
||||
flac: 'audio/flac',
|
||||
wav: 'audio/wav',
|
||||
pcm: 'audio/pcm',
|
||||
linear16: 'audio/pcm',
|
||||
mulaw: 'audio/basic',
|
||||
alaw: 'audio/basic',
|
||||
ogg: 'audio/ogg',
|
||||
}
|
||||
|
||||
// Get file extension from format
|
||||
export function getFileExtension(format: string): string {
|
||||
const formatMap: Record<string, string> = {
|
||||
mp3: 'mp3',
|
||||
opus: 'opus',
|
||||
aac: 'aac',
|
||||
flac: 'flac',
|
||||
wav: 'wav',
|
||||
pcm: 'pcm',
|
||||
linear16: 'wav',
|
||||
mulaw: 'wav',
|
||||
alaw: 'wav',
|
||||
ogg: 'ogg',
|
||||
}
|
||||
return formatMap[format] || 'mp3'
|
||||
}
|
||||
|
||||
// Get MIME type from format
|
||||
export function getMimeType(format: string): string {
|
||||
return AUDIO_MIME_TYPES[format] || 'audio/mpeg'
|
||||
}
|
||||
Reference in New Issue
Block a user