@@ -233,6 +233,9 @@ async def get_working_memory(
233233 """
234234 params = {}
235235
236+ if user_id is not None :
237+ params ["user_id" ] = user_id
238+
236239 if namespace is not None :
237240 params ["namespace" ] = namespace
238241 elif self .config .default_namespace is not None :
@@ -258,7 +261,12 @@ async def get_working_memory(
258261 f"/v1/working-memory/{ session_id } " , params = params
259262 )
260263 response .raise_for_status ()
261- return WorkingMemoryResponse (** response .json ())
264+
265+ # Get the raw JSON response
266+ response_data = response .json ()
267+
268+ # Messages from JSON parsing are already in the correct dict format
269+ return WorkingMemoryResponse (** response_data )
262270 except httpx .HTTPStatusError as e :
263271 self ._handle_http_error (e .response )
264272 raise
@@ -267,6 +275,7 @@ async def put_working_memory(
267275 self ,
268276 session_id : str ,
269277 memory : WorkingMemory ,
278+ user_id : str | None = None ,
270279 model_name : str | None = None ,
271280 context_window_max : int | None = None ,
272281 ) -> WorkingMemoryResponse :
@@ -276,6 +285,7 @@ async def put_working_memory(
276285 Args:
277286 session_id: The session ID to store memory for
278287 memory: WorkingMemory object with messages and optional context
288+ user_id: Optional user ID for the session (overrides user_id in memory object)
279289 model_name: Optional model name for context window management
280290 context_window_max: Optional direct specification of context window max tokens
281291
@@ -289,6 +299,9 @@ async def put_working_memory(
289299 # Build query parameters for model-aware summarization
290300 params = {}
291301
302+ if user_id is not None :
303+ params ["user_id" ] = user_id
304+
292305 # Use provided model_name or fall back to config default
293306 effective_model_name = model_name or self .config .default_model_name
294307 if effective_model_name is not None :
@@ -2023,9 +2036,8 @@ async def update_working_memory_data(
20232036 async def append_messages_to_working_memory (
20242037 self ,
20252038 session_id : str ,
2026- messages : list [Any ], # Using Any since MemoryMessage isn't imported
2039+ messages : list [dict [ str , Any ]] , # Expect proper message dicts
20272040 namespace : str | None = None ,
2028- auto_summarize : bool = True ,
20292041 model_name : str | None = None ,
20302042 context_window_max : int | None = None ,
20312043 ) -> WorkingMemoryResponse :
@@ -2036,9 +2048,8 @@ async def append_messages_to_working_memory(
20362048
20372049 Args:
20382050 session_id: Target session
2039- messages: List of messages to append
2051+ messages: List of message dictionaries with 'role' and 'content' keys
20402052 namespace: Optional namespace
2041- auto_summarize: Whether to allow automatic summarization
20422053 model_name: Optional model name for token-based summarization
20432054 context_window_max: Optional direct specification of context window max tokens
20442055
@@ -2052,48 +2063,19 @@ async def append_messages_to_working_memory(
20522063 session_id = session_id , namespace = namespace
20532064 )
20542065
2055- # Combine messages - convert MemoryMessage objects to dicts if needed
2056- existing_messages = existing_memory .messages if existing_memory else []
2057-
2058- # Convert existing messages to dict format if they're objects
2059- converted_existing_messages = []
2060- for msg in existing_messages :
2061- if hasattr (msg , "model_dump" ) and callable (
2062- getattr (msg , "model_dump" , None )
2063- ):
2064- converted_existing_messages .append (msg .model_dump ()) # type: ignore
2065- elif (
2066- hasattr (msg , "role" )
2067- and hasattr (msg , "content" )
2068- and not isinstance (msg , dict )
2069- ):
2070- converted_existing_messages .append (
2071- {"role" : msg .role , "content" : msg .content } # type: ignore
2072- )
2073- elif isinstance (msg , dict ):
2074- # Message is already a dictionary, use as-is
2075- converted_existing_messages .append (msg )
2076- else :
2077- # Fallback for any other message type - convert to string content
2078- converted_existing_messages .append (
2079- {"role" : "user" , "content" : str (msg )}
2066+ # Validate new messages have required structure
2067+ for msg in messages :
2068+ if not isinstance (msg , dict ) or "role" not in msg or "content" not in msg :
2069+ raise ValueError (
2070+ "All messages must be dictionaries with 'role' and 'content' keys"
20802071 )
20812072
2082- # Convert new messages to dict format if they're objects
2083- new_messages = []
2084- for msg in messages :
2085- if hasattr (msg , "model_dump" ):
2086- new_messages .append (msg .model_dump ())
2087- elif hasattr (msg , "role" ) and hasattr (msg , "content" ):
2088- new_messages .append ({"role" : msg .role , "content" : msg .content })
2089- elif isinstance (msg , dict ):
2090- # Message is already a dictionary, use as-is
2091- new_messages .append (msg )
2092- else :
2093- # Fallback - assume it's already in the right format
2094- new_messages .append (msg )
2073+ # Get existing messages (already in proper dict format from get_working_memory)
2074+ existing_messages = []
2075+ if existing_memory and existing_memory .messages :
2076+ existing_messages = existing_memory .messages
20952077
2096- final_messages = converted_existing_messages + new_messages
2078+ final_messages = existing_messages + messages
20972079
20982080 # Create updated working memory
20992081 working_memory = WorkingMemory (
0 commit comments