Skip to content

fix: crash when profile search returns hits (Cartesia + Pipecat) - #1615

Open
noQbot wants to merge 1 commit into
supermemoryai:mainfrom
VinvAI:fix-search-result-crash
Open

fix: crash when profile search returns hits (Cartesia + Pipecat)#1615
noQbot wants to merge 1 commit into
supermemoryai:mainfrom
VinvAI:fix-search-result-crash

Conversation

@noQbot

@noQbot noQbot commented Aug 29, 2026

Copy link
Copy Markdown

What & why

deduplicate_memories() in both the Cartesia and Pipecat integrations calls r.get("memory") on each search result:

def unique_search(results):
    for r in results:
        memory = r.get("memory", "")   # AttributeError on SDK models

But the callers pass response.search_results.results straight from the SDK (agent.py / service.py), and the Supermemory SDK returns those as Pydantic model objects, not dicts. Models have no .get(), so any non-empty profile search raises AttributeError — on the default mode="full" path. An empty search skips the loop, which is why it only crashes once memories actually exist.

This isn't hypothetical for the SDK shape: the sibling openai-sdk-python package already does results=[r.model_dump() for r in response.results] — you only call .model_dump() on models — so the model shape is established repo behavior. The Cartesia/Pipecat packages just skipped that conversion.

Why existing tests didn't catch it: the current fixtures pass dicts ({"memory": "..."}), so they exercise a shape production never sends.

The fix

Normalize each result to a dict via model_dump(by_alias=True) before reading it (keeping API field names like updatedAt so the temporal context still renders), and pass real dicts through unchanged:

def _result_to_dict(result):
    if isinstance(result, dict):
        return result
    model_dump = getattr(result, "model_dump", None)
    if callable(model_dump):
        return model_dump(by_alias=True)
    return {}

Applied identically to packages/cartesia-sdk-python and packages/pipecat-sdk-python.

Tests

Added tests/test_search_result_models.py to both packages, feeding dict-less model stand-ins through the dedup + formatting path (asserts no crash, correct dedup, updatedAt renders, and that dict inputs still work).

Note: the repo's PR CI runs only TypeScript type-checks + Biome, not the Python suites, so these tests won't run in CI here — I verified them locally.

Compatibility

Backward compatible — dict inputs behave exactly as before. No API or behavior change for callers already passing dicts.

deduplicate_memories() called `r.get("memory")` on each search result, but
the Supermemory SDK returns `response.search_results.results` as Pydantic
model objects, not dicts. Models have no `.get()`, so every non-empty search
raised AttributeError on the default mode="full" path; empty search skipped
the loop and hid the bug. Existing tests only passed dict fixtures, so they
stayed green.

Normalize each result to a dict via model_dump(by_alias=True) before reading
it (mirroring the openai-sdk-python package, which already model_dump()s the
same results), and pass real dicts through unchanged. Add regression tests
that feed dict-less model stand-ins through the dedup + formatting path.

Co-Authored-By: Vinv-AI <309466812+Vinv-AI@users.noreply.github.com>
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.

1 participant