Skip to content

Commit 98e3895

Browse files
authored
Merge branch 'main' into cron-webhook-reject-credentials
2 parents 1329a47 + 4229ffe commit 98e3895

149 files changed

Lines changed: 5649 additions & 3133 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ Docs: https://docs.openclaw.ai
6161
- Models/GitHub Copilot: allow forward-compat dynamic model ids without code updates, while preserving configured provider and per-model overrides for those synthetic models. (#51325) Thanks @fuller-stack-dev.
6262
- Agents/compaction: notify users when followup auto-compaction starts and finishes, keeping those notices out of TTS and preserving reply threading for the real assistant reply. (#38805) Thanks @zidongdesign.
6363
- Models/OpenAI: switch the default OpenAI setup model to `openai/gpt-5.4`, keep Codex on `openai-codex/gpt-5.4`, and centralize OpenAI chat, image, TTS, transcription, and embedding defaults in one shared module so future default-model updates stay low-churn. Thanks @vincentkoc.
64+
- Memory/plugins: let the active memory plugin register its own system-prompt section while preserving cache-clear and snapshot-load prompt isolation. (#40126) Thanks @jarimustonen.
6465

6566
### Fixes
6667

68+
- Gateway/Linux: auto-detect nvm-managed Node TLS CA bundle needs before CLI startup and refresh installed services that are missing `NODE_EXTRA_CA_CERTS`. (#51146) Thanks @GodsBoy.
6769
- CLI/config: make `config set --strict-json` enforce real JSON, prefer `JSON.parse` with JSON5 fallback for machine-written cron/subagent stores, and relabel raw config surfaces as `JSON/JSON5` to match actual compatibility. Related: #48415, #43127, #14529, #21332. Thanks @adhitShet and @vincentkoc.
6870
- CLI/Ollama onboarding: keep the interactive model picker for explicit `openclaw onboard --auth-choice ollama` runs so setup still selects a default model without reintroducing pre-picker auto-pulls. (#49249) Thanks @BruceMacD.
6971
- Plugins/bundler TDZ: fix `RESERVED_COMMANDS` temporal dead zone error that prevented device-pair, phone-control, and talk-voice plugins from registering when the bundler placed the commands module after call sites in the same output chunk. Thanks @BunsDev.
@@ -170,6 +172,7 @@ Docs: https://docs.openclaw.ai
170172
- Exec: harden host env override handling across gateway and node (#51207) Thanks @gladiator9797 and @joshavant.
171173
- Voice Call: enforce spoken-output contract and fix stream TTS silence regression (#51500) Thanks @joshavant.
172174
- xAI/models: rename the bundled Grok 4.20 catalog entries to the GA IDs and normalize saved deprecated beta IDs at runtime so existing configs and sessions keep resolving. (#50772) thanks @Jaaneek
175+
- Plugins/Matrix TTS: send auto-TTS replies as native Matrix voice bubbles instead of generic audio attachments. (#37080) thanks @Matthew19990919.
173176

174177
### Fixes
175178

@@ -204,14 +207,17 @@ Docs: https://docs.openclaw.ai
204207
- Web search: align onboarding, configure, and finalize with plugin-owned provider contracts, including disabled-provider recovery, config-aware credential hooks, and runtime-visible summaries. (#50935) Thanks @gumadeiras.
205208
- Agents/replay: sanitize malformed assistant tool-call replay blocks before provider replay so follow-up Anthropic requests do not inherit the downstream `replace` crash. (#50005) Thanks @jalehman.
206209
- Plugins/context engines: retry strict legacy `assemble()` calls without the new `prompt` field when older engines reject it, preserving prompt-aware retrieval compatibility for pre-prompt plugins. (#50848) thanks @danhdoan.
210+
- make `openclaw update status` explicitly say `up to date` when the local version already matches npm latest, while keeping the availability logic unchanged. (#51409) Thanks @dongzhenye.
207211
- Agents/embedded transport errors: distinguish common network failures like connection refused, DNS lookup failure, and interrupted sockets from true timeouts in embedded-run user messaging and lifecycle diagnostics. (#51419) Thanks @scoootscooob.
208-
- Discord/startup logging: report client initialization while the gateway is still connecting instead of claiming Discord is logged in before readiness is reached. (#51425) Thanks @scoootscooob.
212+
- Discord/startup logging: report client initialization while the gateway is still connecting instead of claiming Discord is logged in before readiness is reached. (#51425) Thanks @scoootscoob.
209213
- Gateway/probe: honor caller `--timeout` for active local loopback probes in `gateway status`, keep inactive remote-mode loopback probes fast, and clamp probe timers to JS-safe bounds so slow local/container gateways stop reporting false timeouts. (#47533) Thanks @MonkeyLeeT.
210214
- Config/startup: keep bundled web-search allowlist compatibility on a lightweight manifest path so config validation no longer pulls bundled web-search registry imports into startup, while still avoiding accidental auto-allow of config-loaded override plugins. (#51574) Thanks @RichardCao.
211215
- Gateway/chat.send: persist uploaded image references across reloads and compaction without delaying first-turn dispatch or double-submitting the same image to vision models. (#51324) Thanks @fuller-stack-dev.
212216
- Plugins/runtime state: share plugin-facing infra singleton state across duplicate module graphs and keep session-binding adapter ownership stable until the active owner unregisters. (#50725) thanks @huntharo.
213217
- Agents/compaction safeguard: preserve split-turn context and preserved recent turns when capped retry fallback reuses the last successful summary. (#27727) thanks @Pandadadadazxf.
214218
- Discord/pickers: keep `/codex_resume --browse-projects` picker callbacks alive in Discord by sharing component callback state across duplicate module graphs, preserving callback fallbacks, and acknowledging matched plugin interactions before dispatch. (#51260) Thanks @huntharo.
219+
- Agents/memory flush: keep transcript-hash dedup active across memory-flush fallback retries so a write-then-throw flush attempt cannot append duplicate `MEMORY.md` entries before the fallback cycle completes. (#34222) Thanks @lml2468.
220+
- make `openclaw update status` explicitly say `up to date` when the local version already matches npm latest, while keeping the availability logic unchanged. (#51409) Thanks @dongzhenye.
215221

216222
### Breaking
217223

@@ -406,6 +412,7 @@ Docs: https://docs.openclaw.ai
406412

407413
- Control UI/auth: restore one-time legacy `?token=` imports for shared Control UI links while keeping `#token=` preferred, and carry pending query tokens through gateway URL confirmation so compatibility links still authenticate after confirmation. (#43979) Thanks @stim64045-spec.
408414
- Plugins/context engines: retry legacy lifecycle calls once without `sessionKey` when older plugins reject that field, memoize legacy mode after the first strict-schema fallback, and preserve non-compat runtime errors without retry. (#44779) thanks @hhhhao28.
415+
- Agents/compaction: treat markup-wrapped heartbeat boilerplate as non-meaningful session history when deciding whether to compact, so heartbeat-only sessions no longer keep compaction alive due to wrapper formatting. (#42119) thanks @samzong.
409416

410417
## 2026.3.11
411418

docs/help/environment.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,29 @@ When set, `OPENCLAW_HOME` replaces the system home directory (`$HOME` / `os.home
133133

134134
`OPENCLAW_HOME` can also be set to a tilde path (e.g. `~/svc`), which gets expanded using `$HOME` before use.
135135

136+
## nvm users: web_fetch TLS failures
137+
138+
If Node.js was installed via **nvm** (not the system package manager), the built-in `fetch()` uses
139+
nvm's bundled CA store, which may be missing modern root CAs (ISRG Root X1/X2 for Let's Encrypt,
140+
DigiCert Global Root G2, etc.). This causes `web_fetch` to fail with `"fetch failed"` on most HTTPS sites.
141+
142+
On Linux, OpenClaw automatically detects nvm and applies the fix in the actual startup environment:
143+
144+
- `openclaw gateway install` writes `NODE_EXTRA_CA_CERTS` into the systemd service environment
145+
- the `openclaw` CLI entrypoint re-execs itself with `NODE_EXTRA_CA_CERTS` set before Node startup
146+
147+
**Manual fix (for older versions or direct `node ...` launches):**
148+
149+
Export the variable before starting OpenClaw:
150+
151+
```bash
152+
export NODE_EXTRA_CA_CERTS=/etc/ssl/certs/ca-certificates.crt
153+
openclaw gateway run
154+
```
155+
156+
Do not rely on writing only to `~/.openclaw/.env` for this variable; Node reads
157+
`NODE_EXTRA_CA_CERTS` at process startup.
158+
136159
## Related
137160

138161
- [Gateway configuration](/gateway/configuration)

docs/plugins/building-plugins.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ my-plugin/
128128
**Provider plugin:**
129129

130130
```typescript
131-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
131+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
132132

133133
export default definePluginEntry({
134134
id: "my-provider",
@@ -144,7 +144,7 @@ my-plugin/
144144
**Multi-capability plugin** (provider + tool):
145145

146146
```typescript
147-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
147+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
148148

149149
export default definePluginEntry({
150150
id: "my-plugin",
@@ -157,8 +157,14 @@ my-plugin/
157157
});
158158
```
159159

160-
Use `defineChannelPluginEntry` for channel plugins and `definePluginEntry`
161-
for everything else. A single plugin can register as many capabilities as needed.
160+
Use `defineChannelPluginEntry` from `plugin-sdk/core` for channel plugins
161+
and `definePluginEntry` from `plugin-sdk/plugin-entry` for everything else.
162+
A single plugin can register as many capabilities as needed.
163+
164+
For chat-style channels, `plugin-sdk/core` also exposes
165+
`createChatChannelPlugin(...)` so you can compose common DM security,
166+
text pairing, reply threading, and attached outbound send results without
167+
wiring each adapter separately.
162168

163169
</Step>
164170

@@ -173,7 +179,7 @@ my-plugin/
173179

174180
```typescript
175181
// Correct: focused subpaths
176-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
182+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
177183
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
178184
import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-oauth";
179185

@@ -187,7 +193,8 @@ my-plugin/
187193
<Accordion title="Common subpaths reference">
188194
| Subpath | Purpose |
189195
| --- | --- |
190-
| `plugin-sdk/core` | Plugin entry definitions and base types |
196+
| `plugin-sdk/plugin-entry` | Canonical `definePluginEntry` helper + provider/plugin entry types |
197+
| `plugin-sdk/core` | Channel entry helpers, channel builders, and shared base types |
191198
| `plugin-sdk/channel-setup` | Setup wizard adapters |
192199
| `plugin-sdk/channel-pairing` | DM pairing primitives |
193200
| `plugin-sdk/channel-reply-pipeline` | Reply prefix + typing wiring |

docs/plugins/sdk-migration.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ is a small, self-contained module with a clear purpose and documented contract.
115115
<Accordion title="Full import path table">
116116
| Import path | Purpose | Key exports |
117117
| --- | --- | --- |
118-
| `plugin-sdk/core` | Plugin entry definitions, base types | `defineChannelPluginEntry`, `definePluginEntry` |
118+
| `plugin-sdk/plugin-entry` | Canonical plugin entry helper | `definePluginEntry` |
119+
| `plugin-sdk/core` | Channel entry definitions, channel builders, base types | `defineChannelPluginEntry`, `createChatChannelPlugin` |
119120
| `plugin-sdk/channel-setup` | Setup wizard adapters | `createOptionalChannelSetupSurface` |
120121
| `plugin-sdk/channel-pairing` | DM pairing primitives | `createChannelPairingController` |
121122
| `plugin-sdk/channel-reply-pipeline` | Reply prefix + typing wiring | `createChannelReplyPipeline` |

extensions/anthropic/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
type ProviderAuthContext,
66
type ProviderResolveDynamicModelContext,
77
type ProviderRuntimeModel,
8-
} from "openclaw/plugin-sdk/core";
8+
} from "openclaw/plugin-sdk/plugin-entry";
99
import {
1010
CLAUDE_CLI_PROFILE_ID,
1111
applyAuthProfileConfig,

extensions/brave/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
1+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
22
import { createBraveWebSearchProvider } from "./src/brave-web-search-provider.js";
33

44
export default definePluginEntry({

extensions/byteplus/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
1+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
22
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth";
33
import { ensureModelAllowlistEntry } from "openclaw/plugin-sdk/provider-onboard";
44
import { buildBytePlusCodingProvider, buildBytePlusProvider } from "./provider-catalog.js";

extensions/cloudflare-ai-gateway/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
1+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
22
import {
33
applyAuthProfileConfig,
44
buildApiKeyCredential,

extensions/diagnostics-otel/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { definePluginEntry } from "openclaw/plugin-sdk/core";
1+
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
22
import { createDiagnosticsOtelService } from "./src/service.js";
33

44
export default definePluginEntry({

extensions/discord/src/directory-config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import {
22
listInspectedDirectoryEntriesFromSources,
33
type DirectoryConfigParams,
44
} from "openclaw/plugin-sdk/directory-runtime";
5-
import { inspectDiscordAccount, type InspectedDiscordAccount } from "../api.js";
5+
import { inspectDiscordAccount, type InspectedDiscordAccount } from "./account-inspect.js";
66

77
export async function listDiscordDirectoryPeersFromConfig(params: DirectoryConfigParams) {
88
return listInspectedDirectoryEntriesFromSources({

0 commit comments

Comments
 (0)