Skip to content

Commit cd6f7e4

Browse files
committed
memory extraction: make speaker person resolution deterministic
Co-Authored-By: GPT-5 Codex (OpenAI)
1 parent 4a862c8 commit cd6f7e4

2 files changed

Lines changed: 38 additions & 1 deletion

File tree

src/ash/memory/processing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ async def process_extracted_facts(
444444
try:
445445
pids = await store.find_person_ids_for_username(source_username)
446446
if pids:
447-
stated_by_pid = next(iter(pids))
447+
stated_by_pid = sorted(pids)[0]
448448
except Exception:
449449
logger.debug(
450450
"stated_by_resolve_failed",

tests/test_memory.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1108,6 +1108,43 @@ async def test_non_owner_subjects_unaffected(self, graph_store: Store):
11081108
subject_pids = get_subject_person_ids(graph_store.graph, stored_ids[0])
11091109
assert bob.id in subject_pids
11101110

1111+
@pytest.mark.asyncio
1112+
async def test_speaker_lookup_is_deterministic_when_multiple_ids(
1113+
self, graph_store: Store, monkeypatch: pytest.MonkeyPatch
1114+
) -> None:
1115+
"""Speaker ID fallback should choose deterministically across set order."""
1116+
from ash.memory.processing import process_extracted_facts
1117+
from ash.store.types import ExtractedFact
1118+
1119+
async def fake_find_person_ids_for_username(_username: str) -> set[str]:
1120+
return {"pid-z", "pid-a"}
1121+
1122+
monkeypatch.setattr(
1123+
graph_store,
1124+
"find_person_ids_for_username",
1125+
fake_find_person_ids_for_username,
1126+
)
1127+
1128+
stored_ids = await process_extracted_facts(
1129+
facts=[
1130+
ExtractedFact(
1131+
content="I prefer tea",
1132+
subjects=[],
1133+
shared=False,
1134+
confidence=0.9,
1135+
speaker="dave",
1136+
)
1137+
],
1138+
store=graph_store,
1139+
user_id="user-1",
1140+
)
1141+
1142+
assert len(stored_ids) == 1
1143+
memory = graph_store.graph.memories[stored_ids[0]]
1144+
assert memory.metadata is not None
1145+
assertion = memory.metadata["assertion"]
1146+
assert assertion["speaker_person_id"] == "pid-a"
1147+
11111148

11121149
class TestDMSensitivityFloor:
11131150
"""Tests for DM sensitivity floor on ephemeral memory types."""

0 commit comments

Comments
 (0)