Skip to content

Commit 345cebe

Browse files
committed
feature #260 [AIBundle] Add missing configuration for stores (Guikingone)
This PR was merged into the main branch. Discussion ---------- [AIBundle] Add missing configuration for stores | Q | A | ------------- | --- | Bug fix? | yes | New feature? | no | Docs? | yes | Issues | None | License | MIT Hi 👋🏻 Following the recently merged PR for vector stores, here's the missing configuration for each of them. Commits ------- ffca876 feat(ai-bundle): configuration added for stores
2 parents 4647967 + ffca876 commit 345cebe

File tree

4 files changed

+275
-1
lines changed

4 files changed

+275
-1
lines changed

src/ai-bundle/config/options.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,28 @@
171171
->end()
172172
->end()
173173
->end()
174+
->arrayNode('meilisearch')
175+
->normalizeKeys(false)
176+
->useAttributeAsKey('name')
177+
->arrayPrototype()
178+
->children()
179+
->scalarNode('api_key')->cannotBeEmpty()->end()
180+
->scalarNode('index_name')->cannotBeEmpty()->end()
181+
->scalarNode('embedder')->end()
182+
->scalarNode('vector_field')->end()
183+
->scalarNode('dimensions')->end()
184+
->end()
185+
->end()
186+
->end()
187+
->arrayNode('memory')
188+
->normalizeKeys(false)
189+
->useAttributeAsKey('name')
190+
->arrayPrototype()
191+
->children()
192+
->scalarNode('distance')->cannotBeEmpty()->end()
193+
->end()
194+
->end()
195+
->end()
174196
->arrayNode('mongodb')
175197
->normalizeKeys(false)
176198
->useAttributeAsKey('name')
@@ -185,6 +207,24 @@
185207
->end()
186208
->end()
187209
->end()
210+
->arrayNode('neo4j')
211+
->normalizeKeys(false)
212+
->useAttributeAsKey('name')
213+
->arrayPrototype()
214+
->children()
215+
->scalarNode('endpoint')->cannotBeEmpty()->end()
216+
->scalarNode('username')->cannotBeEmpty()->end()
217+
->scalarNode('password')->cannotBeEmpty()->end()
218+
->scalarNode('database')->cannotBeEmpty()->end()
219+
->scalarNode('vector_index_name')->cannotBeEmpty()->end()
220+
->scalarNode('node_name')->cannotBeEmpty()->end()
221+
->scalarNode('vector_field')->end()
222+
->scalarNode('dimensions')->end()
223+
->scalarNode('distance')->end()
224+
->booleanNode('quantization')->end()
225+
->end()
226+
->end()
227+
->end()
188228
->arrayNode('pinecone')
189229
->normalizeKeys(false)
190230
->useAttributeAsKey('name')
@@ -199,6 +239,37 @@
199239
->end()
200240
->end()
201241
->end()
242+
->arrayNode('qdrant')
243+
->normalizeKeys(false)
244+
->useAttributeAsKey('name')
245+
->arrayPrototype()
246+
->children()
247+
->scalarNode('endpoint')->cannotBeEmpty()->end()
248+
->scalarNode('api_key')->cannotBeEmpty()->end()
249+
->scalarNode('collection_name')->cannotBeEmpty()->end()
250+
->scalarNode('dimensions')->end()
251+
->scalarNode('distance')->end()
252+
->end()
253+
->end()
254+
->end()
255+
->arrayNode('surreal_db')
256+
->normalizeKeys(false)
257+
->useAttributeAsKey('name')
258+
->arrayPrototype()
259+
->children()
260+
->scalarNode('endpoint')->cannotBeEmpty()->end()
261+
->scalarNode('username')->cannotBeEmpty()->end()
262+
->scalarNode('password')->cannotBeEmpty()->end()
263+
->scalarNode('namespace')->cannotBeEmpty()->end()
264+
->scalarNode('database')->cannotBeEmpty()->end()
265+
->scalarNode('table')->end()
266+
->scalarNode('vector_field')->end()
267+
->scalarNode('strategy')->end()
268+
->scalarNode('dimensions')->end()
269+
->booleanNode('namespaced_user')->end()
270+
->end()
271+
->end()
272+
->end()
202273
->end()
203274
->end()
204275
->arrayNode('indexer')

src/ai-bundle/doc/index.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Configuration
8686
- 'Symfony\AI\Agent\Toolbox\Tool\Wikipedia'
8787
fault_tolerant_toolbox: false # Disables fault tolerant toolbox, default is true
8888
store:
89-
# also azure_search, mongodb and pinecone are supported as store type
89+
# also azure_search, meilisearch, memory, mongodb, pinecone, qdrant and surrealdb are supported as store type
9090
chroma_db:
9191
# multiple collections possible per type
9292
default:

src/ai-bundle/src/AiBundle.php

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,15 @@
4040
use Symfony\AI\Platform\ResultConverterInterface;
4141
use Symfony\AI\Store\Bridge\Azure\SearchStore as AzureSearchStore;
4242
use Symfony\AI\Store\Bridge\ChromaDb\Store as ChromaDbStore;
43+
use Symfony\AI\Store\Bridge\Meilisearch\Store as MeilisearchStore;
4344
use Symfony\AI\Store\Bridge\MongoDb\Store as MongoDbStore;
45+
use Symfony\AI\Store\Bridge\Neo4j\Store as Neo4jStore;
4446
use Symfony\AI\Store\Bridge\Pinecone\Store as PineconeStore;
47+
use Symfony\AI\Store\Bridge\Qdrant\Store as QdrantStore;
48+
use Symfony\AI\Store\Bridge\SurrealDb\Store as SurrealDbStore;
4549
use Symfony\AI\Store\Document\Vectorizer;
4650
use Symfony\AI\Store\Indexer;
51+
use Symfony\AI\Store\InMemoryStore;
4752
use Symfony\AI\Store\StoreInterface;
4853
use Symfony\AI\Store\VectorStoreInterface;
4954
use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;
@@ -476,6 +481,50 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
476481
}
477482
}
478483

484+
if ('meilisearch' === $type) {
485+
foreach ($stores as $name => $store) {
486+
$arguments = [
487+
new Reference('http_client'),
488+
$store['api_key'],
489+
$store['index_name'],
490+
];
491+
492+
if (\array_key_exists('embedder', $store)) {
493+
$arguments[3] = $store['embedder'];
494+
}
495+
496+
if (\array_key_exists('vector_field', $store)) {
497+
$arguments[4] = $store['vector_field'];
498+
}
499+
500+
if (\array_key_exists('dimensions', $store)) {
501+
$arguments[5] = $store['dimensions'];
502+
}
503+
504+
$definition = new Definition(MeilisearchStore::class);
505+
$definition
506+
->addTag('ai.store')
507+
->setArguments($arguments);
508+
509+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
510+
}
511+
}
512+
513+
if ('memory' === $type) {
514+
foreach ($stores as $name => $store) {
515+
$arguments = [
516+
$store['distance'],
517+
];
518+
519+
$definition = new Definition(InMemoryStore::class);
520+
$definition
521+
->addTag('ai.store')
522+
->setArguments($arguments);
523+
524+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
525+
}
526+
}
527+
479528
if ('mongodb' === $type) {
480529
foreach ($stores as $name => $store) {
481530
$arguments = [
@@ -502,6 +551,43 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
502551
}
503552
}
504553

554+
if ('neo4j' === $type) {
555+
foreach ($stores as $name => $store) {
556+
$arguments = [
557+
new Reference('http_client'),
558+
$store['endpoint'],
559+
$store['username'],
560+
$store['password'],
561+
$store['database'],
562+
$store['vector_index_name'],
563+
$store['node_name'],
564+
];
565+
566+
if (\array_key_exists('vector_field', $store)) {
567+
$arguments[7] = $store['vector_field'];
568+
}
569+
570+
if (\array_key_exists('dimensions', $store)) {
571+
$arguments[8] = $store['dimensions'];
572+
}
573+
574+
if (\array_key_exists('distance', $store)) {
575+
$arguments[9] = $store['distance'];
576+
}
577+
578+
if (\array_key_exists('quantization', $store)) {
579+
$arguments[10] = $store['quantization'];
580+
}
581+
582+
$definition = new Definition(Neo4jStore::class);
583+
$definition
584+
->addTag('ai.store')
585+
->setArguments($arguments);
586+
587+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
588+
}
589+
}
590+
505591
if ('pinecone' === $type) {
506592
foreach ($stores as $name => $store) {
507593
$arguments = [
@@ -525,6 +611,72 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
525611
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
526612
}
527613
}
614+
615+
if ('qdrant' === $type) {
616+
foreach ($stores as $name => $store) {
617+
$arguments = [
618+
new Reference('http_client'),
619+
$store['endpoint'],
620+
$store['api_key'],
621+
$store['collection_name'],
622+
];
623+
624+
if (\array_key_exists('dimensions', $store)) {
625+
$arguments[4] = $store['dimensions'];
626+
}
627+
628+
if (\array_key_exists('distance', $store)) {
629+
$arguments[5] = $store['distance'];
630+
}
631+
632+
$definition = new Definition(QdrantStore::class);
633+
$definition
634+
->addTag('ai.store')
635+
->setArguments($arguments);
636+
637+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
638+
}
639+
}
640+
641+
if ('surreal_db' === $type) {
642+
foreach ($stores as $name => $store) {
643+
$arguments = [
644+
new Reference('http_client'),
645+
$store['endpoint'],
646+
$store['username'],
647+
$store['password'],
648+
$store['namespace'],
649+
$store['database'],
650+
];
651+
652+
if (\array_key_exists('table', $store)) {
653+
$arguments[6] = $store['table'];
654+
}
655+
656+
if (\array_key_exists('vector_field', $store)) {
657+
$arguments[7] = $store['vector_field'];
658+
}
659+
660+
if (\array_key_exists('strategy', $store)) {
661+
$arguments[8] = $store['strategy'];
662+
}
663+
664+
if (\array_key_exists('dimensions', $store)) {
665+
$arguments[9] = $store['dimensions'];
666+
}
667+
668+
if (\array_key_exists('namespaced_user', $store)) {
669+
$arguments[10] = $store['namespaced_user'];
670+
}
671+
672+
$definition = new Definition(SurrealDbStore::class);
673+
$definition
674+
->addTag('ai.store')
675+
->setArguments($arguments);
676+
677+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
678+
}
679+
}
528680
}
529681

530682
/**

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ private function getFullConfig(): array
206206
'collection' => 'my_collection',
207207
],
208208
],
209+
'meilisearch' => [
210+
'my_meilisearch_store' => [
211+
'api_key' => 'foo',
212+
'index_name' => 'test',
213+
'embedder' => 'default',
214+
'vector_field' => '_vectors',
215+
'dimensions' => 768,
216+
],
217+
],
218+
'memory' => [
219+
'my_memory_store' => [
220+
'distance' => 'cosine',
221+
],
222+
],
209223
'mongodb' => [
210224
'my_mongo_store' => [
211225
'database' => 'my_db',
@@ -215,13 +229,50 @@ private function getFullConfig(): array
215229
'bulk_write' => true,
216230
],
217231
],
232+
'neo4j' => [
233+
'my_neo4j_store' => [
234+
'endpoint' => 'http://127.0.0.1:8000',
235+
'username' => 'test',
236+
'password' => 'test',
237+
'database' => 'foo',
238+
'vector_index_name' => 'test',
239+
'node_name' => 'foo',
240+
'vector_field' => '_vectors',
241+
'dimensions' => 768,
242+
'distance' => 'cosine',
243+
'quantization' => true,
244+
],
245+
],
218246
'pinecone' => [
219247
'my_pinecone_store' => [
220248
'namespace' => 'my_namespace',
221249
'filter' => ['category' => 'books'],
222250
'top_k' => 10,
223251
],
224252
],
253+
'qdrant' => [
254+
'my_qdrant_store' => [
255+
'endpoint' => 'http://127.0.0.1:8000',
256+
'api_key' => 'test',
257+
'collection_name' => 'foo',
258+
'dimensions' => 768,
259+
'distance' => 'Cosine',
260+
],
261+
],
262+
'surreal_db' => [
263+
'my_surreal_db_store' => [
264+
'endpoint' => 'http://127.0.0.1:8000',
265+
'username' => 'test',
266+
'password' => 'test',
267+
'namespace' => 'foo',
268+
'database' => 'bar',
269+
'table' => 'bar',
270+
'vector_field' => '_vectors',
271+
'strategy' => 'cosine',
272+
'dimensions' => 768,
273+
'namespaced_user' => true,
274+
],
275+
],
225276
],
226277
'indexer' => [
227278
'my_text_indexer' => [

0 commit comments

Comments
 (0)