mirror of
https://github.com/langgenius/dify.git
synced 2026-07-22 12:36:14 -04:00
166 lines
6.5 KiB
Python
166 lines
6.5 KiB
Python
"""Workspace-level Skill Management models.
|
|
|
|
These tables are the source of truth for reusable workspace Skills. Agent Soul
|
|
``config_skills`` and Agent Drive skill rows remain per-agent runtime/config
|
|
assets; they may consume a published Skill snapshot but do not own the Skill's
|
|
draft, metadata, version history, or Agent binding priority.
|
|
"""
|
|
|
|
from enum import StrEnum
|
|
|
|
import sqlalchemy as sa
|
|
from pydantic import BaseModel, ConfigDict
|
|
from sqlalchemy import Index, UniqueConstraint
|
|
from sqlalchemy.orm import Mapped, mapped_column
|
|
|
|
from models.base import Base, DefaultFieldsMixin
|
|
from models.types import EnumText, JSONModelColumn, LongText, StringUUID
|
|
|
|
|
|
class SkillFileKind(StrEnum):
|
|
"""Draft file entry kind."""
|
|
|
|
FILE = "file"
|
|
DIRECTORY = "directory"
|
|
|
|
|
|
class SkillFileStorage(StrEnum):
|
|
"""How a draft file's content is stored."""
|
|
|
|
TEXT = "text"
|
|
TOOL_FILE = "tool_file"
|
|
|
|
|
|
class SkillVersionManifestFile(BaseModel):
|
|
"""One file entry captured in a published Skill snapshot manifest."""
|
|
|
|
path: str
|
|
mime_type: str | None = None
|
|
size: int
|
|
hash: str
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class SkillVersionManifest(BaseModel):
|
|
"""Published Skill snapshot file index."""
|
|
|
|
files: list[SkillVersionManifestFile]
|
|
|
|
model_config = ConfigDict(extra="forbid")
|
|
|
|
|
|
class Skill(DefaultFieldsMixin, Base):
|
|
"""Workspace-level reusable Skill metadata and draft status."""
|
|
|
|
__tablename__ = "skills"
|
|
__table_args__ = (
|
|
sa.PrimaryKeyConstraint("id", name="skill_pkey"),
|
|
UniqueConstraint("tenant_id", "name", name="skill_tenant_name_unique"),
|
|
Index("skills_tenant_updated_at_idx", "tenant_id", "updated_at"),
|
|
)
|
|
|
|
tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
name: Mapped[str] = mapped_column(sa.String(64), nullable=False)
|
|
display_name: Mapped[str] = mapped_column(sa.String(128), nullable=False)
|
|
icon: Mapped[str] = mapped_column(sa.String(16), nullable=False, default="📄", server_default="📄")
|
|
description: Mapped[str] = mapped_column(sa.String(1024), nullable=False, default="", server_default="")
|
|
tags: Mapped[str] = mapped_column(LongText, nullable=False, default="[]", server_default="[]")
|
|
name_manually_edited: Mapped[bool] = mapped_column(
|
|
sa.Boolean,
|
|
nullable=False,
|
|
default=False,
|
|
server_default=sa.false(),
|
|
)
|
|
visibility: Mapped[str] = mapped_column(
|
|
sa.String(32),
|
|
nullable=False,
|
|
default="workspace",
|
|
server_default="workspace",
|
|
)
|
|
latest_published_version_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
created_by: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
updated_by: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
|
|
|
|
class SkillDraftFile(DefaultFieldsMixin, Base):
|
|
"""One draft file or directory in a workspace Skill."""
|
|
|
|
__tablename__ = "skill_draft_files"
|
|
__table_args__ = (
|
|
sa.PrimaryKeyConstraint("id", name="skill_draft_file_pkey"),
|
|
UniqueConstraint("skill_id", "path", name="skill_draft_file_skill_path_unique"),
|
|
Index("skill_draft_files_skill_path_idx", "skill_id", "path"),
|
|
)
|
|
|
|
skill_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
path: Mapped[str] = mapped_column(sa.String(512), nullable=False)
|
|
kind: Mapped[SkillFileKind] = mapped_column(EnumText(SkillFileKind, length=32), nullable=False)
|
|
storage: Mapped[SkillFileStorage | None] = mapped_column(EnumText(SkillFileStorage, length=32), nullable=True)
|
|
mime_type: Mapped[str | None] = mapped_column(sa.String(255), nullable=True)
|
|
content_text: Mapped[str | None] = mapped_column(LongText, nullable=True)
|
|
tool_file_id: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
size: Mapped[int | None] = mapped_column(sa.BigInteger, nullable=True)
|
|
hash: Mapped[str | None] = mapped_column(sa.String(255), nullable=True)
|
|
|
|
|
|
class SkillVersion(DefaultFieldsMixin, Base):
|
|
"""Immutable published Skill snapshot.
|
|
|
|
``hash_code`` uniquely identifies a published version for downstream
|
|
execution audit. It includes Skill identity, version number, and archive
|
|
content digest instead of being only the archive content hash.
|
|
"""
|
|
|
|
__tablename__ = "skill_versions"
|
|
__table_args__ = (
|
|
sa.PrimaryKeyConstraint("id", name="skill_version_pkey"),
|
|
UniqueConstraint("skill_id", "version_number", name="skill_version_skill_number_unique"),
|
|
Index("skill_versions_skill_created_at_idx", "skill_id", "created_at"),
|
|
)
|
|
|
|
skill_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
version_number: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
|
version_name: Mapped[str] = mapped_column(sa.String(128), nullable=False, default="", server_default="")
|
|
publish_note: Mapped[str] = mapped_column(sa.String(1024), nullable=False, default="", server_default="")
|
|
manifest: Mapped[SkillVersionManifest] = mapped_column(JSONModelColumn(SkillVersionManifest), nullable=False)
|
|
archive_tool_file_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
hash_code: Mapped[str] = mapped_column(sa.String(255), nullable=False)
|
|
archive_size: Mapped[int] = mapped_column(sa.BigInteger, nullable=False)
|
|
published_by: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
|
|
|
|
class AgentSkillBinding(DefaultFieldsMixin, Base):
|
|
"""Direct Agent-to-workspace-Skill binding.
|
|
|
|
``priority`` is retained as an internal ordering column for the current
|
|
schema constraints. Runtime Skill selection is Agent-driven and must not
|
|
treat it as a matching priority.
|
|
"""
|
|
|
|
__tablename__ = "agent_skill_bindings"
|
|
__table_args__ = (
|
|
sa.PrimaryKeyConstraint("id", name="agent_skill_binding_pkey"),
|
|
UniqueConstraint("tenant_id", "agent_id", "skill_id", name="agent_skill_binding_unique"),
|
|
UniqueConstraint("tenant_id", "agent_id", "priority", name="agent_skill_binding_priority_unique"),
|
|
Index("agent_skill_bindings_skill_idx", "tenant_id", "skill_id"),
|
|
)
|
|
|
|
tenant_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
agent_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
skill_id: Mapped[str] = mapped_column(StringUUID, nullable=False)
|
|
priority: Mapped[int] = mapped_column(sa.Integer, nullable=False)
|
|
created_by: Mapped[str | None] = mapped_column(StringUUID, nullable=True)
|
|
|
|
|
|
__all__ = [
|
|
"AgentSkillBinding",
|
|
"Skill",
|
|
"SkillDraftFile",
|
|
"SkillFileKind",
|
|
"SkillFileStorage",
|
|
"SkillVersion",
|
|
"SkillVersionManifest",
|
|
"SkillVersionManifestFile",
|
|
]
|