Skip to content

Commit 8a9af86

Browse files
authored
feat: use datetime ranges for archival memory query (#4398)
1 parent 25d37e2 commit 8a9af86

File tree

4 files changed

+54
-8
lines changed

4 files changed

+54
-8
lines changed

letta/server/rest_api/routers/v1/agents.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -993,8 +993,8 @@ async def search_archival_memory(
993993
"any", description="How to match tags - 'any' to match passages with any of the tags, 'all' to match only passages with all tags"
994994
),
995995
top_k: Optional[int] = Query(None, description="Maximum number of results to return. Uses system default if not specified"),
996-
start_datetime: Optional[str] = Query(None, description="Filter results to passages created after this datetime. ISO 8601 format"),
997-
end_datetime: Optional[str] = Query(None, description="Filter results to passages created before this datetime. ISO 8601 format"),
996+
start_datetime: Optional[datetime] = Query(None, description="Filter results to passages created after this datetime"),
997+
end_datetime: Optional[datetime] = Query(None, description="Filter results to passages created before this datetime"),
998998
server: "SyncServer" = Depends(get_letta_server),
999999
actor_id: str | None = Header(None, alias="user_id"),
10001000
):
@@ -1008,6 +1008,10 @@ async def search_archival_memory(
10081008
actor = await server.user_manager.get_actor_or_default_async(actor_id=actor_id)
10091009

10101010
try:
1011+
# convert datetime to string in ISO 8601 format
1012+
start_datetime = start_datetime.isoformat() if start_datetime else None
1013+
end_datetime = end_datetime.isoformat() if end_datetime else None
1014+
10111015
# Use the shared agent manager method
10121016
formatted_results, count = await server.agent_manager.search_agent_archival_memory_async(
10131017
agent_id=agent_id,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ dependencies = [
4545
"llama-index>=0.12.2",
4646
"llama-index-embeddings-openai>=0.3.1",
4747
"anthropic>=0.49.0",
48-
"letta_client>=0.1.301",
48+
"letta-client==0.1.307",
4949
"openai>=1.99.9",
5050
"opentelemetry-api==1.30.0",
5151
"opentelemetry-sdk==1.30.0",

tests/test_sdk_client.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,48 @@ def test_insert_archival_memory(client: LettaSDKClient, agent: AgentState):
558558
assert "This is a test passage" not in passage_texts, f"Memory was not deleted: {passage_texts}"
559559

560560

561+
def test_search_archival_memory(client: LettaSDKClient, agent: AgentState):
562+
from datetime import datetime, timezone
563+
564+
client.agents.passages.create(
565+
agent_id=agent.id,
566+
text="This is a test passage",
567+
)
568+
client.agents.passages.create(
569+
agent_id=agent.id,
570+
text="This is another test passage",
571+
)
572+
client.agents.passages.create(agent_id=agent.id, text="cats")
573+
# insert old passage: 09/03/2001
574+
old_passage = "OLD PASSAGE"
575+
client.agents.passages.create(
576+
agent_id=agent.id,
577+
text=old_passage,
578+
created_at=datetime(2001, 9, 3, 0, 0, 0, 0, timezone.utc),
579+
)
580+
581+
# test seaching for old passage
582+
search_results = client.agents.passages.search(agent_id=agent.id, query="cats", top_k=1)
583+
assert len(search_results.results) == 1
584+
assert search_results.results[0].content == "cats"
585+
586+
# test seaching for old passage
587+
search_results = client.agents.passages.search(agent_id=agent.id, query="cats", top_k=4)
588+
assert len(search_results.results) == 4
589+
assert search_results.results[0].content == "cats"
590+
591+
# search for old passage
592+
search_results = client.agents.passages.search(
593+
agent_id=agent.id,
594+
query="cats",
595+
top_k=4,
596+
start_datetime=datetime(2001, 8, 3, 0, 0, 0, 0, timezone.utc),
597+
end_datetime=datetime(2001, 10, 3, 0, 0, 0, 0, timezone.utc),
598+
)
599+
assert len(search_results.results) == 1
600+
assert search_results.results[0].content == old_passage
601+
602+
561603
def test_function_return_limit(disable_e2b_api_key, client: LettaSDKClient, agent: AgentState):
562604
"""Test to see if the function return limit works"""
563605

uv.lock

Lines changed: 5 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)