def _slice_chat_formatted_example(
    example: ChatFormattedDict,
    tokenizer: PreTrainedTokenizerBase,
) -> list[tuple[str, str]]:
    """Slices chat example into a list of templated prompt, response turns.

    Note: Assistant messages mark the end of chat turns. So there are as many turns as there are
        assistant messages in the chat example.

    Args:
        example (ChatFormattedDict): The chat example containing the messages.
        tokenizer (PreTrainedTokenizerBase): The tokenizer to apply the chat template.

    Returns:
        List[Tuple[str, str]]: A list of templated prompt and response string pairs, one pair per chat turn.

    Raises:
        ValueError: If any chat turn in the example has less than two messages or if the last message is not from the assistant.
        KeyError: If a message does not have a role or content.
    """
    _validate_chat_formatted_example(example)
    messages = example[_get_key(example, ALLOWED_MESSAGES_KEYS)]

    last_message = messages[-1]
    if last_message['role'] != 'assistant':
        raise InvalidLastChatMessageRoleError(
            last_message['role'],
            set('assistant'),
        )

    def slice_out_last_turn(
        messages_through_current_turn: list[dict[str, str]],
        conversation_through_previous_turn: str,
    ) -> tuple[str, str]:
        chat_template = None if tokenizer.chat_template is not None else _DEFAULT_CHAT_TEMPLATE

        try:
            full_conversation = tokenizer.apply_chat_template(
                messages_through_current_turn,
                tokenize=False,
                date_string=get_date_string(),
                chat_template=chat_template,
            )
            prompt_with_history = tokenizer.apply_chat_template(
                messages_through_current_turn[:-1],
                tokenize=False,
                add_generation_prompt=True,
                date_string=get_date_string(),
                chat_template=chat_template,
            )
        except Exception as e:
            raise ChatTemplateError(
                tokenizer.chat_template,  # type: ignore
                sample=messages_through_current_turn,
                inner_message=str(e),
            )
        if conversation_through_previous_turn != full_conversation[:len(  # type: ignore
            conversation_through_previous_turn,
        )]:
            raise InvalidConversationError(
                f'The full conversation must start with the conversation through the previous turn. {conversation_through_previous_turn=}, {full_conversation=}',
            )
        if conversation_through_previous_turn != prompt_with_history[:len(  # type: ignore
            conversation_through_previous_turn,
        )]:
            raise InvalidConversationError(
                f'The prompt_with_history must start with the conversation through the previous turn. {conversation_through_previous_turn=}, {prompt_with_history=}',
            )
        if prompt_with_history != full_conversation[:len(prompt_with_history)
                                                   ]:  # type: ignore
            raise InvalidConversationError(
                f'prompt_with_history must be the first part of the full conversation. {prompt_with_history=}, {full_conversation=}',
            )
        prompt = prompt_with_history[len(conversation_through_previous_turn):
                                    ]  # type: ignore
        response = full_conversation[len(prompt_with_history):]  # type: ignore
        return prompt, response  # type: ignore

    templated_prompt_response_turns: list[tuple[str, str]] = []
    conversation_through_previous_turn = ''
    for idx, message in enumerate(messages):
        if message['role'] == 'assistant':
            prompt, response = slice_out_last_turn(
                messages[:idx + 1],
                conversation_through_previous_turn,
            )
            templated_prompt_response_turns.append((prompt, response))
            conversation_through_previous_turn += prompt
            conversation_through_previous_turn += response

    return templated_prompt_response_turns
Slices chat example into a list of templated prompt, response turns.

    Note: Assistant messages mark the end of chat turns. So there are as many turns as there are
        assistant messages in the chat example.

    Args:
        example (ChatFormattedDict): The chat example containing the messages.
        tokenizer (PreTrainedTokenizerBase): The tokenizer to apply the chat template.

    Returns:
        List[Tuple[str, str]]: A list of templated prompt and response string pairs, one pair per chat turn.

    Raises:
        ValueError: If any chat turn in the example has less than two messages or if the last message is not from the assistant.
        KeyError: If a message does not have a role or content.
    
llmfoundry/data/finetuning/tasks.py