Enforce Birch skill staging and normalize CSS marker
Browse files
research/agent-cards/birch-html.md
CHANGED
|
@@ -6,6 +6,8 @@ servers:
|
|
| 6 |
- hf
|
| 7 |
skills:
|
| 8 |
- skills/birch-html
|
|
|
|
|
|
|
| 9 |
use_history: false
|
| 10 |
model: $system.html
|
| 11 |
tool_hooks:
|
|
@@ -17,6 +19,14 @@ Use the Birch HTML skill for polished, shareable, source-grounded HTML reports,
|
|
| 17 |
briefings, dashboards, explainers, visual summaries, and presentation-style
|
| 18 |
deliverables.
|
| 19 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 20 |
You receive researched content, source notes, and an output path from the
|
| 21 |
research agent. Produce a complete Birch HTML artifact and save it under the
|
| 22 |
provided `output/` bucket path. Use `scratch/` only for temporary drafts or
|
|
@@ -36,10 +46,12 @@ Preserve evidence:
|
|
| 36 |
and not-applicable artifacts.
|
| 37 |
|
| 38 |
Write the complete draft to `scratch/report.html` with the exact
|
| 39 |
-
`__BIRCH_SYSTEM_CSS__`
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
|
|
|
|
|
|
| 43 |
|
| 44 |
{{env}}
|
| 45 |
{{currentDate}}
|
|
|
|
| 6 |
- hf
|
| 7 |
skills:
|
| 8 |
- skills/birch-html
|
| 9 |
+
function_tools:
|
| 10 |
+
- ../birch_renderer.py:read_birch_skill_file
|
| 11 |
use_history: false
|
| 12 |
model: $system.html
|
| 13 |
tool_hooks:
|
|
|
|
| 19 |
briefings, dashboards, explainers, visual summaries, and presentation-style
|
| 20 |
deliverables.
|
| 21 |
|
| 22 |
+
Before calling any Hugging Face tool or drafting HTML:
|
| 23 |
+
|
| 24 |
+
1. Call `read_birch_skill_file(path="SKILL.md")`.
|
| 25 |
+
2. Call `read_birch_skill_file(path="resources/template.html")`.
|
| 26 |
+
3. Read the one or two recipes most relevant to the report.
|
| 27 |
+
4. Follow the canonical template and primitives exactly. Do not recreate Birch
|
| 28 |
+
typography, shells, cards, grids, tables, badges, or colors in local CSS.
|
| 29 |
+
|
| 30 |
You receive researched content, source notes, and an output path from the
|
| 31 |
research agent. Produce a complete Birch HTML artifact and save it under the
|
| 32 |
provided `output/` bucket path. Use `scratch/` only for temporary drafts or
|
|
|
|
| 46 |
and not-applicable artifacts.
|
| 47 |
|
| 48 |
Write the complete draft to `scratch/report.html` with the exact
|
| 49 |
+
`<style data-birch-system>__BIRCH_SYSTEM_CSS__</style>` element, verify that the
|
| 50 |
+
draft was written, and return only the draft path and a concise staging note.
|
| 51 |
+
Do not call Hugging Face Jobs, sandboxes, or a remote finalizer. Do not write
|
| 52 |
+
`output/report.html`. The host application deterministically injects the trusted
|
| 53 |
+
bundled stylesheet and publishes `output/report.html` after the research agent
|
| 54 |
+
returns.
|
| 55 |
|
| 56 |
{{env}}
|
| 57 |
{{currentDate}}
|
research/agent-cards/research.md
CHANGED
|
@@ -52,6 +52,11 @@ only after it verifies a self-contained file with substantive embedded
|
|
| 52 |
report the exact failure and the usable Markdown path. Never manually upload
|
| 53 |
placeholder HTML and describe it as polished.
|
| 54 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
{{env}}
|
| 56 |
{{currentDate}}
|
| 57 |
{{serverInstructions}}
|
|
|
|
| 52 |
report the exact failure and the usable Markdown path. Never manually upload
|
| 53 |
placeholder HTML and describe it as polished.
|
| 54 |
|
| 55 |
+
After the `birch-html` subagent returns, do not inspect, copy, rewrite, validate,
|
| 56 |
+
or publish its draft. Do not call another tool and never write
|
| 57 |
+
`output/report.html`. End the turn with the staged draft path; host finalization
|
| 58 |
+
is the only publisher.
|
| 59 |
+
|
| 60 |
{{env}}
|
| 61 |
{{currentDate}}
|
| 62 |
{{serverInstructions}}
|
research/app_artifacts.py
CHANGED
|
@@ -19,6 +19,10 @@ STYLE_RE = re.compile(
|
|
| 19 |
r"<style\b(?=[^>]*\bdata-birch-system\b)[^>]*>.*?</style>",
|
| 20 |
re.I | re.S,
|
| 21 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
|
| 24 |
def finalize_bucket_html(
|
|
@@ -58,7 +62,7 @@ def finalize_bucket_html(
|
|
| 58 |
return _artifact_urls(username, job.id)
|
| 59 |
|
| 60 |
css = _birch_css_path(home).read_text()
|
| 61 |
-
finalized =
|
| 62 |
_validate_html(finalized)
|
| 63 |
api.batch_bucket_files(
|
| 64 |
bucket_id,
|
|
@@ -98,6 +102,14 @@ def read_bucket_markdown(
|
|
| 98 |
return local.read_text()
|
| 99 |
|
| 100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 101 |
def _download_first(
|
| 102 |
api: Any,
|
| 103 |
bucket_id: str,
|
|
|
|
| 19 |
r"<style\b(?=[^>]*\bdata-birch-system\b)[^>]*>.*?</style>",
|
| 20 |
re.I | re.S,
|
| 21 |
)
|
| 22 |
+
MARKER_STYLE_RE = re.compile(
|
| 23 |
+
rf"<style\b[^>]*>\s*{re.escape(MARKER)}\s*</style>",
|
| 24 |
+
re.I | re.S,
|
| 25 |
+
)
|
| 26 |
|
| 27 |
|
| 28 |
def finalize_bucket_html(
|
|
|
|
| 62 |
return _artifact_urls(username, job.id)
|
| 63 |
|
| 64 |
css = _birch_css_path(home).read_text()
|
| 65 |
+
finalized = _inject_birch_css(html, css)
|
| 66 |
_validate_html(finalized)
|
| 67 |
api.batch_bucket_files(
|
| 68 |
bucket_id,
|
|
|
|
| 102 |
return local.read_text()
|
| 103 |
|
| 104 |
|
| 105 |
+
def _inject_birch_css(html: str, css: str) -> str:
|
| 106 |
+
"""Normalize a marker-only style element and inject trusted Birch CSS."""
|
| 107 |
+
replacement = f"<style data-birch-system>{css.strip()}</style>"
|
| 108 |
+
if MARKER_STYLE_RE.search(html):
|
| 109 |
+
return MARKER_STYLE_RE.sub(replacement, html, count=1)
|
| 110 |
+
return html.replace(MARKER, css.strip())
|
| 111 |
+
|
| 112 |
+
|
| 113 |
def _download_first(
|
| 114 |
api: Any,
|
| 115 |
bucket_id: str,
|