123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- import enum
- from typing import Any, Optional
- from pydantic import BaseModel
- from core.file.tool_file_parser import ToolFileParser
- from core.file.upload_file_parser import UploadFileParser
- from core.model_runtime.entities.message_entities import ImagePromptMessageContent
- from extensions.ext_database import db
- class FileExtraConfig(BaseModel):
- """
- File Upload Entity.
- """
- image_config: Optional[dict[str, Any]] = None
- class FileType(enum.Enum):
- IMAGE = 'image'
- @staticmethod
- def value_of(value):
- for member in FileType:
- if member.value == value:
- return member
- raise ValueError(f"No matching enum found for value '{value}'")
- class FileTransferMethod(enum.Enum):
- REMOTE_URL = 'remote_url'
- LOCAL_FILE = 'local_file'
- TOOL_FILE = 'tool_file'
- @staticmethod
- def value_of(value):
- for member in FileTransferMethod:
- if member.value == value:
- return member
- raise ValueError(f"No matching enum found for value '{value}'")
- class FileBelongsTo(enum.Enum):
- USER = 'user'
- ASSISTANT = 'assistant'
- @staticmethod
- def value_of(value):
- for member in FileBelongsTo:
- if member.value == value:
- return member
- raise ValueError(f"No matching enum found for value '{value}'")
- class FileVar(BaseModel):
- id: Optional[str] = None # message file id
- tenant_id: str
- type: FileType
- transfer_method: FileTransferMethod
- url: Optional[str] = None # remote url
- related_id: Optional[str] = None
- extra_config: Optional[FileExtraConfig] = None
- filename: Optional[str] = None
- extension: Optional[str] = None
- mime_type: Optional[str] = None
- def to_dict(self) -> dict:
- return {
- '__variant': self.__class__.__name__,
- 'tenant_id': self.tenant_id,
- 'type': self.type.value,
- 'transfer_method': self.transfer_method.value,
- 'url': self.preview_url,
- 'remote_url': self.url,
- 'related_id': self.related_id,
- 'filename': self.filename,
- 'extension': self.extension,
- 'mime_type': self.mime_type,
- }
- def to_markdown(self) -> str:
- """
- Convert file to markdown
- :return:
- """
- preview_url = self.preview_url
- if self.type == FileType.IMAGE:
- text = f''
- else:
- text = f'[{self.filename or preview_url}]({preview_url})'
- return text
- @property
- def data(self) -> Optional[str]:
- """
- Get image data, file signed url or base64 data
- depending on config MULTIMODAL_SEND_IMAGE_FORMAT
- :return:
- """
- return self._get_data()
- @property
- def preview_url(self) -> Optional[str]:
- """
- Get signed preview url
- :return:
- """
- return self._get_data(force_url=True)
- @property
- def prompt_message_content(self) -> ImagePromptMessageContent:
- if self.type == FileType.IMAGE:
- image_config = self.extra_config.image_config
- return ImagePromptMessageContent(
- data=self.data,
- detail=ImagePromptMessageContent.DETAIL.HIGH
- if image_config.get("detail") == "high" else ImagePromptMessageContent.DETAIL.LOW
- )
- def _get_data(self, force_url: bool = False) -> Optional[str]:
- from models.model import UploadFile
- if self.type == FileType.IMAGE:
- if self.transfer_method == FileTransferMethod.REMOTE_URL:
- return self.url
- elif self.transfer_method == FileTransferMethod.LOCAL_FILE:
- upload_file = (db.session.query(UploadFile)
- .filter(
- UploadFile.id == self.related_id,
- UploadFile.tenant_id == self.tenant_id
- ).first())
- return UploadFileParser.get_image_data(
- upload_file=upload_file,
- force_url=force_url
- )
- elif self.transfer_method == FileTransferMethod.TOOL_FILE:
- extension = self.extension
- # add sign url
- return ToolFileParser.get_tool_file_manager().sign_file(tool_file_id=self.related_id, extension=extension)
- return None
|