refactor: align skills and tool guidance
Some checks are pending
Build And Publish Docker Images / plan (push) Waiting to run
Build And Publish Docker Images / build (push) Blocked by required conditions

Rename high-impact skills to task-oriented names and move plugin-owned skills into their owning plugin folders.\n\nAlign renamed skill frontmatter with the official SKILL.md standard by keeping trigger language in name/description metadata, replacing the old create-skill wizard with build-skill, and updating browser, A0 connector, computer-use, CLI setup, and scheduler skill references.\n\nTighten the recurring cross-provider guidance gaps surfaced by the evidence sweeps: memory requests now avoid promptinclude-file routing, scheduler prompts distinguish cron schedules from planned ISO dates, document questions prefer document_query, skills_tool search/read_file usage is clearer, normal notifications set info/priority 10, and local/host text editors preserve patch intent.\n\nUpdate regression tests for the renamed skills, plugin ownership, prompt budget reality, and standard frontmatter shape.
This commit is contained in:
Alessandro 2026-05-10 07:13:14 +02:00
parent 79fe46cd7b
commit 6d29268cbd
29 changed files with 243 additions and 424 deletions

View file

@ -229,7 +229,7 @@ from your own browser:
If another agent is helping with setup, do not paste a whole checklist. Paste one line:
```text
Set up the A0 CLI connector for Agent Zero on this machine using the a0-setup-cli Skill.
Set up the A0 CLI connector for Agent Zero on this machine using the setup-a0-cli Skill.
```
## Troubleshooting

View file

@ -4,7 +4,7 @@ Runs shell-backed execution on the machine where a connected A0 CLI is running.
Use this tool, not `code_execution_tool`, when the user asks for the connected
local terminal, the A0 CLI host, their local machine, or explicitly says not to
use Docker/server/container execution.
For complex local project work, optionally load skill `code-execution-remote`.
For complex local project work, optionally load skill `host-code-execution`.
Availability and permissions are checked when the tool runs. If no CLI is
connected, remote execution is disabled, or local access is not Read&Write for a

View file

@ -3,7 +3,7 @@
Reads, writes, and patches files on the machine where a connected A0 CLI is
running. Use this tool, not server-side file tools, when the user asks for files
on the connected local machine, A0 CLI host, or explicitly says not to use
Docker/server files. For complex remote edits, optionally load skill `text-editor-remote`.
Docker/server files. For complex remote edits, optionally load skill `host-file-editing`.
Availability and permissions are checked when the tool runs. If no CLI is
connected, remote file access is disabled, or a write/patch needs Read&Write,
@ -18,6 +18,7 @@ report that to the user instead of falling back to server-side file tools.
## Notes
- Prefer `read` before line-number edits.
- If the user says patch, change without rewriting, or don't rewrite, use `action: "patch"` instead of `write`.
- Prefer `patch_text` for context-anchored changes and `edits` only for fresh, surgical line ranges.
- If freshness checks reject a line patch, reread the file and retry with updated ranges.
- Relative paths are relative to the CLI host filesystem. Do not rewrite them to

View file

@ -1,28 +1,9 @@
---
name: code-execution-remote
description: Guide safe use of code_execution_remote for shell-backed execution on the connected A0 CLI host machine.
version: 1.0.0
author: Agent Zero Team
tags: ["agent-zero", "a0", "cli", "connector", "remote-execution", "shell"]
trigger_patterns:
- "code_execution_remote"
- "remote shell execution"
- "run commands on the cli host"
- "run python on the cli host"
- "run node on the cli host"
- "connected local terminal"
- "connected terminal"
- "local terminal"
- "my terminal"
- "a0 cli"
- "cli host"
- "not docker"
- "not the docker terminal"
allowed_tools:
- code_execution_remote
name: host-code-execution
description: Guide safe use of code_execution_remote for shell-backed execution on the connected A0 CLI host. Use when the user asks for their computer, local terminal, CLI host, remote shell, not Docker, or host-side Python/Node/terminal commands.
---
# Code Execution Remote
# Host Code Execution
## Boundary

View file

@ -1,22 +1,9 @@
---
name: computer-use-remote
description: Beta local desktop control through a connected A0 CLI host; use for screenshots, menus, browser chrome, and native UI tasks.
version: 1.1.0
author: Agent Zero Team
tags: ["computer-use", "desktop", "local-ui", "screenshots", "native-ui"]
trigger_patterns:
- "computer use"
- "computer-use"
- "computer_use_remote"
- "local desktop control"
- "control local browser"
- "click on screen"
- "native ui"
allowed_tools:
- computer_use_remote
name: host-computer-use
description: Beta desktop control through the connected A0 CLI host. Use when the user asks for computer use, screenshots, screen inspection, menus, browser chrome, native UI tasks, clicking, scrolling, typing, or checking computer_use_remote status.
---
# Computer Use Remote
# Host Computer Use
This skill unlocks the beta `computer_use_remote` tool for connected local desktop control through A0 CLI.
@ -26,7 +13,7 @@ Load this skill before using `computer_use_remote` for local desktop and native
If the task is browser-only and the user is flexible, prefer direct browser tooling because it is usually more reliable and token-efficient than screenshot-driven desktop control.
If the task needs shell execution on the CLI host, load `code-execution-remote` separately rather than treating desktop control and shell execution as one affordance.
If the task needs shell execution on the CLI host, load `host-code-execution` separately rather than treating desktop control and shell execution as one affordance.
## Tool Contract

View file

@ -1,25 +1,9 @@
---
name: text-editor-remote
description: Guide safe use of text_editor_remote for reading, writing, and patching files on the connected A0 CLI host machine.
version: 1.0.0
author: Agent Zero Team
tags: ["agent-zero", "a0", "cli", "connector", "remote-files", "file-editing"]
trigger_patterns:
- "text_editor_remote"
- "remote file editing"
- "edit my local files through a0 cli"
- "read files on the cli host"
- "patch files on the cli host"
- "connected local files"
- "connected local machine files"
- "local files not docker"
- "a0 cli files"
- "cli host files"
allowed_tools:
- text_editor_remote
name: host-file-editing
description: Guide safe use of text_editor_remote for reading, writing, and patching files on the connected A0 CLI host. Use when the user asks to inspect or edit files on their computer, local files, CLI host files, or files that are explicitly not Docker/server files.
---
# Text Editor Remote
# Host File Editing
## Boundary

View file

@ -1,20 +1,6 @@
---
name: a0-setup-cli
description: Guide the user through installing and connecting the A0 CLI on the host machine so Dockerized Agent Zero can work on real local files. Use when asked to install A0, set up the CLI connector, connect Agent Zero to local files, or troubleshoot host-vs-container setup confusion.
version: 1.1.0
author: Agent Zero Team
tags: ["agent-zero", "a0", "cli", "connector", "docker", "setup", "local-files"]
trigger_patterns:
- "install a0"
- "install a0 cli"
- "set up a0 cli"
- "set up a0 cli connector"
- "connect a0 to agent zero"
- "connect agent zero to local files"
- "let agent zero work on my local files"
- "install the terminal connector"
- "help me set up the a0 cli connector"
- "install a0 connector"
name: setup-a0-cli
description: Guide installing, connecting, or troubleshooting the A0 CLI connector on the user's host machine so Dockerized Agent Zero can work on real local files. Use for install A0, set up A0 CLI, connect local files, remote tools, host-vs-container confusion, or CLI connector setup problems.
---
# A0 CLI Host Setup

View file

@ -84,7 +84,7 @@ def install_chrome_web_store_extension(source: str) -> dict[str, Any]:
extension_id = parse_chrome_web_store_extension_id(source)
target = get_extensions_root() / "chrome-web-store" / extension_id
with tempfile.TemporaryDirectory(prefix="a0-browser-ext-") as tmp:
with tempfile.TemporaryDirectory(prefix="browser-extension-control-") as tmp:
archive_path = Path(tmp) / f"{extension_id}.crx"
_download_crx(extension_id, archive_path)
payload_path = Path(tmp) / f"{extension_id}.zip"

View file

@ -1,11 +1,11 @@
### browser
Rendered browser automation for pages that need interaction, JavaScript, forms, downloads, screenshots, or visual inspection.
Prefer `search_engine` or `document_query` for plain text research. Use the browser headlessly unless the user opens the Browser surface or asks for a visible browser.
Prefer `search_engine` or `document_query` for plain text research. The tool must not open a Browser surface automatically. Use the tool headlessly unless the user opens the Browser surface or asks for the optional visible WebUI viewer.
The browser may run in Docker container mode or A0 CLI host-browser mode depending on settings. Container-mode paths resolve inside Agent Zero; host-mode paths resolve on the connected A0 CLI host.
For complex browser workflows, load skill `browser-tool`. For fragile forms, load skill `browser-forms`.
For complex browser workflows, load skill `browser-automation`. For fragile forms, load skill `browser-form-workflows`.
Actions: `open`, `list`, `state`, `set_active`, `navigate`, `back`, `forward`, `reload`, `content`, `detail`, `screenshot`, `click`, `hover`, `double_click`, `right_click`, `drag`, `type`, `submit`, `type_submit`, `scroll`, `evaluate`, `key_chord`, `mouse`, `wheel`, `keyboard`, `clipboard`, `set_viewport`, `select_option`, `set_checked`, `upload_file`, `multi`, `close`, `close_all`.
@ -16,7 +16,7 @@ Workflow:
- `content` returns markdown with refs like `[link 3]`, `[button 6]`, `[input text 8]`.
- Interactions use refs from the latest `content` capture.
- `navigate` reuses an existing `browser_id` and is preferred for serial browsing.
- Screenshots are explicit only; call `vision_load` with the returned path before reasoning visually.
- Screenshots are explicit only; the browser does not automatically load screenshots. Call `vision_load` with the returned path before reasoning visually.
- Keep the tab set small; close pages after extracting what you need.
`multi` is only a browser action: use `tool_name: "browser"` with `tool_args.action: "multi"`. Never use `tool_name: "multi"`.

View file

@ -1,5 +1,5 @@
---
name: browser-tool
name: browser-automation
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.
---
@ -39,7 +39,7 @@ Screenshot args include `quality`, `full_page`, and optional `path`. PNG is used
- `select_option` works for native selects and detectable ARIA listbox/combobox controls.
- `set_checked` works for checkbox, radio, switch, and toggle-like refs.
- `upload_file` works for file input refs or associated labels; verify the file exists in the active browser environment.
- For fragile forms, load skill `browser-forms`.
- For fragile forms, load skill `browser-form-workflows`.
## Pointer And Keyboard

View file

@ -1,7 +1,6 @@
---
name: a0-browser-ext
description: Create, inspect, install, and safely maintain Chrome extensions for Agent Zero's built-in Browser plugin.
tags: ["agent-zero", "browser", "chrome-extension", "playwright", "manifest-v3"]
name: browser-extension-control
description: Create, inspect, install, and safely maintain Chrome extensions for Agent Zero's built-in Browser plugin. Use when the user asks to build a browser extension, modify an existing extension, install a Chrome Web Store extension, or review extension permissions.
---
# Agent Zero Browser Extensions

View file

@ -1,5 +1,5 @@
---
name: browser-forms
name: browser-form-workflows
description: Use for complex Agent Zero Browser form workflows involving selects, checkboxes, radios, file uploads, contenteditable fields, multi-step validation, or visually verified submission.
---

View file

@ -446,7 +446,7 @@ const model = {
createExtensionWithAgent() {
this._prefillAgentPrompt(
[
"Use the a0-browser-ext skill to create a new Chrome extension for Agent Zero's Browser.",
"Use the browser-extension-control skill to create a new Chrome extension for Agent Zero's Browser.",
"Start by asking me for the extension name, purpose, target websites, and required permissions.",
`Create it under ${this.extensionsRoot || EXTENSIONS_ROOT}/<extension-slug> and keep permissions minimal.`,
].join("\n")
@ -457,12 +457,12 @@ const model = {
const url = String(this.extensionInstallUrl || "").trim();
const prompt = url
? [
"Use the a0-browser-ext skill to review and optionally install this Chrome Web Store extension for Agent Zero's Browser.",
"Use the browser-extension-control skill to review and optionally install this Chrome Web Store extension for Agent Zero's Browser.",
`Chrome Web Store URL or id: ${url}`,
"Explain the permissions and any sandbox risk before enabling it.",
].join("\n")
: [
"Use the a0-browser-ext skill to help me install and review a Chrome Web Store extension for Agent Zero's Browser.",
"Use the browser-extension-control skill to help me install and review a Chrome Web Store extension for Agent Zero's Browser.",
"Ask me for the Chrome Web Store URL or extension id first.",
"Explain the permissions and any sandbox risk before enabling it.",
].join("\n");

View file

@ -1,9 +1,10 @@
# Behavioral prompt includes
"{{name_pattern}}" files in workdir auto-injected into system prompt
create/edit/delete persist across conversations
preference change/remember/note > MUST persist via text_editor before responding
never just acknowledge verbally always persist to file
use for persistent notes knowledge project context
preference changes, instruction files, project notes, and prompt includes > persist via text_editor before responding
explicit memory requests like "remember this", "what did I ask you to remember", or "forget this" > use memory tools, not promptinclude files, unless the user asks to edit a file
never just acknowledge durable project/instruction changes verbally; persist them to file when the user asks for a file/instruction/preference change
use promptinclude files for persistent project context and behavioral instructions
recursive search alphabetical by full path
{{if includes}}
### includes

View file

@ -45,6 +45,7 @@ usage:
#### patch
edit existing file. prefer patch_text; use edits only right after read for tiny line edits
if the user says patch, change without rewriting, or don't rewrite, use action patch instead of write
args path plus exactly one of: patch_text string OR edits [{from to content}]
patch_text uses current file content, no prior read required
patch_text update-only forms:

View file

@ -1,5 +1,6 @@
## skills
use `skills_tool` action `search` when the user's wording sounds like a task, trigger phrase, or keyword match for a skill
if the user asks to find/search a skill, search first before loading
use `skills_tool` action `list` when you need a broader catalog view
use `skills_tool` action `load` before following a skill
loaded skills may document beta/specialized tools not in the always-on tool list; use them only after loading the skill

View file

@ -1,5 +1,6 @@
### document_query
read local or remote documents or answer questions about them
prefer this over text_editor when the user says "check/read this document" or asks a question about a document path/url, even for Markdown files
args:
- `document`: url path or list of them
- `queries`: optional list of questions

View file

@ -3,4 +3,6 @@ send an out-of-band notification without ending the current task
args: `message`, optional `title`, `detail`, `type`, `priority`, `timeout`
types: `info`, `success`, `warning`, `error`, `progress`
priority values: `20` high urgency, `10` normal urgency; omit for high
normal note/notification -> set `type: "info"` and `priority: 10`
use `success` only for a completed success message, not for a generic note
use for progress or alerts, not as the final answer

View file

@ -1,5 +1,5 @@
### scheduler
Manage saved tasks and schedules. For complex task work, load skill `scheduler-tasks`.
Manage saved tasks and schedules. For complex task work, load skill `scheduled-tasks`.
Actions: `list_tasks`, `find_task_by_name`, `show_task`, `run_task`, `update_task`, `delete_task`, `create_scheduled_task`, `create_adhoc_task`, `create_planned_task`, `wait_for_task`.
@ -10,4 +10,7 @@ Rules:
- Do not run scheduled/planned tasks unless the user asks to run now.
- Do not create recursive task prompts that schedule more tasks.
- New tasks use a dedicated context unless `dedicated_context` is `false`.
- Use IANA timezones like `Europe/Rome`; omit timezone to use the current user timezone.
- Use `create_scheduled_task` for recurring/cron tasks; `schedule` must be cron fields, not an ISO datetime.
- For one planned date/time, use `create_planned_task` with `plan: ["YYYY-MM-DDTHH:MM:SS"]`.
- Use IANA timezones like `Europe/Rome`; include timezone when the user names a timezone.
- For "tomorrow at 9:15 Rome time", scheduled shape is `schedule: {"minute":"15","hour":"9","day":"11","month":"5","weekday":"*","timezone":"Europe/Rome"}`.

View file

@ -7,6 +7,8 @@ workflow:
- action `list`: discover available skills
- action `load`: load one skill by `skill_name`
- action `read_file`: open one file inside a loaded skill directory
if the user says "find/search a skill", call `search` before `load` even when the likely skill name seems obvious
`read_file` requires both `skill_name` and `file_path`; load the skill first, then read `SKILL.md` or the named relative file
after loading a skill, follow its instructions and use referenced files or scripts with other tools
reload a skill if its instructions are no longer in context
example:

View file

@ -33,7 +33,7 @@ This skill provides comprehensive, accurate guidance for extending and building
- Build **API Endpoints** for the Web UI
- Create **Agent Profiles** (subordinates) with custom prompts
- Understand and extend the **Prompt System**
- Create **Skills** (see the dedicated `create-skill` skill for the full wizard)
- Create **Skills** (see the dedicated `build-skill` skill for the full wizard)
- Work with **Projects** and workspace configuration
> **Path convention:** Throughout this guide, `/a0/` refers to the framework root — this is `/a0/` inside Docker, or your local repository root in development. All paths are relative to this root.
@ -41,7 +41,7 @@ This skill provides comprehensive, accurate guidance for extending and building
> [!IMPORTANT]
> **Plugins are the primary way to extend Agent Zero.** Most new tools, extensions, and prompts should be packaged as plugins. For all plugin tasks (create, review, manage, debug, contribute), load the `a0-plugin-router` skill which routes to the appropriate specialist. This guide covers the underlying framework patterns that plugins build upon.
Related skills: `a0-plugin-router` (plugin tasks) | `create-skill` (skill creation wizard) | `a0-create-plugin` | `a0-review-plugin` | `a0-manage-plugin` | `a0-contribute-plugin` | `a0-debug-plugin`
Related skills: `a0-plugin-router` (plugin tasks) | `build-skill` (skill creation wizard) | `a0-create-plugin` | `a0-review-plugin` | `a0-manage-plugin` | `a0-contribute-plugin` | `a0-debug-plugin`
---
@ -631,7 +631,7 @@ The agent interacts with skills through JSON tool calls:
{"tool_name": "skills_tool:load", "tool_args": {"skill_name": "my-skill"}}
```
> For the complete skill creation wizard — including SKILL.md format, frontmatter fields, directory structure, best practices, and examples — load the `create-skill` skill.
> For the complete skill creation wizard — including SKILL.md format, frontmatter fields, directory structure, best practices, and examples — load the `build-skill` skill.
---

View file

@ -0,0 +1,72 @@
---
name: build-skill
description: Build or improve Agent Zero skills following the official SKILL.md standard. Use when the user asks to create, rename, move, audit, test, or refactor a skill, or when a workflow should be packaged as reusable skill instructions.
---
# Build Skill
Skills are small folders that teach Agent Zero a repeatable workflow. Keep the always-visible metadata precise, keep `SKILL.md` lean, and move detailed material into scripts, references, or assets only when the task needs it.
## Standard Shape
Every skill folder must be named exactly like the skill and contain `SKILL.md`.
```text
skill-name/
├── SKILL.md
├── scripts/ # optional deterministic helpers
├── references/ # optional details loaded only when needed
└── assets/ # optional output resources or templates
```
The frontmatter should contain only `name` and `description`:
```yaml
---
name: skill-name
description: What the skill does and when to use it. Include trigger wording here because this is the part visible before the skill loads.
---
```
Use lowercase letters, digits, and hyphens. Prefer short verb-led names such as `build-skill`, `review-plugin`, or `host-file-editing`.
## Workflow
1. Identify two or three real user requests that should trigger the skill.
2. Decide whether the skill belongs in core `skills/` or inside a plugin's `plugins/<plugin>/skills/` directory.
3. Write the frontmatter description with all trigger conditions and key contexts.
4. Keep the body focused on procedure, contracts, failure handling, and the files/scripts to load next.
5. Move long examples, schemas, policies, or variant-specific detail to one-level-deep `references/` files.
6. Add scripts only for deterministic or repeatedly rewritten operations, and test representative scripts.
7. Validate by searching, loading, and using the skill on a median-user prompt.
## Placement
Use plugin-scoped skills when the skill exists to explain a plugin-owned tool or UI surface. Examples: Browser workflows belong under `_browser`; A0 CLI host tools belong under `_a0_connector`; Desktop canvas workflows belong under `_desktop`.
Use root `skills/` for Agent Zero framework workflows that are not owned by one plugin, such as building skills, developing core features, or managing community plugins.
## Writing Rules
- Put trigger language in `description`, not in a body section. The body is loaded only after the skill is already selected.
- Do not add README, changelog, quick reference, or install guide files inside the skill.
- Avoid compatibility aliases in prompts or skill bodies when renaming; update references to the new name.
- Prefer concise examples over long prose.
- Do not duplicate the same guidance in both `SKILL.md` and references.
- When multiple skills could apply, keep each skill's responsibility narrow and name the handoff clearly.
## Validation
Run targeted checks after edits:
```bash
conda run -n a0 pytest tests/test_skills_runtime.py tests/test_tool_action_contracts.py -q
```
Also exercise the live path when the skill changes agent-facing tool behavior:
```text
1. Ask a short ordinary prompt that should discover the skill.
2. Confirm the agent uses skills_tool search/load when appropriate.
3. Confirm it calls the intended tool only after the skill is loaded when the tool is skill-gated.
```

View file

@ -1,288 +0,0 @@
---
name: "create-skill"
description: "Wizard for creating new Agent Zero skills. Guides users through creating well-structured SKILL.md files. Use when users want to create custom skills."
version: "1.0.0"
author: "Agent Zero Team"
tags: ["meta", "wizard", "creation", "tutorial", "skills"]
trigger_patterns:
- "create skill"
- "new skill"
- "make skill"
- "add skill"
- "skill wizard"
---
# Create Skill Wizard
This skill helps you create new Agent Zero skills that follow the SKILL.md standard.
## Quick Start
To create a new skill, I'll guide you through these steps:
1. **Name & Purpose** - What should this skill do?
2. **Trigger Patterns** - When should this skill activate?
3. **Content Structure** - What instructions should the agent follow?
4. **Supporting Files** - Any scripts or templates needed?
## SKILL.md Format
Every skill needs a `SKILL.md` file with YAML frontmatter:
```yaml
---
name: "skill-name"
description: "Clear description of what this skill does and when to use it"
version: "1.0.0"
author: "Your Name"
tags: ["category1", "category2"]
trigger_patterns:
- "keyword1"
- "phrase that triggers this"
---
# Skill Title
Your skill instructions go here...
```
## Required Fields
| Field | Description | Example |
|-------|-------------|---------|
| `name` | Unique identifier (lowercase, hyphens) | `"code-review"` |
| `description` | When/why to use this skill | `"Review code for quality and security issues"` |
## Optional Fields
| Field | Description | Example |
|-------|-------------|---------|
| `version` | Semantic version | `"1.0.0"` |
| `author` | Creator name | `"Jane Developer"` |
| `tags` | Categorization keywords | `["review", "quality"]` |
| `trigger_patterns` | Words/phrases that activate skill | `["review", "check code"]` |
| `allowed_tools` | Tools this skill can use | `["code_execution", "web_search"]` |
## Skill Directory Structure
```
/a0/usr/skills/
└── my-skill/
├── SKILL.md # Required: Main skill file
├── scripts/ # Optional: Helper scripts
│ ├── helper.py
│ └── process.sh
├── templates/ # Optional: Templates
│ └── output.md
└── docs/ # Optional: Additional docs
└── examples.md
```
## Writing Good Skill Instructions
### Be Specific and Actionable
```markdown
# Good
When reviewing code:
1. Check for security vulnerabilities
2. Verify error handling
3. Assess test coverage
# Bad
Review the code and make it better.
```
### Include Examples
```markdown
## Example Usage
**User**: "Review my Python function for issues"
**Agent Response**:
> I'll review your function using the code review checklist:
>
> 1. **Security**: No user input validation detected
> 2. **Error Handling**: Missing try-catch for file operations
> 3. **Testing**: Function is testable but no tests found
```
### Provide Checklists
```markdown
## Review Checklist
- [ ] Input validation present
- [ ] Error handling complete
- [ ] Tests included
- [ ] Documentation updated
```
## Creating Your Skill: Step by Step
### Step 1: Define Purpose
Answer these questions:
- What problem does this skill solve?
- When should the agent use it?
- What's the expected output?
### Step 2: Choose a Name
- Use lowercase letters and hyphens
- Be descriptive but concise
- Examples: `code-review`, `data-analysis`, `deploy-helper`
### Step 3: Write Trigger Patterns
List words/phrases that should activate this skill:
```yaml
trigger_patterns:
- "review"
- "check code"
- "code quality"
- "pull request"
```
### Step 4: Structure Your Content
Organize with clear sections:
```markdown
# Skill Title
## When to Use
Describe the trigger conditions
## The Process
Step-by-step instructions
## Examples
Show sample interactions
## Tips
Additional guidance
```
### Step 5: Add Supporting Files (Optional)
If your skill needs scripts or templates:
```bash
# Create directory structure
mkdir -p /a0/usr/skills/my-skill/{scripts,templates,docs}
```
## Example: Complete Skill
```yaml
---
name: "python-optimizer"
description: "Optimize Python code for performance and readability. Use when asked to improve or optimize Python code."
version: "1.0.0"
author: "Agent Zero Team"
tags: ["python", "optimization", "performance"]
trigger_patterns:
- "optimize python"
- "improve performance"
- "make faster"
- "python optimization"
---
# Python Optimizer
## When to Use
Activate when user asks to optimize, improve, or speed up Python code.
## Optimization Process
### Step 1: Profile First
Before optimizing, understand where time is spent:
```python
import cProfile
cProfile.run('your_function()')
```
### Step 2: Common Optimizations
1. **Use List Comprehensions**
```python
# Slow
result = []
for x in data:
result.append(x * 2)
# Fast
result = [x * 2 for x in data]
```
2. **Use Sets for Lookups**
```python
# Slow: O(n)
if item in large_list:
# Fast: O(1)
if item in large_set:
```
3. **Use Generators for Large Data**
```python
# Memory-heavy
data = [process(x) for x in huge_list]
# Memory-efficient
data = (process(x) for x in huge_list)
```
### Step 3: Verify Improvement
Always measure before and after:
```python
import time
start = time.perf_counter()
# code to measure
elapsed = time.perf_counter() - start
print(f"Took {elapsed:.4f} seconds")
```
## Anti-Patterns to Avoid
- Premature optimization
- Optimizing without profiling
- Sacrificing readability for tiny gains
```
## Skill Installation
### Local Installation
1. Create skill directory:
```bash
mkdir -p /a0/usr/skills/my-skill
```
2. Create SKILL.md:
```bash
touch /a0/usr/skills/my-skill/SKILL.md
```
3. Add content and save
4. Skills are automatically loaded on next agent initialization
### Sharing Skills
To share skills with others:
1. Create a GitHub repository
2. Include the skill directory structure
3. Add a README with installation instructions
4. Users can copy to their `/a0/usr/skills/` directory
## Testing Your Skill
After creating a skill:
1. Start a new conversation
2. Use one of your trigger patterns
3. Verify the agent follows your instructions
4. Iterate and improve based on results

View file

@ -1,5 +1,5 @@
---
name: scheduler-tasks
name: scheduled-tasks
description: Use for complex Agent Zero scheduler work, including creating, updating, deleting, running, waiting for, timezone-correcting, or auditing scheduled, planned, and adhoc tasks.
---
@ -22,7 +22,7 @@ Use the `scheduler` tool to manage saved tasks. Always inspect existing tasks be
## Schedule Fields
Schedules use cron-like fields:
Schedules use cron-like fields. Do not put ISO datetimes into `schedule`.
- `minute`
- `hour`
@ -31,7 +31,38 @@ Schedules use cron-like fields:
- `weekday`
- `timezone`
Use IANA timezones such as `Europe/Rome`. Omit timezone to use the current user timezone. Planned task datetimes should be ISO strings such as `2026-05-09T18:25:00`.
Use IANA timezones such as `Europe/Rome`. Omit timezone to use the current user timezone. Planned task datetimes go in `plan`, not `schedule`, and should be ISO strings such as `2026-05-09T18:25:00`.
For one future reminder, prefer `create_planned_task` with:
```json
{
"action": "create_planned_task",
"name": "drink water",
"prompt": "Remind the user to drink water.",
"plan": ["2026-05-11T09:15:00"],
"dedicated_context": true
}
```
For a recurring or cron-shaped scheduled task, use `create_scheduled_task` with:
```json
{
"action": "create_scheduled_task",
"name": "weekday stretch",
"prompt": "Remind the user to stretch.",
"schedule": {
"minute": "15",
"hour": "9",
"day": "*",
"month": "*",
"weekday": "1-5",
"timezone": "Europe/Rome"
},
"dedicated_context": true
}
```
## Safety

View file

@ -133,7 +133,14 @@ def test_remote_file_and_exec_tools_are_standard_tool_prompts_independent_from_c
def test_beta_computer_use_remote_is_skill_only_not_standard_tool_prompt():
skill = PROJECT_ROOT / "skills" / "computer-use-remote" / "SKILL.md"
skill = (
PROJECT_ROOT
/ "plugins"
/ "_a0_connector"
/ "skills"
/ "host-computer-use"
/ "SKILL.md"
)
assert not (PROMPT_ROOT / "agent.system.tool.computer_use_remote.md").exists()
assert '"tool_name": "computer_use_remote"' in skill.read_text(encoding="utf-8")
@ -288,7 +295,7 @@ def test_remote_affordance_skills_parse():
/ "plugins"
/ "_a0_connector"
/ "skills"
/ "text-editor-remote"
/ "host-file-editing"
/ "SKILL.md"
)
code_execution_skill = _parse_skill_frontmatter(
@ -296,32 +303,43 @@ def test_remote_affordance_skills_parse():
/ "plugins"
/ "_a0_connector"
/ "skills"
/ "code-execution-remote"
/ "host-code-execution"
/ "SKILL.md"
)
computer_skill = _parse_skill_frontmatter(
PROJECT_ROOT / "skills" / "computer-use-remote" / "SKILL.md"
PROJECT_ROOT
/ "plugins"
/ "_a0_connector"
/ "skills"
/ "host-computer-use"
/ "SKILL.md"
)
assert not legacy_connector_skill.exists()
assert text_editor_skill["name"] == "text-editor-remote"
assert text_editor_skill["allowed_tools"] == ["text_editor_remote"]
assert "connected local files" in text_editor_skill["trigger_patterns"]
assert "not docker" in code_execution_skill["trigger_patterns"]
assert "connected local terminal" in code_execution_skill["trigger_patterns"]
assert code_execution_skill["name"] == "code-execution-remote"
assert code_execution_skill["allowed_tools"] == ["code_execution_remote"]
assert computer_skill["name"] == "computer-use-remote"
assert computer_skill["allowed_tools"] == ["computer_use_remote"]
assert text_editor_skill["name"] == "host-file-editing"
assert "text_editor_remote" in text_editor_skill["description"]
assert "not Docker/server files" in text_editor_skill["description"]
assert code_execution_skill["name"] == "host-code-execution"
assert "code_execution_remote" in code_execution_skill["description"]
assert "not Docker" in code_execution_skill["description"]
assert computer_skill["name"] == "host-computer-use"
assert "computer_use_remote" in computer_skill["description"]
def test_remote_tool_stubs_are_self_contained_and_reference_per_tool_skills():
text_stub = (PROMPT_ROOT / "agent.system.tool.text_editor_remote.md").read_text(encoding="utf-8")
exec_stub = (PROMPT_ROOT / "agent.system.tool.code_execution_remote.md").read_text(encoding="utf-8")
computer_skill = (PROJECT_ROOT / "skills" / "computer-use-remote" / "SKILL.md").read_text(encoding="utf-8")
computer_skill = (
PROJECT_ROOT
/ "plugins"
/ "_a0_connector"
/ "skills"
/ "host-computer-use"
/ "SKILL.md"
).read_text(encoding="utf-8")
assert "optionally load skill `text-editor-remote`" in text_stub
assert "optionally load skill `code-execution-remote`" in exec_stub
assert "optionally load skill `host-file-editing`" in text_stub
assert "optionally load skill `host-code-execution`" in exec_stub
assert '"tool_name": "text_editor_remote"' in text_stub
assert '"tool_name": "code_execution_remote"' in exec_stub
assert '"tool_name": "computer_use_remote"' in computer_skill

View file

@ -528,7 +528,14 @@ def test_browser_extension_menu_exposes_agent_and_url_paths():
html = (PROJECT_ROOT / "plugins" / "_browser" / "webui" / "browser-panel.html").read_text(
encoding="utf-8"
)
skill = PROJECT_ROOT / "skills" / "a0-browser-ext" / "SKILL.md"
skill = (
PROJECT_ROOT
/ "plugins"
/ "_browser"
/ "skills"
/ "browser-extension-control"
/ "SKILL.md"
)
assert "Create New Extension with A0" in html
assert "+ Create New with A0" not in html
@ -902,19 +909,19 @@ def test_browser_tool_does_not_auto_open_canvas_policy_is_documented():
assert "select_option" in prompt
assert "set_checked" in prompt
assert "upload_file" in prompt
assert "browser-forms" in prompt
assert "browser-form-workflows" in prompt
assert "does not automatically load screenshots" in prompt
assert "already open" in config
assert "already-open Browser surface" in config_html
def test_browser_forms_skill_is_plugin_owned_and_discoverable():
skill_path = PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-forms" / "SKILL.md"
skill_path = PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-form-workflows" / "SKILL.md"
assert skill_path.exists()
skill = skill_path.read_text(encoding="utf-8")
assert skill.startswith("---\n")
frontmatter = skill.split("---", 2)[1]
assert "name: browser-forms" in frontmatter
assert "name: browser-form-workflows" in frontmatter
assert "description:" in frontmatter
assert "select_option" in skill
assert "set_checked" in skill

View file

@ -46,9 +46,13 @@ async def _build_system_text(profile: str = "agent0") -> str:
async def test_default_agent0_prompt_budget_and_guardrails():
system_text = await _build_system_text()
assert tokens.approximate_tokens(system_text) <= 3000
assert "tool_name` must exactly match a listed tool name" in system_text
assert "tool_args` must stay a json object" in system_text
# The default prompt now intentionally includes the compact always-on tool
# surface plus skill metadata. Keep the guardrail close to the observed
# budget so prompt creep remains visible without pretending this surface is
# a tiny single-tool prompt.
assert tokens.approximate_tokens(system_text) <= 8500
assert "`tool_name` must be one listed tool name" in system_text
assert "- tool_args: key value pairs tool arguments" in system_text
assert '"tool_name": "call_subordinate"' in system_text
assert '"reset": true' in system_text
assert '"tool_name": "text_editor"' in system_text
@ -59,7 +63,7 @@ async def test_default_agent0_prompt_budget_and_guardrails():
assert '"tool_name": "code_execution_remote"' in system_text
assert '"tool_name": "text_editor_remote"' in system_text
assert '"tool_name": "computer_use_remote"' not in system_text
assert "computer-use-remote" in system_text
assert "host-computer-use" in system_text
def test_a0_small_profile_removed_and_prompt_text_generic():

View file

@ -198,13 +198,13 @@ def test_reactivating_name_only_scope_default_by_path_clears_hidden_override(mon
def test_loaded_skill_entries_come_from_agent_data():
agent = DummyAgent()
agent.data[runtime.AGENT_DATA_NAME_LOADED_SKILLS] = [
"computer-use-remote",
"host-computer-use",
"",
"a0-development",
]
assert runtime.get_loaded_skill_entries(agent) == [
{"name": "computer-use-remote"},
{"name": "host-computer-use"},
{"name": "a0-development"},
]
@ -276,16 +276,41 @@ def test_a0_manage_plugin_skill_frontmatter_is_valid_yaml():
assert "Agent Zero Plugin Management" in body
def test_renamed_skills_use_standard_frontmatter_only():
skill_paths = [
PROJECT_ROOT / "skills" / "build-skill" / "SKILL.md",
PROJECT_ROOT / "skills" / "scheduled-tasks" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "host-code-execution" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "host-computer-use" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "host-file-editing" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_a0_connector" / "skills" / "setup-a0-cli" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-automation" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-extension-control" / "SKILL.md",
PROJECT_ROOT / "plugins" / "_browser" / "skills" / "browser-form-workflows" / "SKILL.md",
]
for path in skill_paths:
frontmatter, body, errors = runtime.split_frontmatter(path.read_text(encoding="utf-8"))
assert errors == []
assert set(frontmatter) == {"name", "description"}
assert frontmatter["name"] == path.parent.name
assert frontmatter["description"]
assert body
def test_unload_agent_skill_removes_loaded_skill_by_name():
agent = DummyAgent()
agent.data[runtime.AGENT_DATA_NAME_LOADED_SKILLS] = [
"computer-use-remote",
"host-computer-use",
"a0-development",
]
removed = runtime.unload_agent_skill(
agent,
{"name": "computer-use-remote", "path": "/a0/skills/computer-use-remote"},
{
"name": "host-computer-use",
"path": "/a0/plugins/_a0_connector/skills/host-computer-use",
},
)
assert removed is True

View file

@ -66,7 +66,7 @@ def _load_skills_tool(monkeypatch, skill_root: Path):
skills_stub.AGENT_DATA_NAME_LOADED_SKILLS = "loaded_skills"
skills_stub.MAX_ACTIVE_SKILLS = 20
fake_skill = _FakeSkill(
name="browser-forms",
name="browser-form-workflows",
description="Use for complex browser forms.",
path=skill_root,
tags=[],
@ -99,13 +99,13 @@ def test_skills_tool_accepts_action_alias_for_search(monkeypatch, tmp_path: Path
response = asyncio.run(tool.execute(**tool.args))
assert "browser-forms" in response.message
assert "browser-form-workflows" in response.message
def test_skills_tool_read_file_action_reads_inside_skill_dir(
monkeypatch, tmp_path: Path
):
skill_root = tmp_path / "browser-forms"
skill_root = tmp_path / "browser-form-workflows"
skill_root.mkdir()
(skill_root / "notes.md").write_text("Use labels before typing.\n", encoding="utf-8")
module = _load_skills_tool(monkeypatch, skill_root)
@ -115,7 +115,7 @@ def test_skills_tool_read_file_action_reads_inside_skill_dir(
None,
{
"action": "read_file",
"skill_name": "browser-forms",
"skill_name": "browser-form-workflows",
"file_path": "notes.md",
},
"",
@ -124,7 +124,7 @@ def test_skills_tool_read_file_action_reads_inside_skill_dir(
response = asyncio.run(tool.execute(**tool.args))
assert "Skill file: browser-forms/notes.md" in response.message
assert "Skill file: browser-form-workflows/notes.md" in response.message
assert "Use labels before typing." in response.message
@ -464,9 +464,10 @@ def test_computer_use_remote_is_skill_gated():
/ "plugins/_a0_connector/prompts/agent.system.tool.computer_use_remote.md"
)
skill_text = (
project_root / "skills/computer-use-remote/SKILL.md"
project_root
/ "plugins/_a0_connector/skills/host-computer-use/SKILL.md"
).read_text(encoding="utf-8")
assert not prompt_path.exists()
assert '"tool_name": "computer_use_remote"' in skill_text
assert "Beta local desktop control" in skill_text
assert "Beta desktop control" in skill_text