@@ -2697,12 +2697,6 @@ def _process_stream_chunks_with_accumulator(
26972697 # If we have complete tool calls, execute them with
26982698 # sync status updates
26992699 if accumulated_tool_calls :
2700- # Record assistant message with tool calls first
2701- self ._record_assistant_tool_calls_message (
2702- accumulated_tool_calls ,
2703- content_accumulator .get_full_content (),
2704- )
2705-
27062700 # Execute tools synchronously with
27072701 # optimized status updates
27082702 for (
@@ -2942,10 +2936,19 @@ def _execute_tool_from_stream_data(
29422936 tool = self ._internal_tools [function_name ]
29432937 try :
29442938 result = tool (** args )
2939+ # First, create and record the assistant message with tool
2940+ # call
2941+ assist_msg = FunctionCallingMessage (
2942+ role_name = self .role_name ,
2943+ role_type = self .role_type ,
2944+ meta_dict = None ,
2945+ content = "" ,
2946+ func_name = function_name ,
2947+ args = args ,
2948+ tool_call_id = tool_call_id ,
2949+ )
29452950
2946- # Only record the tool response message, not the assistant
2947- # message assistant message with tool_calls was already
2948- # recorded in _record_assistant_tool_calls_message
2951+ # Then create the tool response message
29492952 func_msg = FunctionCallingMessage (
29502953 role_name = self .role_name ,
29512954 role_type = self .role_type ,
@@ -2956,7 +2959,25 @@ def _execute_tool_from_stream_data(
29562959 tool_call_id = tool_call_id ,
29572960 )
29582961
2959- self .update_memory (func_msg , OpenAIBackendRole .FUNCTION )
2962+ # Record both messages with precise timestamps to ensure
2963+ # correct ordering
2964+ import time
2965+
2966+ current_time_ns = time .time_ns ()
2967+ base_timestamp = (
2968+ current_time_ns / 1_000_000_000
2969+ ) # Convert to seconds
2970+
2971+ self .update_memory (
2972+ assist_msg ,
2973+ OpenAIBackendRole .ASSISTANT ,
2974+ timestamp = base_timestamp ,
2975+ )
2976+ self .update_memory (
2977+ func_msg ,
2978+ OpenAIBackendRole .FUNCTION ,
2979+ timestamp = base_timestamp + 1e-6 ,
2980+ )
29602981
29612982 return ToolCallingRecord (
29622983 tool_name = function_name ,
@@ -3040,10 +3061,19 @@ async def _aexecute_tool_from_stream_data(
30403061 else :
30413062 # Fallback: synchronous call
30423063 result = tool (** args )
3064+ # First, create and record the assistant message with tool
3065+ # call
3066+ assist_msg = FunctionCallingMessage (
3067+ role_name = self .role_name ,
3068+ role_type = self .role_type ,
3069+ meta_dict = None ,
3070+ content = "" ,
3071+ func_name = function_name ,
3072+ args = args ,
3073+ tool_call_id = tool_call_id ,
3074+ )
30433075
3044- # Only record the tool response message, not the assistant
3045- # message assistant message with tool_calls was already
3046- # recorded in _record_assistant_tool_calls_message
3076+ # Then create the tool response message
30473077 func_msg = FunctionCallingMessage (
30483078 role_name = self .role_name ,
30493079 role_type = self .role_type ,
@@ -3054,7 +3084,25 @@ async def _aexecute_tool_from_stream_data(
30543084 tool_call_id = tool_call_id ,
30553085 )
30563086
3057- self .update_memory (func_msg , OpenAIBackendRole .FUNCTION )
3087+ # Record both messages with precise timestamps to ensure
3088+ # correct ordering
3089+ import time
3090+
3091+ current_time_ns = time .time_ns ()
3092+ base_timestamp = (
3093+ current_time_ns / 1_000_000_000
3094+ ) # Convert to seconds
3095+
3096+ self .update_memory (
3097+ assist_msg ,
3098+ OpenAIBackendRole .ASSISTANT ,
3099+ timestamp = base_timestamp ,
3100+ )
3101+ self .update_memory (
3102+ func_msg ,
3103+ OpenAIBackendRole .FUNCTION ,
3104+ timestamp = base_timestamp + 1e-6 ,
3105+ )
30583106
30593107 return ToolCallingRecord (
30603108 tool_name = function_name ,
@@ -3444,13 +3492,6 @@ async def _aprocess_stream_chunks_with_accumulator(
34443492 # If we have complete tool calls, execute them with
34453493 # async status updates
34463494 if accumulated_tool_calls :
3447- # Record assistant message with
3448- # tool calls first
3449- self ._record_assistant_tool_calls_message (
3450- accumulated_tool_calls ,
3451- content_accumulator .get_full_content (),
3452- )
3453-
34543495 # Execute tools asynchronously with real-time
34553496 # status updates
34563497 async for (
0 commit comments