From dc3445f28767a47934d92f6122b51659b58adb99 Mon Sep 17 00:00:00 2001 From: stablegenius49 <185121704+stablegenius49@users.noreply.github.com> Date: Wed, 11 Mar 2026 11:10:59 -0700 Subject: [PATCH] fix(skills): preserve cached sandbox skill paths --- astrbot/core/skills/skill_manager.py | 23 ++++++++++++++--------- tests/test_skill_manager_sandbox_cache.py | 2 +- tests/test_skill_metadata_enrichment.py | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 10 deletions(-) diff --git a/astrbot/core/skills/skill_manager.py b/astrbot/core/skills/skill_manager.py index 9bbdb5aee8..f7533c3032 100644 --- a/astrbot/core/skills/skill_manager.py +++ b/astrbot/core/skills/skill_manager.py @@ -154,10 +154,18 @@ def build_skills_prompt(skills: list[SkillInfo]) -> str: description = "Read SKILL.md for details." if skill.source_type == "sandbox_only": - rendered_path = ( - f"{str(SANDBOX_WORKSPACE_ROOT)}/{str(SANDBOX_SKILLS_ROOT)}/" - f"{display_name}/SKILL.md" - ) + if display_name != skill.name: + rendered_path = ( + f"{str(SANDBOX_WORKSPACE_ROOT)}/{str(SANDBOX_SKILLS_ROOT)}/" + f"{display_name}/SKILL.md" + ) + else: + rendered_path = _sanitize_prompt_path_for_prompt(skill.path) + if not rendered_path: + rendered_path = ( + f"{str(SANDBOX_WORKSPACE_ROOT)}/{str(SANDBOX_SKILLS_ROOT)}/" + f"{display_name}/SKILL.md" + ) else: rendered_path = _sanitize_prompt_path_for_prompt(skill.path) if not rendered_path: @@ -389,12 +397,9 @@ def list_skills( if active_only and not active: continue description = sandbox_cached_descriptions.get(skill_name, "") - if show_sandbox_path: + path_str = sandbox_cached_paths.get(skill_name, "") + if not path_str: path_str = f"{SANDBOX_WORKSPACE_ROOT}/{SANDBOX_SKILLS_ROOT}/{skill_name}/SKILL.md" - else: - path_str = sandbox_cached_paths.get(skill_name, "") - if not path_str: - path_str = f"{SANDBOX_WORKSPACE_ROOT}/{SANDBOX_SKILLS_ROOT}/{skill_name}/SKILL.md" skills_by_name[skill_name] = SkillInfo( name=skill_name, description=description, diff --git a/tests/test_skill_manager_sandbox_cache.py b/tests/test_skill_manager_sandbox_cache.py index 145420156b..35fb608118 100644 --- a/tests/test_skill_manager_sandbox_cache.py +++ b/tests/test_skill_manager_sandbox_cache.py @@ -58,7 +58,7 @@ def test_list_skills_merges_local_and_sandbox_cache(monkeypatch, tmp_path: Path) assert by_name["custom-local"].description == "local description" assert by_name["custom-local"].path == "skills/custom-local/SKILL.md" assert by_name["python-sandbox"].description == "ship built-in" - assert by_name["python-sandbox"].path == "/workspace/skills/python-sandbox/SKILL.md" + assert by_name["python-sandbox"].path == "/app/skills/python-sandbox/SKILL.md" def test_sandbox_cached_skill_respects_active_and_display_path( diff --git a/tests/test_skill_metadata_enrichment.py b/tests/test_skill_metadata_enrichment.py index ba2a215879..535f28d503 100644 --- a/tests/test_skill_metadata_enrichment.py +++ b/tests/test_skill_metadata_enrichment.py @@ -269,6 +269,26 @@ def test_build_skills_prompt_sanitizes_sandbox_skill_metadata_in_inventory(): assert "`/workspace/skills/sandbox-skill/SKILL.md`" in prompt +def test_build_skills_prompt_preserves_cached_absolute_sandbox_path(): + skills = [ + SkillInfo( + name="docx", + description="Read and write Word documents.", + path="/home/ship_0d0fba63/workspace/skills/docx/SKILL.md", + active=True, + source_type="sandbox_only", + source_label="sandbox_preset", + local_exists=False, + sandbox_exists=True, + ) + ] + + prompt = build_skills_prompt(skills) + + assert "`/home/ship_0d0fba63/workspace/skills/docx/SKILL.md`" in prompt + assert "cat /home/ship_0d0fba63/workspace/skills/docx/SKILL.md" in prompt + + def test_build_skills_prompt_sanitizes_invalid_sandbox_skill_name_in_path(): skills = [ SkillInfo(