3232class OpenAIMiddlewareOptions :
3333 """Configuration options for OpenAI middleware."""
3434
35- conversation_id : Optional [str ] = None
3635 verbose : bool = False
3736 mode : Literal ["profile" , "query" , "full" ] = "profile"
3837 add_memory : Literal ["always" , "never" ] = "never"
@@ -263,10 +262,12 @@ def __init__(
263262 self ,
264263 openai_client : Union [OpenAI , AsyncOpenAI ],
265264 container_tag : str ,
265+ conversation_id : str ,
266266 options : Optional [OpenAIMiddlewareOptions ] = None ,
267267 ):
268268 self ._client : Union [OpenAI , AsyncOpenAI ] = openai_client
269269 self ._container_tag : str = container_tag
270+ self ._conversation_id : str = conversation_id
270271 self ._options : OpenAIMiddlewareOptions = options or OpenAIMiddlewareOptions ()
271272 self ._logger : Logger = create_logger (self ._options .verbose )
272273
@@ -336,12 +337,12 @@ async def _create_with_memory_async(
336337 if user_message and user_message .strip ():
337338 content = (
338339 get_conversation_content (messages )
339- if self ._options . conversation_id
340+ if self ._conversation_id
340341 else user_message
341342 )
342343 custom_id = (
343- f"conversation:{ self ._options . conversation_id } "
344- if self ._options . conversation_id
344+ f"conversation:{ self ._conversation_id } "
345+ if self ._conversation_id
345346 else None
346347 )
347348
@@ -399,7 +400,7 @@ def handle_task_exception(task_obj):
399400 "Starting memory search" ,
400401 {
401402 "container_tag" : self ._container_tag ,
402- "conversation_id" : self ._options . conversation_id ,
403+ "conversation_id" : self ._conversation_id ,
403404 "mode" : self ._options .mode ,
404405 },
405406 )
@@ -430,12 +431,12 @@ def _create_with_memory_sync(
430431 if user_message and user_message .strip ():
431432 content = (
432433 get_conversation_content (messages )
433- if self ._options . conversation_id
434+ if self ._conversation_id
434435 else user_message
435436 )
436437 custom_id = (
437- f"conversation:{ self ._options . conversation_id } "
438- if self ._options . conversation_id
438+ f"conversation:{ self ._conversation_id } "
439+ if self ._conversation_id
439440 else None
440441 )
441442
@@ -483,7 +484,7 @@ def _create_with_memory_sync(
483484 "Starting memory search" ,
484485 {
485486 "container_tag" : self ._container_tag ,
486- "conversation_id" : self ._options . conversation_id ,
487+ "conversation_id" : self ._conversation_id ,
487488 "mode" : self ._options .mode ,
488489 },
489490 )
@@ -615,19 +616,17 @@ def __getattr__(self, name: str) -> Any:
615616def with_supermemory (
616617 openai_client : Union [OpenAI , AsyncOpenAI ],
617618 container_tag : str ,
619+ conversation_id : str ,
618620 options : Optional [OpenAIMiddlewareOptions ] = None ,
619621) -> Union [OpenAI , AsyncOpenAI ]:
620622 """
621623 Wraps an OpenAI client with SuperMemory middleware to automatically inject relevant memories
622624 into the system prompt based on the user's message content.
623625
624- This middleware searches the supermemory API for relevant memories using the container tag
625- and user message, then either appends memories to an existing system prompt or creates
626- a new system prompt with the memories.
627-
628626 Args:
629627 openai_client: The OpenAI client to wrap with SuperMemory middleware
630628 container_tag: The container tag/identifier for memory search (e.g., user ID, project ID)
629+ conversation_id: Conversation ID to group messages into a single document
631630 options: Optional configuration options for the middleware
632631
633632 Returns:
@@ -638,19 +637,17 @@ def with_supermemory(
638637 from supermemory_openai import with_supermemory, OpenAIMiddlewareOptions
639638 from openai import OpenAI
640639
641- # Create OpenAI client with supermemory middleware
642640 openai = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
643641 openai_with_supermemory = with_supermemory(
644642 openai,
645643 "user-123",
644+ "conversation-456",
646645 OpenAIMiddlewareOptions(
647- conversation_id="conversation-456",
648646 mode="full",
649647 add_memory="always"
650648 )
651649 )
652650
653- # Use normally - memories will be automatically injected
654651 response = await openai_with_supermemory.chat.completions.create(
655652 model="gpt-4",
656653 messages=[
@@ -663,6 +660,14 @@ def with_supermemory(
663660 ValueError: When SUPERMEMORY_API_KEY environment variable is not set
664661 Exception: When supermemory API request fails
665662 """
666- wrapper = SupermemoryOpenAIWrapper (openai_client , container_tag , options )
663+ if not conversation_id or not conversation_id .strip ():
664+ raise ValueError (
665+ "[supermemory] conversation_id is required and cannot be empty. "
666+ "Pass a unique identifier (e.g., session ID, chat ID) as the third argument to with_supermemory(). "
667+ "This ensures messages are grouped into the same document for a conversation. "
668+ "Example: with_supermemory(openai_client, 'user-123', 'conversation-456')"
669+ )
670+
671+ wrapper = SupermemoryOpenAIWrapper (openai_client , container_tag , conversation_id , options )
667672 # Return the wrapper, which delegates all attributes to the original client
668673 return cast (Union [OpenAI , AsyncOpenAI ], wrapper )
0 commit comments