def process_streaming_objects(
    chat_response: ChatResponse,
    output_cls: Type[Model],
    cur_objects: Optional[Sequence[Model]] = None,
    allow_parallel_tool_calls: bool = False,
    flexible_mode: bool = True,
    llm: Optional[FunctionCallingLLM] = None,
) -> Union[Model, List[Model], FlexibleModel, List[FlexibleModel]]:
    """
    Process streaming response into structured objects.

    Args:
        chat_response (ChatResponse): The chat response to process
        output_cls (Type[BaseModel]): The target output class
        cur_objects (Optional[List[BaseModel]]): Current accumulated objects
        allow_parallel_tool_calls (bool): Whether to allow multiple tool calls
        flexible_mode (bool): Whether to use flexible schema during parsing

    Returns:
        Union[BaseModel, List[BaseModel]]: Processed object(s)

    """
    if flexible_mode:
        # Create flexible version of model that allows partial responses
        partial_output_cls = create_flexible_model(output_cls)
    else:
        partial_output_cls = output_cls  # type: ignore

    # Get tool calls from response, if there are any
    if not chat_response.message.additional_kwargs.get("tool_calls"):
        output_cls_args = [chat_response.message.content]
    else:
        tool_calls: List[ToolSelection] = []
        if not llm:
            raise ValueError("LLM is required to get tool calls")

        if isinstance(chat_response.message.additional_kwargs.get("tool_calls"), list):
            tool_calls = llm.get_tool_calls_from_response(
                chat_response, error_on_no_tool_call=False
            )

        if len(tool_calls) == 0:
            # If no tool calls, return single blank output class
            return partial_output_cls()

        # Extract arguments from tool calls
        output_cls_args = [call.tool_kwargs for call in tool_calls]  # type: ignore

    # Try to parse objects, handling potential incomplete JSON
    objects = []
    for output_cls_arg in output_cls_args:
        try:
            # First try direct validation
            obj = partial_output_cls.model_validate(output_cls_arg)
            objects.append(obj)
        except (ValidationError, ValueError):
            try:
                # Try repairing the JSON if it's a string
                if isinstance(output_cls_arg, str):
                    repaired_json = _repair_incomplete_json(output_cls_arg)
                    obj = partial_output_cls.model_validate_json(repaired_json)
                    objects.append(obj)
                else:
                    raise
            except (ValidationError, ValueError) as e2:
                _logger.debug(f"Validation error during streaming: {e2}")
                # If we have previous objects, keep using those
                if cur_objects:
                    objects = cur_objects  # type: ignore
                else:
                    # Return a blank object if we can't parse anything
                    return partial_output_cls()

    # Update if we have more valid fields than before
    if cur_objects is None or num_valid_fields(objects) >= num_valid_fields(
        cur_objects
    ):
        cur_objects = objects  # type: ignore

    # Try to convert flexible objects to target schema
    new_cur_objects = []
    cur_objects = cur_objects or []
    for o in cur_objects:
        try:
            new_obj = output_cls.model_validate(o.model_dump(exclude_unset=True))
        except ValidationError:
            new_obj = o
        new_cur_objects.append(new_obj)

    if allow_parallel_tool_calls:
        return new_cur_objects
    else:
        if len(new_cur_objects) > 1:
            _logger.warning(
                "Multiple outputs found, returning first one. "
                "If you want to return all outputs, set allow_parallel_tool_calls=True."
            )
        return new_cur_objects[0]

    Process streaming response into structured objects.

    Args:
        chat_response (ChatResponse): The chat response to process
        output_cls (Type[BaseModel]): The target output class
        cur_objects (Optional[List[BaseModel]]): Current accumulated objects
        allow_parallel_tool_calls (bool): Whether to allow multiple tool calls
        flexible_mode (bool): Whether to use flexible schema during parsing

    Returns:
        Union[BaseModel, List[BaseModel]]: Processed object(s)

    
llama-index-core/llama_index/core/program/utils.py