Skip to content

fix(openai-sdk-python): isolate middleware clients - #1503

Open
abhinav7x94 wants to merge 4 commits into
supermemoryai:mainfrom
abhinav7x94:fix/python-isolate-openai-wrappers
Open

fix(openai-sdk-python): isolate middleware clients#1503
abhinav7x94 wants to merge 4 commits into
supermemoryai:mainfrom
abhinav7x94:fix/python-isolate-openai-wrappers

Conversation

@abhinav7x94

@abhinav7x94 abhinav7x94 commented Aug 16, 2026

Copy link
Copy Markdown

Summary

  • stop with_supermemory from mutating the supplied OpenAI client
  • create tenant-isolated chat/completions facades, including every raw and streaming response prefix
  • recover the pristine base client when a middleware facade is wrapped again
  • correctly route decorated AsyncOpenAI methods through async memory lookup and persistence
  • preserve the SDK's async streaming context-manager protocol while applying memory work on entry
  • add sync/async regressions for shared-client tenant isolation, conversation persistence, and response variants

Why

with_supermemory replaced client.chat.completions.create in place. Reusing one OpenAI client with different middleware options stacked the wrappers, so one request could retrieve and inject memories from multiple tenants and persist a conversation through multiple tenant configurations.

The wrapper now delegates unchanged SDK resources to the pristine client while overriding only memory-aware completion entry points. The caller's base client remains untouched.

OpenAI's decorated async create methods are not always reported as coroutine functions, and streaming variants intentionally return async context managers synchronously. The follow-up classifies the canonical client correctly and defers async middleware until streaming context entry, preventing skipped writes and unawaited-coroutine warnings.

Validation

  • tenant isolation and persistence regressions pass
  • real AsyncOpenAI 7-path matrix passes on OpenAI 1.102.0 and 3.1.0: normal, three raw-response prefixes, and three streaming-response prefixes
  • every path performs one lookup, one write, one request, one injection, and emits zero RuntimeWarnings
  • streaming body exceptions propagate and underlying responses close correctly
  • real sync normal/raw/streaming paths remain unchanged on both SDK versions
  • full Python SDK suite passes on both SDK versions
  • Black, isort, mypy baseline comparison, and git diff --check

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.

2 participants