Keep skills tooling compatible

Default empty skills_tool calls to list, accept legacy method as a deprecated action alias, and warn when malformed SKILL.md frontmatter causes a skill to be skipped. Update the helper/tool DOX notes and focused regressions.
This commit is contained in:
Alessandro 2026-06-25 09:41:08 +02:00
parent bd7e829a0f
commit 884f13dea6
6 changed files with 141 additions and 24 deletions

View file

@ -24,17 +24,26 @@ class SkillsTool(Tool):
Script execution is handled by code_execution_tool directly.
"""
def _current_action(self) -> str:
@staticmethod
def _normalize_action(action: object) -> str:
return (
str(
self.args.get("action")
or ""
action
or "list"
)
.strip()
.lower()
.replace("-", "_")
)
def _current_action(self, **kwargs) -> str:
return self._normalize_action(
kwargs.get("action")
or self.args.get("action")
or kwargs.get("method")
or self.args.get("method")
)
@staticmethod
def _normalize_skill_name(skill_name: str) -> str:
skill_name = skill_name.strip()
@ -65,14 +74,14 @@ class SkillsTool(Tool):
return super().get_log_object()
async def before_execution(self, **kwargs):
if self._current_action() != "load":
if self._current_action(**kwargs) != "load":
await super().before_execution(**kwargs)
return
skill_name = self._normalize_skill_name(
str(kwargs.get("skill_name") or self.args.get("skill_name") or "")
)
label = f"{self.name} action {self._current_action()}"
label = f"{self.name} action {self._current_action(**kwargs)}"
if skill_name:
PrintStyle(
font_color="#1B4F72",
@ -90,35 +99,29 @@ class SkillsTool(Tool):
self.log = self.get_log_object()
async def execute(self, **kwargs) -> Response:
action = (
str(
kwargs.get("action")
or self.args.get("action")
or ""
)
.strip()
.lower()
.replace("-", "_")
action = self._current_action(**kwargs)
query = str(kwargs.get("query") or self.args.get("query") or "").strip()
skill_name = self._normalize_skill_name(
str(kwargs.get("skill_name") or self.args.get("skill_name") or "")
)
file_path = str(
kwargs.get("file_path") or self.args.get("file_path") or ""
).strip()
if "action" not in kwargs and "action" not in self.args and "method" in kwargs:
kwargs["action"] = action
if "action" not in self.args and "method" in self.args:
self.args["action"] = action
try:
if action == "list":
return Response(message=self._list(), break_loop=False)
if action == "search":
query = str(kwargs.get("query") or self.args.get("query") or "").strip()
return Response(message=self._search(query), break_loop=False)
if action == "load":
skill_name = self._normalize_skill_name(
str(kwargs.get("skill_name") or self.args.get("skill_name") or "")
)
return self._load(skill_name)
if action == "read_file":
skill_name = self._normalize_skill_name(
str(kwargs.get("skill_name") or self.args.get("skill_name") or "")
)
file_path = str(
kwargs.get("file_path") or self.args.get("file_path") or ""
).strip()
return Response(
message=self._read_file(skill_name, file_path),
break_loop=False,

View file

@ -29,6 +29,7 @@
- Loading a skill appends the full skill body as a normal tool-result history message with `skill_instructions` metadata containing name, path, source, and content visibility.
- Loaded skill IDs are stored in chat-wide context data.
- Duplicate loads omit the full body when the same skill name remains visible in model history.
- Missing or empty `action` defaults to `list`, and legacy `method` is accepted as a deprecated alias when `action` is absent.
- Observed side-effect areas: filesystem reads, filesystem deletion, settings/state persistence, chat history persistence.
- Imported dependency areas include: `__future__`, `helpers`, `helpers.print_style`, `helpers.tool`, `pathlib`, `typing`.