Add browser skill discovery triggers

Add trigger frontmatter for browser automation and browser form workflow skills so relevant-skill recall surfaces them for rendered browsing, screenshots, host-browser, and form-heavy tasks. Update build-skill guidance to document trigger metadata and add regression coverage for parsing and ranking the browser skills.

Alessandro committed Jun 16, 2026 at 13:19 UTC ec3c4cf81b83812fed9e9061dff56b3d38110998
7 files changed +96 -4
plugins/_browser/AGENTS.md
+1
@@ -23,6 +23,7 @@
23
24 - Coordinate tool, helper, and panel changes so browser state shown in the UI matches tool behavior.
25 - Keep `prompts/agent.system.tool.browser.md` as a compact callable contract; move detailed browser workflows into `skills/browser-automation/SKILL.md`.
26 +- Keep `skills/browser-automation/SKILL.md` frontmatter triggers current with rendered browsing, host-browser, screenshot, and web-interaction user phrasing so relevant-skill recall can surface the skill before the full browser workflow is needed.
27 - Keep fragile form guidance progressively disclosed through `skills/browser-form-workflows/SKILL.md`, linked from the browser prompt through `browser-automation`.
28
29 ## Verification
plugins/_browser/skills/browser-automation/SKILL.md
+17
@@ -1,6 +1,23 @@
1 ---
2 name: browser-automation
3 description: Use for complex Agent Zero browser automation, including multi-tab browsing, screenshots, forms, uploads, raw pointer/keyboard actions, host-vs-container browser mode, and visual verification workflows.
4 +triggers:
5 + - "browser automation"
6 + - "web automation"
7 + - "open website"
8 + - "open URL"
9 + - "navigate browser"
10 + - "interact with web page"
11 + - "JavaScript page"
12 + - "browser screenshot"
13 + - "screenshot webpage"
14 + - "visual verification"
15 + - "multi-tab browsing"
16 + - "download file from website"
17 + - "upload file in browser"
18 + - "host browser"
19 + - "local browser"
20 + - "my browser"
21 ---
22
23 # Browser Tool
plugins/_browser/skills/browser-form-workflows/SKILL.md
+13
@@ -1,6 +1,19 @@
1 ---
2 name: browser-form-workflows
3 description: Use for complex Agent Zero Browser form workflows involving selects, checkboxes, radios, file uploads, contenteditable fields, multi-step validation, or visually verified submission.
4 +triggers:
5 + - "browser form"
6 + - "web form"
7 + - "fill form"
8 + - "fill web form"
9 + - "submit form"
10 + - "select option"
11 + - "dropdown"
12 + - "checkbox"
13 + - "radio button"
14 + - "file upload"
15 + - "contenteditable"
16 + - "form validation"
17 ---
18
19 # Browser Forms
skills/build-skill/AGENTS.md
+1
@@ -18,6 +18,7 @@
18 ## Work Guidance
19
20 - Update this skill when skill metadata, discovery, or validation behavior changes.
21 +- Keep frontmatter examples aligned with runtime-supported discovery fields such as `triggers`.
22 - Keep examples concise and avoid duplicating long reference material in the skill body.
23
24 ## Verification
skills/build-skill/SKILL.md
+6 -4
@@ -19,12 +19,14 @@ skill-name/
19 └── assets/ # optional output resources or templates
20 ```
21
22 -The frontmatter should contain only `name` and `description`:
22 +The frontmatter should contain `name`, `description`, and optional `triggers` when lexical discovery needs phrases that do not fit naturally in the description:
23
24 ```yaml
25 ---
26 name: skill-name
27 -description: What the skill does and when to use it. Include trigger wording here because this is the part visible before the skill loads.
27 +description: What the skill does and when to use it.
28 +triggers:
29 + - "user phrase that should surface this skill"
30 ---
31 ```
32
@@ -34,7 +36,7 @@ Use lowercase letters, digits, and hyphens. Prefer short verb-led names such as
36
37 1. Identify two or three real user requests that should trigger the skill.
38 2. Decide whether the skill belongs in core `skills/` or inside a plugin's `plugins/<plugin>/skills/` directory.
37 -3. Write the frontmatter description with all trigger conditions and key contexts.
39 +3. Write the frontmatter description with the core trigger condition and key context; add `triggers` for short user phrases that should rank highly in skill search or relevant-skill recall.
40 4. Keep the body focused on procedure, contracts, failure handling, and the files/scripts to load next.
41 5. Move long examples, schemas, policies, or variant-specific detail to one-level-deep `references/` files.
42 6. Add scripts only for deterministic or repeatedly rewritten operations, and test representative scripts.
@@ -48,7 +50,7 @@ Use root `skills/` for Agent Zero framework workflows that are not owned by one
50
51 ## Writing Rules
52
51 -- Put trigger language in `description`, not in a body section. The body is loaded only after the skill is already selected.
53 +- Put trigger language in frontmatter, not in a body section. Use `description` for the compact always-visible purpose and `triggers` for phrase matches used by search and relevant-skill recall.
54 - Do not add README, changelog, quick reference, or install guide files inside the skill.
55 - Avoid compatibility aliases in prompts or skill bodies when renaming; update references to the new name.
56 - Prefer concise examples over long prose.
tests/test_browser_agent_regressions.py
+8
@@ -934,9 +934,17 @@ def test_browser_skills_are_plugin_owned_and_progressively_linked():
934 automation = automation_path.read_text(encoding="utf-8")
935 skill = skill_path.read_text(encoding="utf-8")
936 assert skill.startswith("---\n")
937 + automation_frontmatter = automation.split("---", 2)[1]
938 frontmatter = skill.split("---", 2)[1]
939 + assert "name: browser-automation" in automation_frontmatter
940 + assert "triggers:" in automation_frontmatter
941 + assert "browser screenshot" in automation_frontmatter
942 + assert "host browser" in automation_frontmatter
943 assert "name: browser-form-workflows" in frontmatter
944 assert "description:" in frontmatter
945 + assert "triggers:" in frontmatter
946 + assert "fill web form" in frontmatter
947 + assert "file upload" in frontmatter
948 assert "progressive-disclosure workflow guide" in automation
949 assert "`browser-form-workflows` with `skills_tool:load`" in automation
950 assert 'skill_name: "browser-form-workflows"' in automation
tests/test_skills_runtime.py
+50
@@ -330,12 +330,62 @@ def test_renamed_skills_use_standard_frontmatter_only():
330 expected_keys = {"name", "description"}
331 if path.parent.name == "host-computer-use":
332 expected_keys.update({"tags", "triggers"})
333 + if path.parent.name in {"browser-automation", "browser-form-workflows"}:
334 + expected_keys.add("triggers")
335 assert set(frontmatter) == expected_keys
336 assert frontmatter["name"] == path.parent.name
337 assert frontmatter["description"]
338 assert body
339
340
341 +def test_browser_skills_rank_for_browser_trigger_phrases(monkeypatch):
342 + browser_automation = runtime.skill_from_markdown(
343 + PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-automation" / "SKILL.md"
344 + )
345 + browser_forms = runtime.skill_from_markdown(
346 + PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-form-workflows" / "SKILL.md"
347 + )
348 + document_query = runtime.skill_from_markdown(
349 + PROJECT_ROOT / "plugins" / "_document_query" / "skills" / "document-query" / "SKILL.md"
350 + )
351 + host_computer = runtime.skill_from_markdown(
352 + PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "host-computer-use" / "SKILL.md"
353 + )
354 + assert browser_automation is not None
355 + assert browser_forms is not None
356 + assert document_query is not None
357 + assert host_computer is not None
358 + monkeypatch.setattr(
359 + runtime,
360 + "list_skills",
361 + lambda *args, **kwargs: [
362 + document_query,
363 + host_computer,
364 + browser_forms,
365 + browser_automation,
366 + ],
367 + )
368 +
369 + browser_queries = (
370 + "open this URL in my browser and take a screenshot",
371 + "interact with a JavaScript page and verify it visually",
372 + "use the host browser for multi-tab browsing",
373 + )
374 + for query in browser_queries:
375 + results = runtime.search_skills(query, limit=3)
376 + assert results[0].name == "browser-automation"
377 +
378 + form_results = [
379 + skill.name
380 + for skill in runtime.search_skills(
381 + "fill a web form with a checkbox and file upload",
382 + limit=3,
383 + )
384 + ]
385 + assert "browser-automation" in form_results
386 + assert "browser-form-workflows" in form_results
387 +
388 +
389 def test_host_computer_use_ranks_before_linux_desktop_for_host_screen_queries(monkeypatch):
390 host_skill = runtime.skill_from_markdown(
391 PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "host-computer-use" / "SKILL.md"