Co-authored-by: JzoNg <jzongcode@gmail.com>tags/0.11.0
| BATCH_UPLOAD_LIMIT=10 | BATCH_UPLOAD_LIMIT=10 | ||||
| KEYWORD_DATA_SOURCE_TYPE=database | KEYWORD_DATA_SOURCE_TYPE=database | ||||
| # Workflow file upload limit | |||||
| WORKFLOW_FILE_UPLOAD_LIMIT=10 | |||||
| # CODE EXECUTION CONFIGURATION | # CODE EXECUTION CONFIGURATION | ||||
| CODE_EXECUTION_ENDPOINT=http://127.0.0.1:8194 | CODE_EXECUTION_ENDPOINT=http://127.0.0.1:8194 | ||||
| CODE_EXECUTION_API_KEY=dify-sandbox | CODE_EXECUTION_API_KEY=dify-sandbox |
| default=20, | default=20, | ||||
| ) | ) | ||||
| WORKFLOW_FILE_UPLOAD_LIMIT: PositiveInt = Field( | |||||
| description="Maximum number of files allowed in a workflow upload operation", | |||||
| default=10, | |||||
| ) | |||||
| class HttpConfig(BaseSettings): | class HttpConfig(BaseSettings): | ||||
| """ | """ |
| from flask_restful import fields | |||||
| parameters__system_parameters = { | |||||
| "image_file_size_limit": fields.Integer, | |||||
| "video_file_size_limit": fields.Integer, | |||||
| "audio_file_size_limit": fields.Integer, | |||||
| "file_size_limit": fields.Integer, | |||||
| "workflow_file_upload_limit": fields.Integer, | |||||
| } | |||||
| parameters_fields = { | |||||
| "opening_statement": fields.String, | |||||
| "suggested_questions": fields.Raw, | |||||
| "suggested_questions_after_answer": fields.Raw, | |||||
| "speech_to_text": fields.Raw, | |||||
| "text_to_speech": fields.Raw, | |||||
| "retriever_resource": fields.Raw, | |||||
| "annotation_reply": fields.Raw, | |||||
| "more_like_this": fields.Raw, | |||||
| "user_input_form": fields.Raw, | |||||
| "sensitive_word_avoidance": fields.Raw, | |||||
| "file_upload": fields.Raw, | |||||
| "system_parameters": fields.Nested(parameters__system_parameters), | |||||
| } |
| import os | import os | ||||
| import re | import re | ||||
| import urllib.parse | import urllib.parse | ||||
| from collections.abc import Mapping | |||||
| from typing import Any | |||||
| from uuid import uuid4 | from uuid import uuid4 | ||||
| import httpx | import httpx | ||||
| from pydantic import BaseModel | from pydantic import BaseModel | ||||
| from configs import dify_config | |||||
| class FileInfo(BaseModel): | class FileInfo(BaseModel): | ||||
| filename: str | filename: str | ||||
| mimetype=mimetype, | mimetype=mimetype, | ||||
| size=int(response.headers.get("Content-Length", -1)), | size=int(response.headers.get("Content-Length", -1)), | ||||
| ) | ) | ||||
| def get_parameters_from_feature_dict(*, features_dict: Mapping[str, Any], user_input_form: list[dict[str, Any]]): | |||||
| return { | |||||
| "opening_statement": features_dict.get("opening_statement"), | |||||
| "suggested_questions": features_dict.get("suggested_questions", []), | |||||
| "suggested_questions_after_answer": features_dict.get("suggested_questions_after_answer", {"enabled": False}), | |||||
| "speech_to_text": features_dict.get("speech_to_text", {"enabled": False}), | |||||
| "text_to_speech": features_dict.get("text_to_speech", {"enabled": False}), | |||||
| "retriever_resource": features_dict.get("retriever_resource", {"enabled": False}), | |||||
| "annotation_reply": features_dict.get("annotation_reply", {"enabled": False}), | |||||
| "more_like_this": features_dict.get("more_like_this", {"enabled": False}), | |||||
| "user_input_form": user_input_form, | |||||
| "sensitive_word_avoidance": features_dict.get( | |||||
| "sensitive_word_avoidance", {"enabled": False, "type": "", "configs": []} | |||||
| ), | |||||
| "file_upload": features_dict.get( | |||||
| "file_upload", | |||||
| { | |||||
| "image": { | |||||
| "enabled": False, | |||||
| "number_limits": 3, | |||||
| "detail": "high", | |||||
| "transfer_methods": ["remote_url", "local_file"], | |||||
| } | |||||
| }, | |||||
| ), | |||||
| "system_parameters": { | |||||
| "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | |||||
| "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | |||||
| "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | |||||
| "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, | |||||
| "workflow_file_upload_limit": dify_config.WORKFLOW_FILE_UPLOAD_LIMIT, | |||||
| }, | |||||
| } |
| from flask_restful import fields, marshal_with | |||||
| from flask_restful import marshal_with | |||||
| from configs import dify_config | |||||
| from controllers.common import fields | |||||
| from controllers.common import helpers as controller_helpers | |||||
| from controllers.console import api | from controllers.console import api | ||||
| from controllers.console.app.error import AppUnavailableError | from controllers.console.app.error import AppUnavailableError | ||||
| from controllers.console.explore.wraps import InstalledAppResource | from controllers.console.explore.wraps import InstalledAppResource | ||||
| class AppParameterApi(InstalledAppResource): | class AppParameterApi(InstalledAppResource): | ||||
| """Resource for app variables.""" | """Resource for app variables.""" | ||||
| variable_fields = { | |||||
| "key": fields.String, | |||||
| "name": fields.String, | |||||
| "description": fields.String, | |||||
| "type": fields.String, | |||||
| "default": fields.String, | |||||
| "max_length": fields.Integer, | |||||
| "options": fields.List(fields.String), | |||||
| } | |||||
| system_parameters_fields = { | |||||
| "image_file_size_limit": fields.Integer, | |||||
| "video_file_size_limit": fields.Integer, | |||||
| "audio_file_size_limit": fields.Integer, | |||||
| "file_size_limit": fields.Integer, | |||||
| } | |||||
| parameters_fields = { | |||||
| "opening_statement": fields.String, | |||||
| "suggested_questions": fields.Raw, | |||||
| "suggested_questions_after_answer": fields.Raw, | |||||
| "speech_to_text": fields.Raw, | |||||
| "text_to_speech": fields.Raw, | |||||
| "retriever_resource": fields.Raw, | |||||
| "annotation_reply": fields.Raw, | |||||
| "more_like_this": fields.Raw, | |||||
| "user_input_form": fields.Raw, | |||||
| "sensitive_word_avoidance": fields.Raw, | |||||
| "file_upload": fields.Raw, | |||||
| "system_parameters": fields.Nested(system_parameters_fields), | |||||
| } | |||||
| @marshal_with(parameters_fields) | |||||
| @marshal_with(fields.parameters_fields) | |||||
| def get(self, installed_app: InstalledApp): | def get(self, installed_app: InstalledApp): | ||||
| """Retrieve app parameters.""" | """Retrieve app parameters.""" | ||||
| app_model = installed_app.app | app_model = installed_app.app | ||||
| if app_model is None: | |||||
| raise AppUnavailableError() | |||||
| if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | ||||
| workflow = app_model.workflow | workflow = app_model.workflow | ||||
| if workflow is None: | if workflow is None: | ||||
| user_input_form = workflow.user_input_form(to_old_structure=True) | user_input_form = workflow.user_input_form(to_old_structure=True) | ||||
| else: | else: | ||||
| app_model_config = app_model.app_model_config | app_model_config = app_model.app_model_config | ||||
| if app_model_config is None: | |||||
| raise AppUnavailableError() | |||||
| features_dict = app_model_config.to_dict() | features_dict = app_model_config.to_dict() | ||||
| user_input_form = features_dict.get("user_input_form", []) | user_input_form = features_dict.get("user_input_form", []) | ||||
| return { | |||||
| "opening_statement": features_dict.get("opening_statement"), | |||||
| "suggested_questions": features_dict.get("suggested_questions", []), | |||||
| "suggested_questions_after_answer": features_dict.get( | |||||
| "suggested_questions_after_answer", {"enabled": False} | |||||
| ), | |||||
| "speech_to_text": features_dict.get("speech_to_text", {"enabled": False}), | |||||
| "text_to_speech": features_dict.get("text_to_speech", {"enabled": False}), | |||||
| "retriever_resource": features_dict.get("retriever_resource", {"enabled": False}), | |||||
| "annotation_reply": features_dict.get("annotation_reply", {"enabled": False}), | |||||
| "more_like_this": features_dict.get("more_like_this", {"enabled": False}), | |||||
| "user_input_form": user_input_form, | |||||
| "sensitive_word_avoidance": features_dict.get( | |||||
| "sensitive_word_avoidance", {"enabled": False, "type": "", "configs": []} | |||||
| ), | |||||
| "file_upload": features_dict.get( | |||||
| "file_upload", | |||||
| { | |||||
| "image": { | |||||
| "enabled": False, | |||||
| "number_limits": 3, | |||||
| "detail": "high", | |||||
| "transfer_methods": ["remote_url", "local_file"], | |||||
| } | |||||
| }, | |||||
| ), | |||||
| "system_parameters": { | |||||
| "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | |||||
| "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | |||||
| "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | |||||
| "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, | |||||
| }, | |||||
| } | |||||
| return controller_helpers.get_parameters_from_feature_dict( | |||||
| features_dict=features_dict, user_input_form=user_input_form | |||||
| ) | |||||
| class ExploreAppMetaApi(InstalledAppResource): | class ExploreAppMetaApi(InstalledAppResource): |
| "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | ||||
| "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | ||||
| "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | ||||
| "workflow_file_upload_limit": dify_config.WORKFLOW_FILE_UPLOAD_LIMIT, | |||||
| }, 200 | }, 200 | ||||
| @setup_required | @setup_required |
| from flask_restful import Resource, fields, marshal_with | |||||
| from flask_restful import Resource, marshal_with | |||||
| from configs import dify_config | |||||
| from controllers.common import fields | |||||
| from controllers.common import helpers as controller_helpers | |||||
| from controllers.service_api import api | from controllers.service_api import api | ||||
| from controllers.service_api.app.error import AppUnavailableError | from controllers.service_api.app.error import AppUnavailableError | ||||
| from controllers.service_api.wraps import validate_app_token | from controllers.service_api.wraps import validate_app_token | ||||
| class AppParameterApi(Resource): | class AppParameterApi(Resource): | ||||
| """Resource for app variables.""" | """Resource for app variables.""" | ||||
| variable_fields = { | |||||
| "key": fields.String, | |||||
| "name": fields.String, | |||||
| "description": fields.String, | |||||
| "type": fields.String, | |||||
| "default": fields.String, | |||||
| "max_length": fields.Integer, | |||||
| "options": fields.List(fields.String), | |||||
| } | |||||
| system_parameters_fields = { | |||||
| "image_file_size_limit": fields.Integer, | |||||
| "video_file_size_limit": fields.Integer, | |||||
| "audio_file_size_limit": fields.Integer, | |||||
| "file_size_limit": fields.Integer, | |||||
| } | |||||
| parameters_fields = { | |||||
| "opening_statement": fields.String, | |||||
| "suggested_questions": fields.Raw, | |||||
| "suggested_questions_after_answer": fields.Raw, | |||||
| "speech_to_text": fields.Raw, | |||||
| "text_to_speech": fields.Raw, | |||||
| "retriever_resource": fields.Raw, | |||||
| "annotation_reply": fields.Raw, | |||||
| "more_like_this": fields.Raw, | |||||
| "user_input_form": fields.Raw, | |||||
| "sensitive_word_avoidance": fields.Raw, | |||||
| "file_upload": fields.Raw, | |||||
| "system_parameters": fields.Nested(system_parameters_fields), | |||||
| } | |||||
| @validate_app_token | @validate_app_token | ||||
| @marshal_with(parameters_fields) | |||||
| @marshal_with(fields.parameters_fields) | |||||
| def get(self, app_model: App): | def get(self, app_model: App): | ||||
| """Retrieve app parameters.""" | """Retrieve app parameters.""" | ||||
| if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | ||||
| user_input_form = workflow.user_input_form(to_old_structure=True) | user_input_form = workflow.user_input_form(to_old_structure=True) | ||||
| else: | else: | ||||
| app_model_config = app_model.app_model_config | app_model_config = app_model.app_model_config | ||||
| if app_model_config is None: | |||||
| raise AppUnavailableError() | |||||
| features_dict = app_model_config.to_dict() | features_dict = app_model_config.to_dict() | ||||
| user_input_form = features_dict.get("user_input_form", []) | user_input_form = features_dict.get("user_input_form", []) | ||||
| return { | |||||
| "opening_statement": features_dict.get("opening_statement"), | |||||
| "suggested_questions": features_dict.get("suggested_questions", []), | |||||
| "suggested_questions_after_answer": features_dict.get( | |||||
| "suggested_questions_after_answer", {"enabled": False} | |||||
| ), | |||||
| "speech_to_text": features_dict.get("speech_to_text", {"enabled": False}), | |||||
| "text_to_speech": features_dict.get("text_to_speech", {"enabled": False}), | |||||
| "retriever_resource": features_dict.get("retriever_resource", {"enabled": False}), | |||||
| "annotation_reply": features_dict.get("annotation_reply", {"enabled": False}), | |||||
| "more_like_this": features_dict.get("more_like_this", {"enabled": False}), | |||||
| "user_input_form": user_input_form, | |||||
| "sensitive_word_avoidance": features_dict.get( | |||||
| "sensitive_word_avoidance", {"enabled": False, "type": "", "configs": []} | |||||
| ), | |||||
| "file_upload": features_dict.get( | |||||
| "file_upload", | |||||
| { | |||||
| "image": { | |||||
| "enabled": False, | |||||
| "number_limits": 3, | |||||
| "detail": "high", | |||||
| "transfer_methods": ["remote_url", "local_file"], | |||||
| } | |||||
| }, | |||||
| ), | |||||
| "system_parameters": { | |||||
| "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | |||||
| "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | |||||
| "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | |||||
| "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, | |||||
| }, | |||||
| } | |||||
| return controller_helpers.get_parameters_from_feature_dict( | |||||
| features_dict=features_dict, user_input_form=user_input_form | |||||
| ) | |||||
| class AppMetaApi(Resource): | class AppMetaApi(Resource): |
| from flask_restful import fields, marshal_with | |||||
| from flask_restful import marshal_with | |||||
| from configs import dify_config | |||||
| from controllers.common import fields | |||||
| from controllers.common import helpers as controller_helpers | |||||
| from controllers.web import api | from controllers.web import api | ||||
| from controllers.web.error import AppUnavailableError | from controllers.web.error import AppUnavailableError | ||||
| from controllers.web.wraps import WebApiResource | from controllers.web.wraps import WebApiResource | ||||
| class AppParameterApi(WebApiResource): | class AppParameterApi(WebApiResource): | ||||
| """Resource for app variables.""" | """Resource for app variables.""" | ||||
| variable_fields = { | |||||
| "key": fields.String, | |||||
| "name": fields.String, | |||||
| "description": fields.String, | |||||
| "type": fields.String, | |||||
| "default": fields.String, | |||||
| "max_length": fields.Integer, | |||||
| "options": fields.List(fields.String), | |||||
| } | |||||
| system_parameters_fields = { | |||||
| "image_file_size_limit": fields.Integer, | |||||
| "video_file_size_limit": fields.Integer, | |||||
| "audio_file_size_limit": fields.Integer, | |||||
| "file_size_limit": fields.Integer, | |||||
| } | |||||
| parameters_fields = { | |||||
| "opening_statement": fields.String, | |||||
| "suggested_questions": fields.Raw, | |||||
| "suggested_questions_after_answer": fields.Raw, | |||||
| "speech_to_text": fields.Raw, | |||||
| "text_to_speech": fields.Raw, | |||||
| "retriever_resource": fields.Raw, | |||||
| "annotation_reply": fields.Raw, | |||||
| "more_like_this": fields.Raw, | |||||
| "user_input_form": fields.Raw, | |||||
| "sensitive_word_avoidance": fields.Raw, | |||||
| "file_upload": fields.Raw, | |||||
| "system_parameters": fields.Nested(system_parameters_fields), | |||||
| } | |||||
| @marshal_with(parameters_fields) | |||||
| @marshal_with(fields.parameters_fields) | |||||
| def get(self, app_model: App, end_user): | def get(self, app_model: App, end_user): | ||||
| """Retrieve app parameters.""" | """Retrieve app parameters.""" | ||||
| if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | if app_model.mode in {AppMode.ADVANCED_CHAT.value, AppMode.WORKFLOW.value}: | ||||
| user_input_form = workflow.user_input_form(to_old_structure=True) | user_input_form = workflow.user_input_form(to_old_structure=True) | ||||
| else: | else: | ||||
| app_model_config = app_model.app_model_config | app_model_config = app_model.app_model_config | ||||
| if app_model_config is None: | |||||
| raise AppUnavailableError() | |||||
| features_dict = app_model_config.to_dict() | features_dict = app_model_config.to_dict() | ||||
| user_input_form = features_dict.get("user_input_form", []) | user_input_form = features_dict.get("user_input_form", []) | ||||
| return { | |||||
| "opening_statement": features_dict.get("opening_statement"), | |||||
| "suggested_questions": features_dict.get("suggested_questions", []), | |||||
| "suggested_questions_after_answer": features_dict.get( | |||||
| "suggested_questions_after_answer", {"enabled": False} | |||||
| ), | |||||
| "speech_to_text": features_dict.get("speech_to_text", {"enabled": False}), | |||||
| "text_to_speech": features_dict.get("text_to_speech", {"enabled": False}), | |||||
| "retriever_resource": features_dict.get("retriever_resource", {"enabled": False}), | |||||
| "annotation_reply": features_dict.get("annotation_reply", {"enabled": False}), | |||||
| "more_like_this": features_dict.get("more_like_this", {"enabled": False}), | |||||
| "user_input_form": user_input_form, | |||||
| "sensitive_word_avoidance": features_dict.get( | |||||
| "sensitive_word_avoidance", {"enabled": False, "type": "", "configs": []} | |||||
| ), | |||||
| "file_upload": features_dict.get( | |||||
| "file_upload", | |||||
| { | |||||
| "image": { | |||||
| "enabled": False, | |||||
| "number_limits": 3, | |||||
| "detail": "high", | |||||
| "transfer_methods": ["remote_url", "local_file"], | |||||
| } | |||||
| }, | |||||
| ), | |||||
| "system_parameters": { | |||||
| "image_file_size_limit": dify_config.UPLOAD_IMAGE_FILE_SIZE_LIMIT, | |||||
| "video_file_size_limit": dify_config.UPLOAD_VIDEO_FILE_SIZE_LIMIT, | |||||
| "audio_file_size_limit": dify_config.UPLOAD_AUDIO_FILE_SIZE_LIMIT, | |||||
| "file_size_limit": dify_config.UPLOAD_FILE_SIZE_LIMIT, | |||||
| }, | |||||
| } | |||||
| return controller_helpers.get_parameters_from_feature_dict( | |||||
| features_dict=features_dict, user_input_form=user_input_form | |||||
| ) | |||||
| class AppMeta(WebApiResource): | class AppMeta(WebApiResource): |
| from collections.abc import Mapping | from collections.abc import Mapping | ||||
| from typing import Any | from typing import Any | ||||
| from core.file.models import FileExtraConfig | |||||
| from models import FileUploadConfig | |||||
| from core.file import FileExtraConfig | |||||
| class FileUploadConfigManager: | class FileUploadConfigManager: | ||||
| if not config.get("file_upload"): | if not config.get("file_upload"): | ||||
| config["file_upload"] = {} | config["file_upload"] = {} | ||||
| else: | else: | ||||
| FileUploadConfig.model_validate(config["file_upload"]) | |||||
| FileExtraConfig.model_validate(config["file_upload"]) | |||||
| return config, ["file_upload"] | return config, ["file_upload"] |
| "image_file_size_limit": fields.Integer, | "image_file_size_limit": fields.Integer, | ||||
| "video_file_size_limit": fields.Integer, | "video_file_size_limit": fields.Integer, | ||||
| "audio_file_size_limit": fields.Integer, | "audio_file_size_limit": fields.Integer, | ||||
| "workflow_file_upload_limit": fields.Integer, | |||||
| } | } | ||||
| file_fields = { | file_fields = { |
| AppMode, | AppMode, | ||||
| Conversation, | Conversation, | ||||
| EndUser, | EndUser, | ||||
| FileUploadConfig, | |||||
| InstalledApp, | InstalledApp, | ||||
| Message, | Message, | ||||
| MessageAnnotation, | MessageAnnotation, | ||||
| "Tenant", | "Tenant", | ||||
| "Conversation", | "Conversation", | ||||
| "MessageAnnotation", | "MessageAnnotation", | ||||
| "FileUploadConfig", | |||||
| "ToolFile", | "ToolFile", | ||||
| ] | ] |
| import json | import json | ||||
| import re | import re | ||||
| import uuid | import uuid | ||||
| from collections.abc import Mapping, Sequence | |||||
| from collections.abc import Mapping | |||||
| from datetime import datetime | from datetime import datetime | ||||
| from enum import Enum | from enum import Enum | ||||
| from typing import Any, Literal, Optional | from typing import Any, Literal, Optional | ||||
| import sqlalchemy as sa | import sqlalchemy as sa | ||||
| from flask import request | from flask import request | ||||
| from flask_login import UserMixin | from flask_login import UserMixin | ||||
| from pydantic import BaseModel, Field | |||||
| from sqlalchemy import Float, func, text | from sqlalchemy import Float, func, text | ||||
| from sqlalchemy.orm import Mapped, mapped_column | from sqlalchemy.orm import Mapped, mapped_column | ||||
| from .types import StringUUID | from .types import StringUUID | ||||
| class FileUploadConfig(BaseModel): | |||||
| enabled: bool = Field(default=False) | |||||
| allowed_file_types: Sequence[FileType] = Field(default_factory=list) | |||||
| allowed_extensions: Sequence[str] = Field(default_factory=list) | |||||
| allowed_upload_methods: Sequence[FileTransferMethod] = Field(default_factory=list) | |||||
| number_limits: int = Field(default=0, gt=0, le=10) | |||||
| class DifySetup(db.Model): | class DifySetup(db.Model): | ||||
| __tablename__ = "dify_setups" | __tablename__ = "dify_setups" | ||||
| __table_args__ = (db.PrimaryKeyConstraint("version", name="dify_setup_pkey"),) | __table_args__ = (db.PrimaryKeyConstraint("version", name="dify_setup_pkey"),) | ||||
| return site | return site | ||||
| @property | @property | ||||
| def app_model_config(self) -> Optional["AppModelConfig"]: | |||||
| def app_model_config(self): | |||||
| if self.app_model_config_id: | if self.app_model_config_id: | ||||
| return db.session.query(AppModelConfig).filter(AppModelConfig.id == self.app_model_config_id).first() | return db.session.query(AppModelConfig).filter(AppModelConfig.id == self.app_model_config_id).first() | ||||
| WORKFLOW_MAX_EXECUTION_TIME=1200 | WORKFLOW_MAX_EXECUTION_TIME=1200 | ||||
| WORKFLOW_CALL_MAX_DEPTH=5 | WORKFLOW_CALL_MAX_DEPTH=5 | ||||
| MAX_VARIABLE_SIZE=204800 | MAX_VARIABLE_SIZE=204800 | ||||
| WORKFLOW_FILE_UPLOAD_LIMIT=10 | |||||
| # HTTP request node in workflow configuration | # HTTP request node in workflow configuration | ||||
| HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760 | HTTP_REQUEST_NODE_MAX_BINARY_SIZE=10485760 |
| x-shared-env: &shared-api-worker-env | x-shared-env: &shared-api-worker-env | ||||
| WORKFLOW_FILE_UPLOAD_LIMIT: ${WORKFLOW_FILE_UPLOAD_LIMIT:-10} | |||||
| LOG_LEVEL: ${LOG_LEVEL:-INFO} | LOG_LEVEL: ${LOG_LEVEL:-INFO} | ||||
| LOG_FILE: ${LOG_FILE:-} | LOG_FILE: ${LOG_FILE:-} | ||||
| LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20} | LOG_FILE_MAX_SIZE: ${LOG_FILE_MAX_SIZE:-20} |
| export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 | export const FILE_SIZE_LIMIT = 15 * 1024 * 1024 | ||||
| export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024 | export const AUDIO_SIZE_LIMIT = 50 * 1024 * 1024 | ||||
| export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024 | export const VIDEO_SIZE_LIMIT = 100 * 1024 * 1024 | ||||
| export const MAX_FILE_UPLOAD_LIMIT = 10 | |||||
| export const FILE_URL_REGEX = /^(https?|ftp):\/\// | export const FILE_URL_REGEX = /^(https?|ftp):\/\// |
| AUDIO_SIZE_LIMIT, | AUDIO_SIZE_LIMIT, | ||||
| FILE_SIZE_LIMIT, | FILE_SIZE_LIMIT, | ||||
| IMG_SIZE_LIMIT, | IMG_SIZE_LIMIT, | ||||
| MAX_FILE_UPLOAD_LIMIT, | |||||
| VIDEO_SIZE_LIMIT, | VIDEO_SIZE_LIMIT, | ||||
| } from '@/app/components/base/file-uploader/constants' | } from '@/app/components/base/file-uploader/constants' | ||||
| import { useToastContext } from '@/app/components/base/toast' | import { useToastContext } from '@/app/components/base/toast' | ||||
| const docSizeLimit = Number(fileUploadConfig?.file_size_limit) * 1024 * 1024 || FILE_SIZE_LIMIT | const docSizeLimit = Number(fileUploadConfig?.file_size_limit) * 1024 * 1024 || FILE_SIZE_LIMIT | ||||
| const audioSizeLimit = Number(fileUploadConfig?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT | const audioSizeLimit = Number(fileUploadConfig?.audio_file_size_limit) * 1024 * 1024 || AUDIO_SIZE_LIMIT | ||||
| const videoSizeLimit = Number(fileUploadConfig?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT | const videoSizeLimit = Number(fileUploadConfig?.video_file_size_limit) * 1024 * 1024 || VIDEO_SIZE_LIMIT | ||||
| const maxFileUploadLimit = Number(fileUploadConfig?.workflow_file_upload_limit) || MAX_FILE_UPLOAD_LIMIT | |||||
| return { | return { | ||||
| imgSizeLimit, | imgSizeLimit, | ||||
| docSizeLimit, | docSizeLimit, | ||||
| audioSizeLimit, | audioSizeLimit, | ||||
| videoSizeLimit, | videoSizeLimit, | ||||
| maxFileUploadLimit, | |||||
| } | } | ||||
| } | } | ||||
| allowed_file_extensions, | allowed_file_extensions, | ||||
| } = payload | } = payload | ||||
| const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) | const { data: fileUploadConfigResponse } = useSWR({ url: '/files/upload' }, fetchFileUploadConfig) | ||||
| const { imgSizeLimit, docSizeLimit, audioSizeLimit, videoSizeLimit } = useFileSizeLimit(fileUploadConfigResponse) | |||||
| const { | |||||
| imgSizeLimit, | |||||
| docSizeLimit, | |||||
| audioSizeLimit, | |||||
| videoSizeLimit, | |||||
| maxFileUploadLimit, | |||||
| } = useFileSizeLimit(fileUploadConfigResponse) | |||||
| const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { | const handleSupportFileTypeChange = useCallback((type: SupportUploadFileTypes) => { | ||||
| const newPayload = produce(payload, (draft) => { | const newPayload = produce(payload, (draft) => { | ||||
| <InputNumberWithSlider | <InputNumberWithSlider | ||||
| value={max_length} | value={max_length} | ||||
| min={1} | min={1} | ||||
| max={10} | |||||
| max={maxFileUploadLimit} | |||||
| onChange={handleMaxUploadNumLimitChange} | onChange={handleMaxUploadNumLimitChange} | ||||
| /> | /> | ||||
| </div> | </div> |
| file_size_limit: number // default is 15MB | file_size_limit: number // default is 15MB | ||||
| audio_file_size_limit?: number // default is 50MB | audio_file_size_limit?: number // default is 50MB | ||||
| video_file_size_limit?: number // default is 100MB | video_file_size_limit?: number // default is 100MB | ||||
| workflow_file_upload_limit?: number // default is 10 | |||||
| } | } | ||||
| export type InvitationResult = { | export type InvitationResult = { |