Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 18 additions & 7 deletions astrbot/core/computer/computer_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,24 @@ def parse_description(text: str) -> str:
break
if end_idx is None:
return ""
for line in lines[1:end_idx]:
if ":" not in line:
continue
key, value = line.split(":", 1)
if key.strip().lower() == "description":
return value.strip().strip('"').strip("'")
return ""

frontmatter = "\n".join(lines[1:end_idx])
try:
import yaml
except ImportError:
return ""

Comment on lines +219 to +222
try:
payload = yaml.safe_load(frontmatter) or dict()
except yaml.YAMLError:
return ""
if not isinstance(payload, dict):
return ""

description = payload.get("description", "")
if not isinstance(description, str):
return ""
return description.strip()


def load_managed_skills() -> list[str]:
Expand Down
22 changes: 15 additions & 7 deletions astrbot/core/skills/skill_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
from datetime import datetime, timezone
from pathlib import Path, PurePosixPath

import yaml

Comment on lines +14 to +15
from astrbot.core.utils.astrbot_path import (
get_astrbot_data_path,
get_astrbot_skills_path,
Expand Down Expand Up @@ -69,13 +71,19 @@ def _parse_frontmatter_description(text: str) -> str:
break
if end_idx is None:
return ""
for line in lines[1:end_idx]:
if ":" not in line:
continue
key, value = line.split(":", 1)
if key.strip().lower() == "description":
return value.strip().strip('"').strip("'")
return ""

frontmatter = "\n".join(lines[1:end_idx])
try:
payload = yaml.safe_load(frontmatter) or {}
except yaml.YAMLError:
return ""
if not isinstance(payload, dict):
return ""

description = payload.get("description", "")
if not isinstance(description, str):
return ""
return description.strip()


# Regex for sanitizing paths used in prompt examples — only allow
Expand Down
33 changes: 33 additions & 0 deletions tests/test_skill_metadata_enrichment.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,39 @@ def test_parse_frontmatter_quoted_description():
assert _parse_frontmatter_description(text) == "quoted value"


def test_parse_frontmatter_multiline_literal_description():
text = (
"---\n"
"name: humanizer-zh\n"
"description: |\n"
" 去除文本中的 AI 生成痕迹。\n"
" 适用于编辑或审阅文本,使其听起来更自然。\n"
"---\n"
)
assert _parse_frontmatter_description(text) == (
"去除文本中的 AI 生成痕迹。\n适用于编辑或审阅文本,使其听起来更自然。"
)


def test_parse_frontmatter_multiline_folded_description():
text = (
"---\n"
"name: humanizer-zh\n"
"description: >\n"
" 去除文本中的 AI 生成痕迹。\n"
" 适用于编辑或审阅文本,使其听起来更自然。\n"
"---\n"
)
assert _parse_frontmatter_description(text) == (
"去除文本中的 AI 生成痕迹。 适用于编辑或审阅文本,使其听起来更自然。"
)


def test_parse_frontmatter_invalid_yaml_returns_empty():
text = "---\ndescription: [broken\n---\n"
assert _parse_frontmatter_description(text) == ""


# ---------- build_skills_prompt tests ----------


Expand Down
Loading