You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -45,6 +45,7 @@ Docs: https://docs.openclaw.ai
45
45
- Discord/components: consume every button or select in a non-reusable component message after the first authorized click, so single-use panels cannot fire sibling callbacks. Fixes #54227. Thanks @fujiwarakasei.
46
46
- macOS/config: preserve existing `gateway.auth` and unrelated config keys during app fallback writes, so dashboard or Talk settings changes cannot strand Control UI clients by dropping persisted auth. Fixes #75631. Thanks @Fuma2013.
47
47
- Control UI/TUI: keep reconnecting chat sends bound to the same backing session id and let TUI relaunches resume the last selected session, avoiding silent fresh sessions after refresh, reconnect, or terminal restart. Fixes #63195, #68162, and #73546. Thanks @bond260312-cmyk, @zhong18804784882, and @mtuwei.
48
+
- Plugins/tools: let plugin manifests declare static tool availability so reply startup skips unavailable plugin tool runtimes instead of importing factories that only return `null`. Thanks @shakkernerd.
48
49
- Discord/reactions: skip reaction listener registration when DMs and group DMs are disabled and every configured guild has `reactionNotifications: "off"`, avoiding needless reaction-event queue work. Fixes #47516. Thanks @x4v13r1120.
49
50
- CLI sessions: preserve explicit manual-attach reuse bindings so trusted CLI sessions are not invalidated on the first turn when auth, prompt, or MCP fingerprints drift. Fixes #75849. Thanks @alfredjbclaw.
50
51
- Telegram/streaming: keep partial preview streaming enabled for plain reply-to replies, disabling drafts only for real native quote excerpts that require Telegram quote parameters. Fixes #73505. Thanks @choury.
Copy file name to clipboardExpand all lines: docs/plugins/manifest.md
+40Lines changed: 40 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -178,6 +178,7 @@ or npm install metadata. Those belong in your plugin code and `package.json`.
178
178
|`imageGenerationProviderMetadata`| No |`Record<string, object>`| Cheap image-generation auth metadata for provider ids declared in `contracts.imageGenerationProviders`, including provider-owned auth aliases and base-url guards. |
179
179
|`videoGenerationProviderMetadata`| No |`Record<string, object>`| Cheap video-generation auth metadata for provider ids declared in `contracts.videoGenerationProviders`, including provider-owned auth aliases and base-url guards. |
180
180
|`musicGenerationProviderMetadata`| No |`Record<string, object>`| Cheap music-generation auth metadata for provider ids declared in `contracts.musicGenerationProviders`, including provider-owned auth aliases and base-url guards. |
181
+
|`toolMetadata`| No |`Record<string, object>`| Cheap availability metadata for plugin-owned tools declared in `contracts.tools`. Use it when a tool should not load runtime unless config, env, or auth evidence exists. |
181
182
|`channelConfigs`| No |`Record<string, object>`| Manifest-owned channel config metadata merged into discovery and validation surfaces before runtime loads. |
182
183
|`skills`| No |`string[]`| Skill directories to load, relative to the plugin root. |
183
184
|`name`| No |`string`| Human-readable plugin name. |
@@ -280,6 +281,45 @@ Each `providerBaseUrl` guard supports:
280
281
|`defaultBaseUrl`| No |`string`| Base URL to assume when the provider config omits `baseUrl`. |
281
282
|`allowedBaseUrls`| Yes |`string[]`| Allowed base URLs for this auth signal. The signal is ignored when the configured or default base URL does not match one of these normalized values. |
282
283
284
+
## Tool metadata reference
285
+
286
+
`toolMetadata` uses the same `configSignals` and `authSignals` shapes as
287
+
generation provider metadata, keyed by tool name. `contracts.tools` declares
288
+
ownership. `toolMetadata` declares cheap availability evidence so OpenClaw can
289
+
avoid importing a plugin runtime just to have its tool factory return `null`.
290
+
291
+
```json
292
+
{
293
+
"providerAuthEnvVars": {
294
+
"example": ["EXAMPLE_API_KEY"]
295
+
},
296
+
"contracts": {
297
+
"tools": ["example_search"]
298
+
},
299
+
"toolMetadata": {
300
+
"example_search": {
301
+
"authSignals": [
302
+
{
303
+
"provider": "example"
304
+
}
305
+
],
306
+
"configSignals": [
307
+
{
308
+
"rootPath": "plugins.entries.example.config",
309
+
"overlayPath": "search",
310
+
"required": ["apiKey"]
311
+
}
312
+
]
313
+
}
314
+
}
315
+
}
316
+
```
317
+
318
+
If a tool has no `toolMetadata`, OpenClaw preserves the existing behavior and
319
+
loads the owning plugin when the tool contract matches policy. For hot-path
320
+
tools whose factory depends on auth/config, plugin authors should declare
321
+
`toolMetadata` instead of making core import runtime to ask.
322
+
283
323
## providerAuthChoices reference
284
324
285
325
Each `providerAuthChoices` entry describes one onboarding or auth choice.
0 commit comments