mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 17:38:04 +08:00
feat(skill): skill support
This commit is contained in:
@ -5,14 +5,8 @@ import logging
|
||||
from io import BytesIO
|
||||
from pathlib import Path
|
||||
|
||||
from core.app.entities.app_invoke_entities import InvokeFrom
|
||||
from core.app_assets.entities import ToolType
|
||||
from core.session.cli_api import CliApiSessionManager
|
||||
from core.skill.entities import ToolManifest
|
||||
from core.skill.skill_manager import SkillManager
|
||||
from core.tools.__base.tool import Tool
|
||||
from core.tools.entities.tool_entities import ToolProviderType
|
||||
from core.tools.tool_manager import ToolManager
|
||||
from core.virtual_environment.__base.helpers import execute, with_connection
|
||||
from core.virtual_environment.__base.virtual_environment import VirtualEnvironment
|
||||
|
||||
@ -32,12 +26,14 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
def __init__(
|
||||
self,
|
||||
tenant_id: str,
|
||||
user_id: str,
|
||||
app_id: str,
|
||||
assets_id: str,
|
||||
cli_root: str | Path | None = None,
|
||||
) -> None:
|
||||
self._tenant_id = tenant_id
|
||||
self._app_id = app_id
|
||||
self._user_id = user_id
|
||||
self._assets_id = assets_id
|
||||
self._locator = DifyCliLocator(root=cli_root)
|
||||
|
||||
@ -52,7 +48,6 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
env,
|
||||
["mkdir", "-p", f"{DIFY_CLI_ROOT}/bin"],
|
||||
connection=conn,
|
||||
timeout=10,
|
||||
error_message="Failed to create dify CLI directory",
|
||||
)
|
||||
|
||||
@ -62,36 +57,33 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
env,
|
||||
["chmod", "+x", DIFY_CLI_PATH],
|
||||
connection=conn,
|
||||
timeout=10,
|
||||
error_message="Failed to mark dify CLI as executable",
|
||||
)
|
||||
|
||||
logger.info("Dify CLI uploaded to sandbox, path=%s", DIFY_CLI_PATH)
|
||||
|
||||
manifest = SkillManager.load_tool_manifest(
|
||||
artifact = SkillManager.load_tool_artifact(
|
||||
self._tenant_id,
|
||||
self._app_id,
|
||||
self._assets_id,
|
||||
)
|
||||
|
||||
if manifest is None or not manifest.tools:
|
||||
logger.info("No tools found in manifest for assets_id=%s", self._assets_id)
|
||||
if artifact is None or not artifact.references:
|
||||
logger.info("No tools found in artifact for assets_id=%s", self._assets_id)
|
||||
return
|
||||
|
||||
self._tools = self._resolve_tools_from_manifest(manifest)
|
||||
self._cli_api_session = CliApiSessionManager().create(tenant_id=self._tenant_id, user_id="system")
|
||||
# FIXME(Mairuis): store it in workflow context
|
||||
self._cli_api_session = CliApiSessionManager().create(tenant_id=self._tenant_id, user_id=self._user_id)
|
||||
|
||||
execute(
|
||||
env,
|
||||
["mkdir", "-p", DIFY_CLI_GLOBAL_TOOLS_PATH],
|
||||
connection=conn,
|
||||
timeout=10,
|
||||
error_message="Failed to create global tools directory",
|
||||
error_message="Failed to create Dify CLI global tools directory",
|
||||
)
|
||||
|
||||
config_json = json.dumps(
|
||||
DifyCliConfig.create(self._cli_api_session, self._tools).model_dump(mode="json"), ensure_ascii=False
|
||||
)
|
||||
config = DifyCliConfig.create(self._cli_api_session, self._tenant_id, artifact)
|
||||
config_json = json.dumps(config.model_dump(mode="json"), ensure_ascii=False)
|
||||
env.upload_file(
|
||||
f"{DIFY_CLI_GLOBAL_TOOLS_PATH}/{DIFY_CLI_CONFIG_FILENAME}", BytesIO(config_json.encode("utf-8"))
|
||||
)
|
||||
@ -100,7 +92,6 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
env,
|
||||
[DIFY_CLI_PATH, "init"],
|
||||
connection=conn,
|
||||
timeout=30,
|
||||
cwd=DIFY_CLI_GLOBAL_TOOLS_PATH,
|
||||
error_message="Failed to initialize Dify CLI",
|
||||
)
|
||||
@ -110,38 +101,3 @@ class DifyCliInitializer(SandboxInitializer):
|
||||
DIFY_CLI_GLOBAL_TOOLS_PATH,
|
||||
len(self._tools),
|
||||
)
|
||||
|
||||
def _resolve_tools_from_manifest(self, manifest: ToolManifest) -> list[Tool]:
|
||||
tools: list[Tool] = []
|
||||
|
||||
for entry in manifest.tools.values():
|
||||
if entry.provider is None or entry.tool_name is None:
|
||||
logger.warning("Skipping tool entry with missing provider or tool_name: %s", entry.uuid)
|
||||
continue
|
||||
|
||||
try:
|
||||
provider_type = self._convert_tool_type(entry.type)
|
||||
tool = ToolManager.get_tool_runtime(
|
||||
tenant_id=self._tenant_id,
|
||||
provider_type=provider_type,
|
||||
provider_id=entry.provider,
|
||||
tool_name=entry.tool_name,
|
||||
invoke_from=InvokeFrom.AGENT,
|
||||
credential_id=entry.credential_id,
|
||||
)
|
||||
tools.append(tool)
|
||||
except Exception as e:
|
||||
logger.warning("Failed to resolve tool %s/%s: %s", entry.provider, entry.tool_name, e)
|
||||
continue
|
||||
|
||||
return tools
|
||||
|
||||
@staticmethod
|
||||
def _convert_tool_type(tool_type: ToolType) -> ToolProviderType:
|
||||
match tool_type:
|
||||
case ToolType.BUILTIN:
|
||||
return ToolProviderType.BUILT_IN
|
||||
case ToolType.MCP:
|
||||
return ToolProviderType.MCP
|
||||
case _:
|
||||
raise ValueError(f"Unsupported tool type: {tool_type}")
|
||||
|
||||
Reference in New Issue
Block a user