Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3382,3 +3382,46 @@ 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 unittest.mock import patch

from dakera.async_client import AsyncDakeraClient
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 unittest.mock import patch

from dakera.async_client import AsyncDakeraClient
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
61 changes: 61 additions & 0 deletions tests/test_memory_extended.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading