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)
This commit is contained in:
Vincent Koc
2026-03-30 10:02:35 +09:00
parent 89f9433fbf
commit 381bfdf031

View File

@@ -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
<Note>
`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.
</Note>
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