2023-11-13 22:05:46 +08:00
|
|
|
import enum
|
2024-08-13 14:44:10 +08:00
|
|
|
from typing import Any, Optional
|
2023-11-13 22:05:46 +08:00
|
|
|
|
2024-02-06 13:21:13 +08:00
|
|
|
from pydantic import BaseModel
|
|
|
|
|
2024-04-08 18:51:46 +08:00
|
|
|
from core.file.tool_file_parser import ToolFileParser
|
2023-11-13 22:05:46 +08:00
|
|
|
from core.file.upload_file_parser import UploadFileParser
|
2024-01-02 23:42:00 +08:00
|
|
|
from core.model_runtime.entities.message_entities import ImagePromptMessageContent
|
2023-11-13 22:05:46 +08:00
|
|
|
from extensions.ext_database import db
|
2024-08-13 14:44:10 +08:00
|
|
|
|
|
|
|
|
|
|
|
class FileExtraConfig(BaseModel):
|
|
|
|
"""
|
|
|
|
File Upload Entity.
|
|
|
|
"""
|
2024-09-10 17:00:20 +08:00
|
|
|
|
2024-08-13 14:44:10 +08:00
|
|
|
image_config: Optional[dict[str, Any]] = None
|
2023-11-13 22:05:46 +08:00
|
|
|
|
|
|
|
|
|
|
|
class FileType(enum.Enum):
|
2024-09-10 17:00:20 +08:00
|
|
|
IMAGE = "image"
|
2023-11-13 22:05:46 +08:00
|
|
|
|
|
|
|
@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):
|
2024-09-10 17:00:20 +08:00
|
|
|
REMOTE_URL = "remote_url"
|
|
|
|
LOCAL_FILE = "local_file"
|
|
|
|
TOOL_FILE = "tool_file"
|
2023-11-13 22:05:46 +08:00
|
|
|
|
|
|
|
@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}'")
|
|
|
|
|
2024-09-10 17:00:20 +08:00
|
|
|
|
2024-01-23 19:58:23 +08:00
|
|
|
class FileBelongsTo(enum.Enum):
|
2024-09-10 17:00:20 +08:00
|
|
|
USER = "user"
|
|
|
|
ASSISTANT = "assistant"
|
2024-01-23 19:58:23 +08:00
|
|
|
|
|
|
|
@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}'")
|
2023-11-13 22:05:46 +08:00
|
|
|
|
2024-04-08 18:51:46 +08:00
|
|
|
|
|
|
|
class FileVar(BaseModel):
|
|
|
|
id: Optional[str] = None # message file id
|
2023-11-13 22:05:46 +08:00
|
|
|
tenant_id: str
|
|
|
|
type: FileType
|
|
|
|
transfer_method: FileTransferMethod
|
2024-04-08 18:51:46 +08:00
|
|
|
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 {
|
2024-09-10 17:00:20 +08:00
|
|
|
"__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,
|
2024-04-08 18:51:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
def to_markdown(self) -> str:
|
|
|
|
"""
|
|
|
|
Convert file to markdown
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
preview_url = self.preview_url
|
|
|
|
if self.type == FileType.IMAGE:
|
|
|
|
text = f'![{self.filename or ""}]({preview_url})'
|
|
|
|
else:
|
2024-09-10 17:00:20 +08:00
|
|
|
text = f"[{self.filename or preview_url}]({preview_url})"
|
2024-04-08 18:51:46 +08:00
|
|
|
|
|
|
|
return text
|
2023-11-13 22:05:46 +08:00
|
|
|
|
|
|
|
@property
|
|
|
|
def data(self) -> Optional[str]:
|
2024-04-08 18:51:46 +08:00
|
|
|
"""
|
|
|
|
Get image data, file signed url or base64 data
|
|
|
|
depending on config MULTIMODAL_SEND_IMAGE_FORMAT
|
|
|
|
:return:
|
|
|
|
"""
|
2023-11-13 22:05:46 +08:00
|
|
|
return self._get_data()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def preview_url(self) -> Optional[str]:
|
2024-04-08 18:51:46 +08:00
|
|
|
"""
|
|
|
|
Get signed preview url
|
|
|
|
:return:
|
|
|
|
"""
|
2023-11-13 22:05:46 +08:00
|
|
|
return self._get_data(force_url=True)
|
|
|
|
|
|
|
|
@property
|
2024-01-02 23:42:00 +08:00
|
|
|
def prompt_message_content(self) -> ImagePromptMessageContent:
|
2023-11-13 22:05:46 +08:00
|
|
|
if self.type == FileType.IMAGE:
|
2024-04-08 18:51:46 +08:00
|
|
|
image_config = self.extra_config.image_config
|
2023-11-13 22:05:46 +08:00
|
|
|
|
2024-01-02 23:42:00 +08:00
|
|
|
return ImagePromptMessageContent(
|
2023-11-13 22:05:46 +08:00
|
|
|
data=self.data,
|
2024-01-02 23:42:00 +08:00
|
|
|
detail=ImagePromptMessageContent.DETAIL.HIGH
|
2024-09-10 17:00:20 +08:00
|
|
|
if image_config.get("detail") == "high"
|
|
|
|
else ImagePromptMessageContent.DETAIL.LOW,
|
2023-11-13 22:05:46 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
def _get_data(self, force_url: bool = False) -> Optional[str]:
|
2024-08-13 14:44:10 +08:00
|
|
|
from models.model import UploadFile
|
2024-09-10 17:00:20 +08:00
|
|
|
|
2023-11-13 22:05:46 +08:00
|
|
|
if self.type == FileType.IMAGE:
|
|
|
|
if self.transfer_method == FileTransferMethod.REMOTE_URL:
|
|
|
|
return self.url
|
|
|
|
elif self.transfer_method == FileTransferMethod.LOCAL_FILE:
|
2024-09-10 17:00:20 +08:00
|
|
|
upload_file = (
|
|
|
|
db.session.query(UploadFile)
|
|
|
|
.filter(UploadFile.id == self.related_id, UploadFile.tenant_id == self.tenant_id)
|
|
|
|
.first()
|
2023-11-13 22:05:46 +08:00
|
|
|
)
|
2024-09-10 17:00:20 +08:00
|
|
|
|
|
|
|
return UploadFileParser.get_image_data(upload_file=upload_file, force_url=force_url)
|
2024-04-08 18:51:46 +08:00
|
|
|
elif self.transfer_method == FileTransferMethod.TOOL_FILE:
|
|
|
|
extension = self.extension
|
|
|
|
# add sign url
|
2024-09-10 17:00:20 +08:00
|
|
|
return ToolFileParser.get_tool_file_manager().sign_file(
|
|
|
|
tool_file_id=self.related_id, extension=extension
|
|
|
|
)
|
2023-11-13 22:05:46 +08:00
|
|
|
|
|
|
|
return None
|