feat: open source yao-meta-skill

This commit is contained in:
yaojingang
2026-03-31 19:59:29 +08:00
commit d4eccba69e
19 changed files with 1364 additions and 0 deletions
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
import argparse
import json
from pathlib import Path
TEXT_EXTS = {".md", ".txt", ".yaml", ".yml", ".json", ".py", ".sh", ".js", ".ts"}
def estimate_tokens(text: str) -> int:
# Fast heuristic suitable for local gating.
return max(1, len(text) // 4)
def read_text(path: Path) -> str:
try:
return path.read_text(encoding="utf-8")
except UnicodeDecodeError:
return path.read_text(encoding="utf-8", errors="ignore")
def classify(path: Path) -> str:
parts = set(path.parts)
if path.name == "SKILL.md":
return "skill_body"
if "references" in parts:
return "reference"
if "scripts" in parts:
return "script"
if "assets" in parts:
return "asset"
if path.suffix in TEXT_EXTS:
return "other_text"
return "binary_or_other"
def summarize(skill_dir: Path) -> dict:
files = []
total_tokens = 0
initial_tokens = 0
for path in sorted(skill_dir.rglob("*")):
if not path.is_file():
continue
kind = classify(path)
if kind in {"binary_or_other", "asset"} and path.suffix not in TEXT_EXTS:
size = path.stat().st_size
files.append({"path": str(path.relative_to(skill_dir)), "kind": kind, "bytes": size})
continue
text = read_text(path)
tokens = estimate_tokens(text)
record = {
"path": str(path.relative_to(skill_dir)),
"kind": kind,
"chars": len(text),
"estimated_tokens": tokens,
}
files.append(record)
total_tokens += tokens
if kind in {"skill_body", "other_text"}:
initial_tokens += tokens
return {
"skill_dir": str(skill_dir),
"estimated_initial_load_tokens": initial_tokens,
"estimated_total_text_tokens": total_tokens,
"warning": initial_tokens > 2000,
"files": files,
}
def main() -> None:
parser = argparse.ArgumentParser(description="Estimate context size for a skill package.")
parser.add_argument("skill_dir", help="Path to the skill directory")
parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON")
args = parser.parse_args()
report = summarize(Path(args.skill_dir).resolve())
if args.json:
print(json.dumps(report, ensure_ascii=False, indent=2))
return
print(f"Skill: {report['skill_dir']}")
print(f"Estimated initial-load tokens: {report['estimated_initial_load_tokens']}")
print(f"Estimated total text tokens: {report['estimated_total_text_tokens']}")
print(f"Initial-load warning (>2000): {'YES' if report['warning'] else 'NO'}")
print("")
for file in report["files"]:
if "estimated_tokens" in file:
print(f"{file['kind']:12} {file['estimated_tokens']:6}t {file['path']}")
else:
print(f"{file['kind']:12} {file['bytes']:6}b {file['path']}")
if __name__ == "__main__":
main()
+171
View File
@@ -0,0 +1,171 @@
#!/usr/bin/env python3
import argparse
import json
import shutil
import zipfile
from pathlib import Path
def read_simple_yaml(path: Path) -> dict:
lines = path.read_text(encoding="utf-8").splitlines()
data: dict = {}
stack: list[tuple[int, dict]] = [(0, data)]
for raw_line in lines:
if not raw_line.strip() or raw_line.lstrip().startswith("#"):
continue
indent = len(raw_line) - len(raw_line.lstrip(" "))
line = raw_line.strip()
while len(stack) > 1 and indent <= stack[-1][0]:
stack.pop()
parent = stack[-1][1]
if line.startswith("- "):
item = line[2:].strip().strip("'\"")
existing = parent.setdefault("__list__", [])
existing.append(item)
continue
if ":" not in line:
continue
key, value = line.split(":", 1)
key = key.strip()
value = value.strip()
if value == "":
child: dict = {}
parent[key] = child
stack.append((indent, child))
else:
parent[key] = value.strip("'\"")
return data
def read_frontmatter(skill_md: Path) -> dict:
text = skill_md.read_text(encoding="utf-8")
if not text.startswith("---"):
return {}
parts = text.split("---", 2)
if len(parts) < 3:
return {}
data = {}
for line in parts[1].splitlines():
if ":" not in line:
continue
key, value = line.split(":", 1)
data[key.strip()] = value.strip().strip("'\"")
return data
def read_interface(skill_dir: Path) -> dict:
path = skill_dir / "agents" / "interface.yaml"
if not path.exists():
return {}
raw = read_simple_yaml(path)
compatibility = raw.get("compatibility", {})
targets = compatibility.get("adapter_targets", {})
if isinstance(targets, dict) and "__list__" in targets:
compatibility["adapter_targets"] = targets["__list__"]
raw["compatibility"] = compatibility
return raw
def build_manifest(skill_dir: Path, platform: str) -> dict:
frontmatter = read_frontmatter(skill_dir / "SKILL.md")
interface = read_interface(skill_dir).get("interface", {})
compatibility = read_interface(skill_dir).get("compatibility", {})
return {
"name": frontmatter.get("name", skill_dir.name),
"description": frontmatter.get("description", ""),
"version": frontmatter.get("version", "1.0.0"),
"platform": platform,
"skill_root": skill_dir.name,
"display_name": interface.get("display_name", skill_dir.name),
"short_description": interface.get("short_description", ""),
"default_prompt": interface.get("default_prompt", ""),
"canonical_metadata": "agents/interface.yaml",
"adapter_targets": compatibility.get("adapter_targets", []),
}
def write_yaml_like(path: Path, payload: dict) -> None:
interface = payload.get("interface", {})
lines = ["interface:"]
for key in ("display_name", "short_description", "default_prompt"):
value = interface.get(key, "")
lines.append(f' {key}: "{value}"')
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
def write_adapter(skill_dir: Path, out_dir: Path, platform: str) -> Path:
target_dir = out_dir / "targets" / platform
target_dir.mkdir(parents=True, exist_ok=True)
payload = build_manifest(skill_dir, platform)
if platform == "openai":
meta_dir = target_dir / "agents"
meta_dir.mkdir(parents=True, exist_ok=True)
write_yaml_like(
meta_dir / "openai.yaml",
{
"interface": {
"display_name": payload["display_name"],
"short_description": payload["short_description"],
"default_prompt": payload["default_prompt"],
}
},
)
payload["install_hint"] = f"Use the packaged skill and include targets/openai/agents/openai.yaml when the client expects OpenAI-style interface metadata."
elif platform == "claude":
notes = target_dir / "README.md"
notes.write_text(
f"# Claude-Compatible Package\n\nUse `{skill_dir.name}` with its neutral source files. This target does not require vendor metadata by default.\n",
encoding="utf-8",
)
payload["install_hint"] = f"Use the packaged skill directly; this target relies on SKILL.md and optional neutral metadata."
else:
payload["install_hint"] = f"Use {skill_dir.name} as an Agent Skills compatible package."
path = target_dir / "adapter.json"
path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8")
return path
def make_zip(skill_dir: Path, out_dir: Path) -> Path:
zip_path = out_dir / f"{skill_dir.name}.zip"
with zipfile.ZipFile(zip_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
for path in skill_dir.rglob("*"):
if path.is_file():
zf.write(path, arcname=str(path.relative_to(skill_dir.parent)))
return zip_path
def copy_manifest(skill_dir: Path, out_dir: Path) -> Path:
manifest_path = out_dir / "manifest.json"
manifest_path.write_text(
json.dumps(build_manifest(skill_dir, "generic"), ensure_ascii=False, indent=2),
encoding="utf-8",
)
return manifest_path
def main() -> None:
parser = argparse.ArgumentParser(description="Generate lightweight cross-platform packaging artifacts.")
parser.add_argument("skill_dir", help="Path to the skill directory")
parser.add_argument("--platform", action="append", default=[], help="Target platform: openai, claude, generic")
parser.add_argument("--output-dir", default="dist", help="Output directory")
parser.add_argument("--zip", action="store_true", help="Create a zip package")
args = parser.parse_args()
skill_dir = Path(args.skill_dir).resolve()
out_dir = Path(args.output_dir).resolve()
if out_dir.exists():
shutil.rmtree(out_dir)
out_dir.mkdir(parents=True)
manifest = copy_manifest(skill_dir, out_dir)
generated = [str(manifest)]
for platform in (args.platform or ["generic"]):
generated.append(str(write_adapter(skill_dir, out_dir, platform)))
if args.zip:
generated.append(str(make_zip(skill_dir, out_dir)))
print(json.dumps({"output_dir": str(out_dir), "generated": generated}, ensure_ascii=False, indent=2))
if __name__ == "__main__":
main()
+94
View File
@@ -0,0 +1,94 @@
#!/usr/bin/env python3
import argparse
import json
import re
from pathlib import Path
WORD_RE = re.compile(r"[a-zA-Z0-9][a-zA-Z0-9_-]*")
def words(text: str) -> set[str]:
return {w.lower() for w in WORD_RE.findall(text)}
def load_cases(path: Path) -> dict:
return json.loads(path.read_text(encoding="utf-8"))
def extract_description(text: str) -> str:
if not text.startswith("---"):
return text
parts = text.split("---", 2)
if len(parts) < 3:
return text
frontmatter = parts[1].splitlines()
for line in frontmatter:
if line.strip().startswith("description:"):
return line.split(":", 1)[1].strip().strip("'\"")
return text
def score_prompt(description_words: set[str], prompt: str) -> float:
prompt_words = words(prompt)
if not prompt_words:
return 0.0
overlap = description_words & prompt_words
return len(overlap) / len(prompt_words)
def evaluate(description: str, cases: dict, threshold: float) -> dict:
desc_words = words(description)
results = {"should_trigger": [], "should_not_trigger": []}
fp = 0
fn = 0
for bucket in ("should_trigger", "should_not_trigger"):
for prompt in cases.get(bucket, []):
score = score_prompt(desc_words, prompt)
predicted = score >= threshold
expected = bucket == "should_trigger"
passed = predicted == expected
if not passed and expected:
fn += 1
if not passed and not expected:
fp += 1
results[bucket].append(
{
"prompt": prompt,
"score": round(score, 3),
"predicted_trigger": predicted,
"passed": passed,
}
)
return {
"threshold": threshold,
"false_positives": fp,
"false_negatives": fn,
"results": results,
}
def main() -> None:
parser = argparse.ArgumentParser(description="Heuristic trigger quality evaluator.")
parser.add_argument("--description", help="Description string to evaluate")
parser.add_argument("--description-file", help="Read description text from file")
parser.add_argument("--cases", required=True, help="JSON file with should_trigger and should_not_trigger arrays")
parser.add_argument("--threshold", type=float, default=0.18, help="Token overlap threshold")
args = parser.parse_args()
description = args.description
if args.description_file:
description = extract_description(Path(args.description_file).read_text(encoding="utf-8"))
if not description:
raise SystemExit("Provide --description or --description-file")
report = evaluate(description, load_cases(Path(args.cases)), args.threshold)
print(json.dumps(report, ensure_ascii=False, indent=2))
if report["false_positives"] > 2:
raise SystemExit(2)
if __name__ == "__main__":
main()