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,73 @@
|
||||
import type {
|
||||
ElevenLabsAudioIsolationParams,
|
||||
ElevenLabsAudioResponse,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsAudioIsolationTool: ToolConfig<
|
||||
ElevenLabsAudioIsolationParams,
|
||||
ElevenLabsAudioResponse
|
||||
> = {
|
||||
id: 'elevenlabs_audio_isolation',
|
||||
name: 'ElevenLabs Audio Isolation',
|
||||
description: 'Remove background noise from an audio file, isolating the speech using ElevenLabs',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
audioFile: {
|
||||
type: 'file',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'The audio file to isolate speech from (e.g., MP3, WAV, M4A)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/elevenlabs/audio',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: ElevenLabsAudioIsolationParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
operation: 'audio_isolation',
|
||||
apiKey: params.apiKey,
|
||||
audioFile: params.audioFile,
|
||||
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 || 'Audio isolation failed',
|
||||
output: { audioUrl: '' },
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL of the isolated audio' },
|
||||
audioFile: { type: 'file', description: 'The isolated audio file' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
import type {
|
||||
ElevenLabsEditVoiceSettingsParams,
|
||||
ElevenLabsEditVoiceSettingsResponse,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsEditVoiceSettingsTool: ToolConfig<
|
||||
ElevenLabsEditVoiceSettingsParams,
|
||||
ElevenLabsEditVoiceSettingsResponse
|
||||
> = {
|
||||
id: 'elevenlabs_edit_voice_settings',
|
||||
name: 'ElevenLabs Edit Voice Settings',
|
||||
description: 'Update the settings for a specific ElevenLabs voice',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the voice to update',
|
||||
},
|
||||
stability: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Voice stability from 0.0 to 1.0 (default 0.5)',
|
||||
},
|
||||
similarityBoost: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Similarity boost from 0.0 to 1.0 (default 0.75)',
|
||||
},
|
||||
style: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Style exaggeration from 0.0 to 1.0 (default 0)',
|
||||
},
|
||||
useSpeakerBoost: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to enhance similarity to the original speaker (default true)',
|
||||
},
|
||||
speed: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Speech speed where 1.0 is normal (default 1.0)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.elevenlabs.io/v1/voices/${params.voiceId.trim()}/settings/edit`,
|
||||
method: 'POST',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (params) => {
|
||||
const body: Record<string, unknown> = {}
|
||||
if (params.stability !== undefined) body.stability = params.stability
|
||||
if (params.similarityBoost !== undefined) body.similarity_boost = params.similarityBoost
|
||||
if (params.style !== undefined) body.style = params.style
|
||||
if (params.useSpeakerBoost !== undefined) body.use_speaker_boost = params.useSpeakerBoost
|
||||
if (params.speed !== undefined) body.speed = params.speed
|
||||
return body
|
||||
},
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
status: data.status ?? 'ok',
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
status: { type: 'string', description: 'Request outcome ("ok" on success)' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
import type { ElevenLabsGetUserParams, ElevenLabsGetUserResponse } from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsGetUserTool: ToolConfig<ElevenLabsGetUserParams, ElevenLabsGetUserResponse> =
|
||||
{
|
||||
id: 'elevenlabs_get_user',
|
||||
name: 'ElevenLabs Get User',
|
||||
description: 'Get account and subscription information for the ElevenLabs user',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.elevenlabs.io/v1/user',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const subscription = data.subscription
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
userId: data.user_id ?? null,
|
||||
isNewUser: data.is_new_user ?? null,
|
||||
subscription: subscription
|
||||
? {
|
||||
tier: subscription.tier ?? null,
|
||||
characterCount: subscription.character_count ?? null,
|
||||
characterLimit: subscription.character_limit ?? null,
|
||||
canExtendCharacterLimit: subscription.can_extend_character_limit ?? null,
|
||||
status: subscription.status ?? null,
|
||||
nextCharacterCountResetUnix: subscription.next_character_count_reset_unix ?? null,
|
||||
}
|
||||
: null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
userId: { type: 'string', description: 'Unique user identifier' },
|
||||
isNewUser: { type: 'boolean', description: 'Whether the user is new' },
|
||||
subscription: {
|
||||
type: 'object',
|
||||
description: 'Subscription and usage details',
|
||||
properties: {
|
||||
tier: { type: 'string', description: 'Subscription tier' },
|
||||
characterCount: { type: 'number', description: 'Characters used this period' },
|
||||
characterLimit: { type: 'number', description: 'Character quota for this period' },
|
||||
canExtendCharacterLimit: {
|
||||
type: 'boolean',
|
||||
description: 'Whether the character limit can be extended',
|
||||
},
|
||||
status: { type: 'string', description: 'Subscription status' },
|
||||
nextCharacterCountResetUnix: {
|
||||
type: 'number',
|
||||
description: 'Unix timestamp when the character count resets',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import type {
|
||||
ElevenLabsGetVoiceSettingsParams,
|
||||
ElevenLabsGetVoiceSettingsResponse,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsGetVoiceSettingsTool: ToolConfig<
|
||||
ElevenLabsGetVoiceSettingsParams,
|
||||
ElevenLabsGetVoiceSettingsResponse
|
||||
> = {
|
||||
id: 'elevenlabs_get_voice_settings',
|
||||
name: 'ElevenLabs Get Voice Settings',
|
||||
description: 'Get the configured settings for a specific ElevenLabs voice',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the voice whose settings to retrieve',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.elevenlabs.io/v1/voices/${params.voiceId.trim()}/settings`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
stability: data.stability ?? null,
|
||||
similarityBoost: data.similarity_boost ?? null,
|
||||
style: data.style ?? null,
|
||||
useSpeakerBoost: data.use_speaker_boost ?? null,
|
||||
speed: data.speed ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
stability: { type: 'number', description: 'Voice stability (0.0-1.0)' },
|
||||
similarityBoost: { type: 'number', description: 'Similarity boost (0.0-1.0)' },
|
||||
style: { type: 'number', description: 'Style exaggeration (0.0-1.0)' },
|
||||
useSpeakerBoost: { type: 'boolean', description: 'Whether speaker boost is enabled' },
|
||||
speed: { type: 'number', description: 'Speech speed (1.0 = normal)' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import type { ElevenLabsGetVoiceParams, ElevenLabsGetVoiceResponse } from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsGetVoiceTool: ToolConfig<
|
||||
ElevenLabsGetVoiceParams,
|
||||
ElevenLabsGetVoiceResponse
|
||||
> = {
|
||||
id: 'elevenlabs_get_voice',
|
||||
name: 'ElevenLabs Get Voice',
|
||||
description: 'Get metadata and settings for a specific ElevenLabs voice',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the voice to retrieve (e.g., "21m00Tcm4TlvDq8ikWAM")',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => `https://api.elevenlabs.io/v1/voices/${params.voiceId.trim()}`,
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
voiceId: data.voice_id,
|
||||
name: data.name ?? null,
|
||||
category: data.category ?? null,
|
||||
description: data.description ?? null,
|
||||
labels: data.labels ?? null,
|
||||
previewUrl: data.preview_url ?? null,
|
||||
settings: data.settings ?? null,
|
||||
availableForTiers: data.available_for_tiers ?? [],
|
||||
highQualityBaseModelIds: data.high_quality_base_model_ids ?? [],
|
||||
isOwner: data.is_owner ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
voiceId: { type: 'string', description: 'Unique voice identifier' },
|
||||
name: { type: 'string', description: 'Voice name' },
|
||||
category: { type: 'string', description: 'Voice category' },
|
||||
description: { type: 'string', description: 'Voice description' },
|
||||
labels: { type: 'json', description: 'Voice labels (accent, gender, age, use case)' },
|
||||
previewUrl: { type: 'string', description: 'URL to a preview audio sample' },
|
||||
settings: { type: 'json', description: 'Default voice settings' },
|
||||
availableForTiers: {
|
||||
type: 'array',
|
||||
description: 'Subscription tiers the voice is available on',
|
||||
},
|
||||
highQualityBaseModelIds: {
|
||||
type: 'array',
|
||||
description: 'Model IDs that support high-quality output for this voice',
|
||||
},
|
||||
isOwner: { type: 'boolean', description: 'Whether the current user owns this voice' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
export { elevenLabsAudioIsolationTool } from '@/tools/elevenlabs/audio-isolation'
|
||||
export { elevenLabsEditVoiceSettingsTool } from '@/tools/elevenlabs/edit-voice-settings'
|
||||
export { elevenLabsGetUserTool } from '@/tools/elevenlabs/get-user'
|
||||
export { elevenLabsGetVoiceTool } from '@/tools/elevenlabs/get-voice'
|
||||
export { elevenLabsGetVoiceSettingsTool } from '@/tools/elevenlabs/get-voice-settings'
|
||||
export { elevenLabsListModelsTool } from '@/tools/elevenlabs/list-models'
|
||||
export { elevenLabsListVoicesTool } from '@/tools/elevenlabs/list-voices'
|
||||
export { elevenLabsSoundEffectsTool } from '@/tools/elevenlabs/sound-effects'
|
||||
export { elevenLabsSpeechToSpeechTool } from '@/tools/elevenlabs/speech-to-speech'
|
||||
export { elevenLabsTtsTool } from '@/tools/elevenlabs/tts'
|
||||
export * from '@/tools/elevenlabs/types'
|
||||
@@ -0,0 +1,87 @@
|
||||
import type {
|
||||
ElevenLabsListModelsParams,
|
||||
ElevenLabsListModelsResponse,
|
||||
ElevenLabsModelSummary,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsListModelsTool: ToolConfig<
|
||||
ElevenLabsListModelsParams,
|
||||
ElevenLabsListModelsResponse
|
||||
> = {
|
||||
id: 'elevenlabs_list_models',
|
||||
name: 'ElevenLabs List Models',
|
||||
description: 'List the models available in ElevenLabs',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: 'https://api.elevenlabs.io/v1/models',
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const models: ElevenLabsModelSummary[] = (Array.isArray(data) ? data : []).map(
|
||||
(model: any) => ({
|
||||
modelId: model.model_id,
|
||||
name: model.name ?? null,
|
||||
description: model.description ?? null,
|
||||
canDoTextToSpeech: model.can_do_text_to_speech ?? null,
|
||||
canDoVoiceConversion: model.can_do_voice_conversion ?? null,
|
||||
canUseStyle: model.can_use_style ?? null,
|
||||
canUseSpeakerBoost: model.can_use_speaker_boost ?? null,
|
||||
languages: (model.languages ?? []).map((language: any) => ({
|
||||
languageId: language.language_id ?? null,
|
||||
name: language.name ?? null,
|
||||
})),
|
||||
})
|
||||
)
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: { models },
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
models: {
|
||||
type: 'array',
|
||||
description: 'List of available models',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
modelId: { type: 'string', description: 'Unique model identifier' },
|
||||
name: { type: 'string', description: 'Model name' },
|
||||
description: { type: 'string', description: 'Model description' },
|
||||
canDoTextToSpeech: { type: 'boolean', description: 'Supports text-to-speech' },
|
||||
canDoVoiceConversion: { type: 'boolean', description: 'Supports voice conversion' },
|
||||
canUseStyle: { type: 'boolean', description: 'Supports the style parameter' },
|
||||
canUseSpeakerBoost: { type: 'boolean', description: 'Supports speaker boost' },
|
||||
languages: {
|
||||
type: 'array',
|
||||
description: 'Languages supported by the model',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
languageId: { type: 'string', description: 'Language code' },
|
||||
name: { type: 'string', description: 'Language name' },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
import type {
|
||||
ElevenLabsListVoicesParams,
|
||||
ElevenLabsListVoicesResponse,
|
||||
ElevenLabsVoiceSummary,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsListVoicesTool: ToolConfig<
|
||||
ElevenLabsListVoicesParams,
|
||||
ElevenLabsListVoicesResponse
|
||||
> = {
|
||||
id: 'elevenlabs_list_voices',
|
||||
name: 'ElevenLabs List Voices',
|
||||
description: 'List the voices available in your ElevenLabs account',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
search: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Search term to filter voices by name, description, labels, or category',
|
||||
},
|
||||
category: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Filter by category: premade, cloned, generated, or professional',
|
||||
},
|
||||
pageSize: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Number of voices to return (1-100, default 10)',
|
||||
},
|
||||
nextPageToken: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Page token from a previous response to fetch the next page of voices',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: (params) => {
|
||||
const query = new URLSearchParams()
|
||||
if (params.search) query.set('search', params.search)
|
||||
if (params.category) query.set('category', params.category)
|
||||
if (params.pageSize !== undefined) query.set('page_size', String(params.pageSize))
|
||||
if (params.nextPageToken) query.set('next_page_token', params.nextPageToken)
|
||||
const qs = query.toString()
|
||||
return `https://api.elevenlabs.io/v2/voices${qs ? `?${qs}` : ''}`
|
||||
},
|
||||
method: 'GET',
|
||||
headers: (params) => ({
|
||||
'xi-api-key': params.apiKey,
|
||||
}),
|
||||
},
|
||||
|
||||
transformResponse: async (response: Response) => {
|
||||
const data = await response.json()
|
||||
const voices: ElevenLabsVoiceSummary[] = (data.voices ?? []).map((voice: any) => ({
|
||||
voiceId: voice.voice_id,
|
||||
name: voice.name ?? null,
|
||||
category: voice.category ?? null,
|
||||
description: voice.description ?? null,
|
||||
labels: voice.labels ?? null,
|
||||
previewUrl: voice.preview_url ?? null,
|
||||
settings: voice.settings ?? null,
|
||||
}))
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
voices,
|
||||
totalCount: data.total_count ?? null,
|
||||
hasMore: data.has_more ?? false,
|
||||
nextPageToken: data.next_page_token ?? null,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
voices: {
|
||||
type: 'array',
|
||||
description: 'List of voices',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
voiceId: { type: 'string', description: 'Unique voice identifier' },
|
||||
name: { type: 'string', description: 'Voice name' },
|
||||
category: { type: 'string', description: 'Voice category' },
|
||||
description: { type: 'string', description: 'Voice description' },
|
||||
labels: { type: 'json', description: 'Voice labels (accent, gender, age, use case)' },
|
||||
previewUrl: { type: 'string', description: 'URL to a preview audio sample' },
|
||||
settings: { type: 'json', description: 'Default voice settings' },
|
||||
},
|
||||
},
|
||||
},
|
||||
totalCount: { type: 'number', description: 'Total number of matching voices', optional: true },
|
||||
hasMore: { type: 'boolean', description: 'Whether more voices are available' },
|
||||
nextPageToken: { type: 'string', description: 'Token to fetch the next page', optional: true },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
import type {
|
||||
ElevenLabsAudioResponse,
|
||||
ElevenLabsSoundEffectsParams,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsSoundEffectsTool: ToolConfig<
|
||||
ElevenLabsSoundEffectsParams,
|
||||
ElevenLabsAudioResponse
|
||||
> = {
|
||||
id: 'elevenlabs_sound_effects',
|
||||
name: 'ElevenLabs Sound Effects',
|
||||
description: 'Generate a sound effect from a text prompt using ElevenLabs',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
text: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The prompt describing the sound effect (e.g., "thunder rumbling in the distance")',
|
||||
},
|
||||
modelId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The model to use (defaults to eleven_text_to_sound_v2)',
|
||||
},
|
||||
durationSeconds: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Length of the sound in seconds (0.5-30). Omit to auto-determine',
|
||||
},
|
||||
promptInfluence: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'How closely to follow the prompt from 0.0 to 1.0 (default 0.3)',
|
||||
},
|
||||
loop: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to generate a seamlessly looping sound effect (default false)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/elevenlabs/audio',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: ElevenLabsSoundEffectsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
operation: 'sound_effects',
|
||||
apiKey: params.apiKey,
|
||||
text: params.text,
|
||||
modelId: params.modelId,
|
||||
durationSeconds: params.durationSeconds,
|
||||
promptInfluence: params.promptInfluence,
|
||||
loop: params.loop,
|
||||
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 || 'Sound effect generation failed',
|
||||
output: { audioUrl: '' },
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL of the generated sound effect' },
|
||||
audioFile: { type: 'file', description: 'The generated sound effect file' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import type {
|
||||
ElevenLabsAudioResponse,
|
||||
ElevenLabsSpeechToSpeechParams,
|
||||
} from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsSpeechToSpeechTool: ToolConfig<
|
||||
ElevenLabsSpeechToSpeechParams,
|
||||
ElevenLabsAudioResponse
|
||||
> = {
|
||||
id: 'elevenlabs_speech_to_speech',
|
||||
name: 'ElevenLabs Speech to Speech',
|
||||
description: 'Convert audio into a chosen ElevenLabs voice while preserving content and emotion',
|
||||
version: '1.0.0',
|
||||
|
||||
params: {
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the target voice to convert the audio into',
|
||||
},
|
||||
audioFile: {
|
||||
type: 'file',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'The source audio file to convert (e.g., MP3, WAV, M4A)',
|
||||
},
|
||||
modelId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The model to use (defaults to eleven_english_sts_v2)',
|
||||
},
|
||||
removeBackgroundNoise: {
|
||||
type: 'boolean',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'Whether to isolate the voice and remove background noise (default false)',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/elevenlabs/audio',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: ElevenLabsSpeechToSpeechParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
operation: 'speech_to_speech',
|
||||
apiKey: params.apiKey,
|
||||
voiceId: params.voiceId,
|
||||
audioFile: params.audioFile,
|
||||
modelId: params.modelId,
|
||||
removeBackgroundNoise: params.removeBackgroundNoise,
|
||||
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 || 'Speech-to-speech conversion failed',
|
||||
output: { audioUrl: '' },
|
||||
}
|
||||
}
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'URL of the converted audio' },
|
||||
audioFile: { type: 'file', description: 'The converted audio file' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import type { ElevenLabsTtsParams, ElevenLabsTtsResponse } from '@/tools/elevenlabs/types'
|
||||
import type { ToolConfig } from '@/tools/types'
|
||||
|
||||
export const elevenLabsTtsTool: ToolConfig<ElevenLabsTtsParams, ElevenLabsTtsResponse> = {
|
||||
id: 'elevenlabs_tts',
|
||||
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 to convert to speech (e.g., "Hello, welcome to our service!")',
|
||||
},
|
||||
voiceId: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-or-llm',
|
||||
description: 'The ID of the voice to use (e.g., "21m00Tcm4TlvDq8ikWAM" for Rachel)',
|
||||
},
|
||||
modelId: {
|
||||
type: 'string',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'The ID of the model to use (e.g., "eleven_multilingual_v2", "eleven_turbo_v2"). Defaults to eleven_monolingual_v1',
|
||||
},
|
||||
stability: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Voice stability setting from 0.0 to 1.0 (e.g., 0.5 for balanced, 0.75 for more stable). Higher values produce more consistent output',
|
||||
},
|
||||
similarityBoost: {
|
||||
type: 'number',
|
||||
required: false,
|
||||
visibility: 'user-or-llm',
|
||||
description:
|
||||
'Similarity boost setting from 0.0 to 1.0 (e.g., 0.75 for natural, 1.0 for maximum similarity). Higher values make the voice more similar to the original',
|
||||
},
|
||||
apiKey: {
|
||||
type: 'string',
|
||||
required: true,
|
||||
visibility: 'user-only',
|
||||
description: 'Your ElevenLabs API key',
|
||||
},
|
||||
},
|
||||
|
||||
request: {
|
||||
url: '/api/tools/tts',
|
||||
method: 'POST',
|
||||
headers: () => ({
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
body: (
|
||||
params: ElevenLabsTtsParams & {
|
||||
_context?: { workspaceId?: string; workflowId?: string; executionId?: string }
|
||||
}
|
||||
) => ({
|
||||
apiKey: params.apiKey,
|
||||
text: params.text,
|
||||
voiceId: params.voiceId,
|
||||
modelId: params.modelId || 'eleven_monolingual_v1',
|
||||
stability: params.stability,
|
||||
similarityBoost: params.similarityBoost,
|
||||
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 || 'Unknown error occurred',
|
||||
output: {
|
||||
audioUrl: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success: true,
|
||||
output: {
|
||||
audioUrl: data.audioUrl,
|
||||
audioFile: data.audioFile,
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
outputs: {
|
||||
audioUrl: { type: 'string', description: 'The URL of the generated audio' },
|
||||
audioFile: { type: 'file', description: 'The generated audio file' },
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
import type { UserFile } from '@/executor/types'
|
||||
import type { ToolResponse } from '@/tools/types'
|
||||
|
||||
export interface ElevenLabsTtsParams {
|
||||
apiKey: string
|
||||
text: string
|
||||
voiceId: string
|
||||
modelId?: string
|
||||
stability?: number
|
||||
similarityBoost?: number
|
||||
}
|
||||
|
||||
export interface ElevenLabsTtsResponse extends ToolResponse {
|
||||
output: {
|
||||
audioUrl: string
|
||||
audioFile?: UserFile
|
||||
}
|
||||
}
|
||||
|
||||
/** Voice settings shared by get/edit settings and embedded voice objects. */
|
||||
export interface ElevenLabsVoiceSettings {
|
||||
stability?: number | null
|
||||
similarity_boost?: number | null
|
||||
style?: number | null
|
||||
use_speaker_boost?: boolean | null
|
||||
speed?: number | null
|
||||
}
|
||||
|
||||
export interface ElevenLabsVoiceSummary {
|
||||
voiceId: string
|
||||
name: string | null
|
||||
category: string | null
|
||||
description: string | null
|
||||
labels: Record<string, string> | null
|
||||
previewUrl: string | null
|
||||
settings: ElevenLabsVoiceSettings | null
|
||||
}
|
||||
|
||||
export interface ElevenLabsListVoicesParams {
|
||||
apiKey: string
|
||||
search?: string
|
||||
category?: string
|
||||
pageSize?: number
|
||||
nextPageToken?: string
|
||||
}
|
||||
|
||||
export interface ElevenLabsListVoicesResponse extends ToolResponse {
|
||||
output: {
|
||||
voices: ElevenLabsVoiceSummary[]
|
||||
totalCount: number | null
|
||||
hasMore: boolean
|
||||
nextPageToken: string | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetVoiceParams {
|
||||
apiKey: string
|
||||
voiceId: string
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetVoiceResponse extends ToolResponse {
|
||||
output: ElevenLabsVoiceSummary & {
|
||||
availableForTiers: string[]
|
||||
highQualityBaseModelIds: string[]
|
||||
isOwner: boolean | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetVoiceSettingsParams {
|
||||
apiKey: string
|
||||
voiceId: string
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetVoiceSettingsResponse extends ToolResponse {
|
||||
output: {
|
||||
stability: number | null
|
||||
similarityBoost: number | null
|
||||
style: number | null
|
||||
useSpeakerBoost: boolean | null
|
||||
speed: number | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsEditVoiceSettingsParams {
|
||||
apiKey: string
|
||||
voiceId: string
|
||||
stability?: number
|
||||
similarityBoost?: number
|
||||
style?: number
|
||||
useSpeakerBoost?: boolean
|
||||
speed?: number
|
||||
}
|
||||
|
||||
export interface ElevenLabsEditVoiceSettingsResponse extends ToolResponse {
|
||||
output: {
|
||||
status: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsModelLanguage {
|
||||
languageId: string | null
|
||||
name: string | null
|
||||
}
|
||||
|
||||
export interface ElevenLabsModelSummary {
|
||||
modelId: string
|
||||
name: string | null
|
||||
description: string | null
|
||||
canDoTextToSpeech: boolean | null
|
||||
canDoVoiceConversion: boolean | null
|
||||
canUseStyle: boolean | null
|
||||
canUseSpeakerBoost: boolean | null
|
||||
languages: ElevenLabsModelLanguage[]
|
||||
}
|
||||
|
||||
export interface ElevenLabsListModelsParams {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
export interface ElevenLabsListModelsResponse extends ToolResponse {
|
||||
output: {
|
||||
models: ElevenLabsModelSummary[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetUserParams {
|
||||
apiKey: string
|
||||
}
|
||||
|
||||
export interface ElevenLabsGetUserResponse extends ToolResponse {
|
||||
output: {
|
||||
userId: string | null
|
||||
isNewUser: boolean | null
|
||||
subscription: {
|
||||
tier: string | null
|
||||
characterCount: number | null
|
||||
characterLimit: number | null
|
||||
canExtendCharacterLimit: boolean | null
|
||||
status: string | null
|
||||
nextCharacterCountResetUnix: number | null
|
||||
} | null
|
||||
}
|
||||
}
|
||||
|
||||
export interface ElevenLabsSoundEffectsParams {
|
||||
apiKey: string
|
||||
text: string
|
||||
modelId?: string
|
||||
durationSeconds?: number
|
||||
promptInfluence?: number
|
||||
loop?: boolean
|
||||
}
|
||||
|
||||
export interface ElevenLabsSpeechToSpeechParams {
|
||||
apiKey: string
|
||||
voiceId: string
|
||||
audioFile?: UserFile
|
||||
modelId?: string
|
||||
removeBackgroundNoise?: boolean
|
||||
}
|
||||
|
||||
export interface ElevenLabsAudioIsolationParams {
|
||||
apiKey: string
|
||||
audioFile?: UserFile
|
||||
}
|
||||
|
||||
export interface ElevenLabsAudioResponse extends ToolResponse {
|
||||
output: {
|
||||
audioUrl: string
|
||||
audioFile?: UserFile
|
||||
}
|
||||
}
|
||||
|
||||
export type ElevenLabsBlockResponse =
|
||||
| ElevenLabsTtsResponse
|
||||
| ElevenLabsListVoicesResponse
|
||||
| ElevenLabsGetVoiceResponse
|
||||
| ElevenLabsGetVoiceSettingsResponse
|
||||
| ElevenLabsEditVoiceSettingsResponse
|
||||
| ElevenLabsListModelsResponse
|
||||
| ElevenLabsGetUserResponse
|
||||
| ElevenLabsAudioResponse
|
||||
Reference in New Issue
Block a user