mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
Merge remote-tracking branch 'origin/feat/r2' into feat/r2
This commit is contained in:
@ -3,8 +3,8 @@ import re
|
||||
import uuid
|
||||
from collections.abc import Mapping
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from enum import Enum, StrEnum
|
||||
from typing import TYPE_CHECKING, Any, Literal, Optional, cast
|
||||
|
||||
from core.plugin.entities.plugin import GenericProviderID
|
||||
from core.tools.entities.tool_entities import ToolProviderType
|
||||
@ -13,9 +13,6 @@ from services.plugin.plugin_service import PluginService
|
||||
if TYPE_CHECKING:
|
||||
from models.workflow import Workflow
|
||||
|
||||
from enum import StrEnum
|
||||
from typing import TYPE_CHECKING, Any, Literal, cast
|
||||
|
||||
import sqlalchemy as sa
|
||||
from flask import request
|
||||
from flask_login import UserMixin # type: ignore
|
||||
@ -23,6 +20,7 @@ from sqlalchemy import Float, Index, PrimaryKeyConstraint, func, text
|
||||
from sqlalchemy.orm import Mapped, Session, mapped_column
|
||||
|
||||
from configs import dify_config
|
||||
from constants import DEFAULT_FILE_NUMBER_LIMITS
|
||||
from core.file import FILE_MODEL_IDENTITY, File, FileTransferMethod, FileType
|
||||
from core.file import helpers as file_helpers
|
||||
from core.file.tool_file_parser import ToolFileParser
|
||||
@ -442,7 +440,7 @@ class AppModelConfig(Base):
|
||||
else {
|
||||
"image": {
|
||||
"enabled": False,
|
||||
"number_limits": 3,
|
||||
"number_limits": DEFAULT_FILE_NUMBER_LIMITS,
|
||||
"detail": "high",
|
||||
"transfer_methods": ["remote_url", "local_file"],
|
||||
}
|
||||
@ -1090,12 +1088,7 @@ class Message(db.Model): # type: ignore[name-defined]
|
||||
|
||||
@property
|
||||
def retriever_resources(self):
|
||||
return (
|
||||
db.session.query(DatasetRetrieverResource)
|
||||
.filter(DatasetRetrieverResource.message_id == self.id)
|
||||
.order_by(DatasetRetrieverResource.position.asc())
|
||||
.all()
|
||||
)
|
||||
return self.message_metadata_dict.get("retriever_resources") if self.message_metadata else []
|
||||
|
||||
@property
|
||||
def message_files(self):
|
||||
@ -1154,7 +1147,7 @@ class Message(db.Model): # type: ignore[name-defined]
|
||||
files.append(file)
|
||||
|
||||
result = [
|
||||
{"belongs_to": message_file.belongs_to, **file.to_dict()}
|
||||
{"belongs_to": message_file.belongs_to, "upload_file_id": message_file.upload_file_id, **file.to_dict()}
|
||||
for (file, message_file) in zip(files, message_files)
|
||||
]
|
||||
|
||||
|
||||
@ -1,21 +1,19 @@
|
||||
import json
|
||||
from collections.abc import Mapping, Sequence
|
||||
from datetime import UTC, datetime
|
||||
from enum import Enum
|
||||
from enum import Enum, StrEnum
|
||||
from typing import TYPE_CHECKING, Any, Optional, Self, Union
|
||||
from uuid import uuid4
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from models.model import AppMode
|
||||
from enum import StrEnum
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy import Index, PrimaryKeyConstraint, func
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
import contexts
|
||||
from constants import HIDDEN_VALUE
|
||||
from constants import DEFAULT_FILE_NUMBER_LIMITS, HIDDEN_VALUE
|
||||
from core.helper import encrypter
|
||||
from core.variables import SecretVariable, Variable
|
||||
from factories import variable_factory
|
||||
@ -39,7 +37,7 @@ class WorkflowType(Enum):
|
||||
WORKFLOW = "workflow"
|
||||
CHAT = "chat"
|
||||
RAG_PIPELINE = "rag_pipeline"
|
||||
|
||||
|
||||
@classmethod
|
||||
def value_of(cls, value: str) -> "WorkflowType":
|
||||
"""
|
||||
@ -190,7 +188,7 @@ class Workflow(Base):
|
||||
features = json.loads(self._features)
|
||||
if features.get("file_upload", {}).get("image", {}).get("enabled", False):
|
||||
image_enabled = True
|
||||
image_number_limits = int(features["file_upload"]["image"].get("number_limits", 1))
|
||||
image_number_limits = int(features["file_upload"]["image"].get("number_limits", DEFAULT_FILE_NUMBER_LIMITS))
|
||||
image_transfer_methods = features["file_upload"]["image"].get(
|
||||
"transfer_methods", ["remote_url", "local_file"]
|
||||
)
|
||||
@ -249,6 +247,13 @@ class Workflow(Base):
|
||||
|
||||
@property
|
||||
def tool_published(self) -> bool:
|
||||
"""
|
||||
DEPRECATED: This property is not accurate for determining if a workflow is published as a tool.
|
||||
It only checks if there's a WorkflowToolProvider for the app, not if this specific workflow version
|
||||
is the one being used by the tool.
|
||||
|
||||
For accurate checking, use a direct query with tenant_id, app_id, and version.
|
||||
"""
|
||||
from models.tools import WorkflowToolProvider
|
||||
|
||||
return (
|
||||
@ -365,6 +370,7 @@ class Workflow(Base):
|
||||
ensure_ascii=False,
|
||||
)
|
||||
|
||||
|
||||
class WorkflowRunStatus(StrEnum):
|
||||
"""
|
||||
Workflow Run Status Enum
|
||||
@ -532,7 +538,7 @@ class WorkflowRun(Base):
|
||||
)
|
||||
|
||||
|
||||
class WorkflowNodeExecutionTriggeredFrom(Enum):
|
||||
class WorkflowNodeExecutionTriggeredFrom(StrEnum):
|
||||
"""
|
||||
Workflow Node Execution Triggered From Enum
|
||||
"""
|
||||
@ -540,21 +546,8 @@ class WorkflowNodeExecutionTriggeredFrom(Enum):
|
||||
SINGLE_STEP = "single-step"
|
||||
WORKFLOW_RUN = "workflow-run"
|
||||
|
||||
@classmethod
|
||||
def value_of(cls, value: str) -> "WorkflowNodeExecutionTriggeredFrom":
|
||||
"""
|
||||
Get value of given mode.
|
||||
|
||||
:param value: mode value
|
||||
:return: mode
|
||||
"""
|
||||
for mode in cls:
|
||||
if mode.value == value:
|
||||
return mode
|
||||
raise ValueError(f"invalid workflow node execution triggered from value {value}")
|
||||
|
||||
|
||||
class WorkflowNodeExecutionStatus(Enum):
|
||||
class WorkflowNodeExecutionStatus(StrEnum):
|
||||
"""
|
||||
Workflow Node Execution Status Enum
|
||||
"""
|
||||
@ -565,19 +558,6 @@ class WorkflowNodeExecutionStatus(Enum):
|
||||
EXCEPTION = "exception"
|
||||
RETRY = "retry"
|
||||
|
||||
@classmethod
|
||||
def value_of(cls, value: str) -> "WorkflowNodeExecutionStatus":
|
||||
"""
|
||||
Get value of given mode.
|
||||
|
||||
:param value: mode value
|
||||
:return: mode
|
||||
"""
|
||||
for mode in cls:
|
||||
if mode.value == value:
|
||||
return mode
|
||||
raise ValueError(f"invalid workflow node execution status value {value}")
|
||||
|
||||
|
||||
class WorkflowNodeExecution(Base):
|
||||
"""
|
||||
@ -678,6 +658,7 @@ class WorkflowNodeExecution(Base):
|
||||
@property
|
||||
def created_by_account(self):
|
||||
created_by_role = CreatedByRole(self.created_by_role)
|
||||
# TODO(-LAN-): Avoid using db.session.get() here.
|
||||
return db.session.get(Account, self.created_by) if created_by_role == CreatedByRole.ACCOUNT else None
|
||||
|
||||
@property
|
||||
@ -685,6 +666,7 @@ class WorkflowNodeExecution(Base):
|
||||
from models.model import EndUser
|
||||
|
||||
created_by_role = CreatedByRole(self.created_by_role)
|
||||
# TODO(-LAN-): Avoid using db.session.get() here.
|
||||
return db.session.get(EndUser, self.created_by) if created_by_role == CreatedByRole.END_USER else None
|
||||
|
||||
@property
|
||||
|
||||
Reference in New Issue
Block a user