@@ -38,6 +38,16 @@ class StreamingState:
3838    function_calls : dict [int , ResponseFunctionToolCall ] =  field (default_factory = dict )
3939
4040
41+ class  SequenceNumber :
42+     def  __init__ (self ):
43+         self ._sequence_number  =  0 
44+ 
45+     def  get_and_increment (self ) ->  int :
46+         num  =  self ._sequence_number 
47+         self ._sequence_number  +=  1 
48+         return  num 
49+ 
50+ 
4151class  ChatCmplStreamHandler :
4252    @classmethod  
4353    async  def  handle_stream (
@@ -47,13 +57,14 @@ async def handle_stream(
4757    ) ->  AsyncIterator [TResponseStreamEvent ]:
4858        usage : CompletionUsage  |  None  =  None 
4959        state  =  StreamingState ()
50- 
60+          sequence_number   =   SequenceNumber () 
5161        async  for  chunk  in  stream :
5262            if  not  state .started :
5363                state .started  =  True 
5464                yield  ResponseCreatedEvent (
5565                    response = response ,
5666                    type = "response.created" ,
67+                     sequence_number = sequence_number .get_and_increment (),
5768                )
5869
5970            # This is always set by the OpenAI API, but not by others e.g. LiteLLM 
@@ -89,6 +100,7 @@ async def handle_stream(
89100                        item = assistant_item ,
90101                        output_index = 0 ,
91102                        type = "response.output_item.added" ,
103+                         sequence_number = sequence_number .get_and_increment (),
92104                    )
93105                    yield  ResponseContentPartAddedEvent (
94106                        content_index = state .text_content_index_and_output [0 ],
@@ -100,6 +112,7 @@ async def handle_stream(
100112                            annotations = [],
101113                        ),
102114                        type = "response.content_part.added" ,
115+                         sequence_number = sequence_number .get_and_increment (),
103116                    )
104117                # Emit the delta for this segment of content 
105118                yield  ResponseTextDeltaEvent (
@@ -108,6 +121,7 @@ async def handle_stream(
108121                    item_id = FAKE_RESPONSES_ID ,
109122                    output_index = 0 ,
110123                    type = "response.output_text.delta" ,
124+                     sequence_number = sequence_number .get_and_increment (),
111125                )
112126                # Accumulate the text into the response part 
113127                state .text_content_index_and_output [1 ].text  +=  delta .content 
@@ -134,6 +148,7 @@ async def handle_stream(
134148                        item = assistant_item ,
135149                        output_index = 0 ,
136150                        type = "response.output_item.added" ,
151+                         sequence_number = sequence_number .get_and_increment (),
137152                    )
138153                    yield  ResponseContentPartAddedEvent (
139154                        content_index = state .refusal_content_index_and_output [0 ],
@@ -145,6 +160,7 @@ async def handle_stream(
145160                            annotations = [],
146161                        ),
147162                        type = "response.content_part.added" ,
163+                         sequence_number = sequence_number .get_and_increment (),
148164                    )
149165                # Emit the delta for this segment of refusal 
150166                yield  ResponseRefusalDeltaEvent (
@@ -153,6 +169,7 @@ async def handle_stream(
153169                    item_id = FAKE_RESPONSES_ID ,
154170                    output_index = 0 ,
155171                    type = "response.refusal.delta" ,
172+                     sequence_number = sequence_number .get_and_increment (),
156173                )
157174                # Accumulate the refusal string in the output part 
158175                state .refusal_content_index_and_output [1 ].refusal  +=  delta .refusal 
@@ -190,6 +207,7 @@ async def handle_stream(
190207                output_index = 0 ,
191208                part = state .text_content_index_and_output [1 ],
192209                type = "response.content_part.done" ,
210+                 sequence_number = sequence_number .get_and_increment (),
193211            )
194212
195213        if  state .refusal_content_index_and_output :
@@ -201,6 +219,7 @@ async def handle_stream(
201219                output_index = 0 ,
202220                part = state .refusal_content_index_and_output [1 ],
203221                type = "response.content_part.done" ,
222+                 sequence_number = sequence_number .get_and_increment (),
204223            )
205224
206225        # Actually send events for the function calls 
@@ -216,13 +235,15 @@ async def handle_stream(
216235                ),
217236                output_index = function_call_starting_index ,
218237                type = "response.output_item.added" ,
238+                 sequence_number = sequence_number .get_and_increment (),
219239            )
220240            # Then, yield the args 
221241            yield  ResponseFunctionCallArgumentsDeltaEvent (
222242                delta = function_call .arguments ,
223243                item_id = FAKE_RESPONSES_ID ,
224244                output_index = function_call_starting_index ,
225245                type = "response.function_call_arguments.delta" ,
246+                 sequence_number = sequence_number .get_and_increment (),
226247            )
227248            # Finally, the ResponseOutputItemDone 
228249            yield  ResponseOutputItemDoneEvent (
@@ -235,6 +256,7 @@ async def handle_stream(
235256                ),
236257                output_index = function_call_starting_index ,
237258                type = "response.output_item.done" ,
259+                 sequence_number = sequence_number .get_and_increment (),
238260            )
239261
240262        # Finally, send the Response completed event 
@@ -258,6 +280,7 @@ async def handle_stream(
258280                item = assistant_msg ,
259281                output_index = 0 ,
260282                type = "response.output_item.done" ,
283+                 sequence_number = sequence_number .get_and_increment (),
261284            )
262285
263286        for  function_call  in  state .function_calls .values ():
@@ -289,4 +312,5 @@ async def handle_stream(
289312        yield  ResponseCompletedEvent (
290313            response = final_response ,
291314            type = "response.completed" ,
315+             sequence_number = sequence_number .get_and_increment (),
292316        )
0 commit comments