"""Routing key normalization for consistent memory addressing.
LLM-generated routing keys are inconsistent across sessions.
This module normalizes them using a synonym table and simple heuristics
to prevent memory fragmentation (e.g., "coffee" vs "beverage" → same node).
"""
_SYNONYM_GROUPS: list[list[str]] = [
["beverage", "coffee", "tea", "drink"],
["commute", "transport", "transportation", "travel_to_work"],
["note_taking", "notes", "note_tool"],
["coding_style", "code_style", "programming_style", "coding_preference"],
["music", "music_taste", "music_preference"],
["food", "food_preference", "diet", "eating"],
["exercise", "workout", "fitness", "gym"],
["reading", "books", "reading_preference"],
["sleep", "sleep_habit", "sleep_schedule"],
["weather", "weather_preference"],
["pets", "pet", "animals"],
]
_SYNONYM_MAP: dict[str, str] = {}
for group in _SYNONYM_GROUPS:
canonical = group[0]
for synonym in group:
_SYNONYM_MAP[synonym] = canonical
def normalize_routing_key(raw_key: str, category: str) -> str:
"""Normalize a routing key for consistent addressing.
Steps:
1. Lowercase + strip whitespace
2. Replace spaces/hyphens with underscores
3. Lookup synonym table
4. Return normalized key
Args:
raw_key: LLM-generated routing key
category: Candidate category (preference, entity, pattern, etc.)
Returns:
Normalized routing key
"""
if not raw_key:
return category
key = raw_key.lower().strip().replace(" ", "_").replace("-", "_")
while "__" in key:
key = key.replace("__", "_")
if key in _SYNONYM_MAP:
return _SYNONYM_MAP[key]
return key