feat: harden memory summary — fingerprint dedup, versioning, prompt injection defense
Summary hardening: - SHA256 fingerprint of events content for deduplication (skips LLM call when events unchanged since last summary) - Versioned summary storage: summary:agent:channel:vN keys - Latest pointer: summary_latest:agent:channel for fast retrieval - Prompt injection defense: sanitize event content before LLM, strip [SYSTEM]/[INTERNAL] markers, block "ignore instructions" patterns - Anti-injection clause in SUMMARY_SYSTEM_PROMPT Database fix: - list_facts_by_agent: SQL filter by fact_prefix to only return chat_events (prevents summary/version facts from consuming LIMIT quota) - Fixed NULL team_id issue in UNIQUE constraint (PostgreSQL NULL != NULL) using "__system__" sentinel for team_id in summary operations Tested on NODE1: dedup works (same events → skipped), force=true bypasses. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -521,14 +521,16 @@ class Database:
|
||||
self,
|
||||
agent_id: str,
|
||||
channel_id: str = None,
|
||||
limit: int = 60
|
||||
limit: int = 60,
|
||||
fact_prefix: str = "chat_event:"
|
||||
) -> list:
|
||||
"""List facts for an agent (any user), ordered by most recent."""
|
||||
"""List facts for an agent (any user), ordered by most recent.
|
||||
Only returns facts matching fact_prefix (default: chat_event:)."""
|
||||
async with self.pool.acquire() as conn:
|
||||
query = "SELECT * FROM user_facts WHERE agent_id = $1"
|
||||
params = [agent_id]
|
||||
query = "SELECT * FROM user_facts WHERE agent_id = $1 AND fact_key LIKE $2 || '%'"
|
||||
params = [agent_id, fact_prefix]
|
||||
if channel_id:
|
||||
query += " AND fact_key LIKE '%' || $2 || '%'"
|
||||
query += " AND fact_key LIKE '%' || $3 || '%'"
|
||||
params.append(channel_id)
|
||||
query += " ORDER BY updated_at DESC"
|
||||
query += f" LIMIT ${len(params) + 1}"
|
||||
|
||||
Reference in New Issue
Block a user