message_transformer.py 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import logging
  2. from mimetypes import guess_extension
  3. from core.tools.entities.tool_entities import ToolInvokeMessage
  4. from core.tools.tool_file_manager import ToolFileManager
  5. logger = logging.getLogger(__name__)
  6. class ToolFileMessageTransformer:
  7. @staticmethod
  8. def transform_tool_invoke_messages(messages: list[ToolInvokeMessage],
  9. user_id: str,
  10. tenant_id: str,
  11. conversation_id: str) -> list[ToolInvokeMessage]:
  12. """
  13. Transform tool message and handle file download
  14. """
  15. result = []
  16. for message in messages:
  17. if message.type == ToolInvokeMessage.MessageType.TEXT:
  18. result.append(message)
  19. elif message.type == ToolInvokeMessage.MessageType.LINK:
  20. result.append(message)
  21. elif message.type == ToolInvokeMessage.MessageType.IMAGE:
  22. # try to download image
  23. try:
  24. file = ToolFileManager.create_file_by_url(
  25. user_id=user_id,
  26. tenant_id=tenant_id,
  27. conversation_id=conversation_id,
  28. file_url=message.message
  29. )
  30. url = f'/files/tools/{file.id}{guess_extension(file.mimetype) or ".png"}'
  31. result.append(ToolInvokeMessage(
  32. type=ToolInvokeMessage.MessageType.IMAGE_LINK,
  33. message=url,
  34. save_as=message.save_as,
  35. meta=message.meta.copy() if message.meta is not None else {},
  36. ))
  37. except Exception as e:
  38. logger.exception(e)
  39. result.append(ToolInvokeMessage(
  40. type=ToolInvokeMessage.MessageType.TEXT,
  41. message=f"Failed to download image: {message.message}, you can try to download it yourself.",
  42. meta=message.meta.copy() if message.meta is not None else {},
  43. save_as=message.save_as,
  44. ))
  45. elif message.type == ToolInvokeMessage.MessageType.BLOB:
  46. # get mime type and save blob to storage
  47. mimetype = message.meta.get('mime_type', 'octet/stream')
  48. # if message is str, encode it to bytes
  49. if isinstance(message.message, str):
  50. message.message = message.message.encode('utf-8')
  51. file = ToolFileManager.create_file_by_raw(
  52. user_id=user_id, tenant_id=tenant_id,
  53. conversation_id=conversation_id,
  54. file_binary=message.message,
  55. mimetype=mimetype
  56. )
  57. url = f'/files/tools/{file.id}{guess_extension(file.mimetype) or ".bin"}'
  58. # check if file is image
  59. if 'image' in mimetype:
  60. result.append(ToolInvokeMessage(
  61. type=ToolInvokeMessage.MessageType.IMAGE_LINK,
  62. message=url,
  63. save_as=message.save_as,
  64. meta=message.meta.copy() if message.meta is not None else {},
  65. ))
  66. else:
  67. result.append(ToolInvokeMessage(
  68. type=ToolInvokeMessage.MessageType.LINK,
  69. message=url,
  70. save_as=message.save_as,
  71. meta=message.meta.copy() if message.meta is not None else {},
  72. ))
  73. else:
  74. result.append(message)
  75. return result