2026.4.22
Changes
- Providers/xAI: add image generation, text-to-speech, and speech-to-text support, including
grok-imagine-image/grok-imagine-image-pro, reference-image edits, six live xAI voices, MP3/WAV/PCM/G.711 TTS formats,grok-sttaudio transcription, and xAI realtime transcription for Voice Call streaming. (#68694) Thanks @KateWilkins. - Providers/STT: add Voice Call streaming transcription for Deepgram, ElevenLabs, and Mistral, alongside the existing OpenAI and xAI realtime STT paths; ElevenLabs also gains Scribe v2 batch audio transcription for inbound media.
- TUI: add local embedded mode for running terminal chats without a Gateway while keeping plugin approval gates enforced. (#66767) Thanks @fuller-stack-dev.
- Onboarding: auto-install missing provider and channel plugins during setup so first-run configuration can complete without manual plugin recovery.
- OpenAI/Responses: use OpenAI's native
web_searchtool automatically for direct OpenAI Responses models when web search is enabled and no managed search provider is pinned; explicit providers such as Brave keep the managedweb_searchtool. - Models/commands: add
/models add <provider> <modelId>so you can register a model from chat and use it without restarting the gateway; keep/modelsas a simple provider browser while adding clearer add guidance and copy-friendly command examples. (#70211) Thanks @Takhoffman. - WhatsApp: add configurable native reply quoting with replyToMode for WhatsApp conversations. Thanks @mcaxtr.
- WhatsApp/groups+direct: forward per-group and per-direct
systemPromptconfig into inbound contextGroupSystemPromptso configured per-chat behavioral instructions are injected on every turn. Supports"*"wildcard fallback and account-scoped overrides underchannels.whatsapp.accounts.<id>.{groups,direct}; account maps fully replace root maps (no deep merge), matching the existingrequireMentionpattern. Closes #7011. (#59553) Thanks @Bluetegu. - Agents/sessions: add mailbox-style
sessions_listfilters for label, agent, and search plus visibility-scoped derived title and last-message previews. (#69839) Thanks @dangoZhang. - Control UI/settings+chat: add a browser-local personal identity for the operator (name plus local-safe avatar), route user identity rendering through the shared chat/avatar path used by assistant and agent surfaces, and tighten Quick Settings, agent fallback chips, and narrow-screen chat layouts so personalization no longer wastes space or clips controls. (#70362) Thanks @BunsDev.
- Gateway/diagnostics: enable payload-free stability recording by default and add a support-ready diagnostics export with sanitized logs, status, health, config, and stability snapshots for bug reports. (#70324) Thanks @gumadeiras.
- Providers/Tencent: add the bundled Tencent Cloud provider plugin with TokenHub onboarding, docs,
hy3-previewmodel catalog entries, and tiered Hy3 pricing metadata. (#68460) Thanks @JuniperSling. - Providers/Amazon Bedrock Mantle: add Claude Opus 4.7 through Mantle's Anthropic Messages route with provider-owned bearer-auth streaming, so the model is actually callable without treating AWS bearer tokens like Anthropic API keys. Thanks @wirjo.
- Providers/GPT-5: move the GPT-5 prompt overlay into the shared provider runtime so compatible GPT-5 models receive the same behavior and heartbeat guidance through OpenAI, OpenRouter, OpenCode, Codex, and other GPT providers; add
agents.defaults.promptOverlays.gpt5.personalityas the global friendly-style toggle while keeping the OpenAI plugin setting as a fallback. - Providers/OpenAI Codex: remove the Codex CLI auth import path from onboarding and provider discovery so OpenClaw no longer copies
~/.codexOAuth material into agent auth stores; use browser login or device pairing instead. (#70390) Thanks @pashpashpash. - CLI/Claude: default
claude-cliruns to warm stdio sessions, including custom configs that omit transport fields, and resume from the stored Claude session after Gateway restarts or idle exits. (#69679) Thanks @obviyus. - Pi/models: update the bundled pi packages to
0.68.1and let the OpenCode Go catalog come from pi instead of plugin-maintained model aliases, adding the refreshedopencode-go/kimi-k2.6, Qwen, GLM, MiMo, and MiniMax entries. - Tokenjuice: add bundled native OpenClaw support for tokenjuice as an opt-in plugin that compacts noisy
execandbashtool results in Pi embedded runs. (#69946) Thanks @vincentkoc. - ACPX: add an explicit
openClawToolsMcpBridgeoption that injects a core OpenClaw MCP server for selected built-in tools, starting withcron. - CLI/doctor plugins: lazy-load doctor plugin paths and prefer installed plugin
dist/*runtime entries over source-adjacent JavaScript fallbacks, reducing the measureddoctor --non-interactiveruntime by about 74% while keeping cold doctor startup on built plugin artifacts. (#69840) Thanks @gumadeiras. - CLI/debugging: add an opt-in temporary debug timing helper for local CLI performance investigations, with readable stderr output, JSONL capture, and docs for removing probes before landing fixes. (#70469) Thanks @shakkernerd.
- Docs/i18n: add Thai translation support for the docs site.
- Providers/OpenAI-compatible: mark known local backends such as vLLM, SGLang, llama.cpp, LM Studio, LocalAI, Jan, TabbyAPI, and text-generation-webui as streaming-usage compatible, so their token accounting no longer degrades to unknown/stale totals. (#68711) Thanks @gaineyllc.
- Providers/OpenAI-compatible: recover streamed token usage from llama.cpp-style
timings.prompt_n/timings.predicted_nmetadata and sanitize usage counts before accumulation, fixing unknown or stale totals when compatible servers do not emit an OpenAI-shapedusageobject. (#41056) Thanks @xaeon2026. - Plugins/startup: prefer native Jiti loading for built bundled plugin dist modules on supported runtimes, cutting measured bundled plugin load time by 82-90% while keeping source TypeScript on the transform path. (#69925) Thanks @aauren.
- Plugin SDK/STT: share realtime transcription WebSocket transport and multipart batch transcription form helpers across bundled STT providers, reducing provider plugin boilerplate while preserving proxy capture, reconnects, audio queueing, close flushing, upload filename normalization, and ready handshakes.
- Plugin SDK/Pi embedded runs: add a bundled-plugin embedded extension factory seam so native plugins can extend Pi embedded runs with async runtime hooks such as
tool_resulthandling instead of falling back to the older synchronous persistence path. (#69946) Thanks @vincentkoc. - Codex harness/hooks: route native Codex app-server turns through
before_prompt_buildand emitbefore_compaction/after_compactionfor native compaction items so prompt and compaction hooks stop drifting from Pi. Thanks @vincentkoc. - Codex harness/plugins: add a bundled-plugin Codex app-server extension seam for async
tool_resultmiddleware, fireafter_tool_callfor Codex tool runs, and route mirrored Codex transcript writes throughbefore_message_writeso tool integrations stop diverging from Pi. Thanks @vincentkoc. - Codex harness/hooks: fire
llm_input,llm_output, andagent_endfor native Codex app-server turns so lifecycle hooks stop drifting from Pi. Thanks @vincentkoc. - QA/Telegram: record per-scenario reply RTT in the live Telegram QA report and summary, starting with the canary response. (#70550) Thanks @obviyus.
- Status: add an explicit
Runner:field to/statusso sessions now report whether they are running on embedded Pi, a CLI-backed provider, or an ACP harness agent/backend such ascodex (acp/acpx)orgemini (acp/acpx). (#70595)
Fixes
- Thinking defaults/status: raise the implicit default thinking level for reasoning-capable models from legacy
off/lowfallback behavior to a safe provider-supportedmediumequivalent when no explicit config default is set, preserve configured-model reasoning metadata when runtime catalog loading is empty, and make/statusreport the same resolved default as runtime. - Gateway/model pricing: fetch OpenRouter and LiteLLM pricing asynchronously at startup and extend catalog fetch timeouts to 30 seconds, reducing noisy timeout warnings during slow upstream responses.
- Agents/sessions: keep daily reset and idle-maintenance bookkeeping from bumping session activity or pruning freshly active routes, so active conversations no longer look newer or disappear for maintenance-only updates.
- Plugins/install: add newly installed plugin ids to an existing
plugins.allowlist before enabling them, so allowlisted configs load installed plugins after restart. - Status: show
Fastin/statuswhen fast mode is enabled, including config/default-derived fast mode, and omit it when disabled. - OpenAI/image generation: detect Azure OpenAI-style image endpoints, use Azure
api-keyauth plus deployment-scoped image URLs, honorAZURE_OPENAI_API_VERSION, and document the Azure setup path so image generation and edits work against Azure-hosted OpenAI resources. (#70570) Thanks @zhanggpcsu. - Telegram/forum topics: cache recovered forum metadata with bounded expiry so supergroup updates no longer need repeated
getChatlookups before topic routing. - Onboarding/WeCom: show the official WeCom channel plugin with its native Enterprise WeChat display name and blurb in the external channel catalog.
- Models/auth: merge provider-owned default-model additions from
openclaw models auth logininstead of replacingagents.defaults.models, so re-authenticating an OAuth provider such as OpenAI Codex no longer wipes other providers' aliases and per-model params. Migrations that must rename keys (Anthropic -> Claude CLI) opt in withreplaceDefaultModels. Fixes #69414. (#70435) Thanks @neeravmakwana. - Media understanding/audio: prefer configured or key-backed STT providers before auto-detected local Whisper CLIs, so installed local transcription tools no longer shadow API providers such as Groq/OpenAI in
tools.media.audioauto mode. Fixes #68727. - Providers/OpenAI: lock the auth picker wording for OpenAI API key, Codex browser login, and Codex device pairing so the setup choices no longer imply a mixed Codex/API-key auth path. (#67848) Thanks @tmlxrd.
- Agents/BTW: route
/btwside questions through provider stream registration with the session workspace, so Ollama provider URL construction and workspace-scoped hooks apply correctly. Fixes #68336. (#70413) Thanks @suboss87. - Agents/sessions: make session transcript write locks non-reentrant by default, so same-process transcript writers contend unless a helper explicitly opts into nested lock ownership.
- ACPX/probe: expose an optional
probeAgentplugin config field so the embedded ACP runtime health probe can target a configured agent (for exampleopencodeorclaude) instead of hardcodingcodex, and stop marking the entire ACP runtime backend unavailable when the default probe agent is simply not installed or not authenticated. (#68409) Thanks @lyfuci. - Memory search: use sqlite-vec KNN for vector recall while preserving full post-filter result limits in multi-model indexes. Fixes #69666. (#69680) Thanks @aalekh-sarvam.
- Providers/OpenAI Codex: stop stale per-agent
openai-codex:defaultOAuth profiles from shadowing a newer main-agent identity-scoped profile, and letopenclaw doctoroffer the matching cleanup. (#70393) Thanks @pashpashpash. - ACPX: route OpenClaw ACP bridge commands through the MCP-free runtime path even when the command is wrapped with
env, has bridge flags, or is resumed from persisted session state, so documentedacpx openclawsetups no longer fail on per-session MCP injection. (#68741) Thanks @alexlomt. - Codex harness: route Codex-tagged MCP tool approval elicitations through OpenClaw plugin approvals, including current empty-schema app-server requests, while leaving generic user-input prompts fail-closed. (#68807) Thanks @kesslerio.
- WhatsApp/outbound: hold an in-memory active-delivery claim while a live outbound send is in flight, so a concurrent reconnect drain no longer re-drives the same pending queue entry and duplicates cron sends 7-12x after the 30-minute inbound-silence watchdog fires mid-delivery. Crash-replay of fresh queue entries left behind by a dead process is preserved because the claim is intentionally process-local. Fixes #70386. (#70428) Thanks @neeravmakwana.
- Matrix/commands: keep Matrix DM allowlist state out of room control-command authorization, so trusted DM senders do not accidentally gain room-command access.
- Providers/SDK retry: cap long
Retry-Aftersleeps in Stainless-based Anthropic/OpenAI model SDKs so 60s+ retry windows surface immediately for OpenClaw failover instead of blocking the run. (#68474) Thanks @jetd1. - Agents/TTS: preserve spoken text in TTS tool results while defusing reply directives in transcript content, so future turns remember voice replies without treating spoken
MEDIA:or voice tags as delivery metadata. (#68869) Thanks @zqchris. - Providers/OpenAI: harden Voice Call realtime transcription against OpenAI Realtime session-update drift, forward language and prompt hints, and add live coverage for realtime STT.
- Agents/Pi embedded runs: suppress the "⚠️ Agent couldn't generate a response" warning when the assistant already delivered user-visible content through a messaging tool and the turn ended cleanly (
stopReason=stop). Real failure modes (tool errors, providerstopReason=error, interrupted tool use) still surface the existing "verify before retrying" warning. Fixes #70396. (#70425) Thanks @neeravmakwana. - Gateway/Linux: wrap gateway-managed supervisor, PTY, MCP stdio, and browser child processes in a tiny
/bin/shshim that raises the child's ownoom_score_adjon Linux, so under cgroup memory pressure the kernel prefers transient workers over the long-lived gateway. Opt out withOPENCLAW_CHILD_OOM_SCORE_ADJ=0. Fixes #70404. (#70419) Thanks @neeravmakwana. - Providers/Moonshot: stop strict-sanitizing Kimi's native tool_call IDs (shaped like
functions.<name>:<index>) on the OpenAI-compatible transport, so multi-turn agentic flows through Kimi K2.6 no longer break after 2-3 tool-calling rounds when the serving layer fails to match mangled IDs against the original tool definitions. Adds asanitizeToolCallIdsopt-out to the sharedopenai-compatiblereplay family helper and wires Moonshot to it. Fixes #62319. (#70030) Thanks @LeoDu0314. - Dependencies/security: override transitive
uuidto14.0.0, clearing the runtime advisory across dependencies. - Codex harness: ignore dynamic tool descriptions when deciding whether to reuse a native app-server thread while still fingerprinting tool schemas, so channel-specific copy changes no longer reset otherwise compatible Codex conversations. (#69976) Thanks @chen-zhang-cs-code.
- Codex harness: expose the Codex app-server model catalog in
models list/status, avoid startup hangs from app-server discovery timeouts, and accept current Codex turn-completion notifications so Docker live gateway turns finish reliably. - Codex harness: drop invalid legacy app-server
serviceTiervalues such as"priority"before native thread and turn requests, while keeping supported Codex tiers limited to"fast"and"flex". Fixes #64815. - Codex harness: show bounded, sanitized permission target samples in app-server approval prompts, so native permission requests keep their specific hosts, roots, and paths visible without leaking home usernames or URL credentials. (#70340) Thanks @Lucenx9.
- Docs/Codex harness: narrow native compaction docs to the current start/completion signals, without promising a readable summary or kept-entry audit list yet. (#69612) Thanks @91wan.
- Providers/Amazon Bedrock: use known context-window metadata for discovered models while keeping the unknown-model fallback conservative, so compaction and overflow handling improve for newer Bedrock models without overstating unlisted model limits. Thanks @wirjo.
- Providers/Amazon Bedrock Mantle: refresh IAM-backed bearer tokens at runtime instead of baking discovery-time tokens into provider config, so long-lived Mantle sessions keep working after the initial token ages out. Thanks @wirjo.
- Config/includes: write through single-file top-level includes for isolated OpenClaw-owned mutations, so
plugins installandplugins updateupdate an includedplugins.json5file instead of flattening modular$includeconfigs. Fixes #41050 and #66048. - Config/reload: plan gateway reloads from source-authored config instead of runtime-materialized snapshots, so plugin update writes no longer trigger false restarts from derived provider/plugin config paths. Fixes #68732.
- Plugins/update: skip npm plugin reinstall/config rewrites when the installed version and recorded artifact identity already match the registry target, let bare npm package names resolve back to tracked install records, and point already-installed
plugins installattempts atplugins update/--forceinstead of a hook-pack fallback. Fixes #46955, #67957, and #68073. - Agents/MCP: keep
mcp.serversand bundle MCP tools available in Pi embedded
codingandmessagingsessions while preservingminimalprofile and
tools.deny: ["bundle-mcp"]opt-out behavior. Fixes #68875 and #68818. - Plugins/startup: tolerate transient bundled-channel catalog/metadata drift while auto-enabling configured plugins, so CLI and gateway startup no longer crash when a channel id is known but its display metadata is unavailable.
- CLI/Claude: report CLI-backed reply runs as streaming while Claude/Codex CLI turns are still in flight, so WebChat keeps visible response state until the backend finishes. Fixes #70125.
- Slack/streaming: fall back to normal Slack replies for Slack Connect streams rejected before the SDK flushes its local buffer, so short replies no longer disappear or report success before Slack acknowledges delivery. Fixes #70295. (#70370) Thanks @mvanhorn.
- Codex harness: rotate the shared app-server websocket client when the configured bearer token changes, so auth-token refreshes reconnect with the new
Authorizationheader instead of reusing a stale socket. (#70328) Thanks @Lucenx9. - Channels/sandbox: derive runtime policy keys for external direct messages that share the main conversation, so sandbox/tool policy no longer treats channel-originated DMs as local main-session runs.
- Config/models: merge provider-scoped model allowlist updates and protect model/provider map writes from accidental full replacement, adding
config set --mergefor additive updates and--replacefor intentional clobbers. Fixes #65920, #68392, and #68653. - Agents/Pi auth: preserve AWS SDK-authenticated Bedrock runs for IMDS and task-role setups, clear stale refresh timers on sentinel fallback, and log unexpected runtime-auth prep failures instead of silently leaving the provider unauthenticated. Thanks @wirjo.
- Config/gateway: restore last-known-good config on critical clobber signatures such as missing metadata, missing
gateway.mode, or sharp size drops, preventing gateway crash loops when a valid backup exists. Fixes #70336. - Config/gateway: recover configs accidentally prefixed with non-JSON output during gateway startup or
openclaw doctor --fix, preserving the clobbered file as a backup while leaving normal config reads read-only. - Agents/GitHub Copilot: normalize connection-bound Responses item IDs in the Copilot provider wrapper so replayed histories no longer fail after the upstream connection changes. (#69362) Thanks @Menci.
- Pi embedded runs: pass real built-in tools into Pi session creation and then narrow active tool names after custom tool registration, so the runner and compaction paths compile cleanly and keep OpenClaw-managed custom tool allowlists without feeding string arrays into
createAgentSession. Thanks @vincentkoc. - Agents/OpenAI websocket: route native OpenAI websocket metadata and session-header decisions through the shared endpoint classifier so local mocks and custom
models.providers.openai.baseUrlendpoints stay out of the native OpenAI path consistently across embedded-runner and websocket transport code. Thanks @vincentkoc. - Cron/MCP: retire bundled MCP runtimes through one shared cleanup path for isolated cron run ends, persistent cron session rollover, and direct cron
deleteAfterRunfallback cleanup. Fixes #69145, #68623, and #68827. - MCP/gateway: tear down stdio MCP process trees on transport close and dispose bundled MCP runtimes during session delete/reset, preventing orphaned wrapper/server processes from accumulating. Fixes #68809 and #69465.
- Agents/MCP: retire bundled MCP runtimes after completed one-shot subagent cleanup and nested
sessions_sendsteps, while keeping persistent subagent sessions warm. - Config: render validation warnings with real line breaks instead of a literal
\nsequence in CLI/audit output. Fixes #70140. - Cron/doctor: repair malformed persisted cron job IDs through
openclaw doctor, including legacyjobId, non-stringid, and missingidrows, socron listno longer needs display-layer coercion for corrupt store data. Fixes #70128. - Discord: normalize prefixed channel targets only at the thread-binding API boundary, so
sessions_spawn({ runtime: "acp", thread: true })can create child threads from Discord channels without breaking current-channel ACP bindings. (#68034) Thanks @Zetarcos. - Discord: harden inbound thread metadata handling against partial Carbon channel getters, so non-command thread messages and queued jobs no longer crash when
name,parentId,parent, orownerIdrequires fetched raw data. - Discord: let
messagetool reactions resolveuser:<id>DM targets and preservechannels.discord.guilds.<guild>.channels.<channel>.requireMention: falseduring reply-stage activation fallback. Fixes #70165 and #69441. - Plugins/startup: pre-normalize and cache Jiti alias maps before creating plugin loaders, so module-scoped loader filenames do not reintroduce per-plugin alias-normalization startup cost. Fixes #70186.
- ACP/Codex: run the bundled Codex ACP harness with an isolated
CODEX_HOMEand avoid writing incomplete ChatGPT auth bridge files, so Codex ACP sessions no longer clobber the user's real Codex CLI auth. Fixes #70234. Thanks @Lonobers88. - Gateway/client: keep long-running RPCs such as ACP
agent.waitcalls in charge of their own timeout instead of closing the websocket on a missed app-level tick while work is still pending. - Telegram/webhooks: lower the grammY webhook callback timeout to 5s so Telegram gets an early 200 response instead of retrying long-running updates as read timeouts. (#70146) Thanks @friday-james.
- Telegram/polling: rebuild the polling HTTP transport after
getUpdates409 conflicts, so retries use a fresh TCP connection instead of looping on a Telegram-terminated keep-alive socket. (#69873) Thanks @hclsys. - Media delivery: strip persisted base64 audio payloads from webchat history, resolve stored
media://inbound/*attachments before local-root checks, suppress duplicate Telegram voice/audio sends when TTS emits the same media twice, and support custom image-model IDs that already include their provider prefix. - Slack/files: resolve
downloadFilebot tokens from the runtime config when callers providecfgwithout an explicit token or prebuilt client, preserving cfg-only file downloads outside the action runtime path. (#70160) Thanks @martingarramon. - Slack/HTTP: dispatch registered Request URL webhooks through the same handler registry used by Slack monitor setup, so HTTP-mode Slack events no longer 404 after successful route registration. (#70275) Thanks @FroeMic.
- Slack/runtime bindings: route focused Slack thread replies through their bound ACP session instead of preparing replies against the default agent shell. Fixes #67739. Thanks @Frankla20.
- CLI/Claude: keep stored Claude CLI sessions through OAuth refresh-token rotation by keying auth epochs on stable account identity instead of mutable OAuth token material. (#70452) Thanks @obviyus.
- CLI/Claude: verify stored Claude CLI session ids have a readable project transcript before resuming, clearing phantom bindings with
reason=transcript-missinginstead of silently starting fresh under--resume. Fixes #70177. - CLI sessions: persist CLI session clearing through the atomic session-store merge path, so expired Claude/Codex CLI bindings are actually removed before retrying without the stale session id. (#70298) Thanks @HFConsultant.
- ACP/sessions_spawn: honor explicit
modeloverrides for ACP child sessions instead of silently falling back to the target agent default model. (#70210) Thanks @felix-miao. - Diffs/viewer: re-read remote viewer access policy from live runtime config on each request, so toggling
plugins.entries.diffs.config.security.allowRemoteViewercloses proxied viewer access immediately instead of waiting for a restart. Thanks @vincentkoc. - Diffs/tooling: re-read
viewerBaseUrl, presentation defaults, and viewer access policy from live runtime config, and fail closed when the livediffsplugin entry disappears instead of reviving startup viewer settings. Thanks @vincentkoc. - Memory/LanceDB: stop resurrecting removed live
memory-lancedbhook config from startup snapshots, so deleting or disabling the plugin entry shuts off auto-recall and auto-capture without a restart. Thanks @vincentkoc. - Memory/LanceDB: keep auto-recall and auto-capture hooks wired when those settings start disabled, so turning them on in live config starts recall and capture without waiting for a restart. Thanks @vincentkoc.
- Skill Workshop: keep the tool plus
before_prompt_build/agent_endhooks wired while the plugin is disabled at startup, so turning the plugin back on in live config starts guidance and capture without waiting for a restart. Thanks @vincentkoc. - Active Memory: stop reviving removed live
active-memoryconfig from startup snapshots, so removing the plugin entry turns the hook off immediately instead of waiting for a restart. Thanks @vincentkoc. - GitHub Copilot: re-read plugin discovery config from the live runtime snapshot, so toggling
plugins.entries.github-copilot.config.discovery.enabledtakes effect without a restart. Thanks @vincentkoc. - Ollama: re-read plugin discovery config from the live runtime snapshot, so toggling
plugins.entries.ollama.config.discovery.enabledtakes effect without a restart. Thanks @vincentkoc. - OpenAI: re-read the plugin prompt-overlay personality from live runtime config, so GPT-5 system prompt contributions update without a restart when
plugins.entries.openai.config.personalitychanges. Thanks @vincentkoc. - Amazon Bedrock: re-read live discovery and guardrail plugin config, so toggling
plugins.entries.amazon-bedrock.config.discoveryorplugins.entries.amazon-bedrock.config.guardrailtakes effect without a restart. Thanks @vincentkoc. - Codex: re-read the plugin discovery config from the live runtime snapshot, so toggling
plugins.entries.codex.config.discoverytakes effect without a restart. Thanks @vincentkoc. - Agents/subagents: drop bare
NO_REPLYfrom the parent turn when the session still has pending spawned children, so direct-conversation surfaces such as Telegram DMs no longer rewrite the sentinel into visible fallback chatter while waiting for the child completion event. (#69942) Thanks @neeravmakwana. - Plugins/install: keep bundled plugin dependencies off npm install while repairing them when plugins activate from a packaged install, including Feishu/Lark, Browser, and direct bundled channel setup-entry loads.
- CLI/channels: skip and cache bundled channel plugin, setup, and secrets load failures during read-only discovery, so one broken unused bundled channel cannot crash
openclaw statusor bootstrap secret scans. - Memory/LanceDB: retry initialization after a failed LanceDB load and report unsupported Intel macOS native runtime clearly instead of caching the failure or repeatedly attempting an install that cannot work.
- CLI/Claude: hash only static extra system prompt parts when deciding whether to reuse a CLI session, so per-message inbound metadata no longer resets Claude CLI conversations on every turn. (#70122) Thanks @zijunl.
- Hooks/Slack: standardize shared message hook routing fields (
threadId/replyToId) and stop Slack outbound delivery from re-runningmessage_sendinginside the channel adapter, so plugins like thread-ownership make one outbound routing decision per reply. Thanks @vincentkoc. - Auto-reply/media: share one run-scoped reply media context between streamed block delivery and final payload filtering, so a local
MEDIA:attachment is staged once and duplicate media sends are suppressed reliably. (#68111) Thanks @ayeshakhalid192007-dev. - Plugins/gateway hooks: expose startup config, workspace dir, and a live cron getter on the typed
gateway_starthook, and move memory-core managed dreaming off the internalgateway:startupbridge so cron reconciliation stays on the public plugin hook path. Thanks @vincentkoc. - Plugins/config: read plugin trust decisions from the source config snapshot when a resolved runtime snapshot is active, so
plugins.allowremains enforced anddoctor/gateway startup no longer warn that the allowlist is empty when it is configured. Fixes #70161. Also fixes #70141. - Agents/openai-completions: enable malformed streamed tool-call argument repair for self-hosted OpenAI-compatible backends such as Kimi/SGLang, so fragmented tool-call arguments no longer reach tools as empty or unusable objects. Fixes #69672. (#70294) Thanks @MonkeyLeeT.
- Gateway/restart: preserve group and channel chat context when resuming an agent turn after a Gateway restart, so continuation replies keep the same prompt, routing, and tool-status behavior as the original conversation.
- Gateway/pairing: shared-secret loopback CLI clients now silently auto-approve
metadata-upgradepairing (platform / device family refresh) instead of being disconnected with1008 pairing required. This matches the scope-upgrade and role-upgrade behavior added in #69431 and unblocks non-interactive CLI automation when a paired-device record has a stale platform string (e.g. device key replicated across hosts, install migrated between OSes, or platform-string format changed between OpenClaw versions). Browser / Control-UI clients keep the existing approval-required flow for metadata changes. - Gateway/pairing: treat any forwarded-header evidence (
Forwarded,X-Forwarded-*, orX-Real-IP) as proxied WebSocket traffic before pairing locality checks, so reverse-proxy topologies cannot use the loopback shared-secret helper auto-pairing path. - Agents/OpenAI: treat exact
NO_REPLYassistant output as a deliberate silent reply in embedded runs, so GPT-5.4 turns with signed reasoning plus a silent final no longer surface a false incomplete-turn error. - Auto-reply/streaming: preserve streamed reply directives through chunk boundaries and phase-aware
final_answerdelivery, so splitMEDIA:<path>lines, voice tags, and reply targets reach channel delivery instead of leaking as text or being dropped. (#70243) Thanks @zqchris. - Anthropic/Claude Opus 4.7: normalize Opus 4.7 and
claude-cliOpus 4.7 variants to a 1M context window in resolved runtime metadata and active-agent status/context reporting, so they no longer inherit the stale 200k fallback. Thanks @BunsDev. - Gateway/pairing webchat: render
/pair qrreplies as structured media instead of raw markdown text, preserve inline reply threading and silent-control handling on media replies, avoid persisting sensitive QR images into transcript history, and keep local webchat media embedding behind internal-only trust markers. (#70047) Thanks @BunsDev. - Codex harness: default app-server runs to unchained local execution, so OpenAI heartbeats can use network and shell tools without stalling behind native Codex approvals or the workspace-write sandbox.
- Codex harness: fail closed for unknown native app-server approval methods instead of routing unsupported future approval shapes through OpenClaw approval grants. (#70356) Thanks @Lucenx9.
- Codex harness: apply the GPT-5 behavior and heartbeat prompt overlay to native Codex app-server runs, so
codex/gpt-5.xsessions get the same follow-through, tool-use, and proactive heartbeat guidance as OpenAI GPT-5 runs. - Codex harness: add an explicit Guardian mode for Codex app-server approvals, plus a Docker live probe for approved and ask-back Guardian decisions, while keeping default app-server runs unchained for unattended local heartbeats. The legacy
OPENCLAW_CODEX_APP_SERVER_GUARDIANshortcut is removed; use plugin configappServer.mode: "guardian"orOPENCLAW_CODEX_APP_SERVER_MODE=guardian. Thanks @pashpashpash. - OpenAI/Responses: keep embedded OpenAI Responses runs on HTTP when
models.providers.openai.baseUrlpoints at a local mock or other non-public endpoint, so mocked/custom endpoints no longer drift onto the hardcoded public websocket transport. (#69815) Thanks @vincentkoc. - Channels/config: require resolved runtime config on channel send/action/client helpers and block runtime helper
loadConfig()calls, so SecretRefs are resolved at startup/boundaries instead of being re-read during sends. - Discord: pass resolved runtime config through guild and moderation action helpers, so thread-originated Discord commands can run channel, member, role, and guild actions without falling back to runtime config reads. (#70215) Thanks @szponeczek.
- CLI/channels: preserve bundled setup promotion metadata when a loaded partial channel plugin omits it, so adding a non-default account still moves legacy single-account fields such as Telegram
streamingintoaccounts.default. - Telegram: keep the sent-message ownership cache isolated per configured session store, so own-message reaction filtering remains correct with custom
session.storepaths. - Security/update: fail closed when exact pinned npm plugin or hook-pack updates detect integrity drift, and expose aborted plugin drift details in
openclaw update --json. - Ollama: forward OpenClaw thinking control to native
/api/chatrequests as top-levelthink, so/think offandopenclaw agent --thinking offsuppress thinking on models such as qwen3 instead of idling until the watchdog fires. Fixes #69902. (#69967) Thanks @WZH8898. - Memory-core/dreaming: suppress the startup-only managed dreaming cron unavailable warning when the cron service is still attaching, while preserving the runtime warning if cron genuinely remains unavailable. Fixes #69939. (#69941) Thanks @Sanjays2402.
- Mattermost: suppress reasoning-only payloads even when they arrive as blockquoted
> Reasoning:text, preventing/reasoning onfrom leaking thinking into channel posts. (#69927) Thanks @lawrence3699. - Discord: read
channel.parentIdthrough a safe accessor in the slash-command, reaction, and model-picker paths so partialGuildThreadChannelprototype getters no longer throwCannot access rawData on partial Channelwhen commands like/newrun from inside a thread. Fixes #69861. (#69908) Thanks @neeravmakwana. - Discord: use safe channel name and parent accessors across voice command authorization, so
/vccommands from partial Discord thread channels no longer crash on Carbon rawData getters. (#70199) Thanks @hanamizuki. - Discord: make auto-thread parent transcript inheritance opt-in via
channels.discord.thread.inheritParent, keeping newly created Discord thread sessions isolated by default while preserving explicit inheritance for configured accounts. Fixes #69907. (#69986) Thanks @Blahdude. - Browser/Chrome MCP: reset cached existing-session control sessions when a
navigate_pagecall times out, so one stuck navigation no longer poisons the browser profile until a gateway restart. (#69733) Thanks @ayeshakhalid192007-dev. - Browser/Chrome MCP: propagate click timeouts and abort signals to existing-session actions so a stuck click fails fast and reconnects instead of poisoning the browser tool until gateway restart. (#63524) Thanks @dongseok0.
- Amazon Bedrock/prompt caching: resolve opaque application inference profile targets before injecting Bedrock cache points, require every routed target to support explicit cache points, and retry transient profile lookups instead of caching a false negative for the rest of the process. (#69953) Thanks @anirudhmarc and @vincentkoc.
- Gateway/channel health: base stale-socket recovery on provider-proven transport activity instead of inbound app-event freshness, preventing quiet Slack, Discord, Telegram, Matrix, and local-style channels from being restarted solely because no user traffic arrived. (#69833) Thanks @bek91.
- OpenCode Go: canonicalize stale bundled
opencode-gobase URLs from/goor/go/v1to/zen/goor/zen/go/v1, so older generated model metadata stops hitting the 404 HTML endpoint. (#69898) - CLI/channels: honor
channels.<id>.enabled=falseas a hard read-only presence opt-out, so env vars, manifest env vars, or stale persisted auth state no longer make disabled channel plugins appear in status, doctor, or setup-only discovery. - Channels/preview streaming: centralize draft-preview finalization so Slack, Discord, Mattermost, and Matrix no longer flush temporary preview messages for media/error finals, and preserve first-reply threading for normal fallback delivery.
- Discord: keep slash command follow-up chunks ephemeral when the command is configured for ephemeral replies, so long
/statusoutput no longer leaks fallback model or runtime details into the public channel. (#69869) thanks @gumadeiras. - Gateway/session history: re-check current auth and
chat.historyscope before later SSE keepalives and transcript updates, so active session-history streams close before delivering post-revocation events. - Plugins/discovery: reject package plugin source entries that escape the package directory before explicit runtime entries or inferred built JavaScript peers can be used. (#69868) thanks @gumadeiras.
- CLI/channels: resolve channel presence through a shared policy that keeps ambient env vars and stale persisted auth from surfacing disabled bundled plugins in status, doctor, security audit, and cron delivery validation unless the channel or plugin is effectively enabled or explicitly configured. (#69862) Thanks @gumadeiras.
- Doctor/plugins: hydrate legacy partial interactive handler state before plugin reload clears dedupe caches, so
openclaw doctorand post-update doctor runs no longer crash withCannot read properties of undefined (reading 'clear'). (#70135) Thanks @ngutman. - Control UI/config: preserve intentionally empty raw config snapshots when clearing pending updates so reset restores the original bytes instead of synthesizing JSON for blank config files. (#68178) Thanks @BunsDev.
- memory-core/dreaming: surface a
Dreaming status: blockedline inopenclaw memory statuswhen dreaming is enabled but the heartbeat that drives the managed cron is not firing for the default agent, and add a Troubleshooting section to the dreaming docs covering the two common causes (per-agentheartbeatblocks excludingmain, andheartbeat.everyset to0/empty/invalid), so the silent failure described in #69843 becomes legible on the status surface. - Cron/run-log: report generic
messagetool sends under the resolved delivery channel when they match the cron target, while preserving account-specific mismatch checks for delivery traces. (#69940) Thanks @davehappyminion. - Doctor/channels: merge configured-channel doctor hooks across read-only, loaded, setup, and runtime plugin discovery so partial adapters no longer hide runtime-only compatibility repair or allowlist warnings, preserve disabled-channel opt-outs, and ignore malformed hook values before they can mask valid fallbacks. (#69919) Thanks @gumadeiras.
- Models/CLI: show bundled provider-owned static catalog rows in
models list --allbefore auth is configured, including Kimi K2.6 rows for Moonshot, OpenRouter, and Vercel AI Gateway, while keeping local-only and workspace plugin catalog paths isolated. (#69909) Thanks @shakkernerd. - Models/CLI: clarify that
models list --providerexpects provider ids and reject display labels before loading model discovery. (#70504) Thanks @shakkernerd. - Configure: skip generic CLI startup bootstrap for
openclaw configureand bound hint-only gateway probes so the onboarding TUI reaches its first prompt faster when the Gateway is unavailable. (#69984) Thanks @obviyus. - Agents/harness: surface selected plugin harness failures directly instead of replaying the same turn through embedded PI, preventing misleading secondary PI auth errors and avoiding duplicate side effects.
- OpenAI Codex: add a ChatGPT device-code auth option beside browser OAuth, so headless or callback-hostile setups can sign in without relying on the localhost browser callback. (#69557) Thanks @vincentkoc.
- CLI sessions: keep provider-owned CLI sessions through implicit daily expiry while preserving explicit reset behavior, and retain Claude CLI binding metadata across gateway agent requests. (#70106) Thanks @obviyus.
- fix(config): accept truncateAfterCompaction (#68395). Thanks @MonkeyLeeT
- CLI/Claude: keep Claude CLI session bindings stable across OAuth access-token refreshes, so gateway restarts continue the same Claude conversation instead of minting a fresh one. (#70132) Thanks @obviyus.
- QQBot: add
INTERACTIONintent (1 << 26) to the gateway constants and include it in theFULL_INTENTSmask so interaction events are received. (#70143) Thanks @cxyhhhhh. - Gateway/restart: preserve one-shot continuation instructions across gateway restarts so agents can resume and reply back to the original chat after reboot. (#63406) Thanks @VACInc.
- Gateway/restart: write restart sentinel files atomically so interrupted writes cannot leave a truncated sentinel behind. (#70225) Thanks @obviyus.
- Pairing: remove stale pending requests for a device when that paired device is deleted, so an old repair approval cannot recreate the removed device from leftover state.
- Security/dotenv: block workspace
.envoverrides for Matrix, Mattermost, IRC, and Synology endpoint settings so cloned workspaces cannot redirect bundled connector traffic through local endpoint config. (#70240) Thanks @drobison00. - Telegram: require the same
/modelsauthorization for group model-picker callbacks, so unauthorized participants can no longer browse or change the session model through inline buttons. (#70235) Thanks @drobison00. - Agents/Pi: keep the filtered tool-name allowlist active for embedded OpenAI/OpenAI Codex GPT-5 runs and compaction sessions, so bundled and client tools still execute after the Pi
0.68.1session-tool allowlist change instead of stopping at plan-only replies with no tool call. (#70281) Thanks @jalehman. - Agents/Pi: honor explicit
strict-agenticexecution contracts for incomplete-turn retry guards across providers, so manually opted-in local or compatible models get the same retry behavior without relying on OpenAI model inference. (#66750) Thanks @ziomancer. - OpenShell/sandbox: pin verified file reads to an already-opened descriptor, walk the ancestor chain for symlinked parents on platforms without fd-path readlink, and re-check file identity so parent symlink swaps cannot redirect in-sandbox reads to host files outside the allowed mount root. (#69798) Thanks @drobison00.
- Gateway/Control UI: require authenticated Control UI read access before serving
/__openclaw/control-ui-config.jsonwhengateway.authis enabled, so unauthenticated callers can no longer read bootstrap metadata. (#70247) Thanks @drobison00. - Gateway/restart: default session-scoped restart sentinels to a one-shot agent continuation, so chat-initiated Gateway restarts acknowledge successful boot automatically. (#70269) Thanks @obviyus.
- Build/npm publish: fail postpublish verification when root
dist/*files import bundled plugin runtime dependencies without mirroring them in the root package manifest, so Slack-style plugin deps cannot silently ship on the wrong module-resolution path again. (#60112) thanks @medns.