def messages_to_anthropic_messages(
    messages: Sequence[ChatMessage],
    cache_idx: Optional[int] = None,
) -> Tuple[Sequence[MessageParam], str]:
    """
    Converts a list of generic ChatMessages to anthropic messages.

    Args:
        messages: List of ChatMessages

    Returns:
        Tuple of:
        - List of anthropic messages
        - System prompt

    """
    anthropic_messages = []
    system_prompt = []
    for idx, message in enumerate(messages):
        # inject cache_control for all messages up to and including the cache_idx
        if cache_idx is not None and (idx <= cache_idx or cache_idx == -1):
            message.additional_kwargs["cache_control"] = {"type": "ephemeral"}

        if message.role == MessageRole.SYSTEM:
            for block in message.blocks:
                if isinstance(block, TextBlock) and block.text:
                    system_prompt.append(
                        _text_block_to_anthropic_message(
                            block, message.additional_kwargs
                        )
                    )
        elif message.role == MessageRole.FUNCTION or message.role == MessageRole.TOOL:
            content = ToolResultBlockParam(
                tool_use_id=message.additional_kwargs["tool_call_id"],
                type="tool_result",
                content=[TextBlockParam(text=message.content, type="text")],
                cache_control=message.additional_kwargs.get("cache_control"),
            )
            anth_message = MessageParam(
                role=MessageRole.USER.value,
                content=[content],
            )
            anthropic_messages.append(anth_message)
        else:
            content: list[TextBlockParam | ImageBlockParam | DocumentBlockParam] = []
            for block in message.blocks:
                if isinstance(block, TextBlock):
                    if block.text or message.additional_kwargs.get("thinking"):
                        content.append(
                            _text_block_to_anthropic_message(
                                block, message.additional_kwargs
                            )
                        )
                elif isinstance(block, ImageBlock):
                    # FUTURE: Claude does not support URLs, so we need to always convert to base64
                    img_bytes = block.resolve_image(as_base64=True).read()
                    img_str = img_bytes.decode("utf-8")

                    block_type = (
                        "document"
                        if block.image_mimetype == "application/pdf"
                        else "image"
                    )
                    block = ImageBlockParam(
                        type=block_type,
                        source={
                            "type": "base64",
                            "media_type": block.image_mimetype,
                            "data": img_str,
                        },
                    )
                    content.append(block)
                elif isinstance(block, DocumentBlock):
                    content.append(
                        _document_block_to_anthropic_message(
                            block=block, kwargs=message.additional_kwargs
                        )
                    )
            tool_calls = message.additional_kwargs.get("tool_calls", [])
            for tool_call in tool_calls:
                assert "id" in tool_call
                assert "input" in tool_call
                assert "name" in tool_call

                content.append(
                    ToolUseBlockParam(
                        id=tool_call["id"],
                        input=tool_call["input"],
                        name=tool_call["name"],
                        type="tool_use",
                    )
                )

            anth_message = MessageParam(
                role=message.role.value,
                content=content,
            )
            anthropic_messages.append(anth_message)

    return __merge_common_role_msgs(anthropic_messages), system_prompt

    Converts a list of generic ChatMessages to anthropic messages.

    Args:
        messages: List of ChatMessages

    Returns:
        Tuple of:
        - List of anthropic messages
        - System prompt

    
llama-index-integrations/llms/llama-index-llms-anthropic/llama_index/llms/anthropic/utils.py