file_obj.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  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"
  98. else ImagePromptMessageContent.DETAIL.LOW,
  99. )
  100. def _get_data(self, force_url: bool = False) -> Optional[str]:
  101. from models.model import UploadFile
  102. if self.type == FileType.IMAGE:
  103. if self.transfer_method == FileTransferMethod.REMOTE_URL:
  104. return self.url
  105. elif self.transfer_method == FileTransferMethod.LOCAL_FILE:
  106. upload_file = (
  107. db.session.query(UploadFile)
  108. .filter(UploadFile.id == self.related_id, UploadFile.tenant_id == self.tenant_id)
  109. .first()
  110. )
  111. return UploadFileParser.get_image_data(upload_file=upload_file, force_url=force_url)
  112. elif self.transfer_method == FileTransferMethod.TOOL_FILE:
  113. extension = self.extension
  114. # add sign url
  115. return ToolFileParser.get_tool_file_manager().sign_file(
  116. tool_file_id=self.related_id, extension=extension
  117. )
  118. return None