From 9d986421a0ca240556dfcce30be92621a9195cfc Mon Sep 17 00:00:00 2001 From: Yiorgis Gozadinos Date: Thu, 26 Mar 2026 11:29:46 +0200 Subject: [PATCH] add visualize_chunk to generated skills and built-in RAG skill --- CHANGELOG.md | 8 ++++++++ docs/skills/index.md | 9 +++++++++ .../rag/skill_generator/templates/__init__.py.j2 | 11 +++++++++++ tests/test_skill_generator.py | 13 +++++++++++++ 4 files changed, 41 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3c78b55..e0b5bf5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # Changelog ## [Unreleased] +### Added + +- **Chunk visualization for generated skills**: `visualize_chunk(chunk_id)` function exposed in generated skill packages, enabling callers to render visual grounding from chunk IDs in skill state + +### Fixed + +- **Generated skill packages**: Include SKILL.md and assets in wheel distributions. Add README to generated packages. + ## [0.35.1] - 2026-03-24 ### Added diff --git a/docs/skills/index.md b/docs/skills/index.md index ffed1e87..4d59c49f 100644 --- a/docs/skills/index.md +++ b/docs/skills/index.md @@ -63,6 +63,15 @@ haiku-skills chat --use-entrypoints --skill recipes Since each generated skill is self-contained with its own database and instructions, you can generate multiple skills for different domains and run them together. The agent sees each skill's description and routes questions to the appropriate knowledge base automatically. +Generated skills also expose `visualize_chunk()` for rendering visual grounding. Use chunk IDs from citations or search results in state: + +```python +from my_skill import visualize_chunk + +images = await visualize_chunk(chunk_id) +# Returns list of PIL Images with highlighted bounding boxes +``` + See [CLI: Create Skill](../cli.md#create-skill) for all options. ## Database Path Resolution diff --git a/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 b/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 index 47c94b89..eaf36767 100644 --- a/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 +++ b/haiku_rag_slim/haiku/rag/skill_generator/templates/__init__.py.j2 @@ -75,3 +75,14 @@ def create_skill() -> Skill: state_type=SkillState, state_namespace="{{ name }}", ) + + +async def visualize_chunk(chunk_id: str) -> list: + from haiku.rag.client import HaikuRAG + + config = _get_config() + async with HaikuRAG(_DB_PATH, config=config, read_only=True) as rag: + chunk = await rag.get_chunk_by_id(chunk_id) + if chunk is None: + return [] + return await rag.visualize_chunk(chunk) diff --git a/tests/test_skill_generator.py b/tests/test_skill_generator.py index 9197295d..37f3d06c 100644 --- a/tests/test_skill_generator.py +++ b/tests/test_skill_generator.py @@ -260,6 +260,19 @@ class TestRenderTemplates: assert "recipes" in content assert "haiku-rag" in content + def test_visualize_chunk_function_present(self, tmp_path): + render_templates( + output_dir=tmp_path, + name="docs", + description="A docs skill.", + tool_names=["search"], + ) + init = tmp_path / "docs-skill" / "docs_skill" / "__init__.py" + content = init.read_text() + assert "async def visualize_chunk(chunk_id: str)" in content + assert "skill_visualize_chunk" not in content + assert "HaikuRAG" in content + def test_generated_python_is_valid(self, tmp_path): render_templates( output_dir=tmp_path,