53 lines
1.7 KiB
Python
53 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
from app.agents.skills.loader import SkillLoader
|
|
from app.agents.skills.types import Skill, SkillMetadata
|
|
|
|
|
|
class SkillRegistry:
|
|
"""builtin 스킬 탐색 및 캐싱."""
|
|
|
|
BUILTIN_DIR: Path = Path(__file__).parent / "builtin"
|
|
_cache: dict[str, SkillMetadata] = {}
|
|
|
|
@classmethod
|
|
def discover(cls) -> list[SkillMetadata]:
|
|
"""BUILTIN_DIR 하위의 */SKILL.md 패턴을 스캔하여 메타데이터 캐싱."""
|
|
cls._cache.clear()
|
|
for skill_file in sorted(cls.BUILTIN_DIR.glob("*/SKILL.md")):
|
|
meta = SkillLoader.extract_metadata(skill_file, "builtin")
|
|
if meta.name:
|
|
cls._cache[meta.name] = meta
|
|
return list(cls._cache.values())
|
|
|
|
@classmethod
|
|
def get(cls, name: str) -> Skill | None:
|
|
"""캐시에서 이름으로 조회 후 전체 Skill(instructions 포함) 로드."""
|
|
if not cls._cache:
|
|
cls.discover()
|
|
meta = cls._cache.get(name)
|
|
if meta is None:
|
|
return None
|
|
return SkillLoader.load_from_path(meta.path, meta.source)
|
|
|
|
@classmethod
|
|
def list_skills(cls) -> list[SkillMetadata]:
|
|
return list(cls._cache.values())
|
|
|
|
@classmethod
|
|
def build_skills_section(cls) -> str:
|
|
"""시스템 프롬프트에 삽입할 스킬 목록 텍스트 생성."""
|
|
skills = cls.list_skills()
|
|
if not skills:
|
|
return ""
|
|
lines = ["## 사용 가능한 스킬\n"]
|
|
for s in skills:
|
|
lines.append(f"- **{s.name}**: {s.description}")
|
|
return "\n".join(lines)
|
|
|
|
@classmethod
|
|
def clear_cache(cls) -> None:
|
|
cls._cache.clear()
|