| 12 | |
| 13 | |
| 14 | def merge_openai_chunks( |
| 15 | base: Optional[ChatCompletion], chunk: ChatCompletionChunk |
| 16 | ) -> ChatCompletion: |
| 17 | if base is None: |
| 18 | return merge_openai_chunks( |
| 19 | ChatCompletion( |
| 20 | id=chunk.id, |
| 21 | choices=[], |
| 22 | created=chunk.created, |
| 23 | model=chunk.model, |
| 24 | object="chat.completion", |
| 25 | system_fingerprint=chunk.system_fingerprint, |
| 26 | ), |
| 27 | chunk, |
| 28 | ) |
| 29 | |
| 30 | base_choices = base.choices.copy() |
| 31 | for choice in chunk.choices: |
| 32 | base_choice = next((c for c in base_choices if c.index == choice.index), None) |
| 33 | |
| 34 | if base_choice: |
| 35 | base_choice.finish_reason = ( |
| 36 | choice.finish_reason or base_choice.finish_reason |
| 37 | ) |
| 38 | |
| 39 | if choice.delta and choice.delta.content: |
| 40 | base_choice.message.content = (base_choice.message.content or "") + ( |
| 41 | choice.delta.content or "" |
| 42 | ) |
| 43 | if choice.delta and choice.delta.function_call: |
| 44 | fn_call = base_choice.message.function_call or {} |
| 45 | fn_call.name = (fn_call.name or "") + ( |
| 46 | choice.delta.function_call.name or "" |
| 47 | ) |
| 48 | fn_call.arguments = (fn_call.arguments or "") + ( |
| 49 | choice.delta.function_call.arguments or "" |
| 50 | ) |
| 51 | if choice.delta and choice.delta.tool_calls: |
| 52 | tool_calls = base_choice.message.tool_calls or [] |
| 53 | tool_call_delta: ChoiceDeltaToolCall = choice.delta.tool_calls[0] |
| 54 | if tool_call_delta.function.name: |
| 55 | tool_calls.append( |
| 56 | ChatCompletionMessageToolCall( |
| 57 | id=tool_call_delta.id, |
| 58 | type="function", |
| 59 | function=Function( |
| 60 | name=tool_call_delta.function.name, |
| 61 | arguments=tool_call_delta.function.arguments, |
| 62 | ), |
| 63 | ) |
| 64 | ) |
| 65 | else: |
| 66 | tool_calls[ |
| 67 | -1 |
| 68 | ].function.arguments += tool_call_delta.function.arguments |
| 69 | base_choice.message.tool_calls = tool_calls |
| 70 | else: |
| 71 | function_call = None |