@@ -35,7 +35,9 @@ async def test_redis_memory_query_with_mock() -> None:
35
35
config = RedisMemoryConfig ()
36
36
memory = RedisMemory (config = config )
37
37
38
- mock_history .get_relevant .return_value = [{"content" : "test content" , "tool_call_id" : '{"foo": "bar"}' }]
38
+ mock_history .get_relevant .return_value = [
39
+ {"content" : "test content" , "tool_call_id" : '{"foo": "bar", "mime_type": "text/plain"}' }
40
+ ]
39
41
result = await memory .query ("test" )
40
42
assert len (result .results ) == 1
41
43
assert result .results [0 ].content == "test content"
@@ -304,8 +306,7 @@ async def test_basic_workflow(semantic_config: RedisMemoryConfig) -> None:
304
306
305
307
@pytest .mark .asyncio
306
308
@pytest .mark .skipif (not redis_available (), reason = "Redis instance not available locally" )
307
- async def test_content_types (semantic_memory : RedisMemory ) -> None :
308
- """Test different content types with semantic memory."""
309
+ async def test_text_memory_type (semantic_memory : RedisMemory ) -> None :
309
310
await semantic_memory .clear ()
310
311
311
312
# Test text content
@@ -317,8 +318,104 @@ async def test_content_types(semantic_memory: RedisMemory) -> None:
317
318
assert len (results .results ) > 0
318
319
assert any ("Simple text content" in str (r .content ) for r in results .results )
319
320
320
- # Test JSON content
321
- json_data = {"key" : "value" , "number" : 42 }
322
- json_content = MemoryContent (content = json_data , mime_type = MemoryMimeType .JSON )
323
- with pytest .raises (NotImplementedError ):
324
- await semantic_memory .add (json_content )
321
+
322
+ @pytest .mark .asyncio
323
+ @pytest .mark .skipif (not redis_available (), reason = "Redis instance not available locally" )
324
+ async def test_json_memory_type (semantic_memory : RedisMemory ) -> None :
325
+ await semantic_memory .clear ()
326
+
327
+ json_data = {"title" : "Hitchhiker's Guide to the Galaxy" , "The answer to life, the universe and everything." : 42 }
328
+ await semantic_memory .add (
329
+ MemoryContent (content = json_data , mime_type = MemoryMimeType .JSON , metadata = {"author" : "Douglas Adams" })
330
+ )
331
+
332
+ results = await semantic_memory .query ("what is the ultimate question of the universe?" )
333
+ assert results .results [0 ].content == json_data
334
+
335
+ # meta data should not be searched
336
+ results = await semantic_memory .query ("who is Douglas Adams?" )
337
+ assert len (results .results ) == 0
338
+
339
+ # test we can't query with JSON also
340
+ with pytest .raises (TypeError ):
341
+ results = await semantic_memory .query ({"question" : "what is the ultimate question of the universe?" }) # type: ignore[arg-type]
342
+
343
+ # but we can if the JSON is within a MemoryContent container
344
+ results = await semantic_memory .query (
345
+ MemoryContent (
346
+ content = {"question" : "what is the ultimate question of the universe?" }, mime_type = MemoryMimeType .JSON
347
+ )
348
+ )
349
+ assert results .results [0 ].content == json_data
350
+
351
+
352
+ @pytest .mark .asyncio
353
+ @pytest .mark .skipif (not redis_available (), reason = "Redis instance not available locally" )
354
+ async def test_markdown_memory_type (semantic_memory : RedisMemory ) -> None :
355
+ await semantic_memory .clear ()
356
+
357
+ markdown_data = """
358
+ This is an H1 header
359
+ ============
360
+
361
+ Paragraphs are separated by a blank line.
362
+
363
+ *Italics are within asteriks*, **bold text is within two asterisks**,
364
+ while `monospace is within back tics`.
365
+
366
+ Itemized lists are made with indented asterisks:
367
+
368
+ * this one
369
+ * that one
370
+ * the next one
371
+
372
+ > Block quotes are make with arrows
373
+ > like this.
374
+ >
375
+ > They can span multiple paragraphs,
376
+ > if you like.
377
+
378
+ Unicode is supported. ☺
379
+ """
380
+
381
+ await semantic_memory .add (
382
+ MemoryContent (content = markdown_data , mime_type = MemoryMimeType .MARKDOWN , metadata = {"type" : "markdown example" })
383
+ )
384
+
385
+ results = await semantic_memory .query ("how can I make itemized lists, or italicize text with asterisks?" )
386
+ assert results .results [0 ].content == markdown_data
387
+
388
+ # test we can query with markdown interpreted as a text string also
389
+ results = await semantic_memory .query ("" )
390
+
391
+ # we can also if the markdown is within a MemoryContent container
392
+ results = await semantic_memory .query (
393
+ MemoryContent (
394
+ content = "**bold text is within 2 asterisks**, and *italics are within 1 asterisk*" ,
395
+ mime_type = MemoryMimeType .MARKDOWN ,
396
+ )
397
+ )
398
+ assert results .results [0 ].content == markdown_data
399
+
400
+
401
+ @pytest .mark .asyncio
402
+ @pytest .mark .skipif (not redis_available (), reason = "Redis instance not available locally" )
403
+ async def test_query_arguments (semantic_memory : RedisMemory ) -> None :
404
+ # test that we can utilize the optional query arguments top_k and distance_threshold
405
+ await semantic_memory .clear ()
406
+
407
+ await semantic_memory .add (MemoryContent (content = "my favorite fruit are apples" , mime_type = MemoryMimeType .TEXT ))
408
+ await semantic_memory .add (MemoryContent (content = "I also like cherries" , mime_type = MemoryMimeType .TEXT ))
409
+ await semantic_memory .add (MemoryContent (content = "I like plums as well" , mime_type = MemoryMimeType .TEXT ))
410
+
411
+ # default search
412
+ results = await semantic_memory .query ("what fruits do I like?" )
413
+ assert len (results .results ) == 3
414
+
415
+ # limit search to 2 results
416
+ results = await semantic_memory .query ("what fruits do I like?" , top_k = 2 )
417
+ assert len (results .results ) == 2
418
+
419
+ # limit search to only close matches
420
+ results = await semantic_memory .query ("my favorite fruit are what?" , distance_threshold = 0.2 )
421
+ assert len (results .results ) == 1
0 commit comments