mirror of
https://github.com/langgenius/dify.git
synced 2026-03-14 19:38:37 +08:00
95 lines
3.2 KiB
Python
95 lines
3.2 KiB
Python
from typing import TYPE_CHECKING
|
|
|
|
from pydantic import BaseModel, ConfigDict, Field
|
|
|
|
from core.app.entities.app_asset_entities import AppAssetFileTree
|
|
from core.skill.entities.skill_metadata import FileReference
|
|
from core.skill.entities.tool_dependencies import ToolDependencies, ToolDependency
|
|
|
|
if TYPE_CHECKING:
|
|
from core.skill.entities.skill_metadata import SkillMetadata
|
|
|
|
|
|
class SkillDependance(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
tools: ToolDependencies = Field(description="Direct tool dependencies parsed from this skill only")
|
|
|
|
files: set[FileReference] = Field(
|
|
default_factory=set,
|
|
description="Direct file references parsed from this skill only",
|
|
)
|
|
|
|
def __or__(self, other: "SkillDependance") -> "SkillDependance":
|
|
return SkillDependance(tools=self.tools.merge(other.tools), files=self.files | other.files)
|
|
|
|
@staticmethod
|
|
def from_metadata(metadata: "SkillMetadata") -> "SkillDependance":
|
|
"""Convert parsed metadata into direct tool/file dependency model."""
|
|
from core.skill.entities.skill_metadata import ToolReference
|
|
|
|
dep_map: dict[str, ToolDependency] = {}
|
|
ref_map: dict[str, ToolReference] = {}
|
|
|
|
for tool_ref in metadata.tools.values():
|
|
dep_map.setdefault(
|
|
tool_ref.tool_id(),
|
|
ToolDependency(
|
|
type=tool_ref.type,
|
|
provider=tool_ref.provider,
|
|
tool_name=tool_ref.tool_name,
|
|
enabled=tool_ref.enabled,
|
|
),
|
|
)
|
|
ref_map.setdefault(tool_ref.uuid, tool_ref)
|
|
|
|
return SkillDependance(
|
|
tools=ToolDependencies(
|
|
dependencies=[dep_map[key] for key in sorted(dep_map.keys())],
|
|
references=[ref_map[key] for key in sorted(ref_map.keys())],
|
|
),
|
|
files=metadata.files,
|
|
)
|
|
|
|
|
|
class Skill(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
skill_id: str = Field(description="Unique identifier for this skill, same with skill_id")
|
|
|
|
direct_dependance: SkillDependance = Field(description="Direct dependencies parsed from this skill only")
|
|
|
|
dependance: SkillDependance = Field(description="All dependencies including transitive closure")
|
|
|
|
content: str = Field(description="Resolved content with all references replaced")
|
|
|
|
@property
|
|
def tools(self) -> ToolDependencies:
|
|
return self.dependance.tools
|
|
|
|
|
|
class SkillBundle(BaseModel):
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
asset_tree: AppAssetFileTree = Field(description="Asset tree for this bundle")
|
|
|
|
assets_id: str = Field(description="Assets ID this bundle belongs to")
|
|
|
|
skills: dict[str, Skill] = Field(default_factory=dict)
|
|
|
|
@property
|
|
def entries(self) -> dict[str, Skill]:
|
|
return self.skills
|
|
|
|
def get(self, skill_id: str) -> Skill | None:
|
|
return self.skills.get(skill_id)
|
|
|
|
def get_tool_dependencies(self) -> ToolDependencies:
|
|
merged = ToolDependencies()
|
|
for skill in self.skills.values():
|
|
merged = merged.merge(skill.dependance.tools)
|
|
return merged
|
|
|
|
def put(self, skill: Skill) -> None:
|
|
self.skills[skill.skill_id] = skill
|