aboutsummaryrefslogtreecommitdiff
path: root/packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py')
-rw-r--r--packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py90
1 files changed, 79 insertions, 11 deletions
diff --git a/packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py b/packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py
index d0f0e461..a27da256 100644
--- a/packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py
+++ b/packages/pipecat-sdk-python/src/supermemory_pipecat/utils.py
@@ -1,6 +1,7 @@
"""Utility functions for Supermemory Pipecat integration."""
-from typing import Dict, List
+from datetime import datetime, timezone
+from typing import Any, Dict, List, Union
def get_last_user_message(messages: List[Dict[str, str]]) -> str | None:
@@ -11,15 +12,58 @@ def get_last_user_message(messages: List[Dict[str, str]]) -> str | None:
return None
+def format_relative_time(iso_timestamp: str) -> str:
+ """Convert ISO timestamp to relative time string.
+
+ Format rules:
+ - [just now] - within 30 minutes
+ - [Xmins ago] - 30-60 minutes
+ - [X hrs ago] - less than 1 day
+ - [Xd ago] - less than 1 week
+ - [X Jul] - more than 1 week, same year
+ - [X Jul, 2023] - different year
+ """
+ try:
+ dt = datetime.fromisoformat(iso_timestamp.replace("Z", "+00:00"))
+ now = datetime.now(timezone.utc)
+ diff = now - dt
+
+ seconds = diff.total_seconds()
+ minutes = seconds / 60
+ hours = seconds / 3600
+ days = seconds / 86400
+
+ if minutes < 30:
+ return "just now"
+ elif minutes < 60:
+ return f"{int(minutes)}mins ago"
+ elif hours < 24:
+ return f"{int(hours)} hrs ago"
+ elif days < 7:
+ return f"{int(days)}d ago"
+ elif dt.year == now.year:
+ return f"{dt.day} {dt.strftime('%b')}"
+ else:
+ return f"{dt.day} {dt.strftime('%b')}, {dt.year}"
+ except Exception:
+ return ""
+
+
def deduplicate_memories(
static: List[str],
dynamic: List[str],
- search_results: List[str],
-) -> Dict[str, List[str]]:
- """Deduplicate memories. Priority: static > dynamic > search."""
+ search_results: List[Dict[str, Any]],
+) -> Dict[str, Union[List[str], List[Dict[str, Any]]]]:
+ """Deduplicate memories. Priority: static > dynamic > search.
+
+ Args:
+ static: List of static memory strings.
+ dynamic: List of dynamic memory strings.
+ search_results: List of search result dicts with 'memory' and 'updatedAt'.
+ """
seen = set()
- def unique(memories):
+ def unique_strings(memories: List[str]) -> List[str]:
out = []
for m in memories:
if m not in seen:
@@ -27,21 +71,33 @@ def deduplicate_memories(
out.append(m)
return out
+ def unique_search(results: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
+ out = []
+ for r in results:
+ memory = r.get("memory", "")
+ if memory and memory not in seen:
+ seen.add(memory)
+ out.append(r)
+ return out
+
return {
- "static": unique(static),
- "dynamic": unique(dynamic),
- "search_results": unique(search_results),
+ "static": unique_strings(static),
+ "dynamic": unique_strings(dynamic),
+ "search_results": unique_search(search_results),
}
def format_memories_to_text(
- memories: Dict[str, List[str]],
+ memories: Dict[str, Union[List[str], List[Dict[str, Any]]]],
system_prompt: str = "Based on previous conversations, I recall:\n\n",
include_static: bool = True,
include_dynamic: bool = True,
include_search: bool = True,
) -> str:
- """Format deduplicated memories into a text string for injection."""
+ """Format deduplicated memories into a text string for injection.
+
+ Search results include temporal context (e.g., '3d ago') from updatedAt.
+ """
sections = []
static = memories["static"]
@@ -58,7 +114,19 @@ def format_memories_to_text(
if include_search and search_results:
sections.append("## Relevant Memories")
- sections.append("\n".join(f"- {item}" for item in search_results))
+ lines = []
+ for item in search_results:
+ if isinstance(item, dict):
+ memory = item.get("memory", "")
+ updated_at = item.get("updatedAt", "")
+ time_str = format_relative_time(updated_at) if updated_at else ""
+ if time_str:
+ lines.append(f"- [{time_str}] {memory}")
+ else:
+ lines.append(f"- {memory}")
+ else:
+ lines.append(f"- {item}")
+ sections.append("\n".join(lines))
if not sections:
return ""