| 1 | # Agent Zero - Core Plugins |
| 2 | |
| 3 | This directory contains the system-level plugins bundled with Agent Zero. |
| 4 | |
| 5 | ## Directory Structure |
| 6 | |
| 7 | - `plugins/`: Core system plugins. Reserved for framework updates — do not place custom plugins here. |
| 8 | - `usr/plugins/`: The correct location for all user-developed and custom plugins. This directory is gitignored. |
| 9 | |
| 10 | ## Documentation |
| 11 | |
| 12 | For detailed guides on how to create, extend, or configure plugins, refer to: |
| 13 | |
| 14 | - [`plugins/AGENTS.md`](AGENTS.md): Bundled and custom plugin architecture, manifest format, extension points, banners, and Plugin Index submission rules. |
| 15 | - [`docs/developer/plugins.md`](../docs/developer/plugins.md): Human-facing developer guide covering the full plugin lifecycle. |
| 16 | - [`AGENTS.md`](../AGENTS.md): Main framework guide and backend context. |
| 17 | - [`skills/a0-plugin-router/SKILL.md`](../skills/a0-plugin-router/SKILL.md): Agent-facing entry point that routes plugin tasks to the appropriate specialist skill. |
| 18 | - [`skills/a0-create-plugin/SKILL.md`](../skills/a0-create-plugin/SKILL.md): Agent-facing authoring workflow (local and community plugins). |
| 19 | |
| 20 | ## What a Plugin Can Provide |
| 21 | |
| 22 | Plugins are automatically discovered based on the presence of a `plugin.yaml` file. Each plugin can contribute: |
| 23 | |
| 24 | - **Backend**: API handlers, tools, helpers, named lifecycle extensions, and implicit `@extensible` hooks under `extensions/python/_functions/...` |
| 25 | - **Frontend**: HTML/JS UI contributions via core extension breakpoints |
| 26 | - **Settings**: Isolated configuration scoped per-project and per-agent profile |
| 27 | - **Activation**: Global and scoped ON/OFF rules via `.toggle-1` and `.toggle-0` files, including advanced per-scope switching in the WebUI |
| 28 | - **Agent profiles**: Plugin-distributed subagent definitions under `agents/<profile>/agent.yaml` |
| 29 | |
| 30 | Backend extension layouts: |
| 31 | - `extensions/python/<point>/` for named lifecycle hooks |
| 32 | - `extensions/python/_functions/<module>/<qualname>/<start|end>/` for implicit `@extensible` hooks |
| 33 | |
| 34 | Do not use the retired flattened `extensions/python/<module>_<qualname>_<start|end>/` form. |
| 35 | |
| 36 | ## Plugin Manifest |
| 37 | |
| 38 | Every plugin requires a `plugin.yaml` at its root: |
| 39 | |
| 40 | ```yaml |
| 41 | name: my_plugin # required for community plugins |
| 42 | title: My Plugin |
| 43 | description: What this plugin does. |
| 44 | version: 1.0.0 |
| 45 | settings_sections: |
| 46 | - agent |
| 47 | per_project_config: false |
| 48 | per_agent_config: false |
| 49 | always_enabled: false |
| 50 | ``` |
| 51 | |
| 52 | ## Plugin Script (`execute.py`) |
| 53 | |
| 54 | Plugins can include an optional `execute.py` at the plugin root for user-triggered operations such as setup, post-install steps, maintenance, repairs, migrations, or resource refreshes. Users trigger it from the Plugin List UI. |
| 55 | |
| 56 | Guidelines: |
| 57 | - Treat it as a manual plugin script, not as the primary way to use the plugin |
| 58 | - Prefer making it safe to rerun, or detect state and explain why a rerun is not appropriate |
| 59 | - Return `0` on success and print progress messages for user feedback |
| 60 | - Use `hooks.py` instead when the behavior is framework-internal or should happen automatically |
| 61 | |
| 62 | ## Runtime Hooks (`hooks.py`) |
| 63 | |
| 64 | Plugins can also include an optional `hooks.py` at the plugin root. The framework loads it on demand and can call exported hook functions by name through `helpers.plugins.call_plugin_hook(...)`. |
| 65 | |
| 66 | - `hooks.py` runs inside the **Agent Zero framework runtime and Python environment**. |
| 67 | - Use it for framework-internal work such as install hooks, cache preparation, registration, or filesystem setup. |
| 68 | - If it runs `sys.executable -m pip install ...`, packages are installed into the same Python environment that runs Agent Zero. |
| 69 | - If you need to install into the separate agent runtime or into the system environment, explicitly target that environment from a subprocess by selecting the correct interpreter, virtualenv, or package manager. |
| 70 | |
| 71 | In Docker, `hooks.py` normally affects `/opt/venv-a0`; the agent execution runtime is `/opt/venv`. |
| 72 | |
| 73 | ### Configuration Hook Context |
| 74 | |
| 75 | Configuration hooks can distinguish why settings are being read or saved. Pass |
| 76 | `caller="ui"` or `caller="agent"` to `get_plugin_config(...)` or |
| 77 | `save_plugin_config(...)`; calls without it keep the compatible default, |
| 78 | `"api"`. |
| 79 | |
| 80 | The hook receives this as `hook_context={"caller": ...}`: |
| 81 | |
| 82 | ```python |
| 83 | def get_plugin_config(default=None, hook_context=None, **kwargs): |
| 84 | caller = (hook_context or {}).get("caller", "api") |
| 85 | if caller == "ui": |
| 86 | return redact_for_display(default) |
| 87 | return default |
| 88 | ``` |
| 89 | |
| 90 | Existing hooks need no change: hooks that ignore `hook_context`, including |
| 91 | strict signatures without `**kwargs`, retain their previous behavior. Use the |
| 92 | context only for behavior selection in plugin-controlled flows; it is not an |
| 93 | authorization boundary. A `config.html` alone does not set the caller; the |
| 94 | backend code loading or saving that configuration must pass it explicitly. |
| 95 | |
| 96 | ## Plugin Index & Community Sharing |
| 97 | |
| 98 | The **Plugin Index** at https://github.com/agent0ai/a0-plugins is the community-maintained registry of plugins available to all Agent Zero users. |
| 99 | |
| 100 | To share a plugin with the community: |
| 101 | |
| 102 | 1. Create a standalone GitHub repository with the plugin contents at the repo root. The runtime `plugin.yaml` must include a `name` field matching the intended index folder name. Add a `LICENSE` file at the repo root (required for Plugin Index listings so users have explicit terms of use). |
| 103 | 2. Fork `https://github.com/agent0ai/a0-plugins` and add a folder `plugins/<your_plugin_name>/` containing a separate index manifest named `index.yaml` (not `plugin.yaml`): |
| 104 | |
| 105 | ```yaml |
| 106 | title: My Plugin |
| 107 | description: What this plugin does. |
| 108 | github: https://github.com/yourname/your-plugin-repo |
| 109 | tags: |
| 110 | - tools |
| 111 | ``` |
| 112 | |
| 113 | Optional additional fields: `screenshots` (up to 5 image URLs). |
| 114 | |
| 115 | 3. Open a Pull Request. CI validates the submission; a maintainer reviews and merges. |
| 116 | |
| 117 | Note: The index `index.yaml` is a **different file with a different schema** from the runtime `plugin.yaml`. Folder names use `^[a-z0-9_]+$` (underscores, no hyphens) and must match the `name` field in the remote `plugin.yaml` exactly. |
| 118 | |
| 119 | ## Plugin Hub |
| 120 | |
| 121 | Agent Zero now includes a built-in Plugin Hub flow through the always-enabled **Plugin Installer** plugin. From the **Plugins** dialog, users can either open the **Browse** tab or click **Install**, which opens the installer modal on its own **Browse** tab. |
| 122 | |
| 123 | The Plugin Hub surfaces Plugin Index entries directly in the UI and lets users search, filter, inspect, and install community plugins without leaving Agent Zero. |