From 1d49da259fd65081ded42229dba40d5694085f5a Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Thu, 13 Nov 2025 10:05:47 -0700 Subject: [PATCH 01/11] Add Pinecone ManagedStore --- .../src/Bridge/Pinecone/ManagedStore.php | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/store/src/Bridge/Pinecone/ManagedStore.php diff --git a/src/store/src/Bridge/Pinecone/ManagedStore.php b/src/store/src/Bridge/Pinecone/ManagedStore.php new file mode 100644 index 000000000..86d916a61 --- /dev/null +++ b/src/store/src/Bridge/Pinecone/ManagedStore.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\AI\Store\Bridge\Pinecone; + +use Probots\Pinecone\Client; +use Symfony\AI\Store\Exception\RuntimeException; +use Symfony\AI\Store\ManagedStoreInterface; + +final class ManagedStore implements ManagedStoreInterface +{ + public function __construct( + private readonly Client $pinecone, + private readonly string $indexName, + private readonly int $dimension, + private readonly string $metric, + private readonly string $cloud, + private readonly string $region, + ) { + if (!class_exists(Client::class)) { + throw new RuntimeException('For using the Pinecone as retrieval vector store, the probots-io/pinecone-php package is required. Try running "composer require probots-io/pinecone-php".'); + } + } + + public function setup(array $options = []): void + { + $this->pinecone + ->control() + ->index($this->indexName) + ->createServerless($this->dimension, $this->metric, $this->cloud, $this->region); + } + + public function drop(): void + { + $this->pinecone + ->control() + ->index($this->indexName) + ->delete(); + } +} From b28bc95d5f6a6541dd0230e927dae6c73e078631 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Thu, 13 Nov 2025 17:51:47 -0700 Subject: [PATCH 02/11] id: support more types and cast to uuid --- src/store/src/Document/VectorDocument.php | 9 ++++++- .../tests/Document/VectorDocumentTest.php | 24 +++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/store/src/Document/VectorDocument.php b/src/store/src/Document/VectorDocument.php index 861f0d882..af6f108c1 100644 --- a/src/store/src/Document/VectorDocument.php +++ b/src/store/src/Document/VectorDocument.php @@ -19,12 +19,19 @@ */ final class VectorDocument { + public readonly int|string|Uuid $id; + public function __construct( - public readonly Uuid $id, + int|string|Uuid $id, public readonly VectorInterface $vector, public readonly Metadata $metadata = new Metadata(), public readonly ?float $score = null, ) { + if (\is_string($id) && Uuid::isValid($id)) { + $this->id = Uuid::fromString($id); + } else { + $this->id = $id; + } } /** diff --git a/src/store/tests/Document/VectorDocumentTest.php b/src/store/tests/Document/VectorDocumentTest.php index 54a5c2f82..ac692f5a9 100644 --- a/src/store/tests/Document/VectorDocumentTest.php +++ b/src/store/tests/Document/VectorDocumentTest.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\Attributes\TestDox; use PHPUnit\Framework\Attributes\TestWith; use PHPUnit\Framework\TestCase; +use Symfony\AI\Platform\Vector\NullVector; use Symfony\AI\Platform\Vector\Vector; use Symfony\AI\Store\Document\Metadata; use Symfony\AI\Store\Document\VectorDocument; @@ -25,6 +26,29 @@ */ final class VectorDocumentTest extends TestCase { + #[TestWith([1])] + #[TestWith(['id'])] + #[TestWith(['uuid'])] + public function testConstructorIdSupportsManyTypes(int|string $id) + { + if ('uuid' === $id) { + $id = Uuid::v4(); + } + + $document = new VectorDocument($id, new NullVector()); + + $this->assertSame($id, $document->id); + } + + #[TestDox('Automatically convert strings in UUID format to Uuid instances')] + public function testConstructorConvertIdToUuid() + { + $id = Uuid::v4()->toString(); + $document = new VectorDocument($id, new NullVector()); + + $this->assertInstanceOf(Uuid::class, $document->id); + } + #[TestDox('Creates document with required parameters only')] public function testConstructorWithRequiredParameters() { From a18b59bf27ac9d7d555e562f4861c7e1225dc958 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Thu, 13 Nov 2025 18:02:01 -0700 Subject: [PATCH 03/11] remove sneaky code --- .../src/Bridge/Pinecone/ManagedStore.php | 48 ------------------- 1 file changed, 48 deletions(-) delete mode 100644 src/store/src/Bridge/Pinecone/ManagedStore.php diff --git a/src/store/src/Bridge/Pinecone/ManagedStore.php b/src/store/src/Bridge/Pinecone/ManagedStore.php deleted file mode 100644 index 86d916a61..000000000 --- a/src/store/src/Bridge/Pinecone/ManagedStore.php +++ /dev/null @@ -1,48 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\AI\Store\Bridge\Pinecone; - -use Probots\Pinecone\Client; -use Symfony\AI\Store\Exception\RuntimeException; -use Symfony\AI\Store\ManagedStoreInterface; - -final class ManagedStore implements ManagedStoreInterface -{ - public function __construct( - private readonly Client $pinecone, - private readonly string $indexName, - private readonly int $dimension, - private readonly string $metric, - private readonly string $cloud, - private readonly string $region, - ) { - if (!class_exists(Client::class)) { - throw new RuntimeException('For using the Pinecone as retrieval vector store, the probots-io/pinecone-php package is required. Try running "composer require probots-io/pinecone-php".'); - } - } - - public function setup(array $options = []): void - { - $this->pinecone - ->control() - ->index($this->indexName) - ->createServerless($this->dimension, $this->metric, $this->cloud, $this->region); - } - - public function drop(): void - { - $this->pinecone - ->control() - ->index($this->indexName) - ->delete(); - } -} From 0339567eb305d7bf1f0f0db5a4a0d00d3b838819 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Fri, 14 Nov 2025 13:47:49 -0700 Subject: [PATCH 04/11] support more types in TextDocument --- src/store/src/Document/TextDocument.php | 12 ++++++++-- src/store/tests/Document/TextDocumentTest.php | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/store/src/Document/TextDocument.php b/src/store/src/Document/TextDocument.php index eefac3f31..db17469af 100644 --- a/src/store/src/Document/TextDocument.php +++ b/src/store/src/Document/TextDocument.php @@ -19,14 +19,22 @@ */ final class TextDocument implements EmbeddableDocumentInterface { + private readonly int|string|Uuid $id; + public function __construct( - private readonly Uuid $id, + int|string|Uuid $id, private readonly string $content, private readonly Metadata $metadata = new Metadata(), ) { if ('' === trim($this->content)) { throw new InvalidArgumentException('The content shall not be an empty string.'); } + + if (\is_string($id) && Uuid::isValid($id)) { + $this->id = Uuid::fromString($id); + } else { + $this->id = $id; + } } public function withContent(string $content): self @@ -34,7 +42,7 @@ public function withContent(string $content): self return new self($this->id, $content, $this->metadata); } - public function getId(): Uuid + public function getId(): int|string|Uuid { return $this->id; } diff --git a/src/store/tests/Document/TextDocumentTest.php b/src/store/tests/Document/TextDocumentTest.php index 5f9c876ad..fd28fe272 100644 --- a/src/store/tests/Document/TextDocumentTest.php +++ b/src/store/tests/Document/TextDocumentTest.php @@ -22,6 +22,29 @@ final class TextDocumentTest extends TestCase { + #[TestWith([1])] + #[TestWith(['id'])] + #[TestWith(['uuid'])] + public function testConstructorIdSupportsManyTypes(int|string $id) + { + if ('uuid' === $id) { + $id = Uuid::v4(); + } + + $document = new TextDocument($id, 'content'); + + $this->assertSame($id, $document->getId()); + } + + #[TestDox('Automatically convert strings in UUID format to Uuid instances')] + public function testConstructorConvertIdToUuid() + { + $id = Uuid::v4()->toString(); + $document = new TextDocument($id, 'content'); + + $this->assertInstanceOf(Uuid::class, $document->getId()); + } + #[TestDox('Creates document with valid content and metadata')] public function testConstructorWithValidContent() { From 4c2532ad4cc8e89dfc0e9ca0fe69a9441aff04a8 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Fri, 14 Nov 2025 13:52:27 -0700 Subject: [PATCH 05/11] fix places where VectorDocument is intantiated --- src/store/src/Bridge/AzureSearch/SearchStore.php | 2 +- src/store/src/Bridge/Cache/Store.php | 2 +- src/store/src/Bridge/ChromaDb/Store.php | 2 +- src/store/src/Bridge/ClickHouse/Store.php | 2 +- src/store/src/Bridge/Cloudflare/Store.php | 2 +- src/store/src/Bridge/ManticoreSearch/Store.php | 2 +- src/store/src/Bridge/Neo4j/Store.php | 2 +- src/store/src/Bridge/Pinecone/Store.php | 3 +-- src/store/src/Bridge/Postgres/Store.php | 2 +- src/store/src/Bridge/Qdrant/Store.php | 2 +- src/store/src/Bridge/Redis/Store.php | 2 +- src/store/src/Bridge/Supabase/Store.php | 2 +- src/store/src/Bridge/SurrealDb/Store.php | 2 +- 13 files changed, 13 insertions(+), 14 deletions(-) diff --git a/src/store/src/Bridge/AzureSearch/SearchStore.php b/src/store/src/Bridge/AzureSearch/SearchStore.php index 77c28745e..6b42dee4a 100644 --- a/src/store/src/Bridge/AzureSearch/SearchStore.php +++ b/src/store/src/Bridge/AzureSearch/SearchStore.php @@ -91,7 +91,7 @@ private function convertToIndexableArray(VectorDocument $document): array private function convertToVectorDocument(array $data): VectorDocument { return new VectorDocument( - id: Uuid::fromString($data['id']), + id: $data['id'], vector: !\array_key_exists($this->vectorFieldName, $data) || null === $data[$this->vectorFieldName] ? new NullVector() : new Vector($data[$this->vectorFieldName]), diff --git a/src/store/src/Bridge/Cache/Store.php b/src/store/src/Bridge/Cache/Store.php index c994531c0..471d2b4a9 100644 --- a/src/store/src/Bridge/Cache/Store.php +++ b/src/store/src/Bridge/Cache/Store.php @@ -79,7 +79,7 @@ public function query(Vector $vector, array $options = []): iterable $documents = $this->cache->get($this->cacheKey, static fn (): array => []); $vectorDocuments = array_map(static fn (array $document): VectorDocument => new VectorDocument( - id: Uuid::fromString($document['id']), + id: $document['id'], vector: new Vector($document['vector']), metadata: new Metadata($document['metadata']), ), $documents); diff --git a/src/store/src/Bridge/ChromaDb/Store.php b/src/store/src/Bridge/ChromaDb/Store.php index 5a9b17934..5db5fbb33 100644 --- a/src/store/src/Bridge/ChromaDb/Store.php +++ b/src/store/src/Bridge/ChromaDb/Store.php @@ -83,7 +83,7 @@ public function query(Vector $vector, array $options = []): iterable } yield new VectorDocument( - id: Uuid::fromString($queryResponse->ids[0][$i]), + id: $queryResponse->ids[0][$i], vector: new Vector($queryResponse->embeddings[0][$i]), metadata: $metaData, score: $queryResponse->distances[0][$i] ?? null, diff --git a/src/store/src/Bridge/ClickHouse/Store.php b/src/store/src/Bridge/ClickHouse/Store.php index dc2b783bc..ee166251a 100644 --- a/src/store/src/Bridge/ClickHouse/Store.php +++ b/src/store/src/Bridge/ClickHouse/Store.php @@ -95,7 +95,7 @@ public function query(Vector $vector, array $options = [], ?float $minScore = nu foreach ($results as $result) { yield new VectorDocument( - id: Uuid::fromString($result['id']), + id: $result['id'], vector: new Vector($result['embedding']), metadata: new Metadata(json_decode($result['metadata'] ?? '{}', true, 512, \JSON_THROW_ON_ERROR)), score: $result['score'], diff --git a/src/store/src/Bridge/Cloudflare/Store.php b/src/store/src/Bridge/Cloudflare/Store.php index 8cd1e5943..528dfb0f0 100644 --- a/src/store/src/Bridge/Cloudflare/Store.php +++ b/src/store/src/Bridge/Cloudflare/Store.php @@ -138,7 +138,7 @@ private function convertToVectorDocument(array $data): VectorDocument : new Vector($data['values']); return new VectorDocument( - id: Uuid::fromString($id), + id: $id, vector: $vector, metadata: new Metadata($data['metadata']), score: $data['score'] ?? null diff --git a/src/store/src/Bridge/ManticoreSearch/Store.php b/src/store/src/Bridge/ManticoreSearch/Store.php index 6875b8d4b..09d8d4d21 100644 --- a/src/store/src/Bridge/ManticoreSearch/Store.php +++ b/src/store/src/Bridge/ManticoreSearch/Store.php @@ -150,7 +150,7 @@ private function convertToVectorDocument(array $data): VectorDocument : new Vector($payload[$this->field]); return new VectorDocument( - id: Uuid::fromString($payload['uuid']), + id: $payload['uuid'], vector: $vector, metadata: new Metadata($payload['metadata'] ?? []), score: $data['_knn_dist'] ?? null diff --git a/src/store/src/Bridge/Neo4j/Store.php b/src/store/src/Bridge/Neo4j/Store.php index 8007e450d..a5da90179 100644 --- a/src/store/src/Bridge/Neo4j/Store.php +++ b/src/store/src/Bridge/Neo4j/Store.php @@ -117,7 +117,7 @@ private function convertToVectorDocument(array $data): VectorDocument : new Vector($payload['properties'][$this->embeddingsField]); return new VectorDocument( - id: Uuid::fromString($id), + id: $id, vector: $vector, metadata: new Metadata(json_decode($payload['properties']['metadata'], true)), score: $data[1] ?? null diff --git a/src/store/src/Bridge/Pinecone/Store.php b/src/store/src/Bridge/Pinecone/Store.php index deabd8bbb..77b19bdc2 100644 --- a/src/store/src/Bridge/Pinecone/Store.php +++ b/src/store/src/Bridge/Pinecone/Store.php @@ -17,7 +17,6 @@ use Symfony\AI\Store\Document\Metadata; use Symfony\AI\Store\Document\VectorDocument; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; /** * @author Christopher Hertel @@ -65,7 +64,7 @@ public function query(Vector $vector, array $options = []): iterable foreach ($result->json()['matches'] as $match) { yield new VectorDocument( - id: Uuid::fromString($match['id']), + id: $match['id'], vector: new Vector($match['values']), metadata: new Metadata($match['metadata']), score: $match['score'], diff --git a/src/store/src/Bridge/Postgres/Store.php b/src/store/src/Bridge/Postgres/Store.php index 92001d04b..593ced2b4 100644 --- a/src/store/src/Bridge/Postgres/Store.php +++ b/src/store/src/Bridge/Postgres/Store.php @@ -172,7 +172,7 @@ public function query(Vector $vector, array $options = []): iterable foreach ($statement->fetchAll(\PDO::FETCH_ASSOC) as $result) { yield new VectorDocument( - id: Uuid::fromString($result['id']), + id: $result['id'], vector: new Vector($this->fromPgvector($result['embedding'])), metadata: new Metadata(json_decode($result['metadata'] ?? '{}', true, 512, \JSON_THROW_ON_ERROR)), score: $result['score'], diff --git a/src/store/src/Bridge/Qdrant/Store.php b/src/store/src/Bridge/Qdrant/Store.php index deb4d760c..b579f95b5 100644 --- a/src/store/src/Bridge/Qdrant/Store.php +++ b/src/store/src/Bridge/Qdrant/Store.php @@ -153,7 +153,7 @@ private function convertToVectorDocument(array $data): VectorDocument : new Vector($data['vector']); return new VectorDocument( - id: Uuid::fromString($id), + id: $id, vector: $vector, metadata: new Metadata($data['payload']), score: $data['score'] ?? null diff --git a/src/store/src/Bridge/Redis/Store.php b/src/store/src/Bridge/Redis/Store.php index e15c6569a..dc89148f8 100644 --- a/src/store/src/Bridge/Redis/Store.php +++ b/src/store/src/Bridge/Redis/Store.php @@ -167,7 +167,7 @@ public function query(Vector $vector, array $options = []): iterable } yield new VectorDocument( - id: Uuid::fromString($data['$.id']), + id: $data['$.id'], vector: new Vector($data['$.embedding'] ?? []), metadata: new Metadata($data['$.metadata'] ?? []), score: $score, diff --git a/src/store/src/Bridge/Supabase/Store.php b/src/store/src/Bridge/Supabase/Store.php index d72ec5dc4..0cf3ec7ae 100644 --- a/src/store/src/Bridge/Supabase/Store.php +++ b/src/store/src/Bridge/Supabase/Store.php @@ -137,7 +137,7 @@ public function query(Vector $vector, array $options = []): iterable $metadata = \is_array($record['metadata']) ? $record['metadata'] : json_decode($record['metadata'], true, 512, \JSON_THROW_ON_ERROR); yield new VectorDocument( - id: Uuid::fromString($record['id']), + id: $record['id'], vector: new Vector($embedding), metadata: new Metadata($metadata), score: (float) $record['score'], diff --git a/src/store/src/Bridge/SurrealDb/Store.php b/src/store/src/Bridge/SurrealDb/Store.php index 660edc95a..389532eda 100644 --- a/src/store/src/Bridge/SurrealDb/Store.php +++ b/src/store/src/Bridge/SurrealDb/Store.php @@ -149,7 +149,7 @@ private function convertToVectorDocument(array $data): VectorDocument unset($data['_metadata']['_id']); return new VectorDocument( - id: Uuid::fromString($id), + id: $id, vector: $vector, metadata: new Metadata($data['_metadata']), ); From 24ce07cf03f52dde5c5144e912eea9cc6700a488 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Fri, 14 Nov 2025 13:52:46 -0700 Subject: [PATCH 06/11] update reference in docs --- docs/cookbook/rag-implementation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/cookbook/rag-implementation.rst b/docs/cookbook/rag-implementation.rst index 46541b42d..8f21c703a 100644 --- a/docs/cookbook/rag-implementation.rst +++ b/docs/cookbook/rag-implementation.rst @@ -203,7 +203,7 @@ Document Loading Strategies $articles = $articleRepository->findAll(); $documents = array_map( fn($article) => new TextDocument( - id: Uuid::fromString($article->getId()), + id: $article->getId(), content: $article->getTitle().PHP_EOL.$article->getContent(), metadata: new Metadata(['author' => $article->getAuthor()]) ), From 1d85de7120af0f04f422632e38b13686b50a4840 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Fri, 14 Nov 2025 14:05:19 -0700 Subject: [PATCH 07/11] Fix PHP CS --- src/store/src/Bridge/AzureSearch/SearchStore.php | 1 - src/store/src/Bridge/Cache/Store.php | 1 - src/store/src/Bridge/ChromaDb/Store.php | 1 - src/store/src/Bridge/ClickHouse/Store.php | 1 - src/store/src/Bridge/Cloudflare/Store.php | 1 - src/store/src/Bridge/ManticoreSearch/Store.php | 1 - src/store/src/Bridge/Neo4j/Store.php | 1 - src/store/src/Bridge/Postgres/Store.php | 1 - src/store/src/Bridge/Qdrant/Store.php | 1 - src/store/src/Bridge/Redis/Store.php | 1 - src/store/src/Bridge/Supabase/Store.php | 1 - src/store/src/Bridge/SurrealDb/Store.php | 1 - 12 files changed, 12 deletions(-) diff --git a/src/store/src/Bridge/AzureSearch/SearchStore.php b/src/store/src/Bridge/AzureSearch/SearchStore.php index 6b42dee4a..d7640a002 100644 --- a/src/store/src/Bridge/AzureSearch/SearchStore.php +++ b/src/store/src/Bridge/AzureSearch/SearchStore.php @@ -16,7 +16,6 @@ use Symfony\AI\Store\Document\Metadata; use Symfony\AI\Store\Document\VectorDocument; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Cache/Store.php b/src/store/src/Bridge/Cache/Store.php index 471d2b4a9..41475e0b6 100644 --- a/src/store/src/Bridge/Cache/Store.php +++ b/src/store/src/Bridge/Cache/Store.php @@ -19,7 +19,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\Cache\CacheInterface; /** diff --git a/src/store/src/Bridge/ChromaDb/Store.php b/src/store/src/Bridge/ChromaDb/Store.php index 5db5fbb33..2e6cdda9b 100644 --- a/src/store/src/Bridge/ChromaDb/Store.php +++ b/src/store/src/Bridge/ChromaDb/Store.php @@ -16,7 +16,6 @@ use Symfony\AI\Store\Document\Metadata; use Symfony\AI\Store\Document\VectorDocument; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; /** * @author Christopher Hertel diff --git a/src/store/src/Bridge/ClickHouse/Store.php b/src/store/src/Bridge/ClickHouse/Store.php index ee166251a..c52f89425 100644 --- a/src/store/src/Bridge/ClickHouse/Store.php +++ b/src/store/src/Bridge/ClickHouse/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\RuntimeException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; use Symfony\Contracts\HttpClient\ResponseInterface; diff --git a/src/store/src/Bridge/Cloudflare/Store.php b/src/store/src/Bridge/Cloudflare/Store.php index 528dfb0f0..36d531120 100644 --- a/src/store/src/Bridge/Cloudflare/Store.php +++ b/src/store/src/Bridge/Cloudflare/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/ManticoreSearch/Store.php b/src/store/src/Bridge/ManticoreSearch/Store.php index 09d8d4d21..5aa2adb76 100644 --- a/src/store/src/Bridge/ManticoreSearch/Store.php +++ b/src/store/src/Bridge/ManticoreSearch/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Neo4j/Store.php b/src/store/src/Bridge/Neo4j/Store.php index a5da90179..3f941a982 100644 --- a/src/store/src/Bridge/Neo4j/Store.php +++ b/src/store/src/Bridge/Neo4j/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Postgres/Store.php b/src/store/src/Bridge/Postgres/Store.php index 593ced2b4..30a8d902f 100644 --- a/src/store/src/Bridge/Postgres/Store.php +++ b/src/store/src/Bridge/Postgres/Store.php @@ -19,7 +19,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; /** * Requires PostgreSQL with pgvector extension. diff --git a/src/store/src/Bridge/Qdrant/Store.php b/src/store/src/Bridge/Qdrant/Store.php index b579f95b5..6f02ee94d 100644 --- a/src/store/src/Bridge/Qdrant/Store.php +++ b/src/store/src/Bridge/Qdrant/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Redis/Store.php b/src/store/src/Bridge/Redis/Store.php index dc89148f8..b7cbd6681 100644 --- a/src/store/src/Bridge/Redis/Store.php +++ b/src/store/src/Bridge/Redis/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\RuntimeException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; /** * @author Grégoire Pineau diff --git a/src/store/src/Bridge/Supabase/Store.php b/src/store/src/Bridge/Supabase/Store.php index 0cf3ec7ae..aae3348e6 100644 --- a/src/store/src/Bridge/Supabase/Store.php +++ b/src/store/src/Bridge/Supabase/Store.php @@ -17,7 +17,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\Exception\RuntimeException; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/SurrealDb/Store.php b/src/store/src/Bridge/SurrealDb/Store.php index 389532eda..4217ce951 100644 --- a/src/store/src/Bridge/SurrealDb/Store.php +++ b/src/store/src/Bridge/SurrealDb/Store.php @@ -19,7 +19,6 @@ use Symfony\AI\Store\Exception\RuntimeException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** From 4fd610516097b507975c6c16fca7c7210ecb5307 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Tue, 18 Nov 2025 09:55:07 -0700 Subject: [PATCH 08/11] remove Uuid auto-casting --- src/store/src/Document/TextDocument.php | 10 +--------- src/store/src/Document/VectorDocument.php | 9 +-------- src/store/tests/Document/TextDocumentTest.php | 9 --------- src/store/tests/Document/VectorDocumentTest.php | 9 --------- 4 files changed, 2 insertions(+), 35 deletions(-) diff --git a/src/store/src/Document/TextDocument.php b/src/store/src/Document/TextDocument.php index db17469af..cd3b5da54 100644 --- a/src/store/src/Document/TextDocument.php +++ b/src/store/src/Document/TextDocument.php @@ -19,22 +19,14 @@ */ final class TextDocument implements EmbeddableDocumentInterface { - private readonly int|string|Uuid $id; - public function __construct( - int|string|Uuid $id, + private readonly int|string|Uuid $id, private readonly string $content, private readonly Metadata $metadata = new Metadata(), ) { if ('' === trim($this->content)) { throw new InvalidArgumentException('The content shall not be an empty string.'); } - - if (\is_string($id) && Uuid::isValid($id)) { - $this->id = Uuid::fromString($id); - } else { - $this->id = $id; - } } public function withContent(string $content): self diff --git a/src/store/src/Document/VectorDocument.php b/src/store/src/Document/VectorDocument.php index af6f108c1..b076ae34d 100644 --- a/src/store/src/Document/VectorDocument.php +++ b/src/store/src/Document/VectorDocument.php @@ -19,19 +19,12 @@ */ final class VectorDocument { - public readonly int|string|Uuid $id; - public function __construct( - int|string|Uuid $id, + public readonly int|string|Uuid $id, public readonly VectorInterface $vector, public readonly Metadata $metadata = new Metadata(), public readonly ?float $score = null, ) { - if (\is_string($id) && Uuid::isValid($id)) { - $this->id = Uuid::fromString($id); - } else { - $this->id = $id; - } } /** diff --git a/src/store/tests/Document/TextDocumentTest.php b/src/store/tests/Document/TextDocumentTest.php index fd28fe272..0a36eaad5 100644 --- a/src/store/tests/Document/TextDocumentTest.php +++ b/src/store/tests/Document/TextDocumentTest.php @@ -36,15 +36,6 @@ public function testConstructorIdSupportsManyTypes(int|string $id) $this->assertSame($id, $document->getId()); } - #[TestDox('Automatically convert strings in UUID format to Uuid instances')] - public function testConstructorConvertIdToUuid() - { - $id = Uuid::v4()->toString(); - $document = new TextDocument($id, 'content'); - - $this->assertInstanceOf(Uuid::class, $document->getId()); - } - #[TestDox('Creates document with valid content and metadata')] public function testConstructorWithValidContent() { diff --git a/src/store/tests/Document/VectorDocumentTest.php b/src/store/tests/Document/VectorDocumentTest.php index ac692f5a9..2b94a5c9b 100644 --- a/src/store/tests/Document/VectorDocumentTest.php +++ b/src/store/tests/Document/VectorDocumentTest.php @@ -40,15 +40,6 @@ public function testConstructorIdSupportsManyTypes(int|string $id) $this->assertSame($id, $document->id); } - #[TestDox('Automatically convert strings in UUID format to Uuid instances')] - public function testConstructorConvertIdToUuid() - { - $id = Uuid::v4()->toString(); - $document = new VectorDocument($id, new NullVector()); - - $this->assertInstanceOf(Uuid::class, $document->id); - } - #[TestDox('Creates document with required parameters only')] public function testConstructorWithRequiredParameters() { From 41888b4aa4c44bde06c4479ac29e461bc1df6cac Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Tue, 18 Nov 2025 10:15:32 -0700 Subject: [PATCH 09/11] fix broken tests --- src/store/src/Bridge/Supabase/Tests/StoreTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/store/src/Bridge/Supabase/Tests/StoreTest.php b/src/store/src/Bridge/Supabase/Tests/StoreTest.php index f353e0394..c99873fc2 100644 --- a/src/store/src/Bridge/Supabase/Tests/StoreTest.php +++ b/src/store/src/Bridge/Supabase/Tests/StoreTest.php @@ -144,7 +144,7 @@ public function testQuerySuccess() $this->assertCount(1, $result); $this->assertInstanceOf(VectorDocument::class, $result[0]); - $this->assertTrue($uuid->equals($result[0]->id)); + $this->assertSame($uuid->toRfc4122(), $result[0]->id); $this->assertSame([0.5, 0.6, 0.7], $result[0]->vector->getData()); $this->assertSame(['category' => 'test'], $result[0]->metadata->getArrayCopy()); $this->assertSame(0.85, $result[0]->score); @@ -176,12 +176,12 @@ public function testQueryHandlesMultipleResultsAndMultipleOptions() $this->assertCount(2, $result); $this->assertInstanceOf(VectorDocument::class, $result[0]); - $this->assertTrue($uuid1->equals($result[0]->id)); + $this->assertSame($uuid1->toRfc4122(), $result[0]->id); $this->assertSame([0.1, 0.2], $result[0]->vector->getData()); $this->assertSame(0.95, $result[0]->score); $this->assertSame(['type' => 'first'], $result[0]->metadata->getArrayCopy()); $this->assertInstanceOf(VectorDocument::class, $result[1]); - $this->assertTrue($uuid2->equals($result[1]->id)); + $this->assertSame($uuid2->toRfc4122(), $result[1]->id); $this->assertSame([0.3, 0.4], $result[1]->vector->getData()); $this->assertSame(0.85, $result[1]->score); $this->assertSame(['type' => 'second'], $result[1]->metadata->getArrayCopy()); @@ -209,7 +209,7 @@ public function testQueryParsesComplexMetadata() $metadata = $document->metadata->getArrayCopy(); $this->assertCount(1, $result); $this->assertInstanceOf(VectorDocument::class, $document); - $this->assertTrue($uuid->equals($document->id)); + $this->assertSame($uuid->toRfc4122(), $document->id); $this->assertSame([0.1, 0.2, 0.3, 0.4], $document->vector->getData()); $this->assertSame(0.92, $document->score); $this->assertSame('Test Document', $metadata['title']); From 317e702abdfbba441a50ae218549361984181853 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Thu, 11 Dec 2025 13:07:59 -0700 Subject: [PATCH 10/11] Remove Uuid auto-casting from all stores --- src/store/src/Bridge/Meilisearch/Store.php | 4 ++-- src/store/src/Bridge/Milvus/Store.php | 4 ++-- src/store/src/Bridge/MongoDb/Store.php | 6 +++--- src/store/src/Bridge/OpenSearch/Store.php | 4 ++-- src/store/src/Bridge/Typesense/Store.php | 4 ++-- src/store/src/Bridge/Weaviate/Store.php | 6 +++--- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/store/src/Bridge/Meilisearch/Store.php b/src/store/src/Bridge/Meilisearch/Store.php index 4a3ce409e..b2aeb5583 100644 --- a/src/store/src/Bridge/Meilisearch/Store.php +++ b/src/store/src/Bridge/Meilisearch/Store.php @@ -130,7 +130,7 @@ private function request(string $method, string $endpoint, array $payload): arra private function convertToIndexableArray(VectorDocument $document): array { return array_merge([ - 'id' => $document->id->toRfc4122(), + 'id' => $document->id, $this->vectorFieldName => [ $this->embedder => [ 'embeddings' => $document->vector->getData(), @@ -154,6 +154,6 @@ private function convertToVectorDocument(array $data): VectorDocument unset($data['id'], $data[$this->vectorFieldName], $data['_rankingScore']); - return new VectorDocument(Uuid::fromString($id), $vector, new Metadata($data), $score); + return new VectorDocument($id, $vector, new Metadata($data), $score); } } diff --git a/src/store/src/Bridge/Milvus/Store.php b/src/store/src/Bridge/Milvus/Store.php index bd9549407..cec264d57 100644 --- a/src/store/src/Bridge/Milvus/Store.php +++ b/src/store/src/Bridge/Milvus/Store.php @@ -151,7 +151,7 @@ private function request(string $method, string $endpoint, array $payload): arra private function convertToIndexableArray(VectorDocument $document): array { return [ - 'id' => $document->id->toRfc4122(), + 'id' => $document->id, '_metadata' => json_encode($document->metadata->getArrayCopy()), $this->vectorFieldName => $document->vector->getData(), ]; @@ -170,6 +170,6 @@ private function convertToVectorDocument(array $data): VectorDocument $score = $data['distance'] ?? null; - return new VectorDocument(Uuid::fromString($id), $vector, new Metadata(json_decode($data['_metadata'], true)), $score); + return new VectorDocument($id, $vector, new Metadata(json_decode($data['_metadata'], true)), $score); } } diff --git a/src/store/src/Bridge/MongoDb/Store.php b/src/store/src/Bridge/MongoDb/Store.php index 1d407c2d6..bea1f5a31 100644 --- a/src/store/src/Bridge/MongoDb/Store.php +++ b/src/store/src/Bridge/MongoDb/Store.php @@ -179,7 +179,7 @@ public function query(Vector $vector, array $options = []): iterable foreach ($results as $result) { yield new VectorDocument( - id: $this->toUuid($result['_id']), + id: $this->getBinaryData($result['_id']), vector: new Vector($result[$this->vectorFieldName]), metadata: new Metadata($result['metadata'] ?? []), score: $result['score'], @@ -197,8 +197,8 @@ private function toBinary(Uuid $uuid): Binary return new Binary($uuid->toBinary(), Binary::TYPE_UUID); } - private function toUuid(Binary $binary): Uuid + private function getBinaryData(Binary $binary): string { - return Uuid::fromString($binary->getData()); + return $binary->getData(); } } diff --git a/src/store/src/Bridge/OpenSearch/Store.php b/src/store/src/Bridge/OpenSearch/Store.php index af9228b81..a2325fb0f 100644 --- a/src/store/src/Bridge/OpenSearch/Store.php +++ b/src/store/src/Bridge/OpenSearch/Store.php @@ -76,7 +76,7 @@ public function add(VectorDocument ...$documents): void $documentToIndex = fn (VectorDocument $document): array => [ 'index' => [ '_index' => $this->indexName, - '_id' => $document->id->toRfc4122(), + '_id' => $document->id, ], ]; @@ -153,6 +153,6 @@ private function convertToVectorDocument(array $document): VectorDocument ? new NullVector() : new Vector($document['_source'][$this->vectorsField]); - return new VectorDocument(Uuid::fromString($id), $vector, new Metadata(json_decode($document['_source']['metadata'], true)), $document['_score'] ?? null); + return new VectorDocument($id, $vector, new Metadata(json_decode($document['_source']['metadata'], true)), $document['_score'] ?? null); } } diff --git a/src/store/src/Bridge/Typesense/Store.php b/src/store/src/Bridge/Typesense/Store.php index 16c44ca4d..09e86e47c 100644 --- a/src/store/src/Bridge/Typesense/Store.php +++ b/src/store/src/Bridge/Typesense/Store.php @@ -115,7 +115,7 @@ private function request(string $method, string $endpoint, array $payload): arra private function convertToIndexableArray(VectorDocument $document): array { return [ - 'id' => $document->id->toRfc4122(), + 'id' => $document->id, $this->vectorFieldName => $document->vector->getData(), 'metadata' => json_encode($document->metadata->getArrayCopy()), ]; @@ -136,6 +136,6 @@ private function convertToVectorDocument(array $data): VectorDocument $score = $data['vector_distance'] ?? null; - return new VectorDocument(Uuid::fromString($id), $vector, new Metadata(json_decode($document['metadata'], true)), $score); + return new VectorDocument($id, $vector, new Metadata(json_decode($document['metadata'], true)), $score); } } diff --git a/src/store/src/Bridge/Weaviate/Store.php b/src/store/src/Bridge/Weaviate/Store.php index 787a1fb80..2d52e9d99 100644 --- a/src/store/src/Bridge/Weaviate/Store.php +++ b/src/store/src/Bridge/Weaviate/Store.php @@ -116,10 +116,10 @@ private function convertToIndexableArray(VectorDocument $document): array { return [ 'class' => $this->collection, - 'id' => $document->id->toRfc4122(), + 'id' => $document->id, 'vector' => $document->vector->getData(), 'properties' => [ - 'uuid' => $document->id->toRfc4122(), + 'uuid' => $document->id, 'vector' => $document->vector->getData(), '_metadata' => json_encode($document->metadata->getArrayCopy()), ], @@ -137,6 +137,6 @@ private function convertToVectorDocument(array $data): VectorDocument ? new NullVector() : new Vector($data['vector']); - return new VectorDocument(Uuid::fromString($id), $vector, new Metadata(json_decode($data['_metadata'], true))); + return new VectorDocument($id, $vector, new Metadata(json_decode($data['_metadata'], true))); } } From e9a9c7cbbcde6585e6f50df77d0f45acdc331c61 Mon Sep 17 00:00:00 2001 From: Diego Aguiar Date: Fri, 19 Dec 2025 11:58:08 -0700 Subject: [PATCH 11/11] remove unused UUID imports --- src/store/src/Bridge/Meilisearch/Store.php | 1 - src/store/src/Bridge/Milvus/Store.php | 1 - src/store/src/Bridge/OpenSearch/Store.php | 1 - src/store/src/Bridge/Typesense/Store.php | 1 - src/store/src/Bridge/Weaviate/Store.php | 1 - 5 files changed, 5 deletions(-) diff --git a/src/store/src/Bridge/Meilisearch/Store.php b/src/store/src/Bridge/Meilisearch/Store.php index b2aeb5583..5370c77f5 100644 --- a/src/store/src/Bridge/Meilisearch/Store.php +++ b/src/store/src/Bridge/Meilisearch/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Milvus/Store.php b/src/store/src/Bridge/Milvus/Store.php index cec264d57..bf6187ba8 100644 --- a/src/store/src/Bridge/Milvus/Store.php +++ b/src/store/src/Bridge/Milvus/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/OpenSearch/Store.php b/src/store/src/Bridge/OpenSearch/Store.php index a2325fb0f..0579f01f6 100644 --- a/src/store/src/Bridge/OpenSearch/Store.php +++ b/src/store/src/Bridge/OpenSearch/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Typesense/Store.php b/src/store/src/Bridge/Typesense/Store.php index 09e86e47c..0bfb3150d 100644 --- a/src/store/src/Bridge/Typesense/Store.php +++ b/src/store/src/Bridge/Typesense/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /** diff --git a/src/store/src/Bridge/Weaviate/Store.php b/src/store/src/Bridge/Weaviate/Store.php index 2d52e9d99..8ee2daca0 100644 --- a/src/store/src/Bridge/Weaviate/Store.php +++ b/src/store/src/Bridge/Weaviate/Store.php @@ -18,7 +18,6 @@ use Symfony\AI\Store\Exception\InvalidArgumentException; use Symfony\AI\Store\ManagedStoreInterface; use Symfony\AI\Store\StoreInterface; -use Symfony\Component\Uid\Uuid; use Symfony\Contracts\HttpClient\HttpClientInterface; /**