mirror of
https://github.com/langgenius/dify.git
synced 2026-01-26 13:42:34 +08:00
refactor: rename new runtime as sandbox feature
This commit is contained in:
parent
3d2840edb6
commit
9dd0361d0e
@ -41,6 +41,7 @@ from factories import file_factory
|
||||
from libs.flask_utils import preserve_flask_contexts
|
||||
from models import Account, App, Conversation, EndUser, Message, Workflow, WorkflowNodeExecutionTriggeredFrom
|
||||
from models.enums import WorkflowRunTriggeredFrom
|
||||
from models.workflow_features import WorkflowFeatures
|
||||
from services.conversation_service import ConversationService
|
||||
from services.workflow_draft_variable_service import (
|
||||
DraftVarLoader,
|
||||
@ -513,10 +514,8 @@ class AdvancedChatAppGenerator(MessageBasedAppGenerator):
|
||||
if workflow is None:
|
||||
raise ValueError("Workflow not found")
|
||||
|
||||
# FIXME:(sandbox) Consolidate runtime config checking into a unified location.
|
||||
runtime = workflow.features_dict.get("runtime")
|
||||
graph_engine_layers: tuple = ()
|
||||
if isinstance(runtime, dict) and runtime.get("enabled"):
|
||||
if workflow.get_feature(WorkflowFeatures.SANDBOX).enabled:
|
||||
graph_engine_layers = (SandboxLayer(tenant_id=application_generate_entity.app_config.tenant_id),)
|
||||
|
||||
# Determine system_user_id based on invocation source
|
||||
|
||||
@ -38,6 +38,7 @@ from factories import file_factory
|
||||
from libs.flask_utils import preserve_flask_contexts
|
||||
from models import Account, App, EndUser, Workflow, WorkflowNodeExecutionTriggeredFrom
|
||||
from models.enums import WorkflowRunTriggeredFrom
|
||||
from models.workflow_features import WorkflowFeatures
|
||||
from services.workflow_draft_variable_service import DraftVarLoader, WorkflowDraftVariableService
|
||||
|
||||
SKIP_PREPARE_USER_INPUTS_KEY = "_skip_prepare_user_inputs"
|
||||
@ -488,9 +489,7 @@ class WorkflowAppGenerator(BaseAppGenerator):
|
||||
if workflow is None:
|
||||
raise ValueError("Workflow not found")
|
||||
|
||||
# FIXME:(sandbox) Consolidate runtime config checking into a unified location.
|
||||
runtime = workflow.features_dict.get("runtime")
|
||||
if isinstance(runtime, dict) and runtime.get("enabled"):
|
||||
if workflow.get_feature(WorkflowFeatures.SANDBOX).enabled:
|
||||
graph_engine_layers = (
|
||||
*graph_engine_layers,
|
||||
SandboxLayer(tenant_id=application_generate_entity.app_config.tenant_id),
|
||||
|
||||
@ -109,6 +109,7 @@ from .workflow import (
|
||||
WorkflowRun,
|
||||
WorkflowType,
|
||||
)
|
||||
from .workflow_features import WorkflowFeature, WorkflowFeatures
|
||||
|
||||
__all__ = [
|
||||
"APIBasedExtension",
|
||||
@ -202,6 +203,8 @@ __all__ = [
|
||||
"Workflow",
|
||||
"WorkflowAppLog",
|
||||
"WorkflowAppLogCreatedFrom",
|
||||
"WorkflowFeature",
|
||||
"WorkflowFeatures",
|
||||
"WorkflowNodeExecutionModel",
|
||||
"WorkflowNodeExecutionOffload",
|
||||
"WorkflowNodeExecutionTriggeredFrom",
|
||||
|
||||
@ -37,13 +37,13 @@ from extensions.ext_storage import Storage
|
||||
from factories.variable_factory import TypeMismatchError, build_segment_with_type
|
||||
from libs.datetime_utils import naive_utc_now
|
||||
from libs.uuid_utils import uuidv7
|
||||
from models.workflow_features import WorkflowFeature, WorkflowFeatures
|
||||
|
||||
from ._workflow_exc import NodeNotFoundError, WorkflowDataError
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .model import AppMode, UploadFile
|
||||
|
||||
|
||||
from constants import DEFAULT_FILE_NUMBER_LIMITS, HIDDEN_VALUE
|
||||
from core.helper import encrypter
|
||||
from core.variables import SecretVariable, Segment, SegmentType, Variable
|
||||
@ -345,6 +345,9 @@ class Workflow(Base): # bug
|
||||
def features_dict(self) -> dict[str, Any]:
|
||||
return json.loads(self.features) if self.features else {}
|
||||
|
||||
def get_feature(self, key: WorkflowFeatures) -> WorkflowFeature:
|
||||
return WorkflowFeature.from_dict(self.features_dict.get(key.value))
|
||||
|
||||
def walk_nodes(
|
||||
self, specific_node_type: NodeType | None = None
|
||||
) -> Generator[tuple[str, Mapping[str, Any]], None, None]:
|
||||
|
||||
26
api/models/workflow_features.py
Normal file
26
api/models/workflow_features.py
Normal file
@ -0,0 +1,26 @@
|
||||
from collections.abc import Mapping
|
||||
from dataclasses import dataclass
|
||||
from enum import StrEnum
|
||||
from typing import Any
|
||||
|
||||
|
||||
class WorkflowFeatures(StrEnum):
|
||||
SANDBOX = "sandbox"
|
||||
SPEECH_TO_TEXT = "speech_to_text"
|
||||
TEXT_TO_SPEECH = "text_to_speech"
|
||||
RETRIEVER_RESOURCE = "retriever_resource"
|
||||
SENSITIVE_WORD_AVOIDANCE = "sensitive_word_avoidance"
|
||||
FILE_UPLOAD = "file_upload"
|
||||
SUGGESTED_QUESTIONS_AFTER_ANSWER = "suggested_questions_after_answer"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class WorkflowFeature:
|
||||
enabled: bool
|
||||
config: Mapping[str, Any]
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, data: Mapping[str, Any] | None) -> "WorkflowFeature":
|
||||
if data is None or not isinstance(data, dict):
|
||||
return cls(enabled=False, config={})
|
||||
return cls(enabled=bool(data.get("enabled", False)), config=data)
|
||||
@ -38,6 +38,7 @@ from models import Account
|
||||
from models.model import App, AppMode
|
||||
from models.tools import WorkflowToolProvider
|
||||
from models.workflow import Workflow, WorkflowNodeExecutionModel, WorkflowNodeExecutionTriggeredFrom, WorkflowType
|
||||
from models.workflow_features import WorkflowFeatures
|
||||
from repositories.factory import DifyAPIRepositoryFactory
|
||||
from services.billing_service import BillingService
|
||||
from services.enterprise.plugin_manager_service import PluginCredentialType
|
||||
@ -697,11 +698,9 @@ class WorkflowService:
|
||||
else:
|
||||
enclosing_node_id = None
|
||||
|
||||
# TODO: Consolidate runtime config checking into a unified location.
|
||||
runtime = draft_workflow.features_dict.get("runtime")
|
||||
sandbox = None
|
||||
single_step_execution_id: str | None = None
|
||||
if isinstance(runtime, dict) and runtime.get("enabled"):
|
||||
if draft_workflow.get_feature(WorkflowFeatures.SANDBOX).enabled:
|
||||
sandbox = SandboxProviderService.create_sandbox(tenant_id=draft_workflow.tenant_id)
|
||||
single_step_execution_id = f"single-step-{uuid.uuid4()}"
|
||||
from core.virtual_environment.sandbox_manager import SandboxManager
|
||||
|
||||
@ -54,7 +54,7 @@ export const createFeaturesStore = (initProps?: Partial<FeaturesState>) => {
|
||||
annotationReply: {
|
||||
enabled: false,
|
||||
},
|
||||
runtime: {
|
||||
sandbox: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
|
||||
@ -91,7 +91,7 @@ export enum FeatureEnum {
|
||||
moderation = 'moderation',
|
||||
file = 'file',
|
||||
annotationReply = 'annotationReply',
|
||||
runtime = 'runtime',
|
||||
sandbox = 'sandbox',
|
||||
}
|
||||
|
||||
export type Features = {
|
||||
@ -104,7 +104,7 @@ export type Features = {
|
||||
[FeatureEnum.moderation]?: SensitiveWordAvoidance
|
||||
[FeatureEnum.file]?: FileUpload
|
||||
[FeatureEnum.annotationReply]?: AnnotationReplyConfig
|
||||
[FeatureEnum.runtime]?: Runtime
|
||||
[FeatureEnum.sandbox]?: Runtime
|
||||
}
|
||||
|
||||
export type OnFeaturesChange = (features?: Features) => void
|
||||
|
||||
@ -71,7 +71,7 @@ export const useNodesSyncDraft = () => {
|
||||
retriever_resource: features.citation,
|
||||
sensitive_word_avoidance: features.moderation,
|
||||
file_upload: features.file,
|
||||
runtime: features.runtime,
|
||||
sandbox: features.sandbox,
|
||||
},
|
||||
environment_variables: environmentVariables,
|
||||
conversation_variables: conversationVariables,
|
||||
|
||||
@ -99,7 +99,7 @@ export const useWorkflowInit = () => {
|
||||
},
|
||||
features: {
|
||||
retriever_resource: { enabled: true },
|
||||
runtime: { enabled: enableSandboxRuntime },
|
||||
sandbox: { enabled: enableSandboxRuntime },
|
||||
},
|
||||
environment_variables: [],
|
||||
conversation_variables: [],
|
||||
|
||||
@ -748,7 +748,7 @@ export const useWorkflowRun = () => {
|
||||
citation: publishedWorkflow.features.retriever_resource,
|
||||
moderation: publishedWorkflow.features.sensitive_word_avoidance,
|
||||
file: publishedWorkflow.features.file_upload,
|
||||
runtime: publishedWorkflow.features.runtime || { enabled: false },
|
||||
sandbox: publishedWorkflow.features.sandbox || { enabled: false },
|
||||
}
|
||||
|
||||
featuresStore?.setState({ features: mappedFeatures })
|
||||
|
||||
@ -192,7 +192,7 @@ const WorkflowAppWithAdditionalContext = () => {
|
||||
text2speech: features.text_to_speech || { enabled: false },
|
||||
citation: features.retriever_resource || { enabled: false },
|
||||
moderation: features.sensitive_word_avoidance || { enabled: false },
|
||||
runtime: features.runtime || { enabled: false },
|
||||
sandbox: features.sandbox || { enabled: false },
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@ -121,7 +121,7 @@ const UpdateDSLModal = ({
|
||||
text2speech: features.text_to_speech || { enabled: false },
|
||||
citation: features.retriever_resource || { enabled: false },
|
||||
moderation: features.sensitive_word_avoidance || { enabled: false },
|
||||
runtime: features.runtime || { enabled: false },
|
||||
sandbox: features.sandbox || { enabled: false },
|
||||
}
|
||||
|
||||
eventEmitter?.emit({
|
||||
|
||||
Loading…
Reference in New Issue
Block a user