From 2162c8c2829548095d152fb1e8eb8de9fdb2b78d Mon Sep 17 00:00:00 2001 From: Dakera Ops Date: Wed, 29 Jul 2026 10:48:25 +0000 Subject: [PATCH 1/2] test(client): add valid_from regression tests for store_memory (DAK-7424) Adds 5 unit tests (3 sync + 2 async) verifying that store_memory() correctly forwards the valid_from bi-temporal timestamp when set and omits it when absent. These cover the field added in PR#186 which merged without dedicated test coverage. - TestStoreMemoryValidFrom (3 sync tests via responses mock) - TestAsyncClientStoreMemoryValidFrom (2 async tests via _request patch) Co-Authored-By: Paperclip --- tests/test_client.py | 41 +++++++++++++++++++++++ tests/test_memory_extended.py | 61 +++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) diff --git a/tests/test_client.py b/tests/test_client.py index 6119b42..4038322 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -3382,3 +3382,44 @@ def test_query_text_deserializes_modernbert_model_in_response(self, client, mock ) result = client.query_text("test-ns", "hello", top_k=1) assert result.model == EmbeddingModel.MODERNBERT_EMBED_BASE + + +# =========================================================================== +# AsyncDakeraClient.store_memory() valid_from parity (DAK-7424) — v0.11.102+ +# =========================================================================== + + +class TestAsyncClientStoreMemoryValidFrom: + """AsyncDakeraClient.store_memory() forwards valid_from for bi-temporal recall (DAK-7424).""" + + async def test_store_memory_with_valid_from_includes_field(self): + """store_memory() sends valid_from in request body when set.""" + from dakera.async_client import AsyncDakeraClient + from unittest.mock import patch + client = AsyncDakeraClient("http://localhost:3000") + captured: dict = {} + + async def fake_request(method, path, data=None, **kwargs): + captured.update(data or {}) + return {"id": "mem_vf1", "content": "past event"} + + with patch.object(client, "_request", side_effect=fake_request): + await client.store_memory("agent-1", "past event", valid_from=1700000000) + + assert captured.get("valid_from") == 1700000000 + + async def test_store_memory_without_valid_from_omits_field(self): + """store_memory() does not include valid_from when caller omits it.""" + from dakera.async_client import AsyncDakeraClient + from unittest.mock import patch + client = AsyncDakeraClient("http://localhost:3000") + captured: dict = {} + + async def fake_request(method, path, data=None, **kwargs): + captured.update(data or {}) + return {"id": "mem_vf2", "content": "now"} + + with patch.object(client, "_request", side_effect=fake_request): + await client.store_memory("agent-1", "now") + + assert "valid_from" not in captured diff --git a/tests/test_memory_extended.py b/tests/test_memory_extended.py index c271d0a..62c0f33 100644 --- a/tests/test_memory_extended.py +++ b/tests/test_memory_extended.py @@ -1257,3 +1257,64 @@ def test_warm_cache(self, client, mock_responses): ) assert result.entries_warmed == 100 assert result.entries_skipped == 50 + + +# =========================================================================== +# valid_from bi-temporal field (DAK-7424) — v0.11.102+ +# =========================================================================== + + +class TestStoreMemoryValidFrom: + """Tests for the valid_from bi-temporal parameter on store_memory (DAK-7424). + + Server v0.11.98 began persisting valid_from so callers can express when a + memory becomes temporally valid, independent of ingest time. + """ + + def test_store_memory_with_valid_from_includes_field(self, client, mock_responses): + """store_memory() forwards valid_from in the request body when set.""" + mock_responses.add( + responses.POST, + "http://localhost:3000/v1/memory/store", + json={"memory": {"id": "mem-vf1", "content": "past event", "memory_type": "episodic"}}, + status=200, + ) + ts = 1700000000 # 2023-11-14 Unix timestamp + client.store_memory("agent-1", "past event", valid_from=ts) + req_body = json.loads(mock_responses.calls[0].request.body) + assert req_body.get("valid_from") == ts + + def test_store_memory_without_valid_from_omits_field(self, client, mock_responses): + """store_memory() does not include valid_from when the caller omits it.""" + mock_responses.add( + responses.POST, + "http://localhost:3000/v1/memory/store", + json={"memory": {"id": "mem-vf2", "content": "now", "memory_type": "episodic"}}, + status=200, + ) + client.store_memory("agent-1", "now") + req_body = json.loads(mock_responses.calls[0].request.body) + assert "valid_from" not in req_body + + def test_store_memory_valid_from_combined_with_other_fields(self, client, mock_responses): + """valid_from can be combined with other optional fields (tags, session_id, ttl_seconds).""" + mock_responses.add( + responses.POST, + "http://localhost:3000/v1/memory/store", + json={"memory": {"id": "mem-vf3", "content": "event", "memory_type": "episodic"}}, + status=200, + ) + ts = 1700000000 + client.store_memory( + "agent-1", + "event", + valid_from=ts, + tags=["history"], + session_id="sess-1", + ttl_seconds=86400, + ) + req_body = json.loads(mock_responses.calls[0].request.body) + assert req_body.get("valid_from") == ts + assert req_body.get("tags") == ["history"] + assert req_body.get("session_id") == "sess-1" + assert req_body.get("ttl_seconds") == 86400 From 2f849c76ade6520faa6a33f34271d9cc8e9e3840 Mon Sep 17 00:00:00 2001 From: Platform Bot Date: Wed, 29 Jul 2026 16:53:26 +0000 Subject: [PATCH 2/2] fix(tests): sort async valid_from test imports to satisfy ruff I001 (DAK-7625) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit stdlib `unittest.mock` must precede first-party `dakera.async_client` imports inside the two async test methods — ruff I001 enforces this order. Co-Authored-By: Claude Sonnet 4.6 --- tests/test_client.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_client.py b/tests/test_client.py index 4038322..a0d6129 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -3394,8 +3394,9 @@ class TestAsyncClientStoreMemoryValidFrom: async def test_store_memory_with_valid_from_includes_field(self): """store_memory() sends valid_from in request body when set.""" - from dakera.async_client import AsyncDakeraClient from unittest.mock import patch + + from dakera.async_client import AsyncDakeraClient client = AsyncDakeraClient("http://localhost:3000") captured: dict = {} @@ -3410,8 +3411,9 @@ async def fake_request(method, path, data=None, **kwargs): async def test_store_memory_without_valid_from_omits_field(self): """store_memory() does not include valid_from when caller omits it.""" - from dakera.async_client import AsyncDakeraClient from unittest.mock import patch + + from dakera.async_client import AsyncDakeraClient client = AsyncDakeraClient("http://localhost:3000") captured: dict = {}