personal memory agent
0

Configure Feed

Select the types of activity you want to include in your feed.

solstone / tests / test_activity_record_merge.py
4.2 kB 133 lines
1# SPDX-License-Identifier: AGPL-3.0-only 2# Copyright (c) 2026 sol pbc 3 4import json 5 6 7def _write_detected_entities(tmp_path, facet: str, day: str, rows: list[dict]) -> None: 8 entities_path = tmp_path / "facets" / facet / "entities" / f"{day}.jsonl" 9 entities_path.parent.mkdir(parents=True, exist_ok=True) 10 entities_path.write_text( 11 "".join(json.dumps(row, ensure_ascii=False) + "\n" for row in rows), 12 encoding="utf-8", 13 ) 14 15 16def _activity_record(): 17 return { 18 "id": "meeting_090000_300", 19 "activity": "meeting", 20 "segments": ["090000_300"], 21 "level_avg": 1.0, 22 "description": "Team sync", 23 "active_entities": ["JB", "Alex"], 24 "created_at": 1, 25 } 26 27 28def test_participation_post_hook_merges_fields_and_preserves_active_entities( 29 tmp_path, monkeypatch 30): 31 from solstone.talent.participation import post_process 32 from solstone.think.activities import append_activity_record, load_activity_records 33 34 facet = "work" 35 day = "20260418" 36 monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 37 38 _write_detected_entities( 39 tmp_path, 40 facet, 41 day, 42 [ 43 { 44 "id": "john_borthwick", 45 "type": "Person", 46 "name": "John Borthwick", 47 "aka": ["JB"], 48 } 49 ], 50 ) 51 append_activity_record(facet, day, _activity_record()) 52 53 post_process( 54 json.dumps( 55 { 56 "participation": [ 57 { 58 "name": "JB", 59 "role": "attendee", 60 "source": "voice", 61 "confidence": 0.91, 62 "context": "Spoke during the meeting", 63 "entity_id": None, 64 }, 65 { 66 "name": "Alex", 67 "role": "mentioned", 68 "source": "transcript", 69 "confidence": 0.42, 70 "context": "Mentioned as a collaborator", 71 "entity_id": None, 72 }, 73 ], 74 "participation_confidence": 0.77, 75 } 76 ), 77 {"facet": facet, "day": day, "activity": {"id": "meeting_090000_300"}}, 78 ) 79 80 record = load_activity_records(facet, day)[0] 81 assert record["active_entities"] == ["JB", "Alex"] 82 assert record["participation_confidence"] == 0.77 83 assert record["participation"][0]["entity_id"] == "john_borthwick" 84 assert record["participation"][1]["entity_id"] is None 85 assert record["title"] == "Team sync" 86 assert record["details"] == "" 87 assert record["hidden"] is False 88 89 90def test_participation_post_hook_leaves_file_unchanged_on_malformed_json( 91 tmp_path, monkeypatch, caplog 92): 93 from solstone.talent.participation import post_process 94 from solstone.think.activities import append_activity_record 95 96 facet = "work" 97 day = "20260418" 98 monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 99 100 append_activity_record(facet, day, _activity_record()) 101 record_path = tmp_path / "facets" / facet / "activities" / f"{day}.jsonl" 102 before = record_path.read_bytes() 103 104 post_process( 105 "{not valid json", 106 {"facet": facet, "day": day, "activity": {"id": "meeting_090000_300"}}, 107 ) 108 109 assert record_path.read_bytes() == before 110 assert "failed to parse JSON" in caplog.text 111 112 113def test_participation_post_hook_requires_activity_context( 114 tmp_path, monkeypatch, caplog 115): 116 from solstone.talent.participation import post_process 117 from solstone.think.activities import append_activity_record 118 119 facet = "work" 120 day = "20260418" 121 monkeypatch.setenv("SOLSTONE_JOURNAL", str(tmp_path)) 122 123 append_activity_record(facet, day, _activity_record()) 124 record_path = tmp_path / "facets" / facet / "activities" / f"{day}.jsonl" 125 before = record_path.read_bytes() 126 127 post_process( 128 json.dumps({"participation": []}), 129 {"facet": facet, "day": day}, 130 ) 131 132 assert record_path.read_bytes() == before 133 assert "missing activity context" in caplog.text