增加uploads路径中的文件到skill扫描范围

This commit is contained in:
Titan 2026-03-11 15:41:42 +08:00
parent dd0885b3a5
commit c669b3bb24
5 changed files with 24 additions and 9 deletions

View File

@ -315,7 +315,7 @@ def get_skills_prompt_section() -> str:
Returns the <skill_system>...</skill_system> block listing all enabled skills,
suitable for injection into any agent's system prompt.
"""
skills = load_skills(enabled_only=True)
skills = load_skills(enabled_only=False) # Load all skills, we'll indicate enabled status in the prompt
try:
from src.config import get_app_config

View File

@ -161,8 +161,8 @@ class ExtensionsConfig(BaseModel):
"""
skill_config = self.skills.get(skill_name)
if skill_config is None:
# Default to enable for public & custom skill
return skill_category in ("public", "custom")
# Default to enable for public/custom/uploads skills
return skill_category in ("public", "custom", "uploads")
return skill_config.enabled

View File

@ -4,6 +4,9 @@ from .parser import parse_skill_file
from .types import Skill
UPLOADS_SKILLS_PATH = Path("/mnt/user-data/uploads")
def get_skills_root_path() -> Path:
"""
Get the root path of the skills directory.
@ -22,7 +25,9 @@ def load_skills(skills_path: Path | None = None, use_config: bool = True, enable
"""
Load all skills from the skills directory.
Scans both public and custom skill directories, parsing SKILL.md files
Scans public/custom skill directories under the skills root, and also
scans user uploads skill directory in the virtual personal folder
(/mnt/user-data/uploads), parsing SKILL.md files
to extract metadata. The enabled state is determined by the skills_state_config.json file.
Args:
@ -53,9 +58,15 @@ def load_skills(skills_path: Path | None = None, use_config: bool = True, enable
skills = []
# Scan public and custom directories
for category in ["public", "custom"]:
category_path = skills_path / category
# Scan public/custom directories under skills root, and uploads skills
# under the virtual personal folder.
scan_targets: list[tuple[str, Path]] = [
("public", skills_path / "public"),
("custom", skills_path / "custom"),
("uploads", UPLOADS_SKILLS_PATH),
]
for category, category_path in scan_targets:
if not category_path.exists() or not category_path.is_dir():
continue

View File

@ -10,7 +10,7 @@ def parse_skill_file(skill_file: Path, category: str) -> Skill | None:
Args:
skill_file: Path to the SKILL.md file
category: Category of the skill ('public' or 'custom')
category: Category of the skill ('public', 'custom', or 'uploads')
Returns:
Skill object if parsing succeeds, None otherwise

View File

@ -11,7 +11,7 @@ class Skill:
license: str | None
skill_dir: Path
skill_file: Path
category: str # 'public' or 'custom'
category: str # 'public', 'custom', or 'uploads'
enabled: bool = False # Whether this skill is enabled
@property
@ -29,6 +29,8 @@ class Skill:
Returns:
Full container path to the skill directory
"""
if self.category == "uploads":
return f"/mnt/user-data/uploads/{self.skill_dir.name}"
return f"{container_base_path}/{self.category}/{self.skill_dir.name}"
def get_container_file_path(self, container_base_path: str = "/mnt/skills") -> str:
@ -41,6 +43,8 @@ class Skill:
Returns:
Full container path to the skill's SKILL.md file
"""
if self.category == "uploads":
return f"/mnt/user-data/uploads/{self.skill_dir.name}/SKILL.md"
return f"{container_base_path}/{self.category}/{self.skill_dir.name}/SKILL.md"
def __repr__(self) -> str: