mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-12 07:20:45 +00:00
fix(skills): make quick_validate work without PyYAML
This commit is contained in:
@@ -8,7 +8,10 @@ import sys
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
import yaml
|
try:
|
||||||
|
import yaml
|
||||||
|
except ModuleNotFoundError:
|
||||||
|
yaml = None
|
||||||
|
|
||||||
MAX_SKILL_NAME_LENGTH = 64
|
MAX_SKILL_NAME_LENGTH = 64
|
||||||
|
|
||||||
@@ -23,6 +26,31 @@ def _extract_frontmatter(content: str) -> Optional[str]:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _parse_simple_frontmatter(frontmatter_text: str) -> Optional[dict[str, str]]:
|
||||||
|
"""
|
||||||
|
Minimal fallback parser used when PyYAML is unavailable.
|
||||||
|
Supports simple `key: value` mappings used by SKILL.md frontmatter.
|
||||||
|
"""
|
||||||
|
parsed: dict[str, str] = {}
|
||||||
|
for raw_line in frontmatter_text.splitlines():
|
||||||
|
line = raw_line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
if ":" not in line:
|
||||||
|
return None
|
||||||
|
key, value = line.split(":", 1)
|
||||||
|
key = key.strip()
|
||||||
|
value = value.strip()
|
||||||
|
if not key:
|
||||||
|
return None
|
||||||
|
if (value.startswith('"') and value.endswith('"')) or (
|
||||||
|
value.startswith("'") and value.endswith("'")
|
||||||
|
):
|
||||||
|
value = value[1:-1]
|
||||||
|
parsed[key] = value
|
||||||
|
return parsed
|
||||||
|
|
||||||
|
|
||||||
def validate_skill(skill_path):
|
def validate_skill(skill_path):
|
||||||
"""Basic validation of a skill"""
|
"""Basic validation of a skill"""
|
||||||
skill_path = Path(skill_path)
|
skill_path = Path(skill_path)
|
||||||
@@ -39,12 +67,20 @@ def validate_skill(skill_path):
|
|||||||
frontmatter_text = _extract_frontmatter(content)
|
frontmatter_text = _extract_frontmatter(content)
|
||||||
if frontmatter_text is None:
|
if frontmatter_text is None:
|
||||||
return False, "Invalid frontmatter format"
|
return False, "Invalid frontmatter format"
|
||||||
try:
|
if yaml is not None:
|
||||||
frontmatter = yaml.safe_load(frontmatter_text)
|
try:
|
||||||
if not isinstance(frontmatter, dict):
|
frontmatter = yaml.safe_load(frontmatter_text)
|
||||||
return False, "Frontmatter must be a YAML dictionary"
|
if not isinstance(frontmatter, dict):
|
||||||
except yaml.YAMLError as e:
|
return False, "Frontmatter must be a YAML dictionary"
|
||||||
return False, f"Invalid YAML in frontmatter: {e}"
|
except yaml.YAMLError as e:
|
||||||
|
return False, f"Invalid YAML in frontmatter: {e}"
|
||||||
|
else:
|
||||||
|
frontmatter = _parse_simple_frontmatter(frontmatter_text)
|
||||||
|
if frontmatter is None:
|
||||||
|
return (
|
||||||
|
False,
|
||||||
|
"Invalid YAML in frontmatter: unsupported syntax without PyYAML installed",
|
||||||
|
)
|
||||||
|
|
||||||
allowed_properties = {"name", "description", "license", "allowed-tools", "metadata"}
|
allowed_properties = {"name", "description", "license", "allowed-tools", "metadata"}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user