mirror of
https://github.com/langgenius/dify.git
synced 2026-05-05 01:48:04 +08:00
feat(sandbox): enhance sandbox management and tool artifact handling
- Introduced SandboxManager.delete_storage method for improved storage management. - Refactored skill loading and tool artifact handling in DifyCliInitializer and SandboxBashSession. - Updated LLMNode to extract and compile tool artifacts, enhancing integration with skills. - Improved attribute management in AttrMap for better error handling and retrieval methods.
This commit is contained in:
@ -8,7 +8,6 @@ from types import TracebackType
|
||||
from core.sandbox.sandbox import Sandbox
|
||||
from core.session.cli_api import CliApiSession, CliApiSessionManager
|
||||
from core.skill.entities.tool_artifact import ToolArtifact
|
||||
from core.skill.skill_manager import SkillManager
|
||||
from core.virtual_environment.__base.helpers import pipeline
|
||||
|
||||
from ..bash.dify_cli import DifyCliConfig
|
||||
@ -19,17 +18,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SandboxBashSession:
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
sandbox: Sandbox,
|
||||
node_id: str,
|
||||
allow_tools: list[tuple[str, str]] | None,
|
||||
) -> None:
|
||||
def __init__(self, *, sandbox: Sandbox, node_id: str, tools: ToolArtifact | None) -> None:
|
||||
self._sandbox = sandbox
|
||||
self._node_id = node_id
|
||||
self._allow_tools = allow_tools
|
||||
|
||||
self._tools = tools
|
||||
self._bash_tool: SandboxBashTool | None = None
|
||||
self._cli_api_session: CliApiSession | None = None
|
||||
self._tenant_id = sandbox.tenant_id
|
||||
@ -42,8 +34,8 @@ class SandboxBashSession:
|
||||
tenant_id=self._tenant_id,
|
||||
user_id=self._user_id,
|
||||
)
|
||||
if self._allow_tools is not None:
|
||||
tools_path = self._setup_node_tools_directory(self._node_id, self._allow_tools, self._cli_api_session)
|
||||
if self._tools is not None and not self._tools.is_empty():
|
||||
tools_path = self._setup_node_tools_directory(self._node_id, self._tools, self._cli_api_session)
|
||||
else:
|
||||
tools_path = DifyCli.GLOBAL_TOOLS_PATH
|
||||
|
||||
@ -57,24 +49,9 @@ class SandboxBashSession:
|
||||
def _setup_node_tools_directory(
|
||||
self,
|
||||
node_id: str,
|
||||
allow_tools: list[tuple[str, str]],
|
||||
tools: ToolArtifact,
|
||||
cli_api_session: CliApiSession,
|
||||
) -> str | None:
|
||||
artifact: ToolArtifact | None = SkillManager.load_tool_artifact(
|
||||
self._sandbox.tenant_id,
|
||||
self._app_id,
|
||||
self._assets_id,
|
||||
)
|
||||
|
||||
if artifact is None or artifact.is_empty():
|
||||
logger.info("No tools found in artifact for assets_id=%s", self._assets_id)
|
||||
return None
|
||||
|
||||
artifact = artifact.filter(allow_tools)
|
||||
if artifact.is_empty():
|
||||
logger.info("No tools found in artifact for assets_id=%s", self._assets_id)
|
||||
return None
|
||||
|
||||
node_tools_path = f"{DifyCli.TOOLS_ROOT}/{node_id}"
|
||||
|
||||
vm = self._sandbox.vm
|
||||
@ -86,7 +63,7 @@ class SandboxBashSession:
|
||||
)
|
||||
|
||||
config_json = json.dumps(
|
||||
DifyCliConfig.create(session=cli_api_session, tenant_id=self._tenant_id, artifact=artifact).model_dump(
|
||||
DifyCliConfig.create(session=cli_api_session, tenant_id=self._tenant_id, artifact=tools).model_dump(
|
||||
mode="json"
|
||||
),
|
||||
ensure_ascii=False,
|
||||
@ -98,7 +75,7 @@ class SandboxBashSession:
|
||||
).execute(raise_on_error=True)
|
||||
|
||||
logger.info(
|
||||
"Node %s tools initialized, path=%s, tool_count=%d", node_id, node_tools_path, len(artifact.references)
|
||||
"Node %s tools initialized, path=%s, tool_count=%d", node_id, node_tools_path, len(tools.references)
|
||||
)
|
||||
return node_tools_path
|
||||
|
||||
|
||||
@ -60,8 +60,8 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
|
||||
logger.info("Dify CLI uploaded to sandbox, path=%s", DifyCli.PATH)
|
||||
|
||||
artifact = SkillManager.load_tool_artifact(self._tenant_id, self._app_id, self._assets_id)
|
||||
if artifact is None or not artifact.references:
|
||||
artifact = SkillManager.load_artifact(self._tenant_id, self._app_id, self._assets_id)
|
||||
if artifact is None or not artifact.get_tool_artifact().is_empty:
|
||||
logger.info("No tools found in artifact for assets_id=%s", self._assets_id)
|
||||
return
|
||||
|
||||
@ -72,7 +72,7 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
["mkdir", "-p", DifyCli.GLOBAL_TOOLS_PATH], error_message="Failed to create global tools dir"
|
||||
).execute(raise_on_error=True)
|
||||
|
||||
config = DifyCliConfig.create(self._cli_api_session, self._tenant_id, artifact)
|
||||
config = DifyCliConfig.create(self._cli_api_session, self._tenant_id, artifact.get_tool_artifact())
|
||||
config_json = json.dumps(config.model_dump(mode="json"), ensure_ascii=False)
|
||||
config_path = f"{DifyCli.GLOBAL_TOOLS_PATH}/{DifyCli.CONFIG_FILENAME}"
|
||||
vm.upload_file(config_path, BytesIO(config_json.encode("utf-8")))
|
||||
|
||||
@ -9,6 +9,7 @@ from core.sandbox.entities import AppAssets, SandboxType
|
||||
from core.sandbox.entities.providers import SandboxProviderEntity
|
||||
from core.sandbox.initializer.app_assets_initializer import AppAssetsInitializer
|
||||
from core.sandbox.initializer.dify_cli_initializer import DifyCliInitializer
|
||||
from core.sandbox.initializer.skill_initializer import SkillInitializer
|
||||
from core.sandbox.sandbox import Sandbox
|
||||
from core.sandbox.storage.archive_storage import ArchiveSandboxStorage
|
||||
from core.virtual_environment.__base.virtual_environment import VirtualEnvironment
|
||||
@ -123,6 +124,7 @@ class SandboxManager:
|
||||
.app(app_id)
|
||||
.initializer(AppAssetsInitializer(tenant_id, app_id, assets.id))
|
||||
.initializer(DifyCliInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.initializer(SkillInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.storage(storage, assets.id)
|
||||
.build()
|
||||
)
|
||||
@ -130,6 +132,11 @@ class SandboxManager:
|
||||
logger.info("Sandbox created: id=%s, assets=%s", sandbox.vm.metadata.id, sandbox.assets_id)
|
||||
return sandbox
|
||||
|
||||
@classmethod
|
||||
def delete_storage(cls, tenant_id: str, user_id: str) -> None:
|
||||
storage = ArchiveSandboxStorage(tenant_id, SandboxBuilder.draft_id(user_id))
|
||||
storage.delete()
|
||||
|
||||
@classmethod
|
||||
def create_draft(
|
||||
cls,
|
||||
@ -153,6 +160,7 @@ class SandboxManager:
|
||||
.app(app_id)
|
||||
.initializer(AppAssetsInitializer(tenant_id, app_id, assets.id))
|
||||
.initializer(DifyCliInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.initializer(SkillInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.storage(storage, assets.id)
|
||||
.build()
|
||||
)
|
||||
@ -183,6 +191,7 @@ class SandboxManager:
|
||||
.app(app_id)
|
||||
.initializer(AppAssetsInitializer(tenant_id, app_id, assets.id))
|
||||
.initializer(DifyCliInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.initializer(SkillInitializer(tenant_id, user_id, app_id, assets.id))
|
||||
.storage(storage, assets.id)
|
||||
.build()
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user