Skip to content

Commit 46f0b27

Browse files
committed
feature #835 [Store] Manticore support (Guikingone)
This PR was squashed before being merged into the main branch. Discussion ---------- [Store] Manticore support | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | Docs? | yes | Issues | Improve #16 | License | MIT Commits ------- 11f0c31 [Store] Manticore support
2 parents 8be61b1 + 11f0c31 commit 46f0b27

File tree

11 files changed

+519
-0
lines changed

11 files changed

+519
-0
lines changed

docs/components/store.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ used vector store::
3636
You can find more advanced usage in combination with an Agent using the store for RAG in the examples folder:
3737

3838
* `Similarity Search with Cloudflare (RAG)`_
39+
* `Similarity Search with Manticore (RAG)`_
3940
* `Similarity Search with MariaDB (RAG)`_
4041
* `Similarity Search with Meilisearch (RAG)`_
4142
* `Similarity Search with memory storage (RAG)`_
@@ -63,6 +64,7 @@ Supported Stores
6364
* `Chroma`_ (requires `codewithkyrian/chromadb-php` as additional dependency)
6465
* `Cloudflare`_
6566
* `InMemory`_
67+
* `Manticore`_
6668
* `MariaDB`_ (requires `ext-pdo`)
6769
* `Meilisearch`_
6870
* `Milvus`_
@@ -128,6 +130,7 @@ This leads to a store implementing two methods::
128130

129131
.. _`Retrieval Augmented Generation`: https://en.wikipedia.org/wiki/Retrieval-augmented_generation
130132
.. _`Similarity Search with Cloudflare (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/cloudflare.php
133+
.. _`Similarity Search with Manticore (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/manticore.php
131134
.. _`Similarity Search with MariaDB (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/mariadb-gemini.php
132135
.. _`Similarity Search with Meilisearch (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/meilisearch.php
133136
.. _`Similarity Search with memory storage (RAG)`: https://github.com/symfony/ai/blob/main/examples/rag/in-memory.php
@@ -144,6 +147,7 @@ This leads to a store implementing two methods::
144147
.. _`Azure AI Search`: https://azure.microsoft.com/products/ai-services/ai-search
145148
.. _`Chroma`: https://www.trychroma.com/
146149
.. _`Cloudflare`: https://developers.cloudflare.com/vectorize/
150+
.. _`Manticore`: https://manticoresearch.com/
147151
.. _`MariaDB`: https://mariadb.org/projects/mariadb-vector/
148152
.. _`Pinecone`: https://www.pinecone.io/
149153
.. _`Postgres`: https://www.postgresql.org/about/news/pgvector-070-released-2852/

examples/.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,6 @@ POGOCACHE_PASSWORD=symfony
171171

172172
# Redis (both store and message store)
173173
REDIS_HOST=localhost
174+
175+
# Manticore (store)
176+
MANTICORE_HOST=http://127.0.0.1:9308

examples/commands/stores.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\AI\Store\Bridge\ClickHouse\Store as ClickHouseStore;
1818
use Symfony\AI\Store\Bridge\Local\CacheStore;
1919
use Symfony\AI\Store\Bridge\Local\InMemoryStore;
20+
use Symfony\AI\Store\Bridge\Manticore\Store as ManticoreStore;
2021
use Symfony\AI\Store\Bridge\MariaDb\Store as MariaDbStore;
2122
use Symfony\AI\Store\Bridge\Meilisearch\Store as MeilisearchStore;
2223
use Symfony\AI\Store\Bridge\Milvus\Store as MilvusStore;
@@ -44,6 +45,12 @@
4445
env('CLICKHOUSE_DATABASE'),
4546
env('CLICKHOUSE_TABLE'),
4647
),
48+
'manticore' => static fn (): ManticoreStore => new ManticoreStore(
49+
http_client(),
50+
env('MANTICORE_HOST'),
51+
'symfony',
52+
'_vectors',
53+
),
4754
'mariadb' => static fn (): MariaDbStore => MariaDbStore::fromDbal(
4855
DriverManager::getConnection((new DsnParser())->parse(env('MARIADB_URI'))),
4956
'my_table_for_commands',

examples/compose.yaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,20 @@ services:
1919
ports:
2020
- '8123:8123'
2121

22+
manticore:
23+
image: manticoresearch/manticore
24+
ulimits:
25+
nproc: 65535
26+
nofile:
27+
soft: 65535
28+
hard: 65535
29+
memlock:
30+
soft: -1
31+
hard: -1
32+
ports:
33+
- '9306:9306'
34+
- '9308:9308'
35+
2236
mariadb:
2337
image: mariadb:11.7
2438
environment:

examples/rag/manticore.php

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
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+
use Symfony\AI\Agent\Agent;
13+
use Symfony\AI\Agent\Toolbox\AgentProcessor;
14+
use Symfony\AI\Agent\Toolbox\Tool\SimilaritySearch;
15+
use Symfony\AI\Agent\Toolbox\Toolbox;
16+
use Symfony\AI\Fixtures\Movies;
17+
use Symfony\AI\Platform\Bridge\OpenAi\PlatformFactory;
18+
use Symfony\AI\Platform\Message\Message;
19+
use Symfony\AI\Platform\Message\MessageBag;
20+
use Symfony\AI\Store\Bridge\Manticore\Store;
21+
use Symfony\AI\Store\Document\Loader\InMemoryLoader;
22+
use Symfony\AI\Store\Document\Metadata;
23+
use Symfony\AI\Store\Document\TextDocument;
24+
use Symfony\AI\Store\Document\Vectorizer;
25+
use Symfony\AI\Store\Indexer;
26+
use Symfony\Component\Uid\Uuid;
27+
28+
require_once dirname(__DIR__).'/bootstrap.php';
29+
30+
// initialize the store
31+
$store = new Store(
32+
httpClient: http_client(),
33+
host: 'http://127.0.0.1:9308',
34+
table: 'movies',
35+
field: '_movie_vectors',
36+
);
37+
38+
// Create the table
39+
$store->setup();
40+
41+
// create embeddings and documents
42+
$documents = [];
43+
foreach (Movies::all() as $i => $movie) {
44+
$documents[] = new TextDocument(
45+
id: Uuid::v4(),
46+
content: 'Title: '.$movie['title'].\PHP_EOL.'Director: '.$movie['director'].\PHP_EOL.'Description: '.$movie['description'],
47+
metadata: new Metadata($movie),
48+
);
49+
}
50+
51+
// create embeddings for documents
52+
$platform = PlatformFactory::create(env('OPENAI_API_KEY'), http_client());
53+
$vectorizer = new Vectorizer($platform, 'text-embedding-3-small', logger());
54+
$indexer = new Indexer(new InMemoryLoader($documents), $vectorizer, $store, logger: logger());
55+
$indexer->index($documents);
56+
57+
$similaritySearch = new SimilaritySearch($vectorizer, $store);
58+
$toolbox = new Toolbox([$similaritySearch], logger: logger());
59+
$processor = new AgentProcessor($toolbox);
60+
$agent = new Agent($platform, 'gpt-4o-mini', [$processor], [$processor]);
61+
62+
$messages = new MessageBag(
63+
Message::forSystem('Please answer all user questions only using SimilaritySearch function.'),
64+
Message::ofUser('Which movie fits the theme of technology?')
65+
);
66+
$result = $agent->call($messages);
67+
68+
echo $result->getContent().\PHP_EOL;

src/ai-bundle/config/options.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,20 @@
514514
->end()
515515
->end()
516516
->end()
517+
->arrayNode('manticore')
518+
->useAttributeAsKey('name')
519+
->arrayPrototype()
520+
->children()
521+
->stringNode('endpoint')->cannotBeEmpty()->end()
522+
->stringNode('table')->cannotBeEmpty()->end()
523+
->stringNode('field')->end()
524+
->stringNode('type')->end()
525+
->stringNode('similarity')->end()
526+
->integerNode('dimensions')->end()
527+
->stringNode('quantization')->end()
528+
->end()
529+
->end()
530+
->end()
517531
->arrayNode('meilisearch')
518532
->useAttributeAsKey('name')
519533
->arrayPrototype()

src/ai-bundle/src/AiBundle.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
use Symfony\AI\Store\Bridge\Local\DistanceCalculator;
7070
use Symfony\AI\Store\Bridge\Local\DistanceStrategy;
7171
use Symfony\AI\Store\Bridge\Local\InMemoryStore;
72+
use Symfony\AI\Store\Bridge\Manticore\Store as ManticoreStore;
7273
use Symfony\AI\Store\Bridge\Meilisearch\Store as MeilisearchStore;
7374
use Symfony\AI\Store\Bridge\Milvus\Store as MilvusStore;
7475
use Symfony\AI\Store\Bridge\MongoDb\Store as MongoDbStore;
@@ -912,6 +913,45 @@ private function processStoreConfig(string $type, array $stores, ContainerBuilde
912913
}
913914
}
914915

916+
if ('manticore' === $type) {
917+
foreach ($stores as $name => $store) {
918+
$arguments = [
919+
new Reference('http_client'),
920+
$store['endpoint'],
921+
$store['table'],
922+
];
923+
924+
if (\array_key_exists('field', $store)) {
925+
$arguments[3] = $store['field'];
926+
}
927+
928+
if (\array_key_exists('type', $store)) {
929+
$arguments[4] = $store['type'];
930+
}
931+
932+
if (\array_key_exists('similarity', $store)) {
933+
$arguments[5] = $store['similarity'];
934+
}
935+
936+
if (\array_key_exists('dimensions', $store)) {
937+
$arguments[6] = $store['dimensions'];
938+
}
939+
940+
if (\array_key_exists('quantization', $store)) {
941+
$arguments[7] = $store['quantization'];
942+
}
943+
944+
$definition = new Definition(ManticoreStore::class);
945+
$definition
946+
->addTag('ai.store')
947+
->setArguments($arguments);
948+
949+
$container->setDefinition('ai.store.'.$type.'.'.$name, $definition);
950+
$container->registerAliasForArgument('ai.store.'.$type.'.'.$name, StoreInterface::class, $name);
951+
$container->registerAliasForArgument('ai.store.'.$type.'.'.$name, StoreInterface::class, $type.'_'.$name);
952+
}
953+
}
954+
915955
if ('meilisearch' === $type) {
916956
foreach ($stores as $name => $store) {
917957
$arguments = [

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2911,6 +2911,17 @@ private function getFullConfig(): array
29112911
'endpoint_url' => 'https://api.cloudflare.com/client/v5/accounts',
29122912
],
29132913
],
2914+
'manticore' => [
2915+
'my_manticore_store' => [
2916+
'endpoint' => 'http://127.0.0.1:9306',
2917+
'table' => 'test',
2918+
'field' => 'foo_vector',
2919+
'type' => 'hnsw',
2920+
'similarity' => 'cosine',
2921+
'dimensions' => 768,
2922+
'quantization' => '1bit',
2923+
],
2924+
],
29142925
'meilisearch' => [
29152926
'my_meilisearch_store' => [
29162927
'endpoint' => 'http://127.0.0.1:7700',

src/store/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ CHANGELOG
3838
- ChromaDB
3939
- ClickHouse
4040
- Cloudflare
41+
- Manticore
4142
- MariaDB
4243
- Meilisearch
4344
- MongoDB

0 commit comments

Comments
 (0)