feat(python-sdks): SDK-level cross-source memory deduplication - #1532
feat(python-sdks): SDK-level cross-source memory deduplication#1532Dhravya wants to merge 1 commit into
Conversation
Port the normalized, priority-ordered (static > dynamic > search) profile deduplication into the Python SDKs, injecting one owned memory block per request that replaces the prior block rather than accumulating. Dedup is request-local (no shared state), so it stays correct under concurrency. Covers OpenAI, Agent Framework (middleware + context provider), Cartesia, and Pipecat. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Claude finished @Dhravya's task in 1m 45s —— View job Code Review Complete
Result: No issues found. The implementation is solid and consistent across all four Python SDKs. Key points reviewed:
Score: 10/10 — Ready to ship. |
There was a problem hiding this comment.
Overview: Ports SDK-level memory deduplication to Python SDKs (OpenAI, Agent Framework, Cartesia, Pipecat), adding normalized fact comparison and request-local context replacement.
Issues found: None — this looks good to ship.
The implementation is consistent across all four Python SDKs:
-
Normalized deduplication (
normalize_fact/fact_key): Correctly strips date prefixes[YYYY-MM-DD], normalizes whitespace, and case-folds for comparison. This handles the"User likes Python"vs" user likes python "vs"[2026-08-10] USER LIKES PYTHON"variations correctly. -
Memory injection replacement: The regex pattern with
re.DOTALLand non-greedy.*?properly matches<supermemory>blocks across newlines. Thestrip_memory_injection→replace_memory_injectionflow correctly replaces prior SDK blocks while preserving caller instructions. -
Mode-aware filtering: In "query" mode, passing empty arrays for static/dynamic to
deduplicate_memoriesis intentional — search results shouldn't be deduplicated against profile data when the mode only wants search results. -
Multi-system-message handling: The injection logic correctly injects into the first system message and strips from subsequent ones, preventing accumulation.
-
Test coverage: Good coverage for normalized deduplication variants and mode-specific behavior.
Score: 10/10
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 42f308b. Configure here.
| different Agent Framework providers. | ||
| """ | ||
| messages = context.messages | ||
| memory_text = f"\n\n{wrap_memory_injection(memories)}" |
There was a problem hiding this comment.
Stale memory blocks not cleared
Medium Severity
_inject_memories now replaces owned <supermemory> blocks, but process only calls it when memories is truthy. On a later turn with an empty retrieval, prior SDK blocks stay in context.messages, so stale memory context keeps going to the model. The OpenAI path in this same PR still runs replace/strip when a system message exists even if new memories are empty.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 42f308b. Configure here.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-app | 42f308b | Commit Preview URL Branch Preview URL |
Aug 18 2026, 03:20 PM |
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
supermemory-mcp | 42f308b | Aug 18 2026, 03:19 PM |



Stack Context
Part 2 of a 3-PR stack moving memory deduplication into the SDKs. See
sdk-dedup/tools-ts(parent) for the full context and the TypeScript implementation this mirrors.What?
Port the normalized, priority-ordered (
static > dynamic > search) profile deduplication into the Python SDKs.Covers OpenAI, Agent Framework (middleware + context provider), Cartesia, and Pipecat.
Why?
Keeps the Python SDKs at behavioral parity with the TypeScript SDK so all integrations deduplicate memory the same way.
Testing
🤖 Generated with Claude Code
Note
Medium Risk
Changes memory formatting and system-prompt injection across multiple SDK integrations; incorrect dedup or replacement could alter LLM context, but there is no auth or data-store risk.
Overview
Ports normalized cross-source memory deduplication and replace-not-append injection into the Python OpenAI, Agent Framework, Cartesia, and Pipecat packages so they match the TypeScript SDK behavior.
Deduplication uses request-local keys: strip optional
[YYYY-MM-DD]prefixes, normalize whitespace, and compare withcasefold, with priority static → dynamic → search. Inquerymode, profile static/dynamic are excluded from dedup input so facts that only appear in search (or overlap profile) are not dropped before formatting.Injection no longer appends memory text every turn. OpenAI and Agent Framework middleware strip prior owned
<supermemory context="user-memories" readonly>blocks and replace them once per request while keeping the caller’s system instructions; extra system messages lose stale blocks only. New helpers (strip/replace/wrap) live in each package’s utils.Tests cover normalized fact variants, query-mode search retention, and stale block replacement.
Reviewed by Cursor Bugbot for commit 42f308b. Bugbot is set up for automated code reviews on this repo. Configure here.