Team Ai
Apppublic

Underground-Digital/Workflow-Engine

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
message_transformer.py126 linesDownload Raw Back to utils
1import logging2from mimetypes import guess_extension3from typing import Optional4 5from core.file import File, FileTransferMethod, FileType6from core.tools.entities.tool_entities import ToolInvokeMessage7from core.tools.tool_file_manager import ToolFileManager8 9logger = logging.getLogger(__name__)10 11 12class ToolFileMessageTransformer:13    @classmethod14    def transform_tool_invoke_messages(15        cls, messages: list[ToolInvokeMessage], user_id: str, tenant_id: str, conversation_id: str | None16    ) -> list[ToolInvokeMessage]:17        """18        Transform tool message and handle file download19        """20        result = []21 22        for message in messages:23            if message.type in {ToolInvokeMessage.MessageType.TEXT, ToolInvokeMessage.MessageType.LINK}:24                result.append(message)25            elif message.type == ToolInvokeMessage.MessageType.IMAGE and isinstance(message.message, str):26                # try to download image27                try:28                    file = ToolFileManager.create_file_by_url(29                        user_id=user_id, tenant_id=tenant_id, conversation_id=conversation_id, file_url=message.message30                    )31 32                    url = f'/files/tools/{file.id}{guess_extension(file.mimetype) or ".png"}'33 34                    result.append(35                        ToolInvokeMessage(36                            type=ToolInvokeMessage.MessageType.IMAGE_LINK,37                            message=url,38                            save_as=message.save_as,39                            meta=message.meta.copy() if message.meta is not None else {},40                        )41                    )42                except Exception as e:43                    logger.exception(e)44                    result.append(45                        ToolInvokeMessage(46                            type=ToolInvokeMessage.MessageType.TEXT,47                            message=f"Failed to download image: {message.message}, please try to download it manually.",48                            meta=message.meta.copy() if message.meta is not None else {},49                            save_as=message.save_as,50                        )51                    )52            elif message.type == ToolInvokeMessage.MessageType.BLOB:53                # get mime type and save blob to storage54                assert message.meta is not None55                mimetype = message.meta.get("mime_type", "octet/stream")56                # if message is str, encode it to bytes57                if isinstance(message.message, str):58                    message.message = message.message.encode("utf-8")59 60                # FIXME: should do a type check here.61                assert isinstance(message.message, bytes)62                file = ToolFileManager.create_file_by_raw(63                    user_id=user_id,64                    tenant_id=tenant_id,65                    conversation_id=conversation_id,66                    file_binary=message.message,67                    mimetype=mimetype,68                )69 70                url = cls.get_tool_file_url(tool_file_id=file.id, extension=guess_extension(file.mimetype))71 72                # check if file is image73                if "image" in mimetype:74                    result.append(75                        ToolInvokeMessage(76                            type=ToolInvokeMessage.MessageType.IMAGE_LINK,77                            message=url,78                            save_as=message.save_as,79                            meta=message.meta.copy() if message.meta is not None else {},80                        )81                    )82                else:83                    result.append(84                        ToolInvokeMessage(85                            type=ToolInvokeMessage.MessageType.LINK,86                            message=url,87                            save_as=message.save_as,88                            meta=message.meta.copy() if message.meta is not None else {},89                        )90                    )91            elif message.type == ToolInvokeMessage.MessageType.FILE:92                assert message.meta is not None93                file = message.meta.get("file")94                if isinstance(file, File):95                    if file.transfer_method == FileTransferMethod.TOOL_FILE:96                        assert file.related_id is not None97                        url = cls.get_tool_file_url(tool_file_id=file.related_id, extension=file.extension)98                        if file.type == FileType.IMAGE:99                            result.append(100                                ToolInvokeMessage(101                                    type=ToolInvokeMessage.MessageType.IMAGE_LINK,102                                    message=url,103                                    save_as=message.save_as,104                                    meta=message.meta.copy() if message.meta is not None else {},105                                )106                            )107                        else:108                            result.append(109                                ToolInvokeMessage(110                                    type=ToolInvokeMessage.MessageType.LINK,111                                    message=url,112                                    save_as=message.save_as,113                                    meta=message.meta.copy() if message.meta is not None else {},114                                )115                            )116                    else:117                        result.append(message)118            else:119                result.append(message)120 121        return result122 123    @classmethod124    def get_tool_file_url(cls, tool_file_id: str, extension: Optional[str]) -> str:125        return f'/files/tools/{tool_file_id}{extension or ".bin"}'126