Skip to content

Commit 8321a12

Browse files
committed
fix: avoid hardcoded sandbox skill root in prompt fallback
1 parent b241b46 commit 8321a12

3 files changed

Lines changed: 57 additions & 4 deletions

File tree

astrbot/core/skills/skill_manager.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
SANDBOX_SKILLS_CACHE_FILENAME = "sandbox_skills_cache.json"
2525
DEFAULT_SKILLS_CONFIG: dict[str, dict] = {"skills": {}}
2626
SANDBOX_SKILLS_ROOT = "skills"
27-
SANDBOX_WORKSPACE_ROOT = "/workspace"
2827
_SANDBOX_SKILLS_CACHE_VERSION = 1
2928

3029
_SKILL_NAME_RE = re.compile(r"^[\w.-]+$")
@@ -36,7 +35,7 @@ def _normalize_skill_name(name: str | None) -> str:
3635

3736

3837
def _default_sandbox_skill_path(name: str) -> str:
39-
return f"{SANDBOX_WORKSPACE_ROOT}/{SANDBOX_SKILLS_ROOT}/{name}/SKILL.md"
38+
return f"{SANDBOX_SKILLS_ROOT}/{name}/SKILL.md"
4039

4140

4241
def _normalize_cached_sandbox_skill_path(name: str, path: str) -> str:
@@ -253,8 +252,8 @@ def build_skills_prompt(skills: list[SkillInfo]) -> str:
253252
"explain why you chose not to.\n"
254253
"3. **Mandatory grounding** — Before executing any skill you MUST "
255254
"first read its `SKILL.md` by running a shell command compatible "
256-
"with the current runtime shell and using the **absolute path** "
257-
f"shown above (e.g. `{example_command}`). "
255+
"with the current runtime shell and using the path shown above "
256+
f"(e.g. `{example_command}`). "
258257
"Never rely on memory or assumptions about a skill's content.\n"
259258
"4. **Progressive disclosure** — Load only what is directly "
260259
"referenced from `SKILL.md`:\n"

tests/test_skill_manager_sandbox_cache.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,3 +155,40 @@ def test_sandbox_and_local_path_resolution_with_show_sandbox_path_false(
155155
assert local_skill_path == skills_root / "custom-local" / "SKILL.md"
156156
assert by_name["python-sandbox"].path == "/app/skills/python-sandbox/SKILL.md"
157157

158+
159+
def test_sandbox_path_fallback_uses_relative_skills_root(
160+
monkeypatch,
161+
tmp_path: Path,
162+
):
163+
data_dir = tmp_path / "data"
164+
temp_dir = tmp_path / "temp"
165+
skills_root = tmp_path / "skills"
166+
data_dir.mkdir(parents=True, exist_ok=True)
167+
temp_dir.mkdir(parents=True, exist_ok=True)
168+
skills_root.mkdir(parents=True, exist_ok=True)
169+
170+
monkeypatch.setattr(
171+
"astrbot.core.skills.skill_manager.get_astrbot_data_path",
172+
lambda: str(data_dir),
173+
)
174+
monkeypatch.setattr(
175+
"astrbot.core.skills.skill_manager.get_astrbot_temp_path",
176+
lambda: str(temp_dir),
177+
)
178+
179+
mgr = SkillManager(skills_root=str(skills_root))
180+
mgr.set_sandbox_skills_cache(
181+
[
182+
{
183+
"name": "docx",
184+
"description": "sandbox skill",
185+
"path": "/workspace/not-the-real-root/docx/readme.txt",
186+
}
187+
]
188+
)
189+
190+
skills = mgr.list_skills(runtime="sandbox")
191+
192+
assert len(skills) == 1
193+
assert skills[0].path == "skills/docx/SKILL.md"
194+

tests/test_skill_metadata_enrichment.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,23 @@ def test_build_skills_prompt_keeps_placeholder_example_literal():
128128
assert example_fragment == "cat <skills_root>/<skill_name>/SKILL.md"
129129

130130

131+
def test_build_skills_prompt_allows_relative_sandbox_path_examples():
132+
skills = [
133+
SkillInfo(
134+
name="docx",
135+
description="sandbox skill",
136+
path="skills/docx/SKILL.md",
137+
active=True,
138+
source_type="sandbox_only",
139+
)
140+
]
141+
142+
prompt = build_skills_prompt(skills)
143+
144+
assert "cat skills/docx/SKILL.md" in prompt
145+
assert "**absolute path**" not in prompt
146+
147+
131148
def test_build_skills_prompt_preserves_windows_absolute_path_in_example(monkeypatch):
132149
monkeypatch.setattr("astrbot.core.skills.skill_manager.os.name", "nt")
133150
skills = [

0 commit comments

Comments
 (0)