mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-22 15:31:07 +00:00
fix: repair main CI contracts and release checks
This commit is contained in:
@@ -23200,6 +23200,56 @@
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmChannelRetry",
|
||||
"kind": "channel",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmChannelRetry.initialDelayMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmChannelRetry.maxDelayMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmChannelRetry.maxRetries",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmChannelRetry.timeoutMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.accounts.*.dmPolicy",
|
||||
"kind": "channel",
|
||||
@@ -23709,6 +23759,56 @@
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmChannelRetry",
|
||||
"kind": "channel",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmChannelRetry.initialDelayMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmChannelRetry.maxDelayMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmChannelRetry.maxRetries",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmChannelRetry.timeoutMs",
|
||||
"kind": "channel",
|
||||
"type": "integer",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "channels.mattermost.dmPolicy",
|
||||
"kind": "channel",
|
||||
@@ -39699,7 +39799,7 @@
|
||||
"network"
|
||||
],
|
||||
"label": "Control UI Allowed Origins",
|
||||
"help": "Allowed browser origins for Control UI/WebChat websocket connections (full origins only, e.g. https://control.example.com). Required for non-loopback Control UI deployments unless dangerous Host-header fallback is explicitly enabled.",
|
||||
"help": "Allowed browser origins for Control UI/WebChat websocket connections (full origins only, e.g. https://control.example.com). Required for non-loopback Control UI deployments unless dangerous Host-header fallback is explicitly enabled. Setting [\"*\"] means allow any browser origin and should be avoided outside tightly controlled local testing.",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
@@ -41038,7 +41138,7 @@
|
||||
"access"
|
||||
],
|
||||
"label": "Hooks Allowed Agent IDs",
|
||||
"help": "Allowlist of agent IDs that hook mappings are allowed to target when selecting execution agents. Use this to constrain automation events to dedicated service agents.",
|
||||
"help": "Allowlist of agent IDs that hook mappings are allowed to target when selecting execution agents. Use this to constrain automation events to dedicated service agents and reduce blast radius if a hook token is exposed.",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
@@ -42156,7 +42256,7 @@
|
||||
"security"
|
||||
],
|
||||
"label": "Hooks Auth Token",
|
||||
"help": "Shared bearer token checked by hooks ingress for request authentication before mappings run. Use environment substitution and rotate regularly when webhook endpoints are internet-accessible.",
|
||||
"help": "Shared bearer token checked by hooks ingress for request authentication before mappings run. Treat holders as full-trust callers for the hook ingress surface, not as a separate non-owner role. Use environment substitution and rotate regularly when webhook endpoints are internet-accessible.",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
@@ -46269,6 +46369,127 @@
|
||||
"help": "Explicitly allows this plugin to request provider/model overrides in background subagent runs. Keep false unless the plugin is trusted to steer model selection.",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes",
|
||||
"kind": "plugin",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"advanced"
|
||||
],
|
||||
"label": "@openclaw/chutes-provider",
|
||||
"help": "OpenClaw Chutes.ai provider plugin (plugin: chutes)",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.config",
|
||||
"kind": "plugin",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"advanced"
|
||||
],
|
||||
"label": "@openclaw/chutes-provider Config",
|
||||
"help": "Plugin-defined config payload for chutes.",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.enabled",
|
||||
"kind": "plugin",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"advanced"
|
||||
],
|
||||
"label": "Enable @openclaw/chutes-provider",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.hooks",
|
||||
"kind": "plugin",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"advanced"
|
||||
],
|
||||
"label": "Plugin Hook Policy",
|
||||
"help": "Per-plugin typed hook policy controls for core-enforced safety gates. Use this to constrain high-impact hook categories without disabling the entire plugin.",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.hooks.allowPromptInjection",
|
||||
"kind": "plugin",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"access"
|
||||
],
|
||||
"label": "Allow Prompt Injection Hooks",
|
||||
"help": "Controls whether this plugin may mutate prompts through typed hooks. Set false to block `before_prompt_build` and ignore prompt-mutating fields from legacy `before_agent_start`, while preserving legacy `modelOverride` and `providerOverride` behavior.",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.subagent",
|
||||
"kind": "plugin",
|
||||
"type": "object",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"advanced"
|
||||
],
|
||||
"label": "Plugin Subagent Policy",
|
||||
"help": "Per-plugin subagent runtime controls for model override trust and allowlists. Keep this unset unless a plugin must explicitly steer subagent model selection.",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.subagent.allowedModels",
|
||||
"kind": "plugin",
|
||||
"type": "array",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"access"
|
||||
],
|
||||
"label": "Plugin Subagent Allowed Models",
|
||||
"help": "Allowed override targets for trusted plugin subagent runs as canonical \"provider/model\" refs. Use \"*\" only when you intentionally allow any model.",
|
||||
"hasChildren": true
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.subagent.allowedModels.*",
|
||||
"kind": "plugin",
|
||||
"type": "string",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [],
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.chutes.subagent.allowModelOverride",
|
||||
"kind": "plugin",
|
||||
"type": "boolean",
|
||||
"required": false,
|
||||
"deprecated": false,
|
||||
"sensitive": false,
|
||||
"tags": [
|
||||
"access"
|
||||
],
|
||||
"label": "Allow Plugin Subagent Model Override",
|
||||
"help": "Explicitly allows this plugin to request provider/model overrides in background subagent runs. Keep false unless the plugin is trusted to steer model selection.",
|
||||
"hasChildren": false
|
||||
},
|
||||
{
|
||||
"path": "plugins.entries.cloudflare-ai-gateway",
|
||||
"kind": "plugin",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{"generatedBy":"scripts/generate-config-doc-baseline.ts","recordType":"meta","totalPaths":5457}
|
||||
{"generatedBy":"scripts/generate-config-doc-baseline.ts","recordType":"meta","totalPaths":5476}
|
||||
{"recordType":"path","path":"acp","kind":"core","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"ACP","help":"ACP runtime controls for enabling dispatch, selecting backends, constraining allowed agent targets, and tuning streamed turn projection behavior.","hasChildren":true}
|
||||
{"recordType":"path","path":"acp.allowedAgents","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"ACP Allowed Agents","help":"Allowlist of ACP target agent ids permitted for ACP runtime sessions. Empty means no additional allowlist restriction.","hasChildren":true}
|
||||
{"recordType":"path","path":"acp.allowedAgents.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
@@ -2086,6 +2086,11 @@
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.commands.nativeSkills","kind":"channel","type":["boolean","string"],"required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.configWrites","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dangerouslyAllowNameMatching","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmChannelRetry","kind":"channel","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":true}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmChannelRetry.initialDelayMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmChannelRetry.maxDelayMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmChannelRetry.maxRetries","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmChannelRetry.timeoutMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.dmPolicy","kind":"channel","type":"string","required":true,"enumValues":["pairing","allowlist","open","disabled"],"defaultValue":"pairing","deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.enabled","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.accounts.*.groupAllowFrom","kind":"channel","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":true}
|
||||
@@ -2130,6 +2135,11 @@
|
||||
{"recordType":"path","path":"channels.mattermost.configWrites","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["channels","network"],"label":"Mattermost Config Writes","help":"Allow Mattermost to write config in response to channel events/commands (default: true).","hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dangerouslyAllowNameMatching","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.defaultAccount","kind":"channel","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dmChannelRetry","kind":"channel","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":true}
|
||||
{"recordType":"path","path":"channels.mattermost.dmChannelRetry.initialDelayMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dmChannelRetry.maxDelayMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dmChannelRetry.maxRetries","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dmChannelRetry.timeoutMs","kind":"channel","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.dmPolicy","kind":"channel","type":"string","required":true,"enumValues":["pairing","allowlist","open","disabled"],"defaultValue":"pairing","deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.enabled","kind":"channel","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"channels.mattermost.groupAllowFrom","kind":"channel","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":true}
|
||||
@@ -3563,7 +3573,7 @@
|
||||
{"recordType":"path","path":"gateway.channelMaxRestartsPerHour","kind":"core","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":["network","performance"],"label":"Gateway Channel Max Restarts Per Hour","help":"Maximum number of health-monitor-initiated channel restarts allowed within a rolling one-hour window. Once hit, further restarts are skipped until the window expires. Default: 10.","hasChildren":false}
|
||||
{"recordType":"path","path":"gateway.channelStaleEventThresholdMinutes","kind":"core","type":"integer","required":false,"deprecated":false,"sensitive":false,"tags":["network"],"label":"Gateway Channel Stale Event Threshold (min)","help":"How many minutes a connected channel can go without receiving any event before the health monitor treats it as a stale socket and triggers a restart. Default: 30.","hasChildren":false}
|
||||
{"recordType":"path","path":"gateway.controlUi","kind":"core","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["network"],"label":"Control UI","help":"Control UI hosting settings including enablement, pathing, and browser-origin/auth hardening behavior. Keep UI exposure minimal and pair with strong auth controls before internet-facing deployments.","hasChildren":true}
|
||||
{"recordType":"path","path":"gateway.controlUi.allowedOrigins","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access","network"],"label":"Control UI Allowed Origins","help":"Allowed browser origins for Control UI/WebChat websocket connections (full origins only, e.g. https://control.example.com). Required for non-loopback Control UI deployments unless dangerous Host-header fallback is explicitly enabled.","hasChildren":true}
|
||||
{"recordType":"path","path":"gateway.controlUi.allowedOrigins","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access","network"],"label":"Control UI Allowed Origins","help":"Allowed browser origins for Control UI/WebChat websocket connections (full origins only, e.g. https://control.example.com). Required for non-loopback Control UI deployments unless dangerous Host-header fallback is explicitly enabled. Setting [\"*\"] means allow any browser origin and should be avoided outside tightly controlled local testing.","hasChildren":true}
|
||||
{"recordType":"path","path":"gateway.controlUi.allowedOrigins.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"gateway.controlUi.allowInsecureAuth","kind":"core","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["access","advanced","network","security"],"label":"Insecure Control UI Auth Toggle","help":"Loosens strict browser auth checks for Control UI when you must run a non-standard setup. Keep this off unless you trust your network and proxy path, because impersonation risk is higher.","hasChildren":false}
|
||||
{"recordType":"path","path":"gateway.controlUi.basePath","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":["network","storage"],"label":"Control UI Base Path","help":"Optional URL prefix where the Control UI is served (e.g. /openclaw).","hasChildren":false}
|
||||
@@ -3667,7 +3677,7 @@
|
||||
{"recordType":"path","path":"gateway.trustedProxies","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["network"],"label":"Gateway Trusted Proxy CIDRs","help":"CIDR/IP allowlist of upstream proxies permitted to provide forwarded client identity headers. Keep this list narrow so untrusted hops cannot impersonate users.","hasChildren":true}
|
||||
{"recordType":"path","path":"gateway.trustedProxies.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"hooks","kind":"core","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Hooks","help":"Inbound webhook automation surface for mapping external events into wake or agent actions in OpenClaw. Keep this locked down with explicit token/session/agent controls before exposing it beyond trusted networks.","hasChildren":true}
|
||||
{"recordType":"path","path":"hooks.allowedAgentIds","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Hooks Allowed Agent IDs","help":"Allowlist of agent IDs that hook mappings are allowed to target when selecting execution agents. Use this to constrain automation events to dedicated service agents.","hasChildren":true}
|
||||
{"recordType":"path","path":"hooks.allowedAgentIds","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Hooks Allowed Agent IDs","help":"Allowlist of agent IDs that hook mappings are allowed to target when selecting execution agents. Use this to constrain automation events to dedicated service agents and reduce blast radius if a hook token is exposed.","hasChildren":true}
|
||||
{"recordType":"path","path":"hooks.allowedAgentIds.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"hooks.allowedSessionKeyPrefixes","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access","storage"],"label":"Hooks Allowed Session Key Prefixes","help":"Allowlist of accepted session-key prefixes for inbound hook requests when caller-provided keys are enabled. Use narrow prefixes to prevent arbitrary session-key injection.","hasChildren":true}
|
||||
{"recordType":"path","path":"hooks.allowedSessionKeyPrefixes.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
@@ -3754,7 +3764,7 @@
|
||||
{"recordType":"path","path":"hooks.path","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":["storage"],"label":"Hooks Endpoint Path","help":"HTTP path used by the hooks endpoint (for example `/hooks`) on the gateway control server. Use a non-guessable path and combine it with token validation for defense in depth.","hasChildren":false}
|
||||
{"recordType":"path","path":"hooks.presets","kind":"core","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Hooks Presets","help":"Named hook preset bundles applied at load time to seed standard mappings and behavior defaults. Keep preset usage explicit so operators can audit which automations are active.","hasChildren":true}
|
||||
{"recordType":"path","path":"hooks.presets.*","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"hooks.token","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":true,"tags":["auth","security"],"label":"Hooks Auth Token","help":"Shared bearer token checked by hooks ingress for request authentication before mappings run. Use environment substitution and rotate regularly when webhook endpoints are internet-accessible.","hasChildren":false}
|
||||
{"recordType":"path","path":"hooks.token","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":true,"tags":["auth","security"],"label":"Hooks Auth Token","help":"Shared bearer token checked by hooks ingress for request authentication before mappings run. Treat holders as full-trust callers for the hook ingress surface, not as a separate non-owner role. Use environment substitution and rotate regularly when webhook endpoints are internet-accessible.","hasChildren":false}
|
||||
{"recordType":"path","path":"hooks.transformsDir","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":["storage"],"label":"Hooks Transforms Directory","help":"Base directory for hook transform modules referenced by mapping transform.module paths. Use a controlled repo directory so dynamic imports remain reviewable and predictable.","hasChildren":false}
|
||||
{"recordType":"path","path":"logging","kind":"core","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Logging","help":"Logging behavior controls for severity, output destinations, formatting, and sensitive-data redaction. Keep levels and redaction strict enough for production while preserving useful diagnostics.","hasChildren":true}
|
||||
{"recordType":"path","path":"logging.consoleLevel","kind":"core","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":["observability"],"label":"Console Log Level","help":"Console-specific log threshold: \"silent\", \"fatal\", \"error\", \"warn\", \"info\", \"debug\", or \"trace\" for terminal output control. Use this to keep local console quieter while retaining richer file logging if needed.","hasChildren":false}
|
||||
@@ -4093,6 +4103,15 @@
|
||||
{"recordType":"path","path":"plugins.entries.byteplus.subagent.allowedModels","kind":"plugin","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Plugin Subagent Allowed Models","help":"Allowed override targets for trusted plugin subagent runs as canonical \"provider/model\" refs. Use \"*\" only when you intentionally allow any model.","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.byteplus.subagent.allowedModels.*","kind":"plugin","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.byteplus.subagent.allowModelOverride","kind":"plugin","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Allow Plugin Subagent Model Override","help":"Explicitly allows this plugin to request provider/model overrides in background subagent runs. Keep false unless the plugin is trusted to steer model selection.","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.chutes","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"@openclaw/chutes-provider","help":"OpenClaw Chutes.ai provider plugin (plugin: chutes)","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.config","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"@openclaw/chutes-provider Config","help":"Plugin-defined config payload for chutes.","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.enabled","kind":"plugin","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Enable @openclaw/chutes-provider","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.hooks","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Plugin Hook Policy","help":"Per-plugin typed hook policy controls for core-enforced safety gates. Use this to constrain high-impact hook categories without disabling the entire plugin.","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.hooks.allowPromptInjection","kind":"plugin","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Allow Prompt Injection Hooks","help":"Controls whether this plugin may mutate prompts through typed hooks. Set false to block `before_prompt_build` and ignore prompt-mutating fields from legacy `before_agent_start`, while preserving legacy `modelOverride` and `providerOverride` behavior.","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.subagent","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Plugin Subagent Policy","help":"Per-plugin subagent runtime controls for model override trust and allowlists. Keep this unset unless a plugin must explicitly steer subagent model selection.","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.subagent.allowedModels","kind":"plugin","type":"array","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Plugin Subagent Allowed Models","help":"Allowed override targets for trusted plugin subagent runs as canonical \"provider/model\" refs. Use \"*\" only when you intentionally allow any model.","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.subagent.allowedModels.*","kind":"plugin","type":"string","required":false,"deprecated":false,"sensitive":false,"tags":[],"hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.chutes.subagent.allowModelOverride","kind":"plugin","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["access"],"label":"Allow Plugin Subagent Model Override","help":"Explicitly allows this plugin to request provider/model overrides in background subagent runs. Keep false unless the plugin is trusted to steer model selection.","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.cloudflare-ai-gateway","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"@openclaw/cloudflare-ai-gateway-provider","help":"OpenClaw Cloudflare AI Gateway provider plugin (plugin: cloudflare-ai-gateway)","hasChildren":true}
|
||||
{"recordType":"path","path":"plugins.entries.cloudflare-ai-gateway.config","kind":"plugin","type":"object","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"@openclaw/cloudflare-ai-gateway-provider Config","help":"Plugin-defined config payload for cloudflare-ai-gateway.","hasChildren":false}
|
||||
{"recordType":"path","path":"plugins.entries.cloudflare-ai-gateway.enabled","kind":"plugin","type":"boolean","required":false,"deprecated":false,"sensitive":false,"tags":["advanced"],"label":"Enable @openclaw/cloudflare-ai-gateway-provider","hasChildren":false}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/chutes-provider",
|
||||
"version": "2026.3.17",
|
||||
"version": "2026.3.14",
|
||||
"private": true,
|
||||
"description": "OpenClaw Chutes.ai provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -45,7 +45,6 @@ export {
|
||||
buildMentionedCardContent,
|
||||
type MentionTarget,
|
||||
} from "./src/mention.js";
|
||||
export { feishuPlugin } from "./src/channel.js";
|
||||
|
||||
export default defineChannelPluginEntry({
|
||||
id: "feishu",
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
export * from "./src/setup-core.js";
|
||||
export * from "./src/setup-surface.js";
|
||||
export * from "./src/runtime.js";
|
||||
|
||||
@@ -1,42 +1,10 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { ResolvedSlackAccount } from "../../../../extensions/slack/src/accounts.js";
|
||||
import type { SlackMessageEvent } from "../../../../extensions/slack/src/types.js";
|
||||
import type { MsgContext } from "../../../auto-reply/templating.js";
|
||||
import type { OpenClawConfig } from "../../../config/config.js";
|
||||
import { inboundCtxCapture } from "./inbound-testkit.js";
|
||||
import { expectChannelInboundContextContract } from "./suites.js";
|
||||
|
||||
const dispatchInboundMessageMock = vi.hoisted(() =>
|
||||
vi.fn(
|
||||
async (params: {
|
||||
ctx: MsgContext;
|
||||
replyOptions?: { onReplyStart?: () => void | Promise<void> };
|
||||
}) => {
|
||||
await Promise.resolve(params.replyOptions?.onReplyStart?.());
|
||||
return { queuedFinal: false, counts: { tool: 0, block: 0, final: 0 } };
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
vi.mock("openclaw/plugin-sdk/reply-runtime", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("openclaw/plugin-sdk/reply-runtime")>();
|
||||
return {
|
||||
...actual,
|
||||
dispatchInboundMessage: vi.fn(async (params: { ctx: MsgContext }) => {
|
||||
inboundCtxCapture.ctx = params.ctx;
|
||||
return await dispatchInboundMessageMock(params);
|
||||
}),
|
||||
dispatchInboundMessageWithDispatcher: vi.fn(async (params: { ctx: MsgContext }) => {
|
||||
inboundCtxCapture.ctx = params.ctx;
|
||||
return await dispatchInboundMessageMock(params);
|
||||
}),
|
||||
dispatchInboundMessageWithBufferedDispatcher: vi.fn(async (params: { ctx: MsgContext }) => {
|
||||
inboundCtxCapture.ctx = params.ctx;
|
||||
return await dispatchInboundMessageMock(params);
|
||||
}),
|
||||
};
|
||||
});
|
||||
|
||||
vi.mock("../../../../extensions/signal/src/send.js", () => ({
|
||||
sendMessageSignal: vi.fn(),
|
||||
sendTypingSignal: vi.fn(async () => true),
|
||||
@@ -62,10 +30,6 @@ vi.mock("../../../../extensions/whatsapp/src/auto-reply/deliver-reply.js", () =>
|
||||
deliverWebReply: vi.fn(async () => {}),
|
||||
}));
|
||||
|
||||
const { processDiscordMessage } =
|
||||
await import("../../../../extensions/discord/src/monitor/message-handler.process.js");
|
||||
const { createBaseDiscordMessageContext, createDiscordDirectMessageContextOverrides } =
|
||||
await import("../../../../extensions/discord/src/monitor/message-handler.test-harness.js");
|
||||
const { finalizeInboundContext } = await import("../../../auto-reply/reply/inbound-context.js");
|
||||
const { prepareSlackMessage } =
|
||||
await import("../../../../extensions/slack/src/monitor/message-handler/prepare.js");
|
||||
@@ -102,20 +66,33 @@ function createSlackMessage(overrides: Partial<SlackMessageEvent>): SlackMessage
|
||||
describe("channel inbound contract", () => {
|
||||
beforeEach(() => {
|
||||
inboundCtxCapture.ctx = undefined;
|
||||
dispatchInboundMessageMock.mockClear();
|
||||
});
|
||||
|
||||
it("keeps Discord inbound context finalized", async () => {
|
||||
const messageCtx = await createBaseDiscordMessageContext({
|
||||
cfg: { messages: {} },
|
||||
ackReactionScope: "direct",
|
||||
...createDiscordDirectMessageContextOverrides(),
|
||||
const ctx = finalizeInboundContext({
|
||||
Body: "hi",
|
||||
BodyForAgent: "hi",
|
||||
RawBody: "hi",
|
||||
CommandBody: "hi",
|
||||
BodyForCommands: "hi",
|
||||
From: "discord:U1",
|
||||
To: "channel:c1",
|
||||
SessionKey: "agent:main:discord:direct:u1",
|
||||
AccountId: "default",
|
||||
ChatType: "direct",
|
||||
ConversationLabel: "alice user id:U1",
|
||||
SenderName: "Alice",
|
||||
SenderId: "U1",
|
||||
SenderUsername: "alice",
|
||||
Provider: "discord",
|
||||
Surface: "discord",
|
||||
MessageSid: "m1",
|
||||
OriginatingChannel: "discord",
|
||||
OriginatingTo: "channel:c1",
|
||||
CommandAuthorized: true,
|
||||
});
|
||||
|
||||
await processDiscordMessage(messageCtx);
|
||||
|
||||
expect(inboundCtxCapture.ctx).toBeTruthy();
|
||||
expectChannelInboundContextContract(inboundCtxCapture.ctx!);
|
||||
expectChannelInboundContextContract(ctx);
|
||||
});
|
||||
|
||||
it("keeps Signal inbound context finalized", async () => {
|
||||
|
||||
@@ -16,16 +16,12 @@ type ResolveOwningPluginIdsForProvider =
|
||||
type ResolveNonBundledProviderPluginIds =
|
||||
typeof import("../providers.js").resolveNonBundledProviderPluginIds;
|
||||
|
||||
const resolvePluginProvidersMock = vi.hoisted(() =>
|
||||
vi.fn<ResolvePluginProviders>((_) => uniqueProviderContractProviders),
|
||||
);
|
||||
const resolvePluginProvidersMock = vi.hoisted(() => vi.fn<ResolvePluginProviders>());
|
||||
const resolveOwningPluginIdsForProviderMock = vi.hoisted(() =>
|
||||
vi.fn<ResolveOwningPluginIdsForProvider>((params) =>
|
||||
resolveProviderContractPluginIdsForProvider(params.provider),
|
||||
),
|
||||
vi.fn<ResolveOwningPluginIdsForProvider>(),
|
||||
);
|
||||
const resolveNonBundledProviderPluginIdsMock = vi.hoisted(() =>
|
||||
vi.fn<ResolveNonBundledProviderPluginIds>((_) => [] as string[]),
|
||||
vi.fn<ResolveNonBundledProviderPluginIds>(),
|
||||
);
|
||||
|
||||
vi.mock("../providers.js", () => ({
|
||||
|
||||
@@ -12,7 +12,7 @@ import perplexityPlugin from "../../../extensions/perplexity/index.js";
|
||||
import xaiPlugin from "../../../extensions/xai/index.js";
|
||||
import zaiPlugin from "../../../extensions/zai/index.js";
|
||||
import { createCapturedPluginRegistration } from "../captured-registration.js";
|
||||
import { resolvePluginProviders } from "../providers.js";
|
||||
import { loadPluginManifestRegistry } from "../manifest-registry.js";
|
||||
import type {
|
||||
ImageGenerationProviderPlugin,
|
||||
MediaUnderstandingProviderPlugin,
|
||||
@@ -99,19 +99,76 @@ export const providerContractRegistry: ProviderContractEntry[] = buildCapability
|
||||
select: () => [],
|
||||
});
|
||||
|
||||
const loadedBundledProviderRegistry: ProviderContractEntry[] = resolvePluginProviders({
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
cache: false,
|
||||
activate: false,
|
||||
})
|
||||
.filter((provider): provider is ProviderPlugin & { pluginId: string } =>
|
||||
Boolean(provider.pluginId),
|
||||
)
|
||||
.map((provider) => ({
|
||||
pluginId: provider.pluginId,
|
||||
provider,
|
||||
}));
|
||||
const bundledProviderContractPluginLoaders: Record<
|
||||
string,
|
||||
() => Promise<{ default: RegistrablePlugin }>
|
||||
> = {
|
||||
"amazon-bedrock": () => import("../../../extensions/amazon-bedrock/index.js"),
|
||||
anthropic: () => import("../../../extensions/anthropic/index.js"),
|
||||
byteplus: () => import("../../../extensions/byteplus/index.js"),
|
||||
chutes: () => import("../../../extensions/chutes/index.js"),
|
||||
"cloudflare-ai-gateway": () => import("../../../extensions/cloudflare-ai-gateway/index.js"),
|
||||
"copilot-proxy": () => import("../../../extensions/copilot-proxy/index.js"),
|
||||
"github-copilot": () => import("../../../extensions/github-copilot/index.js"),
|
||||
google: () => import("../../../extensions/google/index.js"),
|
||||
huggingface: () => import("../../../extensions/huggingface/index.js"),
|
||||
kilocode: () => import("../../../extensions/kilocode/index.js"),
|
||||
kimi: () => import("../../../extensions/kimi-coding/index.js"),
|
||||
minimax: () => import("../../../extensions/minimax/index.js"),
|
||||
mistral: () => import("../../../extensions/mistral/index.js"),
|
||||
modelstudio: () => import("../../../extensions/modelstudio/index.js"),
|
||||
moonshot: () => import("../../../extensions/moonshot/index.js"),
|
||||
nvidia: () => import("../../../extensions/nvidia/index.js"),
|
||||
ollama: () => import("../../../extensions/ollama/index.js"),
|
||||
openai: () => import("../../../extensions/openai/index.js"),
|
||||
opencode: () => import("../../../extensions/opencode/index.js"),
|
||||
"opencode-go": () => import("../../../extensions/opencode-go/index.js"),
|
||||
openrouter: () => import("../../../extensions/openrouter/index.js"),
|
||||
qianfan: () => import("../../../extensions/qianfan/index.js"),
|
||||
"qwen-portal-auth": () => import("../../../extensions/qwen-portal-auth/index.js"),
|
||||
sglang: () => import("../../../extensions/sglang/index.js"),
|
||||
synthetic: () => import("../../../extensions/synthetic/index.js"),
|
||||
together: () => import("../../../extensions/together/index.js"),
|
||||
venice: () => import("../../../extensions/venice/index.js"),
|
||||
"vercel-ai-gateway": () => import("../../../extensions/vercel-ai-gateway/index.js"),
|
||||
vllm: () => import("../../../extensions/vllm/index.js"),
|
||||
volcengine: () => import("../../../extensions/volcengine/index.js"),
|
||||
xai: () => import("../../../extensions/xai/index.js"),
|
||||
xiaomi: () => import("../../../extensions/xiaomi/index.js"),
|
||||
zai: () => import("../../../extensions/zai/index.js"),
|
||||
};
|
||||
|
||||
async function loadBundledProviderContractPlugins(): Promise<RegistrablePlugin[]> {
|
||||
const bundledProviderPluginIds = loadPluginManifestRegistry({})
|
||||
.plugins.filter((plugin) => plugin.origin === "bundled" && plugin.providers.length > 0)
|
||||
.map((plugin) => plugin.id)
|
||||
.toSorted((left, right) => left.localeCompare(right));
|
||||
|
||||
const modules = await Promise.all(
|
||||
bundledProviderPluginIds.map((pluginId) => {
|
||||
const load = bundledProviderContractPluginLoaders[pluginId];
|
||||
if (!load) {
|
||||
throw new Error(`missing bundled provider contract loader for ${pluginId}`);
|
||||
}
|
||||
return load();
|
||||
}),
|
||||
);
|
||||
|
||||
return modules.map((mod, index) => {
|
||||
const plugin = mod.default as RegistrablePlugin | undefined;
|
||||
if (!plugin) {
|
||||
throw new Error(
|
||||
`bundled provider contract plugin missing default export for ${bundledProviderPluginIds[index]}`,
|
||||
);
|
||||
}
|
||||
return plugin;
|
||||
});
|
||||
}
|
||||
|
||||
const loadedBundledProviderRegistry: ProviderContractEntry[] = buildCapabilityContractRegistry({
|
||||
plugins: await loadBundledProviderContractPlugins(),
|
||||
select: (captured) => captured.providers,
|
||||
});
|
||||
|
||||
providerContractRegistry.splice(
|
||||
0,
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { ProviderPlugin } from "../types.js";
|
||||
import { providerContractPluginIds, uniqueProviderContractProviders } from "./registry.js";
|
||||
|
||||
const resolvePluginProvidersMock = vi.fn();
|
||||
const resolvePluginProvidersMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("../providers.js", () => ({
|
||||
resolvePluginProviders: (...args: unknown[]) => resolvePluginProvidersMock(...args),
|
||||
@@ -12,6 +11,8 @@ let buildProviderPluginMethodChoice: typeof import("../provider-wizard.js").buil
|
||||
let resolveProviderModelPickerEntries: typeof import("../provider-wizard.js").resolveProviderModelPickerEntries;
|
||||
let resolveProviderPluginChoice: typeof import("../provider-wizard.js").resolveProviderPluginChoice;
|
||||
let resolveProviderWizardOptions: typeof import("../provider-wizard.js").resolveProviderWizardOptions;
|
||||
let contractProviders: ProviderPlugin[] = [];
|
||||
let providerContractPluginIds: string[] = [];
|
||||
|
||||
function resolveExpectedWizardChoiceValues(providers: ProviderPlugin[]) {
|
||||
const values: string[] = [];
|
||||
@@ -72,6 +73,23 @@ function resolveExpectedModelPickerValues(providers: ProviderPlugin[]) {
|
||||
describe("provider wizard contract", () => {
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
const providersModule =
|
||||
await vi.importActual<typeof import("../providers.js")>("../providers.js");
|
||||
contractProviders = providersModule.resolvePluginProviders({
|
||||
bundledProviderAllowlistCompat: true,
|
||||
bundledProviderVitestCompat: true,
|
||||
env: {
|
||||
...process.env,
|
||||
VITEST: process.env.VITEST || "1",
|
||||
},
|
||||
cache: false,
|
||||
activate: false,
|
||||
});
|
||||
providerContractPluginIds = [
|
||||
...new Set(
|
||||
contractProviders.map((provider) => provider.pluginId).filter(Boolean) as string[],
|
||||
),
|
||||
].toSorted((left, right) => left.localeCompare(right));
|
||||
({
|
||||
buildProviderPluginMethodChoice,
|
||||
resolveProviderModelPickerEntries,
|
||||
@@ -79,7 +97,7 @@ describe("provider wizard contract", () => {
|
||||
resolveProviderWizardOptions,
|
||||
} = await import("../provider-wizard.js"));
|
||||
resolvePluginProvidersMock.mockReset();
|
||||
resolvePluginProvidersMock.mockReturnValue(uniqueProviderContractProviders);
|
||||
resolvePluginProvidersMock.mockReturnValue(contractProviders);
|
||||
});
|
||||
|
||||
it("exposes every registered provider setup choice through the shared wizard layer", () => {
|
||||
@@ -98,7 +116,7 @@ describe("provider wizard contract", () => {
|
||||
|
||||
expect(
|
||||
options.map((option) => option.value).toSorted((left, right) => left.localeCompare(right)),
|
||||
).toEqual(resolveExpectedWizardChoiceValues(uniqueProviderContractProviders));
|
||||
).toEqual(resolveExpectedWizardChoiceValues(contractProviders));
|
||||
expect(options.map((option) => option.value)).toEqual([
|
||||
...new Set(options.map((option) => option.value)),
|
||||
]);
|
||||
@@ -107,7 +125,7 @@ describe("provider wizard contract", () => {
|
||||
it("round-trips every shared wizard choice back to its provider and auth method", () => {
|
||||
for (const option of resolveProviderWizardOptions({ config: {}, env: process.env })) {
|
||||
const resolved = resolveProviderPluginChoice({
|
||||
providers: uniqueProviderContractProviders,
|
||||
providers: contractProviders,
|
||||
choice: option.value,
|
||||
});
|
||||
expect(resolved).not.toBeNull();
|
||||
@@ -121,10 +139,10 @@ describe("provider wizard contract", () => {
|
||||
|
||||
expect(
|
||||
entries.map((entry) => entry.value).toSorted((left, right) => left.localeCompare(right)),
|
||||
).toEqual(resolveExpectedModelPickerValues(uniqueProviderContractProviders));
|
||||
).toEqual(resolveExpectedModelPickerValues(contractProviders));
|
||||
for (const entry of entries) {
|
||||
const resolved = resolveProviderPluginChoice({
|
||||
providers: uniqueProviderContractProviders,
|
||||
providers: contractProviders,
|
||||
choice: entry.value,
|
||||
});
|
||||
expect(resolved).not.toBeNull();
|
||||
|
||||
Reference in New Issue
Block a user