update agents, human docs, plugin skill
Alessandro committed
Feb 22, 2026 at 19:37 UTC
6f6348850d9f24498d49ff185b17f9c47b7c9838
6 files changed
+330
-311
AGENTS.md
+177
-74
@@ -1,113 +1,216 @@
1
-# Agent Zero — Full-Stack Agent & Plugin Architecture
1
+# Agent Zero - AGENTS.md
2
3
-This document bridges the gap between the **Python Backend** (AgentContext, LLM loop) and the **Frontend Component System** (Alpine.js, Modals). Use this as the canonical reference for building deep integrations.
3
+[Generated using reconnaissance on 2026-02-22]
4
+
5
+## Quick Reference
6
+Tech Stack: Python 3.12+ | Flask | Alpine.js | LiteLLM | WebSocket (Socket.io)
7
+Dev Server: python run_ui.py (runs on http://localhost:50001 by default)
8
+Run Tests: pytest (standard) or pytest tests/test_name.py (file-scoped)
9
+Documentation: README.md | docs/
10
+Frontend Deep Dives: [Component System](docs/agents/AGENTS.components.md) | [Modal System](docs/agents/AGENTS.modals.md) | [Plugin Architecture](AGENTS.plugins.md)
11
12
---
13
7
-## 1. The Core Concept: `AgentContext`
14
+## Table of Contents
15
+1. [Project Overview](#project-overview)
16
+2. [Core Commands](#core-commands)
17
+3. [Docker Environment](#docker-environment)
18
+4. [Project Structure](#project-structure)
19
+5. [Development Patterns & Conventions](#development-patterns--conventions)
20
+6. [Safety and Permissions](#safety-and-permissions)
21
+7. [Code Examples](#code-examples)
22
+8. [Git Workflow](#git-workflow)
23
+9. [API Documentation](#api-documentation)
24
+10. [Troubleshooting](#troubleshooting)
25
+
26
+---
27
9
-Every conversation in Agent Zero is an `AgentContext`. It owns the message history, the LLM state, the tool definitions, and the log queue.
28
+## Project Overview
29
11
-### Backend: Managing Contexts
12
-When building a plugin, you must interact with the context system correctly:
30
+Agent Zero is a dynamic, organic agentic framework designed to grow and learn. It uses the operating system as a tool, featuring a multi-agent cooperation model where every agent can create subordinates to break down tasks.
31
14
-```python
15
-from agent import AgentContext, AgentContextType, initialize_agent
16
-from python.helpers.messages import UserMessage
32
+Type: Full-Stack Agentic Framework (Python Backend + Alpine.js Frontend)
33
+Status: Active Development
34
+Primary Language(s): Python, JavaScript (ES Modules)
35
18
-# 1. Access an existing context (e.g., from a stored ID)
19
-context = AgentContext.use(context_id)
36
+---
37
21
-# 2. Or create a new one
22
-config = {} # use defaults
23
-context = AgentContext(config=config, type=AgentContextType.USER)
24
-await initialize_agent(context)
38
+## Core Commands
39
26
-# 3. Communicate (send a message and wait for completion)
27
-task = context.communicate(UserMessage("Hello Agent!"))
28
-response_text = await task.result()
40
+### Setup
41
+Do not combine these commands; run them individually:
42
+```bash
43
+pip install -r requirements.txt
44
+pip install -r requirements2.txt
45
```
46
+- Start WebUI: python run_ui.py
47
31
-### The Glue: `MessageQueue` (mq)
32
-The frontend listens to a WebSocket. To make messages appear in the WebUI from your plugin, use the log helper:
48
+---
49
34
-```python
35
-# In your ApiHandler or bridge
36
-from python.helpers.messages import mq
50
+## Docker Environment
51
38
-# This makes the user message appear in the UI immediately
39
-mq.log_user_message(context.id, "Incoming message from WhatsApp", source="WhatsApp")
40
-```
52
+When running in Docker, Agent Zero uses two distinct Python runtimes to isolate the framework from the code being executed:
53
42
----
54
+### 1. Framework Runtime (/opt/venv-a0)
55
+- Version: Python 3.12.4
56
+- Purpose: Runs the Agent Zero backend, API, and core logic.
57
+- Packages: Contains all dependencies from requirements.txt.
58
+
59
+### 2. Execution Runtime (/opt/venv)
60
+- Version: Python 3.13
61
+- Purpose: Default environment for the interactive terminal and the agent's code execution tool.
62
+- Behavior: This is the environment active when you docker exec into the container. Packages installed by the agent via pip install during a task are stored here.
63
44
-## 2. The Frontend: Component System
64
+---
65
46
-Agent Zero uses a custom **Component Loader** that fetches HTML, extracts `<style>` and `<script type="module">`, and injects them into the DOM.
66
+## Project Structure
67
48
-### The "Golden Rules" of Frontend Components
68
+```
69
+/
70
+├── agent.py # Core Agent and AgentContext definitions
71
+├── initialize.py # Framework initialization logic
72
+├── models.py # LLM provider configurations
73
+├── run_ui.py # WebUI server entry point
74
+├── python/
75
+│ ├── api/ # API Handlers (ApiHandler subclasses)
76
+│ ├── extensions/ # Backend lifecycle extensions
77
+│ ├── helpers/ # Shared Python utilities (plugins, files, etc.)
78
+│ ├── tools/ # Agent tools (Tool subclasses)
79
+│ └── websocket_handlers/# WebSocket event handlers
80
+├── webui/
81
+│ ├── components/ # Alpine.js components
82
+│ ├── js/ # Core frontend logic (modals, stores, etc.)
83
+│ └── index.html # Main UI shell
84
+├── usr/ # User data directory (isolated from core)
85
+│ ├── plugins/ # Custom user plugins
86
+│ ├── settings.json # User-specific configuration
87
+│ └── workdir/ # Default agent workspace
88
+├── plugins/ # Core system plugins
89
+├── agents/ # Agent profiles (prompts and config)
90
+├── prompts/ # System and message prompt templates
91
+└── tests/ # Pytest suite
92
+```
93
50
-1. **Store Gating (Critical)**: Always wrap your component content in a template that waits for the store. This prevents "undefined" errors during the loading race.
51
- ```html
52
- <div x-data>
53
- <template x-if="$store.myStore">
54
- <div class="content">...</div>
55
- </template>
56
- </div>
57
- ```
58
-2. **Separate Store Files**: Never put store registration logic directly inside the HTML `alpine:init` block. Use a separate `*-store.js` file and import it via `<script type="module" src="...">`.
59
-3. **createStore Proxy**: Use `createStore` from `/js/AlpineStore.js`. It ensures the store is available to the module even before Alpine fully boots.
94
+Key Files:
95
+- agent.py: Defines AgentContext and the main Agent class.
96
+- python/helpers/plugins.py: Plugin discovery and configuration logic.
97
+- webui/js/AlpineStore.js: Store factory for reactive frontend state.
98
+- python/helpers/api.py: Base class for all API endpoints.
99
+- docs/agents/AGENTS.components.md: Deep dive into the frontend component architecture.
100
+- docs/agents/AGENTS.modals.md: Guide to the stacked modal system.
101
+- AGENTS.plugins.md: Comprehensive guide to the full-stack plugin system.
102
103
---
104
63
-## 3. The Modal System
105
+## Development Patterns & Conventions
106
+
107
+### Backend (Python)
108
+- Context Access: Use from agent import AgentContext, AgentContextType (not python.helpers.context).
109
+- Communication: Use mq from python.helpers.messages to log proactive UI messages:
110
+ mq.log_user_message(context.id, "Message", source="Plugin")
111
+- API Handlers: Derive from ApiHandler in python/helpers/api.py.
112
+- Extensions: Use the extension framework in python/helpers/extension.py for lifecycle hooks.
113
+- Error Handling: Use RepairableException for errors the LLM might be able to fix.
114
+
115
+### Frontend (Alpine.js)
116
+- Store Gating: Always wrap store-dependent content in a template:
117
+```html
118
+<div x-data>
119
+ <template x-if="$store.myStore">
120
+ <div x-init="$store.myStore.onOpen()">...</div>
121
+ </template>
122
+</div>
123
+```
124
+- Store Registration: Use createStore from /js/AlpineStore.js.
125
+- Modals: Use openModal(path) and closeModal() from /js/modals.js.
126
65
-Modals in A0 are "stacked" and loaded dynamically via `openModal(path)`.
127
+### Plugin Architecture
128
+- Location: Always develop new plugins in usr/plugins/.
129
+- Manifest: Every plugin requires a plugin.json with name, description, version, and optionally settings_sections.
130
+- Discovery: Conventions based on folder names (api/, tools/, webui/, extensions/).
131
+- Settings: Use get_plugin_config(plugin_name, agent=agent) to retrieve settings. Plugins can expose a UI for settings via webui/config.html. For plugins wrapping core settings, set $store.pluginSettings.saveMode = 'core' in x-init.
132
67
-### Directory Convention
68
-- `webui/components/modals/<feature>/<feature>.html`
69
-- `webui/components/modals/<feature>/<feature>-store.js`
133
+### Lifecycle Synchronization
134
+| Action | Backend Extension | Frontend Lifecycle |
135
+|---|---|---|
136
+| Initialization | agent_init | init() in Store |
137
+| Mounting | N/A | x-create directive |
138
+| Processing | monologue_start/end | UI loading state |
139
+| Cleanup | context_deleted | x-destroy directive |
140
71
-### Plugin Settings
141
+---
142
73
-Plugins get a dedicated settings modal with **Project** and **Agent profile** context selectors. To enable it:
143
+## Safety and Permissions
144
75
-1. Add `webui/config.html` to your plugin (auto-detected).
76
-2. Set `"settings_sections": ["agent"]` in `plugin.json` - this places a subsection with a Settings button in the chosen tab.
145
+### Allowed Without Asking
146
+- Read any file in the repository.
147
+- Update code files in usr/.
148
78
-Your `config.html` binds to `$store.pluginSettings.settings` (a plain object persisted as `config.json`). The modal's Save/Cancel footer handles persistence automatically. See `plugins/README.md` for the full contract and settings resolution priority chain.
149
+### Ask Before Executing
150
+- pip install (new dependencies).
151
+- Deleting core files outside of usr/ or tmp/.
152
+- Modifying agent.py or initialize.py.
153
+- Making git commits or pushes.
154
80
-For plugins that surface **existing core settings** (e.g. wrapping `settings/agent/memory.html`), set `$store.pluginSettings.saveMode = 'core'` in `x-init` to route Save through the core settings API instead.
155
+### Never Do
156
+- Commit, hardcode or leak secrets or .env files.
157
+- Bypass CSRF or authentication checks.
158
+- Hardcode API keys.
159
160
---
161
84
-## 4. Lifecycle Synchronization
162
+## Code Examples
163
86
-| Action | Backend Extension | Frontend Lifecycle |
87
-|---|---|---|
88
-| **Initialization** | `agent_init` | `init()` in Store |
89
-| **Mounting** | N/A | `x-create` directive |
90
-| **Processing** | `monologue_start/end` | UI loading state |
91
-| **Cleanup** | `context_deleted` | `x-destroy` directive |
164
+### API Handler (Good)
165
+```python
166
+from python.helpers.api import ApiHandler, Request, Response
167
+
168
+class MyHandler(ApiHandler):
169
+ async def process(self, input: dict, request: Request) -> dict | Response:
170
+ # Business logic here
171
+ return {"ok": True, "data": "result"}
172
+```
173
+
174
+### Alpine Store (Good)
175
+```javascript
176
+import { createStore } from "/js/AlpineStore.js";
177
+
178
+export const store = createStore("myStore", {
179
+ items: [],
180
+ init() { /* global setup */ },
181
+ onOpen() { /* mount setup */ },
182
+ cleanup() { /* unmount cleanup */ }
183
+});
184
+```
185
+
186
+### Tool Definition (Good)
187
+```python
188
+from python.helpers.tool import Tool, ToolResult
189
+
190
+class MyTool(Tool):
191
+ async def execute(self, arg1: str):
192
+ # Tool logic
193
+ return ToolResult("Success")
194
+```
195
196
---
197
95
-## 5. Directory Mapping (Plugin Layout)
96
-
97
-> [!IMPORTANT]
98
-> **Always create new plugins in `usr/plugins/`.** The root `/plugins/` folder is reserved for core Agent Zero plugins and may be overwritten during framework updates.
99
-
100
-```text
101
-usr/plugins/my-plugin/
102
-├── plugin.json # Required manifest (name, version, settings_sections)
103
-├── api/ # ApiHandler (python.helpers.api)
104
-├── extensions/
105
-│ ├── python/agent_init/ # Auto-start logic
106
-│ └── webui/ # sidebar-quick-actions-main-start/
107
-└── webui/
108
- ├── config.html # Optional: plugin settings UI
109
- └── my-modal.html # Full plugin pages + stores
198
+## Troubleshooting
199
+
200
+### Dependency Conflicts
201
+If pip install fails, try running in a clean virtual environment:
202
+```bash
203
+python -m venv .venv
204
+source .venv/bin/activate
205
+pip install -r requirements.txt
206
+pip install -r requirements2.txt
207
```
208
112
-Refer to `docs/agents/AGENTS.components.md` for deep UI technicals and `docs/agents/AGENTS.modals.md` for modal-specific CSS classes (`btn-ok`, `btn-cancel`).
209
+### WebSocket Connection Failures
210
+- Check if X-CSRF-Token is being sent.
211
+- Ensure the runtime ID in the session matches the current server instance.
212
+
213
+---
214
215
+*Last updated: 2026-02-22*
216
+*Maintained by: Agent Zero Core Team*
AGENTS.plugins.md
new
+91
@@ -0,0 +1,91 @@
1
+# Agent Zero - Plugins Guide
2
+
3
+This guide covers the Python Backend and Frontend WebUI plugin architecture. Use this as the definitive reference for building and extending Agent Zero.
4
+
5
+---
6
+
7
+## 1. Architecture Overview
8
+
9
+Agent Zero uses a convention-over-configuration plugin model where runtime capabilities are discovered from the directory structure.
10
+
11
+### Internal Components
12
+
13
+1. Backend discovery (python/helpers/plugins.py): Resolves roots (usr/plugins/ first, then plugins/) and builds the effective set of plugins.
14
+2. Path resolution (python/helpers/subagents.py): Injects plugin paths into the agent's search space for prompts, tools, and configurations.
15
+3. Python extensions (python/helpers/extension.py): Executes lifecycle hooks from extensions/python/<point>/.
16
+4. WebUI extensions (webui/js/extensions.js): Injects HTML/JS contributions into core UI breakpoints (x-extension).
17
+
18
+---
19
+
20
+## 2. File Structure
21
+
22
+Each plugin lives in usr/plugins/<plugin_name>/.
23
+
24
+```text
25
+usr/plugins/<plugin_name>/
26
+├── plugin.json # Required: Name, version, settings config
27
+├── api/ # API handlers (ApiHandler subclasses)
28
+├── tools/ # Agent tools (Tool subclasses)
29
+├── helpers/ # Shared Python logic
30
+├── prompts/ # Prompt templates
31
+├── agents/ # Agent profiles
32
+├── extensions/
33
+│ ├── python/<point>/ # Backend lifecycle hooks
34
+│ └── webui/<point>/ # UI HTML/JS contributions
35
+└── webui/
36
+ ├── config.html # Optional: Plugin settings UI
37
+ └── ... # Full plugin pages/components
38
+```
39
+
40
+### plugin.json format
41
+```json
42
+{
43
+ "name": "My Plugin",
44
+ "description": "What this plugin does.",
45
+ "version": "1.0.0",
46
+ "settings_sections": ["agent"]
47
+}
48
+```
49
+settings_sections values: agent, external, mcp, developer, backup.
50
+
51
+---
52
+
53
+## 3. Frontend Extensions
54
+
55
+### HTML Breakpoints
56
+Core UI defines insertion points like <x-extension id="sidebar-quick-actions-main-start"></x-extension>.
57
+To contribute:
58
+1. Place HTML files in extensions/webui/<extension_point>/.
59
+2. Include a root x-data scope.
60
+3. Include an x-move-* directive (e.g., x-move-to-start, x-move-after="#id").
61
+
62
+### JS Hooks
63
+Place *.js files in extensions/webui/<extension_point>/ and export a default async function. They are called via callJsExtensions("<point>", context).
64
+
65
+---
66
+
67
+## 4. Plugin Settings
68
+
69
+1. Add webui/config.html to your plugin.
70
+2. Bind fields to $store.pluginSettings.settings.
71
+3. Settings are scoped per-project and per-agent automatically.
72
+
73
+### Resolution Priority (Highest First)
74
+1. project/.a0proj/agents/<profile>/plugins/<name>/config.json
75
+2. project/.a0proj/plugins/<name>/config.json
76
+3. usr/agents/<profile>/plugins/<name>/config.json
77
+4. usr/plugins/<name>/config.json
78
+
79
+---
80
+
81
+## 5. Routes
82
+
83
+| Route | Purpose |
84
+|---|---|
85
+| GET /plugins/<name>/<path> | Serve static assets |
86
+| POST /api/plugins/<name>/<handler> | Call plugin API |
87
+| POST /api/plugins | Management (action: get_config, save_config) |
88
+
89
+---
90
+
91
+*Refer to AGENTS.md for the main framework guide.*
docs/agents/AGENTS.components.md
+20
-20
@@ -7,11 +7,11 @@
7
8
| Aspect | Value |
9
|--------|-------|
10
-| **Tech Stack** | Alpine.js, ES Modules, CSS Variables |
11
-| **Component Tag** | `<x-component path="...">` |
12
-| **State Management** | `createStore(name, model)` from `/js/AlpineStore.js` |
13
-| **Modals** | `openModal(path)` / `closeModal()` from `/js/modals.js` |
14
-| **API Layer** | `callJsonApi()` / `fetchApi()` from `/js/api.js` |
10
+| Tech Stack | Alpine.js, ES Modules, CSS Variables |
11
+| Component Tag | `<x-component path="...">` |
12
+| State Management | `createStore(name, model)` from `/js/AlpineStore.js` |
13
+| Modals | `openModal(path)` / `closeModal()` from `/js/modals.js` |
14
+| API Layer | `callJsonApi()` / `fetchApi()` from `/js/api.js` |
15
16
---
17
@@ -182,7 +182,7 @@ This enables safe module-level initialization before Alpine loads.
182
| Module import | `import { store } from "./feature-store.js"; store.prop` |
183
| Global (avoid) | `Alpine.store("featureStore").prop` |
184
185
-**Prefer module imports over global lookups.**
185
+Prefer module imports over global lookups.
186
187
### Persistence Helpers
188
@@ -262,7 +262,7 @@ const model = {
262
};
263
```
264
265
-**Key distinction:**
265
+Key distinction:
266
- `init()` → once per app load (store registration)
267
- `onOpen()` → each time component mounts (modal opens, etc.)
268
- `cleanup()`/`destroy()` → teardown resources
@@ -360,7 +360,7 @@ Parent `x-component` attributes accessible via `globalThis.xAttrs(element)`:
360
</div>
361
```
362
363
-**Always gate components that depend on stores.** Prevents errors during initial load race.
363
+Always gate components that depend on stores. Prevents errors during initial load race.
364
365
---
366
@@ -422,7 +422,7 @@ When `x-component` wrapper would break flex layout:
422
423
### Common Mistakes
424
425
-**Race condition: store not ready**
425
+Race condition: store not ready
426
```html
427
<!-- ❌ BAD: No gate -->
428
<div x-data>
@@ -437,7 +437,7 @@ When `x-component` wrapper would break flex layout:
437
</div>
438
```
439
440
-**Duplicate initialization**
440
+Duplicate initialization
441
```javascript
442
// ❌ BAD: Runs every time store accessed
443
init() {
@@ -452,7 +452,7 @@ init() {
452
}
453
```
454
455
-**Leaking listeners**
455
+Leaking listeners
456
```javascript
457
// ❌ BAD: No cleanup
458
init() {
@@ -474,7 +474,7 @@ destroy() {
474
475
### Minimum Requirements for External Apps
476
477
-1. **Files to copy:**
477
+1. Files to copy:
478
```
479
/js/components.js # Component loader
480
/js/AlpineStore.js # Store factory
@@ -482,11 +482,11 @@ destroy() {
482
/js/initFw.js # Alpine bootstrap + directives
483
```
484
485
-2. **Dependencies:**
485
+2. Dependencies:
486
- Alpine.js (vendor or CDN)
487
- CSS variables (define your theme)
488
489
-3. **Bootstrap sequence:**
489
+3. Bootstrap sequence:
490
```javascript
491
// initFw.js pattern:
492
await import("path/to/alpine.min.js");
@@ -497,7 +497,7 @@ destroy() {
497
// etc.
498
```
499
500
-4. **HTML entry point:**
500
+4. HTML entry point:
501
```html
502
<script type="module" src="/js/initFw.js"></script>
503
<x-component path="app/root.html"></x-component>
@@ -516,10 +516,10 @@ destroy() {
516
517
| Framework | Consideration |
518
|-----------|--------------|
519
-| **Vanilla/Static** | Works directly, include initFw.js |
520
-| **Electron** | Works, may need CSP adjustments for Blob URLs |
521
-| **React/Vue** | Mount Alpine in specific container, avoid conflicts |
522
-| **SPA Routers** | MutationObserver handles dynamic inserts |
519
+| Vanilla/Static | Works directly, include initFw.js |
520
+| Electron | Works, may need CSP adjustments for Blob URLs |
521
+| React/Vue | Mount Alpine in specific container, avoid conflicts |
522
+| SPA Routers | MutationObserver handles dynamic inserts |
523
524
---
525
@@ -551,7 +551,7 @@ webui/components/
551
└── ...
552
```
553
554
-**Naming conventions:**
554
+Naming conventions:
555
- Components: `feature-name.html`
556
- Stores: `feature-store.js` or `feature-name-store.js`
557
- Modals: placed in `modals/` or feature folder
docs/agents/AGENTS.modals.md
+1
-1
@@ -149,7 +149,7 @@ Use these standard button classes for modal actions:
149
| `btn btn-ok` | Positive/confirmatory actions (Save, Create, Confirm) | Solid blue background, white text |
150
| `btn btn-cancel` | Dismissive/negative actions (Cancel, Close, Delete) | Transparent with accent border |
151
152
-Footer button order convention: **positive action first** (left), **negative action second** (right).
152
+Footer button order convention: positive action first (left), negative action second (right).
153
154
Example footer markup:
155
plugins/README.md
+14
-191
@@ -1,199 +1,22 @@
1
-# Agent Zero Plugins
1
+# Agent Zero - Core Plugins
2
3
-This directory contains default plugins. For a full-stack development guide, see [docs/AGENTS.md](../docs/AGENTS.md).
3
+This directory contains the system-level plugins for Agent Zero.
4
5
-> [!TIP]
6
-> While Agent Zero looks for plugins in both `usr/plugins/` and `plugins/`, you should **always develop new plugins in `usr/plugins/`**. This ensures your work is isolated from core system files and persists through framework updates.
5
+## Directory Structure
6
8
-## Architecture
7
+- plugins/: Core system plugins (reserved for framework updates).
8
+- usr/plugins/: Recommended location for user-developed plugins.
9
10
-Agent Zero uses a convention-over-configuration plugin model:
10
+## Documentation
11
12
-- Runtime capabilities are discovered from directory structure.
13
-- Backend owns discovery, routing, and static asset serving.
14
-- Frontend uses explicit `x-extension` breakpoints plus the standard `x-component` loader.
12
+For detailed guides on how to create, extend, or configure plugins, please refer to:
13
16
-### Internal Components
14
+- AGENTS.plugins.md: Full-stack plugin architecture, manifest format, and extension points.
15
+- AGENTS.md: Main framework guide and backend context overview.
16
18
-1. **Backend plugin discovery** (`python/helpers/plugins.py`)
19
- - `get_plugin_roots()` resolves roots in priority order (`usr/plugins` first, then `plugins`).
20
- - `list_plugins()` builds the effective set (first root wins on ID conflicts).
21
- - `get_webui_extensions(extension_point, filters)` scans `extensions/webui/<extension_point>/`.
17
+## Usage
18
23
-2. **Path resolution** (`python/helpers/subagents.py`)
24
- - `get_paths(..., include_plugins=True)` includes plugin candidates for prompts/tools.
25
-
26
-3. **Python extension runtime** (`python/helpers/extension.py`)
27
- - `call_extensions(extension_point, agent, **kwargs)` executes extension classes.
28
- - Searches `python/extensions/<point>/` and `plugins/*/extensions/python/<point>/`.
29
- - Extension classes derive from `Extension` and implement `async execute()`.
30
-
31
-4. **API and static routes** (`run_ui.py`, `python/api/load_webui_extensions.py`)
32
- - `GET /plugins/<plugin_id>/<path>` serves plugin static assets.
33
- - Plugin APIs are mounted under `/api/plugins/<plugin_id>/<handler>`.
34
- - `POST /api/load_webui_extensions` returns extension files for a given extension point.
35
-
36
-5. **Frontend WebUI extension runtime** (`webui/js/extensions.js`)
37
- - HTML flow: discovers `<x-extension>` tags, calls backend API, injects `<x-component>` tags.
38
- - JS flow: `callJsExtensions("<extension_point>", contextObject)` loads and executes plugin JS modules.
39
- - Both HTML and JS lookups are cached per extension point.
40
-
41
-## File Structure
42
-
43
-```text
44
-usr/plugins/
45
- <plugin_name>/
46
- plugin.json # Required manifest (enables discovery)
47
- api/ # API handlers (ApiHandler subclasses)
48
- tools/ # Agent tools (Tool subclasses)
49
- helpers/ # Shared Python helpers
50
- prompts/ # Prompt templates
51
- agents/ # Agent profiles
52
- extensions/
53
- python/<extension_point>/ # Python lifecycle extensions
54
- webui/<extension_point>/ # WebUI HTML/JS hook contributions
55
- webui/
56
- config.html # Optional: plugin settings UI
57
- ... # Full plugin-owned UI pages/components
58
-```
59
-
60
-## Directory Conventions
61
-
62
-Each plugin lives in `usr/plugins/<plugin_name>/`.
63
-
64
-Capability discovery is based on these paths:
65
-
66
-- `plugin.json` - **required** manifest; a directory without it is not recognized as a plugin
67
-- `api/*.py` - API handlers (`ApiHandler` subclasses), exposed under `/api/plugins/<plugin_name>/<handler>`
68
-- `tools/*.py` - agent tools (`Tool` subclasses)
69
-- `helpers/*.py` - shared Python helpers
70
-- `extensions/python/<extension_point>/*.py` - backend lifecycle extensions
71
-- `extensions/webui/<extension_point>/*` - WebUI extension assets (HTML/JS)
72
-- `webui/**` - full plugin-owned UI pages/components (loaded directly by path)
73
-- `webui/config.html` - if present, a Settings button appears for this plugin in the relevant settings tabs
74
-- `prompts/**/*.md` - prompt templates
75
-- `agents/` - agent profiles
76
-
77
-### `plugin.json` format
78
-
79
-```json
80
-{
81
- "name": "My Plugin",
82
- "description": "What this plugin does.",
83
- "version": "1.0.0",
84
- "settings_sections": ["agent"]
85
-}
86
-```
87
-
88
-`settings_sections` controls which Settings tabs show a subsection for this plugin. Current valid values: `agent`, `external`, `mcp`, `developer`, `backup`. Leave empty (`[]`) for no subsection.
89
-
90
-## Frontend Extensions
91
-
92
-### HTML insertion via breakpoints
93
-
94
-Core UI defines insertion points like:
95
-
96
-```html
97
-<x-extension id="sidebar-quick-actions-main-start"></x-extension>
98
-```
99
-
100
-Resolution flow:
101
-
102
-1. `webui/js/extensions.js` finds `x-extension` nodes.
103
-2. It calls `/api/load_webui_extensions` with the extension point and HTML filters.
104
-3. Backend returns matching files from `plugins/*/extensions/webui/<extension_point>/`.
105
-4. `extensions.js` injects returned entries as `<x-component path="...">`.
106
-5. `components.js` loads each component using the standard component pipeline.
107
-
108
-Required baseline for HTML UI extensions in this repository:
109
-- include a root `x-data` scope
110
-- include one explicit `x-move-*` placement directive
111
-
112
-### JS hook extensions
113
-
114
-JS hooks are loaded from the same extension point structure:
115
-
116
-`plugins/<plugin_id>/extensions/webui/<extension_point>/*.js`
117
-
118
-Runtime code calls:
119
-
120
-`callJsExtensions("<extension_point>", contextObject)`
121
-
122
-### Fine placement helpers
123
-
124
-`initFw.js` provides Alpine move directives for plugin markup:
125
-
126
-- `x-move-to-start`
127
-- `x-move-to-end`
128
-- `x-move-to`
129
-- `x-move-before`
130
-- `x-move-after`
131
-
132
-## Plugin Settings
133
-
134
-If your plugin needs user-configurable settings:
135
-
136
-1. Add `webui/config.html` to your plugin. The system detects this file automatically.
137
-2. Declare which settings tabs should show a subsection for your plugin via `settings_sections` in `plugin.json`.
138
-3. The plugin settings modal provides **Project** and **Agent profile** context selectors (same as the Skills list). Settings are scoped per-project and per-agent.
139
-
140
-### Config HTML contract
141
-
142
-Your `config.html` receives context from `$store.pluginSettings`:
143
-
144
-```html
145
-<html>
146
-<head>
147
- <title>My Plugin Config</title>
148
- <script type="module">
149
- import { store } from "/components/plugins/plugin-settings-store.js";
150
- </script>
151
-</head>
152
-<body>
153
- <div x-data>
154
- <!-- bind fields to $store.pluginSettings.settings -->
155
- <input x-model="$store.pluginSettings.settings.my_key" />
156
- </div>
157
-</body>
158
-</html>
159
-```
160
-
161
-- `$store.pluginSettings.settings` - plain object loaded from `config.json`, save-scoped to the selected project/agent.
162
-- The modal's **Save** button calls `POST /plugins` (`action: save_config`) automatically.
163
-- For plugins that surface **core settings** (like memory), set `saveMode = 'core'` in `x-init` so Save delegates to the core settings API instead.
164
-
165
-### Settings resolution priority (highest first)
166
-
167
-```
168
-project/.a0proj/agents/<profile>/plugins/<name>/config.json
169
-project/.a0proj/plugins/<name>/config.json
170
-usr/agents/<profile>/plugins/<name>/config.json
171
-agents/<profile>/plugins/<name>/config.json
172
-usr/plugins/<name>/config.json
173
-plugins/<name>/config.json
174
-```
175
-
176
-## Plugin Author Flow
177
-
178
-1. Create `usr/plugins/<plugin_name>/`.
179
-2. Add `plugin.json` manifest (required for discovery).
180
-3. Add backend capabilities by convention (`api/`, `tools/`, `helpers/`, `extensions/python/`, `prompts/`, `agents/`).
181
-4. Pick a WebUI breakpoint or JS hook extension point.
182
-5. For HTML UI entries: place files under `extensions/webui/<extension_point>/`, use root `x-data` + one `x-move-*` directive.
183
-6. For JS hooks: place `*.js` files under `extensions/webui/<extension_point>/`, export a default async function.
184
-7. Place full plugin pages/components in `webui/` and open them directly by path.
185
-8. Optionally add `webui/config.html` and set `settings_sections` in `plugin.json` to expose settings in the UI.
186
-
187
-## Routes
188
-
189
-- Plugin static assets: `GET /plugins/<plugin_name>/<path>`
190
-- Plugin APIs: `POST /api/plugins/<plugin_name>/<handler>`
191
-- WebUI extension discovery: `POST /api/load_webui_extensions`
192
-- Plugin management (get/save config): `POST /plugins`
193
-
194
-## Notes
195
-
196
-- User plugins in `usr/plugins/` override repo plugins by plugin ID.
197
-- Runtime behavior is fully convention-driven from directory structure.
198
-- Extension point ordering between multiple plugins is currently implicit (filesystem order).
199
-- When you need a new extension point for your plugin, submit a PR - we are actively expanding coverage based on community needs.
19
+Plugins are automatically discovered based on the presence of a plugin.json file. Each plugin can contribute:
20
+- Backend: APIs, Tools, Helpers, and Lifecycle Extensions.
21
+- Frontend: HTML/JS UI contributions via core breakpoints.
22
+- Config: Isolated settings scoped per-project and per-agent profile.
skills/a0-create-plugin/SKILL.md
+27
-25
@@ -6,17 +6,17 @@ description: Create, extend, or modify Agent Zero plugins. Follows strict full-s
6
# Agent Zero Plugin Development
7
8
> [!IMPORTANT]
9
-> **Always create new plugins in `usr/plugins/<plugin_name>/`.** The root `/plugins` directory is reserved for core system plugins.
9
+> Always create new plugins in usr/plugins/<plugin_name>/. The root /plugins directory is reserved for core system plugins.
10
11
Primary references:
12
-- `/a0/AGENTS.md` (Full-stack architecture & AgentContext)
13
-- `/a0/docs/agents/AGENTS.components.md` (Component system deep dive)
14
-- `/a0/docs/agents/AGENTS.modals.md` (Modal system & CSS conventions)
15
-- `/a0/plugins/README.md` (Extension points, plugin.json, settings system)
12
+- /a0/AGENTS.md (Full-stack architecture & AgentContext)
13
+- /a0/docs/agents/AGENTS.components.md (Component system deep dive)
14
+- /a0/docs/agents/AGENTS.modals.md (Modal system & CSS conventions)
15
+- /a0/AGENTS.plugins.md (Extension points, plugin.json, settings system)
16
17
-## 📋 Plugin Manifest (`plugin.json`)
17
+## Plugin Manifest (plugin.json)
18
19
-Every plugin **must** have a `plugin.json` or it will not be discovered:
19
+Every plugin must have a plugin.json or it will not be discovered:
20
21
```json
22
{
@@ -27,12 +27,12 @@ Every plugin **must** have a `plugin.json` or it will not be discovered:
27
}
28
```
29
30
-`settings_sections` controls which Settings tabs show a subsection for this plugin. Valid values: `agent`, `external`, `mcp`, `developer`, `backup`. Use `[]` for no subsection.
30
+settings_sections controls which Settings tabs show a subsection for this plugin. Valid values: agent, external, mcp, developer, backup. Use [] for no subsection.
31
32
-## 🛠️ Mandatory Frontend Patterns
32
+## Mandatory Frontend Patterns
33
34
### 1. The "Store Gate" Template
35
-To avoid race conditions and "undefined" errors, every component must use this wrapper:
35
+To avoid race conditions and undefined errors, every component must use this wrapper:
36
```html
37
<div x-data>
38
<template x-if="$store.myPluginStore">
@@ -44,30 +44,31 @@ To avoid race conditions and "undefined" errors, every component must use this w
44
```
45
46
### 2. Separate Store Module
47
-Place store logic in a separate `.js` file. Do NOT use `alpine:init` listeners inside HTML.
47
+Place store logic in a separate .js file. Do NOT use alpine:init listeners inside HTML.
48
```javascript
49
// webui/my-store.js
50
import { createStore } from "/js/AlpineStore.js";
51
export const store = createStore("myPluginStore", {
52
status: 'idle',
53
init() { ... },
54
- onOpen() { ... }
54
+ onOpen() { ... },
55
+ cleanup() { ... }
56
});
57
```
57
-Import it in the HTML `<head>`:
58
+Import it in the HTML <head>:
59
```html
60
<head>
61
<script type="module" src="/plugins/<plugin_name>/webui/my-store.js"></script>
62
</head>
63
```
64
64
-## ⚙️ Plugin Settings
65
+## Plugin Settings
66
66
-If your plugin needs user-configurable settings, add `webui/config.html`. The system detects it automatically and shows a Settings button in the relevant tabs (per `settings_sections` in `plugin.json`).
67
+If your plugin needs user-configurable settings, add webui/config.html. The system detects it automatically and shows a Settings button in the relevant tabs (per settings_sections in plugin.json).
68
69
### Settings modal contract
70
70
-The modal provides Project + Agent profile context selectors. Your `config.html` binds to `$store.pluginSettings.settings`:
71
+The modal provides Project + Agent profile context selectors. Your config.html binds to $store.pluginSettings.settings:
72
73
```html
74
<html>
@@ -86,11 +87,11 @@ The modal provides Project + Agent profile context selectors. Your `config.html`
87
</html>
88
```
89
89
-The modal's Save button persists `$store.pluginSettings.settings` to `config.json` in the correct scope (project/agent/global).
90
+The modal's Save button persists $store.pluginSettings.settings to config.json in the correct scope (project/agent/global).
91
92
### Surfacing core settings (e.g. memory pattern)
93
93
-If your plugin exposes **existing core settings** rather than plugin-specific ones, set `saveMode = 'core'` so Save delegates to the core settings API:
94
+If your plugin exposes existing core settings rather than plugin-specific ones, set saveMode = 'core' so Save delegates to the core settings API:
95
96
```html
97
<div x-data x-init="
@@ -102,15 +103,16 @@ If your plugin exposes **existing core settings** rather than plugin-specific on
103
```
104
105
### Sidebar Button (sidebar entry point)
105
-- **Extension point**: `sidebar-quick-actions-main-start`
106
-- **Class**: `class="config-button"`
107
-- **Placement**: `x-move-after=".config-button#dashboard"`
108
-- **Action**: `@click="openModal('/plugins/<plugin_name>/webui/my-modal.html')"`
106
+- Extension point: sidebar-quick-actions-main-start
107
+- Class: class="config-button"
108
+- Placement: x-move-after=".config-button#dashboard"
109
+- Action: @click="openModal('/plugins/<plugin_name>/webui/my-modal.html')"
110
110
-## 🐍 Backend API & Context
111
+## Backend API & Context
112
113
### Import Paths
113
-- **Correct**: `from agent import AgentContext` (not python.helpers.agent)
114
+- Correct: from agent import AgentContext, AgentContextType
115
+- Correct: from initialize import initialize_agent
116
117
### Sending Messages Proactively
118
```python
@@ -138,7 +140,7 @@ save_plugin_config(
140
)
141
```
142
141
-## 📁 Directory Layout
143
+## Directory Layout
144
```
145
usr/plugins/<name>/
146
plugin.json # Required manifest