Remove legacy skill prompt cleanup

Delete the empty active-skills prompt extension and its unused prompt template now that selected skills are loaded through chat history instead of protocol. Stop clearing legacy loaded_skills keys from protocol/extras in the loaded-skills hook while keeping history reattachment for compacted skill bodies.

Alessandro committed Jul 8, 2026 at 12:42 UTC f8b06e0b12bb41fd4ca840906fe20b5a4da19e49
6 files changed +5 -39
extensions/python/message_loop_prompts_after/AGENTS.md
+3 -3
@@ -2,14 +2,14 @@
2
3 ## Purpose
4
5 -- Own prompt protocol and extras appended around primary message-loop prompt construction.
5 +- Own prompt protocol, prompt extras, and history reattachment around primary message-loop prompt construction.
6
7 ## Ownership
8
9 -- Ordered Python files own current datetime, skill recall/load context, agent info, parallel job status, and workdir extras injection.
9 +- Ordered Python files own current datetime, relevant-skill hints, loaded-skill history reattachment, agent info, parallel job status, and workdir extras injection.
10 - Explicitly loaded skill bodies belong in tool-result history with metadata so they can survive persistence and be reattached after compaction.
11 - Explicitly loaded skill IDs are chat-wide context data, not agent-local state.
12 -- Legacy active-skill prompt protocol injection must stay empty; selected skills are loaded through history.
12 +- Skills must not write selected or loaded skill bodies into protocol or extras.
13
14 ## Local Contracts
15
extensions/python/message_loop_prompts_after/_65_include_loaded_skills.py
-3
@@ -14,9 +14,6 @@ class IncludeLoadedSkills(Extension):
14 if not self.agent:
15 return
16
17 - loop_data.protocol_persistent.pop("loaded_skills", None)
18 - loop_data.extras_persistent.pop("loaded_skills", None)
19 -
17 skill_names = skills.get_loaded_skill_names(self.agent)
18 if not skill_names:
19 return
plugins/_skills/AGENTS.md
-1
@@ -8,7 +8,6 @@
8
9 - `hooks.py` owns skill config normalization.
10 - `api/skills_catalog.py` owns skill catalog access and loading selected skills into chat history.
11 -- `prompts/agent.system.active_skills.md` is retained only for legacy prompt-protocol compatibility.
11 - `webui/` owns skill settings UI and store.
12 - `default_config.yaml`, `plugin.yaml`, `README.md`, and `LICENSE` own defaults, metadata, docs, and license.
13
plugins/_skills/extensions/python/message_loop_prompts_after/_66_include_active_skills.py deleted
-23
@@ -1,23 +0,0 @@
1 -from __future__ import annotations
2 -
3 -from helpers import skills
4 -from agent import LoopData
5 -from helpers.extension import Extension
6 -
7 -
8 -class IncludeActiveSkills(Extension):
9 - async def execute(self, loop_data: LoopData = LoopData(), **kwargs):
10 - if not self.agent:
11 - return
12 -
13 - protocol = loop_data.protocol_persistent
14 - protocol.pop("active_skills", None)
15 -
16 - content = skills.build_active_skills_prompt(self.agent)
17 - if not content:
18 - return
19 -
20 - protocol["active_skills"] = self.agent.read_prompt(
21 - "agent.system.active_skills.md",
22 - skills=content,
23 - )
plugins/_skills/prompts/agent.system.active_skills.md deleted
-5
@@ -1,5 +0,0 @@
1 -## active skills
2 -The following skills were explicitly activated for this chat.
3 -Treat them as already loaded instructions and follow them when relevant.
4 -
5 -{{skills}}
tests/test_tool_action_contracts.py
+2 -4
@@ -430,8 +430,8 @@ def test_loaded_skills_extension_reattaches_missing_body_after_compaction(
430 module = _load_loaded_skills_extension(monkeypatch, tmp_path)
431 agent = _FakeLoadedSkillAgent()
432 loop_data = types.SimpleNamespace(
433 - protocol_persistent={"loaded_skills": "legacy"},
434 - extras_persistent={"loaded_skills": "legacy"},
433 + protocol_persistent={},
434 + extras_persistent={},
435 history_output=[
436 {
437 "ai": False,
@@ -442,8 +442,6 @@ def test_loaded_skills_extension_reattaches_missing_body_after_compaction(
442
443 asyncio.run(module.IncludeLoadedSkills(agent).execute(loop_data))
444
445 - assert "loaded_skills" not in loop_data.protocol_persistent
446 - assert "loaded_skills" not in loop_data.extras_persistent
445 assert len(agent.added_tool_results) == 1
446 added = agent.added_tool_results[0]
447 assert added["tool_name"] == "skills_tool"