Repository: griptape-ai/griptape

Issue:
Query not returning namespace
When upserting a text artifact to a vector store, it doesn't look like it's storing (or querying?) the namespace correctly..

```python
from griptape.drivers import LocalVectorStoreDriver, OpenAiEmbeddingDriver
from griptape.artifacts import TextArtifact
from rich import print

vector_store_driver = LocalVectorStoreDriver(embedding_driver=OpenAiEmbeddingDriver())

artifact = TextArtifact("error: maya sucks in all the ways a DCC can.")
namespace = "renderlog"
vector_store_driver.upsert_text_artifact(artifact=artifact, namespace=namespace)

result = vector_store_driver.query("error", namespace=namespace)
print(result)
```

```bash
[
    Entry(
        id='dc95fd41-97dc-51cd-93ba-df8527d9e6c9',
        vector=[],
        score=np.float64(0.29184468115467144),
        meta={'artifact': '{"type": "TextArtifact", "id": "6b72d107a0e74215b35bcfff36886a70", "reference": null, "meta": {}, "name": "6b72d107a0e74215b35bcfff36886a70", "value": "error: maya sucks in all the ways a DCC can."}'},
        namespace=None
    )
]
```

Notice namespace=None

Discussion:

Solution patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4932f29f..6f11af48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Occasional crash during `FuturesExecutorMixin` cleanup.
 - `BaseChunker` chunking more than necessary.
 - `BaseLoader.reference` not being set when using `BaseLoader.parse` directly.
+- `LocalVectorStoreDriver` returned Entries not containing the namespace.
 
 ### Deprecated
 
diff --git a/griptape/drivers/vector/local_vector_store_driver.py b/griptape/drivers/vector/local_vector_store_driver.py
index 5cb0750f..139a4dd2 100644
--- a/griptape/drivers/vector/local_vector_store_driver.py
+++ b/griptape/drivers/vector/local_vector_store_driver.py
@@ -99,7 +99,9 @@ class LocalVectorStoreDriver(BaseVectorStoreDriver):
         entries_and_relatednesses.sort(key=operator.itemgetter(1), reverse=True)
 
         result = [
-            BaseVectorStoreDriver.Entry(id=er[0].id, vector=er[0].vector, score=er[1], meta=er[0].meta)
+            BaseVectorStoreDriver.Entry(
+                id=er[0].id, vector=er[0].vector, score=er[1], meta=er[0].meta, namespace=er[0].namespace
+            )
             for er in entries_and_relatednesses
         ][:count]
 


Test patch:
diff --git a/tests/unit/drivers/vector/test_local_vector_store_driver.py b/tests/unit/drivers/vector/test_local_vector_store_driver.py
index 9722bb25..df947b15 100644
--- a/tests/unit/drivers/vector/test_local_vector_store_driver.py
+++ b/tests/unit/drivers/vector/test_local_vector_store_driver.py
@@ -35,3 +35,15 @@ class TestLocalVectorStoreDriver(TestBaseVectorStoreDriver):
         assert len(driver.query("foo", namespace="test1")) == 1000
         assert len(driver.query("foo", namespace="test2")) == 1000
         assert len(driver.query("foo", namespace="test3")) == 1000
+
+    def test_query_vector(self, driver):
+        driver.upsert_text_artifacts({"foo": [TextArtifact("foo bar")]})
+
+        result = driver.query_vector([1.0, 1.0], count=1, include_vectors=True)
+
+        assert len(result) == 1
+        assert result[0].to_artifact().value == "foo bar"
+        assert result[0].id is not None
+        assert result[0].vector == [0, 1]
+        assert result[0].score is not None
+        assert result[0].namespace == "foo"