docs: explain plugin config caller context
Document the optional ui, agent, and api caller context for plugin configuration hooks. Clarify the api default, backwards compatibility, explicit backend opt-in, and that caller context is not an authorization boundary.
Alessandro committed
Aug 12, 2026 at 03:52 UTC
9cb6290aa9d4314015592b7668a0bcce7cacc356
2 files changed
+50
plugins/README.md
+23
@@ -70,6 +70,29 @@ Plugins can also include an optional `hooks.py` at the plugin root. The framewor
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.
skills/a0-create-plugin/SKILL.md
+27
@@ -177,6 +177,33 @@ save_plugin_config(
177
)
178
```
179
180
+### Configuration Hook Caller Context
181
+
182
+Use caller context only when the same settings need different behavior for a
183
+known origin. An unlabeled call remains compatible and uses `"api"`; a
184
+plugin-controlled runtime path can opt in explicitly:
185
+
186
+```python
187
+settings = get_plugin_config("my-plugin", agent=agent, caller="agent") or {}
188
+```
189
+
190
+Its `hooks.py` receives `hook_context={"caller": ...}`. For example, a plugin
191
+can redact a stored credential for a UI-specific path while preserving its
192
+normal runtime configuration:
193
+
194
+```python
195
+def get_plugin_config(default=None, hook_context=None, **kwargs):
196
+ caller = (hook_context or {}).get("caller", "api")
197
+ return redact_for_display(default) if caller == "ui" else default
198
+```
199
+
200
+The available values are `"ui"`, `"agent"`, and `"api"`. Existing hooks do
201
+not need to change: the framework safely ignores this new argument for hooks
202
+that do not accept it. This is behavior metadata, never authorization; do not
203
+use it to grant or deny access to secrets or other protected data. A
204
+`config.html` alone does not set the caller; its backend load/save path must
205
+pass it explicitly.
206
+
207
---
208
209
## Directory Layout