include SKILL.md and assets in generated skill package wheels. Add README to generated skills

This commit is contained in:
Yiorgis Gozadinos 2026-03-26 10:49:57 +02:00
parent f5014f39bf
commit ffc70be7b0
No known key found for this signature in database
4 changed files with 78 additions and 0 deletions

View file

@ -99,6 +99,10 @@ def render_templates(
template = env.get_template("pyproject.toml.j2")
(result_dir / "pyproject.toml").write_text(template.render(context))
# Render README.md
template = env.get_template("README.md.j2")
(result_dir / "README.md").write_text(template.render(context))
# Render __init__.py
template = env.get_template("__init__.py.j2")
(pkg_dir / "__init__.py").write_text(template.render(context))

View file

@ -0,0 +1,11 @@
# {{ name }}-skill
{{ description }}
This skill package was generated by [`haiku-rag create-skill`](https://ggozad.github.io/haiku.rag/).
## Installation
```bash
pip install {{ name }}-skill/
```

View file

@ -6,6 +6,7 @@ build-backend = "setuptools.build_meta"
name = "{{ name }}-skill"
version = "0.1.0"
description = "{{ description }}"
readme = "README.md"
requires-python = ">=3.12"
dependencies = [
"haiku.rag-slim >= {{ rag_version }}",
@ -14,3 +15,6 @@ dependencies = [
[project.entry-points."haiku.skills"]
{{ name }} = "{{ pkg_name }}_skill:create_skill"
[tool.setuptools.package-data]
{{ pkg_name }}_skill = ["SKILL.md", "assets/**/*"]

View file

@ -1,3 +1,7 @@
import shutil
import subprocess
import zipfile
import pytest
from haiku.rag.skill_generator import (
@ -95,6 +99,7 @@ class TestRenderTemplates:
)
assert result == tmp_path / "recipes-skill"
assert result.is_dir()
assert (result / "README.md").is_file()
pkg = result / "recipes_skill"
assert (pkg / "__init__.py").is_file()
assert (pkg / "SKILL.md").is_file()
@ -164,8 +169,11 @@ class TestRenderTemplates:
content = toml.read_text()
assert 'name = "recipes-skill"' in content
assert 'description = "A recipe skill."' in content
assert 'readme = "README.md"' in content
assert 'recipes = "recipes_skill:create_skill"' in content
assert "haiku.rag-slim >= " in content
assert "[tool.setuptools.package-data]" in content
assert 'recipes_skill = ["SKILL.md", "assets/**/*"]' in content
def test_skill_md_conditionals(self, tmp_path):
render_templates(
@ -240,6 +248,18 @@ class TestRenderTemplates:
content = init.read_text()
assert "from haiku.rag.skills._tools import create_skill_tools" in content
def test_readme(self, tmp_path):
render_templates(
output_dir=tmp_path,
name="recipes",
description="A recipe skill.",
tool_names=["search"],
)
readme = tmp_path / "recipes-skill" / "README.md"
content = readme.read_text()
assert "recipes" in content
assert "haiku-rag" in content
def test_generated_python_is_valid(self, tmp_path):
render_templates(
output_dir=tmp_path,
@ -350,3 +370,42 @@ class TestGenerateSkill:
skill_md = result / "recipes_skill" / "SKILL.md"
content = skill_md.read_text()
assert "You are a recipe expert." in content
def test_wheel_includes_package_data(self, tmp_path):
if not shutil.which("uv"):
pytest.skip("uv not available")
db_path = _make_fake_lancedb(tmp_path / "test.lancedb")
config_file = tmp_path / "haiku.rag.yaml"
config_file.write_text("storage:\n data_dir: /tmp\n")
result = generate_skill(
db_path=db_path,
output_dir=tmp_path,
name="recipes",
description="A recipe skill.",
tool_names=["search"],
config_path=config_file,
)
dist_dir = result / "dist"
subprocess.check_call(
[
"uv",
"run",
"--with",
"build",
"--no-project",
"python",
"-m",
"build",
"--wheel",
"--outdir",
str(dist_dir),
str(result),
]
)
wheels = list(dist_dir.glob("*.whl"))
assert len(wheels) == 1
with zipfile.ZipFile(wheels[0]) as zf:
names = zf.namelist()
assert any(n.endswith("SKILL.md") for n in names)
assert any("assets/" in n and n.endswith("data.lance") for n in names)
assert any(n.endswith("haiku.rag.yaml") for n in names)