Skip to content

fix(python-sdks): stop mishandling SDK model objects in memory dedup and formatting#1268

Open
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/python-sdk-model-object-memories
Open

fix(python-sdks): stop mishandling SDK model objects in memory dedup and formatting#1268
abhay-codes07 wants to merge 1 commit into
supermemoryai:mainfrom
abhay-codes07:fix/python-sdk-model-object-memories

Conversation

@abhay-codes07

Copy link
Copy Markdown
Contributor

Fixes #1266

What

The pipecat, cartesia, and agent-framework packages all feed search results from the supermemory SDK — pydantic models with attribute access and snake_case fields — into dedup/format helpers written for plain dicts. The failure mode differs per package, but in each one the core feature is broken on its primary path:

  • pipecat: deduplicate_memories calls r.get("memory", "") on a Result model → AttributeError → caught by the generic frame handler, frame forwarded unchanged. Memories are never injected for any user whose profile lookup returns search results; it only "works" for brand-new users with empty results.
  • cartesia: identical crash, swallowed one level up — memory_context silently comes back None and the process method then strips the previous memory block from the system prompt. Persistent recall is dead for users with stored memories.
  • agent-framework: extract_memory_text handles only dict/str, so model objects fall through to return None and every search-result memory is silently dropped (no crash, just data loss).

The OpenAI package shares the same helper shape but works, because it fetches profile data over raw aiohttp and receives dicts — that asymmetry is what hid this.

Fix

  • pipecat/cartesia: a new extract_search_result_fields helper reads memory/updatedAt off dicts (camelCase keys) or SDK models (snake_case attributes, tolerant of datetime values), and both deduplicate_memories and format_memories_to_text go through it. The formatter also stops printing raw object reprs for non-dict, non-str items.
  • agent-framework: extract_memory_text gains a model-object branch (getattr(item, "memory", None)), keeping the existing trim/empty filtering.

Dict-shaped inputs behave exactly as before in all three packages.

Testing

  • Verified against the real SDK model: built supermemory.types.search_memories_response.Result from an API-shaped payload and ran it through dedup → extract → format. Before: AttributeError: 'Result' object has no attribute 'get'. After: renders - [1 Jan] User prefers async.
  • New regression tests: tests/test_search_result_objects.py in pipecat and cartesia (dedup without crashing, priority vs profile entries, no-repr formatting, dict compatibility, datetime updated_at, missing fields), plus two model-object cases in agent-framework's tests/test_utils.py.
  • Suites: pipecat 7 passed, cartesia 7 passed, agent-framework 56 passed (full suite, in a venv with agent-framework-core==1.0.0rc3 — as noted in Python SDK packages crash or silently drop memories: dedup helpers treat pydantic search results as dicts (pipecat, cartesia, agent-framework) #1266, newer releases dropped BaseContextProvider and break the package import independently of this change).

cc @MaheshtheDev

…format

The pipecat, cartesia, and agent-framework packages all pass
search results from the Supermemory SDK (pydantic models, attribute
access, snake_case fields) into dedup/format helpers written for plain
dicts. The consequences differed by package but all killed the
feature's primary path:

- pipecat: deduplicate_memories called r.get() on a Result model ->
  AttributeError -> the outer handler logs "Error processing frame"
  and forwards the frame unchanged, so memories are never injected for
  any user whose profile lookup returns search results
- cartesia: identical crash, swallowed by _enrich_event_with_memories'
  generic except -> memory_context silently comes back empty and the
  previous memory block is stripped from the system prompt
- agent-framework: extract_memory_text only handled dict/str, so model
  objects fell through to `return None` and every search-result memory
  was silently dropped from the injected context

(The OpenAI package shares the same helper shape but works because it
fetches profile data over raw aiohttp and receives dicts — that
asymmetry is what hid this.)

pipecat/cartesia gain an extract_search_result_fields helper that reads
memory/updatedAt off dicts (camelCase keys) or SDK models (snake_case
attributes, datetime-tolerant), used by both deduplicate_memories and
format_memories_to_text; the formatter also no longer prints raw object
reprs for non-dict items. agent-framework's extract_memory_text gains a
model-object branch.

Verified against the real SDK: built a
supermemory.types.search_memories_response.Result from an API-shaped
payload and ran it through dedup -> extract -> format (crashed with
AttributeError before, renders "- [1 Jan] User prefers async" after).
Test suites: pipecat 7 passed, cartesia 7 passed, agent-framework 56
passed (agent-framework-core pinned to 1.0.0rc3 — newer releases have
dropped BaseContextProvider, which breaks the package import
independently of this change).
Copilot AI review requested due to automatic review settings July 12, 2026 20:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python SDK packages crash or silently drop memories: dedup helpers treat pydantic search results as dicts (pipecat, cartesia, agent-framework)

2 participants