2026.4.25
Highlights
- Voice replies get a full TTS upgrade:
/tts latest, chat-scoped auto-TTS controls, personas, per-agent/per-account overrides, and new Azure Speech, Xiaomi, Local CLI, Inworld, Volcengine, and ElevenLabs v3 provider coverage. Thanks @leonchui, @zoujiejun, @solar2ain, @cshape, @xuruiray, @itsuzef, and @barronlroth. - Plugin startup and install paths move to the cold persisted registry, cutting broad manifest scans while making plugin update, repair, provider discovery, and install metadata more deterministic. Thanks @vincentkoc and @shakkernerd.
- OpenTelemetry coverage expands across model calls, token usage, tool loops, harness runs, exec processes, outbound delivery, context assembly, and memory pressure with bounded low-cardinality attributes. Thanks @vincentkoc, @jlapenna, @Lidang-Jiang, and @oc-factus.
- Browser automation gets safer tab URLs, iframe-aware role snapshots, CDP readiness tuning, headless one-shot launch, and deeper browser doctor probes for slow hosts. Thanks @beat843796 and @BenediktSchackenberg.
- Control UI and setup flows add PWA/Web Push support, Crestodian first-run repair, TUI setup, context mode selection, and a shorter startup greeting. Thanks @eduardocruz, @SebTardif, and @kevinlin-openai.
- Install/update hardening covers Windows, macOS, Linux, Docker, bundled plugin runtime deps, Node service restarts, LaunchAgent token rotation, and mixed-version gateway verification. Thanks @Kobevictor, @igormf, @abhinas90, @jsompis, @Solvely-Colin, and @gucasbrg.
Changes
- TTS/WhatsApp: add
/tts latestread-aloud support with duplicate suppression and/tts chat on|off|defaultsession-scoped auto-TTS overrides, completing the on-demand voice-note UX for current-chat replies. Fixes #66032. - TTS/channels: resolve channel and account TTS overrides generically, enabling Feishu and QQBot accounts to deep-merge
channels.<channel>.accounts.<id>.ttsover global and per-agent TTS config. Thanks @sahilsatralkar. - TTS/agents: allow
agents.list[].ttsto override globalmessages.ttsfor per-agent voices, and make/tts audio,/tts status, and thettsagent tool honor the active voice/provider override while keeping shared provider credentials and preferences in the existing TTS config surface. - Providers/Azure Speech: add Azure Speech as a bundled TTS provider with Speech-resource auth, voice listing, SSML escaping, native Ogg/Opus voice-note output, and telephony output. (#51776) Thanks @leonchui.
- Google Meet: add calendar-backed attendance export workflows, export manifests, dry-run previews, and tool parity for meeting records.
- Control UI: add PWA install support and Web Push notifications for Gateway chat. (#44590) Thanks @eduardocruz.
- Browser automation: add safe tab URLs in agent responses plus a CDP-native role snapshot fallback with iframe-aware refs, cursor-clickable detection, target attach preparation, and
openclaw browser doctor --deeplive snapshot probing. - CLI/image generation: expose generic
--backgroundonopenclaw infer image generateandopenclaw infer image edit, keep--openai-backgroundas an OpenAI alias, and let fal image generation honor--output-format png|jpeg. - Browser/config: allow local managed Chrome launch discovery and post-launch CDP readiness timeouts to be raised for slower hosts such as Raspberry Pi. Fixes #66803. Thanks @beat843796.
- Discord: allow
channels.discord.voice.modelto override the LLM used for voice channel responses while keeping STT and TTS on their existing media settings. (#64368) Thanks @mrdavey. - Browser/CLI: add
openclaw browser start --headlessas a one-shot local managed browser launch override without rewriting persisted browser config. Thanks @BenediktSchackenberg. - CLI/Crestodian/TUI: add the first-run setup helper, local planner fallback, full-TUI interactive Crestodian, startup progress indicators, context mode selector, and a shorter startup greeting. (#71720, #71760) Thanks @SebTardif and @kevinlin-openai.
- Plugins: migrate the local plugin registry automatically during package install/update, keeping install metadata in the plugin index while indexing existing plugin manifests for the new cold registry path. Thanks @vincentkoc and @shakkernerd.
- Plugins/doctor: make
openclaw doctor --fixrefresh the plugin index and cold registry index when needed without treating plugin install records as authored config. Thanks @vincentkoc and @shakkernerd. - Plugins/hooks: add before-agent-finalize hooks, cron
jobIdhook context, bounded native permission fingerprints, and Codex MCP hook relay support. (#71765, #71758, #71707) Thanks @vincentkoc and @pashpashpash. - Plugins/tokenjuice: bump the bundled tokenjuice runtime to 0.6.3. Thanks @vincentkoc.
- Diagnostics/OTEL: align model-call GenAI span attributes with OpenTelemetry stability opt-in semantics, keeping legacy
gen_ai.systemby default while emittinggen_ai.provider.nameunderOTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental. Thanks @vincentkoc. - Diagnostics/OTEL: support signal-specific OTLP endpoint overrides for traces, metrics, and logs via config or standard OTEL environment variables. Thanks @vincentkoc.
- Diagnostics/OTEL: emit bounded telemetry exporter health diagnostics for startup and log-export failures without exporting raw error text. Thanks @vincentkoc.
- Diagnostics/OTEL: export agent harness lifecycle telemetry as bounded
openclaw.harness.runspans andopenclaw.harness.duration_msmetrics so QA-lab, Codex, and future harnesses share one trace shape. Thanks @vincentkoc. - Diagnostics/trace: propagate W3C
traceparentheaders from trusted model-call trace context to provider transports while replacing caller-supplied traceparent values. Thanks @vincentkoc. - Diagnostics/Prometheus: add a bundled
diagnostics-prometheusplugin with a protected gateway scrape route for low-cardinality diagnostics metrics. Thanks @vincentkoc. - Plugins/CLI: add
openclaw plugins registryfor explicit persisted-registry inspection and--refreshrepair without making normal startup rescan plugin locations. Thanks @vincentkoc. - Plugins/CLI: make
openclaw plugins listread the cold persisted registry snapshot by default, leaving module-aware diagnostics toplugins doctorandplugins inspect. Thanks @vincentkoc. - Plugins/startup: move gateway startup plugin planning onto the versioned cold registry index, with postinstall repair for older registry files that predate startup metadata. Thanks @vincentkoc.
- Plugins/startup: normalize startup and provider plugin enablement through registry aliases so boot paths do not need the legacy manifest alias scan. Thanks @vincentkoc.
- Providers/plugins: resolve provider ownership, provider discovery scopes, and catalog-hook provider ids from the cold plugin registry instead of rescanning manifests on those paths. Thanks @vincentkoc.
- Plugins/registry: keep installed plugin index records focused on install/state/load paths and resolve plugin capabilities from manifests scoped to indexed plugins. Thanks @shakkernerd.
- Plugins/registry: route cold manifest and capability lookups through the installed plugin index so setup, channels, config, secrets, doctor, and provider metadata paths avoid broad plugin-root scans before runtime execution. Thanks @shakkernerd.
- CLI/models: speed up
models list --all --provider <id>for static manifest-backed providers by loading catalog rows through the installed plugin index instead of broad manifest scans or runtime suppression hooks. Thanks @shakkernerd. - CLI/models: use OpenClaw Provider Index preview rows as the final cold fallback for installable providers, while keeping user config, installed manifests, and refreshed cache rows above provider-index metadata. Thanks @vincentkoc.
- Providers/plugins: keep onboarding and auth-choice setup lists on cold manifest/install metadata and add Provider Index install metadata for not-yet-installed provider plugins. Thanks @vincentkoc.
- Providers/plugins: keep provider setup guidance and configure auth imports on cold manifest metadata, with a regression guard against static provider-runtime imports on setup/configure list paths. Thanks @vincentkoc.
- CLI/capabilities: keep capability command registration from importing the models auth runtime until
model auth loginactually runs. Thanks @vincentkoc. - CLI/configure: keep web-search configure prompts on cold plugin registry metadata until the user chooses managed search setup. Thanks @vincentkoc.
- Plugins/chat commands: refresh the persisted plugin registry after
/plugins enableand/plugins disable, matching the CLI mutation path. Thanks @vincentkoc. - Plugins/compat: mark
OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRYas a deprecated break-glass switch and point operators at registry repair instead. Thanks @vincentkoc. - Plugins/compat: expand the central compatibility registry with dated owners, replacements, and maximum three-month removal targets for legacy SDK, manifest, setup, registry-migration, and agent-runtime surfaces. Thanks @vincentkoc.
- Plugins/registry: ignore stale persisted registry reads when plugin policy no longer matches current config, and stamp generated registry files with a do-not-edit warning. Thanks @vincentkoc.
- Config/plugins: keep plugin command-alias validation on cold manifest metadata instead of importing the runtime alias resolver. Thanks @vincentkoc.
- Security/plugins: keep web-search credential presence checks on cold config, env, and manifest metadata instead of importing web-search provider runtime. Thanks @vincentkoc.
- Diagnostics/OTEL: surface provider request identifiers as bounded hashes on model-call diagnostics and span events, without exporting raw request IDs or metric labels. Thanks @Lidang-Jiang and @vincentkoc.
- Plugins/diagnostics: add metadata-only
model_call_startedandmodel_call_endedhooks for provider/model call telemetry without exposing prompts, responses, headers, request bodies, or raw provider request IDs. Thanks @vincentkoc. - Diagnostics/OTEL: emit bounded context assembly diagnostics and export
openclaw.context.assembledspans with prompt/history sizes but no prompt, history, response, or session-key content. Thanks @vincentkoc. - Diagnostics/OTEL: export existing tool-loop diagnostics as
openclaw.tool.loopcounters and spans without loop messages, session identifiers, params, or tool output. Thanks @vincentkoc. - Diagnostics/OTEL: export diagnostic memory samples and pressure as bounded memory histograms, counters, and pressure spans to help spot leak regressions without session or payload data. Thanks @vincentkoc.
- Diagnostics/OTEL: add the GenAI
gen_ai.client.token.usagehistogram for input/output model usage while keeping session identifiers and aggregate cache counters out of the semantic metric. Thanks @vincentkoc. - Diagnostics/OTEL: add a bounded
openclaw.agentlabel to OpenClaw token metrics so per-agent Grafana dashboards can group usage without exporting session identifiers. Thanks @oc-factus. - Plugins/install: consolidate managed plugin install metadata into the state-managed plugin index at
plugins/installs.json, replacing the temporaryplugins/installed-index.jsonpath and removingplugins.installsas an authored config surface. Thanks @vincentkoc and @shakkernerd. - Diagnostics/OTEL: add the GenAI
gen_ai.client.operation.durationhistogram for model-call latency in seconds with bounded provider/model/API and error attributes. Thanks @vincentkoc. - Diagnostics/OTEL: add GenAI usage token attributes to model-usage spans, including cache read/write input token counts without session identifiers or prompt/response content. Thanks @vincentkoc.
- Diagnostics/OTEL: include bounded GenAI operation, provider, and request-model attributes on model-usage spans so token usage remains self-describing without diagnostic identifiers. Thanks @vincentkoc.
- Diagnostics/OTEL: keep model-usage span GenAI provider attributes aligned with the existing semantic-convention opt-in policy, using legacy
gen_ai.systemunless latest experimental GenAI conventions are enabled. Thanks @vincentkoc. - Diagnostics/OTEL: keep
gen_ai.request.modelpresent on GenAI token usage metrics with a boundedunknownfallback when model usage events do not include a model. Thanks @vincentkoc. - Docs/OTEL: document the GenAI token and model-call duration metrics, model-usage span attributes, and
OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimentalprovider-attribute behavior. Thanks @vincentkoc. - Docs: refresh the MCP, model provider, doctor, troubleshooting, BlueBubbles, media generation, TTS, subagents, skills, cron/tasks, exec approvals, and voice-call guides with structured Steps, Tabs, and Accordion content.
- Diagnostics/trace: add an internal traceparent propagation helper that only formats trusted dispatcher metadata, keeping plugin-emitted diagnostic traces out of outbound propagation by default. Thanks @vincentkoc.
- Diagnostics/OTEL: add bounded outbound message delivery lifecycle diagnostics and export them as low-cardinality delivery spans/metrics without message body, recipient, room, or media-path data. (#71471) Thanks @vincentkoc and @jlapenna.
- Diagnostics/OTEL: emit bounded exec-process diagnostics and export them as
openclaw.execspans without exposing command text, working directories, or container identifiers. (#71451) Thanks @vincentkoc and @jlapenna. - Diagnostics/OTEL: support
OPENCLAW_OTEL_PRELOADED=1so the plugin can reuse an already-registered OpenTelemetry SDK while keeping OpenClaw diagnostic listeners wired. (#71450) Thanks @vincentkoc and @jlapenna. - Providers/Xiaomi: add MiMo TTS as a bundled speech provider with MP3/WAV output and voice-note Opus transcoding. Fixes #52376. (#55614) Thanks @zoujiejun.
- Providers/ElevenLabs: include
eleven_v3in the bundled TTS model catalog so model selection surfaces can offer ElevenLabs v3. (#68321) Thanks @itsuzef. - Providers/Local CLI TTS: add a bundled local command speech provider with file/stdout input, voice-note Opus conversion, and telephony PCM output. (#56239) Thanks @solar2ain.
- Providers/Inworld: add Inworld as a bundled speech provider with streaming TTS synthesis, voice listing, voice-note output, and PCM telephony output. (#55972) Thanks @cshape.
- Providers/Volcengine: add Volcengine/BytePlus Seed Speech as a bundled TTS provider with API-key auth, native Ogg/Opus voice-note output, and MP3 audio-file output. (#55641) Thanks @xuruiray.
- Android/Talk Mode: expose Talk Mode in the Voice tab with runtime-owned voice capture modes and microphone foreground-service escalation. Thanks @alex-latitude.
- Providers/LiteLLM: register
litellmas an image-generation provider soimage_generate model=litellm/...calls andagents.defaults.imageGenerationModel.fallbacksentries resolve through the LiteLLM proxy. Thanks @zqchris. - Providers/fal: add Seedance 2.0 reference-to-video models with multi-image, video, and audio reference input mapping plus model-specific capability limits for
video_generate. Thanks @shivanker. - Codex harness: require Codex app-server
0.125.0or newer and cover native MCPPreToolUse,PostToolUse, andPermissionRequestpayloads through the OpenClaw hook relay. - Agents/Codex: teach prompts and
agents_listto surface native Codex app-server availability so agents prefer/codex ...over Codex ACP unless ACP/acpx is explicit. Thanks @vincentkoc. - ACPX/Droid: add Factory Droid to the live ACP bind Docker matrix, including
.factorysettings staging,FACTORY_API_KEYforwarding, and the single-agenttest:docker:live-acp-bind:droidrecipe. - TTS/personas: add provider-aware TTS personas with deterministic provider binding merges,
/tts personacontrols, gateway/CLI persona state, Google Geminiaudio-profile-v1prompt wrapping, and OpenAI instruction mapping. (#70748) Thanks @barronlroth. - Voice Wake: add trigger-based routing so macOS voice wake phrases can select a configured agent or session target, with Gateway routing APIs and node update events. (#30354) Thanks @longbiaochen.
Fixes
- Plugins/startup: load the default
memory-coreslot during Gateway startup when permitted so active-memory recall can callmemory_searchandmemory_getwithout requiring an explicitplugins.slots.memoryentry, while preservingplugins.slots.memory: "none". Thanks @codex. - Plugins/CLI: prefer native require for compiled bundled plugin JavaScript before jiti so read-only config, status, device, and node commands avoid unnecessary transform overhead on slow hosts. Fixes #62842. Thanks @Effet.
- Plugins/compat: inventory doctor-side deprecation migrations separately from runtime plugin compatibility so release sweeps preserve needed repairs while enforcing dated removal windows. Thanks @vincentkoc.
- Plugins/compat: add missing dated compatibility records for legacy extension-api, memory registration, provider hook/type aliases, runtime aliases, channel SDK helpers, and approval/test utility shims. Thanks @vincentkoc.
- Plugins/CLI: refresh the persisted registry after managed plugin files are removed so ClawHub uninstall cannot leave stale
plugins listentries. Thanks @codex. - Plugins/CLI: make plugin install and uninstall config writes conflict-aware, clear stale denylist entries on explicit reinstall/removal, and delete managed plugin files only after config/index commit succeeds. Thanks @codex.
- Plugins: fail
plugins updatewhen tracked plugin or hook updates error, keep bundled runtime-dependency repair behind restrictive allowlists, and reject package installs with unloadable extension entries. Thanks @codex. - Gateway/chat: keep duplicate attachment-backed
chat.sendretries with the same idempotency key on the documented in-flight path so aborts still target the real active run. Fixes #70139. Thanks @Feelw00. - Plugins: share package entrypoint resolution between install and discovery, reject mismatched
runtimeExtensions, and cache bundled runtime-dependency manifest reads during scans. Thanks @codex. - Onboarding/setup: keep first-run config reads, plugin compatibility notices, and post-model sanity checks on cold metadata paths unless the user chooses to browse all models, avoiding full plugin/runtime catalog work between prompts. Thanks @shakkernerd.
- Onboarding/auth: run manifest-owned provider auth choices through scoped setup providers so selecting OpenAI Codex browser/device auth no longer loads every provider runtime before OAuth starts. Thanks @shakkernerd.
- Onboarding/auth: keep the post-auth default-model policy lookup on manifest/setup metadata so the next prompt appears without loading broad provider runtime. Thanks @shakkernerd.
- Onboarding/models: keep skip-auth and provider-scoped model picker prompts off the full global model catalog path, and cache provider catalog hook resolution so setup no longer stalls after auth on large plugin registries. Thanks @shakkernerd.
- Gateway/Bonjour: suppress known @homebridge/ciao cancellation and network assertion failures through scoped process handlers so malformed mDNS packets or restricted VPS networking disable/restart Bonjour instead of crashing the gateway. Fixes #67578. Thanks @zenassist26-create.
- Discord: keep late clicks on already-resolved exec approval buttons quiet when elevated mode auto-resolved the request, while still surfacing real approval submission failures. Fixes #66906. Thanks @rlerikse.
- Agents/subagents: deliver completed yielded-subagent results back to no-thread requester routes via direct fallback when the dormant parent announce turn produces no visible reply, and add QA-lab coverage for the regression. Thanks @vincentkoc.
- Gateway/Tailscale: let Tailscale-authenticated Control UI operator sessions with browser device identity skip the device-pairing round trip while still rejecting device-less and node-role connections. Refs #71986. Thanks @jokedul.
- Doctor: honor
OPENCLAW_SERVICE_REPAIR_POLICY=externalby reporting gateway service health while skipping service install/start/restart/bootstrap, supervisor rewrites, and legacy service cleanup for externally managed environments. Thanks @shakkernerd. - CLI/update: run package post-update doctor with
--fixso package updates repair config migrations before restart. Thanks @shakkernerd. - CLI/update: retry failed npm global updates with
--omit=optionaland ignore the superseded first failure when the fallback succeeds. Thanks @shakkernerd. - Plugins/uninstall: migrate and reset
plugins.slots.contextEnginealongside memory slots when plugin ids change or selected plugins are removed. Thanks @shakkernerd. - Agents/Discord: keep raw
Agent failed before replyrunner failures out of Discord group/channel chats and show detailed runner errors in direct chats only when/verboseis enabled. Thanks @codex. - UI/Windows: quote resolved pnpm
.cmdlauncher paths before spawning UI install/build/test commands so Node installs underC:\Program Filesno longer fail asC:\Program. Fixes #45275. Thanks @Kobevictor, @stoppieboy, and @iubns. - Codex/agent: translate
--thinking minimaltolowfor modern Codex models (gpt-5.5, gpt-5.4, gpt-5.4-mini, gpt-5.2) at request build time so the first turn is accepted instead of paying a wasted call + retry-with-low fallback. Older Codex models still receiveminimaldirectly. Fixes #71946. Thanks @hclsys. - Plugins/uninstall: remove tracked plugin files from their recorded managed extensions root even when the current state directory points somewhere else, so
openclaw plugins uninstall --forcedoes not leave the plugin discoverable. Thanks @shakkernerd. - Agents/runtime: add
agentRuntime.idas the canonical config key, migrate legacy runtime-policy configs withopenclaw doctor --fix, route canonical Anthropic models throughclaude-cliwithout passing CLI backend aliases to embedded harness selection, and load CLI backend owner plugins before channel startup. Fixes #71957. Thanks @WolvenRA. - CLI/update: guard Windows scheduled-task stops by state and timeout so auto-update restart cannot hang indefinitely on
schtasks /Endbefore stale-listener cleanup. Fixes #69970. Thanks @yangswld and @sherlock-huang. - Windows install/Lobster: execute
pnpm.exedirectly whennpm_execpathpoints at the native pnpm binary, add an installed-package fallback for the Lobster embedded runtime, and include the Lobster runner regression test in Windows CI. Fixes #69456. Thanks @igormf. - Gateway/install: refresh loaded gateway service installs when the current service embeds stale gateway auth instead of returning already-installed, avoiding LaunchAgent token-mismatch loops after token rotation. Fixes #70752. Thanks @hyspacex.
- Update: ignore bundled plugin
.openclaw-install-stagedirectories during global install verification and packaged dist pruning so leftover runtime-dep staging files do not turn successful updates intounexpected packaged dist filefailures. Fixes #71752. Thanks @waynegault. - CLI/update: fail package updates when post-update plugin sync fails and refresh legacy npm plugin install records before trusting unchanged artifacts, preventing successful updates from restarting with stale or failed plugin state. Thanks @vincentkoc and @shakkernerd.
- Release/update: reject pre-populated bundled plugin
.openclaw-install-stagedirectories, including mixed-case path variants, before package inventory generation so release tarballs cannot ship poisoned runtime-dependency staging debris. Fixes #71752. Thanks @hclsys. - Node runtime: keep node-host retry timers alive across Gateway restarts and exit on terminal credential pauses so supervised nodes do not become silent zombies. Fixes #69800. Thanks @meroli28.
- Gateway/plugins: stop persisted WhatsApp auth state from activating bundled channel runtime-dependency repair during startup when
channels.whatsappis absent, avoiding npm/git stalls on packaged Linux installs. Fixes #71994. Thanks @xiao398008. - Gateway/device tokens: enforce caller-scope containment inside token rotation and revocation so pairing-only sessions cannot mutate higher-scope operator tokens. Fixes #71990. Thanks @coygeek.
- Plugins/channels: keep security checks, thread-binding placement, provider summaries, health formatting, and message action labels on read-only or already-loaded channel metadata instead of importing full channel runtime. Thanks @shakkernerd.
- Plugins/status: keep config-only channel labels and status security summaries from importing plugin runtime modules just to render metadata. Thanks @shakkernerd.
- Sessions/channels: stop group-session metadata from loading bundled channel runtime just to classify
#channelsubjects, using only already-loaded channel capabilities on that path. Thanks @shakkernerd. - Plugins/channels: keep native command and native skill
autodefaults on static channel metadata so config, audit, and command-list checks do not load channel runtime just to read those defaults. Thanks @shakkernerd. - CLI/channels: keep channel remove selection and all-channel capabilities summaries on read-only plugin metadata, loading channel runtime only for the selected mutation path. Thanks @shakkernerd.
- CLI/models: keep Provider Index preview rows out of
models list --all --provider <id>when the owning provider plugin is disabled, preserving config authority for cold catalog fallbacks. Thanks @shakkernerd. - CLI/model runs: keep
openclaw infer model runon explicit OpenRouter models from loading the full provider catalog or inheriting chat-agent silent-reply policy, restoring non-empty one-shot probe output. Fixes #68791. Thanks @limpredator. - Installer/macOS: rerun Homebrew install steps without the gum spinner when raw-mode ioctl failures occur, and avoid claiming
node@24was installed when the Homebrew keg binary is missing. Fixes #70411. Thanks @1fanwang and @dad-io. - Installer: load nvm before Node.js detection so
curl | bashinstalls respect nvm-managed Node instead of stale system Node. Fixes #49556. Thanks @heavenlxj. - Installer/Windows: route PowerShell install failures through a top-level handler so
iwr ... | iexreturns control to the current shell while direct script-file runs still exit non-zero. Fixes #38054. Thanks @PwrSrg. - CLI/Volta: respawn raw
openclawCLI runs through the namednodeshim when the current Node executable resolves tovolta-shim, avoiding direct shim execution failures in non-interactive shells. Fixes #68672. Thanks @sanchezm86. - Installer: warn when multiple npm global roots contain OpenClaw installs, showing active Node/npm/openclaw plus each install path and version so stale version-manager installs are visible. Fixes #40839. Thanks @zhixianio.
- Cron/tasks: recover completed cron task ledger records from durable run logs and job state before marking them
lost, reducing falsebacking session missingaudit errors for isolated cron runs and keeping offline CLI audit from treating its empty local cron active-job set as authoritative. Fixes #71963. - Docker: copy patched dependency files into runtime images so downstream
pnpm installlayers keep working. Fixes #69224. Thanks @gucasbrg. - Package: include patched dependency files in the published npm package so downstream installs can resolve
patchedDependencies. (#69224) Thanks @gucasbrg and @vincentkoc. - Plugins/channels: treat malformed bundled channel plugin loaders that return
undefinedas unavailable instead of crashing config and help paths. Fixes #69044. Thanks @frankhli843 and @vincentkoc. - Scripts/watch: show corrupted dependency package-config recovery guidance when
gateway:watchfails during watcher startup, without double-logging unrelated import failures. (#58780) Thanks @roytong9 and @vincentkoc. - Signal: read signal-cli RPC, health checks, and SSE events through Node's HTTP client so Node 24/25 fetch regressions do not break Signal sends or inbound events. Fixes #51716 and #53040. Thanks @Barukimang, @minupla, and @vincentkoc.
- Skills/Docker: run npm-backed skill dependency installs with an OpenClaw-managed user prefix so non-root Docker images do not write to
/usr/local. Fixes #59601. Thanks @chanjarster and @vincentkoc. - Agents/runtime: submit heartbeat, cron, and exec wakeups as transient runtime context instead of visible user prompts, keeping synthetic system work out of chat transcripts. Fixes #66496 and #66814. Thanks @jeades and @mandomaker.
- Telegram: include native quote excerpts automatically for threaded replies and reply tags when the original Telegram text is available, without adding another config knob. Fixes #6975. Thanks @rex05ai.
- Node/Linux: make
openclaw node installenable and restart theopenclaw-nodesystemd unit instead of the gateway unit on node-only VMs. Fixes #68287. Thanks @dlebee-agent. - Browser/CDP: retry transient raw-CDP WebSocket handshake failures before any browser command is sent, and reconnect stale persistent Playwright CDP sessions for safe tab-list reads without replaying mutating browser actions. Fixes #67728.
- Gateway/Linux: retry
systemctl --user enableafter a second daemon reload when the freshly written gateway unit is not visible yet on migrated systemd installs. Fixes #65184. Thanks @liushuaiiu. - Telegram: preserve exact selected quote text when sending native quote replies, and retry with legacy replies if Telegram rejects quote parameters. (#71952) Thanks @rubencu.
- Plugins/CLI: preserve manifest name, description, format, and source metadata in cold
openclaw plugins listoutput without importing plugin runtime. Thanks @shakkernerd. - Security/audit: read channel exposure and plugin allowlist ownership from read-only plugin index metadata so cold audits do not depend on loaded channel runtime. Thanks @shakkernerd.
- Plugins/chat: keep
/plugins list,/plugins enable, and/plugins disableon the persisted plugin index path so chat plugin management does not load diagnostic/runtime plugin registries before execution. Thanks @shakkernerd. - Plugins/doctor: read workspace plugin status and legacy web-search ownership through installed-index manifest metadata instead of broad manifest registry scans. Thanks @shakkernerd.
- CLI/agents: read channel provider status from read-only plugin index metadata for text
agents listoutput instead of the loaded channel registry. Thanks @shakkernerd. - Logging: redact configured secret patterns at console and file-log sink exits so credentials that reach the logger are masked before terminal display or JSONL persistence. Fixes #67953. Thanks @Ziy1-Tan.
- Gateway/services: refuse process and service mutations from an older OpenClaw binary when the config was last written by a newer version, preventing split-brain installs from stopping or rewriting newer gateway services. Fixes #57079.
- Gateway: reserve
/healthzand/readyzahead of plugin, canvas, and Control UI HTTP stages so liveness/readiness probes still answer when a later route handler stalls. Fixes #69674. Thanks @Xike-Creek. - Logging: load
logging.fileand redaction settings directly from the active OpenClaw config path in bundled runtimes, so packaged gateways stop falling back to/tmp/openclaw. Fixes #59370, #67168, and #61295. Thanks @KeaneYan, @Pan9hu, and @zsjlovelike. - Logging: rotate file logs at
logging.maxFileBytes, keep bounded numbered archives, and make long-lived rolling loggers follow the current-day file instead of suppressing diagnostics or writing stale dated files. Fixes #58583 and #62381. Thanks @jpeghead and @zhaoleink. - Agents/groups: treat clean empty assistant stops as silent
NO_REPLYonly for always-on groups where silent replies are allowed, while keeping direct and mention-gated sessions on the incomplete-turn retry path. Thanks @MagnaAI. - macOS/Node: keep native remote app nodes from advertising
browser.proxy, start browser-capable CLI node services through the restoredopenclaw node startcommand, and show an actionable browser-control error when the local control service is missing. Fixes #66637. - Gateway/update: fail package updates when the restarted managed gateway reports the wrong version, including fallback restarts and JSON mode, avoiding false-success mixed-version restarts after macOS LaunchAgent updates. Fixes #71835. Thanks @abhinas90 and @jsompis.
- Gateway/update: warn before package updates and bundled plugin runtime-dependency repairs when the target volume appears low on disk space, without blocking installs on best-effort filesystem checks. Fixes #71835. Thanks @abhinas90 and @jsompis.
- Plugins/runtime deps: surface activated plugin load failures in health and fail package-update restart verification or doctor repair when bundled runtime deps still cannot load, avoiding false-success repairs. (#71883) Thanks @Solvely-Colin.
- Gateway/Linux: include fnm
aliases/default/binin generated service PATHs and let doctor accept either modern fnm aliases or the legacycurrent/binsymlink, avoiding false PATH repair prompts. Fixes #68169. Thanks @richard-scott. - Installer/Linux: run apt installs with noninteractive dpkg and needrestart settings so fresh Ubuntu 24.04
curl | bashinstalls do not hang while installing Node.js, Git, or build tools. Fixes #41146. Thanks @iht76, @alexcarv318, @cs3gallery, @firofame, and @cgdusek. - Providers/Bedrock: defer the AWS SDK import until Bedrock discovery actually runs so plugin registration and setup stay lightweight on cold start. Fixes #71690. Thanks @jarvis-ai-gregmoser.
- Installer/macOS: stop immediately when Homebrew
node@24installation fails and avoid printing PATH advice for missing Homebrew Node installs. Fixes #70411. Thanks @1fanwang. - WhatsApp: remove ack reactions after a visible reply when
messages.removeAckAfterReplyis enabled, matching other reaction-capable channels. Fixes #26183. Thanks @MrUnforsaken. - Providers/Z.AI: map OpenClaw thinking controls to Z.AI's
thinkingpayload and add opt-in preserved thinking replay viaparams.preserveThinking, so GLM 5.x can keep priorreasoning_contentwhen requested. Fixes #58680. Thanks @xuanmingguo. - Channels/status: keep read-only channel lists on manifest and package metadata by default, loading setup runtime only for explicit fallback callers. Thanks @shakkernerd.
- Plugins: scope setup and web-provider metadata manifest reads to explicit plugin ids when callers already know the owning plugin set. Thanks @vincentkoc.
- Plugins/onboarding: defer onboarding install-record index writes until the guarded config commit so setup failures cannot leave the plugin index ahead of
openclaw.json. Thanks @shakkernerd. - Plugins/registry: resolve web provider ownership from the installed plugin index instead of broad manifest scans on secret, tool, and pricing paths. Thanks @shakkernerd.
- Config/providers: accept
videoandaudioin configured modelinputvalues and preserve them in provider catalog entries. Fixes #20721. Thanks @alvinttang. - Models/auth: honor the parent
--agentflag for auth write commands (add,login,setup-token,paste-token, and the GitHub Copilot shortcut) so OAuth/API-key/token results are written to the requested agent store instead of the default agent. Fixes #71864. (#71933) Thanks @balric-seo. - TTS: strip model-emitted TTS directives from streamed block text before channel delivery, including directives split across adjacent blocks, while preserving the accumulated raw reply for final-mode synthesis. Fixes #38937.
- TTS: keep explicit
provider=...directive keys scoped to that provider and warn on unsupported keys instead of letting another speech provider consume overlapping keys. Fixes #60131. - TTS/Feishu: normalize final-mode streamed TTS-only audio before delivery so generated voice-note files use the same safe media path and native voice routing as normal final replies. Fixes #71920.
- Feishu: transcribe inbound voice-note audio with the shared media audio path before agent dispatch and keep raw Feishu
file_keypayloads out of message text. Fixes #67120 and #61876. - Tasks: terminalize async Gateway agent task records from the Gateway run result while preserving aborted, failed, and cancelled outcomes instead of leaving completed runs stuck as active or lost. (#71905) Thanks @likewen-tech.
- WhatsApp: let authorized group voice-note transcripts satisfy mention gating before reply dispatch, while keeping unmentioned transcripts in pending group history. Fixes #44908.
- Media understanding: carry channel voice-note preflight state into attachment selection so WhatsApp, Feishu, Telegram, and Discord do not transcribe the same inbound audio twice. Fixes #70580.
- TTS/BlueBubbles: deliver compatible auto-TTS audio as iMessage voice memo bubbles instead of plain MP3/CAF file attachments. Fixes #16848.
- TTS: resolve voice-note and voice-memo routing from channel plugin capabilities instead of speech-core-owned channel id lists.
- ACP: send subagent and async-task completion wakes to external ACP harnesses as plain prompts instead of OpenClaw internal runtime-context envelopes, while keeping those envelopes out of ACP transcripts.
- TTS/status: show configured TTS model, voice, and sanitized custom endpoint in
/status, preserve OpenAI-compatible TTS instructions on custom endpoints, and retry empty Microsoft/Edge TTS output once. Addresses #46602, #47232, and #43936. Thanks @leekuangtao, @Huntterxx, and @rex993. - Agents/Gateway: steer agent-driven config edits and restarts through the owner-only
gatewaytool, documentconfig.schema.lookupas the field-doc source, and warn against usinggateway stop && gateway startas a restart substitute on macOS. Fixes #71929. Thanks @ygc3817922006-sketch. - Media understanding/audio: inject a deterministic transcript placeholder for too-small voice notes so agents do not hallucinate transcription or provider failures. Fixes #48944. Thanks @eulicesl.
- Providers/vLLM: send Nemotron 3 chat-template kwargs when thinking is off and honor configured
params.chat_template_kwargsfor OpenAI-compatible completions, so vLLM/Nemotron replies stay visible instead of becoming thinking-only. Fixes #71891. Thanks @jmystaki-create and @dennis-lynch. - Channels/replies: strip copied inbound metadata blocks from user-facing assistant replies and model replay history, so Discord/vLLM sessions do not leak
Conversation info/UNTRUSTED ... message bodyenvelopes after a model echoes them. Fixes #71847. Thanks @jmystaki-create. - Subagents/memory: keep inter-session completion wakes out of memory and dreaming session exports, and strip internal runtime-context blocks from realtime Control UI chat events.
- Agents/Claude: treat zero-token empty
stopturns as failed provider output, retry once, repair replay, and allow configured model fallback instead of preserving them as successful silent replies. Fixes #71880. Thanks @MagnaAI. - Tasks: normalize task lifecycle timestamps at create, update, and restore time, and report retained lost tasks as audit warnings until their cleanup window expires. (#71871) Thanks @likewen-tech.
- Diagnostics/OTEL: treat normal early model stream cleanup as a completed model call instead of exporting a misleading
StreamAbandonederror span. Thanks @vincentkoc. - Gateway/pairing: stop corrupt or unreadable device/node pairing stores from being treated as empty state, preserving
paired.jsonfor repair instead of overwriting approved pairings. Fixes #71873. Thanks @iret77. - ACP: keep
/acpmanagement commands, plus local/statusand/unfocus, on the Gateway path inside ACP-bound threads so they are not consumed as ACP prompt text. Fixes #66298. Thanks @kindomLee. - ACPX: stop probing ACP agents during normal Gateway startup; the embedded backend now registers without spawning Codex/ACP child processes unless
OPENCLAW_ACPX_RUNTIME_STARTUP_PROBE=1is explicitly set. - CLI/image edit: accept
--size,--aspect-ratio, and--resolutiononopenclaw infer image editand report all supported edit flags fromcapability inspect image.edit. Thanks @Pinghuachiu. - ACP: wait for the configured runtime backend to become healthy before startup identity reconciliation, avoiding transient acpx warnings during Gateway boot. Fixes #40566.
- Channels/ACP bindings: time out configured binding readiness checks instead of letting Discord preflight hang forever when an ACP target never settles. Fixes #68776.
- Control UI: hide the chat loading skeleton during background history reloads when existing messages or active stream content are already visible, avoiding reload flashes on high-latency local gateways. Fixes #71844. Thanks @WolvenRA.
- Control UI: keep locally optimistic chat messages visible when a history reload temporarily returns empty, avoiding lost first-turn messages on high-latency gateways. Fixes #71878. Thanks @WolvenRA.
- Control UI: keep chat history limits based on visible messages after filtering heartbeat and control-only transcript rows, so recent hidden entries no longer make older visible replies disappear. Thanks @WolvenRA.
- Agents/images: scrub old
[media attached: ...],[Image: source: ...], andmedia://inbound/...markers from pruned model replay context so stale media refs are not rehydrated as fresh prompt images. Fixes #71868. Thanks @jmeadlock. - Docker/Bonjour: disable Bonjour/mDNS advertising by default for bundled Compose gateways on bridge networking, while keeping host/macvlan opt-in with
OPENCLAW_DISABLE_BONJOUR=0. Fixes #71879. Thanks @gbballpack. - CLI/status: label the OpenClaw Serve/Funnel setting as
Tailscale exposureand show daemon state separately when available, sogateway.tailscale.mode: "off"no longer reads like the Tailscale daemon is stopped. Fixes #71790. Thanks @pesvobodak. - Plugins/Bonjour: stop ciao mDNS watchdog failures from looping forever when the advertiser stays stuck in
probingorannouncing; Bonjour now disables itself for the current Gateway process after repeated failed restarts while the Gateway keeps running. Fixes #69011. Thanks @siddharthaagarwalofficial-ux, @FiredMosquito831, and @spikefcz. - Gateway/Fly.io: seed Control UI allowed origins from the actual runtime bind and port so CLI-driven non-loopback starts do not crash before config exists. Fixes #71823.
- macOS/remote SSH: keep discovered gateway hosts in
gateway.remote.sshTargetwhile pinning SSH transport URLs to the local loopback tunnel, so browser automation does not regress into blocked non-loopbackws://endpoints. Fixes #67336. - Gateway/proxy: bootstrap env proxy dispatching from direct Gateway startup so provider and plugin network requests honor
HTTPS_PROXY/HTTP_PROXYbefore the first embedded agent attempt runs. (#71833) Thanks @mjamiv. - Plugins/runtime deps: verify clean npm installs actually place requested bundled runtime packages in the managed install root, reporting exact missing specs instead of a false successful repair. (#71883) Thanks @Solvely-Colin.
- Plugins/discovery: ignore stale
plugins.load.pathsaliases that point back at packaged bundled plugin directories and have doctor remove them, keeping bundled plugins on the runtime-deps staging path. Thanks @codex. - Models/LM Studio: preserve
@iq*quant suffixes in model refs and provider matching so/model lmstudio/...@iq3_xxskeeps the exact LM Studio variant. Fixes #71474. (#71486) Thanks @Bartok9, @XinwuC, and @Sanjays2402. - Matrix/cron: preserve the live Matrix delivery target when creating implicit announce reminder jobs so mixed-case room IDs are not reconstructed from lowercased session keys. Fixes #71798.
- Feishu: accept Schema 2.0 card action callbacks that report
context.open_chat_idinstead of legacycontext.chat_id, so button callbacks no longer drop as malformed. Fixes #71670. Thanks @eddy1068. - Feishu: keep synthetic card-action and bot-menu ids out of platform reply targets, using the real card callback message id when Feishu provides one and plain-sending otherwise. Fixes #71673. Thanks @eddy1068.
- Plugins/QQ Bot: prefer an installed QQ Bot plugin that declares it replaces the bundled
qqbotchannel, preventing duplicateqqbot_channel_apiandqqbot_remindtool registration noise. Fixes #63102. - Browser automation: keep stable tab ids and labels attached when Chromium replaces the raw target after form submissions or other action-triggered navigations, and return the replacement
targetIdfrom/actwhen the match is provable. Fixes #46137. - QQ Bot: make
qqbot_remindschedule, list, and remove Gateway cron jobs directly for owner-authorized senders instead of returningcronParamsand relying on a follow-up genericcrontool call. Fixes #70865. (#70937) Thanks @GaosCode. - Agents/ACP: hide
sessions_spawnACP runtime options unless an ACP backend is loaded, and make/acp doctorcall outplugins.allowblocking bundledacpx. Thanks @vincentkoc. - Agents/Codex: keep ACP prompt/skill routing hidden unless an ACP runtime backend is available, and warn in doctor when enabled Codex plugin configs still route
openai-codex/*models through PI. Thanks @vincentkoc. - Media delivery: avoid sending generated image attachments twice when the assistant reply already includes explicit
MEDIA:lines for the same turn, and reject unsafe remoteMEDIA:URLs before delivery. Thanks @pashpashpash. - Codex harness: ignore retryable app-server error notifications after Codex recovers, and preserve the real nested error message for terminal app-server failures instead of replacing it with a generic failure. Thanks @pashpashpash.
- Agents/Codex: prepare native Codex sub-agent session metadata without a nested Gateway session patch and add a focused Docker smoke for the app-server sub-agent path. Thanks @vincentkoc.
- Agents/subagents: keep queued subagent announces session-only when the requester has no external channel target, avoiding ambiguous multi-channel delivery failures. Fixes #59201. Thanks @larrylhollan.
- Image understanding: preserve configured provider-prefixed vision model metadata when callers request the model without the provider prefix, so custom image models keep their
input: ["text", "image"]capability. Fixes #33185. Thanks @Kobe9312 and @vincentkoc. - Plugins/install: restore the previous plugin index records if a concurrent config write conflict interrupts install, update, or uninstall metadata commits. Thanks @shakkernerd.
- Plugins/install: reject native plugin archives that do not include a valid
openclaw.plugin.json, preventing manifestless archives from writing install records that later show missing-manifest diagnostics. Thanks @shakkernerd. - Plugins/uninstall: remove tracked managed plugin install directories even when the persisted install path differs from the default id-derived target, while still refusing deletes outside the managed extensions root. Thanks @shakkernerd.
- Plugins/update: restore previous plugin index records if core update or channel setup hits a concurrent config write conflict after plugin metadata changes. Thanks @shakkernerd.
- Plugins/onboarding: defer channel/provider plugin install records until the owning config write commits, keeping setup failures from advancing the plugin index ahead of
openclaw.json. Thanks @shakkernerd. - Plugins/config: route configure and agent setup writes with pending plugin install records through the plugin index commit helper so provider onboarding metadata is not stripped by plain config writes. Thanks @shakkernerd.
- Plugins/channels: merge pending channel plugin install records with the existing plugin index before config writes, preserving unrelated tracked installs during channel setup, resolve, remove, and capability repair flows. Thanks @shakkernerd.
- Plugins/config: defer shipped
plugins.installsindex migration during config writes until the guarded config commit window and roll it back if the config write fails before commit. Thanks @shakkernerd. - Sessions: keep embedded runtime context out of the visible user prompt by sending it as a hidden next-turn custom message, and teach doctor to repair affected 2026.4.24 transcripts with duplicated prompt-rewrite branches. Fixes #71761.
- Gateway/subagents: keep direct-loopback backend RPCs authenticated with the shared gateway token/password off stale CLI paired-device scope baselines, so internal calls no longer hit
scope-upgradepairing prompts while remote, browser, node, device-token, and explicit-device paths still require normal pairing approval. Fixes #63548. - Providers/Azure OpenAI: give deployment-scoped image generation requests a longer 600s default timeout so slow
gpt-image-2generations can complete without a per-calltimeoutMs. Fixes #71705. Thanks @voytas75. - Gateway/plugins: link source-checkout bundled runtime dependency caches instead of recursively copying
node_moduleson the gateway main thread, preventing local status, node, and skill probes from timing out during startup cache restores. - Skills/remote nodes: only expose remote macOS skill bins for connected nodes, clear stale bin matches when node probes fail, and include probe command, timeout, bin count, and connection state in timeout logs.
- Skills/remote nodes: recognize
system.whichobject-map responses when probing connected macOS nodes, so Linux gateways can expose macOS-only skills such as Apple Notes when the required binaries are installed remotely. Fixes #71877. Thanks @miguelarios. - CLI/gateway: keep diagnostic probes from creating first-time read-only device pairings, while still reusing cached device tokens for detailed read probes. Fixes #71766. Thanks @SunboZ.
- CLI/plugins: keep
messagestartup,channels logs,agents delete, andagents set-identityoff broad plugin preloading; message delivery still loads plugins when the action actually runs. - Image understanding: resolve configured image models such as local LM Studio vision entries before reporting
Unknown modelwhen the discovery registry has not registered that provider. Fixes #66486. Thanks @zhanggpcsu. - QQ Bot: ignore self-echoed bot messages using the outbound ref-index marker, preventing mirrored replies from re-entering the agent loop while still allowing users to quote bot replies. Fixes #71912. Thanks @wangyc6003.
- Sessions: separate reset freshness from session-store
updatedAt, so heartbeat, cron, exec, and gateway bookkeeping no longer prevent configured daily/idle resets from rolling long-running channel sessions. Fixes #68315, #63732, #63820, and #69083. Thanks @maxatv, @longhairedsi, @bradfreels, and @akessel56. - Sessions: clear queued system-event notices during
/new,/reset, gatewaysessions.reset, and daily/idle rollover so stale background updates cannot leak into the first prompt of the fresh session. Fixes #66864. Thanks @opeyio, @Magicray1217, and @cedillarack. - CLI/agents: keep
agents bind,agents unbind, andagents bindingson setup-safe channel metadata paths so they do not preload bundled plugin runtimes or stage runtime dependencies. Fixes #71743. - Plugins/registry: preserve explicit disabled plugin records during registry migration without persisting every unused bundled plugin discovered on disk. Thanks @shakkernerd.
- Windows/native: keep CLI startup and bundled provider plugin loading off Windows ESM raw-path failure paths, fixing native onboarding/install smoke on Node 24.
- Plugins/doctor: read bundled channel doctor capabilities through the same packaged plugin directory resolver used by plugin loading, so published installs keep Matrix DM allowlist repairs on
channels.matrix.dm.*instead of writing invalid top-leveldmPolicykeys. Fixes #71757. - Plugins/Windows: keep bundled plugin Jiti loaders off the native import path on Windows so channel plugins such as Telegram no longer crash with
ERR_UNSUPPORTED_ESM_URL_SCHEMEonC:\...paths. Fixes #71749. Thanks @smeyer9. - Providers/Ollama: use Ollama's current
/api/web_searchendpoint and honorhttps://ollama.commodel-provider base URLs for Ollama Web Search. Fixes #71741. Thanks @madhvidua. - Memory/Ollama: serialize Ollama memory embedding batches and add an inline batch timeout override, with longer defaults for local/self-hosted embedding providers.
- Sessions/usage: exclude compaction checkpoint transcript snapshots from usage totals and session discovery, while keeping old checkpoint files removable.
- CLI/agents: keep
openclaw agents list --jsonon the config-only path by default, avoiding bundled plugin loading unless callers request--bindings. Fixes #71739. Thanks @kaloster. - Plugins/install: force plugin dependency installs to stay project-local even when inherited npm config requests global installs, so successful installs still materialize the plugin's staged
node_modules. - Providers/Google: transcode Gemini TTS PCM to Opus for voice-note targets so WhatsApp and other native voice-note replies can play as voice messages.
- TTS/WhatsApp: mark non-Opus provider output as voice-note intent so channel delivery transcodes MP3/WebM replies to Ogg/Opus PTT audio.
- Plugins/runtime deps: reuse existing external bundled-plugin stage roots when mirrored plugin roots are inspected again, avoiding second-generation
openclaw-unknown-*stages and repeated first-turn restaging. Fixes #71599. - iOS/macOS Talk Mode: allow
talk.speechLocaleto set the speech recognition locale for non-English voice conversations. Fixes #44688. - Plugins/providers: honor explicit plugin candidate lists instead of reading a persisted registry snapshot from local state, keeping candidate-scoped provider discovery hermetic.
- Plugins/doctor: keep bundled plugin runtime-dependency repairs inside the managed OpenClaw stage even when user npm prefix/global config points npm at
$HOME/node_modules. Fixes #71730. - ACP/sessions_spawn: reject normal OpenClaw config agent ids when callers explicitly request
runtime="acp", while allowing agents configured withruntime.type="acp"to resolve to their ACP harness id. Fixes #63914. - ACP/sessions_spawn: apply
runTimeoutSecondsto ACP child turns and dispatch those turns on the background subagent lane, so quota-stalled ACP harnesses do not occupy the main agent lane indefinitely. Fixes #68823. - ACP/oneshot: reconcile runtime session identity before closing completed oneshot ACP runs, so finished
sessions.jsonentries do not stay stuck withacp.identity.state="pending". - ACPX: bundle
acpx@0.6.1so unsupported generic model overrides fail clearly instead of silently falling back to the target adapter default. - ACP/models: document that non-Codex ACP model overrides require adapter support for ACP
modelsplussession/set_model, so unsupported harnesses fail clearly instead of silently falling back to their defaults. - Plugins/Voice Call: treat missing provider credentials as setup-incomplete during Gateway startup and log the missing keys as a warning instead of a runtime startup error, while keeping explicit command/tool errors when used.
- Android/Talk Mode: prevent duplicate TTS playback when fast or repeated final chat events arrive while Talk Mode is waiting for its own response. Fixes #46546.
- Tooling/check:changed: pass parent heavy-check lock markers to lint lanes so
pnpm check:changedno longer waits on its ownlint:extensionschild. - CLI/completion: dedupe provider auth flags before registering
openclaw onboardoptions, so completion-cache refresh during update no longer fails when stale core fallback flags overlap plugin manifest flags. Fixes #71667. - Diagnostics/trace: report live context usage from the current prompt snapshot instead of provider turn totals, avoiding false near-full context spikes on cached or tool-heavy runs.
- Providers/Google: honor
models.providers.google.request.allowPrivateNetworkfor Gemini TTS and telephony TTS, matching Google image generation and media understanding. (#71723) Thanks @ro-hansolo. - Providers/MiniMax: register
minimax-portalfor music and video generation, preserving OAuth auth and regional MiniMax base URLs across the sharedmusic_generateandvideo_generatetools. (#63241) Thanks @tars90percent. - Providers/onboarding: keep Runway and Alibaba Model Studio out of the text-inference setup picker by scoping their video-generation auth choices to the media setup flow. (#65856) Thanks @Jah-yee.
- Plugins/Bonjour: stop the gateway from crash-looping on
CIAO PROBING CANCELLEDwhen the mDNS watchdog cancels a stuck probe. Restores the rejection-handler wiring dropped during the bonjour plugin migration and shares unhandled-rejection state across module instances so plugin-staged copies ofopenclaw/plugin-sdk/runtimeregister into the same handler set the host consults. Especially affects Docker on macOS, where mDNS probing reliably hits the watchdog. Thanks @troyhitch. - Google Meet: report pinned Chrome nodes as offline or missing capabilities in setup/join diagnostics, keep inaccessible nodes out of auto-selection, and preflight local BlackHole/SoX requirements before agents try local Chrome.
- Providers/MiniMax: route
image-01requests to the dedicated image generation endpoint while preserving CN endpoint selection. Fixes #61149. Thanks @mushuiyu886. - Plugins/startup: remove ownerless bundled runtime-dependency install locks after a short grace window and include lock owner details when startup times out waiting for a plugin runtime-deps lock.
- Plugins/install: anchor bundled runtime-dependency npm installs with an OpenClaw-owned package manifest so Linux updates cannot accidentally write to a parent
$HOME/node_modulestree. Fixes #71730. - Plugins/install: pass onboarding plugin config into plugin index writes so local plugin installs outside default discovery roots keep their install records. Thanks @shakkernerd.
- Plugins/install: migrate shipped
plugins.installsconfig records into the plugin index while stripping them from runtime config and future writes. Thanks @shakkernerd. - Plugins/install: durably remove shipped
plugins.installsfromopenclaw.jsonafter its records are copied into the plugin index, while rolling back the index write if config cleanup fails. Thanks @shakkernerd. - Plugins/install: keep migrated plugin install records in the plugin index even when the plugin manifest is missing or invalid, so update, uninstall, inspect, and audit can still recover broken installs. Thanks @shakkernerd.
- Plugins/security: keep plugin audit JSON check ids stable while reporting plugin index install-record findings with updated wording. Thanks @shakkernerd.
- CLI/config: reject direct
plugins.installsedits with guidance to useopenclaw plugins install,openclaw plugins update, oropenclaw plugins uninstallinstead. Thanks @shakkernerd. - Live tests/voice: accept common STT variants for OpenClaw and ElevenLabs brand names so provider smoke tests fail on real regressions rather than equivalent transcripts.
- Agents/replies: forward sanitized underlying agent failure details on external channels instead of replacing unknown failures with a generic retry message.
- CLI/MCP: translate OpenClaw
mcp.servers.*.transportentries into Claude/Gemini CLItypefields so streamable HTTP MCP servers load in CLI backend sessions. (#71724) Thanks @Blockchain-Oracle. - Browser/CDP: honor configured remote and
attachOnlyCDP HTTP/WebSocket timeouts when opening tabs through raw CDP or/json/newfallback. (#54238) Thanks @FuncWei. - WhatsApp/TTS: send visible text separately from PTT voice-note audio instead of relying on hidden voice-note captions. Fixes #51081.
- Browser/client: avoid telling agents to restart OpenClaw for dispatcher timeouts on external browser profiles such as
attachOnly, remote CDP, and existing-session. (#40815) Thanks @0xsline. - Agents/TTS: preserve
[[audio_as_voice]]directives on trusted text tool-resultMEDIA:payloads so generated audio still delivers as a voice note. (#46535) Thanks @azade-c. - Agents/TTS: keep queued tool media when an assistant ends with
NO_REPLYon non-block delivery paths, so media-only generated audio replies still send. (#60025) Thanks @bradlind1. - Telegram/STT: frame inbound voice-note transcripts as machine-generated, untrusted text in agent context while preserving raw transcript mention detection. Closes #33360. Thanks @smartchainark.
- Subagents/browser: show an actionable
/toolsnotice when browser automation is configured but filtered out by the active tool profile, and document that coding-profile agents should usetools.alsoAllow: ["browser"]rather than subagent allowlists alone. - Control UI/Quick Settings: persist the assistant avatar override to browser local storage (mirroring the user avatar) so uploaded image data URLs no longer fail config validation with "Too big: expected string to have <=200 characters". Also lift the gateway-side
ui.assistant.avatarlength cap to match the user avatar size budget for non-UI clients writing the field directly. Thanks @BunsDev. - Plugin SDK: share diagnostic event subscriptions across duplicate source/dist module graphs so legacy root SDK imports still receive runtime diagnostic events.
- Agents/Bedrock: prevent empty assistant stream-error turns from poisoning Converse replay by persisting, repairing, and replaying a non-empty fallback block. Fixes #71572. (#71627) Thanks @openperf.
- Agents/Anthropic/Bedrock: strip thinking blocks with missing, empty, or blank replay signatures before provider conversion, falling back to non-empty omitted-reasoning text when needed so corrupted signed-thinking history no longer poisons subsequent turns. Fixes #45010. (#70054) Thanks @castaples.
- Agents/Anthropic/Bedrock: preserve stripped thinking-only assistant replay turns with non-empty omitted-reasoning text so provider adapters keep strict user/assistant turn shape. Thanks @wujiaming88.
- ACP/Codex: pass
sessions_spawn(runtime="acp")model and thinking overrides into Codex ACP startup, normalizeopenai-codex/*refs and slash reasoning suffixes, and recognize managed Codex ACP wrapper commands without blocking currentgpt-5.5sessions. Fixes #40393. (#71643) Thanks @91wan. - Browser/CDP: make readiness diagnostics use the same discovery-first fallback as reachability for bare
ws://Browserless and Browserbase CDP URLs. Fixes #69532. - Browser/CDP: explain that loopback Browserless or other externally managed CDP services need
attachOnly: trueand matching BrowserlessEXTERNALendpoint when reporting local port ownership conflicts, and fall back to the configured bare WebSocket root when a discovered Browserless endpoint rejects CDP. Fixes #49815. - Gateway/reload: preserve indefinite
gateway.reload.deferralTimeoutMs: 0semantics for channel hot reload deferrals so active agent runs are not interrupted by a forced channel restart. (#71637) Thanks @Poo-Squirry. - Agents/tool results: cap persisted Pi tool-result details and strip hidden diagnostics before provider conversion, preventing large debug payloads from bloating session transcripts. (#71637) Thanks @Poo-Squirry.
- ACP/OpenCode: update the bundled acpx runtime to 0.6.0 and cover the OpenCode ACP bind path in Docker live tests.
- Providers/OpenCode Go: add DeepSeek V4 Pro and DeepSeek V4 Flash to the Go catalog while the bundled Pi registry catches up. Fixes #71587.
- Providers/OpenCode Go: route DeepSeek V4 Pro/Flash through the OpenAI-compatible Go endpoint and suppress invalid
reasoning_effort: "off"payloads, fixing tool-enabled requests foropencode-go/deepseek-v4-flash. Fixes #71683. - Plugins/model defaults: run Skill Workshop review, Active Memory recall, and session-memory slug generation on the configured agent default model instead of the hardcoded OpenAI SDK fallback when hook context lacks model metadata. Fixes #71659.
- Providers/Venice: fill the required DeepSeek V4
reasoning_contentplaceholder forvenice/deepseek-v4-proandvenice/deepseek-v4-flashreplay turns without sending native DeepSeekthinkingcontrols that Venice rejects. Fixes #71628. - Browser/existing-session: support per-profile Chrome MCP command/args, map
cdpUrlto--browserUrlor--wsEndpoint, and avoid combining endpoint flags with--userDataDir. Fixes #47879, #48037, and #62706. Thanks @puneet1409, @zhehao, and @madkow1001. - Media/plugins: bound MIME sniffing and ZIP archive preflight before handing untrusted files to
file-typeorjszip, reducing parser CPU and memory exposure for attachments and ClawHub plugin archives. Thanks @vincentkoc. - Memory-host SDK: use trusted env-proxy mode for remote embedding and batch HTTP calls only when Undici will proxy that target, preserving SSRF DNS pinning for
ALL_PROXY-only andNO_PROXYbypass cases. Fixes #52162. (#71506) Thanks @DhtIsCoding. - Gateway/dashboard: render Control UI and WebSocket links with
https:///wss://whengateway.tls.enabled=true, includingopenclaw gateway status. Fixes #71494. (#71499) Thanks @deepkilo. - Agents/OpenAI-compatible: default proxy/local completions tool requests to
tool_choice: "auto"when tools are present, so providers enter native tool-calling mode instead of replying with plain-text tool directives. (#71472) Thanks @Speed-maker. - OpenAI image generation: use
gpt-5.5for the Codex OAuth responses transport instead of the retiredgpt-5.4model, fixing 500s from ChatGPT Codex image generation. Fixes #71513. Thanks @baolongl. - OpenAI image generation: route transparent-background default-model requests to
gpt-image-1.5, document the expectedimage_generatecall shape, and keep Azure/custom OpenAI-compatible deployment names untouched. - Google video generation: download direct MLDev Veo
video.uriresults instead of passing them through the Files API path, fixing 404s after successful generation/polling. Fixes #71200. Thanks @panhaishan. - Google video generation: fall back to the REST
predictLongRunningVeo endpoint for text-only SDK 404s while keeping reference image/video generation on the SDK path. Fixes #62309 and #63008. (#62343) Thanks @leoleedev. - MiniMax music generation: switch the bundled default model from the unsupported
music-2.5+id to the currentmusic-2.6API model. Fixes #64870 and addresses the music default from #62315. Thanks @noahclanman and @edwardzheng1. - Cron: record jobs interrupted by a gateway restart as failed at their original
runningAtMs, skip unsafe startup replay, and disable interrupted one-shot jobs so they show a visible failure instead of silently disappearing or duplicating work. Fixes #59056, #61343, #63657, and #59301. Thanks @ponchoooPenguin, @daemic24, @myradon, and @hikiwibot. - Cron tool: recover flat top-level schedule shorthand such as
cron,tz, andstaggerMsbefore gateway validation, so model-generated cron add/update calls preserve cron jitter settings. Thanks @tyxben. - Cron: hydrate flat legacy job rows with top-level
cron,tz,session, andmessagefields into canonical schedule, target, and payload objects before startup recomputes run times. Fixes #43351. - Agents/replies: let pending group chat history trigger bare mentioned turns without treating metadata-only inbound context as user input. Fixes #71489. (#71520) Thanks @SymbolStar.
- Google media generation: strip a configured trailing
/v1betafrom Google music/video provider base URLs before calling the Google GenAI SDK, preventing doubled/v1beta/v1betapaths. Fixes #63240. (#63258) Thanks @Hybirdss. - Discord: restore direct-message voice-note preflight transcription and classify URL-only Ogg/Opus voice attachments as audio while skipping partial attachments without usable URLs. Fixes #61314 and #64803.
- Plugins/build: copy bundled plugin skill trees into
dist-runtime, broaden Windows symlink-copy fallbacks, and fingerprint runtime dependencies fromlstatso symlink-like directory entries cannot crash staging. - Google Chat: preserve reply text when a typing indicator message is deleted or can no longer be updated, so media captions and first text chunks are resent instead of silently disappearing. (#71498) Thanks @colin-lgtm.
- Cron: tolerate malformed legacy job rows in startup, main-session system-event payloads, and human-readable
cron listoutput so missingstate,payload.text, or display fields no longer crash the scheduler or CLI. Fixes #66016, #65916, #64137, #57872, #59968, #63813, #52804, and #43163. (#71509) Thanks @vincentkoc. - CLI/models: make
openclaw models scanfall back to public OpenRouter free-model metadata when noOPENROUTER_API_KEYis configured, avoid config secret resolution for explicit--no-probescans, and apply the scan timeout to the OpenRouter catalog request. - Feishu: keep streaming cards to one live card per turn, flush throttled card edits after meaningful text boundaries, and skip exact block/partial repeats so tool-heavy replies do not duplicate card output. Thanks @allan0509.
- Feishu: finish the streaming-card duplicate closeout by stripping leaked reasoning tags, preserving cross-block partial snapshots, enabling topic-thread streaming cards, omitting the generic
maincard header, surfacing transient tool/compaction status, and cleaning streaming state after close failures. Thanks @sesame437, @Vicky-v7, @maoku-family, @Pengxiao-Wang, and @Maple778. - Telegram: recover incomplete partial-stream previews by falling back to a final send when an ambiguous final edit failure would otherwise retain a strict prefix of the answer. Fixes #71525. (#71554) Thanks @sahilsatralkar.
- Control UI/chat: collapse assistant token/model context details behind an explicit Context disclosure and show full dates in message footers, making historical transcript timing clear without noisy default metadata. (#71337) Thanks @BunsDev.
- OpenAI/Codex OAuth: explain
unsupported_country_region_territorytoken-exchange failures with a proxy/region hint instead of surfacing a generic OAuth error. Fixes #51175. (#71501) Thanks @vincentkoc and @wulala-xjj. - Browser/Linux: fall back to headless mode for local managed profiles on hosts without a display server, while preserving explicit per-profile headed overrides and reporting the headless source. (#60953) Thanks @rrpsantos.
- Telegram: remove the startup persisted-offset
getUpdatespreflight so polling restarts do not self-conflict before the runner starts. Fixes #69304. (#69779) Thanks @chinar-amrutkar. - Telegram: keep the polling stall watchdog active even when grammY reports the runner as not running while its task is still pending, so a rebuilt transport cannot leave
getUpdatessilent until a manual gateway restart. Fixes #69064. Thanks @LDLoeb. - Subagents: fall back to direct completion delivery when the parent announce turn finishes without a visible payload, so child results still reach channel-backed requester sessions.
- Subagents: tell parent agents to use
sessions_yieldwhile waiting for child completion events, preventing GPT-5 fast runs from ending silently after spawning workers. - Browser/Playwright: ignore benign already-handled route races during guarded navigation so browser-page tasks no longer fail when Playwright tears down a route mid-flight. (#68708) Thanks @Steady-ai.
- Browser/CLI: lazy-load browser command groups and plugin runtime services so
openclaw browser --helpcan render without loading the full browser automation stack. Fixes #65400. (#65460, #66640) Thanks @pandego and @Tianworld. - Browser/CLI: serve precomputed
openclaw browser --helptext from CLI startup metadata, avoiding the full plugin/config startup path for the common help invocation. - Browser/downloads: seed managed Chrome profiles with OpenClaw download prefs and capture unmanaged click-triggered downloads under the guarded downloads directory, while explicit download waiters still own their target file. (#64558) Thanks @Pearcekieser.
- Browser/Chrome: stop passing redundant
--disable-setuid-sandboxwhenbrowser.noSandboxis enabled;--no-sandboxremains the effective sandbox opt-out. (#67939) Thanks @sebykrueger. - Browser/client: stop telling agents to permanently avoid the browser after transient timeout or cancellation failures; keep the no-retry hint for persistent unavailable/rate-limit cases. (#46505) Thanks @jriff.
- Browser/aria snapshots: bind
format=ariaaxNrefs to live DOM nodes through backend DOM ids when Playwright is available, so follow-up browser actions can use those refs without timing out. (#62434) Thanks @MrKipler. - Telegram: prevent duplicate in-process long pollers for the same bot token and add clearer
getUpdatesconflict diagnostics for external duplicate pollers. Fixes #56230. Thanks @Co-Messi. - Browser/Linux: detect Chromium-based installs under
/opt/google,/opt/brave.com,/usr/lib/chromium, and/usr/lib/chromium-browserbefore asking users to setbrowser.executablePath. (#48563) Thanks @lupuletic. - Sessions/browser: close tracked browser tabs when idle, daily,
/new, or/resetsession rollover archives the previous transcript, preventing tabs from leaking past the old session. Thanks @jakozloski. - Sessions/forking: fall back to transcript-estimated parent token counts when cached totals are stale or missing, so oversized thread forks start fresh instead of cloning the full parent transcript. Thanks @jalehman.
- OpenAI/Codex: send Codex Responses system prompts through top-level
instructionswhile preserving the existing native Codex payload controls. - MCP/CLI: retire bundled MCP runtimes at the end of one-shot
openclaw agentandopenclaw infer model rungateway/local executions, so repeated scripted runs do not accumulate stdio MCP child processes. Fixes #71457. Thanks @spartoviMD. - OpenAI/Codex image generation: canonicalize legacy
openai-codex.baseUrlvalues such ashttps://chatgpt.com/backend-apito the Codex Responses backend before callinggpt-image-2, matching the chat transport. Fixes #71460. Thanks @GodsBoy. - Control UI: make
/usageuse the fresh context snapshot for context percentage, and include cache-write tokens in the Usage overview cache-hit denominator. Fixes #47885. Thanks @imwyvern and @Ante042. - GitHub Copilot: preserve encrypted Responses reasoning item IDs during replay so Copilot can validate encrypted reasoning payloads across requests. (#71448) Thanks @a410979729-sys.
- GitHub Copilot: never rewrite connection-bound reasoning item IDs regardless of whether
encrypted_contentis present, fixing a 400 "Encrypted content item_id did not match" error withgpt-5.3-codexand future Codex models that fall through to the forward-compat catch-all withreasoning: false. Also recognize Codex-named models as reasoning-capable so they inherit the correct capability flags. Refs #68735. Thanks @InvalidPandaa. - Agents/replies: recover final-answer text when streamed assistant chunks contain only whitespace, preventing completed turns from surfacing as empty-payload errors. Fixes #71454. (#71467) Thanks @Sanjays2402.
- Feishu/TTS: transcode voice-intent MP3 and other audio replies to Ogg/Opus before sending native Feishu audio bubbles, while keeping ordinary MP3 attachments as files. Fixes #61249 and #37868. Thanks @sg1416-zg and @ycjlb2023-peteryi.
- WhatsApp/TTS: transcode MP3/WebM audio, including Microsoft Edge TTS output, to Ogg/Opus before sending PTT voice notes.
- QQBot/TTS: honor plain
audioAsVoicereplies by synthesizing TTS to native QQ voice messages, and mark inbound voice-only messages as audio media without exposing raw voice paths to generic media context. - Providers/SenseAudio: add bundled SenseAudio batch audio transcription through
tools.media.audiowithSENSEAUDIO_API_KEYauth. (#66943) Thanks @Fl0rencess720. - Providers/MiniMax: let TTS use MiniMax portal OAuth and Token Plan credentials before falling back to
MINIMAX_API_KEY, and include current TTS HD model ids. Fixes #55017. Thanks @zx15210404690-hash. - Telegram/webhook: acknowledge validated webhook updates before running bot middleware, keeping slow agent turns from tripping Telegram delivery retries while preserving per-chat processing lanes. Fixes #71392. Thanks @joelforsberg46-source.
- MCP/config reload: hot-apply
mcp.*changes by disposing cached session MCP runtimes, and dispose bundled MCP runtimes during gateway shutdown so removedmcp.serversentries reap child processes promptly. Fixes #60656. Thanks @xieyuanqing. - Active Memory: keep silent recall sub-agent billing/auth failures out of shared auth-profile cooldown state, so a Claude CLI extra-usage rejection cannot disable normal Claude-backed turns. Fixes #71284. (#71539) Thanks @vishutdhar and @obviyus.
- Auth/Claude CLI: sync refreshed Claude CLI OAuth credentials into the managed auth profile so long-running Claude CLI runs stop falling back to stale OpenClaw snapshots. (#70902) Thanks @starvex.
- Sessions: make
sessions_spawn(mode="session")errors name usable alternatives when the current channel cannot bind subagent threads. Fixes #67400. (#67790) Thanks @stainlu. - Agents/Claude CLI: pass the OpenClaw system prompt through Claude's prompt-file flag so Windows runs avoid argv length failures without changing system prompt semantics. Fixes #69158. (#69211) Thanks @skylee-01, @cassioanorte, @Syu0, and @Stache73.
- Agents/CLI sessions: bind
google-gemini-clisession auth-epoch to the Google account identity in~/.gemini/oauth_creds.json, so Gemini-backed agents resume their conversation after gateway restart instead of minting a fresh session, and stale bindings are invalidated when the authenticated Google account changes. Fixes #70973. (#71076) Thanks @openperf. - Slack: stop treating user mentions in assistant-authored message edit blocks as sender attribution, preventing edited bot messages from spoofing a mentioned DM user. (#71700) Thanks @vincentkoc.
- Codex: consume unauthorized bound conversation inbound claims before they can fall through to other claim handlers or enqueue Codex turns. (#71702) Thanks @vincentkoc.
- Codex media understanding: require approval-checked app-server image turns while explicitly declining tool, file, permission, and elicitation approval requests for the bounded image worker. (#71703) Thanks @vincentkoc.
- Agents/Claude CLI: allow large live
stream-jsonJSONL lines up to the existing per-turn raw limit, preventing large Telegram, WebChat, MCP, and image turns from aborting on the old stdout buffer cap. Fixes #71793, #71080, and #70766. (#71897) Thanks @chacher86, @shivamgrover21, and @tpjordan. - Agents/Claude CLI: unwrap nested Claude result envelopes in CLI JSON output so delegated agent responses surface as final text instead of raw result JSON. (#66819) Thanks @mraleko.
- Agents/Claude CLI: apply the configured 1M context window override to eligible Claude CLI Opus and Sonnet models when
context1mis enabled. (#70863) Thanks @bidadh. - Models/status: report fresh Claude CLI native auth instead of stale stored
anthropic:claude-cliprofile expiry when local credentials are current. Fixes #71256. (#71332) Thanks @matthiasjanke and @neeravmakwana. - CLI backends: compact OpenClaw transcripts after over-budget CLI turns and reseed fresh CLI sessions from the compacted transcript instead of stale external resume state. Fixes #68329. (#71916) Thanks @obviyus.
- Telegram: keep default tool progress messages visible when answer preview streaming is disabled. (#71825) Thanks @VACInc.
- Configure/models: clear deselected model fallbacks when updating the model picker allowlist, including provider-scoped setup flows. (#71596) Thanks @rubencu.
- Agents/streaming: strip namespaced
<antml:thinking>reasoning tags from streamed assistant replies before user-visible text is emitted. (#69288) Thanks @xialonglee.