skill loading in extras
3clyp50 committed
Feb 5, 2026 at 16:03 UTC
6585d895a903f90cf619eb9a2b3efe7b101223c9
3 files changed
+58
-7
prompts/agent.system.skills.loaded.md
new
+5
@@ -0,0 +1,5 @@
1
+# Loaded skill
2
+- The following skill was explicitly loaded via skills_tool
3
+- Full content persists here each turn to survive history compression
4
+
5
+{{skills}}
python/extensions/message_loop_prompts_after/_65_include_loaded_skills.py
new
+29
@@ -0,0 +1,29 @@
1
+from python.helpers.extension import Extension
2
+from agent import LoopData
3
+
4
+
5
+DATA_NAME_LOADED_SKILL = "loaded_skill"
6
+
7
+
8
+class IncludeLoadedSkills(Extension):
9
+ async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
10
+ extras = loop_data.extras_persistent
11
+
12
+ # Clear previous
13
+ if "loaded_skills" in extras:
14
+ del extras["loaded_skills"]
15
+
16
+ # Get single loaded skill
17
+ skill_data = self.agent.data.get(DATA_NAME_LOADED_SKILL)
18
+ if not skill_data or not isinstance(skill_data, dict):
19
+ return
20
+
21
+ content = str(skill_data.get("content") or "").strip()
22
+ if not content:
23
+ return
24
+
25
+ # Inject into extras
26
+ extras["loaded_skills"] = self.agent.read_prompt(
27
+ "agent.system.skills.loaded.md",
28
+ skills=content,
29
+ )
python/tools/skills_tool.py
+24
-7
@@ -8,6 +8,9 @@ from python.helpers import projects, files, file_tree
8
from python.helpers import skills as skills_helper, runtime
9
10
11
+DATA_NAME_LOADED_SKILL = "loaded_skill"
12
+
13
+
14
class SkillsTool(Tool):
15
"""
16
Manage and use SKILL.md-based Skills (Anthropic open standard).
@@ -106,7 +109,6 @@ class SkillsTool(Tool):
109
return "\n".join(lines)
110
111
def _load(self, skill_name: str) -> str:
109
-
112
skill_name = skill_name.strip()
113
if skill_name.startswith("**") and skill_name.endswith("**"):
114
skill_name = skill_name[
@@ -124,17 +126,32 @@ class SkillsTool(Tool):
126
if not skill:
127
return f"Error: skill not found: {skill_name!r}. Try skills_tool method=list or method=search."
128
127
- # Enumerate files under the skill directory for progressive disclosure
128
- referenced_files = self._list_skill_files(skill.path, max_files=80)
129
- rel_skill_dir = Path(files.deabsolute_path(str(skill.path)))
129
+ # Build skill content block
130
+ files_tree = self._list_skill_files(skill.path, max_files=80)
131
if self.agent.config.code_exec_ssh_enabled:
132
runtime_path = files.normalize_a0_path(str(skill.path))
133
else:
134
runtime_path = str(skill.path)
135
136
+ content_block = self._build_loaded_skill_block(
137
+ skill=skill,
138
+ runtime_path=runtime_path,
139
+ files_tree=files_tree,
140
+ )
141
+
142
+ # Store single skill in agent.data (replaces previous)
143
+ self.agent.data[DATA_NAME_LOADED_SKILL] = {
144
+ "name": skill.name,
145
+ "content": content_block,
146
+ }
147
+
148
+ return f"Loaded skill '{skill.name}' into persistent extras."
149
+
150
+ def _build_loaded_skill_block(
151
+ self, *, skill: skills_helper.Skill, runtime_path: str, files_tree: str
152
+ ) -> str:
153
lines: List[str] = []
154
lines.append(f"Skill: {skill.name}")
137
- # lines.append(f"Path: {rel_skill_dir}")
155
lines.append(f"Path: {runtime_path}")
156
if skill.version:
157
lines.append(f"Version: {skill.version}")
@@ -161,11 +178,11 @@ class SkillsTool(Tool):
178
lines.append(skill.content.strip() or "(empty)")
179
lines.append("")
180
164
- if referenced_files:
181
+ if files_tree:
182
lines.append(
183
"Files in skill directory (use skills_tool method=read_file to open):"
184
)
168
- lines.append(referenced_files)
185
+ lines.append(files_tree)
186
else:
187
lines.append("No additional files found in skill directory.")
188