From 381bfdf0317cdf3d3c936e8c52fa4e8c7e8694fe Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Mon, 30 Mar 2026 10:02:35 +0900 Subject: [PATCH] docs: fix architecture.md P1s and P2s - Remove stale "Qwen portal" reference (no such bundled plugin) - Add activate hook note (legacy alias for register) - Add api.runtime.imageGeneration documentation (generate, listProviders) - Fix install command: document --omit=dev flag - Document external catalog aliases (packages, plugins accepted alongside entries) --- docs/plugins/architecture.md | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/plugins/architecture.md b/docs/plugins/architecture.md index 5cd099e0825..ba47a00d4df 100644 --- a/docs/plugins/architecture.md +++ b/docs/plugins/architecture.md @@ -474,9 +474,13 @@ At startup, OpenClaw does roughly this: `slots`, `load.paths`) 5. decide enablement for each candidate 6. load enabled native modules via jiti -7. call native `register(api)` hooks and collect registrations into the plugin registry +7. call native `register(api)` (or `activate(api)` — a legacy alias) hooks and collect registrations into the plugin registry 8. expose the registry to commands/runtime surfaces + +`activate` is a legacy alias for `register` — the loader resolves whichever is present (`def.register ?? def.activate`) and calls it at the same point. All bundled plugins use `register`; prefer `register` for new plugins. + + The safety gates happen **before** runtime execution. Candidates are blocked when the entry escapes the plugin root, the path is world-writable, or path ownership looks suspicious for non-bundled plugins. @@ -740,7 +744,6 @@ api.registerProvider({ `huggingface`, `kimi-coding`, `modelstudio`, `nvidia`, `qianfan`, `synthetic`, `together`, `venice`, `vercel-ai-gateway`, and `volcengine` use `catalog` only. -- Qwen portal uses `catalog`, `auth`, and `refreshOAuth`. - MiniMax and Xiaomi use `catalog` plus usage hooks because their `/usage` behavior is plugin-owned even though inference still runs through the shared transports. @@ -905,6 +908,22 @@ Notes: - Use web-search providers for vendor-specific search transports. - `api.runtime.webSearch.*` is the preferred shared surface for feature/channel plugins that need search behavior without depending on the agent tool wrapper. +### `api.runtime.imageGeneration` + +```ts +const result = await api.runtime.imageGeneration.generate({ + config: api.config, + args: { prompt: "A friendly lobster mascot", size: "1024x1024" }, +}); + +const providers = api.runtime.imageGeneration.listProviders({ + config: api.config, +}); +``` + +- `generate(...)`: generate an image using the configured image-generation provider chain. +- `listProviders(...)`: list available image-generation providers and their capabilities. + ## Gateway HTTP routes Plugins can expose HTTP endpoints with `api.registerHttpRoute(...)`. @@ -1158,7 +1177,7 @@ directory after symlink resolution. Entries that escape the package directory ar rejected. Security note: `openclaw plugins install` installs plugin dependencies with -`npm install --ignore-scripts` (no lifecycle scripts). Keep plugin dependency +`npm install --omit=dev --ignore-scripts` (no lifecycle scripts, no dev dependencies at runtime). Keep plugin dependency trees "pure JS/TS" and avoid packages that require `postinstall` builds. Optional: `openclaw.setupEntry` can point at a lightweight setup-only module. @@ -1239,7 +1258,7 @@ registry export). Drop a JSON file at one of: Or point `OPENCLAW_PLUGIN_CATALOG_PATHS` (or `OPENCLAW_MPM_CATALOG_PATHS`) at one or more JSON files (comma/semicolon/`PATH`-delimited). Each file should -contain `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. +contain `{ "entries": [ { "name": "@scope/pkg", "openclaw": { "channel": {...}, "install": {...} } } ] }`. The parser also accepts `"packages"` or `"plugins"` as legacy aliases for the `"entries"` key. ## Context engine plugins