file_obj.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import enum
  2. from typing import Any, Optional
  3. from pydantic import BaseModel
  4. from core.file.tool_file_parser import ToolFileParser
  5. from core.file.upload_file_parser import UploadFileParser
  6. from core.model_runtime.entities.message_entities import ImagePromptMessageContent
  7. from extensions.ext_database import db
  8. class FileExtraConfig(BaseModel):
  9. """
  10. File Upload Entity.
  11. """
  12. image_config: Optional[dict[str, Any]] = None
  13. class FileType(enum.Enum):
  14. IMAGE = 'image'
  15. @staticmethod
  16. def value_of(value):
  17. for member in FileType:
  18. if member.value == value:
  19. return member
  20. raise ValueError(f"No matching enum found for value '{value}'")
  21. class FileTransferMethod(enum.Enum):
  22. REMOTE_URL = 'remote_url'
  23. LOCAL_FILE = 'local_file'
  24. TOOL_FILE = 'tool_file'
  25. @staticmethod
  26. def value_of(value):
  27. for member in FileTransferMethod:
  28. if member.value == value:
  29. return member
  30. raise ValueError(f"No matching enum found for value '{value}'")
  31. class FileBelongsTo(enum.Enum):
  32. USER = 'user'
  33. ASSISTANT = 'assistant'
  34. @staticmethod
  35. def value_of(value):
  36. for member in FileBelongsTo:
  37. if member.value == value:
  38. return member
  39. raise ValueError(f"No matching enum found for value '{value}'")
  40. class FileVar(BaseModel):
  41. id: Optional[str] = None # message file id
  42. tenant_id: str
  43. type: FileType
  44. transfer_method: FileTransferMethod
  45. url: Optional[str] = None # remote url
  46. related_id: Optional[str] = None
  47. extra_config: Optional[FileExtraConfig] = None
  48. filename: Optional[str] = None
  49. extension: Optional[str] = None
  50. mime_type: Optional[str] = None
  51. def to_dict(self) -> dict:
  52. return {
  53. '__variant': self.__class__.__name__,
  54. 'tenant_id': self.tenant_id,
  55. 'type': self.type.value,
  56. 'transfer_method': self.transfer_method.value,
  57. 'url': self.preview_url,
  58. 'remote_url': self.url,
  59. 'related_id': self.related_id,
  60. 'filename': self.filename,
  61. 'extension': self.extension,
  62. 'mime_type': self.mime_type,
  63. }
  64. def to_markdown(self) -> str:
  65. """
  66. Convert file to markdown
  67. :return:
  68. """
  69. preview_url = self.preview_url
  70. if self.type == FileType.IMAGE:
  71. text = f'![{self.filename or ""}]({preview_url})'
  72. else:
  73. text = f'[{self.filename or preview_url}]({preview_url})'
  74. return text
  75. @property
  76. def data(self) -> Optional[str]:
  77. """
  78. Get image data, file signed url or base64 data
  79. depending on config MULTIMODAL_SEND_IMAGE_FORMAT
  80. :return:
  81. """
  82. return self._get_data()
  83. @property
  84. def preview_url(self) -> Optional[str]:
  85. """
  86. Get signed preview url
  87. :return:
  88. """
  89. return self._get_data(force_url=True)
  90. @property
  91. def prompt_message_content(self) -> ImagePromptMessageContent:
  92. if self.type == FileType.IMAGE:
  93. image_config = self.extra_config.image_config
  94. return ImagePromptMessageContent(
  95. data=self.data,
  96. detail=ImagePromptMessageContent.DETAIL.HIGH
  97. if image_config.get("detail") == "high" else ImagePromptMessageContent.DETAIL.LOW
  98. )
  99. def _get_data(self, force_url: bool = False) -> Optional[str]:
  100. from models.model import UploadFile
  101. if self.type == FileType.IMAGE:
  102. if self.transfer_method == FileTransferMethod.REMOTE_URL:
  103. return self.url
  104. elif self.transfer_method == FileTransferMethod.LOCAL_FILE:
  105. upload_file = (db.session.query(UploadFile)
  106. .filter(
  107. UploadFile.id == self.related_id,
  108. UploadFile.tenant_id == self.tenant_id
  109. ).first())
  110. return UploadFileParser.get_image_data(
  111. upload_file=upload_file,
  112. force_url=force_url
  113. )
  114. elif self.transfer_method == FileTransferMethod.TOOL_FILE:
  115. extension = self.extension
  116. # add sign url
  117. return ToolFileParser.get_tool_file_manager().sign_file(tool_file_id=self.related_id, extension=extension)
  118. return None