Skip to content

Commit a6f5170

Browse files
committed
feat: Init s3 vectors store bridge
Built on top of s3 vector client from async aws
1 parent 9842d72 commit a6f5170

File tree

20 files changed

+913
-2
lines changed

20 files changed

+913
-2
lines changed

examples/.env

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,14 @@ AZURE_OPENAI_WHISPER_API_VERSION=
3838
AZURE_LLAMA_BASEURL=
3939
AZURE_LLAMA_KEY=
4040

41-
# For using Bedrock
41+
# For using Bedrock and S3 Vectors
4242
AWS_ACCESS_KEY_ID=
4343
AWS_SECRET_ACCESS_KEY=
4444
AWS_DEFAULT_REGION=
4545

46+
# For S3 Vectors (store)
47+
S3_VECTORS_BUCKET=
48+
4649
# Hugging Face Access Token
4750
HUGGINGFACE_KEY=
4851

examples/commands/stores.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
require_once dirname(__DIR__).'/bootstrap.php';
1313

14+
use AsyncAws\S3Vectors\S3VectorsClient;
1415
use Doctrine\DBAL\DriverManager;
1516
use Doctrine\DBAL\Tools\DsnParser;
1617
use MongoDB\Client as MongoDbClient;
@@ -29,6 +30,7 @@
2930
use Symfony\AI\Store\Bridge\Postgres\Store as PostgresStore;
3031
use Symfony\AI\Store\Bridge\Qdrant\Store as QdrantStore;
3132
use Symfony\AI\Store\Bridge\Redis\Store as RedisStore;
33+
use Symfony\AI\Store\Bridge\S3Vectors\Store as S3VectorsStore;
3234
use Symfony\AI\Store\Bridge\SurrealDb\Store as SurrealDbStore;
3335
use Symfony\AI\Store\Bridge\Typesense\Store as TypesenseStore;
3436
use Symfony\AI\Store\Bridge\Weaviate\Store as WeaviateStore;
@@ -119,6 +121,15 @@
119121
'host' => env('REDIS_HOST'),
120122
'port' => 6379,
121123
]), 'symfony'),
124+
's3vectors' => static fn (): S3VectorsStore => new S3VectorsStore(
125+
new S3VectorsClient([
126+
'region' => env('AWS_DEFAULT_REGION'),
127+
'accessKeyId' => env('AWS_ACCESS_KEY_ID'),
128+
'accessKeySecret' => env('AWS_SECRET_ACCESS_KEY'),
129+
]),
130+
env('S3_VECTORS_BUCKET'),
131+
'symfony',
132+
),
122133
'surrealdb' => static fn (): SurrealDbStore => new SurrealDbStore(
123134
httpClient: http_client(),
124135
endpointUrl: env('SURREALDB_HOST'),

examples/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
"symfony/ai-vertex-ai-platform": "^0.3",
9090
"symfony/ai-voyage-platform": "^0.3",
9191
"symfony/ai-weaviate-store": "^0.3",
92+
"symfony/ai-s3vectors-store": "^0.4",
9293
"symfony/ai-wikipedia-tool": "^0.3",
9394
"symfony/ai-youtube-tool": "^0.3",
9495
"symfony/console": "^7.4|^8.0",

splitsh.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"ai-supabase-store": "src/store/src/Bridge/Supabase",
9292
"ai-surreal-db-store": "src/store/src/Bridge/SurrealDb",
9393
"ai-typesense-store": "src/store/src/Bridge/Typesense",
94-
"ai-weaviate-store": "src/store/src/Bridge/Weaviate"
94+
"ai-weaviate-store": "src/store/src/Bridge/Weaviate",
95+
"ai-s3vectors-store": "src/store/src/Bridge/S3Vectors"
9596
}
9697
}

src/ai-bundle/composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@
9494
"symfony/ai-vertex-ai-platform": "^0.3",
9595
"symfony/ai-voyage-platform": "^0.3",
9696
"symfony/ai-weaviate-store": "^0.3",
97+
"symfony/ai-s3vectors-store": "^0.4",
9798
"symfony/expression-language": "^7.3|^8.0",
9899
"symfony/security-core": "^7.3|^8.0",
99100
"symfony/translation": "^7.3|^8.0"

src/ai-bundle/config/options.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,7 @@
359359
->append($import('store/postgres'))
360360
->append($import('store/qdrant'))
361361
->append($import('store/redis'))
362+
->append($import('store/s3vectors'))
362363
->append($import('store/supabase'))
363364
->append($import('store/surrealdb'))
364365
->append($import('store/typesense'))
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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\Component\Config\Definition\Configurator;
13+
14+
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
15+
16+
return (new ArrayNodeDefinition('s3vectors'))
17+
->useAttributeAsKey('name')
18+
->arrayPrototype()
19+
->children()
20+
->stringNode('client')
21+
->info('Service reference to an existing S3VectorsClient')
22+
->end()
23+
->arrayNode('configuration')
24+
->info('AsyncAws S3Vectors client configuration (used if client service is not provided)')
25+
->end()
26+
->stringNode('vector_bucket_name')
27+
->isRequired()
28+
->cannotBeEmpty()
29+
->end()
30+
->stringNode('index_name')->end()
31+
->arrayNode('filter')
32+
->info('Default filter for queries')
33+
->end()
34+
->integerNode('top_k')
35+
->info('Default number of results to return')
36+
->defaultValue(3)
37+
->end()
38+
->end()
39+
->end();

src/ai-bundle/src/AiBundle.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@
106106
use Symfony\AI\Store\Bridge\Qdrant\Store as QdrantStore;
107107
use Symfony\AI\Store\Bridge\Redis\Distance as RedisDistance;
108108
use Symfony\AI\Store\Bridge\Redis\Store as RedisStore;
109+
use Symfony\AI\Store\Bridge\S3Vectors\Store as S3VectorsStore;
109110
use Symfony\AI\Store\Bridge\Supabase\Store as SupabaseStore;
110111
use Symfony\AI\Store\Bridge\SurrealDb\Store as SurrealDbStore;
111112
use Symfony\AI\Store\Bridge\Typesense\Store as TypesenseStore;
@@ -1939,6 +1940,47 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
19391940
$container->registerAliasForArgument('ai.store.'.$type.'.'.$name, StoreInterface::class, $type.'_'.$name);
19401941
}
19411942
}
1943+
1944+
if ('s3vectors' === $type) {
1945+
if (!ContainerBuilder::willBeAvailable('symfony/ai-s3vectors-store', S3VectorsStore::class, ['symfony/ai-bundle'])) {
1946+
throw new RuntimeException('S3Vectors store configuration requires "symfony/ai-s3vectors-store" package. Try running "composer require symfony/ai-s3vectors-store".');
1947+
}
1948+
1949+
foreach ($stores as $name => $store) {
1950+
if (isset($store['client'])) {
1951+
$s3VectorsClient = new Reference($store['client']);
1952+
} else {
1953+
$s3VectorsClient = new Definition(\AsyncAws\S3Vectors\S3VectorsClient::class);
1954+
$s3VectorsClient->setArguments([$store['configuration'] ?? []]);
1955+
}
1956+
1957+
$arguments = [
1958+
$s3VectorsClient,
1959+
$store['vector_bucket_name'],
1960+
$store['index_name'] ?? $name,
1961+
];
1962+
1963+
if (\array_key_exists('filter', $store)) {
1964+
$arguments[3] = $store['filter'];
1965+
}
1966+
1967+
if (\array_key_exists('top_k', $store)) {
1968+
$arguments[4] = $store['top_k'];
1969+
}
1970+
1971+
$definition = new Definition(S3VectorsStore::class);
1972+
$definition
1973+
->setLazy(true)
1974+
->setArguments($arguments)
1975+
->addTag('proxy', ['interface' => StoreInterface::class])
1976+
->addTag('proxy', ['interface' => ManagedStoreInterface::class])
1977+
->addTag('ai.store');
1978+
1979+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
1980+
$container->registerAliasForArgument('ai.store.'.$type.'.'.$name, StoreInterface::class, $name);
1981+
$container->registerAliasForArgument('ai.store.'.$type.'.'.$name, StoreInterface::class, $type.'_'.$name);
1982+
}
1983+
}
19421984
}
19431985

19441986
/**
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.github export-ignore
2+
/.gitattributes export-ignore
3+
/.gitignore export-ignore
4+
/phpstan.dist.neon export-ignore
5+
/phpunit.xml.dist export-ignore
6+
/Tests export-ignore
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Please do not submit any Pull Requests here. They will be closed.
2+
---
3+
4+
Please submit your PR here instead:
5+
https://github.com/symfony/ai
6+
7+
This repository is what we call a "subtree split": a read-only subset of that main repository.
8+
We're looking forward to your PR there!

0 commit comments

Comments
 (0)