Skip to content

Commit 2abb1b5

Browse files
committed
feat(platform): ElevenLabs platform
1 parent a50d26e commit 2abb1b5

File tree

21 files changed

+660
-5
lines changed

21 files changed

+660
-5
lines changed

examples/.env

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ HUGGINGFACE_KEY=
4343
# For using OpenRouter
4444
OPENROUTER_KEY=
4545

46+
# For using ElevenLabs
47+
ELEVEN_LABS_URL=https://api.elevenlabs.io/v1
48+
ELEVEN_LABS_API_KEY=
49+
4650
# For using SerpApi (tool)
4751
SERP_API_KEY=
4852

examples/composer.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
"symfony/event-dispatcher": "^6.4|^7.0",
2323
"symfony/filesystem": "^6.4|^7.0",
2424
"symfony/finder": "^6.4|^7.0",
25+
"symfony/mime": "^7.3",
2526
"symfony/process": "^6.4|^7.0",
2627
"symfony/var-dumper": "^6.4|^7.0"
2728
},
@@ -33,6 +34,7 @@
3334
"config": {
3435
"allow-plugins": {
3536
"codewithkyrian/platform-package-installer": true,
37+
"codewithkyrian/transformers-libsloader": true,
3638
"php-http/discovery": true
3739
},
3840
"sort-packages": true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\AI\Platform\Bridge\ElevenLabs\ElevenLabs;
13+
use Symfony\AI\Platform\Bridge\ElevenLabs\PlatformFactory;
14+
use Symfony\AI\Platform\Message\Content\Audio;
15+
16+
require_once dirname(__DIR__).'/bootstrap.php';
17+
18+
$platform = PlatformFactory::create(
19+
env('ELEVEN_LABS_URL'),
20+
env('ELEVEN_LABS_API_KEY'),
21+
__DIR__.'/tmp',
22+
http_client()
23+
);
24+
$model = new ElevenLabs(ElevenLabs::SPEECH_TO_TEXT, options: [
25+
'model' => 'scribe_v1',
26+
]);
27+
$file = Audio::fromFile(dirname(__DIR__, 2).'/fixtures/audio.mp3');
28+
29+
$result = $platform->invoke($model, $file);
30+
31+
echo $result->asText().\PHP_EOL;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
use Symfony\AI\Platform\Bridge\ElevenLabs\ElevenLabs;
13+
use Symfony\AI\Platform\Bridge\ElevenLabs\PlatformFactory;
14+
use Symfony\AI\Platform\Message\Content\Text;
15+
16+
require_once dirname(__DIR__).'/bootstrap.php';
17+
18+
$platform = PlatformFactory::create(
19+
env('ELEVEN_LABS_URL'),
20+
env('ELEVEN_LABS_API_KEY'),
21+
__DIR__.'/tmp',
22+
http_client(),
23+
);
24+
$model = new ElevenLabs(options: [
25+
'model' => 'Dslrhjl3ZpzrctukrQSN', // Brad (https://elevenlabs.io/app/voice-library?voiceId=Dslrhjl3ZpzrctukrQSN)
26+
]);
27+
28+
$result = $platform->invoke($model, new Text('Hello world'));
29+
30+
echo $result->asAudio().\PHP_EOL;

src/ai-bundle/config/options.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@
4040
->end()
4141
->end()
4242
->end()
43+
->arrayNode('eleven_labs')
44+
->children()
45+
->scalarNode('host')->end()
46+
->scalarNode('api_key')->isRequired()->end()
47+
->scalarNode('output_path')->isRequired()->end()
48+
->end()
49+
->end()
4350
->arrayNode('gemini')
4451
->children()
4552
->scalarNode('api_key')->isRequired()->end()

src/ai-bundle/doc/index.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Configuration
3434
class: 'Symfony\AI\Platform\Bridge\OpenAi\Gpt'
3535
name: !php/const Symfony\AI\Platform\Bridge\OpenAi\Gpt::GPT_4O_MINI
3636
37-
**Advanced Example with Anthropic, Azure, Gemini and multiple agents**
37+
**Advanced Example with Anthropic, Azure, ElevenLabs, Gemini, Ollama multiple agents**
3838

3939
.. code-block:: yaml
4040
@@ -50,6 +50,10 @@ Configuration
5050
deployment: '%env(AZURE_OPENAI_GPT)%'
5151
api_key: '%env(AZURE_OPENAI_KEY)%'
5252
api_version: '%env(AZURE_GPT_VERSION)%'
53+
eleven_labs:
54+
host: '%env(ELEVEN_LABS_HOST)%'
55+
api_key: '%env(ELEVEN_LABS_API_KEY)%'
56+
output_path: '%env(ELEVEN_LABS_OUTPUT_PATH)%'
5357
gemini:
5458
api_key: '%env(GEMINI_API_KEY)%'
5559
ollama:
@@ -85,6 +89,12 @@ Configuration
8589
tools: # If undefined, all tools are injected into the agent, use "tools: false" to disable tools.
8690
- 'Symfony\AI\Agent\Toolbox\Tool\Wikipedia'
8791
fault_tolerant_toolbox: false # Disables fault tolerant toolbox, default is true
92+
audio:
93+
platform: 'ai.platform.eleven_labs'
94+
model:
95+
class: 'Symfony\AI\Platform\Bridge\ElevenLabs'
96+
name: !php/const Symfony\AI\Platform\Bridge\ElevenLabs\TEXT_TO_SPEECH
97+
tools: false
8898
store:
8999
# also azure_search, meilisearch, memory, mongodb, pinecone, qdrant and surrealdb are supported as store type
90100
chroma_db:

src/ai-bundle/src/AiBundle.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@
2727
use Symfony\AI\AiBundle\Security\Attribute\IsGrantedTool;
2828
use Symfony\AI\Platform\Bridge\Anthropic\PlatformFactory as AnthropicPlatformFactory;
2929
use Symfony\AI\Platform\Bridge\Azure\OpenAi\PlatformFactory as AzureOpenAiPlatformFactory;
30+
use Symfony\AI\Platform\Bridge\Cerebras\PlatformFactory as CerebrasPlatformFactory;
31+
use Symfony\AI\Platform\Bridge\ElevenLabs\PlatformFactory as ElevenLabsPlatformFactory;
3032
use Symfony\AI\Platform\Bridge\Gemini\PlatformFactory as GeminiPlatformFactory;
3133
use Symfony\AI\Platform\Bridge\LmStudio\PlatformFactory as LmStudioPlatformFactory;
3234
use Symfony\AI\Platform\Bridge\Mistral\PlatformFactory as MistralPlatformFactory;
3335
use Symfony\AI\Platform\Bridge\Ollama\PlatformFactory as OllamaPlatformFactory;
3436
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory as OpenAiPlatformFactory;
3537
use Symfony\AI\Platform\Bridge\OpenRouter\PlatformFactory as OpenRouterPlatformFactory;
36-
use Symfony\AI\Platform\Bridge\Cerebras\PlatformFactory as CerebrasPlatformFactory;
3738
use Symfony\AI\Platform\Model;
3839
use Symfony\AI\Platform\ModelClientInterface;
3940
use Symfony\AI\Platform\Platform;
@@ -208,6 +209,26 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
208209
return;
209210
}
210211

212+
if ('eleven_labs' === $type) {
213+
$platformId = 'ai.platform.eleven_labs';
214+
$definition = (new Definition(Platform::class))
215+
->setFactory(ElevenLabsPlatformFactory::class.'::create')
216+
->setLazy(true)
217+
->addTag('proxy', ['interface' => PlatformInterface::class])
218+
->setArguments([
219+
$platform['host'],
220+
$platform['api_key'],
221+
$platform['output_path'],
222+
new Reference('http_client', ContainerInterface::NULL_ON_INVALID_REFERENCE),
223+
new Reference('ai.platform.contract.default'),
224+
])
225+
->addTag('ai.platform');
226+
227+
$container->setDefinition($platformId, $definition);
228+
229+
return;
230+
}
231+
211232
if ('gemini' === $type) {
212233
$platformId = 'ai.platform.gemini';
213234
$definition = (new Definition(Platform::class))

src/ai-bundle/tests/DependencyInjection/AiBundleTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@ private function getFullConfig(): array
143143
'api_version' => '2024-02-15-preview',
144144
],
145145
],
146+
'eleven_labs' => [
147+
'host' => 'https://api.elevenlabs.io/v1',
148+
'api_key' => 'eleven_labs_key_full',
149+
'output_path' => 'path/to/output',
150+
],
146151
'gemini' => [
147152
'api_key' => 'gemini_key_full',
148153
],

src/platform/composer.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,13 @@
4040
"phpstan/phpstan": "^2.1.17",
4141
"phpstan/phpstan-symfony": "^2.0.6",
4242
"phpunit/phpunit": "^11.5",
43+
"symfony/ai-agent": "@dev",
4344
"symfony/console": "^6.4 || ^7.1",
4445
"symfony/dotenv": "^6.4 || ^7.1",
45-
"symfony/ai-agent": "@dev",
4646
"symfony/event-dispatcher": "^6.4 || ^7.1",
47+
"symfony/filesystem": "^7.3",
4748
"symfony/finder": "^6.4 || ^7.1",
49+
"symfony/mime": "^7.3",
4850
"symfony/process": "^6.4 || ^7.1",
4951
"symfony/var-dumper": "^6.4 || ^7.1"
5052
},
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\AI\Platform\Bridge\ElevenLabs;
13+
14+
use Symfony\AI\Platform\Model;
15+
16+
/**
17+
* @author Guillaume Loulier <[email protected]>
18+
*/
19+
final class ElevenLabs extends Model
20+
{
21+
public const TEXT_TO_SPEECH = 'text-to-speech';
22+
public const SPEECH_TO_TEXT = 'speech-to-text';
23+
24+
public function __construct(
25+
string $name = self::TEXT_TO_SPEECH,
26+
array $capabilities = [],
27+
array $options = [],
28+
) {
29+
parent::__construct($name, $capabilities, $options);
30+
}
31+
}

0 commit comments

Comments
 (0)