mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 14:30:45 +00:00
feat(plugins): expose activation plan reasons (#70943)
This commit is contained in:
@@ -61,6 +61,14 @@ to narrow plugin loading before broader registry materialization:
|
||||
- explicit provider setup/runtime resolution narrows to plugins that own the
|
||||
requested provider id
|
||||
|
||||
The activation planner exposes both an ids-only API for existing callers and a
|
||||
plan API for new diagnostics. Plan entries report why a plugin was selected,
|
||||
separating explicit `activation.*` planner hints from manifest ownership
|
||||
fallback such as `providers`, `channels`, `commandAliases`, `setup.providers`,
|
||||
`contracts.tools`, and hooks. That reason split is the compatibility boundary:
|
||||
existing plugin metadata keeps working, while new code can detect broad hints
|
||||
or fallback behavior without changing runtime loading semantics.
|
||||
|
||||
Setup discovery now prefers descriptor-owned ids such as `setup.providers` and
|
||||
`setup.cliBackends` to narrow candidate plugins before it falls back to
|
||||
`setup-api` for plugins that still need setup-time runtime hooks. If more than
|
||||
|
||||
@@ -153,6 +153,26 @@ The important design boundary:
|
||||
That split lets OpenClaw validate config, explain missing/disabled plugins, and
|
||||
build UI/schema hints before the full runtime is active.
|
||||
|
||||
### Activation planning
|
||||
|
||||
Activation planning is part of the control plane. Callers can ask which plugins
|
||||
are relevant to a concrete command, provider, channel, route, agent harness, or
|
||||
capability before loading broader runtime registries.
|
||||
|
||||
The planner keeps current manifest behavior compatible:
|
||||
|
||||
- `activation.*` fields are explicit planner hints
|
||||
- `providers`, `channels`, `commandAliases`, `setup.providers`,
|
||||
`contracts.tools`, and hooks remain manifest ownership fallback
|
||||
- the ids-only planner API stays available for existing callers
|
||||
- the plan API reports reason labels so diagnostics can distinguish explicit
|
||||
hints from ownership fallback
|
||||
|
||||
Do not treat `activation` as a lifecycle hook or a replacement for
|
||||
`register(...)`. It is metadata used to narrow loading. Prefer ownership fields
|
||||
when they already describe the relationship; use `activation` only for extra
|
||||
planner hints.
|
||||
|
||||
### Channel plugins and the shared message tool
|
||||
|
||||
Channel plugins do not need to register a separate send/edit/react tool for
|
||||
|
||||
@@ -152,7 +152,7 @@ or npm install metadata. Those belong in your plugin code and `package.json`.
|
||||
| `providerAuthAliases` | No | `Record<string, string>` | Provider ids that should reuse another provider id for auth lookup, for example a coding provider that shares the base provider API key and auth profiles. |
|
||||
| `channelEnvVars` | No | `Record<string, string[]>` | Cheap channel env metadata that OpenClaw can inspect without loading plugin code. Use this for env-driven channel setup or auth surfaces that generic startup/config helpers should see. |
|
||||
| `providerAuthChoices` | No | `object[]` | Cheap auth-choice metadata for onboarding pickers, preferred-provider resolution, and simple CLI flag wiring. |
|
||||
| `activation` | No | `object` | Cheap activation hints for provider, command, channel, route, and capability-triggered loading. Metadata only; plugin runtime still owns actual behavior. |
|
||||
| `activation` | No | `object` | Cheap activation planner metadata for provider, command, channel, route, and capability-triggered loading. Metadata only; plugin runtime still owns actual behavior. |
|
||||
| `setup` | No | `object` | Cheap setup/onboarding descriptors that discovery and setup surfaces can inspect without loading plugin runtime. |
|
||||
| `qaRunners` | No | `object[]` | Cheap QA runner descriptors used by the shared `openclaw qa` host before plugin runtime loads. |
|
||||
| `contracts` | No | `object` | Static bundled capability snapshot for external auth hooks, speech, realtime transcription, realtime voice, media-understanding, image-generation, music-generation, video-generation, web-fetch, web search, and tool ownership. |
|
||||
@@ -215,7 +215,62 @@ uses this metadata for diagnostics without importing plugin runtime code.
|
||||
## activation reference
|
||||
|
||||
Use `activation` when the plugin can cheaply declare which control-plane events
|
||||
should activate it later.
|
||||
should include it in an activation/load plan.
|
||||
|
||||
This block is planner metadata, not a lifecycle API. It does not register
|
||||
runtime behavior, does not replace `register(...)`, and does not promise that
|
||||
plugin code has already executed. The activation planner uses these fields to
|
||||
narrow candidate plugins before falling back to existing manifest ownership
|
||||
metadata such as `providers`, `channels`, `commandAliases`, `setup.providers`,
|
||||
`contracts.tools`, and hooks.
|
||||
|
||||
Prefer the narrowest metadata that already describes ownership. Use
|
||||
`providers`, `channels`, `commandAliases`, setup descriptors, or `contracts`
|
||||
when those fields express the relationship. Use `activation` for extra planner
|
||||
hints that cannot be represented by those ownership fields.
|
||||
|
||||
This block is metadata only. It does not register runtime behavior, and it does
|
||||
not replace `register(...)`, `setupEntry`, or other runtime/plugin entrypoints.
|
||||
Current consumers use it as a narrowing hint before broader plugin loading, so
|
||||
missing activation metadata usually only costs performance; it should not
|
||||
change correctness while legacy manifest ownership fallbacks still exist.
|
||||
|
||||
```json
|
||||
{
|
||||
"activation": {
|
||||
"onProviders": ["openai"],
|
||||
"onCommands": ["models"],
|
||||
"onChannels": ["web"],
|
||||
"onRoutes": ["gateway-webhook"],
|
||||
"onCapabilities": ["provider", "tool"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Required | Type | What it means |
|
||||
| ---------------- | -------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `onProviders` | No | `string[]` | Provider ids that should include this plugin in activation/load plans. |
|
||||
| `onCommands` | No | `string[]` | Command ids that should include this plugin in activation/load plans. |
|
||||
| `onChannels` | No | `string[]` | Channel ids that should include this plugin in activation/load plans. |
|
||||
| `onRoutes` | No | `string[]` | Route kinds that should include this plugin in activation/load plans. |
|
||||
| `onCapabilities` | No | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Broad capability hints used by control-plane activation planning. Prefer narrower fields when possible. |
|
||||
|
||||
Current live consumers:
|
||||
|
||||
- command-triggered CLI planning falls back to legacy
|
||||
`commandAliases[].cliCommand` or `commandAliases[].name`
|
||||
- channel-triggered setup/channel planning falls back to legacy `channels[]`
|
||||
ownership when explicit channel activation metadata is missing
|
||||
- provider-triggered setup/runtime planning falls back to legacy
|
||||
`providers[]` and top-level `cliBackends[]` ownership when explicit provider
|
||||
activation metadata is missing
|
||||
|
||||
Planner diagnostics can distinguish explicit activation hints from manifest
|
||||
ownership fallback. For example, `activation-command-hint` means
|
||||
`activation.onCommands` matched, while `manifest-command-alias` means the
|
||||
planner used `commandAliases` ownership instead. These reason labels are for
|
||||
host diagnostics and tests; plugin authors should keep declaring the metadata
|
||||
that best describes ownership.
|
||||
|
||||
## qaRunners reference
|
||||
|
||||
@@ -240,42 +295,6 @@ runtime still owns actual CLI registration through a lightweight
|
||||
| `commandName` | Yes | `string` | Subcommand mounted beneath `openclaw qa`, for example `matrix`. |
|
||||
| `description` | No | `string` | Fallback help text used when the shared host needs a stub command. |
|
||||
|
||||
This block is metadata only. It does not register runtime behavior, and it does
|
||||
not replace `register(...)`, `setupEntry`, or other runtime/plugin entrypoints.
|
||||
Current consumers use it as a narrowing hint before broader plugin loading, so
|
||||
missing activation metadata usually only costs performance; it should not
|
||||
change correctness while legacy manifest ownership fallbacks still exist.
|
||||
|
||||
```json
|
||||
{
|
||||
"activation": {
|
||||
"onProviders": ["openai"],
|
||||
"onCommands": ["models"],
|
||||
"onChannels": ["web"],
|
||||
"onRoutes": ["gateway-webhook"],
|
||||
"onCapabilities": ["provider", "tool"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Required | Type | What it means |
|
||||
| ---------------- | -------- | ---------------------------------------------------- | ----------------------------------------------------------------- |
|
||||
| `onProviders` | No | `string[]` | Provider ids that should activate this plugin when requested. |
|
||||
| `onCommands` | No | `string[]` | Command ids that should activate this plugin. |
|
||||
| `onChannels` | No | `string[]` | Channel ids that should activate this plugin. |
|
||||
| `onRoutes` | No | `string[]` | Route kinds that should activate this plugin. |
|
||||
| `onCapabilities` | No | `Array<"provider" \| "channel" \| "tool" \| "hook">` | Broad capability hints used by control-plane activation planning. |
|
||||
|
||||
Current live consumers:
|
||||
|
||||
- command-triggered CLI planning falls back to legacy
|
||||
`commandAliases[].cliCommand` or `commandAliases[].name`
|
||||
- channel-triggered setup/channel planning falls back to legacy `channels[]`
|
||||
ownership when explicit channel activation metadata is missing
|
||||
- provider-triggered setup/runtime planning falls back to legacy
|
||||
`providers[]` and top-level `cliBackends[]` ownership when explicit provider
|
||||
activation metadata is missing
|
||||
|
||||
## setup reference
|
||||
|
||||
Use `setup` when setup and onboarding surfaces need cheap plugin-owned metadata
|
||||
|
||||
@@ -28,6 +28,12 @@ Both surfaces are now **deprecated**. They still work at runtime, but new
|
||||
plugins must not use them, and existing plugins should migrate before the next
|
||||
major release removes them.
|
||||
|
||||
OpenClaw does not remove or reinterpret documented plugin behavior in the same
|
||||
change that introduces a replacement. Breaking contract changes must first go
|
||||
through a compatibility adapter, diagnostics, docs, and a deprecation window.
|
||||
That applies to SDK imports, manifest fields, setup APIs, hooks, and runtime
|
||||
registration behavior.
|
||||
|
||||
<Warning>
|
||||
The backwards-compatibility layer will be removed in a future major release.
|
||||
Plugins that still import from these surfaces will break when that happens.
|
||||
@@ -62,6 +68,22 @@ Current bundled provider examples:
|
||||
- OpenRouter keeps provider builder and onboarding/config helpers in its own
|
||||
`api.ts`
|
||||
|
||||
## Compatibility policy
|
||||
|
||||
For external plugins, compatibility work follows this order:
|
||||
|
||||
1. add the new contract
|
||||
2. keep the old behavior wired through a compatibility adapter
|
||||
3. emit a diagnostic or warning that names the old path and replacement
|
||||
4. cover both paths in tests
|
||||
5. document the deprecation and migration path
|
||||
6. remove only after the announced migration window, usually in a major release
|
||||
|
||||
If a manifest field is still accepted, plugin authors can keep using it until
|
||||
the docs and diagnostics say otherwise. New code should prefer the documented
|
||||
replacement, but existing plugins should not break during ordinary minor
|
||||
releases.
|
||||
|
||||
## How to migrate
|
||||
|
||||
<Steps>
|
||||
|
||||
Reference in New Issue
Block a user