Skip to content

Commit eae1d83

Browse files
committed
refactor(platform): ElevenLabs improvement
1 parent 75e8236 commit eae1d83

File tree

19 files changed

+136
-133
lines changed

19 files changed

+136
-133
lines changed

UPGRADE.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ Platform
6161
* The `hostUrl` parameter for `OllamaClient` has been removed
6262
* The `host` parameter for `OllamaApiCatalog` has been removed
6363
* The `hostUrl` parameter for `PlatformFactory::create()` in `Ollama` has been renamed to `endpoint`
64+
* The `hostUrl` parameter for `ElevenLabsClient` has been removed
65+
* The `host` parameter for `ElevenLabsApiCatalog` has been removed
66+
* The `hostUrl` parameter for `PlatformFactory::create()` in `ElevenLabs` has been renamed to `endpoint`
6467

6568
Store
6669
-----

examples/elevenlabs/speech-to-text.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
require_once dirname(__DIR__).'/bootstrap.php';
1616

17-
$platform = PlatformFactory::create(
18-
apiKey: env('ELEVEN_LABS_API_KEY'),
19-
httpClient: http_client()
20-
);
17+
$platform = PlatformFactory::create(env('ELEVEN_LABS_API_KEY'), httpClient: http_client());
2118

2219
$result = $platform->invoke('scribe_v1', Audio::fromFile(dirname(__DIR__, 2).'/fixtures/audio.mp3'));
2320

examples/elevenlabs/text-to-speech-as-stream.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
require_once dirname(__DIR__).'/bootstrap.php';
1616

17-
$platform = PlatformFactory::create(
18-
apiKey: env('ELEVEN_LABS_API_KEY'),
19-
httpClient: http_client(),
20-
);
17+
$platform = PlatformFactory::create(env('ELEVEN_LABS_API_KEY'), httpClient: http_client());
2118

2219
$result = $platform->invoke('eleven_multilingual_v2', new Text('The first move is what sets everything in motion.'), [
2320
'voice' => 'Dslrhjl3ZpzrctukrQSN', // Brad (https://elevenlabs.io/app/voice-library?voiceId=Dslrhjl3ZpzrctukrQSN)

examples/elevenlabs/text-to-speech.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@
1414

1515
require_once dirname(__DIR__).'/bootstrap.php';
1616

17-
$platform = PlatformFactory::create(
18-
apiKey: env('ELEVEN_LABS_API_KEY'),
19-
httpClient: http_client(),
20-
);
17+
$platform = PlatformFactory::create(env('ELEVEN_LABS_API_KEY'), httpClient: http_client());
2118

2219
$result = $platform->invoke('eleven_multilingual_v2', new Text('Hello world'), [
2320
'voice' => 'Dslrhjl3ZpzrctukrQSN', // Brad (https://elevenlabs.io/app/voice-library?voiceId=Dslrhjl3ZpzrctukrQSN)

src/ai-bundle/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* [BC BREAK] Rename service ID prefix `ai.toolbox.{agent}.agent_wrapper.` to `ai.toolbox.{agent}.subagent.`
99
* Add support for `DocumentIndexer` when no loader is configured for an indexer
1010
* [BC BREAK] The `host_url` configuration key for `Ollama` has been renamed `endpoint`
11+
* [BC BREAK] The `host_url` configuration key for `ElevenLabs` has been renamed `endpoint`
1112

1213
0.2
1314
---

src/ai-bundle/config/platform/elevenlabs.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
return (new ArrayNodeDefinition('elevenlabs'))
1717
->children()
1818
->stringNode('api_key')->isRequired()->end()
19-
->stringNode('host')
20-
->defaultValue('https://api.elevenlabs.io/v1')
19+
->stringNode('endpoint')
20+
->defaultValue('https://api.elevenlabs.io/v1/')
2121
->end()
2222
->stringNode('http_client')
2323
->defaultValue('http_client')

src/ai-bundle/config/services.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use Symfony\AI\Platform\Bridge\Decart\ModelCatalog as DecartModelCatalog;
3636
use Symfony\AI\Platform\Bridge\DeepSeek\ModelCatalog as DeepSeekModelCatalog;
3737
use Symfony\AI\Platform\Bridge\DockerModelRunner\ModelCatalog as DockerModelRunnerModelCatalog;
38+
use Symfony\AI\Platform\Bridge\ElevenLabs\Contract\ElevenLabsContract;
3839
use Symfony\AI\Platform\Bridge\ElevenLabs\ModelCatalog as ElevenLabsModelCatalog;
3940
use Symfony\AI\Platform\Bridge\Gemini\Contract\GeminiContract;
4041
use Symfony\AI\Platform\Bridge\Gemini\ModelCatalog as GeminiModelCatalog;
@@ -82,6 +83,8 @@
8283
->factory([OpenAiContract::class, 'create'])
8384
->set('ai.platform.contract.anthropic', Contract::class)
8485
->factory([AnthropicContract::class, 'create'])
86+
->set('ai.platform.contract.elevenlabs', Contract::class)
87+
->factory([ElevenLabsContract::class, 'create'])
8588
->set('ai.platform.contract.gemini', Contract::class)
8689
->factory([GeminiContract::class, 'create'])
8790
->set('ai.platform.contract.huggingface', Contract::class)
@@ -105,7 +108,7 @@
105108
->set('ai.platform.model_catalog.deepseek', DeepSeekModelCatalog::class)
106109
->set('ai.platform.model_catalog.dockermodelrunner', DockerModelRunnerModelCatalog::class)
107110
->set('ai.platform.model_catalog.elevenlabs', ElevenLabsModelCatalog::class)
108-
->lazy(true)
111+
->lazy()
109112
->tag('proxy', ['interface' => ModelCatalogInterface::class])
110113
->set('ai.platform.model_catalog.gemini', GeminiModelCatalog::class)
111114
->set('ai.platform.model_catalog.huggingface', HuggingFaceModelCatalog::class)

src/ai-bundle/src/AiBundle.php

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,29 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
602602
throw new RuntimeException('ElevenLabs platform configuration requires "symfony/ai-eleven-labs-platform" package. Try running "composer require symfony/ai-eleven-labs-platform".');
603603
}
604604

605+
$httpClientReference = new Reference($platform['http_client']);
606+
607+
$scopedHttpClientDefinition = (new Definition(ScopingHttpClient::class))
608+
->setFactory([ScopingHttpClient::class, 'forBaseUri'])
609+
->setArguments([
610+
$httpClientReference,
611+
$platform['endpoint'],
612+
[
613+
'headers' => [
614+
'x-api-key' => $platform['api_key'],
615+
],
616+
],
617+
]);
618+
619+
$container->setDefinition('ai.platform.elevenlabs.scoped_http_client', $scopedHttpClientDefinition);
620+
621+
$httpClientReference = new Reference('ai.platform.elevenlabs.scoped_http_client');
622+
605623
if (\array_key_exists('api_catalog', $platform) && $platform['api_catalog']) {
606624
$catalogDefinition = (new Definition(ElevenLabsApiCatalog::class))
607625
->setLazy(true)
608626
->setArguments([
609-
new Reference($platform['http_client']),
610-
$platform['api_key'],
611-
$platform['host'],
627+
$httpClientReference,
612628
])
613629
->addTag('proxy', ['interface' => ModelCatalogInterface::class]);
614630

@@ -620,10 +636,10 @@ private function processPlatformConfig(string $type, array $platform, ContainerB
620636
->setLazy(true)
621637
->setArguments([
622638
$platform['api_key'],
623-
$platform['host'],
624-
new Reference($platform['http_client'], ContainerInterface::NULL_ON_INVALID_REFERENCE),
639+
$platform['endpoint'],
640+
$httpClientReference,
625641
new Reference('ai.platform.model_catalog.'.$type),
626-
null,
642+
new Reference('ai.platform.contract.'.$type),
627643
new Reference('event_dispatcher'),
628644
])
629645
->addTag('proxy', ['interface' => PlatformInterface::class])

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

Lines changed: 20 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3901,7 +3901,7 @@ public function testToolboxWithoutExplicitToolsDefined()
39013901
$this->assertTrue($foundOutput, 'Default tool processor should have output tag with full agent ID');
39023902
}
39033903

3904-
public function testElevenLabsPlatformCanBeRegistered()
3904+
public function testElevenLabsPlatformCanBeConfigured()
39053905
{
39063906
$container = $this->buildContainer([
39073907
'ai' => [
@@ -3916,18 +3916,18 @@ public function testElevenLabsPlatformCanBeRegistered()
39163916
$this->assertTrue($container->hasDefinition('ai.platform.elevenlabs'));
39173917

39183918
$definition = $container->getDefinition('ai.platform.elevenlabs');
3919-
39203919
$this->assertTrue($definition->isLazy());
39213920
$this->assertSame([ElevenLabsPlatformFactory::class, 'create'], $definition->getFactory());
39223921

39233922
$this->assertCount(6, $definition->getArguments());
39243923
$this->assertSame('foo', $definition->getArgument(0));
3925-
$this->assertSame('https://api.elevenlabs.io/v1', $definition->getArgument(1));
3924+
$this->assertSame('https://api.elevenlabs.io/v1/', $definition->getArgument(1));
39263925
$this->assertInstanceOf(Reference::class, $definition->getArgument(2));
3927-
$this->assertSame('http_client', (string) $definition->getArgument(2));
3926+
$this->assertSame('ai.platform.elevenlabs.scoped_http_client', (string) $definition->getArgument(2));
39283927
$this->assertInstanceOf(Reference::class, $definition->getArgument(3));
39293928
$this->assertSame('ai.platform.model_catalog.elevenlabs', (string) $definition->getArgument(3));
3930-
$this->assertNull($definition->getArgument(4));
3929+
$this->assertInstanceOf(Reference::class, $definition->getArgument(4));
3930+
$this->assertSame('ai.platform.contract.elevenlabs', (string) $definition->getArgument(4));
39313931
$this->assertInstanceOf(Reference::class, $definition->getArgument(5));
39323932
$this->assertSame('event_dispatcher', (string) $definition->getArgument(5));
39333933

@@ -3946,16 +3946,13 @@ public function testElevenLabsPlatformCanBeRegistered()
39463946

39473947
$this->assertTrue($modelCatalogDefinition->hasTag('proxy'));
39483948
$this->assertSame([['interface' => ModelCatalogInterface::class]], $modelCatalogDefinition->getTag('proxy'));
3949-
}
39503949

3951-
public function testElevenLabsPlatformWithCustomEndpointCanBeRegistered()
3952-
{
39533950
$container = $this->buildContainer([
39543951
'ai' => [
39553952
'platform' => [
39563953
'elevenlabs' => [
3954+
'endpoint' => 'https://api.elevenlabs.io/v2',
39573955
'api_key' => 'foo',
3958-
'host' => 'https://api.elevenlabs.io/v2',
39593956
],
39603957
],
39613958
],
@@ -3964,18 +3961,18 @@ public function testElevenLabsPlatformWithCustomEndpointCanBeRegistered()
39643961
$this->assertTrue($container->hasDefinition('ai.platform.elevenlabs'));
39653962

39663963
$definition = $container->getDefinition('ai.platform.elevenlabs');
3967-
39683964
$this->assertTrue($definition->isLazy());
39693965
$this->assertSame([ElevenLabsPlatformFactory::class, 'create'], $definition->getFactory());
39703966

39713967
$this->assertCount(6, $definition->getArguments());
39723968
$this->assertSame('foo', $definition->getArgument(0));
39733969
$this->assertSame('https://api.elevenlabs.io/v2', $definition->getArgument(1));
39743970
$this->assertInstanceOf(Reference::class, $definition->getArgument(2));
3975-
$this->assertSame('http_client', (string) $definition->getArgument(2));
3971+
$this->assertSame('ai.platform.elevenlabs.scoped_http_client', (string) $definition->getArgument(2));
39763972
$this->assertInstanceOf(Reference::class, $definition->getArgument(3));
39773973
$this->assertSame('ai.platform.model_catalog.elevenlabs', (string) $definition->getArgument(3));
3978-
$this->assertNull($definition->getArgument(4));
3974+
$this->assertInstanceOf(Reference::class, $definition->getArgument(4));
3975+
$this->assertSame('ai.platform.contract.elevenlabs', (string) $definition->getArgument(4));
39793976
$this->assertInstanceOf(Reference::class, $definition->getArgument(5));
39803977
$this->assertSame('event_dispatcher', (string) $definition->getArgument(5));
39813978

@@ -3994,10 +3991,7 @@ public function testElevenLabsPlatformWithCustomEndpointCanBeRegistered()
39943991

39953992
$this->assertTrue($modelCatalogDefinition->hasTag('proxy'));
39963993
$this->assertSame([['interface' => ModelCatalogInterface::class]], $modelCatalogDefinition->getTag('proxy'));
3997-
}
39983994

3999-
public function testElevenLabsPlatformWithCustomHttpClientCanBeRegistered()
4000-
{
40013995
$container = $this->buildContainer([
40023996
'ai' => [
40033997
'platform' => [
@@ -4018,12 +4012,13 @@ public function testElevenLabsPlatformWithCustomHttpClientCanBeRegistered()
40184012

40194013
$this->assertCount(6, $definition->getArguments());
40204014
$this->assertSame('foo', $definition->getArgument(0));
4021-
$this->assertSame('https://api.elevenlabs.io/v1', $definition->getArgument(1));
4015+
$this->assertSame('https://api.elevenlabs.io/v1/', $definition->getArgument(1));
40224016
$this->assertInstanceOf(Reference::class, $definition->getArgument(2));
4023-
$this->assertSame('foo', (string) $definition->getArgument(2));
4017+
$this->assertSame('ai.platform.elevenlabs.scoped_http_client', (string) $definition->getArgument(2));
40244018
$this->assertInstanceOf(Reference::class, $definition->getArgument(3));
40254019
$this->assertSame('ai.platform.model_catalog.elevenlabs', (string) $definition->getArgument(3));
4026-
$this->assertNull($definition->getArgument(4));
4020+
$this->assertInstanceOf(Reference::class, $definition->getArgument(4));
4021+
$this->assertSame('ai.platform.contract.elevenlabs', (string) $definition->getArgument(4));
40274022
$this->assertInstanceOf(Reference::class, $definition->getArgument(5));
40284023
$this->assertSame('event_dispatcher', (string) $definition->getArgument(5));
40294024

@@ -4042,10 +4037,7 @@ public function testElevenLabsPlatformWithCustomHttpClientCanBeRegistered()
40424037

40434038
$this->assertTrue($modelCatalogDefinition->hasTag('proxy'));
40444039
$this->assertSame([['interface' => ModelCatalogInterface::class]], $modelCatalogDefinition->getTag('proxy'));
4045-
}
40464040

4047-
public function testElevenLabsPlatformWithApiCatalogCanBeRegistered()
4048-
{
40494041
$container = $this->buildContainer([
40504042
'ai' => [
40514043
'platform' => [
@@ -4067,12 +4059,13 @@ public function testElevenLabsPlatformWithApiCatalogCanBeRegistered()
40674059

40684060
$this->assertCount(6, $definition->getArguments());
40694061
$this->assertSame('foo', $definition->getArgument(0));
4070-
$this->assertSame('https://api.elevenlabs.io/v1', $definition->getArgument(1));
4062+
$this->assertSame('https://api.elevenlabs.io/v1/', $definition->getArgument(1));
40714063
$this->assertInstanceOf(Reference::class, $definition->getArgument(2));
4072-
$this->assertSame('http_client', (string) $definition->getArgument(2));
4064+
$this->assertSame('ai.platform.elevenlabs.scoped_http_client', (string) $definition->getArgument(2));
40734065
$this->assertInstanceOf(Reference::class, $definition->getArgument(3));
40744066
$this->assertSame('ai.platform.model_catalog.elevenlabs', (string) $definition->getArgument(3));
4075-
$this->assertNull($definition->getArgument(4));
4067+
$this->assertInstanceOf(Reference::class, $definition->getArgument(4));
4068+
$this->assertSame('ai.platform.contract.elevenlabs', (string) $definition->getArgument(4));
40764069
$this->assertInstanceOf(Reference::class, $definition->getArgument(5));
40774070
$this->assertSame('event_dispatcher', (string) $definition->getArgument(5));
40784071

@@ -4088,11 +4081,9 @@ public function testElevenLabsPlatformWithApiCatalogCanBeRegistered()
40884081

40894082
$this->assertSame(ElevenLabsApiCatalog::class, $modelCatalogDefinition->getClass());
40904083
$this->assertTrue($modelCatalogDefinition->isLazy());
4091-
$this->assertCount(3, $modelCatalogDefinition->getArguments());
4084+
$this->assertCount(1, $modelCatalogDefinition->getArguments());
40924085
$this->assertInstanceOf(Reference::class, $modelCatalogDefinition->getArgument(0));
4093-
$this->assertSame('http_client', (string) $modelCatalogDefinition->getArgument(0));
4094-
$this->assertSame('foo', $modelCatalogDefinition->getArgument(1));
4095-
$this->assertSame('https://api.elevenlabs.io/v1', $modelCatalogDefinition->getArgument(2));
4086+
$this->assertSame('ai.platform.elevenlabs.scoped_http_client', (string) $modelCatalogDefinition->getArgument(0));
40964087

40974088
$this->assertTrue($modelCatalogDefinition->hasTag('proxy'));
40984089
$this->assertSame([['interface' => ModelCatalogInterface::class]], $modelCatalogDefinition->getTag('proxy'));
@@ -7610,7 +7601,7 @@ private function getFullConfig(): array
76107601
'api_key' => 'foo',
76117602
],
76127603
'elevenlabs' => [
7613-
'host' => 'https://api.elevenlabs.io/v1',
7604+
'endpoint' => 'https://api.elevenlabs.io/v1',
76147605
'api_key' => 'elevenlabs_key_full',
76157606
],
76167607
'failover' => [

src/platform/src/Bridge/ElevenLabs/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
CHANGELOG
22
=========
33

4+
0.4
5+
---
6+
7+
* [BC BREAK] The `hostUrl` parameter for `ElevenLabsClient` has been removed
8+
* [BC BREAK] The `host` parameter for `ElevenLabsApiCatalog` has been removed
9+
* [BC BREAK] The `hostUrl` parameter for `PlatformFactory::create()` has been renamed `endpoint`
10+
411
0.3
512
---
613

0 commit comments

Comments
 (0)