diff --git a/circuitforge_core/vector/base.py b/circuitforge_core/vector/base.py index d1c6f9b..737beaa 100644 --- a/circuitforge_core/vector/base.py +++ b/circuitforge_core/vector/base.py @@ -8,21 +8,16 @@ from __future__ import annotations from abc import ABC, abstractmethod from dataclasses import dataclass, field -from types import MappingProxyType -from typing import Any, Mapping +from typing import Any @dataclass(frozen=True) class VectorMatch: """A single result from a vector similarity search.""" - entry_id: str + id: str score: float # lower is better (L2 / cosine distance) - metadata: Mapping[str, Any] = field(default_factory=dict) - - def __post_init__(self) -> None: - if isinstance(self.metadata, dict): - object.__setattr__(self, "metadata", MappingProxyType(self.metadata)) + metadata: dict[str, Any] = field(default_factory=dict) class VectorStore(ABC): diff --git a/tests/test_vector/test_base.py b/tests/test_vector/test_base.py index dfd89df..077eef4 100644 --- a/tests/test_vector/test_base.py +++ b/tests/test_vector/test_base.py @@ -3,7 +3,6 @@ from __future__ import annotations from dataclasses import FrozenInstanceError -from types import MappingProxyType import pytest @@ -26,7 +25,7 @@ class _ConcreteStore(VectorStore): filter_metadata: dict | None = None, ) -> list[VectorMatch]: results = [ - VectorMatch(entry_id=k, score=0.0, metadata=v[1]) + VectorMatch(id=k, score=0.0, metadata=v[1]) for k, v in self._data.items() ] if filter_metadata: @@ -52,16 +51,15 @@ class _ConcreteStore(VectorStore): def test_vector_match_is_frozen(): - match = VectorMatch(entry_id="a", score=0.1, metadata={}) + match = VectorMatch(id="a", score=0.1, metadata={}) with pytest.raises(FrozenInstanceError): match.score = 0.5 # type: ignore[misc] -def test_vector_match_metadata_is_not_mutable(): - match = VectorMatch(entry_id="a", score=0.1, metadata={"k": "v"}) - assert isinstance(match.metadata, MappingProxyType) - with pytest.raises(TypeError): - match.metadata["k"] = "changed" # type: ignore[index] +def test_vector_match_metadata_is_dict(): + match = VectorMatch(id="a", score=0.1, metadata={"k": "v"}) + assert isinstance(match.metadata, dict) + assert match.metadata["k"] == "v" def test_upsert_and_query(): @@ -69,7 +67,7 @@ def test_upsert_and_query(): store.upsert("chunk-1", [0.1, 0.2], {"doc_id": "book-a", "page": 1}) results = store.query([0.1, 0.2]) assert len(results) == 1 - assert results[0].entry_id == "chunk-1" + assert results[0].id == "chunk-1" assert results[0].metadata["page"] == 1 @@ -79,7 +77,7 @@ def test_query_filter_metadata(): store.upsert("c2", [0.2], {"doc_id": "book-b"}) results = store.query([0.1], filter_metadata={"doc_id": "book-a"}) assert len(results) == 1 - assert results[0].entry_id == "c1" + assert results[0].id == "c1" def test_delete():